gladvn 0.2.14
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/README.md +112 -0
- package/bin/cli.js +326 -0
- package/dist/components/macro/accordion-preset.d.ts +14 -0
- package/dist/components/macro/accordion-preset.d.ts.map +1 -0
- package/dist/components/macro/alert-dialog-preset.d.ts +26 -0
- package/dist/components/macro/alert-dialog-preset.d.ts.map +1 -0
- package/dist/components/macro/alert-preset.d.ts +14 -0
- package/dist/components/macro/alert-preset.d.ts.map +1 -0
- package/dist/components/macro/avatar-preset.d.ts +11 -0
- package/dist/components/macro/avatar-preset.d.ts.map +1 -0
- package/dist/components/macro/breadcrumb-preset.d.ts +12 -0
- package/dist/components/macro/breadcrumb-preset.d.ts.map +1 -0
- package/dist/components/macro/card-preset.d.ts +10 -0
- package/dist/components/macro/card-preset.d.ts.map +1 -0
- package/dist/components/macro/carousel-preset.d.ts +18 -0
- package/dist/components/macro/carousel-preset.d.ts.map +1 -0
- package/dist/components/macro/checkbox-preset.d.ts +14 -0
- package/dist/components/macro/checkbox-preset.d.ts.map +1 -0
- package/dist/components/macro/combobox-preset.d.ts +27 -0
- package/dist/components/macro/combobox-preset.d.ts.map +1 -0
- package/dist/components/macro/command-preset.d.ts +16 -0
- package/dist/components/macro/command-preset.d.ts.map +1 -0
- package/dist/components/macro/date-picker.d.ts +62 -0
- package/dist/components/macro/date-picker.d.ts.map +1 -0
- package/dist/components/macro/dialog-preset.d.ts +24 -0
- package/dist/components/macro/dialog-preset.d.ts.map +1 -0
- package/dist/components/macro/empty-preset.d.ts +15 -0
- package/dist/components/macro/empty-preset.d.ts.map +1 -0
- package/dist/components/macro/field-preset.d.ts +15 -0
- package/dist/components/macro/field-preset.d.ts.map +1 -0
- package/dist/components/macro/index.d.ts +22 -0
- package/dist/components/macro/index.d.ts.map +1 -0
- package/dist/components/macro/input-otp-preset.d.ts +13 -0
- package/dist/components/macro/input-otp-preset.d.ts.map +1 -0
- package/dist/components/macro/input-preset.d.ts +21 -0
- package/dist/components/macro/input-preset.d.ts.map +1 -0
- package/dist/components/macro/pagination-preset.d.ts +13 -0
- package/dist/components/macro/pagination-preset.d.ts.map +1 -0
- package/dist/components/macro/progress-preset.d.ts +10 -0
- package/dist/components/macro/progress-preset.d.ts.map +1 -0
- package/dist/components/macro/radio-group-preset.d.ts +22 -0
- package/dist/components/macro/radio-group-preset.d.ts.map +1 -0
- package/dist/components/macro/select-preset.d.ts +42 -0
- package/dist/components/macro/select-preset.d.ts.map +1 -0
- package/dist/components/macro/slider-preset.d.ts +12 -0
- package/dist/components/macro/slider-preset.d.ts.map +1 -0
- package/dist/components/macro/switch-preset.d.ts +12 -0
- package/dist/components/macro/switch-preset.d.ts.map +1 -0
- package/dist/components/macro/tabs-preset.d.ts +17 -0
- package/dist/components/macro/tabs-preset.d.ts.map +1 -0
- package/dist/components/macro/textarea-preset.d.ts +17 -0
- package/dist/components/macro/textarea-preset.d.ts.map +1 -0
- package/dist/components/micro/accordion.d.ts +8 -0
- package/dist/components/micro/accordion.d.ts.map +1 -0
- package/dist/components/micro/alert-dialog.d.ts +33 -0
- package/dist/components/micro/alert-dialog.d.ts.map +1 -0
- package/dist/components/micro/alert.d.ts +28 -0
- package/dist/components/micro/alert.d.ts.map +1 -0
- package/dist/components/micro/aspect-ratio.d.ts +13 -0
- package/dist/components/micro/aspect-ratio.d.ts.map +1 -0
- package/dist/components/micro/avatar.d.ts +23 -0
- package/dist/components/micro/avatar.d.ts.map +1 -0
- package/dist/components/micro/badge.d.ts +16 -0
- package/dist/components/micro/badge.d.ts.map +1 -0
- package/dist/components/micro/breadcrumb.d.ts +24 -0
- package/dist/components/micro/breadcrumb.d.ts.map +1 -0
- package/dist/components/micro/button.d.ts +39 -0
- package/dist/components/micro/button.d.ts.map +1 -0
- package/dist/components/micro/calendar.d.ts +28 -0
- package/dist/components/micro/calendar.d.ts.map +1 -0
- package/dist/components/micro/card.d.ts +28 -0
- package/dist/components/micro/card.d.ts.map +1 -0
- package/dist/components/micro/carousel.d.ts +29 -0
- package/dist/components/micro/carousel.d.ts.map +1 -0
- package/dist/components/micro/chart.d.ts +49 -0
- package/dist/components/micro/chart.d.ts.map +1 -0
- package/dist/components/micro/checkbox.d.ts +17 -0
- package/dist/components/micro/checkbox.d.ts.map +1 -0
- package/dist/components/micro/collapsible.d.ts +15 -0
- package/dist/components/micro/collapsible.d.ts.map +1 -0
- package/dist/components/micro/combobox.d.ts +33 -0
- package/dist/components/micro/combobox.d.ts.map +1 -0
- package/dist/components/micro/command.d.ts +79 -0
- package/dist/components/micro/command.d.ts.map +1 -0
- package/dist/components/micro/context-menu.d.ts +60 -0
- package/dist/components/micro/context-menu.d.ts.map +1 -0
- package/dist/components/micro/dialog.d.ts +14 -0
- package/dist/components/micro/dialog.d.ts.map +1 -0
- package/dist/components/micro/direction.d.ts +2 -0
- package/dist/components/micro/direction.d.ts.map +1 -0
- package/dist/components/micro/drawer.d.ts +17 -0
- package/dist/components/micro/drawer.d.ts.map +1 -0
- package/dist/components/micro/dropdown-menu.d.ts +37 -0
- package/dist/components/micro/dropdown-menu.d.ts.map +1 -0
- package/dist/components/micro/empty.d.ts +23 -0
- package/dist/components/micro/empty.d.ts.map +1 -0
- package/dist/components/micro/field.d.ts +29 -0
- package/dist/components/micro/field.d.ts.map +1 -0
- package/dist/components/micro/hover-card.d.ts +17 -0
- package/dist/components/micro/hover-card.d.ts.map +1 -0
- package/dist/components/micro/input-group.d.ts +17 -0
- package/dist/components/micro/input-group.d.ts.map +1 -0
- package/dist/components/micro/input-otp.d.ts +44 -0
- package/dist/components/micro/input-otp.d.ts.map +1 -0
- package/dist/components/micro/input.d.ts +22 -0
- package/dist/components/micro/input.d.ts.map +1 -0
- package/dist/components/micro/item.d.ts +31 -0
- package/dist/components/micro/item.d.ts.map +1 -0
- package/dist/components/micro/kbd.d.ts +9 -0
- package/dist/components/micro/kbd.d.ts.map +1 -0
- package/dist/components/micro/label.d.ts +15 -0
- package/dist/components/micro/label.d.ts.map +1 -0
- package/dist/components/micro/menubar.d.ts +41 -0
- package/dist/components/micro/menubar.d.ts.map +1 -0
- package/dist/components/micro/navigation-menu.d.ts +18 -0
- package/dist/components/micro/navigation-menu.d.ts.map +1 -0
- package/dist/components/micro/pagination.d.ts +33 -0
- package/dist/components/micro/pagination.d.ts.map +1 -0
- package/dist/components/micro/popover.d.ts +23 -0
- package/dist/components/micro/popover.d.ts.map +1 -0
- package/dist/components/micro/progress.d.ts +19 -0
- package/dist/components/micro/progress.d.ts.map +1 -0
- package/dist/components/micro/radio-group.d.ts +13 -0
- package/dist/components/micro/radio-group.d.ts.map +1 -0
- package/dist/components/micro/resizable.d.ts +12 -0
- package/dist/components/micro/resizable.d.ts.map +1 -0
- package/dist/components/micro/scroll-area.d.ts +12 -0
- package/dist/components/micro/scroll-area.d.ts.map +1 -0
- package/dist/components/micro/select.d.ts +21 -0
- package/dist/components/micro/select.d.ts.map +1 -0
- package/dist/components/micro/separator.d.ts +9 -0
- package/dist/components/micro/separator.d.ts.map +1 -0
- package/dist/components/micro/sheet.d.ts +17 -0
- package/dist/components/micro/sheet.d.ts.map +1 -0
- package/dist/components/micro/sidebar.d.ts +28 -0
- package/dist/components/micro/sidebar.d.ts.map +1 -0
- package/dist/components/micro/skeleton.d.ts +9 -0
- package/dist/components/micro/skeleton.d.ts.map +1 -0
- package/dist/components/micro/slider.d.ts +14 -0
- package/dist/components/micro/slider.d.ts.map +1 -0
- package/dist/components/micro/sonner.d.ts +5 -0
- package/dist/components/micro/sonner.d.ts.map +1 -0
- package/dist/components/micro/spinner.d.ts +21 -0
- package/dist/components/micro/spinner.d.ts.map +1 -0
- package/dist/components/micro/switch.d.ts +13 -0
- package/dist/components/micro/switch.d.ts.map +1 -0
- package/dist/components/micro/table.d.ts +17 -0
- package/dist/components/micro/table.d.ts.map +1 -0
- package/dist/components/micro/tabs.d.ts +13 -0
- package/dist/components/micro/tabs.d.ts.map +1 -0
- package/dist/components/micro/textarea.d.ts +17 -0
- package/dist/components/micro/textarea.d.ts.map +1 -0
- package/dist/components/micro/theme-provider.d.ts +76 -0
- package/dist/components/micro/theme-provider.d.ts.map +1 -0
- package/dist/components/micro/toggle-group.d.ts +22 -0
- package/dist/components/micro/toggle-group.d.ts.map +1 -0
- package/dist/components/micro/toggle.d.ts +16 -0
- package/dist/components/micro/toggle.d.ts.map +1 -0
- package/dist/components/micro/tooltip.d.ts +20 -0
- package/dist/components/micro/tooltip.d.ts.map +1 -0
- package/dist/dev/App.d.ts +3 -0
- package/dist/dev/App.d.ts.map +1 -0
- package/dist/dev/components/GladcnLogo.d.ts +10 -0
- package/dist/dev/components/GladcnLogo.d.ts.map +1 -0
- package/dist/dev/components/code-highlighter.d.ts +5 -0
- package/dist/dev/components/code-highlighter.d.ts.map +1 -0
- package/dist/dev/components/dev-context.d.ts +12 -0
- package/dist/dev/components/dev-context.d.ts.map +1 -0
- package/dist/dev/components/showcase.d.ts +72 -0
- package/dist/dev/components/showcase.d.ts.map +1 -0
- package/dist/dev/data.d.ts +68 -0
- package/dist/dev/data.d.ts.map +1 -0
- package/dist/dev/main.d.ts +1 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/dev/sections/buttons.d.ts +2 -0
- package/dist/dev/sections/buttons.d.ts.map +1 -0
- package/dist/dev/sections/display.d.ts +2 -0
- package/dist/dev/sections/display.d.ts.map +1 -0
- package/dist/dev/sections/feedback.d.ts +2 -0
- package/dist/dev/sections/feedback.d.ts.map +1 -0
- package/dist/dev/sections/forms.d.ts +2 -0
- package/dist/dev/sections/forms.d.ts.map +1 -0
- package/dist/dev/sections/interactive.d.ts +2 -0
- package/dist/dev/sections/interactive.d.ts.map +1 -0
- package/dist/dev/sections/overview.d.ts +2 -0
- package/dist/dev/sections/overview.d.ts.map +1 -0
- package/dist/dev/showcase/accordion.d.ts +2 -0
- package/dist/dev/showcase/accordion.d.ts.map +1 -0
- package/dist/dev/showcase/alert-dialog.d.ts +2 -0
- package/dist/dev/showcase/alert-dialog.d.ts.map +1 -0
- package/dist/dev/showcase/alert.d.ts +2 -0
- package/dist/dev/showcase/alert.d.ts.map +1 -0
- package/dist/dev/showcase/aspect-ratio.d.ts +2 -0
- package/dist/dev/showcase/aspect-ratio.d.ts.map +1 -0
- package/dist/dev/showcase/avatar.d.ts +2 -0
- package/dist/dev/showcase/avatar.d.ts.map +1 -0
- package/dist/dev/showcase/badge.d.ts +2 -0
- package/dist/dev/showcase/badge.d.ts.map +1 -0
- package/dist/dev/showcase/breadcrumb.d.ts +2 -0
- package/dist/dev/showcase/breadcrumb.d.ts.map +1 -0
- package/dist/dev/showcase/button.d.ts +2 -0
- package/dist/dev/showcase/button.d.ts.map +1 -0
- package/dist/dev/showcase/calendar.d.ts +2 -0
- package/dist/dev/showcase/calendar.d.ts.map +1 -0
- package/dist/dev/showcase/card.d.ts +2 -0
- package/dist/dev/showcase/card.d.ts.map +1 -0
- package/dist/dev/showcase/carousel.d.ts +2 -0
- package/dist/dev/showcase/carousel.d.ts.map +1 -0
- package/dist/dev/showcase/chart.d.ts +2 -0
- package/dist/dev/showcase/chart.d.ts.map +1 -0
- package/dist/dev/showcase/checkbox.d.ts +2 -0
- package/dist/dev/showcase/checkbox.d.ts.map +1 -0
- package/dist/dev/showcase/collapsible.d.ts +3 -0
- package/dist/dev/showcase/collapsible.d.ts.map +1 -0
- package/dist/dev/showcase/combobox.d.ts +2 -0
- package/dist/dev/showcase/combobox.d.ts.map +1 -0
- package/dist/dev/showcase/command.d.ts +2 -0
- package/dist/dev/showcase/command.d.ts.map +1 -0
- package/dist/dev/showcase/context-menu.d.ts +2 -0
- package/dist/dev/showcase/context-menu.d.ts.map +1 -0
- package/dist/dev/showcase/dialog.d.ts +2 -0
- package/dist/dev/showcase/dialog.d.ts.map +1 -0
- package/dist/dev/showcase/drawer.d.ts +2 -0
- package/dist/dev/showcase/drawer.d.ts.map +1 -0
- package/dist/dev/showcase/dropdown-menu.d.ts +2 -0
- package/dist/dev/showcase/dropdown-menu.d.ts.map +1 -0
- package/dist/dev/showcase/empty.d.ts +2 -0
- package/dist/dev/showcase/empty.d.ts.map +1 -0
- package/dist/dev/showcase/hover-card.d.ts +2 -0
- package/dist/dev/showcase/hover-card.d.ts.map +1 -0
- package/dist/dev/showcase/input-group.d.ts +2 -0
- package/dist/dev/showcase/input-group.d.ts.map +1 -0
- package/dist/dev/showcase/input-otp.d.ts +2 -0
- package/dist/dev/showcase/input-otp.d.ts.map +1 -0
- package/dist/dev/showcase/input.d.ts +2 -0
- package/dist/dev/showcase/input.d.ts.map +1 -0
- package/dist/dev/showcase/item.d.ts +2 -0
- package/dist/dev/showcase/item.d.ts.map +1 -0
- package/dist/dev/showcase/kbd.d.ts +2 -0
- package/dist/dev/showcase/kbd.d.ts.map +1 -0
- package/dist/dev/showcase/label.d.ts +2 -0
- package/dist/dev/showcase/label.d.ts.map +1 -0
- package/dist/dev/showcase/menubar.d.ts +2 -0
- package/dist/dev/showcase/menubar.d.ts.map +1 -0
- package/dist/dev/showcase/navigation-menu.d.ts +3 -0
- package/dist/dev/showcase/navigation-menu.d.ts.map +1 -0
- package/dist/dev/showcase/overview.d.ts +2 -0
- package/dist/dev/showcase/overview.d.ts.map +1 -0
- package/dist/dev/showcase/pagination.d.ts +2 -0
- package/dist/dev/showcase/pagination.d.ts.map +1 -0
- package/dist/dev/showcase/popover.d.ts +2 -0
- package/dist/dev/showcase/popover.d.ts.map +1 -0
- package/dist/dev/showcase/progress.d.ts +2 -0
- package/dist/dev/showcase/progress.d.ts.map +1 -0
- package/dist/dev/showcase/radio-group.d.ts +2 -0
- package/dist/dev/showcase/radio-group.d.ts.map +1 -0
- package/dist/dev/showcase/resizable.d.ts +2 -0
- package/dist/dev/showcase/resizable.d.ts.map +1 -0
- package/dist/dev/showcase/scroll-area.d.ts +2 -0
- package/dist/dev/showcase/scroll-area.d.ts.map +1 -0
- package/dist/dev/showcase/select.d.ts +2 -0
- package/dist/dev/showcase/select.d.ts.map +1 -0
- package/dist/dev/showcase/separator.d.ts +2 -0
- package/dist/dev/showcase/separator.d.ts.map +1 -0
- package/dist/dev/showcase/sheet.d.ts +2 -0
- package/dist/dev/showcase/sheet.d.ts.map +1 -0
- package/dist/dev/showcase/sidebar.d.ts +2 -0
- package/dist/dev/showcase/sidebar.d.ts.map +1 -0
- package/dist/dev/showcase/skeleton.d.ts +2 -0
- package/dist/dev/showcase/skeleton.d.ts.map +1 -0
- package/dist/dev/showcase/slider.d.ts +2 -0
- package/dist/dev/showcase/slider.d.ts.map +1 -0
- package/dist/dev/showcase/sonner.d.ts +2 -0
- package/dist/dev/showcase/sonner.d.ts.map +1 -0
- package/dist/dev/showcase/spinner.d.ts +2 -0
- package/dist/dev/showcase/spinner.d.ts.map +1 -0
- package/dist/dev/showcase/switch.d.ts +2 -0
- package/dist/dev/showcase/switch.d.ts.map +1 -0
- package/dist/dev/showcase/table.d.ts +2 -0
- package/dist/dev/showcase/table.d.ts.map +1 -0
- package/dist/dev/showcase/tabs.d.ts +2 -0
- package/dist/dev/showcase/tabs.d.ts.map +1 -0
- package/dist/dev/showcase/textarea.d.ts +2 -0
- package/dist/dev/showcase/textarea.d.ts.map +1 -0
- package/dist/dev/showcase/theme-provider.d.ts +2 -0
- package/dist/dev/showcase/theme-provider.d.ts.map +1 -0
- package/dist/dev/showcase/toast.d.ts +2 -0
- package/dist/dev/showcase/toast.d.ts.map +1 -0
- package/dist/dev/showcase/toggle-group.d.ts +2 -0
- package/dist/dev/showcase/toggle-group.d.ts.map +1 -0
- package/dist/dev/showcase/toggle.d.ts +2 -0
- package/dist/dev/showcase/toggle.d.ts.map +1 -0
- package/dist/dev/showcase/tooltip.d.ts +2 -0
- package/dist/dev/showcase/tooltip.d.ts.map +1 -0
- package/dist/hooks/use-controllable-state.d.ts +14 -0
- package/dist/hooks/use-controllable-state.d.ts.map +1 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/index.cjs +5099 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4740 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/types.d.ts +4 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/preset.d.ts +18 -0
- package/dist/preset.d.ts.map +1 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/llms.txt +74 -0
- package/package.json +117 -0
- package/scripts/add-icononly-prop.ts +84 -0
- package/scripts/audit-best-practices.ts +114 -0
- package/scripts/audit-showcase.ts +262 -0
- package/scripts/audit-showcases.ts +83 -0
- package/scripts/clean-imports.ts +21 -0
- package/scripts/count_missing.ts +24 -0
- package/scripts/find-css-vars.ts +62 -0
- package/scripts/fix-portals.ts +90 -0
- package/scripts/full-audit.ts +89 -0
- package/scripts/merge-components.cjs +65 -0
- package/scripts/merge-components.js +64 -0
- package/scripts/optimize-barrel.ts +116 -0
- package/scripts/postinstall.cjs +228 -0
- package/scripts/refactor_divs.ts +39 -0
- package/scripts/remove_div_wrappers.ts +17 -0
- package/scripts/update-gaps.ts +83 -0
- package/scripts/update_showcase_codestrings.ts +87 -0
- package/src/components/macro/accordion-preset.test.tsx +37 -0
- package/src/components/macro/accordion-preset.tsx +41 -0
- package/src/components/macro/alert-dialog-preset.tsx +116 -0
- package/src/components/macro/alert-preset.tsx +94 -0
- package/src/components/macro/avatar-preset.tsx +54 -0
- package/src/components/macro/breadcrumb-preset.tsx +50 -0
- package/src/components/macro/card-preset.tsx +44 -0
- package/src/components/macro/carousel-preset.tsx +150 -0
- package/src/components/macro/checkbox-preset.test.tsx +49 -0
- package/src/components/macro/checkbox-preset.tsx +84 -0
- package/src/components/macro/combobox-preset.tsx +171 -0
- package/src/components/macro/command-preset.tsx +74 -0
- package/src/components/macro/date-picker.tsx +289 -0
- package/src/components/macro/dialog-preset.tsx +105 -0
- package/src/components/macro/empty-preset.tsx +46 -0
- package/src/components/macro/field-preset.test.tsx +69 -0
- package/src/components/macro/field-preset.tsx +65 -0
- package/src/components/macro/index.ts +21 -0
- package/src/components/macro/input-otp-preset.tsx +98 -0
- package/src/components/macro/input-preset.test.tsx +52 -0
- package/src/components/macro/input-preset.tsx +139 -0
- package/src/components/macro/pagination-preset.tsx +153 -0
- package/src/components/macro/progress-preset.test.tsx +65 -0
- package/src/components/macro/progress-preset.tsx +45 -0
- package/src/components/macro/radio-group-preset.tsx +115 -0
- package/src/components/macro/select-preset.tsx +168 -0
- package/src/components/macro/slider-preset.test.tsx +43 -0
- package/src/components/macro/slider-preset.tsx +86 -0
- package/src/components/macro/switch-preset.test.tsx +53 -0
- package/src/components/macro/switch-preset.tsx +70 -0
- package/src/components/macro/tabs-preset.test.tsx +31 -0
- package/src/components/macro/tabs-preset.tsx +51 -0
- package/src/components/macro/textarea-preset.test.tsx +39 -0
- package/src/components/macro/textarea-preset.tsx +55 -0
- package/src/components/micro/accordion.tsx +76 -0
- package/src/components/micro/alert-dialog.tsx +213 -0
- package/src/components/micro/alert.tsx +146 -0
- package/src/components/micro/aspect-ratio.tsx +38 -0
- package/src/components/micro/avatar.tsx +143 -0
- package/src/components/micro/badge.tsx +207 -0
- package/src/components/micro/breadcrumb.tsx +162 -0
- package/src/components/micro/button.test.tsx +25 -0
- package/src/components/micro/button.tsx +361 -0
- package/src/components/micro/calendar.tsx +383 -0
- package/src/components/micro/card.tsx +112 -0
- package/src/components/micro/carousel.tsx +341 -0
- package/src/components/micro/chart.tsx +392 -0
- package/src/components/micro/checkbox.tsx +74 -0
- package/src/components/micro/collapsible.tsx +65 -0
- package/src/components/micro/combobox.tsx +349 -0
- package/src/components/micro/command.tsx +238 -0
- package/src/components/micro/context-menu.tsx +285 -0
- package/src/components/micro/dialog.tsx +143 -0
- package/src/components/micro/direction.tsx +13 -0
- package/src/components/micro/drawer.tsx +149 -0
- package/src/components/micro/dropdown-menu.tsx +305 -0
- package/src/components/micro/empty.tsx +144 -0
- package/src/components/micro/field.tsx +311 -0
- package/src/components/micro/hover-card.tsx +86 -0
- package/src/components/micro/input-group.tsx +269 -0
- package/src/components/micro/input-otp.tsx +130 -0
- package/src/components/micro/input.tsx +56 -0
- package/src/components/micro/item.tsx +206 -0
- package/src/components/micro/kbd.tsx +38 -0
- package/src/components/micro/label.tsx +48 -0
- package/src/components/micro/menubar.tsx +302 -0
- package/src/components/micro/navigation-menu.tsx +197 -0
- package/src/components/micro/pagination.tsx +162 -0
- package/src/components/micro/popover.tsx +131 -0
- package/src/components/micro/progress.tsx +144 -0
- package/src/components/micro/radio-group.tsx +73 -0
- package/src/components/micro/resizable.tsx +64 -0
- package/src/components/micro/scroll-area.tsx +68 -0
- package/src/components/micro/select.tsx +234 -0
- package/src/components/micro/separator.tsx +37 -0
- package/src/components/micro/sheet.tsx +144 -0
- package/src/components/micro/sidebar.tsx +238 -0
- package/src/components/micro/skeleton.tsx +29 -0
- package/src/components/micro/slider.tsx +135 -0
- package/src/components/micro/sonner.tsx +85 -0
- package/src/components/micro/spinner.tsx +44 -0
- package/src/components/micro/switch.tsx +70 -0
- package/src/components/micro/table.tsx +210 -0
- package/src/components/micro/tabs.tsx +100 -0
- package/src/components/micro/textarea.tsx +53 -0
- package/src/components/micro/theme-provider.tsx +163 -0
- package/src/components/micro/toggle-group.tsx +121 -0
- package/src/components/micro/toggle.tsx +55 -0
- package/src/components/micro/tooltip.tsx +105 -0
- package/src/dev/App.tsx +322 -0
- package/src/dev/_debug_select.html +29 -0
- package/src/dev/components/GladcnLogo.tsx +80 -0
- package/src/dev/components/code-highlighter.tsx +67 -0
- package/src/dev/components/dev-context.tsx +31 -0
- package/src/dev/components/showcase.tsx +413 -0
- package/src/dev/data.ts +341 -0
- package/src/dev/index.css +55 -0
- package/src/dev/main.tsx +30 -0
- package/src/dev/sections/buttons.tsx +303 -0
- package/src/dev/sections/display.tsx +270 -0
- package/src/dev/sections/feedback.tsx +371 -0
- package/src/dev/sections/forms.tsx +652 -0
- package/src/dev/sections/interactive.tsx +51 -0
- package/src/dev/sections/overview.tsx +396 -0
- package/src/dev/showcase/accordion.tsx +947 -0
- package/src/dev/showcase/alert-dialog.tsx +1056 -0
- package/src/dev/showcase/alert.tsx +756 -0
- package/src/dev/showcase/aspect-ratio.tsx +339 -0
- package/src/dev/showcase/avatar.tsx +470 -0
- package/src/dev/showcase/badge.tsx +227 -0
- package/src/dev/showcase/breadcrumb.tsx +269 -0
- package/src/dev/showcase/button.tsx +309 -0
- package/src/dev/showcase/calendar.tsx +380 -0
- package/src/dev/showcase/card.tsx +448 -0
- package/src/dev/showcase/carousel.tsx +562 -0
- package/src/dev/showcase/chart.tsx +130 -0
- package/src/dev/showcase/checkbox.tsx +611 -0
- package/src/dev/showcase/collapsible.tsx +298 -0
- package/src/dev/showcase/combobox.tsx +777 -0
- package/src/dev/showcase/command.tsx +245 -0
- package/src/dev/showcase/context-menu.tsx +239 -0
- package/src/dev/showcase/dialog.tsx +1141 -0
- package/src/dev/showcase/drawer.tsx +392 -0
- package/src/dev/showcase/dropdown-menu.tsx +420 -0
- package/src/dev/showcase/empty.tsx +493 -0
- package/src/dev/showcase/hover-card.tsx +336 -0
- package/src/dev/showcase/input-group.tsx +511 -0
- package/src/dev/showcase/input-otp.tsx +404 -0
- package/src/dev/showcase/input.tsx +530 -0
- package/src/dev/showcase/item.tsx +295 -0
- package/src/dev/showcase/kbd.tsx +276 -0
- package/src/dev/showcase/label.tsx +121 -0
- package/src/dev/showcase/menubar.tsx +392 -0
- package/src/dev/showcase/navigation-menu.tsx +304 -0
- package/src/dev/showcase/overview.tsx +1106 -0
- package/src/dev/showcase/pagination.tsx +312 -0
- package/src/dev/showcase/popover.tsx +374 -0
- package/src/dev/showcase/progress.tsx +299 -0
- package/src/dev/showcase/radio-group.tsx +612 -0
- package/src/dev/showcase/resizable.tsx +237 -0
- package/src/dev/showcase/scroll-area.tsx +157 -0
- package/src/dev/showcase/select.tsx +628 -0
- package/src/dev/showcase/separator.tsx +126 -0
- package/src/dev/showcase/sheet.tsx +566 -0
- package/src/dev/showcase/sidebar.tsx +120 -0
- package/src/dev/showcase/skeleton.tsx +213 -0
- package/src/dev/showcase/slider.tsx +506 -0
- package/src/dev/showcase/sonner.tsx +376 -0
- package/src/dev/showcase/spinner.tsx +124 -0
- package/src/dev/showcase/switch.tsx +602 -0
- package/src/dev/showcase/table.tsx +196 -0
- package/src/dev/showcase/tabs.tsx +662 -0
- package/src/dev/showcase/textarea.tsx +498 -0
- package/src/dev/showcase/theme-provider.tsx +894 -0
- package/src/dev/showcase/toast.tsx +119 -0
- package/src/dev/showcase/toggle-group.tsx +223 -0
- package/src/dev/showcase/toggle.tsx +171 -0
- package/src/dev/showcase/tooltip.tsx +372 -0
- package/src/hooks/use-controllable-state.ts +87 -0
- package/src/hooks/use-mobile.ts +21 -0
- package/src/index.ts +62 -0
- package/src/lib/types.ts +14 -0
- package/src/lib/utils.test.ts +14 -0
- package/src/lib/utils.ts +6 -0
- package/src/preset.ts +17 -0
- package/src/styles/gladcn.css +116 -0
- package/src/styles/tokens.css +213 -0
- package/src/test/setup.ts +8 -0
- package/src/vite-env.d.ts +1 -0
|
@@ -0,0 +1,1141 @@
|
|
|
1
|
+
import { useDevContext } from "../../dev/components/dev-context";
|
|
2
|
+
import {
|
|
3
|
+
DocsCode,
|
|
4
|
+
DocsH3,
|
|
5
|
+
DocsP,
|
|
6
|
+
ExampleGrid,
|
|
7
|
+
ExampleSection,
|
|
8
|
+
Showcase,
|
|
9
|
+
ShowcaseDocs,
|
|
10
|
+
} from "../../dev/components/showcase";
|
|
11
|
+
import { CheckCircle2Icon, LayersIcon, XIcon } from "lucide-react";
|
|
12
|
+
import { useState } from "react";
|
|
13
|
+
|
|
14
|
+
import { DialogPreset } from "../../components/macro/dialog-preset";
|
|
15
|
+
import { Button } from "../../components/micro/button";
|
|
16
|
+
import {
|
|
17
|
+
Dialog,
|
|
18
|
+
DialogClose,
|
|
19
|
+
DialogContent,
|
|
20
|
+
DialogDescription,
|
|
21
|
+
DialogFooter,
|
|
22
|
+
DialogHeader,
|
|
23
|
+
DialogTitle,
|
|
24
|
+
DialogTrigger,
|
|
25
|
+
DialogPortal,
|
|
26
|
+
} from "../../components/micro/dialog";
|
|
27
|
+
import { Input } from "../../components/micro/input";
|
|
28
|
+
import { Label } from "../../components/micro/label";
|
|
29
|
+
import { type Size } from "../../lib/types";
|
|
30
|
+
import { cn } from "../../lib/utils";
|
|
31
|
+
|
|
32
|
+
// ──────────────────────────────────────────────────────────
|
|
33
|
+
// Macro Showcase
|
|
34
|
+
// ──────────────────────────────────────────────────────────
|
|
35
|
+
function DialogMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
36
|
+
const [controlledOpen, setControlledOpen] = useState(false);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className="space-y-10">
|
|
40
|
+
<ExampleGrid>
|
|
41
|
+
<ExampleSection
|
|
42
|
+
label="Basic Usage"
|
|
43
|
+
description="DialogPreset với title, description và footer đơn giản."
|
|
44
|
+
codeString={`<DialogPreset
|
|
45
|
+
title="Update Subscription"
|
|
46
|
+
description="Are you sure you want to upgrade your plan to Pro? This will charge your card immediately."
|
|
47
|
+
trigger={<Button variant="outline">Upgrade Plan</Button>}
|
|
48
|
+
footer={
|
|
49
|
+
<>
|
|
50
|
+
<Button variant="ghost">Cancel</Button>
|
|
51
|
+
<Button color="primary">Confirm</Button>
|
|
52
|
+
</>
|
|
53
|
+
}
|
|
54
|
+
/>
|
|
55
|
+
`}
|
|
56
|
+
>
|
|
57
|
+
<DialogPreset
|
|
58
|
+
size={globalSize}
|
|
59
|
+
title="Update Subscription"
|
|
60
|
+
description="Are you sure you want to upgrade your plan to Pro? This will charge your card immediately."
|
|
61
|
+
trigger={
|
|
62
|
+
<Button variant="outline" size={globalSize}>
|
|
63
|
+
Upgrade Plan
|
|
64
|
+
</Button>
|
|
65
|
+
}
|
|
66
|
+
footer={
|
|
67
|
+
<>
|
|
68
|
+
<Button variant="ghost" size={globalSize}>
|
|
69
|
+
Cancel
|
|
70
|
+
</Button>
|
|
71
|
+
<Button color="primary" size={globalSize}>
|
|
72
|
+
Confirm
|
|
73
|
+
</Button>
|
|
74
|
+
</>
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
</ExampleSection>
|
|
78
|
+
|
|
79
|
+
<ExampleSection
|
|
80
|
+
label="Forms & Custom Content"
|
|
81
|
+
description="Sử dụng children để render form hoặc nội dung phức tạp."
|
|
82
|
+
codeString={`<DialogPreset
|
|
83
|
+
title="Edit profile"
|
|
84
|
+
description="Make changes to your profile here. Click save when you're done."
|
|
85
|
+
trigger={<Button variant="outline">Edit Profile</Button>}
|
|
86
|
+
footer={<Button type="submit">Save changes</Button>}
|
|
87
|
+
>
|
|
88
|
+
<div className="grid gap-4 py-4">
|
|
89
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
90
|
+
<Label htmlFor="name" className="text-right">
|
|
91
|
+
Name
|
|
92
|
+
</Label>
|
|
93
|
+
<Input
|
|
94
|
+
id="name"
|
|
95
|
+
defaultValue="Pedro Duarte"
|
|
96
|
+
className="col-span-3"
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
100
|
+
<Label htmlFor="username" className="text-right">
|
|
101
|
+
Username
|
|
102
|
+
</Label>
|
|
103
|
+
<Input
|
|
104
|
+
id="username"
|
|
105
|
+
defaultValue="@peduarte"
|
|
106
|
+
className="col-span-3"
|
|
107
|
+
/>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</DialogPreset>
|
|
111
|
+
`}
|
|
112
|
+
>
|
|
113
|
+
<DialogPreset
|
|
114
|
+
size={globalSize}
|
|
115
|
+
title="Edit profile"
|
|
116
|
+
description="Make changes to your profile here. Click save when you're done."
|
|
117
|
+
trigger={
|
|
118
|
+
<Button variant="outline" size={globalSize}>
|
|
119
|
+
Edit Profile
|
|
120
|
+
</Button>
|
|
121
|
+
}
|
|
122
|
+
footer={
|
|
123
|
+
<Button type="submit" size={globalSize}>
|
|
124
|
+
Save changes
|
|
125
|
+
</Button>
|
|
126
|
+
}
|
|
127
|
+
>
|
|
128
|
+
<div className="grid gap-4 py-4">
|
|
129
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
130
|
+
<Label htmlFor="name" className="text-right">
|
|
131
|
+
Name
|
|
132
|
+
</Label>
|
|
133
|
+
<Input
|
|
134
|
+
id="name"
|
|
135
|
+
defaultValue="Pedro Duarte"
|
|
136
|
+
className="col-span-3"
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
140
|
+
<Label htmlFor="username" className="text-right">
|
|
141
|
+
Username
|
|
142
|
+
</Label>
|
|
143
|
+
<Input
|
|
144
|
+
id="username"
|
|
145
|
+
defaultValue="@peduarte"
|
|
146
|
+
className="col-span-3"
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</DialogPreset>
|
|
151
|
+
</ExampleSection>
|
|
152
|
+
</ExampleGrid>
|
|
153
|
+
|
|
154
|
+
<ExampleGrid>
|
|
155
|
+
<ExampleSection
|
|
156
|
+
label="No Close Button"
|
|
157
|
+
description="Ẩn nút X ở góc trên bằng showCloseButton={false}."
|
|
158
|
+
codeString={`<DialogPreset
|
|
159
|
+
showCloseButton={false}
|
|
160
|
+
title="Terms of Service"
|
|
161
|
+
description="You must accept the new terms to continue using the application."
|
|
162
|
+
trigger={<Button variant="outline">View Terms</Button>}
|
|
163
|
+
footer={
|
|
164
|
+
<>
|
|
165
|
+
<Button variant="outline">Decline</Button>
|
|
166
|
+
<Button>Accept</Button>
|
|
167
|
+
</>
|
|
168
|
+
}
|
|
169
|
+
>
|
|
170
|
+
<p className="text-sm text-muted-foreground">
|
|
171
|
+
By clicking accept, you agree to our updated Terms of Service and Privacy Policy.
|
|
172
|
+
</p>
|
|
173
|
+
</DialogPreset>
|
|
174
|
+
`}
|
|
175
|
+
>
|
|
176
|
+
<DialogPreset
|
|
177
|
+
size={globalSize}
|
|
178
|
+
showCloseButton={false}
|
|
179
|
+
title="Terms of Service"
|
|
180
|
+
description="You must accept the new terms to continue using the application."
|
|
181
|
+
trigger={
|
|
182
|
+
<Button variant="outline" size={globalSize}>
|
|
183
|
+
View Terms
|
|
184
|
+
</Button>
|
|
185
|
+
}
|
|
186
|
+
footer={
|
|
187
|
+
<>
|
|
188
|
+
<Button variant="outline" size={globalSize}>
|
|
189
|
+
Decline
|
|
190
|
+
</Button>
|
|
191
|
+
<Button size={globalSize}>Accept</Button>
|
|
192
|
+
</>
|
|
193
|
+
}
|
|
194
|
+
>
|
|
195
|
+
<p className="text-sm text-muted-foreground">
|
|
196
|
+
By clicking accept, you agree to our updated Terms of Service and
|
|
197
|
+
Privacy Policy.
|
|
198
|
+
</p>
|
|
199
|
+
</DialogPreset>
|
|
200
|
+
</ExampleSection>
|
|
201
|
+
|
|
202
|
+
<ExampleSection
|
|
203
|
+
label="Large Content Sizing"
|
|
204
|
+
description="Sử dụng size='lg' cho nội dung lớn hơn."
|
|
205
|
+
codeString={`<DialogPreset
|
|
206
|
+
title="Detailed Report"
|
|
207
|
+
description="Monthly analytics and performance overview."
|
|
208
|
+
trigger={<Button variant="outline">View Report</Button>}
|
|
209
|
+
footer={<Button>Download PDF</Button>}
|
|
210
|
+
>
|
|
211
|
+
<div className="h-[200px] flex items-center justify-center rounded-md border border-border border-dashed bg-muted/20">
|
|
212
|
+
<span className="text-muted-foreground text-sm">Large Content Area</span>
|
|
213
|
+
</div>
|
|
214
|
+
</DialogPreset>
|
|
215
|
+
`}
|
|
216
|
+
>
|
|
217
|
+
<DialogPreset
|
|
218
|
+
size={globalSize}
|
|
219
|
+
title="Detailed Report"
|
|
220
|
+
description="Monthly analytics and performance overview."
|
|
221
|
+
trigger={
|
|
222
|
+
<Button variant="outline" size={globalSize}>
|
|
223
|
+
View Report
|
|
224
|
+
</Button>
|
|
225
|
+
}
|
|
226
|
+
footer={<Button size={globalSize}>Download PDF</Button>}
|
|
227
|
+
>
|
|
228
|
+
<div className="h-[200px] flex items-center justify-center rounded-md border border-border border-dashed bg-muted/20">
|
|
229
|
+
<span className="text-muted-foreground text-sm">
|
|
230
|
+
Large Content Area
|
|
231
|
+
</span>
|
|
232
|
+
</div>
|
|
233
|
+
</DialogPreset>
|
|
234
|
+
</ExampleSection>
|
|
235
|
+
</ExampleGrid>
|
|
236
|
+
|
|
237
|
+
<ExampleGrid>
|
|
238
|
+
<ExampleSection
|
|
239
|
+
label="Controlled State"
|
|
240
|
+
description="Sử dụng open và onOpenChange để quản lý trạng thái đóng mở bằng React state."
|
|
241
|
+
codeString={`<div className="w-full flex flex-col gap-4 items-center justify-center">
|
|
242
|
+
<div className="flex gap-4 items-center">
|
|
243
|
+
<Button onClick={() => setControlledOpen(true)} variant="outline">
|
|
244
|
+
Open Controlled Dialog
|
|
245
|
+
</Button>
|
|
246
|
+
<span className="text-sm text-muted-foreground font-mono">
|
|
247
|
+
State: {controlledOpen ? "true" : "false"}
|
|
248
|
+
</span>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<DialogPreset
|
|
252
|
+
open={controlledOpen}
|
|
253
|
+
onOpenChange={setControlledOpen}
|
|
254
|
+
title="Controlled Dialog"
|
|
255
|
+
description="Trạng thái của dialog này được quản lý hoàn toàn bởi React state bên ngoài."
|
|
256
|
+
footer={
|
|
257
|
+
<Button color="primary" onClick={() => setControlledOpen(false)}>
|
|
258
|
+
Close Manually
|
|
259
|
+
</Button>
|
|
260
|
+
}
|
|
261
|
+
>
|
|
262
|
+
<p className="text-sm text-foreground">Bạn có thể đóng bằng nút bên dưới hoặc dấu X.</p>
|
|
263
|
+
</DialogPreset>
|
|
264
|
+
</div>
|
|
265
|
+
`}
|
|
266
|
+
>
|
|
267
|
+
<div className="w-full flex flex-col gap-4 items-center justify-center">
|
|
268
|
+
<div className="flex gap-4 items-center">
|
|
269
|
+
<Button
|
|
270
|
+
onClick={() => setControlledOpen(true)}
|
|
271
|
+
variant="outline"
|
|
272
|
+
size={globalSize}
|
|
273
|
+
>
|
|
274
|
+
Open Controlled Dialog
|
|
275
|
+
</Button>
|
|
276
|
+
<span className="text-sm text-muted-foreground font-mono">
|
|
277
|
+
State: {controlledOpen ? "true" : "false"}
|
|
278
|
+
</span>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
<DialogPreset
|
|
282
|
+
open={controlledOpen}
|
|
283
|
+
onOpenChange={setControlledOpen}
|
|
284
|
+
size={globalSize}
|
|
285
|
+
title="Controlled Dialog"
|
|
286
|
+
description="Trạng thái của dialog này được quản lý hoàn toàn bởi React state bên ngoài."
|
|
287
|
+
footer={
|
|
288
|
+
<Button
|
|
289
|
+
color="primary"
|
|
290
|
+
onClick={() => setControlledOpen(false)}
|
|
291
|
+
size={globalSize}
|
|
292
|
+
>
|
|
293
|
+
Close Manually
|
|
294
|
+
</Button>
|
|
295
|
+
}
|
|
296
|
+
>
|
|
297
|
+
<p className="text-sm text-foreground">
|
|
298
|
+
Bạn có thể đóng bằng nút bên dưới hoặc dấu X.
|
|
299
|
+
</p>
|
|
300
|
+
</DialogPreset>
|
|
301
|
+
</div>
|
|
302
|
+
</ExampleSection>
|
|
303
|
+
|
|
304
|
+
<ExampleSection
|
|
305
|
+
label="Sticky Footer (Long Content)"
|
|
306
|
+
description="Layout in-flow giúp footer luôn dính ở dưới cùng khi có thanh cuộn."
|
|
307
|
+
codeString={`<DialogPreset
|
|
308
|
+
trigger={
|
|
309
|
+
<Button variant="outline">
|
|
310
|
+
View Long Content
|
|
311
|
+
</Button>
|
|
312
|
+
}
|
|
313
|
+
title="Terms & Conditions"
|
|
314
|
+
description="Cuộn xuống dưới cùng để có thể đồng ý với điều khoản."
|
|
315
|
+
footer={
|
|
316
|
+
<div className="flex w-full sm:justify-end gap-2">
|
|
317
|
+
<DialogClose
|
|
318
|
+
render={<Button variant="ghost" />}
|
|
319
|
+
>
|
|
320
|
+
Cancel
|
|
321
|
+
</DialogClose>
|
|
322
|
+
<Button>I Agree</Button>
|
|
323
|
+
</div>
|
|
324
|
+
}
|
|
325
|
+
>
|
|
326
|
+
<div className="flex h-[800px] flex-col items-center justify-between rounded-md border border-border border-dashed bg-muted/20 py-8">
|
|
327
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
328
|
+
START OF CONTENT
|
|
329
|
+
</span>
|
|
330
|
+
<div className="flex flex-col items-center gap-2">
|
|
331
|
+
<span className="text-4xl">👇</span>
|
|
332
|
+
<span className="text-sm text-muted-foreground">Keep scrolling</span>
|
|
333
|
+
</div>
|
|
334
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
335
|
+
END OF CONTENT
|
|
336
|
+
</span>
|
|
337
|
+
</div>
|
|
338
|
+
</DialogPreset>
|
|
339
|
+
`}
|
|
340
|
+
>
|
|
341
|
+
<DialogPreset
|
|
342
|
+
trigger={
|
|
343
|
+
<Button variant="outline" size={globalSize}>
|
|
344
|
+
View Long Content
|
|
345
|
+
</Button>
|
|
346
|
+
}
|
|
347
|
+
size={globalSize}
|
|
348
|
+
title="Terms & Conditions"
|
|
349
|
+
description="Cuộn xuống dưới cùng để có thể đồng ý với điều khoản."
|
|
350
|
+
footer={
|
|
351
|
+
<div className="flex w-full sm:justify-end gap-2">
|
|
352
|
+
<DialogClose
|
|
353
|
+
render={<Button variant="ghost" size={globalSize} />}
|
|
354
|
+
>
|
|
355
|
+
Cancel
|
|
356
|
+
</DialogClose>
|
|
357
|
+
<Button size={globalSize}>I Agree</Button>
|
|
358
|
+
</div>
|
|
359
|
+
}
|
|
360
|
+
>
|
|
361
|
+
<div className="flex h-[800px] flex-col items-center justify-between rounded-md border border-border border-dashed bg-muted/20 py-8">
|
|
362
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
363
|
+
START OF CONTENT
|
|
364
|
+
</span>
|
|
365
|
+
<div className="flex flex-col items-center gap-2">
|
|
366
|
+
<span className="text-4xl">👇</span>
|
|
367
|
+
<span className="text-sm text-muted-foreground">
|
|
368
|
+
Keep scrolling
|
|
369
|
+
</span>
|
|
370
|
+
</div>
|
|
371
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
372
|
+
END OF CONTENT
|
|
373
|
+
</span>
|
|
374
|
+
</div>
|
|
375
|
+
</DialogPreset>
|
|
376
|
+
</ExampleSection>
|
|
377
|
+
</ExampleGrid>
|
|
378
|
+
</div>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ──────────────────────────────────────────────────────────
|
|
383
|
+
// Micro Showcase
|
|
384
|
+
// ──────────────────────────────────────────────────────────
|
|
385
|
+
function DialogMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
386
|
+
const [controlledOpen, setControlledOpen] = useState(false);
|
|
387
|
+
const contentClass =
|
|
388
|
+
globalSize === "sm"
|
|
389
|
+
? "sm:max-w-md"
|
|
390
|
+
: globalSize === "md"
|
|
391
|
+
? "sm:max-w-lg"
|
|
392
|
+
: "sm:max-w-xl";
|
|
393
|
+
|
|
394
|
+
return (
|
|
395
|
+
<div className="space-y-10">
|
|
396
|
+
<ExampleGrid>
|
|
397
|
+
<ExampleSection
|
|
398
|
+
label="Basic Usage"
|
|
399
|
+
description="Sử dụng các thành phần rời rạc để tạo dialog cơ bản."
|
|
400
|
+
codeString={`<Dialog>
|
|
401
|
+
<DialogTrigger
|
|
402
|
+
render={
|
|
403
|
+
<Button variant="outline">
|
|
404
|
+
Upgrade Plan
|
|
405
|
+
</Button>
|
|
406
|
+
}
|
|
407
|
+
/>
|
|
408
|
+
|
|
409
|
+
<DialogPortal><DialogContent className={contentClass}>
|
|
410
|
+
<DialogHeader>
|
|
411
|
+
<DialogTitle>Update Subscription</DialogTitle>
|
|
412
|
+
<DialogDescription>
|
|
413
|
+
Are you sure you want to upgrade your plan to Pro? This will
|
|
414
|
+
charge your card immediately.
|
|
415
|
+
</DialogDescription>
|
|
416
|
+
</DialogHeader>
|
|
417
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
418
|
+
<DialogClose
|
|
419
|
+
render={<Button variant="ghost" />}
|
|
420
|
+
>
|
|
421
|
+
Cancel
|
|
422
|
+
</DialogClose>
|
|
423
|
+
<Button color="primary">
|
|
424
|
+
Confirm
|
|
425
|
+
</Button>
|
|
426
|
+
</DialogFooter>
|
|
427
|
+
<DialogClose
|
|
428
|
+
render={
|
|
429
|
+
<Button
|
|
430
|
+
variant="ghost"
|
|
431
|
+
className="absolute top-2 right-2"
|
|
432
|
+
size="sm"
|
|
433
|
+
iconOnly
|
|
434
|
+
/>
|
|
435
|
+
}
|
|
436
|
+
>
|
|
437
|
+
<XIcon />
|
|
438
|
+
<span className="sr-only">Close</span>
|
|
439
|
+
</DialogClose>
|
|
440
|
+
</DialogContent></DialogPortal>
|
|
441
|
+
|
|
442
|
+
</Dialog>
|
|
443
|
+
`}
|
|
444
|
+
>
|
|
445
|
+
<Dialog>
|
|
446
|
+
<DialogTrigger
|
|
447
|
+
render={
|
|
448
|
+
<Button variant="outline" size={globalSize}>
|
|
449
|
+
Upgrade Plan
|
|
450
|
+
</Button>
|
|
451
|
+
}
|
|
452
|
+
/>
|
|
453
|
+
|
|
454
|
+
<DialogPortal>
|
|
455
|
+
<DialogContent className={contentClass}>
|
|
456
|
+
<DialogHeader>
|
|
457
|
+
<DialogTitle>Update Subscription</DialogTitle>
|
|
458
|
+
<DialogDescription>
|
|
459
|
+
Are you sure you want to upgrade your plan to Pro? This will
|
|
460
|
+
charge your card immediately.
|
|
461
|
+
</DialogDescription>
|
|
462
|
+
</DialogHeader>
|
|
463
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
464
|
+
<DialogClose
|
|
465
|
+
render={<Button variant="ghost" size={globalSize} />}
|
|
466
|
+
>
|
|
467
|
+
Cancel
|
|
468
|
+
</DialogClose>
|
|
469
|
+
<Button color="primary" size={globalSize}>
|
|
470
|
+
Confirm
|
|
471
|
+
</Button>
|
|
472
|
+
</DialogFooter>
|
|
473
|
+
<DialogClose
|
|
474
|
+
render={
|
|
475
|
+
<Button
|
|
476
|
+
variant="ghost"
|
|
477
|
+
className="absolute top-2 right-2"
|
|
478
|
+
size="sm"
|
|
479
|
+
iconOnly
|
|
480
|
+
/>
|
|
481
|
+
}
|
|
482
|
+
>
|
|
483
|
+
<XIcon />
|
|
484
|
+
<span className="sr-only">Close</span>
|
|
485
|
+
</DialogClose>
|
|
486
|
+
</DialogContent>
|
|
487
|
+
</DialogPortal>
|
|
488
|
+
</Dialog>
|
|
489
|
+
</ExampleSection>
|
|
490
|
+
|
|
491
|
+
<ExampleSection
|
|
492
|
+
label="Forms & Custom Content"
|
|
493
|
+
description="Sử dụng form bên trong DialogContent."
|
|
494
|
+
codeString={`<Dialog>
|
|
495
|
+
<DialogTrigger
|
|
496
|
+
render={
|
|
497
|
+
<Button variant="outline">
|
|
498
|
+
Edit Profile
|
|
499
|
+
</Button>
|
|
500
|
+
}
|
|
501
|
+
/>
|
|
502
|
+
|
|
503
|
+
<DialogPortal><DialogContent className={contentClass}>
|
|
504
|
+
<DialogHeader>
|
|
505
|
+
<DialogTitle>Edit profile</DialogTitle>
|
|
506
|
+
<DialogDescription>
|
|
507
|
+
Make changes to your profile here. Click save when you're
|
|
508
|
+
done.
|
|
509
|
+
</DialogDescription>
|
|
510
|
+
</DialogHeader>
|
|
511
|
+
<div className="grid gap-4 py-4">
|
|
512
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
513
|
+
<Label htmlFor="name" className="text-right">
|
|
514
|
+
Name
|
|
515
|
+
</Label>
|
|
516
|
+
<Input
|
|
517
|
+
id="name"
|
|
518
|
+
defaultValue="Pedro Duarte"
|
|
519
|
+
className="col-span-3"
|
|
520
|
+
/>
|
|
521
|
+
</div>
|
|
522
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
523
|
+
<Label htmlFor="username" className="text-right">
|
|
524
|
+
Username
|
|
525
|
+
</Label>
|
|
526
|
+
<Input
|
|
527
|
+
id="username"
|
|
528
|
+
defaultValue="@peduarte"
|
|
529
|
+
className="col-span-3"
|
|
530
|
+
/>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
534
|
+
<Button type="submit">
|
|
535
|
+
Save changes
|
|
536
|
+
</Button>
|
|
537
|
+
</DialogFooter>
|
|
538
|
+
<DialogClose
|
|
539
|
+
render={
|
|
540
|
+
<Button
|
|
541
|
+
variant="ghost"
|
|
542
|
+
className="absolute top-2 right-2"
|
|
543
|
+
size="sm"
|
|
544
|
+
iconOnly
|
|
545
|
+
/>
|
|
546
|
+
}
|
|
547
|
+
>
|
|
548
|
+
<XIcon />
|
|
549
|
+
<span className="sr-only">Close</span>
|
|
550
|
+
</DialogClose>
|
|
551
|
+
</DialogContent></DialogPortal>
|
|
552
|
+
|
|
553
|
+
</Dialog>
|
|
554
|
+
`}
|
|
555
|
+
>
|
|
556
|
+
<Dialog>
|
|
557
|
+
<DialogTrigger
|
|
558
|
+
render={
|
|
559
|
+
<Button variant="outline" size={globalSize}>
|
|
560
|
+
Edit Profile
|
|
561
|
+
</Button>
|
|
562
|
+
}
|
|
563
|
+
/>
|
|
564
|
+
|
|
565
|
+
<DialogPortal>
|
|
566
|
+
<DialogContent className={contentClass}>
|
|
567
|
+
<DialogHeader>
|
|
568
|
+
<DialogTitle>Edit profile</DialogTitle>
|
|
569
|
+
<DialogDescription>
|
|
570
|
+
Make changes to your profile here. Click save when you're
|
|
571
|
+
done.
|
|
572
|
+
</DialogDescription>
|
|
573
|
+
</DialogHeader>
|
|
574
|
+
<div className="grid gap-4 py-4">
|
|
575
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
576
|
+
<Label htmlFor="name" className="text-right">
|
|
577
|
+
Name
|
|
578
|
+
</Label>
|
|
579
|
+
<Input
|
|
580
|
+
id="name"
|
|
581
|
+
defaultValue="Pedro Duarte"
|
|
582
|
+
className="col-span-3"
|
|
583
|
+
/>
|
|
584
|
+
</div>
|
|
585
|
+
<div className="grid grid-cols-4 items-center gap-4">
|
|
586
|
+
<Label htmlFor="username" className="text-right">
|
|
587
|
+
Username
|
|
588
|
+
</Label>
|
|
589
|
+
<Input
|
|
590
|
+
id="username"
|
|
591
|
+
defaultValue="@peduarte"
|
|
592
|
+
className="col-span-3"
|
|
593
|
+
/>
|
|
594
|
+
</div>
|
|
595
|
+
</div>
|
|
596
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
597
|
+
<Button type="submit" size={globalSize}>
|
|
598
|
+
Save changes
|
|
599
|
+
</Button>
|
|
600
|
+
</DialogFooter>
|
|
601
|
+
<DialogClose
|
|
602
|
+
render={
|
|
603
|
+
<Button
|
|
604
|
+
variant="ghost"
|
|
605
|
+
className="absolute top-2 right-2"
|
|
606
|
+
size="sm"
|
|
607
|
+
iconOnly
|
|
608
|
+
/>
|
|
609
|
+
}
|
|
610
|
+
>
|
|
611
|
+
<XIcon />
|
|
612
|
+
<span className="sr-only">Close</span>
|
|
613
|
+
</DialogClose>
|
|
614
|
+
</DialogContent>
|
|
615
|
+
</DialogPortal>
|
|
616
|
+
</Dialog>
|
|
617
|
+
</ExampleSection>
|
|
618
|
+
</ExampleGrid>
|
|
619
|
+
|
|
620
|
+
<ExampleGrid>
|
|
621
|
+
<ExampleSection
|
|
622
|
+
label="No Close Button"
|
|
623
|
+
description="Không render nút XIcon thủ công."
|
|
624
|
+
codeString={`<Dialog>
|
|
625
|
+
<DialogTrigger
|
|
626
|
+
render={
|
|
627
|
+
<Button variant="outline">
|
|
628
|
+
View Terms
|
|
629
|
+
</Button>
|
|
630
|
+
}
|
|
631
|
+
/>
|
|
632
|
+
|
|
633
|
+
<DialogPortal><DialogContent className={contentClass}>
|
|
634
|
+
<DialogHeader>
|
|
635
|
+
<DialogTitle>Terms of Service</DialogTitle>
|
|
636
|
+
<DialogDescription>
|
|
637
|
+
You must accept the new terms to continue using the
|
|
638
|
+
application.
|
|
639
|
+
</DialogDescription>
|
|
640
|
+
</DialogHeader>
|
|
641
|
+
<p className="text-sm text-muted-foreground">
|
|
642
|
+
By clicking accept, you agree to our updated Terms of Service
|
|
643
|
+
and Privacy Policy.
|
|
644
|
+
</p>
|
|
645
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
646
|
+
<DialogClose
|
|
647
|
+
render={<Button variant="outline" />}
|
|
648
|
+
>
|
|
649
|
+
Decline
|
|
650
|
+
</DialogClose>
|
|
651
|
+
<Button>Accept</Button>
|
|
652
|
+
</DialogFooter>
|
|
653
|
+
</DialogContent></DialogPortal>
|
|
654
|
+
|
|
655
|
+
</Dialog>
|
|
656
|
+
`}
|
|
657
|
+
>
|
|
658
|
+
<Dialog>
|
|
659
|
+
<DialogTrigger
|
|
660
|
+
render={
|
|
661
|
+
<Button variant="outline" size={globalSize}>
|
|
662
|
+
View Terms
|
|
663
|
+
</Button>
|
|
664
|
+
}
|
|
665
|
+
/>
|
|
666
|
+
|
|
667
|
+
<DialogPortal>
|
|
668
|
+
<DialogContent className={contentClass}>
|
|
669
|
+
<DialogHeader>
|
|
670
|
+
<DialogTitle>Terms of Service</DialogTitle>
|
|
671
|
+
<DialogDescription>
|
|
672
|
+
You must accept the new terms to continue using the
|
|
673
|
+
application.
|
|
674
|
+
</DialogDescription>
|
|
675
|
+
</DialogHeader>
|
|
676
|
+
<p className="text-sm text-muted-foreground">
|
|
677
|
+
By clicking accept, you agree to our updated Terms of Service
|
|
678
|
+
and Privacy Policy.
|
|
679
|
+
</p>
|
|
680
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
681
|
+
<DialogClose
|
|
682
|
+
render={<Button variant="outline" size={globalSize} />}
|
|
683
|
+
>
|
|
684
|
+
Decline
|
|
685
|
+
</DialogClose>
|
|
686
|
+
<Button size={globalSize}>Accept</Button>
|
|
687
|
+
</DialogFooter>
|
|
688
|
+
</DialogContent>
|
|
689
|
+
</DialogPortal>
|
|
690
|
+
</Dialog>
|
|
691
|
+
</ExampleSection>
|
|
692
|
+
|
|
693
|
+
<ExampleSection
|
|
694
|
+
label="Large Content Sizing"
|
|
695
|
+
description="Sử dụng sm:max-w-lg cho nội dung lớn hơn."
|
|
696
|
+
codeString={`<Dialog>
|
|
697
|
+
<DialogTrigger
|
|
698
|
+
render={
|
|
699
|
+
<Button variant="outline">
|
|
700
|
+
View Report
|
|
701
|
+
</Button>
|
|
702
|
+
}
|
|
703
|
+
/>
|
|
704
|
+
|
|
705
|
+
<DialogPortal><DialogContent className={contentClass}>
|
|
706
|
+
<DialogHeader>
|
|
707
|
+
<DialogTitle>Detailed Report</DialogTitle>
|
|
708
|
+
<DialogDescription>
|
|
709
|
+
Monthly analytics and performance overview.
|
|
710
|
+
</DialogDescription>
|
|
711
|
+
</DialogHeader>
|
|
712
|
+
<div className="flex h-[200px] items-center justify-center rounded-md border border-border border-dashed bg-muted/20">
|
|
713
|
+
<span className="text-sm text-muted-foreground">
|
|
714
|
+
Large Content Area
|
|
715
|
+
</span>
|
|
716
|
+
</div>
|
|
717
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
718
|
+
<Button>Download PDF</Button>
|
|
719
|
+
</DialogFooter>
|
|
720
|
+
<DialogClose
|
|
721
|
+
render={
|
|
722
|
+
<Button
|
|
723
|
+
variant="ghost"
|
|
724
|
+
className="absolute top-2 right-2"
|
|
725
|
+
size="sm"
|
|
726
|
+
iconOnly
|
|
727
|
+
/>
|
|
728
|
+
}
|
|
729
|
+
>
|
|
730
|
+
<XIcon />
|
|
731
|
+
<span className="sr-only">Close</span>
|
|
732
|
+
</DialogClose>
|
|
733
|
+
</DialogContent></DialogPortal>
|
|
734
|
+
|
|
735
|
+
</Dialog>
|
|
736
|
+
`}
|
|
737
|
+
>
|
|
738
|
+
<Dialog>
|
|
739
|
+
<DialogTrigger
|
|
740
|
+
render={
|
|
741
|
+
<Button variant="outline" size={globalSize}>
|
|
742
|
+
View Report
|
|
743
|
+
</Button>
|
|
744
|
+
}
|
|
745
|
+
/>
|
|
746
|
+
|
|
747
|
+
<DialogPortal>
|
|
748
|
+
<DialogContent className={contentClass}>
|
|
749
|
+
<DialogHeader>
|
|
750
|
+
<DialogTitle>Detailed Report</DialogTitle>
|
|
751
|
+
<DialogDescription>
|
|
752
|
+
Monthly analytics and performance overview.
|
|
753
|
+
</DialogDescription>
|
|
754
|
+
</DialogHeader>
|
|
755
|
+
<div className="flex h-[200px] items-center justify-center rounded-md border border-border border-dashed bg-muted/20">
|
|
756
|
+
<span className="text-sm text-muted-foreground">
|
|
757
|
+
Large Content Area
|
|
758
|
+
</span>
|
|
759
|
+
</div>
|
|
760
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
761
|
+
<Button size={globalSize}>Download PDF</Button>
|
|
762
|
+
</DialogFooter>
|
|
763
|
+
<DialogClose
|
|
764
|
+
render={
|
|
765
|
+
<Button
|
|
766
|
+
variant="ghost"
|
|
767
|
+
className="absolute top-2 right-2"
|
|
768
|
+
size="sm"
|
|
769
|
+
iconOnly
|
|
770
|
+
/>
|
|
771
|
+
}
|
|
772
|
+
>
|
|
773
|
+
<XIcon />
|
|
774
|
+
<span className="sr-only">Close</span>
|
|
775
|
+
</DialogClose>
|
|
776
|
+
</DialogContent>
|
|
777
|
+
</DialogPortal>
|
|
778
|
+
</Dialog>
|
|
779
|
+
</ExampleSection>
|
|
780
|
+
</ExampleGrid>
|
|
781
|
+
|
|
782
|
+
<ExampleGrid>
|
|
783
|
+
<ExampleSection
|
|
784
|
+
label="Controlled State"
|
|
785
|
+
description="Sử dụng open và onOpenChange để quản lý trạng thái đóng mở bằng React state."
|
|
786
|
+
codeString={`<div className="w-full flex flex-col gap-4 items-center justify-center">
|
|
787
|
+
<div className="flex gap-4 items-center">
|
|
788
|
+
<Button onClick={() => setControlledOpen(true)} variant="outline">
|
|
789
|
+
Open Controlled Dialog
|
|
790
|
+
</Button>
|
|
791
|
+
<span className="text-sm text-muted-foreground font-mono">
|
|
792
|
+
State: {controlledOpen ? "true" : "false"}
|
|
793
|
+
</span>
|
|
794
|
+
</div>
|
|
795
|
+
|
|
796
|
+
<Dialog open={controlledOpen} onOpenChange={setControlledOpen}>
|
|
797
|
+
|
|
798
|
+
<DialogPortal><DialogContent className={contentClass}>
|
|
799
|
+
<DialogHeader>
|
|
800
|
+
<DialogTitle>Controlled Dialog</DialogTitle>
|
|
801
|
+
<DialogDescription>
|
|
802
|
+
Trạng thái của dialog này được quản lý hoàn toàn bởi React state bên ngoài.
|
|
803
|
+
</DialogDescription>
|
|
804
|
+
</DialogHeader>
|
|
805
|
+
<p className="text-sm text-foreground">Bạn có thể đóng bằng nút bên dưới hoặc dấu X.</p>
|
|
806
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
807
|
+
<Button color="primary" onClick={() => setControlledOpen(false)}>
|
|
808
|
+
Close Manually
|
|
809
|
+
</Button>
|
|
810
|
+
</DialogFooter>
|
|
811
|
+
<DialogClose
|
|
812
|
+
render={
|
|
813
|
+
<Button
|
|
814
|
+
variant="ghost"
|
|
815
|
+
className="absolute top-2 right-2"
|
|
816
|
+
size="sm"
|
|
817
|
+
iconOnly
|
|
818
|
+
/>
|
|
819
|
+
}
|
|
820
|
+
>
|
|
821
|
+
<XIcon />
|
|
822
|
+
<span className="sr-only">Close</span>
|
|
823
|
+
</DialogClose>
|
|
824
|
+
</DialogContent></DialogPortal>
|
|
825
|
+
|
|
826
|
+
</Dialog>
|
|
827
|
+
</div>
|
|
828
|
+
`}
|
|
829
|
+
>
|
|
830
|
+
<div className="w-full flex flex-col gap-4 items-center justify-center">
|
|
831
|
+
<div className="flex gap-4 items-center">
|
|
832
|
+
<Button
|
|
833
|
+
onClick={() => setControlledOpen(true)}
|
|
834
|
+
variant="outline"
|
|
835
|
+
size={globalSize}
|
|
836
|
+
>
|
|
837
|
+
Open Controlled Dialog
|
|
838
|
+
</Button>
|
|
839
|
+
<span className="text-sm text-muted-foreground font-mono">
|
|
840
|
+
State: {controlledOpen ? "true" : "false"}
|
|
841
|
+
</span>
|
|
842
|
+
</div>
|
|
843
|
+
|
|
844
|
+
<Dialog open={controlledOpen} onOpenChange={setControlledOpen}>
|
|
845
|
+
<DialogPortal>
|
|
846
|
+
<DialogContent className={contentClass}>
|
|
847
|
+
<DialogHeader>
|
|
848
|
+
<DialogTitle>Controlled Dialog</DialogTitle>
|
|
849
|
+
<DialogDescription>
|
|
850
|
+
Trạng thái của dialog này được quản lý hoàn toàn bởi
|
|
851
|
+
React state bên ngoài.
|
|
852
|
+
</DialogDescription>
|
|
853
|
+
</DialogHeader>
|
|
854
|
+
<p className="text-sm text-foreground">
|
|
855
|
+
Bạn có thể đóng bằng nút bên dưới hoặc dấu X.
|
|
856
|
+
</p>
|
|
857
|
+
<DialogFooter className="-mx-4 -mb-4 mt-4 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
858
|
+
<Button
|
|
859
|
+
color="primary"
|
|
860
|
+
onClick={() => setControlledOpen(false)}
|
|
861
|
+
size={globalSize}
|
|
862
|
+
>
|
|
863
|
+
Close Manually
|
|
864
|
+
</Button>
|
|
865
|
+
</DialogFooter>
|
|
866
|
+
<DialogClose
|
|
867
|
+
render={
|
|
868
|
+
<Button
|
|
869
|
+
variant="ghost"
|
|
870
|
+
className="absolute top-2 right-2"
|
|
871
|
+
size="sm"
|
|
872
|
+
iconOnly
|
|
873
|
+
/>
|
|
874
|
+
}
|
|
875
|
+
>
|
|
876
|
+
<XIcon />
|
|
877
|
+
<span className="sr-only">Close</span>
|
|
878
|
+
</DialogClose>
|
|
879
|
+
</DialogContent>
|
|
880
|
+
</DialogPortal>
|
|
881
|
+
</Dialog>
|
|
882
|
+
</div>
|
|
883
|
+
</ExampleSection>
|
|
884
|
+
|
|
885
|
+
<ExampleSection
|
|
886
|
+
label="Sticky Footer (Long Content)"
|
|
887
|
+
description="Ghi đè class của DialogContent thành flex-col để khóa scroll ở phần body."
|
|
888
|
+
codeString={`<Dialog>
|
|
889
|
+
<DialogTrigger
|
|
890
|
+
render={
|
|
891
|
+
<Button variant="outline">
|
|
892
|
+
View Long Content
|
|
893
|
+
</Button>
|
|
894
|
+
}
|
|
895
|
+
/>
|
|
896
|
+
|
|
897
|
+
<DialogPortal><DialogContent className={cn(contentClass, "flex flex-col gap-0 p-0 overflow-hidden")}>
|
|
898
|
+
<DialogHeader className="shrink-0 p-4 pb-0">
|
|
899
|
+
<DialogTitle>Terms & Conditions</DialogTitle>
|
|
900
|
+
<DialogDescription>
|
|
901
|
+
Cuộn xuống dưới cùng để có thể đồng ý với điều khoản.
|
|
902
|
+
</DialogDescription>
|
|
903
|
+
</DialogHeader>
|
|
904
|
+
<div className="flex-1 min-h-0 overflow-y-auto p-4">
|
|
905
|
+
<div className="flex h-[800px] flex-col items-center justify-between rounded-md border border-border border-dashed bg-muted/20 py-8">
|
|
906
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
907
|
+
START OF CONTENT
|
|
908
|
+
</span>
|
|
909
|
+
<div className="flex flex-col items-center gap-2">
|
|
910
|
+
<span className="text-4xl">👇</span>
|
|
911
|
+
<span className="text-sm text-muted-foreground">Keep scrolling</span>
|
|
912
|
+
</div>
|
|
913
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
914
|
+
END OF CONTENT
|
|
915
|
+
</span>
|
|
916
|
+
</div>
|
|
917
|
+
</div>
|
|
918
|
+
<DialogFooter className="shrink-0 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
919
|
+
<DialogClose
|
|
920
|
+
render={<Button variant="ghost" />}
|
|
921
|
+
>
|
|
922
|
+
Cancel
|
|
923
|
+
</DialogClose>
|
|
924
|
+
<Button>I Agree</Button>
|
|
925
|
+
</DialogFooter>
|
|
926
|
+
<DialogClose
|
|
927
|
+
render={
|
|
928
|
+
<Button
|
|
929
|
+
variant="ghost"
|
|
930
|
+
className="absolute top-2 right-2"
|
|
931
|
+
size="sm"
|
|
932
|
+
iconOnly
|
|
933
|
+
/>
|
|
934
|
+
}
|
|
935
|
+
>
|
|
936
|
+
<XIcon />
|
|
937
|
+
<span className="sr-only">Close</span>
|
|
938
|
+
</DialogClose>
|
|
939
|
+
</DialogContent></DialogPortal>
|
|
940
|
+
|
|
941
|
+
</Dialog>
|
|
942
|
+
`}
|
|
943
|
+
>
|
|
944
|
+
<Dialog>
|
|
945
|
+
<DialogTrigger
|
|
946
|
+
render={
|
|
947
|
+
<Button variant="outline" size={globalSize}>
|
|
948
|
+
View Long Content
|
|
949
|
+
</Button>
|
|
950
|
+
}
|
|
951
|
+
/>
|
|
952
|
+
|
|
953
|
+
<DialogPortal>
|
|
954
|
+
<DialogContent
|
|
955
|
+
className={cn(
|
|
956
|
+
contentClass,
|
|
957
|
+
"flex flex-col gap-0 p-0 overflow-hidden",
|
|
958
|
+
)}
|
|
959
|
+
>
|
|
960
|
+
<DialogHeader className="shrink-0 p-4 pb-0">
|
|
961
|
+
<DialogTitle>Terms & Conditions</DialogTitle>
|
|
962
|
+
<DialogDescription>
|
|
963
|
+
Cuộn xuống dưới cùng để có thể đồng ý với điều khoản.
|
|
964
|
+
</DialogDescription>
|
|
965
|
+
</DialogHeader>
|
|
966
|
+
<div className="flex-1 min-h-0 overflow-y-auto p-4">
|
|
967
|
+
<div className="flex h-[800px] flex-col items-center justify-between rounded-md border border-border border-dashed bg-muted/20 py-8">
|
|
968
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
969
|
+
START OF CONTENT
|
|
970
|
+
</span>
|
|
971
|
+
<div className="flex flex-col items-center gap-2">
|
|
972
|
+
<span className="text-4xl">👇</span>
|
|
973
|
+
<span className="text-sm text-muted-foreground">
|
|
974
|
+
Keep scrolling
|
|
975
|
+
</span>
|
|
976
|
+
</div>
|
|
977
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
978
|
+
END OF CONTENT
|
|
979
|
+
</span>
|
|
980
|
+
</div>
|
|
981
|
+
</div>
|
|
982
|
+
<DialogFooter className="shrink-0 rounded-b-xl border-t border-t-border bg-muted/50 p-4">
|
|
983
|
+
<DialogClose
|
|
984
|
+
render={<Button variant="ghost" size={globalSize} />}
|
|
985
|
+
>
|
|
986
|
+
Cancel
|
|
987
|
+
</DialogClose>
|
|
988
|
+
<Button size={globalSize}>I Agree</Button>
|
|
989
|
+
</DialogFooter>
|
|
990
|
+
<DialogClose
|
|
991
|
+
render={
|
|
992
|
+
<Button
|
|
993
|
+
variant="ghost"
|
|
994
|
+
className="absolute top-2 right-2"
|
|
995
|
+
size="sm"
|
|
996
|
+
iconOnly
|
|
997
|
+
/>
|
|
998
|
+
}
|
|
999
|
+
>
|
|
1000
|
+
<XIcon />
|
|
1001
|
+
<span className="sr-only">Close</span>
|
|
1002
|
+
</DialogClose>
|
|
1003
|
+
</DialogContent>
|
|
1004
|
+
</DialogPortal>
|
|
1005
|
+
</Dialog>
|
|
1006
|
+
</ExampleSection>
|
|
1007
|
+
|
|
1008
|
+
{/* ── Use Case Comparison ─────────────────────── */}
|
|
1009
|
+
<ExampleSection
|
|
1010
|
+
label="🧭 Use Case Comparison"
|
|
1011
|
+
description="Các kịch bản thực tế giúp bạn quyết định nên dùng Micro hay Macro."
|
|
1012
|
+
fullWidth
|
|
1013
|
+
codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
1014
|
+
{/* ── Story 1: Macro wins ── */}
|
|
1015
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
1016
|
+
<div className="flex items-start gap-3">
|
|
1017
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
1018
|
+
<CheckCircle2Icon className="size-4" aria-hidden="true" />
|
|
1019
|
+
</span>
|
|
1020
|
+
<div>
|
|
1021
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
1022
|
+
Story 1 · Dùng Macro
|
|
1023
|
+
</p>
|
|
1024
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
1025
|
+
Cảnh báo hoặc Form cơ bản
|
|
1026
|
+
</h3>
|
|
1027
|
+
</div>
|
|
1028
|
+
</div>
|
|
1029
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
1030
|
+
Khi bạn chỉ cần một tiêu đề, mô tả và vài nút bấm ở footer (hoặc 1 form ngắn), Macro giúp bạn không phải khai báo hàng loạt component con.
|
|
1031
|
+
</p>
|
|
1032
|
+
</div>
|
|
1033
|
+
|
|
1034
|
+
{/* ── Story 2: Micro wins ── */}
|
|
1035
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
1036
|
+
<div className="flex items-start gap-3">
|
|
1037
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
1038
|
+
<LayersIcon className="size-4" aria-hidden="true" />
|
|
1039
|
+
</span>
|
|
1040
|
+
<div>
|
|
1041
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
1042
|
+
Story 2 · Dùng Micro
|
|
1043
|
+
</p>
|
|
1044
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
1045
|
+
Layout tuỳ chỉnh phức tạp
|
|
1046
|
+
</h3>
|
|
1047
|
+
</div>
|
|
1048
|
+
</div>
|
|
1049
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
1050
|
+
Khi bạn muốn Header có hình ảnh/icon đặc biệt, bỏ qua Footer chuẩn, hoặc có layout split-pane phức tạp bên trong Dialog. Micro cho phép bạn tự do thay đổi từng phần.
|
|
1051
|
+
</p>
|
|
1052
|
+
</div>
|
|
1053
|
+
</div>`}
|
|
1054
|
+
>
|
|
1055
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
1056
|
+
{/* ── Story 1: Macro wins ── */}
|
|
1057
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
1058
|
+
<div className="flex items-start gap-3">
|
|
1059
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
1060
|
+
<CheckCircle2Icon className="size-4" aria-hidden="true" />
|
|
1061
|
+
</span>
|
|
1062
|
+
<div>
|
|
1063
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
1064
|
+
Story 1 · Dùng Macro
|
|
1065
|
+
</p>
|
|
1066
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
1067
|
+
Cảnh báo hoặc Form cơ bản
|
|
1068
|
+
</h3>
|
|
1069
|
+
</div>
|
|
1070
|
+
</div>
|
|
1071
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
1072
|
+
Khi bạn chỉ cần một tiêu đề, mô tả và vài nút bấm ở footer (hoặc
|
|
1073
|
+
1 form ngắn), Macro giúp bạn không phải khai báo hàng loạt
|
|
1074
|
+
component con.
|
|
1075
|
+
</p>
|
|
1076
|
+
</div>
|
|
1077
|
+
|
|
1078
|
+
{/* ── Story 2: Micro wins ── */}
|
|
1079
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
1080
|
+
<div className="flex items-start gap-3">
|
|
1081
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
1082
|
+
<LayersIcon className="size-4" aria-hidden="true" />
|
|
1083
|
+
</span>
|
|
1084
|
+
<div>
|
|
1085
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
1086
|
+
Story 2 · Dùng Micro
|
|
1087
|
+
</p>
|
|
1088
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
1089
|
+
Layout tuỳ chỉnh phức tạp
|
|
1090
|
+
</h3>
|
|
1091
|
+
</div>
|
|
1092
|
+
</div>
|
|
1093
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
1094
|
+
Khi bạn muốn Header có hình ảnh/icon đặc biệt, bỏ qua Footer
|
|
1095
|
+
chuẩn, hoặc có layout split-pane phức tạp bên trong Dialog.
|
|
1096
|
+
Micro cho phép bạn tự do thay đổi từng phần.
|
|
1097
|
+
</p>
|
|
1098
|
+
</div>
|
|
1099
|
+
</div>
|
|
1100
|
+
</ExampleSection>
|
|
1101
|
+
</ExampleGrid>
|
|
1102
|
+
</div>
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// ──────────────────────────────────────────────────────────
|
|
1107
|
+
// Main Showcase
|
|
1108
|
+
// ──────────────────────────────────────────────────────────
|
|
1109
|
+
export default function DialogShowcase() {
|
|
1110
|
+
const { size: globalSize } = useDevContext();
|
|
1111
|
+
return (
|
|
1112
|
+
<Showcase
|
|
1113
|
+
title="Dialog"
|
|
1114
|
+
description="Một cửa sổ phương thức làm gián đoạn người dùng với nội dung quan trọng và mong đợi phản hồi."
|
|
1115
|
+
tabs={[
|
|
1116
|
+
{
|
|
1117
|
+
label: "Micro (Primitive)",
|
|
1118
|
+
content: <DialogMicroShowcase globalSize={globalSize} />,
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
label: "Macro (Preset)",
|
|
1122
|
+
content: <DialogMacroShowcase globalSize={globalSize} />,
|
|
1123
|
+
},
|
|
1124
|
+
]}
|
|
1125
|
+
generalConcept={
|
|
1126
|
+
<ShowcaseDocs>
|
|
1127
|
+
<DocsH3>Cấu trúc và Định tuyến</DocsH3>
|
|
1128
|
+
<DocsP>
|
|
1129
|
+
<DocsCode>DialogPreset</DocsCode> là một component Macro giúp rút
|
|
1130
|
+
gọn API của Dialog, bao gồm Trigger, Header, Content và Footer.
|
|
1131
|
+
</DocsP>
|
|
1132
|
+
<DocsP>
|
|
1133
|
+
Dialog luôn được render thông qua Portal để tránh bị che khuất bởi
|
|
1134
|
+
các container có <DocsCode>overflow: hidden</DocsCode> hoặc{" "}
|
|
1135
|
+
<DocsCode>z-index</DocsCode> thấp.
|
|
1136
|
+
</DocsP>
|
|
1137
|
+
</ShowcaseDocs>
|
|
1138
|
+
}
|
|
1139
|
+
/>
|
|
1140
|
+
);
|
|
1141
|
+
}
|