@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,433 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { cn } from "../../../lib/utils";
|
|
3
|
+
import { Theme } from "../theme";
|
|
4
|
+
import {
|
|
5
|
+
Card,
|
|
6
|
+
CardContent,
|
|
7
|
+
CardDescription,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
} from "../card";
|
|
11
|
+
import { Badge } from "../badge";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The cn utility function combines class names with Tailwind CSS conflict resolution.
|
|
15
|
+
* It uses clsx for conditional class handling and tailwind-merge to ensure later classes
|
|
16
|
+
* override earlier ones when they conflict.
|
|
17
|
+
*/
|
|
18
|
+
const meta: Meta = {
|
|
19
|
+
title: "Utilities/cn",
|
|
20
|
+
parameters: {
|
|
21
|
+
layout: "padded",
|
|
22
|
+
docs: {
|
|
23
|
+
description: {
|
|
24
|
+
component: `
|
|
25
|
+
The **cn** utility function is a powerful class name combiner that handles Tailwind CSS class conflicts intelligently.
|
|
26
|
+
|
|
27
|
+
**Key Features:**
|
|
28
|
+
- 🎯 **Smart conflict resolution** - Later Tailwind classes override earlier ones
|
|
29
|
+
- 🔄 **Conditional classes** - Supports boolean, object, and array syntax
|
|
30
|
+
- ⚡ **Performance optimized** - Uses clsx and tailwind-merge under the hood
|
|
31
|
+
- 🎨 **Custom class support** - Extended with custom Tailwind classes
|
|
32
|
+
- 💪 **Type safe** - Full TypeScript support with ClassValue types
|
|
33
|
+
|
|
34
|
+
**Usage:**
|
|
35
|
+
\`\`\`tsx
|
|
36
|
+
import { cn } from "@neynar/ui";
|
|
37
|
+
|
|
38
|
+
// Basic combining
|
|
39
|
+
cn("px-4 py-2", "bg-blue-500", "text-white")
|
|
40
|
+
|
|
41
|
+
// Conditional classes
|
|
42
|
+
cn(
|
|
43
|
+
"base-class",
|
|
44
|
+
isActive && "active-class",
|
|
45
|
+
isDisabled && "disabled-class"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
// Conflict resolution
|
|
49
|
+
cn("px-4", "px-2") // Returns: "px-2" (later wins)
|
|
50
|
+
cn("text-red-500", "text-blue-500") // Returns: "text-blue-500"
|
|
51
|
+
\`\`\`
|
|
52
|
+
`,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
tags: ["autodocs"],
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default meta;
|
|
60
|
+
type Story = StoryObj;
|
|
61
|
+
|
|
62
|
+
// Demo component to show cn usage
|
|
63
|
+
function CnDemo() {
|
|
64
|
+
const examples = [
|
|
65
|
+
{
|
|
66
|
+
title: "Basic Combining",
|
|
67
|
+
code: `cn("px-4 py-2", "bg-blue-500", "text-white")`,
|
|
68
|
+
result: cn("px-4 py-2", "bg-blue-500", "text-white"),
|
|
69
|
+
description: "Combines multiple class strings into one",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: "Conflict Resolution",
|
|
73
|
+
code: `cn("px-4", "px-2")`,
|
|
74
|
+
result: cn("px-4", "px-2"),
|
|
75
|
+
description: "Later padding class (px-2) overrides earlier one (px-4)",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
title: "Color Conflicts",
|
|
79
|
+
code: `cn("text-red-500", "text-blue-500", "text-green-500")`,
|
|
80
|
+
result: cn("text-red-500", "text-blue-500", "text-green-500"),
|
|
81
|
+
description: "Last color class wins (text-green-500)",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: "Conditional Classes",
|
|
85
|
+
code: `cn("base", true && "active", false && "disabled")`,
|
|
86
|
+
result: cn("base", "active", "disabled"),
|
|
87
|
+
description: "Only truthy conditions are included",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
title: "Object Syntax",
|
|
91
|
+
code: `cn({ "font-bold": true, "italic": false, "underline": true })`,
|
|
92
|
+
result: cn({ "font-bold": true, italic: false, underline: true }),
|
|
93
|
+
description: "Object keys with truthy values are included",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
title: "Complex Example",
|
|
97
|
+
code: `cn("btn", "px-4 py-2", isActive && "bg-blue-500", !isActive && "bg-gray-500")`,
|
|
98
|
+
result: cn("btn", "px-4 py-2", "bg-blue-500", "bg-gray-500"),
|
|
99
|
+
description: "Real-world component styling with conditions",
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div className="space-y-6">
|
|
105
|
+
<Theme />
|
|
106
|
+
|
|
107
|
+
<Card>
|
|
108
|
+
<CardHeader>
|
|
109
|
+
<CardTitle className="text-sm font-medium">
|
|
110
|
+
Interactive Examples
|
|
111
|
+
</CardTitle>
|
|
112
|
+
<CardDescription>
|
|
113
|
+
Live demonstrations of cn utility function behavior
|
|
114
|
+
</CardDescription>
|
|
115
|
+
</CardHeader>
|
|
116
|
+
<CardContent className="space-y-6">
|
|
117
|
+
{examples.map((example, index) => (
|
|
118
|
+
<div key={index} className="space-y-3">
|
|
119
|
+
<div className="flex items-center gap-2">
|
|
120
|
+
<Badge variant="outline" className="text-xs">
|
|
121
|
+
{example.title}
|
|
122
|
+
</Badge>
|
|
123
|
+
<span className="text-sm text-muted-foreground">
|
|
124
|
+
{example.description}
|
|
125
|
+
</span>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
129
|
+
<div className="space-y-2">
|
|
130
|
+
<div className="text-xs text-muted-foreground font-medium">
|
|
131
|
+
Code
|
|
132
|
+
</div>
|
|
133
|
+
<pre className="text-xs bg-muted p-3 rounded overflow-x-auto">
|
|
134
|
+
{example.code}
|
|
135
|
+
</pre>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div className="space-y-2">
|
|
139
|
+
<div className="text-xs text-muted-foreground font-medium">
|
|
140
|
+
Result
|
|
141
|
+
</div>
|
|
142
|
+
<div className="bg-muted p-3 rounded">
|
|
143
|
+
<code className="text-xs break-all">
|
|
144
|
+
"{example.result}"
|
|
145
|
+
</code>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
))}
|
|
151
|
+
</CardContent>
|
|
152
|
+
</Card>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Interactive demonstration of the cn utility function showing class combining and conflict resolution.
|
|
159
|
+
* Explore how cn handles different class combinations and Tailwind CSS conflicts.
|
|
160
|
+
*/
|
|
161
|
+
export const Interactive: Story = {
|
|
162
|
+
render: () => <CnDemo />,
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Common usage patterns showing how cn is used in real component development.
|
|
167
|
+
*/
|
|
168
|
+
export const UsagePatterns: Story = {
|
|
169
|
+
render: () => (
|
|
170
|
+
<div className="space-y-6">
|
|
171
|
+
<Theme />
|
|
172
|
+
|
|
173
|
+
<div className="grid gap-6 md:grid-cols-2">
|
|
174
|
+
{/* Pattern 1: Component Variants */}
|
|
175
|
+
<Card>
|
|
176
|
+
<CardHeader>
|
|
177
|
+
<CardTitle className="text-sm font-medium">
|
|
178
|
+
Component Variants
|
|
179
|
+
</CardTitle>
|
|
180
|
+
<CardDescription>
|
|
181
|
+
Using cn to create button variants
|
|
182
|
+
</CardDescription>
|
|
183
|
+
</CardHeader>
|
|
184
|
+
<CardContent>
|
|
185
|
+
<ComponentVariantExample />
|
|
186
|
+
<pre className="text-xs bg-muted p-3 rounded mt-4 overflow-x-auto">
|
|
187
|
+
{`function Button({ variant, size, className, ...props }) {
|
|
188
|
+
return (
|
|
189
|
+
<button
|
|
190
|
+
className={cn(
|
|
191
|
+
"inline-flex items-center justify-center",
|
|
192
|
+
"rounded-md font-medium transition-colors",
|
|
193
|
+
{
|
|
194
|
+
"bg-primary text-primary-foreground": variant === "default",
|
|
195
|
+
"border border-input bg-background": variant === "outline",
|
|
196
|
+
"bg-secondary text-secondary-foreground": variant === "secondary",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"h-10 px-4 py-2": size === "default",
|
|
200
|
+
"h-9 rounded-md px-3": size === "sm",
|
|
201
|
+
"h-11 rounded-md px-8": size === "lg",
|
|
202
|
+
},
|
|
203
|
+
className
|
|
204
|
+
)}
|
|
205
|
+
{...props}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
}`}
|
|
209
|
+
</pre>
|
|
210
|
+
</CardContent>
|
|
211
|
+
</Card>
|
|
212
|
+
|
|
213
|
+
{/* Pattern 2: Conditional Styling */}
|
|
214
|
+
<Card>
|
|
215
|
+
<CardHeader>
|
|
216
|
+
<CardTitle className="text-sm font-medium">
|
|
217
|
+
Conditional Styling
|
|
218
|
+
</CardTitle>
|
|
219
|
+
<CardDescription>State-based class application</CardDescription>
|
|
220
|
+
</CardHeader>
|
|
221
|
+
<CardContent>
|
|
222
|
+
<ConditionalStylingExample />
|
|
223
|
+
<pre className="text-xs bg-muted p-3 rounded mt-4 overflow-x-auto">
|
|
224
|
+
{`function Card({ isActive, isDisabled, className }) {
|
|
225
|
+
return (
|
|
226
|
+
<div
|
|
227
|
+
className={cn(
|
|
228
|
+
"border rounded-lg p-4",
|
|
229
|
+
"transition-all duration-200",
|
|
230
|
+
isActive && "border-primary bg-primary/5",
|
|
231
|
+
isDisabled && "opacity-50 cursor-not-allowed",
|
|
232
|
+
!isDisabled && "hover:shadow-md",
|
|
233
|
+
className
|
|
234
|
+
)}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}`}
|
|
238
|
+
</pre>
|
|
239
|
+
</CardContent>
|
|
240
|
+
</Card>
|
|
241
|
+
|
|
242
|
+
{/* Pattern 3: Responsive Design */}
|
|
243
|
+
<Card>
|
|
244
|
+
<CardHeader>
|
|
245
|
+
<CardTitle className="text-sm font-medium">
|
|
246
|
+
Responsive Classes
|
|
247
|
+
</CardTitle>
|
|
248
|
+
<CardDescription>Combining responsive utilities</CardDescription>
|
|
249
|
+
</CardHeader>
|
|
250
|
+
<CardContent>
|
|
251
|
+
<ResponsiveExample />
|
|
252
|
+
<pre className="text-xs bg-muted p-3 rounded mt-4 overflow-x-auto">
|
|
253
|
+
{`function ResponsiveGrid({ columns, className }) {
|
|
254
|
+
return (
|
|
255
|
+
<div
|
|
256
|
+
className={cn(
|
|
257
|
+
"grid gap-4",
|
|
258
|
+
{
|
|
259
|
+
"grid-cols-1": columns === 1,
|
|
260
|
+
"grid-cols-1 md:grid-cols-2": columns === 2,
|
|
261
|
+
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3": columns === 3,
|
|
262
|
+
},
|
|
263
|
+
"sm:gap-6 lg:gap-8",
|
|
264
|
+
className
|
|
265
|
+
)}
|
|
266
|
+
/>
|
|
267
|
+
);
|
|
268
|
+
}`}
|
|
269
|
+
</pre>
|
|
270
|
+
</CardContent>
|
|
271
|
+
</Card>
|
|
272
|
+
|
|
273
|
+
{/* Pattern 4: Override Protection */}
|
|
274
|
+
<Card>
|
|
275
|
+
<CardHeader>
|
|
276
|
+
<CardTitle className="text-sm font-medium">
|
|
277
|
+
Safe Overrides
|
|
278
|
+
</CardTitle>
|
|
279
|
+
<CardDescription>Allowing prop-based customization</CardDescription>
|
|
280
|
+
</CardHeader>
|
|
281
|
+
<CardContent>
|
|
282
|
+
<OverrideExample />
|
|
283
|
+
<pre className="text-xs bg-muted p-3 rounded mt-4 overflow-x-auto">
|
|
284
|
+
{`function Alert({ variant, className }) {
|
|
285
|
+
return (
|
|
286
|
+
<div
|
|
287
|
+
className={cn(
|
|
288
|
+
// Base styles
|
|
289
|
+
"relative w-full rounded-lg border p-4",
|
|
290
|
+
"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
|
|
291
|
+
// Variant styles (can be overridden)
|
|
292
|
+
{
|
|
293
|
+
"bg-background text-foreground": variant === "default",
|
|
294
|
+
"border-destructive/50 text-destructive": variant === "destructive",
|
|
295
|
+
},
|
|
296
|
+
// User overrides come last
|
|
297
|
+
className
|
|
298
|
+
)}
|
|
299
|
+
/>
|
|
300
|
+
);
|
|
301
|
+
}`}
|
|
302
|
+
</pre>
|
|
303
|
+
</CardContent>
|
|
304
|
+
</Card>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
),
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// Helper components for the examples
|
|
311
|
+
function ComponentVariantExample() {
|
|
312
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
313
|
+
const Button = ({ variant, size, className, children, ...props }: any) => (
|
|
314
|
+
<button
|
|
315
|
+
className={cn(
|
|
316
|
+
"inline-flex items-center justify-center",
|
|
317
|
+
"rounded-md font-medium transition-colors",
|
|
318
|
+
{
|
|
319
|
+
"bg-primary text-primary-foreground hover:bg-primary/90":
|
|
320
|
+
variant === "default",
|
|
321
|
+
"border border-input bg-background hover:bg-accent":
|
|
322
|
+
variant === "outline",
|
|
323
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80":
|
|
324
|
+
variant === "secondary",
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"h-10 px-4 py-2 text-sm": size === "default",
|
|
328
|
+
"h-9 rounded-md px-3 text-xs": size === "sm",
|
|
329
|
+
"h-11 rounded-md px-8": size === "lg",
|
|
330
|
+
},
|
|
331
|
+
className,
|
|
332
|
+
)}
|
|
333
|
+
{...props}
|
|
334
|
+
>
|
|
335
|
+
{children}
|
|
336
|
+
</button>
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<div className="flex flex-wrap gap-2">
|
|
341
|
+
<Button variant="default" size="sm">
|
|
342
|
+
Primary
|
|
343
|
+
</Button>
|
|
344
|
+
<Button variant="outline" size="sm">
|
|
345
|
+
Outline
|
|
346
|
+
</Button>
|
|
347
|
+
<Button variant="secondary" size="sm">
|
|
348
|
+
Secondary
|
|
349
|
+
</Button>
|
|
350
|
+
</div>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function ConditionalStylingExample() {
|
|
355
|
+
const states = [
|
|
356
|
+
{ label: "Normal", isActive: false, isDisabled: false },
|
|
357
|
+
{ label: "Active", isActive: true, isDisabled: false },
|
|
358
|
+
{ label: "Disabled", isActive: false, isDisabled: true },
|
|
359
|
+
];
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
<div className="space-y-2">
|
|
363
|
+
{states.map((state) => (
|
|
364
|
+
<div
|
|
365
|
+
key={state.label}
|
|
366
|
+
className={cn(
|
|
367
|
+
"border rounded-lg p-3 text-sm",
|
|
368
|
+
"transition-all duration-200",
|
|
369
|
+
state.isActive && "border-primary bg-primary/5",
|
|
370
|
+
state.isDisabled && "opacity-50 cursor-not-allowed",
|
|
371
|
+
!state.isDisabled && "hover:shadow-sm",
|
|
372
|
+
)}
|
|
373
|
+
>
|
|
374
|
+
{state.label} State
|
|
375
|
+
</div>
|
|
376
|
+
))}
|
|
377
|
+
</div>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function ResponsiveExample() {
|
|
382
|
+
return (
|
|
383
|
+
<div
|
|
384
|
+
className={cn(
|
|
385
|
+
"grid gap-2",
|
|
386
|
+
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
|
|
387
|
+
"sm:gap-3 lg:gap-4",
|
|
388
|
+
)}
|
|
389
|
+
>
|
|
390
|
+
{[1, 2, 3].map((i) => (
|
|
391
|
+
<div key={i} className="bg-muted rounded p-2 text-center text-xs">
|
|
392
|
+
Item {i}
|
|
393
|
+
</div>
|
|
394
|
+
))}
|
|
395
|
+
</div>
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function OverrideExample() {
|
|
400
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
401
|
+
const Alert = ({ variant, className, children }: any) => (
|
|
402
|
+
<div
|
|
403
|
+
className={cn(
|
|
404
|
+
"relative w-full rounded-lg border p-3",
|
|
405
|
+
{
|
|
406
|
+
"bg-background text-foreground": variant === "default",
|
|
407
|
+
"border-destructive/50 text-destructive dark:border-destructive":
|
|
408
|
+
variant === "destructive",
|
|
409
|
+
},
|
|
410
|
+
className,
|
|
411
|
+
)}
|
|
412
|
+
>
|
|
413
|
+
{children}
|
|
414
|
+
</div>
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
return (
|
|
418
|
+
<div className="space-y-2">
|
|
419
|
+
<Alert variant="default">
|
|
420
|
+
<div className="text-xs">Default alert styling</div>
|
|
421
|
+
</Alert>
|
|
422
|
+
<Alert variant="destructive">
|
|
423
|
+
<div className="text-xs">Destructive alert styling</div>
|
|
424
|
+
</Alert>
|
|
425
|
+
<Alert
|
|
426
|
+
variant="default"
|
|
427
|
+
className="bg-blue-50 border-blue-200 text-blue-800 dark:bg-blue-950 dark:border-blue-800 dark:text-blue-200"
|
|
428
|
+
>
|
|
429
|
+
<div className="text-xs">Custom override with className prop</div>
|
|
430
|
+
</Alert>
|
|
431
|
+
</div>
|
|
432
|
+
);
|
|
433
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { ChevronDown, Settings, HelpCircle, Info } from "lucide-react";
|
|
4
|
+
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "../collapsible";
|
|
5
|
+
import { Button } from "../button";
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: "Layout and Structure/Collapsible",
|
|
9
|
+
component: Collapsible,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
"An interactive component which expands/collapses a panel. Built with Radix UI primitives and perfect for FAQ sections, expandable details, and settings panels.",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
tags: ["autodocs"],
|
|
20
|
+
argTypes: {
|
|
21
|
+
open: {
|
|
22
|
+
control: "boolean",
|
|
23
|
+
description: "Controls the open state of the collapsible",
|
|
24
|
+
},
|
|
25
|
+
defaultOpen: {
|
|
26
|
+
control: "boolean",
|
|
27
|
+
description: "The initial open state when uncontrolled",
|
|
28
|
+
},
|
|
29
|
+
disabled: {
|
|
30
|
+
control: "boolean",
|
|
31
|
+
description: "When true, prevents the user from interacting with the collapsible",
|
|
32
|
+
},
|
|
33
|
+
onOpenChange: {
|
|
34
|
+
action: "onOpenChange",
|
|
35
|
+
description: "Callback fired when the open state changes",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
} satisfies Meta<typeof Collapsible>;
|
|
39
|
+
|
|
40
|
+
export default meta;
|
|
41
|
+
type Story = StoryObj<typeof meta>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Interactive playground for testing all collapsible props and behaviors.
|
|
45
|
+
* Use the controls panel to experiment with different configurations.
|
|
46
|
+
*/
|
|
47
|
+
export const Interactive: Story = {
|
|
48
|
+
render: (args) => {
|
|
49
|
+
const [isOpen, setIsOpen] = React.useState(args.defaultOpen ?? false);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Collapsible
|
|
53
|
+
{...args}
|
|
54
|
+
open={args.open ?? isOpen}
|
|
55
|
+
onOpenChange={(open) => {
|
|
56
|
+
setIsOpen(open);
|
|
57
|
+
args.onOpenChange?.(open);
|
|
58
|
+
}}
|
|
59
|
+
className="w-96 space-y-2"
|
|
60
|
+
>
|
|
61
|
+
<CollapsibleTrigger asChild>
|
|
62
|
+
<Button variant="outline" className="w-full justify-between" disabled={args.disabled}>
|
|
63
|
+
Can I use this in my project?
|
|
64
|
+
<ChevronDown className="h-4 w-4" />
|
|
65
|
+
</Button>
|
|
66
|
+
</CollapsibleTrigger>
|
|
67
|
+
<CollapsibleContent className="rounded-md border px-4 py-3 bg-muted/50">
|
|
68
|
+
<p className="text-sm">
|
|
69
|
+
Yes. Free to use for personal and commercial projects.
|
|
70
|
+
No attribution required.
|
|
71
|
+
</p>
|
|
72
|
+
<p className="text-sm text-muted-foreground mt-2">
|
|
73
|
+
This interactive example demonstrates the collapsible functionality
|
|
74
|
+
with smooth animations and accessibility features.
|
|
75
|
+
</p>
|
|
76
|
+
</CollapsibleContent>
|
|
77
|
+
</Collapsible>
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
args: {
|
|
81
|
+
defaultOpen: false,
|
|
82
|
+
disabled: false,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Showcase of different collapsible variants and styling approaches.
|
|
88
|
+
* Demonstrates various visual styles and use cases.
|
|
89
|
+
*/
|
|
90
|
+
export const Variants: Story = {
|
|
91
|
+
render: () => (
|
|
92
|
+
<div className="w-96 space-y-6">
|
|
93
|
+
{/* Basic Button Style */}
|
|
94
|
+
<div className="space-y-2">
|
|
95
|
+
<h4 className="text-sm font-semibold text-muted-foreground">Button Style</h4>
|
|
96
|
+
<Collapsible className="space-y-2">
|
|
97
|
+
<CollapsibleTrigger asChild>
|
|
98
|
+
<Button variant="outline" className="w-full justify-between">
|
|
99
|
+
Basic Button Trigger
|
|
100
|
+
<ChevronDown className="h-4 w-4" />
|
|
101
|
+
</Button>
|
|
102
|
+
</CollapsibleTrigger>
|
|
103
|
+
<CollapsibleContent className="rounded-md border px-4 py-3 bg-muted/50">
|
|
104
|
+
<p className="text-sm">Content revealed with button-style trigger.</p>
|
|
105
|
+
</CollapsibleContent>
|
|
106
|
+
</Collapsible>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
{/* Custom Trigger Style */}
|
|
110
|
+
<div className="space-y-2">
|
|
111
|
+
<h4 className="text-sm font-semibold text-muted-foreground">Custom Trigger</h4>
|
|
112
|
+
<Collapsible className="space-y-2">
|
|
113
|
+
<CollapsibleTrigger className="flex items-center justify-between w-full p-3 bg-secondary rounded-md hover:bg-secondary/80 transition-colors">
|
|
114
|
+
<span className="font-medium flex items-center gap-2">
|
|
115
|
+
<Settings className="h-4 w-4" />
|
|
116
|
+
Advanced Settings
|
|
117
|
+
</span>
|
|
118
|
+
<ChevronDown className="h-4 w-4" />
|
|
119
|
+
</CollapsibleTrigger>
|
|
120
|
+
<CollapsibleContent className="rounded-md border px-4 py-3">
|
|
121
|
+
<p className="text-sm">Settings panel with custom styled trigger.</p>
|
|
122
|
+
</CollapsibleContent>
|
|
123
|
+
</Collapsible>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
{/* FAQ Style */}
|
|
127
|
+
<div className="space-y-2">
|
|
128
|
+
<h4 className="text-sm font-semibold text-muted-foreground">FAQ Style</h4>
|
|
129
|
+
<Collapsible className="space-y-2">
|
|
130
|
+
<CollapsibleTrigger className="flex items-center gap-3 w-full p-3 text-left bg-background border rounded-md hover:bg-muted/50 transition-colors">
|
|
131
|
+
<HelpCircle className="h-4 w-4 text-blue-500" />
|
|
132
|
+
<span className="font-medium">How does this work?</span>
|
|
133
|
+
<ChevronDown className="h-4 w-4 ml-auto" />
|
|
134
|
+
</CollapsibleTrigger>
|
|
135
|
+
<CollapsibleContent className="px-4 py-3 border rounded-md bg-muted/30">
|
|
136
|
+
<p className="text-sm">FAQ-style implementation with question and answer format.</p>
|
|
137
|
+
</CollapsibleContent>
|
|
138
|
+
</Collapsible>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
{/* Minimal Style */}
|
|
142
|
+
<div className="space-y-2">
|
|
143
|
+
<h4 className="text-sm font-semibold text-muted-foreground">Minimal Style</h4>
|
|
144
|
+
<Collapsible>
|
|
145
|
+
<CollapsibleTrigger className="font-medium hover:underline cursor-pointer">
|
|
146
|
+
Show technical details
|
|
147
|
+
</CollapsibleTrigger>
|
|
148
|
+
<CollapsibleContent className="mt-2 text-sm text-muted-foreground">
|
|
149
|
+
<p>Minimal styling with just text and underline hover effect.</p>
|
|
150
|
+
</CollapsibleContent>
|
|
151
|
+
</Collapsible>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
{/* Alert Style */}
|
|
155
|
+
<div className="space-y-2">
|
|
156
|
+
<h4 className="text-sm font-semibold text-muted-foreground">Alert Style</h4>
|
|
157
|
+
<Collapsible className="space-y-2">
|
|
158
|
+
<CollapsibleTrigger className="flex items-center gap-3 w-full p-3 text-left bg-blue-50 border border-blue-200 rounded-md hover:bg-blue-100 transition-colors">
|
|
159
|
+
<Info className="h-4 w-4 text-blue-600" />
|
|
160
|
+
<span className="font-medium text-blue-900">Important Information</span>
|
|
161
|
+
<ChevronDown className="h-4 w-4 ml-auto text-blue-600" />
|
|
162
|
+
</CollapsibleTrigger>
|
|
163
|
+
<CollapsibleContent className="px-4 py-3 bg-blue-50 border border-blue-200 rounded-md">
|
|
164
|
+
<p className="text-sm text-blue-800">
|
|
165
|
+
Alert-style collapsible with colored background and borders.
|
|
166
|
+
</p>
|
|
167
|
+
</CollapsibleContent>
|
|
168
|
+
</Collapsible>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
),
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Real-world usage example showing collapsibles in a dashboard settings context.
|
|
176
|
+
* Demonstrates how designers and business teams might use this component.
|
|
177
|
+
*/
|
|
178
|
+
export const InContext: Story = {
|
|
179
|
+
render: () => (
|
|
180
|
+
<div className="w-full max-w-2xl mx-auto space-y-6 p-6 bg-background border rounded-lg">
|
|
181
|
+
<div className="space-y-2">
|
|
182
|
+
<h2 className="text-xl font-semibold">Dashboard Settings</h2>
|
|
183
|
+
<p className="text-sm text-muted-foreground">
|
|
184
|
+
Configure your dashboard preferences and advanced options.
|
|
185
|
+
</p>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div className="space-y-4">
|
|
189
|
+
{/* Profile Settings */}
|
|
190
|
+
<Collapsible defaultOpen className="space-y-3">
|
|
191
|
+
<CollapsibleTrigger className="flex items-center justify-between w-full p-4 bg-card border rounded-lg hover:bg-muted/50 transition-colors">
|
|
192
|
+
<div className="text-left">
|
|
193
|
+
<h3 className="font-medium">Profile Settings</h3>
|
|
194
|
+
<p className="text-sm text-muted-foreground">Manage your account and personal information</p>
|
|
195
|
+
</div>
|
|
196
|
+
<ChevronDown className="h-5 w-5 text-muted-foreground" />
|
|
197
|
+
</CollapsibleTrigger>
|
|
198
|
+
<CollapsibleContent className="px-4 py-3 border rounded-lg bg-muted/30">
|
|
199
|
+
<div className="grid grid-cols-2 gap-3">
|
|
200
|
+
<Button variant="outline" size="sm">Edit Profile</Button>
|
|
201
|
+
<Button variant="outline" size="sm">Change Password</Button>
|
|
202
|
+
<Button variant="outline" size="sm">Privacy Settings</Button>
|
|
203
|
+
<Button variant="outline" size="sm">Notifications</Button>
|
|
204
|
+
</div>
|
|
205
|
+
</CollapsibleContent>
|
|
206
|
+
</Collapsible>
|
|
207
|
+
|
|
208
|
+
{/* Advanced Configuration */}
|
|
209
|
+
<Collapsible className="space-y-3">
|
|
210
|
+
<CollapsibleTrigger className="flex items-center justify-between w-full p-4 bg-card border rounded-lg hover:bg-muted/50 transition-colors">
|
|
211
|
+
<div className="text-left">
|
|
212
|
+
<h3 className="font-medium">Advanced Configuration</h3>
|
|
213
|
+
<p className="text-sm text-muted-foreground">API keys, webhooks, and developer settings</p>
|
|
214
|
+
</div>
|
|
215
|
+
<ChevronDown className="h-5 w-5 text-muted-foreground" />
|
|
216
|
+
</CollapsibleTrigger>
|
|
217
|
+
<CollapsibleContent className="px-4 py-3 border rounded-lg bg-muted/30">
|
|
218
|
+
<div className="space-y-3">
|
|
219
|
+
<div className="flex items-center justify-between">
|
|
220
|
+
<span className="text-sm font-medium">API Access</span>
|
|
221
|
+
<Button variant="outline" size="sm">Manage Keys</Button>
|
|
222
|
+
</div>
|
|
223
|
+
<div className="flex items-center justify-between">
|
|
224
|
+
<span className="text-sm font-medium">Webhooks</span>
|
|
225
|
+
<Button variant="outline" size="sm">Configure</Button>
|
|
226
|
+
</div>
|
|
227
|
+
<div className="flex items-center justify-between">
|
|
228
|
+
<span className="text-sm font-medium">Developer Mode</span>
|
|
229
|
+
<Button variant="outline" size="sm">Enable</Button>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
</CollapsibleContent>
|
|
233
|
+
</Collapsible>
|
|
234
|
+
|
|
235
|
+
{/* Help & Support */}
|
|
236
|
+
<Collapsible className="space-y-3">
|
|
237
|
+
<CollapsibleTrigger className="flex items-center justify-between w-full p-4 bg-card border rounded-lg hover:bg-muted/50 transition-colors">
|
|
238
|
+
<div className="text-left">
|
|
239
|
+
<h3 className="font-medium">Help & Support</h3>
|
|
240
|
+
<p className="text-sm text-muted-foreground">Documentation, tutorials, and support resources</p>
|
|
241
|
+
</div>
|
|
242
|
+
<ChevronDown className="h-5 w-5 text-muted-foreground" />
|
|
243
|
+
</CollapsibleTrigger>
|
|
244
|
+
<CollapsibleContent className="px-4 py-3 border rounded-lg bg-muted/30">
|
|
245
|
+
<div className="space-y-2">
|
|
246
|
+
<a href="#" className="block text-sm text-blue-600 hover:underline">Getting Started Guide</a>
|
|
247
|
+
<a href="#" className="block text-sm text-blue-600 hover:underline">API Documentation</a>
|
|
248
|
+
<a href="#" className="block text-sm text-blue-600 hover:underline">Video Tutorials</a>
|
|
249
|
+
<a href="#" className="block text-sm text-blue-600 hover:underline">Contact Support</a>
|
|
250
|
+
</div>
|
|
251
|
+
</CollapsibleContent>
|
|
252
|
+
</Collapsible>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
),
|
|
256
|
+
};
|