Skip to content

Commit

Permalink
feat(ui): update Progress to use Ark UI and add Progress Circular
Browse files Browse the repository at this point in the history
  • Loading branch information
tszhong0411 committed Jan 15, 2025
1 parent 0205113 commit a18660a
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-maps-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tszhong0411/ui': patch
---

Update Progress to use Ark UI and add Progress Circular
22 changes: 20 additions & 2 deletions apps/docs/src/app/ui/components/progress.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,27 @@ description: Displays an indicator showing the completion progress of a task, ty
## Usage

```tsx
import { Progress } from '@tszhong0411/ui'
import { Progress, ProgressRange, ProgressTrack } from '@tszhong0411/ui'
```

```tsx
<Progress value={33} />
<Progress value={66}>
<ProgressTrack>
<ProgressRange />
</ProgressTrack>
</Progress>
```

## Examples

### With Label

<ComponentPreview name='progress/with-label' />

### With Value

<ComponentPreview name='progress/with-value' />

### Circular

<ComponentPreview name='progress/circular' />
37 changes: 37 additions & 0 deletions apps/docs/src/components/demos/progress/circular.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use client'

import {
Progress,
ProgressCircle,
ProgressCircleRange,
ProgressCircleTrack,
ProgressLabel,
ProgressValueText
} from '@tszhong0411/ui'
import { useEffect, useState } from 'react'

const ProgressCircularDemo = () => {
const [progress, setProgress] = useState(13)

useEffect(() => {
const timer = setTimeout(() => {
setProgress(66)
}, 500)

return () => {
clearTimeout(timer)
}
}, [])
return (
<Progress value={progress}>
<ProgressLabel>Label</ProgressLabel>
<ProgressCircle>
<ProgressCircleTrack />
<ProgressCircleRange />
</ProgressCircle>
<ProgressValueText />
</Progress>
)
}

export default ProgressCircularDemo
24 changes: 17 additions & 7 deletions apps/docs/src/components/demos/progress/progress.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
'use client'

import { Progress } from '@tszhong0411/ui'
import { Progress, ProgressRange, ProgressTrack, ProgressValueText } from '@tszhong0411/ui'
import { useEffect, useState } from 'react'

const ProgressDemo = () => {
const [progress, setProgress] = useState(13)
const [progress, setProgress] = useState(0)

useEffect(() => {
const timer = setTimeout(() => {
setProgress(66)
}, 500)
const interval = setInterval(() => {
setProgress((value) => (value === 100 ? 0 : value + 1))
// eslint-disable-next-line sonarjs/pseudo-random -- it's safe
}, Math.random() * 500)

return () => {
clearTimeout(timer)
clearInterval(interval)
}
}, [])

return <Progress aria-label='Loading...' value={progress} className='max-w-md' />
return (
<Progress value={progress} min={0} max={100} className='w-3/5 max-w-md'>
<ProgressTrack>
<ProgressRange />
</ProgressTrack>
<div className='w-full text-center'>
<ProgressValueText />
</div>
</Progress>
)
}

export default ProgressDemo
29 changes: 29 additions & 0 deletions apps/docs/src/components/demos/progress/with-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { Progress, ProgressLabel, ProgressRange, ProgressTrack } from '@tszhong0411/ui'
import { useEffect, useState } from 'react'

const ProgressWithLabelDemo = () => {
const [progress, setProgress] = useState(13)

useEffect(() => {
const timer = setTimeout(() => {
setProgress(66)
}, 500)

return () => {
clearTimeout(timer)
}
}, [])

return (
<Progress value={progress} className='w-3/5 max-w-md'>
<ProgressLabel>Label</ProgressLabel>
<ProgressTrack>
<ProgressRange />
</ProgressTrack>
</Progress>
)
}

export default ProgressWithLabelDemo
29 changes: 29 additions & 0 deletions apps/docs/src/components/demos/progress/with-value.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { Progress, ProgressRange, ProgressTrack, ProgressValueText } from '@tszhong0411/ui'
import { useEffect, useState } from 'react'

const ProgressWithValueDemo = () => {
const [progress, setProgress] = useState(13)

useEffect(() => {
const timer = setTimeout(() => {
setProgress(66)
}, 500)

return () => {
clearTimeout(timer)
}
}, [])

return (
<Progress value={progress} className='w-3/5 max-w-md'>
<ProgressTrack>
<ProgressRange />
</ProgressTrack>
<ProgressValueText />
</Progress>
)
}

export default ProgressWithValueDemo
97 changes: 88 additions & 9 deletions packages/ui/src/progress.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,103 @@
'use client'

import * as ProgressPrimitive from '@radix-ui/react-progress'
import { Progress as ProgressPrimitive } from '@ark-ui/react'
import { cn } from '@tszhong0411/utils'

type ProgressProps = React.ComponentProps<typeof ProgressPrimitive.Root>

const Progress = (props: ProgressProps) => {
const { className, value, ...rest } = props
const { className, ...rest } = props

return (
<ProgressPrimitive.Root
className={cn('[--size:96px] [--thickness:12px]', className)}
{...rest}
/>
)
}

type ProgressLabelProps = React.ComponentProps<typeof ProgressPrimitive.Label>

const ProgressLabel = (props: ProgressLabelProps) => {
const { className, ...rest } = props

return (
<ProgressPrimitive.Label
className={cn('text-sm font-medium leading-none', className)}
{...rest}
/>
)
}

type ProgressTrackProps = React.ComponentProps<typeof ProgressPrimitive.Track>

const ProgressTrack = (props: ProgressTrackProps) => {
const { className, ...rest } = props

return (
<ProgressPrimitive.Track
className={cn('bg-secondary relative h-3 w-full overflow-hidden rounded-full', className)}
{...rest}
>
<ProgressPrimitive.Indicator
className='bg-primary size-full flex-1 transition-all'
style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }}
/>
</ProgressPrimitive.Root>
/>
)
}

type ProgressRangeProps = React.ComponentProps<typeof ProgressPrimitive.Range>

const ProgressRange = (props: ProgressRangeProps) => {
const { className, ...rest } = props

return (
<ProgressPrimitive.Range
className={cn('bg-primary size-full flex-1 transition-all', className)}
{...rest}
/>
)
}

export { Progress }
type ProgressValueTextProps = React.ComponentProps<typeof ProgressPrimitive.ValueText>

const ProgressValueText = (props: ProgressValueTextProps) => {
const { className, ...rest } = props

return (
<ProgressPrimitive.ValueText
className={cn('text-muted-foreground text-sm', className)}
{...rest}
/>
)
}

const ProgressCircle = ProgressPrimitive.Circle

type ProgressCircleTrackProps = React.ComponentProps<typeof ProgressPrimitive.CircleTrack>

const ProgressCircleTrack = (props: ProgressCircleTrackProps) => {
const { className, ...rest } = props

return <ProgressPrimitive.CircleTrack className={cn('stroke-secondary', className)} {...rest} />
}

type ProgressCircleRangeProps = React.ComponentProps<typeof ProgressPrimitive.CircleRange>

const ProgressCircleRange = (props: ProgressCircleRangeProps) => {
const { className, ...rest } = props

return (
<ProgressPrimitive.CircleRange
className={cn('stroke-primary transition-all', className)}
{...rest}
/>
)
}

export {
Progress,
ProgressCircle,
ProgressCircleRange,
ProgressCircleTrack,
ProgressLabel,
ProgressRange,
ProgressTrack,
ProgressValueText
}

0 comments on commit a18660a

Please sign in to comment.