@neynar/ui 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/components/ui/accordion.d.ts +229 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +247 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert.d.ts +187 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +94 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/avatar.d.ts +244 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/badge.d.ts +163 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +281 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/button.d.ts +129 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/calendar.d.ts +169 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/card.d.ts +365 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/carousel.d.ts +369 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/chart.d.ts +442 -0
- package/dist/components/ui/chart.d.ts.map +1 -0
- package/dist/components/ui/checkbox.d.ts +88 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/collapsible.d.ts +182 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/combobox.d.ts +270 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/command.d.ts +355 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/container.d.ts +102 -0
- package/dist/components/ui/container.d.ts.map +1 -0
- package/dist/components/ui/context-menu.d.ts +339 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/date-picker.d.ts +145 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/dialog.d.ts +322 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/drawer.d.ts +154 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +349 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/empty-state.d.ts +133 -0
- package/dist/components/ui/empty-state.d.ts.map +1 -0
- package/dist/components/ui/hover-card.d.ts +109 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/input.d.ts +89 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/label.d.ts +93 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/menubar.d.ts +306 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +318 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/pagination.d.ts +343 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/popover.d.ts +178 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/progress.d.ts +64 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/radio-group.d.ts +144 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/resizable.d.ts +164 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +82 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/select.d.ts +316 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/separator.d.ts +80 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/sheet.d.ts +346 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sidebar.d.ts +1561 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/skeleton.d.ts +66 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/slider.d.ts +95 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/sonner.d.ts +101 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/stack.d.ts +192 -0
- package/dist/components/ui/stack.d.ts.map +1 -0
- package/dist/components/ui/stories/accordion.stories.d.ts +71 -0
- package/dist/components/ui/stories/accordion.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/alert-dialog.stories.d.ts +39 -0
- package/dist/components/ui/stories/alert-dialog.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/alert.stories.d.ts +48 -0
- package/dist/components/ui/stories/alert.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts +53 -0
- package/dist/components/ui/stories/aspect-ratio.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/avatar.stories.d.ts +49 -0
- package/dist/components/ui/stories/avatar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/badge.stories.d.ts +64 -0
- package/dist/components/ui/stories/badge.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/breadcrumb.stories.d.ts +27 -0
- package/dist/components/ui/stories/breadcrumb.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/button.stories.d.ts +92 -0
- package/dist/components/ui/stories/button.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/calendar.stories.d.ts +94 -0
- package/dist/components/ui/stories/calendar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/card.stories.d.ts +29 -0
- package/dist/components/ui/stories/card.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/carousel.stories.d.ts +42 -0
- package/dist/components/ui/stories/carousel.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/chart.stories.d.ts +51 -0
- package/dist/components/ui/stories/chart.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/checkbox.stories.d.ts +72 -0
- package/dist/components/ui/stories/checkbox.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/cn.stories.d.ts +19 -0
- package/dist/components/ui/stories/cn.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/collapsible.stories.d.ts +51 -0
- package/dist/components/ui/stories/collapsible.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/colors.stories.d.ts +31 -0
- package/dist/components/ui/stories/colors.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/combobox.stories.d.ts +89 -0
- package/dist/components/ui/stories/combobox.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/command.stories.d.ts +69 -0
- package/dist/components/ui/stories/command.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/container.stories.d.ts +42 -0
- package/dist/components/ui/stories/container.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/context-menu.stories.d.ts +32 -0
- package/dist/components/ui/stories/context-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/date-picker.stories.d.ts +67 -0
- package/dist/components/ui/stories/date-picker.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/dialog.stories.d.ts +48 -0
- package/dist/components/ui/stories/dialog.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/drawer.stories.d.ts +33 -0
- package/dist/components/ui/stories/drawer.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/dropdown-menu.stories.d.ts +31 -0
- package/dist/components/ui/stories/dropdown-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/empty-state.stories.d.ts +74 -0
- package/dist/components/ui/stories/empty-state.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/hover-card.stories.d.ts +35 -0
- package/dist/components/ui/stories/hover-card.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/input.stories.d.ts +69 -0
- package/dist/components/ui/stories/input.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/label.stories.d.ts +47 -0
- package/dist/components/ui/stories/label.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/menubar.stories.d.ts +39 -0
- package/dist/components/ui/stories/menubar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/navigation-menu.stories.d.ts +44 -0
- package/dist/components/ui/stories/navigation-menu.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/pagination.stories.d.ts +33 -0
- package/dist/components/ui/stories/pagination.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/popover.stories.d.ts +36 -0
- package/dist/components/ui/stories/popover.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/progress.stories.d.ts +38 -0
- package/dist/components/ui/stories/progress.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/radio-group.stories.d.ts +76 -0
- package/dist/components/ui/stories/radio-group.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/resizable.stories.d.ts +49 -0
- package/dist/components/ui/stories/resizable.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/scroll-area.stories.d.ts +35 -0
- package/dist/components/ui/stories/scroll-area.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/select.stories.d.ts +51 -0
- package/dist/components/ui/stories/select.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/separator.stories.d.ts +58 -0
- package/dist/components/ui/stories/separator.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sheet.stories.d.ts +43 -0
- package/dist/components/ui/stories/sheet.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sidebar.stories.d.ts +60 -0
- package/dist/components/ui/stories/sidebar.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/skeleton.stories.d.ts +42 -0
- package/dist/components/ui/stories/skeleton.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/slider.stories.d.ts +99 -0
- package/dist/components/ui/stories/slider.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/sonner.stories.d.ts +9 -0
- package/dist/components/ui/stories/sonner.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/stack.stories.d.ts +39 -0
- package/dist/components/ui/stories/stack.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/switch.stories.d.ts +71 -0
- package/dist/components/ui/stories/switch.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/table.stories.d.ts +40 -0
- package/dist/components/ui/stories/table.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/tabs.stories.d.ts +62 -0
- package/dist/components/ui/stories/tabs.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/text-field.stories.d.ts +78 -0
- package/dist/components/ui/stories/text-field.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/textarea.stories.d.ts +57 -0
- package/dist/components/ui/stories/textarea.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/theme-toggle.stories.d.ts +71 -0
- package/dist/components/ui/stories/theme-toggle.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/theme.stories.d.ts +51 -0
- package/dist/components/ui/stories/theme.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/toggle-group.stories.d.ts +71 -0
- package/dist/components/ui/stories/toggle-group.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/toggle.stories.d.ts +78 -0
- package/dist/components/ui/stories/toggle.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/tooltip.stories.d.ts +37 -0
- package/dist/components/ui/stories/tooltip.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/typography.stories.d.ts +137 -0
- package/dist/components/ui/stories/typography.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/use-mobile.stories.d.ts +20 -0
- package/dist/components/ui/stories/use-mobile.stories.d.ts.map +1 -0
- package/dist/components/ui/stories/use-theme.stories.d.ts +23 -0
- package/dist/components/ui/stories/use-theme.stories.d.ts.map +1 -0
- package/dist/components/ui/switch.d.ts +84 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/table.d.ts +321 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +260 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/text-field.d.ts +157 -0
- package/dist/components/ui/text-field.d.ts.map +1 -0
- package/dist/components/ui/textarea.d.ts +84 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/theme-toggle.d.ts +105 -0
- package/dist/components/ui/theme-toggle.d.ts.map +1 -0
- package/dist/components/ui/theme.d.ts +110 -0
- package/dist/components/ui/theme.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +133 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle.d.ts +84 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/tooltip.d.ts +202 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/typography.d.ts +287 -0
- package/dist/components/ui/typography.d.ts.map +1 -0
- package/dist/hooks/use-mobile.d.ts +74 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-theme.d.ts +142 -0
- package/dist/hooks/use-theme.d.ts.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27498 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +43 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/llm/colors.md +273 -0
- package/docs/llm/components/buttons.md +68 -0
- package/docs/llm/components/cards.md +53 -0
- package/docs/llm/components/display.md +134 -0
- package/docs/llm/components/feedback.md +96 -0
- package/docs/llm/components/forms.md +90 -0
- package/docs/llm/components/layout.md +59 -0
- package/docs/llm/components/menus.md +70 -0
- package/docs/llm/components/navigation.md +80 -0
- package/docs/llm/components/overlays.md +83 -0
- package/docs/llm/components/tables.md +73 -0
- package/docs/llm/components/typography.md +199 -0
- package/docs/llm/components/utilities.md +114 -0
- package/docs/llm/guide.md +165 -0
- package/llms.txt +122 -0
- package/package.json +104 -0
- package/src/components/ui/accordion.tsx +285 -0
- package/src/components/ui/alert-dialog.tsx +387 -0
- package/src/components/ui/alert.tsx +243 -0
- package/src/components/ui/aspect-ratio.tsx +99 -0
- package/src/components/ui/avatar.tsx +288 -0
- package/src/components/ui/badge.tsx +205 -0
- package/src/components/ui/breadcrumb.tsx +378 -0
- package/src/components/ui/button.tsx +195 -0
- package/src/components/ui/calendar.tsx +371 -0
- package/src/components/ui/card.tsx +447 -0
- package/src/components/ui/carousel.tsx +624 -0
- package/src/components/ui/chart.tsx +802 -0
- package/src/components/ui/checkbox.tsx +113 -0
- package/src/components/ui/collapsible.tsx +207 -0
- package/src/components/ui/combobox.tsx +373 -0
- package/src/components/ui/command.tsx +518 -0
- package/src/components/ui/container.tsx +114 -0
- package/src/components/ui/context-menu.tsx +563 -0
- package/src/components/ui/date-picker.tsx +213 -0
- package/src/components/ui/dialog.tsx +447 -0
- package/src/components/ui/drawer.tsx +273 -0
- package/src/components/ui/dropdown-menu.tsx +578 -0
- package/src/components/ui/empty-state.tsx +145 -0
- package/src/components/ui/hover-card.tsx +144 -0
- package/src/components/ui/input.tsx +106 -0
- package/src/components/ui/label.tsx +110 -0
- package/src/components/ui/menubar.tsx +553 -0
- package/src/components/ui/navigation-menu.tsx +471 -0
- package/src/components/ui/pagination.tsx +456 -0
- package/src/components/ui/popover.tsx +216 -0
- package/src/components/ui/progress.tsx +88 -0
- package/src/components/ui/radio-group.tsx +183 -0
- package/src/components/ui/resizable.tsx +209 -0
- package/src/components/ui/scroll-area.tsx +132 -0
- package/src/components/ui/select.tsx +485 -0
- package/src/components/ui/separator.tsx +101 -0
- package/src/components/ui/sheet.tsx +495 -0
- package/src/components/ui/sidebar.tsx +2211 -0
- package/src/components/ui/skeleton.tsx +76 -0
- package/src/components/ui/slider.tsx +147 -0
- package/src/components/ui/sonner.tsx +120 -0
- package/src/components/ui/stack.tsx +180 -0
- package/src/components/ui/stories/accordion.stories.tsx +429 -0
- package/src/components/ui/stories/alert-dialog.stories.tsx +519 -0
- package/src/components/ui/stories/alert.stories.tsx +228 -0
- package/src/components/ui/stories/aspect-ratio.stories.tsx +200 -0
- package/src/components/ui/stories/avatar.stories.tsx +317 -0
- package/src/components/ui/stories/badge.stories.tsx +260 -0
- package/src/components/ui/stories/breadcrumb.stories.tsx +482 -0
- package/src/components/ui/stories/button.stories.tsx +266 -0
- package/src/components/ui/stories/calendar.stories.tsx +375 -0
- package/src/components/ui/stories/card.stories.tsx +308 -0
- package/src/components/ui/stories/carousel.stories.tsx +328 -0
- package/src/components/ui/stories/chart.stories.tsx +430 -0
- package/src/components/ui/stories/checkbox.stories.tsx +297 -0
- package/src/components/ui/stories/cn.stories.tsx +433 -0
- package/src/components/ui/stories/collapsible.stories.tsx +256 -0
- package/src/components/ui/stories/colors.stories.tsx +502 -0
- package/src/components/ui/stories/combobox.stories.tsx +301 -0
- package/src/components/ui/stories/command.stories.tsx +632 -0
- package/src/components/ui/stories/container.stories.tsx +250 -0
- package/src/components/ui/stories/context-menu.stories.tsx +446 -0
- package/src/components/ui/stories/date-picker.stories.tsx +378 -0
- package/src/components/ui/stories/dialog.stories.tsx +535 -0
- package/src/components/ui/stories/drawer.stories.tsx +364 -0
- package/src/components/ui/stories/dropdown-menu.stories.tsx +374 -0
- package/src/components/ui/stories/empty-state.stories.tsx +244 -0
- package/src/components/ui/stories/hover-card.stories.tsx +355 -0
- package/src/components/ui/stories/input.stories.tsx +289 -0
- package/src/components/ui/stories/label.stories.tsx +294 -0
- package/src/components/ui/stories/menubar.stories.tsx +764 -0
- package/src/components/ui/stories/navigation-menu.stories.tsx +539 -0
- package/src/components/ui/stories/pagination.stories.tsx +604 -0
- package/src/components/ui/stories/popover.stories.tsx +392 -0
- package/src/components/ui/stories/progress.stories.tsx +218 -0
- package/src/components/ui/stories/radio-group.stories.tsx +400 -0
- package/src/components/ui/stories/resizable.stories.tsx +417 -0
- package/src/components/ui/stories/scroll-area.stories.tsx +180 -0
- package/src/components/ui/stories/select.stories.tsx +389 -0
- package/src/components/ui/stories/separator.stories.tsx +192 -0
- package/src/components/ui/stories/sheet.stories.tsx +468 -0
- package/src/components/ui/stories/sidebar.stories.tsx +731 -0
- package/src/components/ui/stories/skeleton.stories.tsx +216 -0
- package/src/components/ui/stories/slider.stories.tsx +321 -0
- package/src/components/ui/stories/sonner.stories.tsx +373 -0
- package/src/components/ui/stories/stack.stories.tsx +222 -0
- package/src/components/ui/stories/switch.stories.tsx +202 -0
- package/src/components/ui/stories/table.stories.tsx +541 -0
- package/src/components/ui/stories/tabs.stories.tsx +544 -0
- package/src/components/ui/stories/text-field.stories.tsx +280 -0
- package/src/components/ui/stories/textarea.stories.tsx +245 -0
- package/src/components/ui/stories/theme-toggle.stories.tsx +275 -0
- package/src/components/ui/stories/theme.stories.tsx +412 -0
- package/src/components/ui/stories/toggle-group.stories.tsx +337 -0
- package/src/components/ui/stories/toggle.stories.tsx +325 -0
- package/src/components/ui/stories/tooltip.stories.tsx +444 -0
- package/src/components/ui/stories/typography.stories.tsx +1586 -0
- package/src/components/ui/stories/use-mobile.stories.tsx +420 -0
- package/src/components/ui/stories/use-theme.stories.tsx +531 -0
- package/src/components/ui/switch.tsx +106 -0
- package/src/components/ui/table.tsx +424 -0
- package/src/components/ui/tabs.tsx +316 -0
- package/src/components/ui/text-field.tsx +206 -0
- package/src/components/ui/textarea.tsx +98 -0
- package/src/components/ui/theme-toggle.tsx +185 -0
- package/src/components/ui/theme.tsx +148 -0
- package/src/components/ui/toggle-group.tsx +196 -0
- package/src/components/ui/toggle.tsx +115 -0
- package/src/components/ui/tooltip.tsx +253 -0
- package/src/components/ui/typography.tsx +468 -0
- package/src/hooks/use-mobile.ts +91 -0
- package/src/hooks/use-theme.ts +319 -0
- package/src/index.ts +77 -0
- package/src/lib/utils.ts +57 -0
- package/src/styles/globals.css +160 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ProgressPrimitive from "@radix-ui/react-progress";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Progress component displays completion progress of tasks and operations
|
|
8
|
+
*
|
|
9
|
+
* A visual progress indicator built on Radix UI primitives that shows the
|
|
10
|
+
* completion state of tasks, file uploads, multi-step processes, and other
|
|
11
|
+
* operations requiring user feedback about progress status.
|
|
12
|
+
*
|
|
13
|
+
* @example Basic usage
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Progress value={60} />
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @example With label and percentage
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <div className="space-y-2">
|
|
21
|
+
* <div className="flex justify-between text-sm">
|
|
22
|
+
* <span>Loading data...</span>
|
|
23
|
+
* <span>{progress}%</span>
|
|
24
|
+
* </div>
|
|
25
|
+
* <Progress value={progress} />
|
|
26
|
+
* </div>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example File upload progress
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <div className="space-y-2">
|
|
32
|
+
* <Progress value={uploadProgress} />
|
|
33
|
+
* <p className="text-sm text-muted-foreground">
|
|
34
|
+
* {uploadProgress}% of 2.4 MB uploaded
|
|
35
|
+
* </p>
|
|
36
|
+
* </div>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example Custom height and colors
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <Progress
|
|
42
|
+
* value={85}
|
|
43
|
+
* className="h-4 [&>div]:bg-green-500"
|
|
44
|
+
* />
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Multi-step process
|
|
48
|
+
* ```tsx
|
|
49
|
+
* const stepProgress = (currentStep / totalSteps) * 100;
|
|
50
|
+
* <Progress value={stepProgress} />
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @param value - Progress value from 0 to 100. Undefined shows no progress.
|
|
54
|
+
* @param className - Additional CSS classes for styling customization
|
|
55
|
+
*
|
|
56
|
+
* @accessibility
|
|
57
|
+
* - Built on Radix UI Progress primitive with proper ARIA attributes
|
|
58
|
+
* - Announces progress changes to screen readers
|
|
59
|
+
* - Supports custom aria-label and aria-valuetext for enhanced descriptions
|
|
60
|
+
* - Smooth visual transitions provide clear feedback
|
|
61
|
+
*
|
|
62
|
+
* @see {@link https://ui.shadcn.com/docs/components/progress} for design patterns
|
|
63
|
+
* @since 1.0.0
|
|
64
|
+
*/
|
|
65
|
+
function Progress({
|
|
66
|
+
className,
|
|
67
|
+
value,
|
|
68
|
+
...props
|
|
69
|
+
}: React.ComponentProps<typeof ProgressPrimitive.Root>) {
|
|
70
|
+
return (
|
|
71
|
+
<ProgressPrimitive.Root
|
|
72
|
+
data-slot="progress"
|
|
73
|
+
className={cn(
|
|
74
|
+
"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
|
|
75
|
+
className,
|
|
76
|
+
)}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
<ProgressPrimitive.Indicator
|
|
80
|
+
data-slot="progress-indicator"
|
|
81
|
+
className="bg-primary h-full w-full flex-1 transition-all"
|
|
82
|
+
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
83
|
+
/>
|
|
84
|
+
</ProgressPrimitive.Root>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { Progress };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
5
|
+
import { CircleIcon } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A radio group component for single selection from multiple options
|
|
11
|
+
*
|
|
12
|
+
* RadioGroup allows users to select exactly one option from a set of mutually exclusive choices.
|
|
13
|
+
* Built on Radix UI primitives with custom styling that follows shadcn/ui design patterns.
|
|
14
|
+
* Each radio group should contain RadioGroupItem components paired with Labels for accessibility.
|
|
15
|
+
*
|
|
16
|
+
* @example Basic usage
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <RadioGroup defaultValue="option-one">
|
|
19
|
+
* <div className="flex items-center space-x-2">
|
|
20
|
+
* <RadioGroupItem value="option-one" id="option-one" />
|
|
21
|
+
* <Label htmlFor="option-one">Option One</Label>
|
|
22
|
+
* </div>
|
|
23
|
+
* <div className="flex items-center space-x-2">
|
|
24
|
+
* <RadioGroupItem value="option-two" id="option-two" />
|
|
25
|
+
* <Label htmlFor="option-two">Option Two</Label>
|
|
26
|
+
* </div>
|
|
27
|
+
* </RadioGroup>
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Controlled radio group
|
|
31
|
+
* ```tsx
|
|
32
|
+
* function SizeSelector() {
|
|
33
|
+
* const [size, setSize] = useState("medium");
|
|
34
|
+
*
|
|
35
|
+
* return (
|
|
36
|
+
* <RadioGroup value={size} onValueChange={setSize}>
|
|
37
|
+
* <div className="flex items-center space-x-2">
|
|
38
|
+
* <RadioGroupItem value="small" id="size-small" />
|
|
39
|
+
* <Label htmlFor="size-small">Small</Label>
|
|
40
|
+
* </div>
|
|
41
|
+
* <div className="flex items-center space-x-2">
|
|
42
|
+
* <RadioGroupItem value="medium" id="size-medium" />
|
|
43
|
+
* <Label htmlFor="size-medium">Medium</Label>
|
|
44
|
+
* </div>
|
|
45
|
+
* <div className="flex items-center space-x-2">
|
|
46
|
+
* <RadioGroupItem value="large" id="size-large" />
|
|
47
|
+
* <Label htmlFor="size-large">Large</Label>
|
|
48
|
+
* </div>
|
|
49
|
+
* </RadioGroup>
|
|
50
|
+
* );
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example Horizontal layout
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <RadioGroup defaultValue="option-one" className="flex gap-4">
|
|
57
|
+
* <div className="flex items-center space-x-2">
|
|
58
|
+
* <RadioGroupItem value="option-one" id="r1" />
|
|
59
|
+
* <Label htmlFor="r1">Option One</Label>
|
|
60
|
+
* </div>
|
|
61
|
+
* <div className="flex items-center space-x-2">
|
|
62
|
+
* <RadioGroupItem value="option-two" id="r2" />
|
|
63
|
+
* <Label htmlFor="r2">Option Two</Label>
|
|
64
|
+
* </div>
|
|
65
|
+
* </RadioGroup>
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example With descriptions
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <RadioGroup defaultValue="card">
|
|
71
|
+
* <div className="flex items-start space-x-2">
|
|
72
|
+
* <RadioGroupItem value="card" id="card" className="mt-1" />
|
|
73
|
+
* <div className="grid gap-1">
|
|
74
|
+
* <Label htmlFor="card">Credit Card</Label>
|
|
75
|
+
* <p className="text-sm text-muted-foreground">
|
|
76
|
+
* Pay with your credit or debit card
|
|
77
|
+
* </p>
|
|
78
|
+
* </div>
|
|
79
|
+
* </div>
|
|
80
|
+
* </RadioGroup>
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @param defaultValue - The default selected value when uncontrolled
|
|
84
|
+
* @param value - The controlled value of the radio group
|
|
85
|
+
* @param onValueChange - Callback fired when the value changes
|
|
86
|
+
* @param disabled - Whether the entire radio group is disabled
|
|
87
|
+
* @param required - Whether the radio group is required for form validation
|
|
88
|
+
* @param orientation - The orientation of the radio group (defaults to vertical)
|
|
89
|
+
* @param className - Additional CSS classes to apply to the radio group
|
|
90
|
+
* @param children - RadioGroupItem components and their associated labels
|
|
91
|
+
*
|
|
92
|
+
* @see {@link https://ui.shadcn.com/docs/components/radio-group} for design patterns
|
|
93
|
+
* @since 1.0.0
|
|
94
|
+
* @see {@link RadioGroupItem} for individual radio options
|
|
95
|
+
* @see {@link Checkbox} for multiple selection use cases
|
|
96
|
+
* @see {@link Select} for dropdown-style single selection
|
|
97
|
+
*/
|
|
98
|
+
function RadioGroup({
|
|
99
|
+
className,
|
|
100
|
+
...props
|
|
101
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
|
|
102
|
+
return (
|
|
103
|
+
<RadioGroupPrimitive.Root
|
|
104
|
+
data-slot="radio-group"
|
|
105
|
+
className={cn("grid gap-3", className)}
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Individual radio button item for use within RadioGroup
|
|
113
|
+
*
|
|
114
|
+
* RadioGroupItem represents a single selectable option in a radio group.
|
|
115
|
+
* Must be used within a RadioGroup component and paired with a Label for accessibility.
|
|
116
|
+
* The component automatically handles visual states including checked, unchecked, focused, and disabled.
|
|
117
|
+
*
|
|
118
|
+
* @example Basic usage
|
|
119
|
+
* ```tsx
|
|
120
|
+
* <RadioGroupItem value="option-one" id="option-one" />
|
|
121
|
+
* <Label htmlFor="option-one">Option One</Label>
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @example With custom styling
|
|
125
|
+
* ```tsx
|
|
126
|
+
* <RadioGroupItem
|
|
127
|
+
* value="premium"
|
|
128
|
+
* id="premium"
|
|
129
|
+
* className="border-purple-500 text-purple-500"
|
|
130
|
+
* />
|
|
131
|
+
* <Label htmlFor="premium">Premium Plan</Label>
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @example Disabled state
|
|
135
|
+
* ```tsx
|
|
136
|
+
* <RadioGroupItem value="unavailable" id="unavailable" disabled />
|
|
137
|
+
* <Label htmlFor="unavailable" className="opacity-50">
|
|
138
|
+
* Unavailable Option
|
|
139
|
+
* </Label>
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @param value - The unique value for this radio option
|
|
143
|
+
* @param id - The id attribute for accessibility (should match Label's htmlFor)
|
|
144
|
+
* @param disabled - Whether this specific radio option is disabled
|
|
145
|
+
* @param className - Additional CSS classes for custom styling
|
|
146
|
+
* @param ref - React ref forwarded to the underlying input element
|
|
147
|
+
*
|
|
148
|
+
* @accessibility
|
|
149
|
+
* - Automatically receives focus management from parent RadioGroup
|
|
150
|
+
* - Arrow keys navigate between radio options
|
|
151
|
+
* - Space key toggles selection
|
|
152
|
+
* - Screen readers announce checked/unchecked state
|
|
153
|
+
* - Focus visible indicator for keyboard navigation
|
|
154
|
+
* - Proper ARIA attributes and roles
|
|
155
|
+
*
|
|
156
|
+
* @see {@link RadioGroup} for the parent container component
|
|
157
|
+
* @see {@link https://ui.shadcn.com/docs/components/radio-group} for usage patterns
|
|
158
|
+
* @since 1.0.0
|
|
159
|
+
*/
|
|
160
|
+
function RadioGroupItem({
|
|
161
|
+
className,
|
|
162
|
+
...props
|
|
163
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
|
|
164
|
+
return (
|
|
165
|
+
<RadioGroupPrimitive.Item
|
|
166
|
+
data-slot="radio-group-item"
|
|
167
|
+
className={cn(
|
|
168
|
+
"border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
169
|
+
className,
|
|
170
|
+
)}
|
|
171
|
+
{...props}
|
|
172
|
+
>
|
|
173
|
+
<RadioGroupPrimitive.Indicator
|
|
174
|
+
data-slot="radio-group-indicator"
|
|
175
|
+
className="relative flex items-center justify-center"
|
|
176
|
+
>
|
|
177
|
+
<CircleIcon className="fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" />
|
|
178
|
+
</RadioGroupPrimitive.Indicator>
|
|
179
|
+
</RadioGroupPrimitive.Item>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export { RadioGroup, RadioGroupItem };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { GripVerticalIcon } from "lucide-react";
|
|
3
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Container for creating resizable panel groups with keyboard accessibility
|
|
9
|
+
*
|
|
10
|
+
* ResizablePanelGroup provides a flexible container for organizing multiple resizable panels.
|
|
11
|
+
* Panels can be resized by dragging handles between them, with full keyboard support.
|
|
12
|
+
* Built on top of react-resizable-panels with enhanced styling and accessibility features.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Basic horizontal layout
|
|
17
|
+
* <ResizablePanelGroup direction="horizontal" className="h-full">
|
|
18
|
+
* <ResizablePanel defaultSize={50}>
|
|
19
|
+
* <div className="p-4">Left panel</div>
|
|
20
|
+
* </ResizablePanel>
|
|
21
|
+
* <ResizableHandle />
|
|
22
|
+
* <ResizablePanel defaultSize={50}>
|
|
23
|
+
* <div className="p-4">Right panel</div>
|
|
24
|
+
* </ResizablePanel>
|
|
25
|
+
* </ResizablePanelGroup>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Vertical layout with handle
|
|
31
|
+
* <ResizablePanelGroup direction="vertical" className="min-h-[400px]">
|
|
32
|
+
* <ResizablePanel defaultSize={30}>
|
|
33
|
+
* <header>Header content</header>
|
|
34
|
+
* </ResizablePanel>
|
|
35
|
+
* <ResizableHandle withHandle />
|
|
36
|
+
* <ResizablePanel defaultSize={70}>
|
|
37
|
+
* <main>Main content</main>
|
|
38
|
+
* </ResizablePanel>
|
|
39
|
+
* </ResizablePanelGroup>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* // Complex layout with size constraints
|
|
45
|
+
* <ResizablePanelGroup direction="horizontal">
|
|
46
|
+
* <ResizablePanel defaultSize={25} minSize={20} maxSize={40}>
|
|
47
|
+
* <nav>Sidebar (20-40%)</nav>
|
|
48
|
+
* </ResizablePanel>
|
|
49
|
+
* <ResizableHandle withHandle />
|
|
50
|
+
* <ResizablePanel defaultSize={75} minSize={60}>
|
|
51
|
+
* <main>Content (min 60%)</main>
|
|
52
|
+
* </ResizablePanel>
|
|
53
|
+
* </ResizablePanelGroup>
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @param direction - Layout direction: "horizontal" or "vertical"
|
|
57
|
+
* @param className - Additional CSS classes
|
|
58
|
+
* @param children - ResizablePanel and ResizableHandle components
|
|
59
|
+
*
|
|
60
|
+
* @accessibility
|
|
61
|
+
* - Full keyboard navigation with arrow keys when handles are focused
|
|
62
|
+
* - Screen reader support with proper ARIA labels
|
|
63
|
+
* - Respects prefers-reduced-motion for users with motion sensitivity
|
|
64
|
+
* - Maintains focus management during resize operations
|
|
65
|
+
*
|
|
66
|
+
* @see {@link https://ui.shadcn.com/docs/components/resizable} for design patterns
|
|
67
|
+
* @since 1.0.0
|
|
68
|
+
* @see {@link ResizablePanel} for individual panel configuration
|
|
69
|
+
* @see {@link ResizableHandle} for handle customization options
|
|
70
|
+
*/
|
|
71
|
+
function ResizablePanelGroup({
|
|
72
|
+
className,
|
|
73
|
+
...props
|
|
74
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {
|
|
75
|
+
return (
|
|
76
|
+
<ResizablePrimitive.PanelGroup
|
|
77
|
+
data-slot="resizable-panel-group"
|
|
78
|
+
className={cn(
|
|
79
|
+
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
|
80
|
+
className,
|
|
81
|
+
)}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Individual resizable panel within a panel group
|
|
89
|
+
*
|
|
90
|
+
* ResizablePanel represents a single section that can be resized within a ResizablePanelGroup.
|
|
91
|
+
* Supports size constraints, default sizing, and programmatic control. Each panel automatically
|
|
92
|
+
* handles overflow and maintains content accessibility during resize operations.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```tsx
|
|
96
|
+
* // Basic panel with default size
|
|
97
|
+
* <ResizablePanel defaultSize={50}>
|
|
98
|
+
* <div className="p-4">Panel content</div>
|
|
99
|
+
* </ResizablePanel>
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```tsx
|
|
104
|
+
* // Panel with size constraints
|
|
105
|
+
* <ResizablePanel
|
|
106
|
+
* defaultSize={30}
|
|
107
|
+
* minSize={20}
|
|
108
|
+
* maxSize={60}
|
|
109
|
+
* collapsible
|
|
110
|
+
* >
|
|
111
|
+
* <aside>Collapsible sidebar</aside>
|
|
112
|
+
* </ResizablePanel>
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @param defaultSize - Initial size as percentage (0-100)
|
|
116
|
+
* @param minSize - Minimum size as percentage
|
|
117
|
+
* @param maxSize - Maximum size as percentage
|
|
118
|
+
* @param collapsible - Whether panel can be collapsed to zero size
|
|
119
|
+
* @param order - Display order within the group
|
|
120
|
+
* @param id - Unique identifier for programmatic control
|
|
121
|
+
* @param onCollapse - Callback when panel is collapsed
|
|
122
|
+
* @param onExpand - Callback when panel is expanded
|
|
123
|
+
* @param onResize - Callback when panel size changes
|
|
124
|
+
*
|
|
125
|
+
* @accessibility
|
|
126
|
+
* - Maintains focus within panel during resize
|
|
127
|
+
* - Preserves scroll position when possible
|
|
128
|
+
* - Announces size changes to screen readers when significant
|
|
129
|
+
*/
|
|
130
|
+
function ResizablePanel({
|
|
131
|
+
...props
|
|
132
|
+
}: React.ComponentProps<typeof ResizablePrimitive.Panel>) {
|
|
133
|
+
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Draggable handle for resizing panels with optional visual indicator
|
|
138
|
+
*
|
|
139
|
+
* ResizableHandle provides the interactive area between panels that allows users to
|
|
140
|
+
* resize them via mouse, touch, or keyboard. The handle can display an optional
|
|
141
|
+
* visual grip indicator for improved usability and accessibility.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```tsx
|
|
145
|
+
* // Basic invisible handle
|
|
146
|
+
* <ResizableHandle />
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```tsx
|
|
151
|
+
* // Handle with visual grip indicator
|
|
152
|
+
* <ResizableHandle withHandle />
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```tsx
|
|
157
|
+
* // Custom styled handle
|
|
158
|
+
* <ResizableHandle
|
|
159
|
+
* withHandle
|
|
160
|
+
* className="bg-blue-200 hover:bg-blue-300"
|
|
161
|
+
* />
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @param withHandle - Whether to display visual grip indicator
|
|
165
|
+
* @param className - Additional CSS classes for styling
|
|
166
|
+
* @param disabled - Whether the handle is disabled
|
|
167
|
+
* @param hitAreaMargins - Margins around the hit area for easier interaction
|
|
168
|
+
* @param onDragging - Callback during drag operations
|
|
169
|
+
*
|
|
170
|
+
* @accessibility
|
|
171
|
+
* - Keyboard resizable using arrow keys when focused
|
|
172
|
+
* - Proper ARIA roles and labels for screen readers
|
|
173
|
+
* - Focus indicators that meet WCAG contrast requirements
|
|
174
|
+
* - Touch-friendly hit area of at least 44x44px
|
|
175
|
+
* - Announces resize actions and current sizes to assistive technology
|
|
176
|
+
*
|
|
177
|
+
* @see {@link https://ui.shadcn.com/docs/components/resizable} for usage examples
|
|
178
|
+
* @since 1.0.0
|
|
179
|
+
*/
|
|
180
|
+
function ResizableHandle({
|
|
181
|
+
withHandle,
|
|
182
|
+
className,
|
|
183
|
+
...props
|
|
184
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
|
185
|
+
/**
|
|
186
|
+
* Whether to show a visual grip handle
|
|
187
|
+
* @default false
|
|
188
|
+
*/
|
|
189
|
+
withHandle?: boolean;
|
|
190
|
+
}) {
|
|
191
|
+
return (
|
|
192
|
+
<ResizablePrimitive.PanelResizeHandle
|
|
193
|
+
data-slot="resizable-handle"
|
|
194
|
+
className={cn(
|
|
195
|
+
"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
|
196
|
+
className,
|
|
197
|
+
)}
|
|
198
|
+
{...props}
|
|
199
|
+
>
|
|
200
|
+
{withHandle && (
|
|
201
|
+
<div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
|
|
202
|
+
<GripVerticalIcon className="size-2.5" />
|
|
203
|
+
</div>
|
|
204
|
+
)}
|
|
205
|
+
</ResizablePrimitive.PanelResizeHandle>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ScrollArea component provides cross-browser custom scrollbar styling
|
|
8
|
+
*
|
|
9
|
+
* Augments native scroll functionality for custom, cross-browser styling with enhanced
|
|
10
|
+
* scrolling experience. Built on Radix UI's ScrollArea primitive for accessibility
|
|
11
|
+
* and keyboard navigation support. Provides consistent scrollbar appearance across
|
|
12
|
+
* different browsers while maintaining native scroll behavior.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Basic vertical scrollable area
|
|
17
|
+
* <ScrollArea className="h-72 w-48 rounded-md border">
|
|
18
|
+
* <div className="p-4">
|
|
19
|
+
* {items.map((item) => (
|
|
20
|
+
* <div key={item.id} className="mb-4">
|
|
21
|
+
* {item.content}
|
|
22
|
+
* </div>
|
|
23
|
+
* ))}
|
|
24
|
+
* </div>
|
|
25
|
+
* </ScrollArea>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Horizontal scrolling with custom scrollbar
|
|
31
|
+
* <ScrollArea className="w-full whitespace-nowrap rounded-md border">
|
|
32
|
+
* <div className="flex gap-4 p-4">
|
|
33
|
+
* {cards.map((card) => (
|
|
34
|
+
* <div key={card.id} className="w-64 flex-none">
|
|
35
|
+
* {card.content}
|
|
36
|
+
* </div>
|
|
37
|
+
* ))}
|
|
38
|
+
* </div>
|
|
39
|
+
* <ScrollBar orientation="horizontal" />
|
|
40
|
+
* </ScrollArea>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* // Both scrollbars for large content
|
|
46
|
+
* <ScrollArea className="h-96 w-80 rounded-md border">
|
|
47
|
+
* <div className="w-[600px] p-4">
|
|
48
|
+
* // Wide content with vertical overflow
|
|
49
|
+
* </div>
|
|
50
|
+
* <ScrollBar orientation="horizontal" />
|
|
51
|
+
* </ScrollArea>
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @param className - Additional CSS classes for styling
|
|
55
|
+
* @param children - Content to be rendered inside the scrollable area
|
|
56
|
+
*
|
|
57
|
+
* @see {@link https://ui.shadcn.com/docs/components/scroll-area} - shadcn/ui ScrollArea documentation
|
|
58
|
+
* @since 1.0.0
|
|
59
|
+
* @see {@link ScrollBar} - Companion scrollbar component for horizontal scrolling
|
|
60
|
+
*/
|
|
61
|
+
function ScrollArea({
|
|
62
|
+
className,
|
|
63
|
+
children,
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
|
66
|
+
return (
|
|
67
|
+
<ScrollAreaPrimitive.Root
|
|
68
|
+
data-slot="scroll-area"
|
|
69
|
+
className={cn("relative", className)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
<ScrollAreaPrimitive.Viewport
|
|
73
|
+
data-slot="scroll-area-viewport"
|
|
74
|
+
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
</ScrollAreaPrimitive.Viewport>
|
|
78
|
+
<ScrollBar />
|
|
79
|
+
<ScrollAreaPrimitive.Corner />
|
|
80
|
+
</ScrollAreaPrimitive.Root>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* ScrollBar component for custom scrollbar styling
|
|
86
|
+
*
|
|
87
|
+
* Companion component to ScrollArea that renders styled scrollbars with
|
|
88
|
+
* support for both vertical and horizontal orientations. Usually used
|
|
89
|
+
* when explicit horizontal scrolling is needed.
|
|
90
|
+
*
|
|
91
|
+
* @param className - Additional CSS classes for scrollbar styling
|
|
92
|
+
* @param orientation - Scrollbar orientation, defaults to "vertical"
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```tsx
|
|
96
|
+
* // Horizontal scrollbar (vertical is automatic)
|
|
97
|
+
* <ScrollArea className="w-full">
|
|
98
|
+
* <div className="flex gap-4 p-4">
|
|
99
|
+
* // Wide content
|
|
100
|
+
* </div>
|
|
101
|
+
* <ScrollBar orientation="horizontal" />
|
|
102
|
+
* </ScrollArea>
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function ScrollBar({
|
|
106
|
+
className,
|
|
107
|
+
orientation = "vertical",
|
|
108
|
+
...props
|
|
109
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
110
|
+
return (
|
|
111
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
112
|
+
data-slot="scroll-area-scrollbar"
|
|
113
|
+
orientation={orientation}
|
|
114
|
+
className={cn(
|
|
115
|
+
"flex touch-none p-px transition-colors select-none",
|
|
116
|
+
orientation === "vertical" &&
|
|
117
|
+
"h-full w-2.5 border-l border-l-transparent",
|
|
118
|
+
orientation === "horizontal" &&
|
|
119
|
+
"h-2.5 flex-col border-t border-t-transparent",
|
|
120
|
+
className,
|
|
121
|
+
)}
|
|
122
|
+
{...props}
|
|
123
|
+
>
|
|
124
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
|
125
|
+
data-slot="scroll-area-thumb"
|
|
126
|
+
className="bg-border relative flex-1 rounded-full"
|
|
127
|
+
/>
|
|
128
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { ScrollArea, ScrollBar };
|