Skip to content

Commit

Permalink
Merge pull request #445 from omnifed/441-feat-make-progressbar-component
Browse files Browse the repository at this point in the history
441 feat make progressbar component
  • Loading branch information
caseybaggz committed Sep 5, 2024
2 parents 7efbb36 + 9a5b186 commit 026131c
Show file tree
Hide file tree
Showing 16 changed files with 262 additions and 50 deletions.
10 changes: 10 additions & 0 deletions docs/app/components/code-builder/builder-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
BooleanResult,
BuilderResult,
EnumResult,
NumberResult,
TextResult,
} from './helpers'
import { Field, Label, Show } from '@cerberus-design/react'
Expand Down Expand Up @@ -88,6 +89,15 @@ export default function BuilderForm(props: BuilderFormProps) {
selectedValue={selectedProps[key] as string}
/>
</Show>
<Show when={props.api[key].type === 'number'}>
<Input
{...(props.api[key] as NumberResult)}
id={key}
name={key}
onChange={handleInputChange}
selectedValue={selectedProps[key] as string}
/>
</Show>
<Show when={props.api[key].type === 'boolean'}>
<Toggle
{...(props.api[key] as BooleanResult)}
Expand Down
9 changes: 5 additions & 4 deletions docs/app/components/code-builder/builder-input.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
'use client'

import { Input, type InputProps } from '@cerberus-design/react'
import type { TextResult } from './helpers'

interface BuilderInputProps
extends Omit<InputProps, 'name' | 'type' | 'value'>,
TextResult {
extends Omit<InputProps, 'name' | 'type' | 'value'> {
name: string
type: 'text' | 'number'
value: string | number
selectedValue: string
}

export default function BuilderInput(props: BuilderInputProps) {
const { selectedValue, ...nativeProps } = props
return <Input {...nativeProps} type="text" value={selectedValue} />
return <Input {...nativeProps} value={selectedValue} />
}
14 changes: 12 additions & 2 deletions docs/app/components/code-builder/builder-snippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ import { useMemo, type PropsWithChildren } from 'react'
import { css } from '@cerberus/styled-system/css'

function isFormState(key: string) {
return ['disabled', 'required', 'readOnly', 'invalid'].includes(key)
return [
'disabled',
'required',
'readOnly',
'invalid',
'indeterminate',
].includes(key)
}

function isProgressKey(key: string) {
return ['now'].includes(key)
}

function isChildContent(key: string) {
Expand All @@ -28,7 +38,7 @@ export default function BuilderSnippet(
return (selectedProps[key as keyof typeof selectedProps] ||
'Add Text') as string
}
if (isFormState(key)) {
if (isFormState(key) || isProgressKey(key)) {
return `{${selectedProps[key as keyof typeof selectedProps] || 'false'}}`
}
return `"${selectedProps[key as keyof typeof selectedProps] || 'false'}"`
Expand Down
21 changes: 20 additions & 1 deletion docs/app/components/code-builder/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ function Enum(name: string, value: string[]): EnumResult {
}
}

export interface NumberResult {
name: string
type: 'number'
value: number
}

function Number(name: string, value: number): NumberResult {
return {
name,
type: 'number',
value,
}
}

export interface TextResult {
name: string
type: 'text'
Expand Down Expand Up @@ -40,10 +54,15 @@ function Boolean(name: string, value: boolean): BooleanResult {
}
}

export type BuilderResult = EnumResult | TextResult | BooleanResult
export type BuilderResult =
| EnumResult
| TextResult
| BooleanResult
| NumberResult

export const builder = {
Boolean,
Enum,
Text,
Number,
}
8 changes: 4 additions & 4 deletions docs/app/context/code-builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ function getInitialAPIValues(api: Record<string, BuilderResult>, key: string) {
switch (result.type) {
case 'enum':
return result.value[0]
case 'text':
return result.value
case 'boolean':
return false
default:
return result.value
}
}

interface CodeBuilderContextValue {
selectedProps: Record<string, boolean | string>
selectedProps: Record<string, boolean | string | number>
setSelectedProps: (key: string, value: boolean | string) => void
}

Expand All @@ -37,7 +37,7 @@ export default function CodeBuilderProvider(
props: PropsWithChildren<CodeBuilderProviderProps>,
) {
const [selectedProps, setSelectedProps] = useState<
Record<string, boolean | string>
Record<string, boolean | string | number>
>(() => {
return Object.keys(props.api).reduce(
(acc, key) => ({ ...acc, [key]: getInitialAPIValues(props.api, key) }),
Expand Down
43 changes: 43 additions & 0 deletions docs/app/react/progress-bar/components/live-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use client'

import CodeBuilder from '@/app/components/code-builder/code-builder'
import { builder } from '@/app/components/code-builder/helpers'
import { useCodeBuilder } from '@/app/context/code-builder'
import { ProgressBar } from '@cerberus-design/react'

const api = {
size: builder.Enum('size', ['sm', 'md']),
usage: builder.Enum('usage', ['rounded', 'block']),
now: builder.Number('now', 75),
indeterminate: builder.Boolean('indeterminate', false),
}

export function LivePlayground() {
return (
<CodeBuilder api={api}>
<ProgressBarPreview />
</CodeBuilder>
)
}

export function LivePlaygroundWithCode() {
return (
<CodeBuilder
api={api}
code={`import { ProgressBar, type ProgressBarProps } from '@cerberus-design/react'
export function MyProgressBar(props: ProgressBarProps) {
return (
<ProgressBar indeterminate={{indeterminate}} size={{size}} usage={{usage}} now={{now}} />
)
}`}
>
<ProgressBarPreview />
</CodeBuilder>
)
}

export function ProgressBarPreview() {
const { selectedProps } = useCodeBuilder()
return <ProgressBar {...selectedProps} now={selectedProps.now as number} />
}
29 changes: 3 additions & 26 deletions docs/app/react/progress-bar/components/progress-bar-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
import { Tag } from '@cerberus-design/react'
import { ProgressBar, Tag } from '@cerberus-design/react'
import { hstack, vstack } from '@cerberus/styled-system/patterns'
import {
progressBar,
type ProgressBarVariantProps,
} from '@cerberus/styled-system/recipes'
import type { HtmlHTMLAttributes } from 'react'

type ProgressBarProps = HtmlHTMLAttributes<HTMLDivElement> &
ProgressBarVariantProps & {
value: number
}

function ProgressBar(props: ProgressBarProps) {
const styles = progressBar({ size: props.size, usage: props.usage })
const width = {
width: `${props.value}%`,
}

return (
<div className={styles.root}>
<div className={styles.bar} style={width} />
</div>
)
}

export function OverviewPreview() {
return (
Expand All @@ -38,7 +15,7 @@ export function OverviewPreview() {
w: 'full',
})}
>
<ProgressBar size="sm" value={75} />
<ProgressBar size="sm" now={75} />
<Tag shape="pill">Rounded</Tag>
</div>
<div
Expand All @@ -47,7 +24,7 @@ export function OverviewPreview() {
w: 'full',
})}
>
<ProgressBar size="sm" usage="block" value={75} />
<ProgressBar size="sm" usage="block" now={75} />
<Tag shape="pill">Block</Tag>
</div>
</div>
Expand Down
21 changes: 12 additions & 9 deletions docs/app/react/progress-bar/dev.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,39 @@ import CodePreview from '@/app/components/CodePreview'
import {
NoteAdmonition
} from '@/app/components/Admonition'
import {
OverviewPreview
} from '@/app/react/progress-bar/components/progress-bar-preview'
import { LivePlaygroundWithCode } from '@/app/react/progress-bar/components/live-preview'

```tsx
import { ProgressBar } from '@cerberus-design/react'
```

## Usage

<CodePreview preview={<OverviewPreview />} />
<LivePlaygroundWithCode />

## Customization

You can customize the table by utilizing the `css` function. For full control, we recommend extending the recipes provided in your panda config.

<CodePreview preview={<OverviewPreview />} />
To customize the ProgressBar we recommend extending the slot recipe provided by the `@cerberus-design/panda-preset` package.

## API

```ts showLineNumbers=false
export interface ProgressBarProps extends HTMLAttributes<HTMLDivElement> {
export interface ProgressBarBaseProps extends HTMLAttributes<HTMLDivElement> {
size?: 'sm' | 'md'
usage?: 'block' | 'rounded'
now: number
}
type IndeterminateProgressBarProps = Omit<ProgressBarProps, 'now'> & {
indeterminate: true
}
type ProgressBarProps = ProgressBarBaseProps & IndeterminateProgressBarProps

define function ProgressBar(props: ProgressBarProps): ReactNode
````

| Name | Default | Description |
| -------- | ------- | -------------------------------------------- |
| size | `md` | The size of the progress bar. |
| usage | `rounded` | The style of the progress bar. |
| usage | `rounded` | The style of the progress bar. |
| now | | The current progress value. |
| indeterminate | `false` | If the progress bar is in an indeterminate state. |
2 changes: 2 additions & 0 deletions docs/app/react/progress-bar/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OverviewList from '@/app/components/OverviewList'
import {
OverviewPreview
} from '@/app/react/progress-bar/components/progress-bar-preview'
import { LivePlayground } from '@/app/react/progress-bar/components/live-preview'

<OverviewList rules={[
'Two styles: block and rounded',
Expand All @@ -20,6 +21,7 @@ import {
## Example

<CodePreview preview={<OverviewPreview />} />
<LivePlayground />

## Resources

Expand Down
14 changes: 12 additions & 2 deletions packages/panda-preset/src/recipes/slots/progressBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const progressBar: Partial<SlotRecipeConfig> = defineSlotRecipe({
base: {
root: {
bgColor: 'page.bg.100',
overflow: 'hidden',
position: 'relative',
w: 'full',
},
Expand All @@ -27,11 +28,20 @@ export const progressBar: Partial<SlotRecipeConfig> = defineSlotRecipe({
top: 0,
willChange: 'width',
zIndex: 'decorator',
['&:is([data-complete=true])']: {
bgImage: 'none',
bgColor: 'success.bg.initial',
},
_motionSafe: {
transitionProperty: 'width',
transitionProperty: 'background-color,background-image,width',
transitionDuration: '150ms',
transitionTimingFunction: 'ease',
_indeterminate: {},
_indeterminate: {
animationName: 'rubberBand',
animationIterationCount: 'infinite',
animationDuration: '1.25s',
animationTimingFunction: 'ease-in-out',
},
},
},
},
Expand Down
19 changes: 19 additions & 0 deletions packages/panda-preset/src/theme/keyframes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ export const keyframes: CssKeyframes = defineKeyframes({
transform: 'translateY(0)',
},
},
rubberBand: {
'0%': {
animationTimingFunction:
'cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971)',
transform: 'translateX(0)',
},
'19.15%': {
animationTimingFunction:
'cubic-bezier(0.152313, 0.196432, 0.648374, 1.00432)',
transform: 'scaleX(1.5)',
},
'45.15%': {
animationTimingFunction:
'cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179)',
},
'100%': {
transform: 'translateX(200%)',
},
},
zoomIn: {
'0%': {
opacity: '0',
Expand Down
Loading

0 comments on commit 026131c

Please sign in to comment.