@nofinite/nui 1.1.2 → 2.0.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/README.md +61 -48
- package/dist/components/accordion/Accordion.cjs +1 -1
- package/dist/components/accordion/Accordion.cjs.map +1 -1
- package/dist/components/accordion/Accordion.js +64 -43
- package/dist/components/accordion/Accordion.js.map +1 -1
- package/dist/components/alert/Alert.cjs +1 -1
- package/dist/components/alert/Alert.cjs.map +1 -1
- package/dist/components/alert/Alert.js +39 -25
- package/dist/components/alert/Alert.js.map +1 -1
- package/dist/components/avatar/Avatar.cjs +1 -1
- package/dist/components/avatar/Avatar.cjs.map +1 -1
- package/dist/components/avatar/Avatar.js +58 -44
- package/dist/components/avatar/Avatar.js.map +1 -1
- package/dist/components/avatar/AvatarGroup.cjs +1 -1
- package/dist/components/avatar/AvatarGroup.cjs.map +1 -1
- package/dist/components/avatar/AvatarGroup.js +34 -25
- package/dist/components/avatar/AvatarGroup.js.map +1 -1
- package/dist/components/badge/Badge.cjs +1 -1
- package/dist/components/badge/Badge.cjs.map +1 -1
- package/dist/components/badge/Badge.js +43 -68
- package/dist/components/badge/Badge.js.map +1 -1
- package/dist/components/badge/BadgeGroup.cjs +1 -1
- package/dist/components/badge/BadgeGroup.cjs.map +1 -1
- package/dist/components/badge/BadgeGroup.js +20 -10
- package/dist/components/badge/BadgeGroup.js.map +1 -1
- package/dist/components/breadcrumbs/Breadcrumbs.cjs +1 -1
- package/dist/components/breadcrumbs/Breadcrumbs.cjs.map +1 -1
- package/dist/components/breadcrumbs/Breadcrumbs.js +59 -39
- package/dist/components/breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/button/Button.cjs +1 -1
- package/dist/components/button/Button.cjs.map +1 -1
- package/dist/components/button/Button.js +52 -17
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/card/Card.cjs +1 -1
- package/dist/components/card/Card.cjs.map +1 -1
- package/dist/components/card/Card.js +44 -41
- package/dist/components/card/Card.js.map +1 -1
- package/dist/components/checkbox/Checkbox.cjs +1 -1
- package/dist/components/checkbox/Checkbox.cjs.map +1 -1
- package/dist/components/checkbox/Checkbox.js +59 -40
- package/dist/components/checkbox/Checkbox.js.map +1 -1
- package/dist/components/chip/Chip.cjs +1 -1
- package/dist/components/chip/Chip.cjs.map +1 -1
- package/dist/components/chip/Chip.js +67 -47
- package/dist/components/chip/Chip.js.map +1 -1
- package/dist/components/combobox/Combobox.cjs +1 -1
- package/dist/components/combobox/Combobox.cjs.map +1 -1
- package/dist/components/combobox/Combobox.js +123 -108
- package/dist/components/combobox/Combobox.js.map +1 -1
- package/dist/components/commandpalette/CommandPalette.cjs +1 -1
- package/dist/components/commandpalette/CommandPalette.cjs.map +1 -1
- package/dist/components/commandpalette/CommandPalette.js +96 -73
- package/dist/components/commandpalette/CommandPalette.js.map +1 -1
- package/dist/components/contextmenu/ContextMenu.cjs +1 -1
- package/dist/components/contextmenu/ContextMenu.cjs.map +1 -1
- package/dist/components/contextmenu/ContextMenu.js +79 -58
- package/dist/components/contextmenu/ContextMenu.js.map +1 -1
- package/dist/components/datagrid/DataGrid.cjs +1 -1
- package/dist/components/datagrid/DataGrid.cjs.map +1 -1
- package/dist/components/datagrid/DataGrid.js +184 -202
- package/dist/components/datagrid/DataGrid.js.map +1 -1
- package/dist/components/datepicker/DatePicker.cjs +1 -1
- package/dist/components/datepicker/DatePicker.cjs.map +1 -1
- package/dist/components/datepicker/DatePicker.js +197 -164
- package/dist/components/datepicker/DatePicker.js.map +1 -1
- package/dist/components/daterangepicker/DateRangePicker.cjs +1 -1
- package/dist/components/daterangepicker/DateRangePicker.cjs.map +1 -1
- package/dist/components/daterangepicker/DateRangePicker.js +254 -213
- package/dist/components/daterangepicker/DateRangePicker.js.map +1 -1
- package/dist/components/dialog/DialogProvider.cjs +2 -0
- package/dist/components/dialog/DialogProvider.cjs.map +1 -0
- package/dist/components/dialog/DialogProvider.js +71 -0
- package/dist/components/dialog/DialogProvider.js.map +1 -0
- package/dist/components/dialog/dialogStore.cjs +2 -0
- package/dist/components/dialog/dialogStore.cjs.map +1 -0
- package/dist/components/dialog/dialogStore.js +60 -0
- package/dist/components/dialog/dialogStore.js.map +1 -0
- package/dist/components/drawer/Drawer.cjs +1 -1
- package/dist/components/drawer/Drawer.cjs.map +1 -1
- package/dist/components/drawer/Drawer.js +69 -47
- package/dist/components/drawer/Drawer.js.map +1 -1
- package/dist/components/dropdown/Dropdown.cjs +1 -1
- package/dist/components/dropdown/Dropdown.cjs.map +1 -1
- package/dist/components/dropdown/Dropdown.js +134 -108
- package/dist/components/dropdown/Dropdown.js.map +1 -1
- package/dist/components/fileuploader/FileUploader.cjs +1 -1
- package/dist/components/fileuploader/FileUploader.cjs.map +1 -1
- package/dist/components/fileuploader/FileUploader.js +96 -61
- package/dist/components/fileuploader/FileUploader.js.map +1 -1
- package/dist/components/hovercard/HoverCard.cjs +1 -1
- package/dist/components/hovercard/HoverCard.cjs.map +1 -1
- package/dist/components/hovercard/HoverCard.js +124 -69
- package/dist/components/hovercard/HoverCard.js.map +1 -1
- package/dist/components/input/Input.cjs +1 -1
- package/dist/components/input/Input.cjs.map +1 -1
- package/dist/components/input/Input.js +62 -37
- package/dist/components/input/Input.js.map +1 -1
- package/dist/components/layout/Container.cjs +1 -1
- package/dist/components/layout/Container.cjs.map +1 -1
- package/dist/components/layout/Container.js +21 -30
- package/dist/components/layout/Container.js.map +1 -1
- package/dist/components/layout/Flex.cjs +1 -1
- package/dist/components/layout/Flex.cjs.map +1 -1
- package/dist/components/layout/Flex.js +36 -19
- package/dist/components/layout/Flex.js.map +1 -1
- package/dist/components/layout/Grid.cjs +1 -1
- package/dist/components/layout/Grid.cjs.map +1 -1
- package/dist/components/layout/Grid.js +30 -18
- package/dist/components/layout/Grid.js.map +1 -1
- package/dist/components/link/Link.cjs +2 -0
- package/dist/components/link/Link.cjs.map +1 -0
- package/dist/components/link/Link.js +41 -0
- package/dist/components/link/Link.js.map +1 -0
- package/dist/components/megamenu/MegaMenu.cjs +1 -1
- package/dist/components/megamenu/MegaMenu.cjs.map +1 -1
- package/dist/components/megamenu/MegaMenu.js +107 -38
- package/dist/components/megamenu/MegaMenu.js.map +1 -1
- package/dist/components/modal/Modal.cjs +1 -1
- package/dist/components/modal/Modal.cjs.map +1 -1
- package/dist/components/modal/Modal.js +91 -83
- package/dist/components/modal/Modal.js.map +1 -1
- package/dist/components/multiselect/MultiSelect.cjs +2 -0
- package/dist/components/multiselect/MultiSelect.cjs.map +1 -0
- package/dist/components/multiselect/MultiSelect.js +176 -0
- package/dist/components/multiselect/MultiSelect.js.map +1 -0
- package/dist/components/nuiprovider/NUIProvider.cjs +2 -0
- package/dist/components/nuiprovider/NUIProvider.cjs.map +1 -0
- package/dist/components/nuiprovider/NUIProvider.js +36 -0
- package/dist/components/nuiprovider/NUIProvider.js.map +1 -0
- package/dist/components/pagination/Pagination.cjs +1 -1
- package/dist/components/pagination/Pagination.cjs.map +1 -1
- package/dist/components/pagination/Pagination.js +74 -41
- package/dist/components/pagination/Pagination.js.map +1 -1
- package/dist/components/popover/Popover.cjs +1 -1
- package/dist/components/popover/Popover.cjs.map +1 -1
- package/dist/components/popover/Popover.js +99 -100
- package/dist/components/popover/Popover.js.map +1 -1
- package/dist/components/progress/Progress.cjs +1 -1
- package/dist/components/progress/Progress.cjs.map +1 -1
- package/dist/components/progress/Progress.js +44 -22
- package/dist/components/progress/Progress.js.map +1 -1
- package/dist/components/radiogroup/RadioGroup.cjs +1 -1
- package/dist/components/radiogroup/RadioGroup.cjs.map +1 -1
- package/dist/components/radiogroup/RadioGroup.js +69 -74
- package/dist/components/radiogroup/RadioGroup.js.map +1 -1
- package/dist/components/rating/Rating.cjs +1 -1
- package/dist/components/rating/Rating.cjs.map +1 -1
- package/dist/components/rating/Rating.js +72 -33
- package/dist/components/rating/Rating.js.map +1 -1
- package/dist/components/resizable/Resizable.cjs +2 -0
- package/dist/components/resizable/Resizable.cjs.map +1 -0
- package/dist/components/resizable/Resizable.js +134 -0
- package/dist/components/resizable/Resizable.js.map +1 -0
- package/dist/components/select/Select.cjs +1 -1
- package/dist/components/select/Select.cjs.map +1 -1
- package/dist/components/select/Select.js +114 -113
- package/dist/components/select/Select.js.map +1 -1
- package/dist/components/skeleton/Skeleton.cjs +1 -1
- package/dist/components/skeleton/Skeleton.cjs.map +1 -1
- package/dist/components/skeleton/Skeleton.js +90 -67
- package/dist/components/skeleton/Skeleton.js.map +1 -1
- package/dist/components/slider/Slider.cjs +1 -1
- package/dist/components/slider/Slider.cjs.map +1 -1
- package/dist/components/slider/Slider.js +85 -82
- package/dist/components/slider/Slider.js.map +1 -1
- package/dist/components/spinner/Spinner.cjs +1 -1
- package/dist/components/spinner/Spinner.cjs.map +1 -1
- package/dist/components/spinner/Spinner.js +60 -17
- package/dist/components/spinner/Spinner.js.map +1 -1
- package/dist/components/stepper/Stepper.cjs +1 -5
- package/dist/components/stepper/Stepper.cjs.map +1 -1
- package/dist/components/stepper/Stepper.js +65 -39
- package/dist/components/stepper/Stepper.js.map +1 -1
- package/dist/components/switch/Switch.cjs +1 -1
- package/dist/components/switch/Switch.cjs.map +1 -1
- package/dist/components/switch/Switch.js +89 -62
- package/dist/components/switch/Switch.js.map +1 -1
- package/dist/components/table/Table.cjs +1 -1
- package/dist/components/table/Table.cjs.map +1 -1
- package/dist/components/table/Table.js +62 -35
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/tabs/Tabs.cjs +1 -1
- package/dist/components/tabs/Tabs.cjs.map +1 -1
- package/dist/components/tabs/Tabs.js +110 -50
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/components/textarea/Textarea.cjs +1 -1
- package/dist/components/textarea/Textarea.cjs.map +1 -1
- package/dist/components/textarea/Textarea.js +63 -58
- package/dist/components/textarea/Textarea.js.map +1 -1
- package/dist/components/timepicker/TimePicker.cjs +2 -0
- package/dist/components/timepicker/TimePicker.cjs.map +1 -0
- package/dist/components/timepicker/TimePicker.js +159 -0
- package/dist/components/timepicker/TimePicker.js.map +1 -0
- package/dist/components/timerangepicker/TimeRangePicker.cjs +2 -0
- package/dist/components/timerangepicker/TimeRangePicker.cjs.map +1 -0
- package/dist/components/timerangepicker/TimeRangePicker.js +208 -0
- package/dist/components/timerangepicker/TimeRangePicker.js.map +1 -0
- package/dist/components/toast/Toast.cjs +1 -1
- package/dist/components/toast/Toast.cjs.map +1 -1
- package/dist/components/toast/Toast.js +91 -38
- package/dist/components/toast/Toast.js.map +1 -1
- package/dist/components/tooltip/Tooltip.cjs +1 -1
- package/dist/components/tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/tooltip/Tooltip.js +72 -56
- package/dist/components/tooltip/Tooltip.js.map +1 -1
- package/dist/components/treeview/TreeView.cjs +1 -1
- package/dist/components/treeview/TreeView.cjs.map +1 -1
- package/dist/components/treeview/TreeView.js +120 -90
- package/dist/components/treeview/TreeView.js.map +1 -1
- package/dist/components/virtuallist/VirtualList.cjs +1 -1
- package/dist/components/virtuallist/VirtualList.cjs.map +1 -1
- package/dist/components/virtuallist/VirtualList.js +52 -34
- package/dist/components/virtuallist/VirtualList.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -0
- package/dist/index.js +118 -107
- package/dist/index.js.map +1 -1
- package/dist/package.json +49 -6
- package/dist/types/components/accordion/Accordion.d.ts +7 -3
- package/dist/types/components/accordion/Accordion.d.ts.map +1 -1
- package/dist/types/components/alert/Alert.d.ts +18 -5
- package/dist/types/components/alert/Alert.d.ts.map +1 -1
- package/dist/types/components/avatar/Avatar.d.ts +12 -8
- package/dist/types/components/avatar/Avatar.d.ts.map +1 -1
- package/dist/types/components/avatar/AvatarGroup.d.ts +11 -4
- package/dist/types/components/avatar/AvatarGroup.d.ts.map +1 -1
- package/dist/types/components/badge/Badge.d.ts +19 -11
- package/dist/types/components/badge/Badge.d.ts.map +1 -1
- package/dist/types/components/badge/BadgeGroup.d.ts +7 -4
- package/dist/types/components/badge/BadgeGroup.d.ts.map +1 -1
- package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +14 -6
- package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts.map +1 -1
- package/dist/types/components/button/Button.d.ts +25 -10
- package/dist/types/components/button/Button.d.ts.map +1 -1
- package/dist/types/components/card/Card.d.ts +12 -21
- package/dist/types/components/card/Card.d.ts.map +1 -1
- package/dist/types/components/checkbox/Checkbox.d.ts +12 -7
- package/dist/types/components/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/types/components/chip/Chip.d.ts +14 -11
- package/dist/types/components/chip/Chip.d.ts.map +1 -1
- package/dist/types/components/combobox/Combobox.d.ts +15 -4
- package/dist/types/components/combobox/Combobox.d.ts.map +1 -1
- package/dist/types/components/commandpalette/CommandPalette.d.ts +12 -3
- package/dist/types/components/commandpalette/CommandPalette.d.ts.map +1 -1
- package/dist/types/components/contextmenu/ContextMenu.d.ts +14 -6
- package/dist/types/components/contextmenu/ContextMenu.d.ts.map +1 -1
- package/dist/types/components/datagrid/DataGrid.d.ts +16 -4
- package/dist/types/components/datagrid/DataGrid.d.ts.map +1 -1
- package/dist/types/components/datepicker/DatePicker.d.ts +13 -1
- package/dist/types/components/datepicker/DatePicker.d.ts.map +1 -1
- package/dist/types/components/daterangepicker/DateRangePicker.d.ts +3 -1
- package/dist/types/components/daterangepicker/DateRangePicker.d.ts.map +1 -1
- package/dist/types/components/dialog/DialogProvider.d.ts +2 -0
- package/dist/types/components/dialog/DialogProvider.d.ts.map +1 -0
- package/dist/types/components/dialog/dialogStore.d.ts +42 -0
- package/dist/types/components/dialog/dialogStore.d.ts.map +1 -0
- package/dist/types/components/drawer/Drawer.d.ts +18 -4
- package/dist/types/components/drawer/Drawer.d.ts.map +1 -1
- package/dist/types/components/dropdown/Dropdown.d.ts +21 -16
- package/dist/types/components/dropdown/Dropdown.d.ts.map +1 -1
- package/dist/types/components/fileuploader/FileUploader.d.ts +22 -3
- package/dist/types/components/fileuploader/FileUploader.d.ts.map +1 -1
- package/dist/types/components/hovercard/HoverCard.d.ts +45 -5
- package/dist/types/components/hovercard/HoverCard.d.ts.map +1 -1
- package/dist/types/components/input/Input.d.ts +20 -10
- package/dist/types/components/input/Input.d.ts.map +1 -1
- package/dist/types/components/layout/Container.d.ts +8 -4
- package/dist/types/components/layout/Container.d.ts.map +1 -1
- package/dist/types/components/layout/Flex.d.ts +27 -10
- package/dist/types/components/layout/Flex.d.ts.map +1 -1
- package/dist/types/components/layout/Grid.d.ts +11 -5
- package/dist/types/components/layout/Grid.d.ts.map +1 -1
- package/dist/types/components/link/Link.d.ts +22 -0
- package/dist/types/components/link/Link.d.ts.map +1 -0
- package/dist/types/components/megamenu/MegaMenu.d.ts +8 -11
- package/dist/types/components/megamenu/MegaMenu.d.ts.map +1 -1
- package/dist/types/components/modal/Modal.d.ts +8 -7
- package/dist/types/components/modal/Modal.d.ts.map +1 -1
- package/dist/types/components/multiselect/MultiSelect.d.ts +33 -0
- package/dist/types/components/multiselect/MultiSelect.d.ts.map +1 -0
- package/dist/types/components/nuiprovider/NUIProvider.d.ts +29 -0
- package/dist/types/components/nuiprovider/NUIProvider.d.ts.map +1 -0
- package/dist/types/components/pagination/Pagination.d.ts +17 -3
- package/dist/types/components/pagination/Pagination.d.ts.map +1 -1
- package/dist/types/components/popover/Popover.d.ts +54 -16
- package/dist/types/components/popover/Popover.d.ts.map +1 -1
- package/dist/types/components/progress/Progress.d.ts +17 -7
- package/dist/types/components/progress/Progress.d.ts.map +1 -1
- package/dist/types/components/radiogroup/RadioGroup.d.ts +15 -10
- package/dist/types/components/radiogroup/RadioGroup.d.ts.map +1 -1
- package/dist/types/components/rating/Rating.d.ts +24 -10
- package/dist/types/components/rating/Rating.d.ts.map +1 -1
- package/dist/types/components/resizable/Resizable.d.ts +24 -0
- package/dist/types/components/resizable/Resizable.d.ts.map +1 -0
- package/dist/types/components/select/Select.d.ts +17 -8
- package/dist/types/components/select/Select.d.ts.map +1 -1
- package/dist/types/components/skeleton/Skeleton.d.ts +37 -36
- package/dist/types/components/skeleton/Skeleton.d.ts.map +1 -1
- package/dist/types/components/slider/Slider.d.ts +15 -4
- package/dist/types/components/slider/Slider.d.ts.map +1 -1
- package/dist/types/components/spinner/Spinner.d.ts +14 -4
- package/dist/types/components/spinner/Spinner.d.ts.map +1 -1
- package/dist/types/components/stepper/Stepper.d.ts +17 -3
- package/dist/types/components/stepper/Stepper.d.ts.map +1 -1
- package/dist/types/components/switch/Switch.d.ts +20 -5
- package/dist/types/components/switch/Switch.d.ts.map +1 -1
- package/dist/types/components/table/Table.d.ts +24 -4
- package/dist/types/components/table/Table.d.ts.map +1 -1
- package/dist/types/components/tabs/Tabs.d.ts +25 -12
- package/dist/types/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/types/components/textarea/Textarea.d.ts +8 -5
- package/dist/types/components/textarea/Textarea.d.ts.map +1 -1
- package/dist/types/components/timepicker/TimePicker.d.ts +26 -0
- package/dist/types/components/timepicker/TimePicker.d.ts.map +1 -0
- package/dist/types/components/timerangepicker/TimeRangePicker.d.ts +32 -0
- package/dist/types/components/timerangepicker/TimeRangePicker.d.ts.map +1 -0
- package/dist/types/components/toast/Toast.d.ts +23 -7
- package/dist/types/components/toast/Toast.d.ts.map +1 -1
- package/dist/types/components/tooltip/Tooltip.d.ts +13 -2
- package/dist/types/components/tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/components/treeview/TreeView.d.ts +20 -6
- package/dist/types/components/treeview/TreeView.d.ts.map +1 -1
- package/dist/types/components/virtuallist/VirtualList.d.ts +12 -16
- package/dist/types/components/virtuallist/VirtualList.d.ts.map +1 -1
- package/dist/types/index.d.ts +8 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/cn/cn.d.ts +19 -0
- package/dist/types/utils/cn/cn.d.ts.map +1 -0
- package/dist/types/utils/generateid/generateId.d.ts +7 -0
- package/dist/types/utils/generateid/generateId.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/inertmanager/inertManager.d.ts +13 -0
- package/dist/types/utils/inertmanager/inertManager.d.ts.map +1 -1
- package/dist/types/utils/keyboardnav/keyboardNav.d.ts +17 -6
- package/dist/types/utils/keyboardnav/keyboardNav.d.ts.map +1 -1
- package/dist/types/utils/onclickoutside/onClickOutside.d.ts +9 -1
- package/dist/types/utils/onclickoutside/onClickOutside.d.ts.map +1 -1
- package/dist/types/utils/portal/portal.d.ts +14 -1
- package/dist/types/utils/portal/portal.d.ts.map +1 -1
- package/dist/types/utils/restorefocus/restoreFocus.d.ts +8 -4
- package/dist/types/utils/restorefocus/restoreFocus.d.ts.map +1 -1
- package/dist/types/utils/scrolllock/scrollLock.d.ts +10 -2
- package/dist/types/utils/scrolllock/scrollLock.d.ts.map +1 -1
- package/dist/types/utils/slot/slot.d.ts +12 -0
- package/dist/types/utils/slot/slot.d.ts.map +1 -0
- package/dist/types/utils/trapfocus/trapFocus.d.ts +6 -2
- package/dist/types/utils/trapfocus/trapFocus.d.ts.map +1 -1
- package/dist/utils/cn/cn.cjs +2 -0
- package/dist/utils/cn/cn.cjs.map +1 -0
- package/dist/utils/cn/cn.js +21 -0
- package/dist/utils/cn/cn.js.map +1 -0
- package/dist/utils/inertmanager/inertManager.cjs.map +1 -1
- package/dist/utils/inertmanager/inertManager.js.map +1 -1
- package/dist/utils/onclickoutside/onClickOutside.cjs +1 -1
- package/dist/utils/onclickoutside/onClickOutside.cjs.map +1 -1
- package/dist/utils/onclickoutside/onClickOutside.js +10 -6
- package/dist/utils/onclickoutside/onClickOutside.js.map +1 -1
- package/dist/utils/portal/portal.cjs.map +1 -1
- package/dist/utils/portal/portal.js.map +1 -1
- package/dist/utils/restorefocus/restoreFocus.cjs.map +1 -1
- package/dist/utils/restorefocus/restoreFocus.js.map +1 -1
- package/dist/utils/scrolllock/scrollLock.cjs.map +1 -1
- package/dist/utils/scrolllock/scrollLock.js +7 -0
- package/dist/utils/scrolllock/scrollLock.js.map +1 -1
- package/dist/utils/slot/slot.cjs +2 -0
- package/dist/utils/slot/slot.cjs.map +1 -0
- package/dist/utils/slot/slot.js +57 -0
- package/dist/utils/slot/slot.js.map +1 -0
- package/dist/utils/trapfocus/trapFocus.cjs.map +1 -1
- package/dist/utils/trapfocus/trapFocus.js.map +1 -1
- package/package.json +49 -6
- package/dist/components/layout/HStack.cjs +0 -2
- package/dist/components/layout/HStack.cjs.map +0 -1
- package/dist/components/layout/HStack.js +0 -9
- package/dist/components/layout/HStack.js.map +0 -1
- package/dist/components/layout/Stack.cjs +0 -2
- package/dist/components/layout/Stack.cjs.map +0 -1
- package/dist/components/layout/Stack.js +0 -9
- package/dist/components/layout/Stack.js.map +0 -1
- package/dist/styles/nui.css +0 -1
- package/dist/theme/NUIProvider.cjs +0 -2
- package/dist/theme/NUIProvider.cjs.map +0 -1
- package/dist/theme/NUIProvider.js +0 -34
- package/dist/theme/NUIProvider.js.map +0 -1
- package/dist/theme/useTheme.cjs +0 -2
- package/dist/theme/useTheme.cjs.map +0 -1
- package/dist/theme/useTheme.js +0 -9
- package/dist/theme/useTheme.js.map +0 -1
- package/dist/types/components/layout/HStack.d.ts +0 -8
- package/dist/types/components/layout/HStack.d.ts.map +0 -1
- package/dist/types/components/layout/Stack.d.ts +0 -8
- package/dist/types/components/layout/Stack.d.ts.map +0 -1
- package/dist/types/theme/NUIProvider.d.ts +0 -14
- package/dist/types/theme/NUIProvider.d.ts.map +0 -1
- package/dist/types/theme/useTheme.d.ts +0 -11
- package/dist/types/theme/useTheme.d.ts.map +0 -1
- package/dist/utils/generateid/generateId.cjs +0 -2
- package/dist/utils/generateid/generateId.cjs.map +0 -1
- package/dist/utils/generateid/generateId.js +0 -7
- package/dist/utils/generateid/generateId.js.map +0 -1
- package/dist/utils/keyboardnav/keyboardNav.cjs +0 -2
- package/dist/utils/keyboardnav/keyboardNav.cjs.map +0 -1
- package/dist/utils/keyboardnav/keyboardNav.js +0 -10
- package/dist/utils/keyboardnav/keyboardNav.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.cjs","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"Switch.cjs","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useId, useState } from 'react';\nimport { cn } from '../../utils';\nimport './Switch.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'> {\n /** The controlled checked state of the switch */\n checked?: boolean;\n /** The uncontrolled default checked state */\n defaultChecked?: boolean;\n /** Callback fired when the state changes */\n onChange?: (checked: boolean) => void;\n \n /** Disables the switch, preventing interaction */\n disabled?: boolean;\n /** The primary text label for the switch */\n label?: React.ReactNode;\n /** Secondary descriptive text linked via WAI-ARIA */\n description?: React.ReactNode;\n \n /** Name attribute for native form submission */\n name?: string;\n /** Value submitted in a native form when checked. Defaults to \"on\". */\n value?: string;\n /** The visual size variant. Defaults to 'md'. */\n size?: 'sm' | 'md';\n \n /** Additional CSS classes for the outer wrapping div */\n wrapperClassName?: string;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Switch Component\n * * A WAI-ARIA compliant toggle switch used to turn settings on or off.\n * * Automatically handles native form submission using a hidden input.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n label,\n description,\n id,\n name,\n value,\n size = 'md',\n className,\n wrapperClassName,\n ...props\n },\n ref\n ) => {\n // Unique ID generation for WCAG label and description linkage\n const reactId = useId();\n const switchId = id ?? `nui-switch-${reactId}`;\n const descriptionId = `${switchId}-description`;\n\n // State Management\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const currentChecked = isControlled ? checked : internalChecked;\n\n const toggle = () => {\n if (disabled) return;\n const nextState = !currentChecked;\n if (!isControlled) setInternalChecked(nextState);\n onChange?.(nextState);\n };\n\n // Keyboard Accessibility (Space & Enter)\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault(); // Prevent page scroll on Spacebar\n toggle();\n }\n props.onKeyDown?.(e);\n };\n\n // Robust Label Click Handler\n // Standard <label> clicks only *focus* <button> elements in Safari/Firefox. \n // This handler ensures clicking the text always toggles the state.\n const handleLabelClick = (e: React.MouseEvent) => {\n if (disabled) return;\n e.preventDefault(); \n toggle();\n document.getElementById(switchId)?.focus();\n };\n\n // Hidden input value for standard HTML form submissions\n const hiddenValue = value ?? (currentChecked ? 'on' : 'off');\n\n return (\n <div \n className={cn(\n \"nui-switch-wrapper\", \n disabled && \"nui-switch-wrapper--disabled\", \n wrapperClassName\n )}\n >\n {/* Hidden Form Input */}\n {name && (\n <input type=\"hidden\" name={name} value={currentChecked ? hiddenValue : ''} />\n )}\n\n {/* The Actual Switch (Button) */}\n <button\n ref={ref}\n id={switchId}\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n className={cn(\n \"nui-switch\",\n `nui-switch--${size}`,\n currentChecked && \"nui-switch--checked\",\n className\n )}\n onClick={toggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n {...props}\n >\n <span \n className={cn(\n \"nui-switch__thumb\", \n `nui-switch__thumb--${size}`, \n currentChecked && \"nui-switch__thumb--checked\"\n )} \n aria-hidden=\"true\" \n />\n </button>\n\n {/* Text Content */}\n {(label || description) && (\n <div className=\"nui-switch__text-container\">\n {label && (\n <label \n htmlFor={switchId} \n className=\"nui-switch__label\"\n onClick={handleLabelClick}\n >\n {label}\n </label>\n )}\n {description && (\n <div id={descriptionId} className=\"nui-switch__description\">\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n);\n\nSwitch.displayName = 'Switch';"],"names":["Switch","forwardRef","checked","defaultChecked","onChange","disabled","label","description","id","name","value","size","className","wrapperClassName","props","ref","reactId","useId","switchId","descriptionId","isControlled","internalChecked","setInternalChecked","useState","currentChecked","toggle","nextState","handleKeyDown","handleLabelClick","hiddenValue","jsxs","cn","jsx"],"mappings":"6MA6CaA,EAASC,EAAAA,WACpB,CACE,CACE,QAAAC,EACA,eAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,GACX,MAAAC,EACA,YAAAC,EACA,GAAAC,EACA,KAAAC,EACA,MAAAC,EACA,KAAAC,EAAO,KACP,UAAAC,EACA,iBAAAC,EACA,GAAGC,CAAA,EAELC,IACG,CAEH,MAAMC,EAAUC,EAAAA,MAAA,EACVC,EAAWV,GAAM,cAAcQ,CAAO,GACtCG,EAAgB,GAAGD,CAAQ,eAG3BE,EAAelB,IAAY,OAC3B,CAACmB,EAAiBC,CAAkB,EAAIC,EAAAA,SAASpB,GAAkB,EAAK,EACxEqB,EAAiBJ,EAAelB,EAAUmB,EAE1CI,EAAS,IAAM,CACnB,GAAIpB,EAAU,OACd,MAAMqB,EAAY,CAACF,EACdJ,GAAcE,EAAmBI,CAAS,EAC/CtB,IAAWsB,CAAS,CACtB,EAGMC,EAAiB,GAA8C,EAC/D,EAAE,MAAQ,KAAO,EAAE,MAAQ,WAC7B,EAAE,eAAA,EACFF,EAAA,GAEFX,EAAM,YAAY,CAAC,CACrB,EAKMc,EAAoB,GAAwB,CAC5CvB,IACJ,EAAE,eAAA,EACFoB,EAAA,EACA,SAAS,eAAeP,CAAQ,GAAG,MAAA,EACrC,EAGMW,EAAcnB,IAAUc,EAAiB,KAAO,OAEtD,OACEM,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,qBACA1B,GAAY,+BACZQ,CAAA,EAID,SAAA,CAAAJ,GACCuB,EAAAA,IAAC,SAAM,KAAK,SAAS,KAAAvB,EAAY,MAAOe,EAAiBK,EAAc,EAAA,CAAI,EAI7EG,EAAAA,IAAC,SAAA,CACC,IAAAjB,EACA,GAAIG,EACJ,KAAK,SACL,KAAK,SACL,eAAcM,EACd,gBAAenB,EACf,mBAAkBE,EAAcY,EAAgB,OAChD,UAAWY,EAAAA,GACT,aACA,eAAepB,CAAI,GACnBa,GAAkB,sBAClBZ,CAAA,EAEF,QAASa,EACT,UAAWE,EACX,SAAAtB,EACC,GAAGS,EAEJ,SAAAkB,EAAAA,IAAC,OAAA,CACC,UAAWD,EAAAA,GACT,oBACA,sBAAsBpB,CAAI,GAC1Ba,GAAkB,4BAAA,EAEpB,cAAY,MAAA,CAAA,CACd,CAAA,GAIAlB,GAASC,IACTuB,EAAAA,KAAC,MAAA,CAAI,UAAU,6BACZ,SAAA,CAAAxB,GACC0B,EAAAA,IAAC,QAAA,CACC,QAASd,EACT,UAAU,oBACV,QAASU,EAER,SAAAtB,CAAA,CAAA,EAGJC,GACCyB,EAAAA,IAAC,MAAA,CAAI,GAAIb,EAAe,UAAU,0BAC/B,SAAAZ,CAAA,CACH,CAAA,CAAA,CAEJ,CAAA,CAAA,CAAA,CAIR,CACF,EAEAP,EAAO,YAAc"}
|
|
@@ -1,67 +1,94 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
1
|
+
import { jsxs as f, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as g, useId as K, useState as j } from "react";
|
|
3
3
|
/* empty css */
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
className: `ui-switch-root ${y}`,
|
|
39
|
-
htmlFor: d,
|
|
40
|
-
"aria-disabled": e || void 0,
|
|
41
|
-
children: [
|
|
42
|
-
l && /* @__PURE__ */ i("input", { type: "hidden", name: l, value: t ? b : "" }),
|
|
43
|
-
/* @__PURE__ */ i(
|
|
44
|
-
"button",
|
|
45
|
-
{
|
|
46
|
-
id: d,
|
|
47
|
-
ref: o,
|
|
48
|
-
type: "button",
|
|
49
|
-
role: "switch",
|
|
50
|
-
"aria-checked": t,
|
|
51
|
-
"aria-disabled": e || void 0,
|
|
52
|
-
className: "ui-switch-control",
|
|
53
|
-
"data-state": t ? "on" : "off",
|
|
54
|
-
onClick: N,
|
|
55
|
-
tabIndex: e ? -1 : 0,
|
|
56
|
-
children: /* @__PURE__ */ i("span", { className: "ui-switch-thumb", "aria-hidden": "true" })
|
|
57
|
-
}
|
|
4
|
+
import { cn as a } from "../../utils/cn/cn.js";
|
|
5
|
+
const E = g(
|
|
6
|
+
({
|
|
7
|
+
checked: h,
|
|
8
|
+
defaultChecked: p,
|
|
9
|
+
onChange: _,
|
|
10
|
+
disabled: n = !1,
|
|
11
|
+
label: r,
|
|
12
|
+
description: c,
|
|
13
|
+
id: k,
|
|
14
|
+
name: d,
|
|
15
|
+
value: y,
|
|
16
|
+
size: u = "md",
|
|
17
|
+
className: v,
|
|
18
|
+
wrapperClassName: C,
|
|
19
|
+
...l
|
|
20
|
+
}, N) => {
|
|
21
|
+
const b = K(), s = k ?? `nui-switch-${b}`, w = `${s}-description`, m = h !== void 0, [I, x] = j(p ?? !1), e = m ? h : I, o = () => {
|
|
22
|
+
if (n) return;
|
|
23
|
+
const t = !e;
|
|
24
|
+
m || x(t), _?.(t);
|
|
25
|
+
}, D = (t) => {
|
|
26
|
+
(t.key === " " || t.key === "Enter") && (t.preventDefault(), o()), l.onKeyDown?.(t);
|
|
27
|
+
}, S = (t) => {
|
|
28
|
+
n || (t.preventDefault(), o(), document.getElementById(s)?.focus());
|
|
29
|
+
}, $ = y ?? (e ? "on" : "off");
|
|
30
|
+
return /* @__PURE__ */ f(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
className: a(
|
|
34
|
+
"nui-switch-wrapper",
|
|
35
|
+
n && "nui-switch-wrapper--disabled",
|
|
36
|
+
C
|
|
58
37
|
),
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
38
|
+
children: [
|
|
39
|
+
d && /* @__PURE__ */ i("input", { type: "hidden", name: d, value: e ? $ : "" }),
|
|
40
|
+
/* @__PURE__ */ i(
|
|
41
|
+
"button",
|
|
42
|
+
{
|
|
43
|
+
ref: N,
|
|
44
|
+
id: s,
|
|
45
|
+
type: "button",
|
|
46
|
+
role: "switch",
|
|
47
|
+
"aria-checked": e,
|
|
48
|
+
"aria-disabled": n,
|
|
49
|
+
"aria-describedby": c ? w : void 0,
|
|
50
|
+
className: a(
|
|
51
|
+
"nui-switch",
|
|
52
|
+
`nui-switch--${u}`,
|
|
53
|
+
e && "nui-switch--checked",
|
|
54
|
+
v
|
|
55
|
+
),
|
|
56
|
+
onClick: o,
|
|
57
|
+
onKeyDown: D,
|
|
58
|
+
disabled: n,
|
|
59
|
+
...l,
|
|
60
|
+
children: /* @__PURE__ */ i(
|
|
61
|
+
"span",
|
|
62
|
+
{
|
|
63
|
+
className: a(
|
|
64
|
+
"nui-switch__thumb",
|
|
65
|
+
`nui-switch__thumb--${u}`,
|
|
66
|
+
e && "nui-switch__thumb--checked"
|
|
67
|
+
),
|
|
68
|
+
"aria-hidden": "true"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
(r || c) && /* @__PURE__ */ f("div", { className: "nui-switch__text-container", children: [
|
|
74
|
+
r && /* @__PURE__ */ i(
|
|
75
|
+
"label",
|
|
76
|
+
{
|
|
77
|
+
htmlFor: s,
|
|
78
|
+
className: "nui-switch__label",
|
|
79
|
+
onClick: S,
|
|
80
|
+
children: r
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
c && /* @__PURE__ */ i("div", { id: w, className: "nui-switch__description", children: c })
|
|
84
|
+
] })
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
E.displayName = "Switch";
|
|
64
91
|
export {
|
|
65
|
-
|
|
92
|
+
E as Switch
|
|
66
93
|
};
|
|
67
94
|
//# sourceMappingURL=Switch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.js","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"Switch.js","sources":["../../../src/components/switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useId, useState } from 'react';\nimport { cn } from '../../utils';\nimport './Switch.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'> {\n /** The controlled checked state of the switch */\n checked?: boolean;\n /** The uncontrolled default checked state */\n defaultChecked?: boolean;\n /** Callback fired when the state changes */\n onChange?: (checked: boolean) => void;\n \n /** Disables the switch, preventing interaction */\n disabled?: boolean;\n /** The primary text label for the switch */\n label?: React.ReactNode;\n /** Secondary descriptive text linked via WAI-ARIA */\n description?: React.ReactNode;\n \n /** Name attribute for native form submission */\n name?: string;\n /** Value submitted in a native form when checked. Defaults to \"on\". */\n value?: string;\n /** The visual size variant. Defaults to 'md'. */\n size?: 'sm' | 'md';\n \n /** Additional CSS classes for the outer wrapping div */\n wrapperClassName?: string;\n}\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Switch Component\n * * A WAI-ARIA compliant toggle switch used to turn settings on or off.\n * * Automatically handles native form submission using a hidden input.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n label,\n description,\n id,\n name,\n value,\n size = 'md',\n className,\n wrapperClassName,\n ...props\n },\n ref\n ) => {\n // Unique ID generation for WCAG label and description linkage\n const reactId = useId();\n const switchId = id ?? `nui-switch-${reactId}`;\n const descriptionId = `${switchId}-description`;\n\n // State Management\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const currentChecked = isControlled ? checked : internalChecked;\n\n const toggle = () => {\n if (disabled) return;\n const nextState = !currentChecked;\n if (!isControlled) setInternalChecked(nextState);\n onChange?.(nextState);\n };\n\n // Keyboard Accessibility (Space & Enter)\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault(); // Prevent page scroll on Spacebar\n toggle();\n }\n props.onKeyDown?.(e);\n };\n\n // Robust Label Click Handler\n // Standard <label> clicks only *focus* <button> elements in Safari/Firefox. \n // This handler ensures clicking the text always toggles the state.\n const handleLabelClick = (e: React.MouseEvent) => {\n if (disabled) return;\n e.preventDefault(); \n toggle();\n document.getElementById(switchId)?.focus();\n };\n\n // Hidden input value for standard HTML form submissions\n const hiddenValue = value ?? (currentChecked ? 'on' : 'off');\n\n return (\n <div \n className={cn(\n \"nui-switch-wrapper\", \n disabled && \"nui-switch-wrapper--disabled\", \n wrapperClassName\n )}\n >\n {/* Hidden Form Input */}\n {name && (\n <input type=\"hidden\" name={name} value={currentChecked ? hiddenValue : ''} />\n )}\n\n {/* The Actual Switch (Button) */}\n <button\n ref={ref}\n id={switchId}\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n className={cn(\n \"nui-switch\",\n `nui-switch--${size}`,\n currentChecked && \"nui-switch--checked\",\n className\n )}\n onClick={toggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n {...props}\n >\n <span \n className={cn(\n \"nui-switch__thumb\", \n `nui-switch__thumb--${size}`, \n currentChecked && \"nui-switch__thumb--checked\"\n )} \n aria-hidden=\"true\" \n />\n </button>\n\n {/* Text Content */}\n {(label || description) && (\n <div className=\"nui-switch__text-container\">\n {label && (\n <label \n htmlFor={switchId} \n className=\"nui-switch__label\"\n onClick={handleLabelClick}\n >\n {label}\n </label>\n )}\n {description && (\n <div id={descriptionId} className=\"nui-switch__description\">\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n);\n\nSwitch.displayName = 'Switch';"],"names":["Switch","forwardRef","checked","defaultChecked","onChange","disabled","label","description","id","name","value","size","className","wrapperClassName","props","ref","reactId","useId","switchId","descriptionId","isControlled","internalChecked","setInternalChecked","useState","currentChecked","toggle","nextState","handleKeyDown","e","handleLabelClick","hiddenValue","jsxs","cn","jsx"],"mappings":";;;;AA6CO,MAAMA,IAASC;AAAA,EACpB,CACE;AAAA,IACE,SAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,OAAAC;AAAA,IACA,aAAAC;AAAA,IACA,IAAAC;AAAA,IACA,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,WAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AAEH,UAAMC,IAAUC,EAAA,GACVC,IAAWV,KAAM,cAAcQ,CAAO,IACtCG,IAAgB,GAAGD,CAAQ,gBAG3BE,IAAelB,MAAY,QAC3B,CAACmB,GAAiBC,CAAkB,IAAIC,EAASpB,KAAkB,EAAK,GACxEqB,IAAiBJ,IAAelB,IAAUmB,GAE1CI,IAAS,MAAM;AACnB,UAAIpB,EAAU;AACd,YAAMqB,IAAY,CAACF;AACnB,MAAKJ,KAAcE,EAAmBI,CAAS,GAC/CtB,IAAWsB,CAAS;AAAA,IACtB,GAGMC,IAAgB,CAACC,MAA8C;AACnE,OAAIA,EAAE,QAAQ,OAAOA,EAAE,QAAQ,aAC7BA,EAAE,eAAA,GACFH,EAAA,IAEFX,EAAM,YAAYc,CAAC;AAAA,IACrB,GAKMC,IAAmB,CAACD,MAAwB;AAChD,MAAIvB,MACJuB,EAAE,eAAA,GACFH,EAAA,GACA,SAAS,eAAeP,CAAQ,GAAG,MAAA;AAAA,IACrC,GAGMY,IAAcpB,MAAUc,IAAiB,OAAO;AAEtD,WACE,gBAAAO;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACA3B,KAAY;AAAA,UACZQ;AAAA,QAAA;AAAA,QAID,UAAA;AAAA,UAAAJ,KACC,gBAAAwB,EAAC,WAAM,MAAK,UAAS,MAAAxB,GAAY,OAAOe,IAAiBM,IAAc,GAAA,CAAI;AAAA,UAI7E,gBAAAG;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAAlB;AAAA,cACA,IAAIG;AAAA,cACJ,MAAK;AAAA,cACL,MAAK;AAAA,cACL,gBAAcM;AAAA,cACd,iBAAenB;AAAA,cACf,oBAAkBE,IAAcY,IAAgB;AAAA,cAChD,WAAWa;AAAA,gBACT;AAAA,gBACA,eAAerB,CAAI;AAAA,gBACnBa,KAAkB;AAAA,gBAClBZ;AAAA,cAAA;AAAA,cAEF,SAASa;AAAA,cACT,WAAWE;AAAA,cACX,UAAAtB;AAAA,cACC,GAAGS;AAAA,cAEJ,UAAA,gBAAAmB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAWD;AAAA,oBACT;AAAA,oBACA,sBAAsBrB,CAAI;AAAA,oBAC1Ba,KAAkB;AAAA,kBAAA;AAAA,kBAEpB,eAAY;AAAA,gBAAA;AAAA,cAAA;AAAA,YACd;AAAA,UAAA;AAAA,WAIAlB,KAASC,MACT,gBAAAwB,EAAC,OAAA,EAAI,WAAU,8BACZ,UAAA;AAAA,YAAAzB,KACC,gBAAA2B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAASf;AAAA,gBACT,WAAU;AAAA,gBACV,SAASW;AAAA,gBAER,UAAAvB;AAAA,cAAA;AAAA,YAAA;AAAA,YAGJC,KACC,gBAAA0B,EAAC,OAAA,EAAI,IAAId,GAAe,WAAU,2BAC/B,UAAAZ,EAAA,CACH;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEAP,EAAO,cAAc;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),g=require("react");;/* empty css */const k=require("../../utils/cn/cn.cjs");function _({columns:o,data:c,rowKey:d,emptyText:f="No data available",className:j}){const[r,b]=g.useState(null),h=g.useMemo(()=>{if(!r)return c;const{key:e,direction:n}=r,a=o.find(l=>l.key===e);return[...c].sort((l,u)=>{if(a?.sortFn)return n==="asc"?a.sortFn(l,u):a.sortFn(u,l);const i=l[e],s=u[e];if(i===s)return 0;if(i==null)return n==="asc"?-1:1;if(s==null)return n==="asc"?1:-1;if(typeof i=="number"&&typeof s=="number")return n==="asc"?i-s:s-i;const S=String(i),v=String(s),x=S.localeCompare(v);return n==="asc"?x:-x})},[c,r,o]),y=e=>{e.sortable&&b(n=>!n||n.key!==e.key?{key:e.key,direction:"asc"}:n.direction==="asc"?{key:e.key,direction:"desc"}:null)},p=e=>typeof d=="function"?d(e):String(e[d]),m=e=>{if(!e.sortable)return null;const n=r?.key===e.key,a=r?.direction;return t.jsx("span",{className:k.cn("nui-table__sort-icon",n&&"active"),"aria-hidden":"true",children:n&&a==="asc"?t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("path",{d:"m18 15-6-6-6 6"})}):n&&a==="desc"?t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("path",{d:"m6 9 6 6 6-6"})}):t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("path",{d:"m7 15 5 5 5-5"}),t.jsx("path",{d:"m7 9 5-5 5 5"})]})})};return t.jsx("div",{className:"nui-table-wrapper",children:t.jsxs("table",{className:k.cn("nui-table",j),children:[t.jsx("thead",{children:t.jsx("tr",{children:o.map(e=>t.jsx("th",{scope:"col",style:{textAlign:e.align||"left"},"aria-sort":r?.key===e.key?r.direction==="asc"?"ascending":"descending":"none",children:e.sortable?t.jsxs("button",{type:"button",className:"nui-table__sort-button",onClick:()=>y(e),style:{justifyContent:e.align==="right"?"flex-end":e.align==="center"?"center":"flex-start"},children:[e.label,m(e)]}):t.jsx("span",{className:"nui-table__header-label",children:e.label})},String(e.key)))})}),t.jsx("tbody",{children:h.length===0?t.jsx("tr",{children:t.jsx("td",{className:"nui-table__empty",colSpan:o.length,children:t.jsx("div",{className:"nui-table__empty-content",children:f})})}):h.map(e=>t.jsx("tr",{className:"nui-table__row",children:o.map(n=>t.jsx("td",{style:{textAlign:n.align||"left"},children:n.render?n.render(e):String(e[n.key]??"")},String(n.key)))},p(e)))})]})})}exports.Table=_;
|
|
2
2
|
//# sourceMappingURL=Table.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.cjs","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["/**\r\n * Table.tsx\r\n * ----------\r\n * Accessible, sortable, theme-aware table.\r\n */\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport './Table.css';\r\n\r\nexport interface TableColumn<T> {\r\n key: keyof T;\r\n label: string;\r\n sortable?: boolean;\r\n}\r\n\r\ninterface TableProps<T> {\r\n columns: TableColumn<T>[];\r\n data: T[];\r\n emptyText?: string;\r\n className?: string;\r\n}\r\n\r\ntype SortState<T> = {\r\n key: keyof T;\r\n direction: 'asc' | 'desc';\r\n} | null;\r\n\r\nexport function Table<T extends Record<string, any>>({\r\n columns,\r\n data,\r\n emptyText = 'No data available',\r\n className = '',\r\n}: TableProps<T>) {\r\n const [sort, setSort] = useState<SortState<T>>(null);\r\n\r\n const sortedData = useMemo(() => {\r\n if (!sort) return data;\r\n\r\n const sorted = [...data].sort((a, b) => {\r\n const aVal = a[sort.key];\r\n const bVal = b[sort.key];\r\n\r\n if (aVal < bVal) return sort.direction === 'asc' ? -1 : 1;\r\n if (aVal > bVal) return sort.direction === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n\r\n return sorted;\r\n }, [data, sort]);\r\n\r\n const toggleSort = (col: TableColumn<T>) => {\r\n if (!col.sortable) return;\r\n\r\n setSort((prev) => {\r\n if (!prev || prev.key !== col.key) {\r\n return { key: col.key, direction: 'asc' };\r\n }\r\n if (prev.direction === 'asc') {\r\n return { key: col.key, direction: 'desc' };\r\n }\r\n return null; // reset\r\n });\r\n };\r\n\r\n const renderSortIcon = (col: TableColumn<T>) => {\r\n if (!col.sortable) return null;\r\n\r\n const isActive = sort?.key === col.key;\r\n const dir = sort?.direction ?? 'asc';\r\n\r\n return (\r\n <span\r\n className={`ui-table-sort-indicator ${isActive ? 'active' : ''}`}\r\n aria-hidden=\"true\"\r\n >\r\n {isActive ? (dir === 'asc' ? '▲' : '▼') : '↕'}\r\n </span>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"ui-table-container\">\r\n <table className={`ui-table ${className}`}>\r\n <thead>\r\n <tr>\r\n {columns.map((col) => (\r\n <th key={String(col.key)} scope=\"col\">\r\n {col.sortable ? (\r\n <button\r\n type=\"button\"\r\n className=\"ui-table-sort-button\"\r\n onClick={() => toggleSort(col)}\r\n >\r\n {col.label}\r\n {renderSortIcon(col)}\r\n </button>\r\n ) : (\r\n col.label\r\n )}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n {sortedData.length === 0 ? (\r\n <tr>\r\n <td className=\"ui-table-empty\" colSpan={columns.length}>\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : (\r\n sortedData.map((row, i) => (\r\n <tr key={i} className=\"ui-table-row\">\r\n {columns.map((col) => (\r\n <td key={String(col.key)}>{String(row[col.key])}</td>\r\n ))}\r\n </tr>\r\n ))\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n"],"names":["Table","columns","data","emptyText","className","sort","setSort","useState","sortedData","useMemo","a","b","aVal","bVal","toggleSort","col","prev","renderSortIcon","isActive","dir","jsx","jsxs","row","i"],"mappings":"mKA2BO,SAASA,EAAqC,CACnD,QAAAC,EACA,KAAAC,EACA,UAAAC,EAAY,oBACZ,UAAAC,EAAY,EACd,EAAkB,CAChB,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAuB,IAAI,EAE7CC,EAAaC,EAAAA,QAAQ,IACpBJ,EAEU,CAAC,GAAGH,CAAI,EAAE,KAAK,CAACQ,EAAGC,IAAM,CACtC,MAAMC,EAAOF,EAAEL,EAAK,GAAG,EACjBQ,EAAOF,EAAEN,EAAK,GAAG,EAEvB,OAAIO,EAAOC,EAAaR,EAAK,YAAc,MAAQ,GAAK,EACpDO,EAAOC,EAAaR,EAAK,YAAc,MAAQ,EAAI,GAChD,CACT,CAAC,EATiBH,EAYjB,CAACA,EAAMG,CAAI,CAAC,EAETS,EAAcC,GAAwB,CACrCA,EAAI,UAETT,EAASU,GACH,CAACA,GAAQA,EAAK,MAAQD,EAAI,IACrB,CAAE,IAAKA,EAAI,IAAK,UAAW,KAAA,EAEhCC,EAAK,YAAc,MACd,CAAE,IAAKD,EAAI,IAAK,UAAW,MAAA,EAE7B,IACR,CACH,EAEME,EAAkBF,GAAwB,CAC9C,GAAI,CAACA,EAAI,SAAU,OAAO,KAE1B,MAAMG,EAAWb,GAAM,MAAQU,EAAI,IAC7BI,EAAMd,GAAM,WAAa,MAE/B,OACEe,EAAAA,IAAC,OAAA,CACC,UAAW,2BAA2BF,EAAW,SAAW,EAAE,GAC9D,cAAY,OAEX,SAAAA,EAAYC,IAAQ,MAAQ,IAAM,IAAO,GAAA,CAAA,CAGhD,EAEA,OACEC,EAAAA,IAAC,OAAI,UAAU,qBACb,gBAAC,QAAA,CAAM,UAAW,YAAYhB,CAAS,GACrC,SAAA,CAAAgB,MAAC,QAAA,CACC,SAAAA,EAAAA,IAAC,KAAA,CACE,SAAAnB,EAAQ,IAAKc,GACZK,EAAAA,IAAC,KAAA,CAAyB,MAAM,MAC7B,SAAAL,EAAI,SACHM,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,UAAU,uBACV,QAAS,IAAMP,EAAWC,CAAG,EAE5B,SAAA,CAAAA,EAAI,MACJE,EAAeF,CAAG,CAAA,CAAA,CAAA,EAGrBA,EAAI,KAAA,EAXC,OAAOA,EAAI,GAAG,CAavB,CACD,CAAA,CACH,EACF,EAEAK,EAAAA,IAAC,SACE,SAAAZ,EAAW,SAAW,EACrBY,EAAAA,IAAC,KAAA,CACC,eAAC,KAAA,CAAG,UAAU,iBAAiB,QAASnB,EAAQ,OAC7C,SAAAE,CAAA,CACH,EACF,EAEAK,EAAW,IAAI,CAACc,EAAKC,IACnBH,EAAAA,IAAC,MAAW,UAAU,eACnB,WAAQ,IAAKL,GACZK,EAAAA,IAAC,KAAA,CAA0B,gBAAOE,EAAIP,EAAI,GAAG,CAAC,CAAA,EAArC,OAAOA,EAAI,GAAG,CAAyB,CACjD,GAHMQ,CAIT,CACD,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,CACF,CAEJ"}
|
|
1
|
+
{"version":3,"file":"Table.cjs","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo } from 'react';\nimport { cn } from '../../utils';\nimport './Table.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface TableColumn<T> {\n /** The key from your data object that this column maps to */\n key: keyof T;\n /** The text displayed in the table header */\n label: string;\n /** Enables clicking the header to sort the table by this column */\n sortable?: boolean;\n /** Aligns the text in the column header and cells. Defaults to 'left' */\n align?: 'left' | 'center' | 'right';\n /** Custom render function for the cell. Useful for formatting (e.g., currency) or custom UI (e.g., status badges) */\n render?: (row: T) => React.ReactNode;\n /** Optional custom sorting function to override the default alphabetic/numeric sort */\n sortFn?: (a: T, b: T) => number;\n}\n\nexport interface TableProps<T> {\n /** Array of column configuration objects */\n columns: TableColumn<T>[];\n /** Array of data objects to render */\n data: T[];\n /** A unique identifier for each row (string/number key, or a function that returns a string) */\n rowKey: keyof T | ((row: T) => string);\n /** Text or React Node to display when the data array is empty */\n emptyText?: React.ReactNode;\n /** Custom class applied to the <table> element */\n className?: string;\n}\n\ntype SortState<T> = {\n key: keyof T;\n direction: 'asc' | 'desc';\n} | null;\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Table Component\n * * A highly generic data table that supports automatic sorting and custom cell rendering.\n * * Uses strict TypeScript generics (`<T>`) so it can perfectly map to any data shape passed into it.\n */\nexport function Table<T>({\n columns,\n data,\n rowKey,\n emptyText = 'No data available',\n className,\n}: TableProps<T>) {\n const [sort, setSort] = useState<SortState<T>>(null);\n\n /* ----------------------------------------------------\n Sorting Logic\n ---------------------------------------------------- */\n const sortedData = useMemo(() => {\n if (!sort) return data;\n\n const { key, direction } = sort;\n const column = columns.find((c) => c.key === key);\n\n return [...data].sort((a, b) => {\n // 1. Fallback to custom sort function if provided\n if (column?.sortFn) {\n return direction === 'asc' ? column.sortFn(a, b) : column.sortFn(b, a);\n }\n\n const aVal = a[key];\n const bVal = b[key];\n\n if (aVal === bVal) return 0;\n if (aVal === null || aVal === undefined) return direction === 'asc' ? -1 : 1;\n if (bVal === null || bVal === undefined) return direction === 'asc' ? 1 : -1;\n\n // 2. Type-safe numeric sorting\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return direction === 'asc' ? aVal - bVal : bVal - aVal;\n }\n\n // 3. Type-safe string sorting (perfect for alphabetic ordering)\n const aStr = String(aVal);\n const bStr = String(bVal);\n const diff = aStr.localeCompare(bStr);\n \n return direction === 'asc' ? diff : -diff;\n });\n }, [data, sort, columns]);\n\n /* ----------------------------------------------------\n Event Handlers\n ---------------------------------------------------- */\n const toggleSort = (col: TableColumn<T>) => {\n if (!col.sortable) return;\n\n setSort((prev) => {\n // If clicking a new column, or clicking for the first time, sort ASC\n if (!prev || prev.key !== col.key) {\n return { key: col.key, direction: 'asc' };\n }\n // If currently ASC, flip to DESC\n if (prev.direction === 'asc') {\n return { key: col.key, direction: 'desc' };\n }\n // If currently DESC, clear the sort\n return null;\n });\n };\n\n const getRowId = (row: T): string => {\n return typeof rowKey === 'function' ? rowKey(row) : String(row[rowKey]);\n };\n\n /* ----------------------------------------------------\n Render Helpers\n ---------------------------------------------------- */\n const renderSortIcon = (col: TableColumn<T>) => {\n if (!col.sortable) return null;\n\n const isActive = sort?.key === col.key;\n const dir = sort?.direction;\n\n return (\n <span className={cn(\"nui-table__sort-icon\", isActive && \"active\")} aria-hidden=\"true\">\n {isActive && dir === 'asc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m18 15-6-6-6 6\"/></svg>\n ) : isActive && dir === 'desc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg>\n )}\n </span>\n );\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div className=\"nui-table-wrapper\">\n <table className={cn(\"nui-table\", className)}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th \n key={String(col.key)} \n scope=\"col\"\n style={{ textAlign: col.align || 'left' }}\n aria-sort={sort?.key === col.key ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className=\"nui-table__sort-button\"\n onClick={() => toggleSort(col)}\n style={{ justifyContent: col.align === 'right' ? 'flex-end' : col.align === 'center' ? 'center' : 'flex-start' }}\n >\n {col.label}\n {renderSortIcon(col)}\n </button>\n ) : (\n <span className=\"nui-table__header-label\">{col.label}</span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n\n <tbody>\n {sortedData.length === 0 ? (\n <tr>\n <td className=\"nui-table__empty\" colSpan={columns.length}>\n <div className=\"nui-table__empty-content\">\n {emptyText}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((row) => (\n <tr key={getRowId(row)} className=\"nui-table__row\">\n {columns.map((col) => (\n <td \n key={String(col.key)}\n style={{ textAlign: col.align || 'left' }}\n >\n {col.render ? col.render(row) : String(row[col.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n );\n}"],"names":["Table","columns","data","rowKey","emptyText","className","sort","setSort","useState","sortedData","useMemo","key","direction","column","c","a","b","aVal","bVal","aStr","bStr","diff","toggleSort","col","prev","getRowId","row","renderSortIcon","isActive","dir","cn","jsx","jsxs"],"mappings":"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"}
|
|
@@ -1,46 +1,73 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useState as
|
|
1
|
+
import { jsx as n, jsxs as h } from "react/jsx-runtime";
|
|
2
|
+
import { useState as N, useMemo as j } from "react";
|
|
3
3
|
/* empty css */
|
|
4
|
-
|
|
4
|
+
import { cn as g } from "../../utils/cn/cn.js";
|
|
5
|
+
function B({
|
|
5
6
|
columns: a,
|
|
6
|
-
data:
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
data: d,
|
|
8
|
+
rowKey: c,
|
|
9
|
+
emptyText: p = "No data available",
|
|
10
|
+
className: m
|
|
9
11
|
}) {
|
|
10
|
-
const [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const [r, y] = N(null), f = j(() => {
|
|
13
|
+
if (!r) return d;
|
|
14
|
+
const { key: e, direction: t } = r, o = a.find((l) => l.key === e);
|
|
15
|
+
return [...d].sort((l, u) => {
|
|
16
|
+
if (o?.sortFn)
|
|
17
|
+
return t === "asc" ? o.sortFn(l, u) : o.sortFn(u, l);
|
|
18
|
+
const i = l[e], s = u[e];
|
|
19
|
+
if (i === s) return 0;
|
|
20
|
+
if (i == null) return t === "asc" ? -1 : 1;
|
|
21
|
+
if (s == null) return t === "asc" ? 1 : -1;
|
|
22
|
+
if (typeof i == "number" && typeof s == "number")
|
|
23
|
+
return t === "asc" ? i - s : s - i;
|
|
24
|
+
const v = String(i), x = String(s), k = v.localeCompare(x);
|
|
25
|
+
return t === "asc" ? k : -k;
|
|
26
|
+
});
|
|
27
|
+
}, [d, r, a]), b = (e) => {
|
|
28
|
+
e.sortable && y((t) => !t || t.key !== e.key ? { key: e.key, direction: "asc" } : t.direction === "asc" ? { key: e.key, direction: "desc" } : null);
|
|
29
|
+
}, S = (e) => typeof c == "function" ? c(e) : String(e[c]), _ = (e) => {
|
|
16
30
|
if (!e.sortable) return null;
|
|
17
|
-
const t =
|
|
18
|
-
return /* @__PURE__ */
|
|
19
|
-
"
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
"aria-hidden": "true",
|
|
23
|
-
children: t ? i === "asc" ? "▲" : "▼" : "↕"
|
|
24
|
-
}
|
|
25
|
-
);
|
|
31
|
+
const t = r?.key === e.key, o = r?.direction;
|
|
32
|
+
return /* @__PURE__ */ n("span", { className: g("nui-table__sort-icon", t && "active"), "aria-hidden": "true", children: t && o === "asc" ? /* @__PURE__ */ n("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ n("path", { d: "m18 15-6-6-6 6" }) }) : t && o === "desc" ? /* @__PURE__ */ n("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ n("path", { d: "m6 9 6 6 6-6" }) }) : /* @__PURE__ */ h("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
33
|
+
/* @__PURE__ */ n("path", { d: "m7 15 5 5 5-5" }),
|
|
34
|
+
/* @__PURE__ */ n("path", { d: "m7 9 5-5 5 5" })
|
|
35
|
+
] }) });
|
|
26
36
|
};
|
|
27
|
-
return /* @__PURE__ */
|
|
28
|
-
/* @__PURE__ */
|
|
29
|
-
"
|
|
37
|
+
return /* @__PURE__ */ n("div", { className: "nui-table-wrapper", children: /* @__PURE__ */ h("table", { className: g("nui-table", m), children: [
|
|
38
|
+
/* @__PURE__ */ n("thead", { children: /* @__PURE__ */ n("tr", { children: a.map((e) => /* @__PURE__ */ n(
|
|
39
|
+
"th",
|
|
40
|
+
{
|
|
41
|
+
scope: "col",
|
|
42
|
+
style: { textAlign: e.align || "left" },
|
|
43
|
+
"aria-sort": r?.key === e.key ? r.direction === "asc" ? "ascending" : "descending" : "none",
|
|
44
|
+
children: e.sortable ? /* @__PURE__ */ h(
|
|
45
|
+
"button",
|
|
46
|
+
{
|
|
47
|
+
type: "button",
|
|
48
|
+
className: "nui-table__sort-button",
|
|
49
|
+
onClick: () => b(e),
|
|
50
|
+
style: { justifyContent: e.align === "right" ? "flex-end" : e.align === "center" ? "center" : "flex-start" },
|
|
51
|
+
children: [
|
|
52
|
+
e.label,
|
|
53
|
+
_(e)
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
) : /* @__PURE__ */ n("span", { className: "nui-table__header-label", children: e.label })
|
|
57
|
+
},
|
|
58
|
+
String(e.key)
|
|
59
|
+
)) }) }),
|
|
60
|
+
/* @__PURE__ */ n("tbody", { children: f.length === 0 ? /* @__PURE__ */ n("tr", { children: /* @__PURE__ */ n("td", { className: "nui-table__empty", colSpan: a.length, children: /* @__PURE__ */ n("div", { className: "nui-table__empty-content", children: p }) }) }) : f.map((e) => /* @__PURE__ */ n("tr", { className: "nui-table__row", children: a.map((t) => /* @__PURE__ */ n(
|
|
61
|
+
"td",
|
|
30
62
|
{
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
k(e)
|
|
37
|
-
]
|
|
38
|
-
}
|
|
39
|
-
) : e.label }, String(e.key))) }) }),
|
|
40
|
-
/* @__PURE__ */ r("tbody", { children: c.length === 0 ? /* @__PURE__ */ r("tr", { children: /* @__PURE__ */ r("td", { className: "ui-table-empty", colSpan: a.length, children: u }) }) : c.map((e, t) => /* @__PURE__ */ r("tr", { className: "ui-table-row", children: a.map((i) => /* @__PURE__ */ r("td", { children: String(e[i.key]) }, String(i.key))) }, t)) })
|
|
63
|
+
style: { textAlign: t.align || "left" },
|
|
64
|
+
children: t.render ? t.render(e) : String(e[t.key] ?? "")
|
|
65
|
+
},
|
|
66
|
+
String(t.key)
|
|
67
|
+
)) }, S(e))) })
|
|
41
68
|
] }) });
|
|
42
69
|
}
|
|
43
70
|
export {
|
|
44
|
-
|
|
71
|
+
B as Table
|
|
45
72
|
};
|
|
46
73
|
//# sourceMappingURL=Table.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["/**\r\n * Table.tsx\r\n * ----------\r\n * Accessible, sortable, theme-aware table.\r\n */\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport './Table.css';\r\n\r\nexport interface TableColumn<T> {\r\n key: keyof T;\r\n label: string;\r\n sortable?: boolean;\r\n}\r\n\r\ninterface TableProps<T> {\r\n columns: TableColumn<T>[];\r\n data: T[];\r\n emptyText?: string;\r\n className?: string;\r\n}\r\n\r\ntype SortState<T> = {\r\n key: keyof T;\r\n direction: 'asc' | 'desc';\r\n} | null;\r\n\r\nexport function Table<T extends Record<string, any>>({\r\n columns,\r\n data,\r\n emptyText = 'No data available',\r\n className = '',\r\n}: TableProps<T>) {\r\n const [sort, setSort] = useState<SortState<T>>(null);\r\n\r\n const sortedData = useMemo(() => {\r\n if (!sort) return data;\r\n\r\n const sorted = [...data].sort((a, b) => {\r\n const aVal = a[sort.key];\r\n const bVal = b[sort.key];\r\n\r\n if (aVal < bVal) return sort.direction === 'asc' ? -1 : 1;\r\n if (aVal > bVal) return sort.direction === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n\r\n return sorted;\r\n }, [data, sort]);\r\n\r\n const toggleSort = (col: TableColumn<T>) => {\r\n if (!col.sortable) return;\r\n\r\n setSort((prev) => {\r\n if (!prev || prev.key !== col.key) {\r\n return { key: col.key, direction: 'asc' };\r\n }\r\n if (prev.direction === 'asc') {\r\n return { key: col.key, direction: 'desc' };\r\n }\r\n return null; // reset\r\n });\r\n };\r\n\r\n const renderSortIcon = (col: TableColumn<T>) => {\r\n if (!col.sortable) return null;\r\n\r\n const isActive = sort?.key === col.key;\r\n const dir = sort?.direction ?? 'asc';\r\n\r\n return (\r\n <span\r\n className={`ui-table-sort-indicator ${isActive ? 'active' : ''}`}\r\n aria-hidden=\"true\"\r\n >\r\n {isActive ? (dir === 'asc' ? '▲' : '▼') : '↕'}\r\n </span>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"ui-table-container\">\r\n <table className={`ui-table ${className}`}>\r\n <thead>\r\n <tr>\r\n {columns.map((col) => (\r\n <th key={String(col.key)} scope=\"col\">\r\n {col.sortable ? (\r\n <button\r\n type=\"button\"\r\n className=\"ui-table-sort-button\"\r\n onClick={() => toggleSort(col)}\r\n >\r\n {col.label}\r\n {renderSortIcon(col)}\r\n </button>\r\n ) : (\r\n col.label\r\n )}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n {sortedData.length === 0 ? (\r\n <tr>\r\n <td className=\"ui-table-empty\" colSpan={columns.length}>\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : (\r\n sortedData.map((row, i) => (\r\n <tr key={i} className=\"ui-table-row\">\r\n {columns.map((col) => (\r\n <td key={String(col.key)}>{String(row[col.key])}</td>\r\n ))}\r\n </tr>\r\n ))\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n"],"names":["Table","columns","data","emptyText","className","sort","setSort","useState","sortedData","useMemo","a","b","aVal","bVal","toggleSort","col","prev","renderSortIcon","isActive","dir","jsx","jsxs","row","i"],"mappings":";;;AA2BO,SAASA,EAAqC;AAAA,EACnD,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC,IAAY;AACd,GAAkB;AAChB,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAuB,IAAI,GAE7CC,IAAaC,EAAQ,MACpBJ,IAEU,CAAC,GAAGH,CAAI,EAAE,KAAK,CAACQ,GAAGC,MAAM;AACtC,UAAMC,IAAOF,EAAEL,EAAK,GAAG,GACjBQ,IAAOF,EAAEN,EAAK,GAAG;AAEvB,WAAIO,IAAOC,IAAaR,EAAK,cAAc,QAAQ,KAAK,IACpDO,IAAOC,IAAaR,EAAK,cAAc,QAAQ,IAAI,KAChD;AAAA,EACT,CAAC,IATiBH,GAYjB,CAACA,GAAMG,CAAI,CAAC,GAETS,IAAa,CAACC,MAAwB;AAC1C,IAAKA,EAAI,YAETT,EAAQ,CAACU,MACH,CAACA,KAAQA,EAAK,QAAQD,EAAI,MACrB,EAAE,KAAKA,EAAI,KAAK,WAAW,MAAA,IAEhCC,EAAK,cAAc,QACd,EAAE,KAAKD,EAAI,KAAK,WAAW,OAAA,IAE7B,IACR;AAAA,EACH,GAEME,IAAiB,CAACF,MAAwB;AAC9C,QAAI,CAACA,EAAI,SAAU,QAAO;AAE1B,UAAMG,IAAWb,GAAM,QAAQU,EAAI,KAC7BI,IAAMd,GAAM,aAAa;AAE/B,WACE,gBAAAe;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,2BAA2BF,IAAW,WAAW,EAAE;AAAA,QAC9D,eAAY;AAAA,QAEX,UAAAA,IAAYC,MAAQ,QAAQ,MAAM,MAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAGhD;AAEA,SACE,gBAAAC,EAAC,SAAI,WAAU,sBACb,4BAAC,SAAA,EAAM,WAAW,YAAYhB,CAAS,IACrC,UAAA;AAAA,IAAA,gBAAAgB,EAAC,SAAA,EACC,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAnB,EAAQ,IAAI,CAACc,MACZ,gBAAAK,EAAC,MAAA,EAAyB,OAAM,OAC7B,UAAAL,EAAI,WACH,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAMP,EAAWC,CAAG;AAAA,QAE5B,UAAA;AAAA,UAAAA,EAAI;AAAA,UACJE,EAAeF,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,IAGrBA,EAAI,MAAA,GAXC,OAAOA,EAAI,GAAG,CAavB,CACD,EAAA,CACH,GACF;AAAA,IAEA,gBAAAK,EAAC,WACE,UAAAZ,EAAW,WAAW,IACrB,gBAAAY,EAAC,MAAA,EACC,4BAAC,MAAA,EAAG,WAAU,kBAAiB,SAASnB,EAAQ,QAC7C,UAAAE,EAAA,CACH,GACF,IAEAK,EAAW,IAAI,CAACc,GAAKC,MACnB,gBAAAH,EAAC,QAAW,WAAU,gBACnB,YAAQ,IAAI,CAACL,MACZ,gBAAAK,EAAC,MAAA,EAA0B,iBAAOE,EAAIP,EAAI,GAAG,CAAC,EAAA,GAArC,OAAOA,EAAI,GAAG,CAAyB,CACjD,KAHMQ,CAIT,CACD,EAAA,CAEL;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"Table.js","sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo } from 'react';\nimport { cn } from '../../utils';\nimport './Table.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport interface TableColumn<T> {\n /** The key from your data object that this column maps to */\n key: keyof T;\n /** The text displayed in the table header */\n label: string;\n /** Enables clicking the header to sort the table by this column */\n sortable?: boolean;\n /** Aligns the text in the column header and cells. Defaults to 'left' */\n align?: 'left' | 'center' | 'right';\n /** Custom render function for the cell. Useful for formatting (e.g., currency) or custom UI (e.g., status badges) */\n render?: (row: T) => React.ReactNode;\n /** Optional custom sorting function to override the default alphabetic/numeric sort */\n sortFn?: (a: T, b: T) => number;\n}\n\nexport interface TableProps<T> {\n /** Array of column configuration objects */\n columns: TableColumn<T>[];\n /** Array of data objects to render */\n data: T[];\n /** A unique identifier for each row (string/number key, or a function that returns a string) */\n rowKey: keyof T | ((row: T) => string);\n /** Text or React Node to display when the data array is empty */\n emptyText?: React.ReactNode;\n /** Custom class applied to the <table> element */\n className?: string;\n}\n\ntype SortState<T> = {\n key: keyof T;\n direction: 'asc' | 'desc';\n} | null;\n\n/* ============================================================\n * Component\n * ============================================================ */\n\n/**\n * Table Component\n * * A highly generic data table that supports automatic sorting and custom cell rendering.\n * * Uses strict TypeScript generics (`<T>`) so it can perfectly map to any data shape passed into it.\n */\nexport function Table<T>({\n columns,\n data,\n rowKey,\n emptyText = 'No data available',\n className,\n}: TableProps<T>) {\n const [sort, setSort] = useState<SortState<T>>(null);\n\n /* ----------------------------------------------------\n Sorting Logic\n ---------------------------------------------------- */\n const sortedData = useMemo(() => {\n if (!sort) return data;\n\n const { key, direction } = sort;\n const column = columns.find((c) => c.key === key);\n\n return [...data].sort((a, b) => {\n // 1. Fallback to custom sort function if provided\n if (column?.sortFn) {\n return direction === 'asc' ? column.sortFn(a, b) : column.sortFn(b, a);\n }\n\n const aVal = a[key];\n const bVal = b[key];\n\n if (aVal === bVal) return 0;\n if (aVal === null || aVal === undefined) return direction === 'asc' ? -1 : 1;\n if (bVal === null || bVal === undefined) return direction === 'asc' ? 1 : -1;\n\n // 2. Type-safe numeric sorting\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return direction === 'asc' ? aVal - bVal : bVal - aVal;\n }\n\n // 3. Type-safe string sorting (perfect for alphabetic ordering)\n const aStr = String(aVal);\n const bStr = String(bVal);\n const diff = aStr.localeCompare(bStr);\n \n return direction === 'asc' ? diff : -diff;\n });\n }, [data, sort, columns]);\n\n /* ----------------------------------------------------\n Event Handlers\n ---------------------------------------------------- */\n const toggleSort = (col: TableColumn<T>) => {\n if (!col.sortable) return;\n\n setSort((prev) => {\n // If clicking a new column, or clicking for the first time, sort ASC\n if (!prev || prev.key !== col.key) {\n return { key: col.key, direction: 'asc' };\n }\n // If currently ASC, flip to DESC\n if (prev.direction === 'asc') {\n return { key: col.key, direction: 'desc' };\n }\n // If currently DESC, clear the sort\n return null;\n });\n };\n\n const getRowId = (row: T): string => {\n return typeof rowKey === 'function' ? rowKey(row) : String(row[rowKey]);\n };\n\n /* ----------------------------------------------------\n Render Helpers\n ---------------------------------------------------- */\n const renderSortIcon = (col: TableColumn<T>) => {\n if (!col.sortable) return null;\n\n const isActive = sort?.key === col.key;\n const dir = sort?.direction;\n\n return (\n <span className={cn(\"nui-table__sort-icon\", isActive && \"active\")} aria-hidden=\"true\">\n {isActive && dir === 'asc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m18 15-6-6-6 6\"/></svg>\n ) : isActive && dir === 'desc' ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg>\n )}\n </span>\n );\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div className=\"nui-table-wrapper\">\n <table className={cn(\"nui-table\", className)}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th \n key={String(col.key)} \n scope=\"col\"\n style={{ textAlign: col.align || 'left' }}\n aria-sort={sort?.key === col.key ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className=\"nui-table__sort-button\"\n onClick={() => toggleSort(col)}\n style={{ justifyContent: col.align === 'right' ? 'flex-end' : col.align === 'center' ? 'center' : 'flex-start' }}\n >\n {col.label}\n {renderSortIcon(col)}\n </button>\n ) : (\n <span className=\"nui-table__header-label\">{col.label}</span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n\n <tbody>\n {sortedData.length === 0 ? (\n <tr>\n <td className=\"nui-table__empty\" colSpan={columns.length}>\n <div className=\"nui-table__empty-content\">\n {emptyText}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((row) => (\n <tr key={getRowId(row)} className=\"nui-table__row\">\n {columns.map((col) => (\n <td \n key={String(col.key)}\n style={{ textAlign: col.align || 'left' }}\n >\n {col.render ? col.render(row) : String(row[col.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n );\n}"],"names":["Table","columns","data","rowKey","emptyText","className","sort","setSort","useState","sortedData","useMemo","key","direction","column","c","a","b","aVal","bVal","aStr","bStr","diff","toggleSort","col","prev","getRowId","row","renderSortIcon","isActive","dir","cn","jsx","jsxs"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("react/jsx-runtime"),o=require("react");;/* empty css */const x=require("../../utils/cn/cn.cjs"),y=o.createContext(null);function h(){const e=o.useContext(y);if(!e)throw new Error("Tabs components must be used within <Tabs>");return e}const m=o.forwardRef(({value:e,defaultValue:c,onChange:u,children:n,className:i,...b},t)=>{const l=e!==void 0,[d,s]=o.useState(c||""),a=o.useId(),r=l?e:d,f=T=>{l||s(T),u?.(T)};return g.jsx(y.Provider,{value:{value:r,onValueChange:f,idPrefix:a},children:g.jsx("div",{ref:t,className:x.cn("nui-tabs-root",i),...b,children:n})})});m.displayName="Tabs";const p=o.forwardRef(({children:e,className:c,...u},n)=>{const i=o.useRef(null),b=t=>{const l=t.target;if(l.getAttribute("role")!=="tab")return;const d=i.current;if(!d)return;const s=Array.from(d.querySelectorAll('[role="tab"]:not([disabled])')),a=s.indexOf(l);if(a===-1)return;let r=a;if(t.key==="ArrowRight")r=(a+1)%s.length;else if(t.key==="ArrowLeft")r=(a-1+s.length)%s.length;else if(t.key==="Home")r=0;else if(t.key==="End")r=s.length-1;else return;t.preventDefault(),s[r].focus()};return g.jsx("div",{ref:t=>{i.current=t,typeof n=="function"?n(t):n&&(n.current=t)},role:"tablist","aria-orientation":"horizontal",className:x.cn("nui-tabs-list",c),onKeyDown:b,...u,children:e})});p.displayName="Tabs.List";const C=o.forwardRef(({value:e,children:c,className:u,disabled:n,onClick:i,onFocus:b,...t},l)=>{const{value:d,onValueChange:s,idPrefix:a}=h(),r=d===e;return g.jsx("button",{ref:l,type:"button",role:"tab",id:`tab-${a}-${e}`,"aria-selected":r,"aria-controls":`panel-${a}-${e}`,tabIndex:r?0:-1,disabled:n,className:x.cn("nui-tabs-trigger",r&&"selected",n&&"disabled",u),onClick:f=>{n||s(e),i?.(f)},onFocus:f=>{n||s(e),b?.(f)},...t,children:c})});C.displayName="Tabs.Trigger";const w=o.forwardRef(({value:e,children:c,className:u,...n},i)=>{const{value:b,idPrefix:t}=h();return b===e?g.jsx("div",{ref:i,role:"tabpanel",id:`panel-${t}-${e}`,"aria-labelledby":`tab-${t}-${e}`,tabIndex:0,className:x.cn("nui-tabs-content",u),...n,children:c}):null});w.displayName="Tabs.Content";const R=Object.assign(m,{List:p,Trigger:C,Content:w});exports.Tabs=R;
|
|
2
2
|
//# sourceMappingURL=Tabs.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.cjs","sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["/**\r\n * Tabs.tsx\r\n * ---------\r\n * Fully accessible WAI-ARIA Tabs Component.\r\n *\r\n * Features:\r\n * - roving tabindex\r\n * - ArrowLeft, ArrowRight, Home, End keyboard navigation\r\n * - aria-selected, aria-controls, role=\"tablist\"\r\n * - auto-focus on selected tab\r\n * - single-component API\r\n */\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport './Tabs.css';\r\n\r\nexport interface TabItem {\r\n id: string;\r\n label: string;\r\n content: React.ReactNode;\r\n}\r\n\r\ninterface TabsProps {\r\n tabs: TabItem[];\r\n defaultTab?: string;\r\n className?: string;\r\n}\r\n\r\nexport function Tabs({ tabs, defaultTab, className = '' }: TabsProps) {\r\n const [active, setActive] = useState(defaultTab || tabs[0]?.id);\r\n\r\n const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);\r\n\r\n // Focus active tab\r\n useEffect(() => {\r\n const index = tabs.findIndex((t) => t.id === active);\r\n tabRefs.current[index]?.focus();\r\n }, [active, tabs]);\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent, index: number) => {\r\n if (!['ArrowRight', 'ArrowLeft', 'Home', 'End'].includes(e.key)) return;\r\n\r\n e.preventDefault();\r\n\r\n let newIndex = index;\r\n\r\n if (e.key === 'ArrowRight') newIndex = (index + 1) % tabs.length;\r\n if (e.key === 'ArrowLeft')\r\n newIndex = (index - 1 + tabs.length) % tabs.length;\r\n if (e.key === 'Home') newIndex = 0;\r\n if (e.key === 'End') newIndex = tabs.length - 1;\r\n\r\n setActive(tabs[newIndex].id);\r\n };\r\n\r\n return (\r\n <div className={`ui-tabs ${className}`}>\r\n <div role=\"tablist\" className=\"ui-tabs-list\">\r\n {tabs.map((tab, index) => {\r\n const isSelected = tab.id === active;\r\n\r\n return (\r\n <button\r\n key={tab.id}\r\n ref={(el) => {\r\n tabRefs.current[index] = el;\r\n }}\r\n role=\"tab\"\r\n id={`tab-${tab.id}`}\r\n aria-selected={isSelected}\r\n aria-controls={`panel-${tab.id}`}\r\n tabIndex={isSelected ? 0 : -1}\r\n className=\"ui-tab\"\r\n onClick={() => setActive(tab.id)}\r\n onKeyDown={(e) => handleKeyDown(e, index)}\r\n >\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {tabs.map((tab) =>\r\n tab.id === active ? (\r\n <div\r\n key={tab.id}\r\n id={`panel-${tab.id}`}\r\n role=\"tabpanel\"\r\n aria-labelledby={`tab-${tab.id}`}\r\n className=\"ui-tabs-panel\"\r\n >\r\n {tab.content}\r\n </div>\r\n ) : null\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["Tabs","tabs","defaultTab","className","active","setActive","useState","tabRefs","useRef","useEffect","index","t","handleKeyDown","newIndex","jsxs","jsx","tab","isSelected","el","e"],"mappings":"kKA4BO,SAASA,EAAK,CAAE,KAAAC,EAAM,WAAAC,EAAY,UAAAC,EAAY,IAAiB,CACpE,KAAM,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAASJ,GAAcD,EAAK,CAAC,GAAG,EAAE,EAExDM,EAAUC,EAAAA,OAAqC,EAAE,EAGvDC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAQT,EAAK,UAAWU,GAAMA,EAAE,KAAOP,CAAM,EACnDG,EAAQ,QAAQG,CAAK,GAAG,MAAA,CAC1B,EAAG,CAACN,EAAQH,CAAI,CAAC,EAEjB,MAAMW,EAAgB,CAAC,EAAwBF,IAAkB,CAC/D,GAAI,CAAC,CAAC,aAAc,YAAa,OAAQ,KAAK,EAAE,SAAS,EAAE,GAAG,EAAG,OAEjE,EAAE,eAAA,EAEF,IAAIG,EAAWH,EAEX,EAAE,MAAQ,eAAcG,GAAYH,EAAQ,GAAKT,EAAK,QACtD,EAAE,MAAQ,cACZY,GAAYH,EAAQ,EAAIT,EAAK,QAAUA,EAAK,QAC1C,EAAE,MAAQ,SAAQY,EAAW,GAC7B,EAAE,MAAQ,QAAOA,EAAWZ,EAAK,OAAS,GAE9CI,EAAUJ,EAAKY,CAAQ,EAAE,EAAE,CAC7B,EAEA,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAW,WAAWX,CAAS,GAClC,SAAA,CAAAY,EAAAA,IAAC,MAAA,CAAI,KAAK,UAAU,UAAU,eAC3B,SAAAd,EAAK,IAAI,CAACe,EAAKN,IAAU,CACxB,MAAMO,EAAaD,EAAI,KAAOZ,EAE9B,OACEW,EAAAA,IAAC,SAAA,CAEC,IAAMG,GAAO,CACXX,EAAQ,QAAQG,CAAK,EAAIQ,CAC3B,EACA,KAAK,MACL,GAAI,OAAOF,EAAI,EAAE,GACjB,gBAAeC,EACf,gBAAe,SAASD,EAAI,EAAE,GAC9B,SAAUC,EAAa,EAAI,GAC3B,UAAU,SACV,QAAS,IAAMZ,EAAUW,EAAI,EAAE,EAC/B,UAAYG,GAAMP,EAAcO,EAAGT,CAAK,EAEvC,SAAAM,EAAI,KAAA,EAbAA,EAAI,EAAA,CAgBf,CAAC,CAAA,CACH,EAECf,EAAK,IAAKe,GACTA,EAAI,KAAOZ,EACTW,EAAAA,IAAC,MAAA,CAEC,GAAI,SAASC,EAAI,EAAE,GACnB,KAAK,WACL,kBAAiB,OAAOA,EAAI,EAAE,GAC9B,UAAU,gBAET,SAAAA,EAAI,OAAA,EANAA,EAAI,EAAA,EAQT,IAAA,CACN,EACF,CAEJ"}
|
|
1
|
+
{"version":3,"file":"Tabs.cjs","sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useState, useRef, forwardRef, useId } from 'react';\nimport { cn } from '../../utils';\nimport './Tabs.css';\n\n/* ============================================================\n * Context\n * ============================================================ */\n\ninterface TabsContextValue {\n value: string;\n onValueChange: (value: string) => void;\n // A unique ID prefix to link triggers and panels for screen readers\n idPrefix: string; \n}\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabs() {\n const ctx = useContext(TabsContext);\n if (!ctx) throw new Error('Tabs components must be used within <Tabs>');\n return ctx;\n}\n\n/* ============================================================\n * 1. Tabs Root\n * ============================================================ */\n\nexport interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Controlled state value representing the active tab */\n value?: string;\n /** Uncontrolled initial value */\n defaultValue?: string;\n /** Callback fired when the active tab changes */\n onChange?: (value: string) => void;\n children: React.ReactNode;\n}\n\n/**\n * Tabs Component (Root)\n * * A Compound Component that manages the state and accessibility linking for a tabbed interface.\n */\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(\n ({ value, defaultValue, onChange, children, className, ...props }, ref) => {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue || '');\n \n // Generate a stable, SSR-safe ID for ARIA linkage\n const idPrefix = useId();\n\n const currentValue = isControlled ? value : internalValue;\n\n const handleValueChange = (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n };\n\n return (\n <TabsContext.Provider value={{ value: currentValue, onValueChange: handleValueChange, idPrefix }}>\n <div ref={ref} className={cn(\"nui-tabs-root\", className)} {...props}>\n {children}\n </div>\n </TabsContext.Provider>\n );\n }\n);\nTabsRoot.displayName = 'Tabs';\n\n/* ============================================================\n * 2. Tabs List\n * ============================================================ */\n\nexport interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n/**\n * Tabs List\n * * Contains the tab triggers.\n * * Implements a \"Roving Tabindex\" to allow users to navigate tabs via arrow keys.\n */\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n ({ children, className, ...props }, ref) => {\n const listRef = useRef<HTMLDivElement>(null);\n\n // Smart Roving Tabindex for Keyboard Navigation\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute('role') !== 'tab') return;\n\n const list = listRef.current;\n if (!list) return;\n\n // Find all valid tab triggers\n const tabs = Array.from(\n list.querySelectorAll('[role=\"tab\"]:not([disabled])')\n ) as HTMLElement[];\n \n const currentIndex = tabs.indexOf(target);\n if (currentIndex === -1) return;\n\n let nextIndex = currentIndex;\n\n if (e.key === 'ArrowRight') nextIndex = (currentIndex + 1) % tabs.length;\n else if (e.key === 'ArrowLeft') nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;\n else if (e.key === 'Home') nextIndex = 0;\n else if (e.key === 'End') nextIndex = tabs.length - 1;\n else return;\n\n e.preventDefault();\n tabs[nextIndex].focus();\n };\n\n return (\n <div\n ref={(node) => {\n listRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n className={cn(\"nui-tabs-list\", className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nTabsList.displayName = 'Tabs.List';\n\n/* ============================================================\n * 3. Tabs Trigger\n * ============================================================ */\n\nexport interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** The unique identifier associated with this tab's content */\n value: string;\n}\n\n/**\n * Tabs Trigger\n * * The interactive button that activates a specific tab panel.\n * * Follows the WAI-ARIA \"Automatic Activation\" pattern (focusing the tab activates it).\n */\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ value, children, className, disabled, onClick, onFocus, ...props }, ref) => {\n const { value: selectedValue, onValueChange, idPrefix } = useTabs();\n const isSelected = selectedValue === value;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"tab\"\n id={`tab-${idPrefix}-${value}`}\n aria-selected={isSelected}\n aria-controls={`panel-${idPrefix}-${value}`}\n tabIndex={isSelected ? 0 : -1} // Only active tab is in the natural page tab sequence\n disabled={disabled}\n className={cn(\n \"nui-tabs-trigger\",\n isSelected && \"selected\",\n disabled && \"disabled\",\n className\n )}\n onClick={(e) => {\n if (!disabled) onValueChange(value);\n onClick?.(e);\n }}\n onFocus={(e) => {\n // Automatic Activation: Auto-select on keyboard focus\n if (!disabled) onValueChange(value);\n onFocus?.(e);\n }}\n {...props}\n >\n {children}\n </button>\n );\n }\n);\nTabsTrigger.displayName = 'Tabs.Trigger';\n\n/* ============================================================\n * 4. Tabs Content\n * ============================================================ */\n\nexport interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The unique identifier connecting this panel to its trigger */\n value: string;\n}\n\n/**\n * Tabs Content\n * * The panel that displays when its associated trigger is active.\n * * Only mounts to the DOM when active to keep the DOM clean.\n */\nconst TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(\n ({ value, children, className, ...props }, ref) => {\n const { value: selectedValue, idPrefix } = useTabs();\n const isSelected = selectedValue === value;\n\n if (!isSelected) return null;\n\n return (\n <div\n ref={ref}\n role=\"tabpanel\"\n id={`panel-${idPrefix}-${value}`}\n aria-labelledby={`tab-${idPrefix}-${value}`}\n tabIndex={0} // Allows content area to be focused and read by screen readers\n className={cn(\"nui-tabs-content\", className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nTabsContent.displayName = 'Tabs.Content';\n\n/* ============================================================\n * Export\n * ============================================================ */\n\nexport const Tabs = Object.assign(TabsRoot, {\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n});"],"names":["TabsContext","createContext","useTabs","ctx","useContext","TabsRoot","forwardRef","value","defaultValue","onChange","children","className","props","ref","isControlled","internalValue","setInternalValue","useState","idPrefix","useId","currentValue","handleValueChange","newValue","jsx","cn","TabsList","listRef","useRef","handleKeyDown","e","target","list","tabs","currentIndex","nextIndex","node","TabsTrigger","disabled","onClick","onFocus","selectedValue","onValueChange","isSelected","TabsContent","Tabs"],"mappings":"2MAiBMA,EAAcC,EAAAA,cAAuC,IAAI,EAE/D,SAASC,GAAU,CACjB,MAAMC,EAAMC,EAAAA,WAAWJ,CAAW,EAClC,GAAI,CAACG,EAAK,MAAM,IAAI,MAAM,4CAA4C,EACtE,OAAOA,CACT,CAoBA,MAAME,EAAWC,EAAAA,WACf,CAAC,CAAE,MAAAC,EAAO,aAAAC,EAAc,SAAAC,EAAU,SAAAC,EAAU,UAAAC,EAAW,GAAGC,CAAA,EAASC,IAAQ,CACzE,MAAMC,EAAeP,IAAU,OACzB,CAACQ,EAAeC,CAAgB,EAAIC,EAAAA,SAAST,GAAgB,EAAE,EAG/DU,EAAWC,EAAAA,MAAA,EAEXC,EAAeN,EAAeP,EAAQQ,EAEtCM,EAAqBC,GAAqB,CACzCR,GAAcE,EAAiBM,CAAQ,EAC5Cb,IAAWa,CAAQ,CACrB,EAEA,OACEC,MAACvB,EAAY,SAAZ,CAAqB,MAAO,CAAE,MAAOoB,EAAc,cAAeC,EAAmB,SAAAH,CAAA,EACpF,SAAAK,EAAAA,IAAC,MAAA,CAAI,IAAAV,EAAU,UAAWW,EAAAA,GAAG,gBAAiBb,CAAS,EAAI,GAAGC,EAC3D,SAAAF,CAAA,CACH,CAAA,CACF,CAEJ,CACF,EACAL,EAAS,YAAc,OAevB,MAAMoB,EAAWnB,EAAAA,WACf,CAAC,CAAE,SAAAI,EAAU,UAAAC,EAAW,GAAGC,CAAA,EAASC,IAAQ,CAC1C,MAAMa,EAAUC,EAAAA,OAAuB,IAAI,EAGrCC,EAAiBC,GAA2C,CAChE,MAAMC,EAASD,EAAE,OACjB,GAAIC,EAAO,aAAa,MAAM,IAAM,MAAO,OAE3C,MAAMC,EAAOL,EAAQ,QACrB,GAAI,CAACK,EAAM,OAGX,MAAMC,EAAO,MAAM,KACjBD,EAAK,iBAAiB,8BAA8B,CAAA,EAGhDE,EAAeD,EAAK,QAAQF,CAAM,EACxC,GAAIG,IAAiB,GAAI,OAEzB,IAAIC,EAAYD,EAEhB,GAAIJ,EAAE,MAAQ,aAAcK,GAAaD,EAAe,GAAKD,EAAK,eACzDH,EAAE,MAAQ,YAAaK,GAAaD,EAAe,EAAID,EAAK,QAAUA,EAAK,eAC3EH,EAAE,MAAQ,OAAQK,EAAY,UAC9BL,EAAE,MAAQ,MAAOK,EAAYF,EAAK,OAAS,MAC/C,QAELH,EAAE,eAAA,EACFG,EAAKE,CAAS,EAAE,MAAA,CAClB,EAEA,OACEX,EAAAA,IAAC,MAAA,CACC,IAAMY,GAAS,CACbT,EAAQ,QAAUS,EACd,OAAOtB,GAAQ,WAAYA,EAAIsB,CAAI,EAC9BtB,MAAS,QAAUsB,EAC9B,EACA,KAAK,UACL,mBAAiB,aACjB,UAAWX,EAAAA,GAAG,gBAAiBb,CAAS,EACxC,UAAWiB,EACV,GAAGhB,EAEH,SAAAF,CAAA,CAAA,CAGP,CACF,EACAe,EAAS,YAAc,YAgBvB,MAAMW,EAAc9B,EAAAA,WAClB,CAAC,CAAE,MAAAC,EAAO,SAAAG,EAAU,UAAAC,EAAW,SAAA0B,EAAU,QAAAC,EAAS,QAAAC,EAAS,GAAG3B,CAAA,EAASC,IAAQ,CAC7E,KAAM,CAAE,MAAO2B,EAAe,cAAAC,EAAe,SAAAvB,CAAA,EAAahB,EAAA,EACpDwC,EAAaF,IAAkBjC,EAErC,OACEgB,EAAAA,IAAC,SAAA,CACC,IAAAV,EACA,KAAK,SACL,KAAK,MACL,GAAI,OAAOK,CAAQ,IAAIX,CAAK,GAC5B,gBAAemC,EACf,gBAAe,SAASxB,CAAQ,IAAIX,CAAK,GACzC,SAAUmC,EAAa,EAAI,GAC3B,SAAAL,EACA,UAAWb,EAAAA,GACT,mBACAkB,GAAc,WACdL,GAAY,WACZ1B,CAAA,EAEF,QAAUkB,GAAM,CACTQ,GAAUI,EAAclC,CAAK,EAClC+B,IAAUT,CAAC,CACb,EACA,QAAUA,GAAM,CAETQ,GAAUI,EAAclC,CAAK,EAClCgC,IAAUV,CAAC,CACb,EACC,GAAGjB,EAEH,SAAAF,CAAA,CAAA,CAGP,CACF,EACA0B,EAAY,YAAc,eAgB1B,MAAMO,EAAcrC,EAAAA,WAClB,CAAC,CAAE,MAAAC,EAAO,SAAAG,EAAU,UAAAC,EAAW,GAAGC,CAAA,EAASC,IAAQ,CACjD,KAAM,CAAE,MAAO2B,EAAe,SAAAtB,CAAA,EAAahB,EAAA,EAG3C,OAFmBsC,IAAkBjC,EAKnCgB,EAAAA,IAAC,MAAA,CACC,IAAAV,EACA,KAAK,WACL,GAAI,SAASK,CAAQ,IAAIX,CAAK,GAC9B,kBAAiB,OAAOW,CAAQ,IAAIX,CAAK,GACzC,SAAU,EACV,UAAWiB,EAAAA,GAAG,mBAAoBb,CAAS,EAC1C,GAAGC,EAEH,SAAAF,CAAA,CAAA,EAZmB,IAe1B,CACF,EACAiC,EAAY,YAAc,eAMnB,MAAMC,EAAO,OAAO,OAAOvC,EAAU,CAC1C,KAAMoB,EACN,QAASW,EACT,QAASO,CACX,CAAC"}
|