@nofinite/nui 1.1.1 → 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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { jsxs as b, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as K, useState as x, useRef as v, useEffect as L, useCallback as Q, useLayoutEffect as T, useMemo as y } from "react";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import { onClickOutside as U } from "../../utils/onclickoutside/onClickOutside.js";
|
|
5
|
+
import { restoreFocus as Z } from "../../utils/restorefocus/restoreFocus.js";
|
|
6
|
+
import { cn as E } from "../../utils/cn/cn.js";
|
|
7
|
+
import { Portal as ee } from "../../utils/portal/portal.js";
|
|
8
|
+
const m = (l) => String(l).padStart(2, "0");
|
|
9
|
+
function z(l, g = 12) {
|
|
10
|
+
if (!l) return null;
|
|
11
|
+
const [a, r] = l.split(":");
|
|
12
|
+
let n = parseInt(a, 10);
|
|
13
|
+
const d = parseInt(r, 10);
|
|
14
|
+
if (isNaN(n) || isNaN(d)) return null;
|
|
15
|
+
if (g === 24)
|
|
16
|
+
return { hour: n, minute: d, ampm: null };
|
|
17
|
+
const R = n >= 12 ? "PM" : "AM";
|
|
18
|
+
return n = n % 12, n = n || 12, { hour: n, minute: d, ampm: R };
|
|
19
|
+
}
|
|
20
|
+
function te(l, g, a, r) {
|
|
21
|
+
let n = l;
|
|
22
|
+
return r === 12 && (a === "PM" && n < 12 && (n += 12), a === "AM" && n === 12 && (n = 0)), `${m(n)}:${m(g)}`;
|
|
23
|
+
}
|
|
24
|
+
const ne = K(({
|
|
25
|
+
value: l,
|
|
26
|
+
defaultValue: g,
|
|
27
|
+
onChange: a,
|
|
28
|
+
clockType: r = 12,
|
|
29
|
+
minuteStep: n = 1,
|
|
30
|
+
placeholder: d = "Select time",
|
|
31
|
+
id: R,
|
|
32
|
+
className: O,
|
|
33
|
+
name: M,
|
|
34
|
+
disabled: V = !1,
|
|
35
|
+
...W
|
|
36
|
+
}, X) => {
|
|
37
|
+
const P = l !== void 0, [Y, q] = x(g), w = P ? l : Y, [o, A] = x(!1), p = v(null), N = v(null), S = v(null), I = v(null), j = v(null), u = z(w, r) || {
|
|
38
|
+
hour: r === 12 ? 12 : 0,
|
|
39
|
+
minute: 0,
|
|
40
|
+
ampm: "AM"
|
|
41
|
+
};
|
|
42
|
+
L(() => o ? U([N, p], () => A(!1)) : void 0, [o]), L(() => {
|
|
43
|
+
!o && p.current && Z(p.current);
|
|
44
|
+
}, [o]);
|
|
45
|
+
const [B, D] = x({ top: -9999, left: -9999 }), f = Q(() => {
|
|
46
|
+
if (!p.current || !N.current) return;
|
|
47
|
+
const e = p.current.getBoundingClientRect(), t = N.current.getBoundingClientRect(), s = window.scrollY, c = window.scrollX;
|
|
48
|
+
let C = e.bottom + s + 8, k = e.left + c;
|
|
49
|
+
const h = 16, G = document.documentElement.clientWidth - t.width - h;
|
|
50
|
+
k > G + c && (k = e.right + c - t.width, k < h + c && (k = h + c));
|
|
51
|
+
const J = document.documentElement.clientHeight - t.height - h;
|
|
52
|
+
e.bottom + 8 > J && (C = e.top + s - t.height - 8, C < h + s && (C = h + s)), D({ top: C, left: k });
|
|
53
|
+
}, []);
|
|
54
|
+
T(() => {
|
|
55
|
+
if (o)
|
|
56
|
+
return f(), window.addEventListener("resize", f), window.addEventListener("scroll", f, !0), () => {
|
|
57
|
+
window.removeEventListener("resize", f), window.removeEventListener("scroll", f, !0);
|
|
58
|
+
};
|
|
59
|
+
}, [o, f]), L(() => {
|
|
60
|
+
if (!o) return;
|
|
61
|
+
const e = setTimeout(() => {
|
|
62
|
+
[S, I, j].forEach((t) => {
|
|
63
|
+
if (!t.current) return;
|
|
64
|
+
const s = t.current.querySelector(".selected");
|
|
65
|
+
s && s.scrollIntoView({ block: "center", behavior: "instant" });
|
|
66
|
+
});
|
|
67
|
+
}, 0);
|
|
68
|
+
return () => clearTimeout(e);
|
|
69
|
+
}, [o]);
|
|
70
|
+
const F = y(() => {
|
|
71
|
+
const e = r === 12 ? 12 : 24, t = r === 12 ? 1 : 0;
|
|
72
|
+
return Array.from({ length: e }).map((s, c) => t + c);
|
|
73
|
+
}, [r]), H = y(() => {
|
|
74
|
+
const e = [];
|
|
75
|
+
for (let t = 0; t < 60; t += n) e.push(t);
|
|
76
|
+
return e;
|
|
77
|
+
}, [n]), $ = (e, t, s) => {
|
|
78
|
+
const c = te(e, t, s, r);
|
|
79
|
+
P || q(c), a?.(c);
|
|
80
|
+
}, _ = () => {
|
|
81
|
+
if (!w) return d;
|
|
82
|
+
const e = z(w, r);
|
|
83
|
+
return e ? r === 12 ? `${m(e.hour)}:${m(e.minute)} ${e.ampm}` : `${m(e.hour)}:${m(e.minute)}` : d;
|
|
84
|
+
};
|
|
85
|
+
return /* @__PURE__ */ b("div", { ref: X, className: E("nui-timepicker-root", O), ...W, children: [
|
|
86
|
+
M && /* @__PURE__ */ i("input", { type: "hidden", name: M, value: w ?? "" }),
|
|
87
|
+
/* @__PURE__ */ b(
|
|
88
|
+
"button",
|
|
89
|
+
{
|
|
90
|
+
id: R,
|
|
91
|
+
ref: p,
|
|
92
|
+
type: "button",
|
|
93
|
+
disabled: V,
|
|
94
|
+
className: "nui-timepicker-trigger",
|
|
95
|
+
"aria-haspopup": "dialog",
|
|
96
|
+
"aria-expanded": o,
|
|
97
|
+
onClick: () => A((e) => !e),
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ i("span", { className: w ? "" : "nui-timepicker-placeholder", children: _() }),
|
|
100
|
+
/* @__PURE__ */ b("svg", { className: "nui-timepicker-icon", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
101
|
+
/* @__PURE__ */ i("circle", { cx: "12", cy: "12", r: "10" }),
|
|
102
|
+
/* @__PURE__ */ i("polyline", { points: "12 6 12 12 16 14" })
|
|
103
|
+
] })
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
o && /* @__PURE__ */ i(ee, { children: /* @__PURE__ */ i(
|
|
108
|
+
"div",
|
|
109
|
+
{
|
|
110
|
+
ref: N,
|
|
111
|
+
className: "nui-timepicker-popover",
|
|
112
|
+
style: { position: "absolute", top: B.top, left: B.left },
|
|
113
|
+
children: /* @__PURE__ */ i("div", { className: "nui-timepicker-panel", children: /* @__PURE__ */ b("div", { className: "nui-timepicker-columns", children: [
|
|
114
|
+
/* @__PURE__ */ i("div", { className: "nui-timepicker-col", ref: S, children: F.map((e) => {
|
|
115
|
+
const t = u.hour === e;
|
|
116
|
+
return /* @__PURE__ */ i(
|
|
117
|
+
"button",
|
|
118
|
+
{
|
|
119
|
+
className: E("nui-timepicker-item", t && "selected"),
|
|
120
|
+
onClick: () => $(e, u.minute, u.ampm),
|
|
121
|
+
children: m(e)
|
|
122
|
+
},
|
|
123
|
+
`h-${e}`
|
|
124
|
+
);
|
|
125
|
+
}) }),
|
|
126
|
+
/* @__PURE__ */ i("div", { className: "nui-timepicker-col", ref: I, children: H.map((e) => {
|
|
127
|
+
const t = u.minute === e;
|
|
128
|
+
return /* @__PURE__ */ i(
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
className: E("nui-timepicker-item", t && "selected"),
|
|
132
|
+
onClick: () => $(u.hour, e, u.ampm),
|
|
133
|
+
children: m(e)
|
|
134
|
+
},
|
|
135
|
+
`m-${e}`
|
|
136
|
+
);
|
|
137
|
+
}) }),
|
|
138
|
+
r === 12 && /* @__PURE__ */ i("div", { className: "nui-timepicker-col", ref: j, children: ["AM", "PM"].map((e) => {
|
|
139
|
+
const t = u.ampm === e;
|
|
140
|
+
return /* @__PURE__ */ i(
|
|
141
|
+
"button",
|
|
142
|
+
{
|
|
143
|
+
className: E("nui-timepicker-item", t && "selected"),
|
|
144
|
+
onClick: () => $(u.hour, u.minute, e),
|
|
145
|
+
children: e
|
|
146
|
+
},
|
|
147
|
+
e
|
|
148
|
+
);
|
|
149
|
+
}) })
|
|
150
|
+
] }) })
|
|
151
|
+
}
|
|
152
|
+
) })
|
|
153
|
+
] });
|
|
154
|
+
});
|
|
155
|
+
ne.displayName = "TimePicker";
|
|
156
|
+
export {
|
|
157
|
+
ne as TimePicker
|
|
158
|
+
};
|
|
159
|
+
//# sourceMappingURL=TimePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimePicker.js","sources":["../../../src/components/timepicker/TimePicker.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n forwardRef,\n} from 'react';\nimport { cn } from '../../utils';\nimport { Portal, onClickOutside, restoreFocus } from '../../utils';\nimport './TimePicker.css';\n\n/* ----------------------------------------------------\n Helpers\n---------------------------------------------------- */\nconst pad = (n: number | string) => String(n).padStart(2, '0');\n\ninterface ParsedTime {\n hour: number;\n minute: number;\n ampm: 'AM' | 'PM' | null;\n}\n\nfunction parseTime(timeStr?: string, clockType: 12 | 24 = 12): ParsedTime | null {\n if (!timeStr) return null;\n const [hStr, mStr] = timeStr.split(':');\n let h = parseInt(hStr, 10);\n const m = parseInt(mStr, 10);\n\n if (isNaN(h) || isNaN(m)) return null;\n\n if (clockType === 24) {\n return { hour: h, minute: m, ampm: null };\n }\n\n const ampm: 'AM' | 'PM' = h >= 12 ? 'PM' : 'AM';\n h = h % 12;\n h = h ? h : 12; \n return { hour: h, minute: m, ampm };\n}\n\n// Converts 12h/24h selections back into standard HH:mm HTML format\nfunction buildTime(hour: number, minute: number, ampm: 'AM' | 'PM' | null, clockType: 12 | 24) {\n let h = hour;\n if (clockType === 12) {\n if (ampm === 'PM' && h < 12) h += 12;\n if (ampm === 'AM' && h === 12) h = 0;\n }\n return `${pad(h)}:${pad(minute)}`;\n}\n\n/* ----------------------------------------------------\n Types\n---------------------------------------------------- */\nexport interface TimePickerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'value' | 'defaultValue'> {\n /** Standard HTML5 time format: HH:mm (24-hour format internally) */\n value?: string; \n /** Uncontrolled default time */\n defaultValue?: string;\n /** Callback fired when a time segment is selected */\n onChange?: (v: string) => void;\n \n /** 12-hour or 24-hour clock formatting. Defaults to 12. */\n clockType?: 12 | 24;\n /** Step interval for the minute column. Defaults to 1. */\n minuteStep?: number; \n \n /** Placeholder text when empty */\n placeholder?: string;\n /** Name attribute for the hidden input (for native forms) */\n name?: string;\n /** Disables the time picker trigger */\n disabled?: boolean;\n}\n\n/* ----------------------------------------------------\n Component\n---------------------------------------------------- */\n\n/**\n * TimePicker Component\n * * A highly usable dropdown for selecting hours, minutes, and periods.\n * * Uses smart positioning and automatic scroll-to-selected logic.\n */\nexport const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(({\n value,\n defaultValue,\n onChange,\n clockType = 12,\n minuteStep = 1,\n placeholder = 'Select time',\n id,\n className,\n name,\n disabled = false,\n ...props\n}, ref) => {\n const controlled = value !== undefined;\n const [internal, setInternal] = useState<string | undefined>(defaultValue);\n const selectedTime = controlled ? value : internal;\n\n const [open, setOpen] = useState(false);\n\n // Refs for positioning and click-outside\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const popRef = useRef<HTMLDivElement | null>(null);\n\n // Refs for scroll columns\n const hourColRef = useRef<HTMLDivElement | null>(null);\n const minColRef = useRef<HTMLDivElement | null>(null);\n const ampmColRef = useRef<HTMLDivElement | null>(null);\n\n // Parse current selection for UI\n const parsed = parseTime(selectedTime, clockType) || {\n hour: clockType === 12 ? 12 : 0,\n minute: 0,\n ampm: 'AM' as const,\n };\n\n /* ----------------------------------------------------\n Click outside & Restore Focus\n ---------------------------------------------------- */\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([popRef, triggerRef], () => setOpen(false));\n return cleanup;\n }, [open]);\n\n useEffect(() => {\n if (!open && triggerRef.current) restoreFocus(triggerRef.current);\n }, [open]);\n\n /* ----------------------------------------------------\n Smart Popover Position (with collision math)\n ---------------------------------------------------- */\n const [coords, setCoords] = useState({ top: -9999, left: -9999 });\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !popRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const popRect = popRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = triggerRect.bottom + scrollY + 8;\n let left = triggerRect.left + scrollX;\n const padding = 16;\n\n // X-Axis Clamp\n const maxLeft = document.documentElement.clientWidth - popRect.width - padding;\n if (left > maxLeft + scrollX) {\n left = triggerRect.right + scrollX - popRect.width;\n if (left < padding + scrollX) left = padding + scrollX;\n }\n\n // Y-Axis Clamp (Hard Top Clamp included)\n const maxTop = document.documentElement.clientHeight - popRect.height - padding;\n if (triggerRect.bottom + 8 > maxTop) {\n top = triggerRect.top + scrollY - popRect.height - 8;\n if (top < padding + scrollY) top = padding + scrollY;\n }\n\n setCoords({ top, left });\n }, []);\n\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition]);\n\n /* ----------------------------------------------------\n Auto-Scroll to Selected Item\n ---------------------------------------------------- */\n useEffect(() => {\n if (!open) return;\n // Wait a tick for the popover to render and measure\n const timer = setTimeout(() => {\n [hourColRef, minColRef, ampmColRef].forEach((colRef) => {\n if (!colRef.current) return;\n const selectedEl = colRef.current.querySelector('.selected');\n if (selectedEl) {\n selectedEl.scrollIntoView({ block: 'center', behavior: 'instant' });\n }\n });\n }, 0);\n return () => clearTimeout(timer);\n }, [open]);\n\n /* ----------------------------------------------------\n Column Generation\n ---------------------------------------------------- */\n const hours = useMemo(() => {\n const length = clockType === 12 ? 12 : 24;\n const start = clockType === 12 ? 1 : 0;\n return Array.from({ length }).map((_, i) => start + i);\n }, [clockType]);\n\n const minutes = useMemo(() => {\n const arr = [];\n for (let i = 0; i < 60; i += minuteStep) arr.push(i);\n return arr;\n }, [minuteStep]);\n\n /* ----------------------------------------------------\n Commit Selections\n ---------------------------------------------------- */\n const commit = (h: number, m: number, a: 'AM' | 'PM' | null) => {\n const newVal = buildTime(h, m, a, clockType);\n if (!controlled) setInternal(newVal);\n onChange?.(newVal);\n };\n\n /* ----------------------------------------------------\n Display Label\n ---------------------------------------------------- */\n const formatDisplay = () => {\n if (!selectedTime) return placeholder;\n const p = parseTime(selectedTime, clockType);\n if (!p) return placeholder;\n return clockType === 12 \n ? `${pad(p.hour)}:${pad(p.minute)} ${p.ampm}`\n : `${pad(p.hour)}:${pad(p.minute)}`;\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div ref={ref} className={cn(\"nui-timepicker-root\", className)} {...props}>\n {name && <input type=\"hidden\" name={name} value={selectedTime ?? ''} />}\n\n <button\n id={id}\n ref={triggerRef}\n type=\"button\"\n disabled={disabled}\n className=\"nui-timepicker-trigger\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onClick={() => setOpen((s) => !s)}\n >\n <span className={!selectedTime ? \"nui-timepicker-placeholder\" : \"\"}>\n {formatDisplay()}\n </span>\n <svg className=\"nui-timepicker-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n </button>\n\n {open && (\n <Portal>\n <div\n ref={popRef}\n className=\"nui-timepicker-popover\"\n style={{ position: 'absolute', top: coords.top, left: coords.left }}\n >\n <div className=\"nui-timepicker-panel\">\n <div className=\"nui-timepicker-columns\">\n \n {/* HOURS */}\n <div className=\"nui-timepicker-col\" ref={hourColRef}>\n {hours.map((h) => {\n const sel = parsed.hour === h;\n return (\n <button\n key={`h-${h}`}\n className={cn(\"nui-timepicker-item\", sel && \"selected\")}\n onClick={() => commit(h, parsed.minute, parsed.ampm)}\n >\n {pad(h)}\n </button>\n );\n })}\n </div>\n\n {/* MINUTES */}\n <div className=\"nui-timepicker-col\" ref={minColRef}>\n {minutes.map((m) => {\n const sel = parsed.minute === m;\n return (\n <button\n key={`m-${m}`}\n className={cn(\"nui-timepicker-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, m, parsed.ampm)}\n >\n {pad(m)}\n </button>\n );\n })}\n </div>\n\n {/* AM / PM (Only for 12h clock) */}\n {clockType === 12 && (\n <div className=\"nui-timepicker-col\" ref={ampmColRef}>\n {(['AM', 'PM'] as const).map((a) => {\n const sel = parsed.ampm === a;\n return (\n <button\n key={a}\n className={cn(\"nui-timepicker-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, parsed.minute, a)}\n >\n {a}\n </button>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n});\n\nTimePicker.displayName = 'TimePicker';"],"names":["pad","n","parseTime","timeStr","clockType","hStr","mStr","h","m","ampm","buildTime","hour","minute","TimePicker","forwardRef","value","defaultValue","onChange","minuteStep","placeholder","id","className","name","disabled","props","ref","controlled","internal","setInternal","useState","selectedTime","open","setOpen","triggerRef","useRef","popRef","hourColRef","minColRef","ampmColRef","parsed","useEffect","onClickOutside","restoreFocus","coords","setCoords","updatePosition","useCallback","triggerRect","popRect","scrollY","scrollX","top","left","padding","maxLeft","maxTop","useLayoutEffect","timer","colRef","selectedEl","hours","useMemo","length","start","_","i","minutes","arr","commit","a","newVal","formatDisplay","p","jsxs","cn","s","jsx","Portal","sel"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),i=require("react");;/* empty css */const Q=require("../../utils/onclickoutside/onClickOutside.cjs"),U=require("../../utils/restorefocus/restoreFocus.cjs"),v=require("../../utils/cn/cn.cjs"),Z=require("../../utils/portal/portal.cjs"),d=u=>String(u).padStart(2,"0");function B(u,j=12){if(!u)return null;const[f,s]=u.split(":");let r=parseInt(f,10);const N=parseInt(s,10);if(isNaN(r)||isNaN(N))return null;if(j===24)return{hour:r,minute:N,ampm:null};const E=r>=12?"PM":"AM";return r=r%12,r=r||12,{hour:r,minute:N,ampm:E}}function ee(u,j,f,s){let r=u;return s===12&&(f==="PM"&&r<12&&(r+=12),f==="AM"&&r===12&&(r=0)),`${d(r)}:${d(j)}`}const T=i.forwardRef(({value:u,defaultValue:j,onChange:f,clockType:s=12,minuteStep:r=1,placeholder:N="Select time range",id:E,className:z,nameFrom:S,nameTo:M,disabled:V=!1,...W},X)=>{const $=u!==void 0,[Y,L]=i.useState(j),o=$?u||{}:Y||{},[c,R]=i.useState(!1),[b,k]=i.useState("from"),p=i.useRef(null),C=i.useRef(null),q=i.useRef(null),A=i.useRef(null),y=i.useRef(null),F=b==="from"?o.from:o.to,a=B(F,s)||{hour:s===12?12:0,minute:0,ampm:"AM"};i.useEffect(()=>c?Q.onClickOutside([C,p],()=>R(!1)):void 0,[c]),i.useEffect(()=>{!c&&p.current&&U.restoreFocus(p.current)},[c]);const[I,H]=i.useState({top:-9999,left:-9999}),g=i.useCallback(()=>{if(!p.current||!C.current)return;const e=p.current.getBoundingClientRect(),t=C.current.getBoundingClientRect(),l=window.scrollY,m=window.scrollX;let h=e.bottom+l+8,w=e.left+m;const x=16,J=document.documentElement.clientWidth-t.width-x;w>J+m&&(w=e.right+m-t.width,w<x+m&&(w=x+m));const K=document.documentElement.clientHeight-t.height-x;e.bottom+8>K&&(h=e.top+l-t.height-8,h<x+l&&(h=x+l)),H({top:h,left:w})},[]);i.useLayoutEffect(()=>{if(c)return g(),window.addEventListener("resize",g),window.addEventListener("scroll",g,!0),()=>{window.removeEventListener("resize",g),window.removeEventListener("scroll",g,!0)}},[c,g]),i.useEffect(()=>{if(!c)return;const e=setTimeout(()=>{[q,A,y].forEach(t=>{if(!t.current)return;const l=t.current.querySelector(".selected");l&&l.scrollIntoView({block:"center",behavior:"smooth"})})},10);return()=>clearTimeout(e)},[c,b]);const _=i.useMemo(()=>{const e=s===12?12:24,t=s===12?1:0;return Array.from({length:e}).map((l,m)=>t+m)},[s]),D=i.useMemo(()=>{const e=[];for(let t=0;t<60;t+=r)e.push(t);return e},[r]),P=(e,t,l)=>{const m=ee(e,t,l,s),h={...o,[b]:m};$||L(h),f?.(h)},O=e=>{if(!e)return null;const t=B(e,s);return t?s===12?`${d(t.hour)}:${d(t.minute)} ${t.ampm}`:`${d(t.hour)}:${d(t.minute)}`:null},G=()=>{if(!o.from&&!o.to)return N;const e=O(o.from),t=O(o.to);return e&&!t?`${e} → `:!e&&t?` → ${t}`:`${e} → ${t}`};return n.jsxs("div",{ref:X,className:v.cn("nui-timerange-root",z),...W,children:[S&&n.jsx("input",{type:"hidden",name:S,value:o.from??""}),M&&n.jsx("input",{type:"hidden",name:M,value:o.to??""}),n.jsxs("button",{id:E,ref:p,type:"button",disabled:V,className:"nui-timerange-trigger","aria-haspopup":"dialog","aria-expanded":c,onClick:()=>{R(e=>!e),k("from")},children:[n.jsx("span",{className:!o.from&&!o.to?"nui-timerange-placeholder":"",children:G()}),n.jsxs("svg",{className:"nui-timerange-icon",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[n.jsx("circle",{cx:"12",cy:"12",r:"10"}),n.jsx("polyline",{points:"12 6 12 12 16 14"})]})]}),c&&n.jsx(Z.Portal,{children:n.jsx("div",{ref:C,className:"nui-timerange-popover",style:{position:"absolute",top:I.top,left:I.left},children:n.jsxs("div",{className:"nui-timerange-panel",children:[n.jsxs("div",{className:"nui-timerange-actions",children:[n.jsx("button",{className:v.cn("nui-timerange-part",b==="from"&&"active"),onClick:()=>k("from"),children:"Start Time"}),n.jsx("button",{className:v.cn("nui-timerange-part",b==="to"&&"active"),onClick:()=>k("to"),children:"End Time"})]}),n.jsxs("div",{className:"nui-timerange-columns",children:[n.jsx("div",{className:"nui-timerange-col",ref:q,children:_.map(e=>{const t=a.hour===e;return n.jsx("button",{className:v.cn("nui-timerange-item",t&&"selected"),onClick:()=>P(e,a.minute,a.ampm),children:d(e)},`h-${e}`)})}),n.jsx("div",{className:"nui-timerange-col",ref:A,children:D.map(e=>{const t=a.minute===e;return n.jsx("button",{className:v.cn("nui-timerange-item",t&&"selected"),onClick:()=>P(a.hour,e,a.ampm),children:d(e)},`m-${e}`)})}),s===12&&n.jsx("div",{className:"nui-timerange-col",ref:y,children:["AM","PM"].map(e=>{const t=a.ampm===e;return n.jsx("button",{className:v.cn("nui-timerange-item",t&&"selected"),onClick:()=>P(a.hour,a.minute,e),children:e},e)})})]}),n.jsxs("div",{className:"nui-timerange-footer",children:[n.jsx("button",{className:"nui-timerange-clear",onClick:()=>{const e={from:void 0,to:void 0};$||L(e),f?.(e),R(!1)},children:"Clear"}),n.jsx("button",{className:"nui-timerange-close",onClick:()=>R(!1),children:"Apply"})]})]})})})]})});T.displayName="TimeRangePicker";exports.TimeRangePicker=T;
|
|
2
|
+
//# sourceMappingURL=TimeRangePicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeRangePicker.cjs","sources":["../../../src/components/timerangepicker/TimeRangePicker.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n forwardRef,\n} from 'react';\nimport { cn } from '../../utils';\nimport { Portal, onClickOutside, restoreFocus } from '../../utils';\nimport './TimeRangePicker.css';\n\n/* ----------------------------------------------------\n Helpers\n---------------------------------------------------- */\nconst pad = (n: number | string) => String(n).padStart(2, '0');\n\ninterface ParsedTime {\n hour: number;\n minute: number;\n ampm: 'AM' | 'PM' | null;\n}\n\nfunction parseTime(timeStr?: string, clockType: 12 | 24 = 12): ParsedTime | null {\n if (!timeStr) return null;\n const [hStr, mStr] = timeStr.split(':');\n let h = parseInt(hStr, 10);\n const m = parseInt(mStr, 10);\n\n if (isNaN(h) || isNaN(m)) return null;\n\n if (clockType === 24) {\n return { hour: h, minute: m, ampm: null };\n }\n\n const ampm: 'AM' | 'PM' = h >= 12 ? 'PM' : 'AM';\n h = h % 12;\n h = h ? h : 12; \n return { hour: h, minute: m, ampm };\n}\n\nfunction buildTime(hour: number, minute: number, ampm: 'AM' | 'PM' | null, clockType: 12 | 24) {\n let h = hour;\n if (clockType === 12) {\n if (ampm === 'PM' && h < 12) h += 12;\n if (ampm === 'AM' && h === 12) h = 0;\n }\n return `${pad(h)}:${pad(minute)}`;\n}\n\n/* ----------------------------------------------------\n Types\n---------------------------------------------------- */\nexport interface TimeRange {\n from?: string; // Standard HH:mm format\n to?: string; // Standard HH:mm format\n}\n\nexport interface TimeRangePickerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'value' | 'defaultValue'> {\n /** Controlled time range object */\n value?: TimeRange;\n /** Uncontrolled default time range object */\n defaultValue?: TimeRange;\n /** Callback fired when either the start or end time changes */\n onChange?: (v: TimeRange) => void;\n \n /** Uses 12-hour or 24-hour clock formatting. Defaults to 12. */\n clockType?: 12 | 24;\n /** Step interval for the minute column. Defaults to 1. */\n minuteStep?: number;\n \n /** Placeholder text displayed when no range is selected */\n placeholder?: string;\n /** Name attribute applied to the \"from\" hidden input for native forms */\n nameFrom?: string;\n /** Name attribute applied to the \"to\" hidden input for native forms */\n nameTo?: string;\n /** Disables the picker entirely */\n disabled?: boolean;\n}\n\n/* ----------------------------------------------------\n Component\n---------------------------------------------------- */\n\n/**\n * TimeRangePicker Component\n * * A dual-state dropdown for selecting a start and end time.\n * * Features automatic scrolling, safe boundary positioning, and WAI-ARIA compliance.\n */\nexport const TimeRangePicker = forwardRef<HTMLDivElement, TimeRangePickerProps>(({\n value,\n defaultValue,\n onChange,\n clockType = 12,\n minuteStep = 1,\n placeholder = 'Select time range',\n id,\n className,\n nameFrom,\n nameTo,\n disabled = false,\n ...props\n}, ref) => {\n const controlled = value !== undefined;\n const [internal, setInternal] = useState<TimeRange | undefined>(defaultValue);\n const range: TimeRange = controlled ? value || {} : internal || {};\n\n const [open, setOpen] = useState(false);\n const [activePart, setActivePart] = useState<'from' | 'to'>('from');\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const popRef = useRef<HTMLDivElement | null>(null);\n\n const hourColRef = useRef<HTMLDivElement | null>(null);\n const minColRef = useRef<HTMLDivElement | null>(null);\n const ampmColRef = useRef<HTMLDivElement | null>(null);\n\n // Parse the currently active time part for the scroll wheels\n const activeTimeStr = activePart === 'from' ? range.from : range.to;\n const parsed = parseTime(activeTimeStr, clockType) || {\n hour: clockType === 12 ? 12 : 0,\n minute: 0,\n ampm: 'AM' as const,\n };\n\n /* ----------------------------------------------------\n Click Outside & Focus Management\n ---------------------------------------------------- */\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([popRef, triggerRef], () => setOpen(false));\n return cleanup;\n }, [open]);\n\n useEffect(() => {\n if (!open && triggerRef.current) restoreFocus(triggerRef.current);\n }, [open]);\n\n /* ----------------------------------------------------\n Smart Popover Position (with Hard Top Clamp)\n ---------------------------------------------------- */\n const [coords, setCoords] = useState({ top: -9999, left: -9999 });\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !popRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const popRect = popRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = triggerRect.bottom + scrollY + 8;\n let left = triggerRect.left + scrollX;\n const padding = 16;\n\n // X-Axis Clamp\n const maxLeft = document.documentElement.clientWidth - popRect.width - padding;\n if (left > maxLeft + scrollX) {\n left = triggerRect.right + scrollX - popRect.width;\n if (left < padding + scrollX) left = padding + scrollX;\n }\n\n // Y-Axis Clamp\n const maxTop = document.documentElement.clientHeight - popRect.height - padding;\n if (triggerRect.bottom + 8 > maxTop) {\n top = triggerRect.top + scrollY - popRect.height - 8;\n // Hard Top Clamp\n if (top < padding + scrollY) {\n top = padding + scrollY;\n }\n }\n\n setCoords({ top, left });\n }, []);\n\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition]);\n\n /* ----------------------------------------------------\n Auto-Scroll to Selected Item\n ---------------------------------------------------- */\n // We run this effect when `open` changes AND when `activePart` changes!\n useEffect(() => {\n if (!open) return;\n const timer = setTimeout(() => {\n [hourColRef, minColRef, ampmColRef].forEach((colRef) => {\n if (!colRef.current) return;\n const selectedEl = colRef.current.querySelector('.selected');\n if (selectedEl) {\n selectedEl.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n });\n }, 10);\n return () => clearTimeout(timer);\n }, [open, activePart]);\n\n /* ----------------------------------------------------\n Column Generation\n ---------------------------------------------------- */\n const hours = useMemo(() => {\n const length = clockType === 12 ? 12 : 24;\n const start = clockType === 12 ? 1 : 0;\n return Array.from({ length }).map((_, i) => start + i);\n }, [clockType]);\n\n const minutes = useMemo(() => {\n const arr = [];\n for (let i = 0; i < 60; i += minuteStep) arr.push(i);\n return arr;\n }, [minuteStep]);\n\n /* ----------------------------------------------------\n Commit Selections\n ---------------------------------------------------- */\n const commit = (h: number, m: number, a: 'AM' | 'PM' | null) => {\n const newVal = buildTime(h, m, a, clockType);\n const newRange = { ...range, [activePart]: newVal };\n \n if (!controlled) setInternal(newRange);\n onChange?.(newRange);\n };\n\n /* ----------------------------------------------------\n Display Label\n ---------------------------------------------------- */\n const formatLabel = (timeStr?: string) => {\n if (!timeStr) return null;\n const p = parseTime(timeStr, clockType);\n if (!p) return null;\n return clockType === 12 \n ? `${pad(p.hour)}:${pad(p.minute)} ${p.ampm}`\n : `${pad(p.hour)}:${pad(p.minute)}`;\n };\n\n const label = (): string => {\n if (!range.from && !range.to) return placeholder;\n const f = formatLabel(range.from);\n const t = formatLabel(range.to);\n \n if (f && !t) return `${f} → `;\n if (!f && t) return ` → ${t}`;\n return `${f} → ${t}`;\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div ref={ref} className={cn(\"nui-timerange-root\", className)} {...props}>\n {nameFrom && <input type=\"hidden\" name={nameFrom} value={range.from ?? ''} />}\n {nameTo && <input type=\"hidden\" name={nameTo} value={range.to ?? ''} />}\n\n <button\n id={id}\n ref={triggerRef}\n type=\"button\"\n disabled={disabled}\n className=\"nui-timerange-trigger\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onClick={() => {\n setOpen((s) => !s);\n setActivePart('from');\n }}\n >\n <span className={(!range.from && !range.to) ? \"nui-timerange-placeholder\" : \"\"}>\n {label()}\n </span>\n <svg className=\"nui-timerange-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n </button>\n\n {open && (\n <Portal>\n <div\n ref={popRef}\n className=\"nui-timerange-popover\"\n style={{ position: 'absolute', top: coords.top, left: coords.left }}\n >\n <div className=\"nui-timerange-panel\">\n \n {/* Internal Part Toggle */}\n <div className=\"nui-timerange-actions\">\n <button\n className={cn(\"nui-timerange-part\", activePart === 'from' && \"active\")}\n onClick={() => setActivePart('from')}\n >\n Start Time\n </button>\n <button\n className={cn(\"nui-timerange-part\", activePart === 'to' && \"active\")}\n onClick={() => setActivePart('to')}\n >\n End Time\n </button>\n </div>\n\n {/* Time Columns */}\n <div className=\"nui-timerange-columns\">\n {/* HOURS */}\n <div className=\"nui-timerange-col\" ref={hourColRef}>\n {hours.map((h) => {\n const sel = parsed.hour === h;\n return (\n <button\n key={`h-${h}`}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(h, parsed.minute, parsed.ampm)}\n >\n {pad(h)}\n </button>\n );\n })}\n </div>\n\n {/* MINUTES */}\n <div className=\"nui-timerange-col\" ref={minColRef}>\n {minutes.map((m) => {\n const sel = parsed.minute === m;\n return (\n <button\n key={`m-${m}`}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, m, parsed.ampm)}\n >\n {pad(m)}\n </button>\n );\n })}\n </div>\n\n {/* AM / PM */}\n {clockType === 12 && (\n <div className=\"nui-timerange-col\" ref={ampmColRef}>\n {(['AM', 'PM'] as const).map((a) => {\n const sel = parsed.ampm === a;\n return (\n <button\n key={a}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, parsed.minute, a)}\n >\n {a}\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* FOOTER */}\n <div className=\"nui-timerange-footer\">\n <button\n className=\"nui-timerange-clear\"\n onClick={() => {\n const empty = { from: undefined, to: undefined };\n if (!controlled) setInternal(empty);\n onChange?.(empty);\n setOpen(false);\n }}\n >\n Clear\n </button>\n\n <button\n className=\"nui-timerange-close\"\n onClick={() => setOpen(false)}\n >\n Apply\n </button>\n </div>\n\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n});\n\nTimeRangePicker.displayName = 'TimeRangePicker';"],"names":["pad","n","parseTime","timeStr","clockType","hStr","mStr","h","m","ampm","buildTime","hour","minute","TimeRangePicker","forwardRef","value","defaultValue","onChange","minuteStep","placeholder","id","className","nameFrom","nameTo","disabled","props","ref","controlled","internal","setInternal","useState","range","open","setOpen","activePart","setActivePart","triggerRef","useRef","popRef","hourColRef","minColRef","ampmColRef","activeTimeStr","parsed","useEffect","onClickOutside","restoreFocus","coords","setCoords","updatePosition","useCallback","triggerRect","popRect","scrollY","scrollX","top","left","padding","maxLeft","maxTop","useLayoutEffect","timer","colRef","selectedEl","hours","useMemo","length","start","_","i","minutes","arr","commit","a","newVal","newRange","formatLabel","p","label","f","jsxs","cn","jsx","s","Portal","sel","empty"],"mappings":"mXAkBMA,EAAOC,GAAuB,OAAOA,CAAC,EAAE,SAAS,EAAG,GAAG,EAQ7D,SAASC,EAAUC,EAAkBC,EAAqB,GAAuB,CAC/E,GAAI,CAACD,EAAS,OAAO,KACrB,KAAM,CAACE,EAAMC,CAAI,EAAIH,EAAQ,MAAM,GAAG,EACtC,IAAII,EAAI,SAASF,EAAM,EAAE,EACzB,MAAMG,EAAI,SAASF,EAAM,EAAE,EAE3B,GAAI,MAAMC,CAAC,GAAK,MAAMC,CAAC,EAAG,OAAO,KAEjC,GAAIJ,IAAc,GAChB,MAAO,CAAE,KAAMG,EAAG,OAAQC,EAAG,KAAM,IAAA,EAGrC,MAAMC,EAAoBF,GAAK,GAAK,KAAO,KAC3C,OAAAA,EAAIA,EAAI,GACRA,EAAIA,GAAQ,GACL,CAAE,KAAMA,EAAG,OAAQC,EAAG,KAAAC,CAAA,CAC/B,CAEA,SAASC,GAAUC,EAAcC,EAAgBH,EAA0BL,EAAoB,CAC7F,IAAIG,EAAII,EACR,OAAIP,IAAc,KACZK,IAAS,MAAQF,EAAI,KAAIA,GAAK,IAC9BE,IAAS,MAAQF,IAAM,KAAIA,EAAI,IAE9B,GAAGP,EAAIO,CAAC,CAAC,IAAIP,EAAIY,CAAM,CAAC,EACjC,CA0CO,MAAMC,EAAkBC,EAAAA,WAAiD,CAAC,CAC/E,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,UAAAb,EAAY,GACZ,WAAAc,EAAa,EACb,YAAAC,EAAc,oBACd,GAAAC,EACA,UAAAC,EACA,SAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,GACX,GAAGC,CACL,EAAGC,IAAQ,CACT,MAAMC,EAAaZ,IAAU,OACvB,CAACa,EAAUC,CAAW,EAAIC,EAAAA,SAAgCd,CAAY,EACtEe,EAAmBJ,EAAaZ,GAAS,CAAA,EAAKa,GAAY,CAAA,EAE1D,CAACI,EAAMC,CAAO,EAAIH,EAAAA,SAAS,EAAK,EAChC,CAACI,EAAYC,CAAa,EAAIL,EAAAA,SAAwB,MAAM,EAE5DM,EAAaC,EAAAA,OAAiC,IAAI,EAClDC,EAASD,EAAAA,OAA8B,IAAI,EAE3CE,EAAaF,EAAAA,OAA8B,IAAI,EAC/CG,EAAYH,EAAAA,OAA8B,IAAI,EAC9CI,EAAaJ,EAAAA,OAA8B,IAAI,EAG/CK,EAAgBR,IAAe,OAASH,EAAM,KAAOA,EAAM,GAC3DY,EAASzC,EAAUwC,EAAetC,CAAS,GAAK,CACpD,KAAMA,IAAc,GAAK,GAAK,EAC9B,OAAQ,EACR,KAAM,IAAA,EAMRwC,EAAAA,UAAU,IACHZ,EACWa,EAAAA,eAAe,CAACP,EAAQF,CAAU,EAAG,IAAMH,EAAQ,EAAK,CAAC,EAD9D,OAGV,CAACD,CAAI,CAAC,EAETY,EAAAA,UAAU,IAAM,CACV,CAACZ,GAAQI,EAAW,SAASU,EAAAA,aAAaV,EAAW,OAAO,CAClE,EAAG,CAACJ,CAAI,CAAC,EAKT,KAAM,CAACe,EAAQC,CAAS,EAAIlB,EAAAA,SAAS,CAAE,IAAK,MAAO,KAAM,MAAO,EAE1DmB,EAAiBC,EAAAA,YAAY,IAAM,CACvC,GAAI,CAACd,EAAW,SAAW,CAACE,EAAO,QAAS,OAE5C,MAAMa,EAAcf,EAAW,QAAQ,sBAAA,EACjCgB,EAAUd,EAAO,QAAQ,sBAAA,EACzBe,EAAU,OAAO,QACjBC,EAAU,OAAO,QAEvB,IAAIC,EAAMJ,EAAY,OAASE,EAAU,EACrCG,EAAOL,EAAY,KAAOG,EAC9B,MAAMG,EAAU,GAGVC,EAAU,SAAS,gBAAgB,YAAcN,EAAQ,MAAQK,EACnED,EAAOE,EAAUJ,IACnBE,EAAOL,EAAY,MAAQG,EAAUF,EAAQ,MACzCI,EAAOC,EAAUH,IAASE,EAAOC,EAAUH,IAIjD,MAAMK,EAAS,SAAS,gBAAgB,aAAeP,EAAQ,OAASK,EACpEN,EAAY,OAAS,EAAIQ,IAC3BJ,EAAMJ,EAAY,IAAME,EAAUD,EAAQ,OAAS,EAE/CG,EAAME,EAAUJ,IAClBE,EAAME,EAAUJ,IAIpBL,EAAU,CAAE,IAAAO,EAAK,KAAAC,EAAM,CACzB,EAAG,CAAA,CAAE,EAELI,EAAAA,gBAAgB,IAAM,CACpB,GAAK5B,EACL,OAAAiB,EAAA,EACA,OAAO,iBAAiB,SAAUA,CAAc,EAChD,OAAO,iBAAiB,SAAUA,EAAgB,EAAI,EAC/C,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAc,EACnD,OAAO,oBAAoB,SAAUA,EAAgB,EAAI,CAC3D,CACF,EAAG,CAACjB,EAAMiB,CAAc,CAAC,EAMzBL,EAAAA,UAAU,IAAM,CACd,GAAI,CAACZ,EAAM,OACX,MAAM6B,EAAQ,WAAW,IAAM,CAC7B,CAACtB,EAAYC,EAAWC,CAAU,EAAE,QAASqB,GAAW,CACtD,GAAI,CAACA,EAAO,QAAS,OACrB,MAAMC,EAAaD,EAAO,QAAQ,cAAc,WAAW,EACvDC,GACFA,EAAW,eAAe,CAAE,MAAO,SAAU,SAAU,SAAU,CAErE,CAAC,CACH,EAAG,EAAE,EACL,MAAO,IAAM,aAAaF,CAAK,CACjC,EAAG,CAAC7B,EAAME,CAAU,CAAC,EAKrB,MAAM8B,EAAQC,EAAAA,QAAQ,IAAM,CAC1B,MAAMC,EAAS9D,IAAc,GAAK,GAAK,GACjC+D,EAAQ/D,IAAc,GAAK,EAAI,EACrC,OAAO,MAAM,KAAK,CAAE,OAAA8D,EAAQ,EAAE,IAAI,CAACE,EAAGC,IAAMF,EAAQE,CAAC,CACvD,EAAG,CAACjE,CAAS,CAAC,EAERkE,EAAUL,EAAAA,QAAQ,IAAM,CAC5B,MAAMM,EAAM,CAAA,EACZ,QAASF,EAAI,EAAGA,EAAI,GAAIA,GAAKnD,EAAYqD,EAAI,KAAKF,CAAC,EACnD,OAAOE,CACT,EAAG,CAACrD,CAAU,CAAC,EAKTsD,EAAS,CAACjE,EAAWC,EAAWiE,IAA0B,CAC9D,MAAMC,EAAShE,GAAUH,EAAGC,EAAGiE,EAAGrE,CAAS,EACrCuE,EAAW,CAAE,GAAG5C,EAAO,CAACG,CAAU,EAAGwC,CAAA,EAEtC/C,GAAYE,EAAY8C,CAAQ,EACrC1D,IAAW0D,CAAQ,CACrB,EAKMC,EAAezE,GAAqB,CACxC,GAAI,CAACA,EAAS,OAAO,KACrB,MAAM0E,EAAI3E,EAAUC,EAASC,CAAS,EACtC,OAAKyE,EACEzE,IAAc,GACjB,GAAGJ,EAAI6E,EAAE,IAAI,CAAC,IAAI7E,EAAI6E,EAAE,MAAM,CAAC,IAAIA,EAAE,IAAI,GACzC,GAAG7E,EAAI6E,EAAE,IAAI,CAAC,IAAI7E,EAAI6E,EAAE,MAAM,CAAC,GAHpB,IAIjB,EAEMC,EAAQ,IAAc,CAC1B,GAAI,CAAC/C,EAAM,MAAQ,CAACA,EAAM,GAAI,OAAOZ,EACrC,MAAM4D,EAAIH,EAAY7C,EAAM,IAAI,EAC1B,EAAI6C,EAAY7C,EAAM,EAAE,EAE9B,OAAIgD,GAAK,CAAC,EAAU,GAAGA,CAAC,MACpB,CAACA,GAAK,EAAU,MAAM,CAAC,GACpB,GAAGA,CAAC,MAAM,CAAC,EACpB,EAKA,OACEC,OAAC,OAAI,IAAAtD,EAAU,UAAWuD,KAAG,qBAAsB5D,CAAS,EAAI,GAAGI,EAChE,SAAA,CAAAH,GAAY4D,EAAAA,IAAC,SAAM,KAAK,SAAS,KAAM5D,EAAU,MAAOS,EAAM,MAAQ,EAAA,CAAI,EAC1ER,GAAU2D,EAAAA,IAAC,QAAA,CAAM,KAAK,SAAS,KAAM3D,EAAQ,MAAOQ,EAAM,IAAM,EAAA,CAAI,EAErEiD,EAAAA,KAAC,SAAA,CACC,GAAA5D,EACA,IAAKgB,EACL,KAAK,SACL,SAAAZ,EACA,UAAU,wBACV,gBAAc,SACd,gBAAeQ,EACf,QAAS,IAAM,CACbC,EAASkD,GAAM,CAACA,CAAC,EACjBhD,EAAc,MAAM,CACtB,EAEA,SAAA,CAAA+C,EAAAA,IAAC,OAAA,CAAK,UAAY,CAACnD,EAAM,MAAQ,CAACA,EAAM,GAAM,4BAA8B,GACzE,SAAA+C,EAAA,CAAM,CACT,EACAE,EAAAA,KAAC,OAAI,UAAU,qBAAqB,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,YAAY,IAAI,cAAc,QAAQ,eAAe,QAAQ,cAAY,OACxL,SAAA,CAAAE,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,EAC/BA,EAAAA,IAAC,WAAA,CAAS,OAAO,kBAAA,CAAmB,CAAA,CAAA,CACtC,CAAA,CAAA,CAAA,EAGDlD,SACEoD,SAAA,CACC,SAAAF,EAAAA,IAAC,MAAA,CACC,IAAK5C,EACL,UAAU,wBACV,MAAO,CAAE,SAAU,WAAY,IAAKS,EAAO,IAAK,KAAMA,EAAO,IAAA,EAE7D,SAAAiC,EAAAA,KAAC,MAAA,CAAI,UAAU,sBAGb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,wBACb,SAAA,CAAAE,EAAAA,IAAC,SAAA,CACC,UAAWD,EAAAA,GAAG,qBAAsB/C,IAAe,QAAU,QAAQ,EACrE,QAAS,IAAMC,EAAc,MAAM,EACpC,SAAA,YAAA,CAAA,EAGD+C,EAAAA,IAAC,SAAA,CACC,UAAWD,EAAAA,GAAG,qBAAsB/C,IAAe,MAAQ,QAAQ,EACnE,QAAS,IAAMC,EAAc,IAAI,EAClC,SAAA,UAAA,CAAA,CAED,EACF,EAGA6C,EAAAA,KAAC,MAAA,CAAI,UAAU,wBAEb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,oBAAoB,IAAK3C,EACrC,SAAAyB,EAAM,IAAKzD,GAAM,CAChB,MAAM8E,EAAM1C,EAAO,OAASpC,EAC5B,OACE2E,EAAAA,IAAC,SAAA,CAEC,UAAWD,EAAAA,GAAG,qBAAsBI,GAAO,UAAU,EACrD,QAAS,IAAMb,EAAOjE,EAAGoC,EAAO,OAAQA,EAAO,IAAI,EAElD,WAAIpC,CAAC,CAAA,EAJD,KAAKA,CAAC,EAAA,CAOjB,CAAC,CAAA,CACH,EAGA2E,EAAAA,IAAC,OAAI,UAAU,oBAAoB,IAAK1C,EACrC,SAAA8B,EAAQ,IAAK9D,GAAM,CAClB,MAAM6E,EAAM1C,EAAO,SAAWnC,EAC9B,OACE0E,EAAAA,IAAC,SAAA,CAEC,UAAWD,EAAAA,GAAG,qBAAsBI,GAAO,UAAU,EACrD,QAAS,IAAMb,EAAO7B,EAAO,KAAMnC,EAAGmC,EAAO,IAAI,EAEhD,WAAInC,CAAC,CAAA,EAJD,KAAKA,CAAC,EAAA,CAOjB,CAAC,CAAA,CACH,EAGCJ,IAAc,IACb8E,EAAAA,IAAC,MAAA,CAAI,UAAU,oBAAoB,IAAKzC,EACpC,SAAA,CAAC,KAAM,IAAI,EAAY,IAAKgC,GAAM,CAClC,MAAMY,EAAM1C,EAAO,OAAS8B,EAC5B,OACES,EAAAA,IAAC,SAAA,CAEC,UAAWD,EAAAA,GAAG,qBAAsBI,GAAO,UAAU,EACrD,QAAS,IAAMb,EAAO7B,EAAO,KAAMA,EAAO,OAAQ8B,CAAC,EAElD,SAAAA,CAAA,EAJIA,CAAA,CAOX,CAAC,CAAA,CACH,CAAA,EAEJ,EAGAO,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAE,EAAAA,IAAC,SAAA,CACC,UAAU,sBACV,QAAS,IAAM,CACb,MAAMI,EAAQ,CAAE,KAAM,OAAW,GAAI,MAAA,EAChC3D,GAAYE,EAAYyD,CAAK,EAClCrE,IAAWqE,CAAK,EAChBrD,EAAQ,EAAK,CACf,EACD,SAAA,OAAA,CAAA,EAIDiD,EAAAA,IAAC,SAAA,CACC,UAAU,sBACV,QAAS,IAAMjD,EAAQ,EAAK,EAC7B,SAAA,OAAA,CAAA,CAED,CAAA,CACF,CAAA,CAAA,CAEF,CAAA,CAAA,CACF,CACF,CAAA,EAEJ,CAEJ,CAAC,EAEDpB,EAAgB,YAAc"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { jsxs as p, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as ee, useState as L, useRef as $, useEffect as S, useCallback as te, useLayoutEffect as ne, useMemo as X } from "react";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import { onClickOutside as re } from "../../utils/onclickoutside/onClickOutside.js";
|
|
5
|
+
import { restoreFocus as ie } from "../../utils/restorefocus/restoreFocus.js";
|
|
6
|
+
import { cn as N } from "../../utils/cn/cn.js";
|
|
7
|
+
import { Portal as oe } from "../../utils/portal/portal.js";
|
|
8
|
+
const m = (c) => String(c).padStart(2, "0");
|
|
9
|
+
function Y(c, w = 12) {
|
|
10
|
+
if (!c) return null;
|
|
11
|
+
const [d, i] = c.split(":");
|
|
12
|
+
let n = parseInt(d, 10);
|
|
13
|
+
const b = parseInt(i, 10);
|
|
14
|
+
if (isNaN(n) || isNaN(b)) return null;
|
|
15
|
+
if (w === 24)
|
|
16
|
+
return { hour: n, minute: b, ampm: null };
|
|
17
|
+
const P = n >= 12 ? "PM" : "AM";
|
|
18
|
+
return n = n % 12, n = n || 12, { hour: n, minute: b, ampm: P };
|
|
19
|
+
}
|
|
20
|
+
function se(c, w, d, i) {
|
|
21
|
+
let n = c;
|
|
22
|
+
return i === 12 && (d === "PM" && n < 12 && (n += 12), d === "AM" && n === 12 && (n = 0)), `${m(n)}:${m(w)}`;
|
|
23
|
+
}
|
|
24
|
+
const le = ee(({
|
|
25
|
+
value: c,
|
|
26
|
+
defaultValue: w,
|
|
27
|
+
onChange: d,
|
|
28
|
+
clockType: i = 12,
|
|
29
|
+
minuteStep: n = 1,
|
|
30
|
+
placeholder: b = "Select time range",
|
|
31
|
+
id: P,
|
|
32
|
+
className: q,
|
|
33
|
+
nameFrom: y,
|
|
34
|
+
nameTo: I,
|
|
35
|
+
disabled: H = !1,
|
|
36
|
+
...T
|
|
37
|
+
}, _) => {
|
|
38
|
+
const x = c !== void 0, [D, j] = L(w), o = x ? c || {} : D || {}, [s, E] = L(!1), [C, M] = L("from"), h = $(null), k = $(null), B = $(null), z = $(null), O = $(null), F = C === "from" ? o.from : o.to, a = Y(F, i) || {
|
|
39
|
+
hour: i === 12 ? 12 : 0,
|
|
40
|
+
minute: 0,
|
|
41
|
+
ampm: "AM"
|
|
42
|
+
};
|
|
43
|
+
S(() => s ? re([k, h], () => E(!1)) : void 0, [s]), S(() => {
|
|
44
|
+
!s && h.current && ie(h.current);
|
|
45
|
+
}, [s]);
|
|
46
|
+
const [V, G] = L({ top: -9999, left: -9999 }), g = te(() => {
|
|
47
|
+
if (!h.current || !k.current) return;
|
|
48
|
+
const e = h.current.getBoundingClientRect(), t = k.current.getBoundingClientRect(), l = window.scrollY, u = window.scrollX;
|
|
49
|
+
let f = e.bottom + l + 8, R = e.left + u;
|
|
50
|
+
const v = 16, U = document.documentElement.clientWidth - t.width - v;
|
|
51
|
+
R > U + u && (R = e.right + u - t.width, R < v + u && (R = v + u));
|
|
52
|
+
const Z = document.documentElement.clientHeight - t.height - v;
|
|
53
|
+
e.bottom + 8 > Z && (f = e.top + l - t.height - 8, f < v + l && (f = v + l)), G({ top: f, left: R });
|
|
54
|
+
}, []);
|
|
55
|
+
ne(() => {
|
|
56
|
+
if (s)
|
|
57
|
+
return g(), window.addEventListener("resize", g), window.addEventListener("scroll", g, !0), () => {
|
|
58
|
+
window.removeEventListener("resize", g), window.removeEventListener("scroll", g, !0);
|
|
59
|
+
};
|
|
60
|
+
}, [s, g]), S(() => {
|
|
61
|
+
if (!s) return;
|
|
62
|
+
const e = setTimeout(() => {
|
|
63
|
+
[B, z, O].forEach((t) => {
|
|
64
|
+
if (!t.current) return;
|
|
65
|
+
const l = t.current.querySelector(".selected");
|
|
66
|
+
l && l.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
67
|
+
});
|
|
68
|
+
}, 10);
|
|
69
|
+
return () => clearTimeout(e);
|
|
70
|
+
}, [s, C]);
|
|
71
|
+
const J = X(() => {
|
|
72
|
+
const e = i === 12 ? 12 : 24, t = i === 12 ? 1 : 0;
|
|
73
|
+
return Array.from({ length: e }).map((l, u) => t + u);
|
|
74
|
+
}, [i]), K = X(() => {
|
|
75
|
+
const e = [];
|
|
76
|
+
for (let t = 0; t < 60; t += n) e.push(t);
|
|
77
|
+
return e;
|
|
78
|
+
}, [n]), A = (e, t, l) => {
|
|
79
|
+
const u = se(e, t, l, i), f = { ...o, [C]: u };
|
|
80
|
+
x || j(f), d?.(f);
|
|
81
|
+
}, W = (e) => {
|
|
82
|
+
if (!e) return null;
|
|
83
|
+
const t = Y(e, i);
|
|
84
|
+
return t ? i === 12 ? `${m(t.hour)}:${m(t.minute)} ${t.ampm}` : `${m(t.hour)}:${m(t.minute)}` : null;
|
|
85
|
+
}, Q = () => {
|
|
86
|
+
if (!o.from && !o.to) return b;
|
|
87
|
+
const e = W(o.from), t = W(o.to);
|
|
88
|
+
return e && !t ? `${e} → ` : !e && t ? ` → ${t}` : `${e} → ${t}`;
|
|
89
|
+
};
|
|
90
|
+
return /* @__PURE__ */ p("div", { ref: _, className: N("nui-timerange-root", q), ...T, children: [
|
|
91
|
+
y && /* @__PURE__ */ r("input", { type: "hidden", name: y, value: o.from ?? "" }),
|
|
92
|
+
I && /* @__PURE__ */ r("input", { type: "hidden", name: I, value: o.to ?? "" }),
|
|
93
|
+
/* @__PURE__ */ p(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
id: P,
|
|
97
|
+
ref: h,
|
|
98
|
+
type: "button",
|
|
99
|
+
disabled: H,
|
|
100
|
+
className: "nui-timerange-trigger",
|
|
101
|
+
"aria-haspopup": "dialog",
|
|
102
|
+
"aria-expanded": s,
|
|
103
|
+
onClick: () => {
|
|
104
|
+
E((e) => !e), M("from");
|
|
105
|
+
},
|
|
106
|
+
children: [
|
|
107
|
+
/* @__PURE__ */ r("span", { className: !o.from && !o.to ? "nui-timerange-placeholder" : "", children: Q() }),
|
|
108
|
+
/* @__PURE__ */ p("svg", { className: "nui-timerange-icon", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
109
|
+
/* @__PURE__ */ r("circle", { cx: "12", cy: "12", r: "10" }),
|
|
110
|
+
/* @__PURE__ */ r("polyline", { points: "12 6 12 12 16 14" })
|
|
111
|
+
] })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
s && /* @__PURE__ */ r(oe, { children: /* @__PURE__ */ r(
|
|
116
|
+
"div",
|
|
117
|
+
{
|
|
118
|
+
ref: k,
|
|
119
|
+
className: "nui-timerange-popover",
|
|
120
|
+
style: { position: "absolute", top: V.top, left: V.left },
|
|
121
|
+
children: /* @__PURE__ */ p("div", { className: "nui-timerange-panel", children: [
|
|
122
|
+
/* @__PURE__ */ p("div", { className: "nui-timerange-actions", children: [
|
|
123
|
+
/* @__PURE__ */ r(
|
|
124
|
+
"button",
|
|
125
|
+
{
|
|
126
|
+
className: N("nui-timerange-part", C === "from" && "active"),
|
|
127
|
+
onClick: () => M("from"),
|
|
128
|
+
children: "Start Time"
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
/* @__PURE__ */ r(
|
|
132
|
+
"button",
|
|
133
|
+
{
|
|
134
|
+
className: N("nui-timerange-part", C === "to" && "active"),
|
|
135
|
+
onClick: () => M("to"),
|
|
136
|
+
children: "End Time"
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
] }),
|
|
140
|
+
/* @__PURE__ */ p("div", { className: "nui-timerange-columns", children: [
|
|
141
|
+
/* @__PURE__ */ r("div", { className: "nui-timerange-col", ref: B, children: J.map((e) => {
|
|
142
|
+
const t = a.hour === e;
|
|
143
|
+
return /* @__PURE__ */ r(
|
|
144
|
+
"button",
|
|
145
|
+
{
|
|
146
|
+
className: N("nui-timerange-item", t && "selected"),
|
|
147
|
+
onClick: () => A(e, a.minute, a.ampm),
|
|
148
|
+
children: m(e)
|
|
149
|
+
},
|
|
150
|
+
`h-${e}`
|
|
151
|
+
);
|
|
152
|
+
}) }),
|
|
153
|
+
/* @__PURE__ */ r("div", { className: "nui-timerange-col", ref: z, children: K.map((e) => {
|
|
154
|
+
const t = a.minute === e;
|
|
155
|
+
return /* @__PURE__ */ r(
|
|
156
|
+
"button",
|
|
157
|
+
{
|
|
158
|
+
className: N("nui-timerange-item", t && "selected"),
|
|
159
|
+
onClick: () => A(a.hour, e, a.ampm),
|
|
160
|
+
children: m(e)
|
|
161
|
+
},
|
|
162
|
+
`m-${e}`
|
|
163
|
+
);
|
|
164
|
+
}) }),
|
|
165
|
+
i === 12 && /* @__PURE__ */ r("div", { className: "nui-timerange-col", ref: O, children: ["AM", "PM"].map((e) => {
|
|
166
|
+
const t = a.ampm === e;
|
|
167
|
+
return /* @__PURE__ */ r(
|
|
168
|
+
"button",
|
|
169
|
+
{
|
|
170
|
+
className: N("nui-timerange-item", t && "selected"),
|
|
171
|
+
onClick: () => A(a.hour, a.minute, e),
|
|
172
|
+
children: e
|
|
173
|
+
},
|
|
174
|
+
e
|
|
175
|
+
);
|
|
176
|
+
}) })
|
|
177
|
+
] }),
|
|
178
|
+
/* @__PURE__ */ p("div", { className: "nui-timerange-footer", children: [
|
|
179
|
+
/* @__PURE__ */ r(
|
|
180
|
+
"button",
|
|
181
|
+
{
|
|
182
|
+
className: "nui-timerange-clear",
|
|
183
|
+
onClick: () => {
|
|
184
|
+
const e = { from: void 0, to: void 0 };
|
|
185
|
+
x || j(e), d?.(e), E(!1);
|
|
186
|
+
},
|
|
187
|
+
children: "Clear"
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
/* @__PURE__ */ r(
|
|
191
|
+
"button",
|
|
192
|
+
{
|
|
193
|
+
className: "nui-timerange-close",
|
|
194
|
+
onClick: () => E(!1),
|
|
195
|
+
children: "Apply"
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
] })
|
|
199
|
+
] })
|
|
200
|
+
}
|
|
201
|
+
) })
|
|
202
|
+
] });
|
|
203
|
+
});
|
|
204
|
+
le.displayName = "TimeRangePicker";
|
|
205
|
+
export {
|
|
206
|
+
le as TimeRangePicker
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=TimeRangePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeRangePicker.js","sources":["../../../src/components/timerangepicker/TimeRangePicker.tsx"],"sourcesContent":["\"use client\";\n\nimport React, {\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n forwardRef,\n} from 'react';\nimport { cn } from '../../utils';\nimport { Portal, onClickOutside, restoreFocus } from '../../utils';\nimport './TimeRangePicker.css';\n\n/* ----------------------------------------------------\n Helpers\n---------------------------------------------------- */\nconst pad = (n: number | string) => String(n).padStart(2, '0');\n\ninterface ParsedTime {\n hour: number;\n minute: number;\n ampm: 'AM' | 'PM' | null;\n}\n\nfunction parseTime(timeStr?: string, clockType: 12 | 24 = 12): ParsedTime | null {\n if (!timeStr) return null;\n const [hStr, mStr] = timeStr.split(':');\n let h = parseInt(hStr, 10);\n const m = parseInt(mStr, 10);\n\n if (isNaN(h) || isNaN(m)) return null;\n\n if (clockType === 24) {\n return { hour: h, minute: m, ampm: null };\n }\n\n const ampm: 'AM' | 'PM' = h >= 12 ? 'PM' : 'AM';\n h = h % 12;\n h = h ? h : 12; \n return { hour: h, minute: m, ampm };\n}\n\nfunction buildTime(hour: number, minute: number, ampm: 'AM' | 'PM' | null, clockType: 12 | 24) {\n let h = hour;\n if (clockType === 12) {\n if (ampm === 'PM' && h < 12) h += 12;\n if (ampm === 'AM' && h === 12) h = 0;\n }\n return `${pad(h)}:${pad(minute)}`;\n}\n\n/* ----------------------------------------------------\n Types\n---------------------------------------------------- */\nexport interface TimeRange {\n from?: string; // Standard HH:mm format\n to?: string; // Standard HH:mm format\n}\n\nexport interface TimeRangePickerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'value' | 'defaultValue'> {\n /** Controlled time range object */\n value?: TimeRange;\n /** Uncontrolled default time range object */\n defaultValue?: TimeRange;\n /** Callback fired when either the start or end time changes */\n onChange?: (v: TimeRange) => void;\n \n /** Uses 12-hour or 24-hour clock formatting. Defaults to 12. */\n clockType?: 12 | 24;\n /** Step interval for the minute column. Defaults to 1. */\n minuteStep?: number;\n \n /** Placeholder text displayed when no range is selected */\n placeholder?: string;\n /** Name attribute applied to the \"from\" hidden input for native forms */\n nameFrom?: string;\n /** Name attribute applied to the \"to\" hidden input for native forms */\n nameTo?: string;\n /** Disables the picker entirely */\n disabled?: boolean;\n}\n\n/* ----------------------------------------------------\n Component\n---------------------------------------------------- */\n\n/**\n * TimeRangePicker Component\n * * A dual-state dropdown for selecting a start and end time.\n * * Features automatic scrolling, safe boundary positioning, and WAI-ARIA compliance.\n */\nexport const TimeRangePicker = forwardRef<HTMLDivElement, TimeRangePickerProps>(({\n value,\n defaultValue,\n onChange,\n clockType = 12,\n minuteStep = 1,\n placeholder = 'Select time range',\n id,\n className,\n nameFrom,\n nameTo,\n disabled = false,\n ...props\n}, ref) => {\n const controlled = value !== undefined;\n const [internal, setInternal] = useState<TimeRange | undefined>(defaultValue);\n const range: TimeRange = controlled ? value || {} : internal || {};\n\n const [open, setOpen] = useState(false);\n const [activePart, setActivePart] = useState<'from' | 'to'>('from');\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const popRef = useRef<HTMLDivElement | null>(null);\n\n const hourColRef = useRef<HTMLDivElement | null>(null);\n const minColRef = useRef<HTMLDivElement | null>(null);\n const ampmColRef = useRef<HTMLDivElement | null>(null);\n\n // Parse the currently active time part for the scroll wheels\n const activeTimeStr = activePart === 'from' ? range.from : range.to;\n const parsed = parseTime(activeTimeStr, clockType) || {\n hour: clockType === 12 ? 12 : 0,\n minute: 0,\n ampm: 'AM' as const,\n };\n\n /* ----------------------------------------------------\n Click Outside & Focus Management\n ---------------------------------------------------- */\n useEffect(() => {\n if (!open) return;\n const cleanup = onClickOutside([popRef, triggerRef], () => setOpen(false));\n return cleanup;\n }, [open]);\n\n useEffect(() => {\n if (!open && triggerRef.current) restoreFocus(triggerRef.current);\n }, [open]);\n\n /* ----------------------------------------------------\n Smart Popover Position (with Hard Top Clamp)\n ---------------------------------------------------- */\n const [coords, setCoords] = useState({ top: -9999, left: -9999 });\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !popRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const popRect = popRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = triggerRect.bottom + scrollY + 8;\n let left = triggerRect.left + scrollX;\n const padding = 16;\n\n // X-Axis Clamp\n const maxLeft = document.documentElement.clientWidth - popRect.width - padding;\n if (left > maxLeft + scrollX) {\n left = triggerRect.right + scrollX - popRect.width;\n if (left < padding + scrollX) left = padding + scrollX;\n }\n\n // Y-Axis Clamp\n const maxTop = document.documentElement.clientHeight - popRect.height - padding;\n if (triggerRect.bottom + 8 > maxTop) {\n top = triggerRect.top + scrollY - popRect.height - 8;\n // Hard Top Clamp\n if (top < padding + scrollY) {\n top = padding + scrollY;\n }\n }\n\n setCoords({ top, left });\n }, []);\n\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition]);\n\n /* ----------------------------------------------------\n Auto-Scroll to Selected Item\n ---------------------------------------------------- */\n // We run this effect when `open` changes AND when `activePart` changes!\n useEffect(() => {\n if (!open) return;\n const timer = setTimeout(() => {\n [hourColRef, minColRef, ampmColRef].forEach((colRef) => {\n if (!colRef.current) return;\n const selectedEl = colRef.current.querySelector('.selected');\n if (selectedEl) {\n selectedEl.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n });\n }, 10);\n return () => clearTimeout(timer);\n }, [open, activePart]);\n\n /* ----------------------------------------------------\n Column Generation\n ---------------------------------------------------- */\n const hours = useMemo(() => {\n const length = clockType === 12 ? 12 : 24;\n const start = clockType === 12 ? 1 : 0;\n return Array.from({ length }).map((_, i) => start + i);\n }, [clockType]);\n\n const minutes = useMemo(() => {\n const arr = [];\n for (let i = 0; i < 60; i += minuteStep) arr.push(i);\n return arr;\n }, [minuteStep]);\n\n /* ----------------------------------------------------\n Commit Selections\n ---------------------------------------------------- */\n const commit = (h: number, m: number, a: 'AM' | 'PM' | null) => {\n const newVal = buildTime(h, m, a, clockType);\n const newRange = { ...range, [activePart]: newVal };\n \n if (!controlled) setInternal(newRange);\n onChange?.(newRange);\n };\n\n /* ----------------------------------------------------\n Display Label\n ---------------------------------------------------- */\n const formatLabel = (timeStr?: string) => {\n if (!timeStr) return null;\n const p = parseTime(timeStr, clockType);\n if (!p) return null;\n return clockType === 12 \n ? `${pad(p.hour)}:${pad(p.minute)} ${p.ampm}`\n : `${pad(p.hour)}:${pad(p.minute)}`;\n };\n\n const label = (): string => {\n if (!range.from && !range.to) return placeholder;\n const f = formatLabel(range.from);\n const t = formatLabel(range.to);\n \n if (f && !t) return `${f} → `;\n if (!f && t) return ` → ${t}`;\n return `${f} → ${t}`;\n };\n\n /* ----------------------------------------------------\n Render\n ---------------------------------------------------- */\n return (\n <div ref={ref} className={cn(\"nui-timerange-root\", className)} {...props}>\n {nameFrom && <input type=\"hidden\" name={nameFrom} value={range.from ?? ''} />}\n {nameTo && <input type=\"hidden\" name={nameTo} value={range.to ?? ''} />}\n\n <button\n id={id}\n ref={triggerRef}\n type=\"button\"\n disabled={disabled}\n className=\"nui-timerange-trigger\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onClick={() => {\n setOpen((s) => !s);\n setActivePart('from');\n }}\n >\n <span className={(!range.from && !range.to) ? \"nui-timerange-placeholder\" : \"\"}>\n {label()}\n </span>\n <svg className=\"nui-timerange-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n </button>\n\n {open && (\n <Portal>\n <div\n ref={popRef}\n className=\"nui-timerange-popover\"\n style={{ position: 'absolute', top: coords.top, left: coords.left }}\n >\n <div className=\"nui-timerange-panel\">\n \n {/* Internal Part Toggle */}\n <div className=\"nui-timerange-actions\">\n <button\n className={cn(\"nui-timerange-part\", activePart === 'from' && \"active\")}\n onClick={() => setActivePart('from')}\n >\n Start Time\n </button>\n <button\n className={cn(\"nui-timerange-part\", activePart === 'to' && \"active\")}\n onClick={() => setActivePart('to')}\n >\n End Time\n </button>\n </div>\n\n {/* Time Columns */}\n <div className=\"nui-timerange-columns\">\n {/* HOURS */}\n <div className=\"nui-timerange-col\" ref={hourColRef}>\n {hours.map((h) => {\n const sel = parsed.hour === h;\n return (\n <button\n key={`h-${h}`}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(h, parsed.minute, parsed.ampm)}\n >\n {pad(h)}\n </button>\n );\n })}\n </div>\n\n {/* MINUTES */}\n <div className=\"nui-timerange-col\" ref={minColRef}>\n {minutes.map((m) => {\n const sel = parsed.minute === m;\n return (\n <button\n key={`m-${m}`}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, m, parsed.ampm)}\n >\n {pad(m)}\n </button>\n );\n })}\n </div>\n\n {/* AM / PM */}\n {clockType === 12 && (\n <div className=\"nui-timerange-col\" ref={ampmColRef}>\n {(['AM', 'PM'] as const).map((a) => {\n const sel = parsed.ampm === a;\n return (\n <button\n key={a}\n className={cn(\"nui-timerange-item\", sel && \"selected\")}\n onClick={() => commit(parsed.hour, parsed.minute, a)}\n >\n {a}\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* FOOTER */}\n <div className=\"nui-timerange-footer\">\n <button\n className=\"nui-timerange-clear\"\n onClick={() => {\n const empty = { from: undefined, to: undefined };\n if (!controlled) setInternal(empty);\n onChange?.(empty);\n setOpen(false);\n }}\n >\n Clear\n </button>\n\n <button\n className=\"nui-timerange-close\"\n onClick={() => setOpen(false)}\n >\n Apply\n </button>\n </div>\n\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n});\n\nTimeRangePicker.displayName = 'TimeRangePicker';"],"names":["pad","n","parseTime","timeStr","clockType","hStr","mStr","h","m","ampm","buildTime","hour","minute","TimeRangePicker","forwardRef","value","defaultValue","onChange","minuteStep","placeholder","id","className","nameFrom","nameTo","disabled","props","ref","controlled","internal","setInternal","useState","range","open","setOpen","activePart","setActivePart","triggerRef","useRef","popRef","hourColRef","minColRef","ampmColRef","activeTimeStr","parsed","useEffect","onClickOutside","restoreFocus","coords","setCoords","updatePosition","useCallback","triggerRect","popRect","scrollY","scrollX","top","left","padding","maxLeft","maxTop","useLayoutEffect","timer","colRef","selectedEl","hours","useMemo","length","start","_","i","minutes","arr","commit","a","newVal","newRange","formatLabel","p","label","f","jsxs","cn","jsx","s","Portal","sel","empty"],"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 i=require("react/jsx-runtime"),t=require("react");;/* empty css */const h=require("../../utils/portal/portal.cjs"),v=require("../../utils/cn/cn.cjs"),m=t.createContext(null);function p(){const s=t.useContext(m);if(!s)throw new Error("useToast must be used inside a <ToastProvider>");return s}function g({children:s}){const[d,o]=t.useState([]),[f,u]=t.useState(!1);t.useEffect(()=>{u(!0)},[]);const c=t.useCallback((e,a)=>{const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`toast-${Date.now()}-${Math.floor(Math.random()*1e4)}`;return o(x=>[...x,{id:n,message:e,...a}]),n},[]),r=t.useCallback(e=>{o(a=>a.map(n=>n.id===e?{...n,isClosing:!0}:n))},[]),l=t.useCallback(e=>{o(a=>a.filter(n=>n.id!==e))},[]);return i.jsxs(m.Provider,{value:{show:c,dismiss:r},children:[s,f&&i.jsx(h.Portal,{children:i.jsx("div",{className:"nui-toast-region","aria-live":"polite","aria-atomic":"true",role:"region","aria-label":"Notifications",children:d.map(e=>i.jsx(j,{toast:e,onDismiss:()=>r(e.id),onRemove:()=>l(e.id)},e.id))})})]})}function j({toast:s,onRemove:d}){const[o,f]=t.useState(!1),u=t.useRef(null),c=s.duration!==void 0?s.duration:4e3,r=t.useCallback(()=>{f(!0),setTimeout(()=>{d()},200)},[d]);t.useEffect(()=>{s.isClosing&&r()},[s.isClosing,r]);const l=t.useCallback(()=>{c===1/0||o||(u.current=setTimeout(()=>{r()},c))},[c,o,r]),e=t.useCallback(()=>{u.current&&clearTimeout(u.current)},[]);t.useEffect(()=>(l(),e),[l,e]);const a=s.variant==="error"?"alert":"status";return i.jsxs("div",{className:v.cn("nui-toast",`nui-toast--${s.variant||"default"}`),"data-state":o?"closed":"open",onMouseEnter:e,onMouseLeave:l,role:a,children:[i.jsxs("div",{className:"nui-toast__content",children:[i.jsx("strong",{className:"nui-toast__title",children:s.message}),s.description&&i.jsx("p",{className:"nui-toast__description",children:s.description})]}),i.jsx("button",{type:"button","aria-label":"Close notification",className:"nui-toast__close",onClick:n=>{n.preventDefault(),e(),r()},children:i.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[i.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),i.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})}exports.ToastProvider=g;exports.useToast=p;
|
|
2
2
|
//# sourceMappingURL=Toast.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.cjs","sources":["../../../src/components/toast/Toast.tsx"],"sourcesContent":["/**\r\n * Toast.tsx\r\n * ----------\r\n * Basic toast component UI. The provider handles logic.\r\n * ------------------\r\n * - Global provider that renders all toasts\r\n * - Contains aria-live region for screen readers\r\n * - Handles auto-dismiss\r\n * - Provides useToast() hook\r\n */\r\n\r\nimport React, { createContext, useContext, useState, useCallback } from 'react';\r\nimport { Portal } from '../../utils/portal/portal';\r\nimport './Toast.css';\r\n\r\ninterface ToastItem {\r\n id: string;\r\n message: string;\r\n}\r\n\r\ninterface ToastContextValue {\r\n show: (message: string, timeout?: number) => void;\r\n}\r\n\r\ninterface ToastProps {\r\n id: string;\r\n message: string;\r\n onClose: (id: string) => void;\r\n}\r\n\r\nexport function Toast({ id, message, onClose }: ToastProps) {\r\n return (\r\n <div className=\"ui-toast\" role=\"alert\">\r\n <span>{message}</span>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Close notification\"\r\n onClick={() => onClose(id)}\r\n >\r\n ×\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nconst ToastContext = createContext<ToastContextValue | null>(null);\r\n\r\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\r\n const [toasts, setToasts] = useState<ToastItem[]>([]);\r\n\r\n const show = useCallback((message: string, timeout = 3000) => {\r\n const id = Math.random().toString(36).slice(2);\r\n\r\n setToasts((prev) => [...prev, { id, message }]);\r\n\r\n setTimeout(() => {\r\n setToasts((prev) => prev.filter((t) => t.id !== id));\r\n }, timeout);\r\n }, []);\r\n\r\n const remove = (id: string) => {\r\n setToasts((prev) => prev.filter((t) => t.id !== id));\r\n };\r\n\r\n return (\r\n <ToastContext.Provider value={{ show }}>\r\n {/* Main app */}\r\n {children}\r\n\r\n {/* Portal for notification list */}\r\n <Portal>\r\n <div\r\n className=\"ui-toast-container\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\"\r\n >\r\n {toasts.map((t) => (\r\n <Toast key={t.id} id={t.id} message={t.message} onClose={remove} />\r\n ))}\r\n </div>\r\n </Portal>\r\n </ToastContext.Provider>\r\n );\r\n}\r\n\r\nexport function useToast() {\r\n const ctx = useContext(ToastContext);\r\n if (!ctx) throw new Error('useToast must be used inside <ToastProvider>');\r\n return ctx;\r\n}\r\n"],"names":["Toast","id","message","onClose","jsxs","jsx","ToastContext","createContext","ToastProvider","children","toasts","setToasts","useState","show","useCallback","timeout","prev","t","remove","Portal","useToast","ctx","useContext"],"mappings":"8MA8BO,SAASA,EAAM,CAAE,GAAAC,EAAI,QAAAC,EAAS,QAAAC,GAAuB,CAC1D,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,WAAW,KAAK,QAC7B,SAAA,CAAAC,EAAAA,IAAC,QAAM,SAAAH,CAAA,CAAQ,EACfG,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,qBACX,QAAS,IAAMF,EAAQF,CAAE,EAC1B,SAAA,GAAA,CAAA,CAED,EACF,CAEJ,CAEA,MAAMK,EAAeC,EAAAA,cAAwC,IAAI,EAE1D,SAASC,EAAc,CAAE,SAAAC,GAA2C,CACzE,KAAM,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAsB,CAAA,CAAE,EAE9CC,EAAOC,EAAAA,YAAY,CAACZ,EAAiBa,EAAU,MAAS,CAC5D,MAAMd,EAAK,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,CAAC,EAE7CU,EAAWK,GAAS,CAAC,GAAGA,EAAM,CAAE,GAAAf,EAAI,QAAAC,CAAA,CAAS,CAAC,EAE9C,WAAW,IAAM,CACfS,EAAWK,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOhB,CAAE,CAAC,CACrD,EAAGc,CAAO,CACZ,EAAG,CAAA,CAAE,EAECG,EAAUjB,GAAe,CAC7BU,EAAWK,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOhB,CAAE,CAAC,CACrD,EAEA,cACGK,EAAa,SAAb,CAAsB,MAAO,CAAE,KAAAO,GAE7B,SAAA,CAAAJ,QAGAU,EAAAA,OAAA,CACC,SAAAd,EAAAA,IAAC,MAAA,CACC,UAAU,qBACV,YAAU,SACV,cAAY,OAEX,WAAO,IAAKY,GACXZ,MAACL,GAAiB,GAAIiB,EAAE,GAAI,QAASA,EAAE,QAAS,QAASC,CAAA,EAA7CD,EAAE,EAAmD,CAClE,CAAA,CAAA,CACH,CACF,CAAA,EACF,CAEJ,CAEO,SAASG,GAAW,CACzB,MAAMC,EAAMC,EAAAA,WAAWhB,CAAY,EACnC,GAAI,CAACe,EAAK,MAAM,IAAI,MAAM,8CAA8C,EACxE,OAAOA,CACT"}
|
|
1
|
+
{"version":3,"file":"Toast.cjs","sources":["../../../src/components/toast/Toast.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { cn } from '../../utils';\nimport { Portal } from '../../utils';\nimport './Toast.css';\n\n/* ============================================================\n * Types\n * ============================================================ */\n\nexport type ToastVariant = 'default' | 'success' | 'error' | 'warning';\n\nexport interface ToastOptions {\n /** Time in milliseconds before the toast auto-dismisses. Set to Infinity to disable. Defaults to 4000. */\n duration?: number;\n /** The semantic visual variant of the toast. Defaults to 'default'. */\n variant?: ToastVariant;\n /** Secondary descriptive text displayed below the main message. */\n description?: React.ReactNode;\n}\n\nexport interface ToastData extends ToastOptions {\n id: string;\n message: React.ReactNode;\n}\n\ninterface ToastContextValue {\n /** Displays a new toast notification and returns its unique ID */\n show: (message: React.ReactNode, options?: ToastOptions) => string;\n /** Programmatically triggers the exit animation and removes the toast by ID */\n dismiss: (id: string) => void;\n}\n\n/* ============================================================\n * Context\n * ============================================================ */\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\nexport function useToast() {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error('useToast must be used inside a <ToastProvider>');\n return ctx;\n}\n\n/* ============================================================\n * 1. Provider & Container\n * ============================================================ */\n\n/**\n * Toast Provider\n * * Wraps your application to provide the `useToast` hook.\n * * Automatically manages the WAI-ARIA live region Portal for rendering notifications.\n * * Note: Does not use `forwardRef` as it strictly returns a Context Provider and a Portal.\n */\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n const [toasts, setToasts] = useState<ToastData[]>([]);\n const [isMounted, setIsMounted] = useState(false);\n\n // Prevent SSR Hydration mismatch for the Portal by only mounting the region on the client\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n const show = useCallback((message: React.ReactNode, options?: ToastOptions) => {\n // Generate a secure, unique ID without relying on math.random() alone\n const id = typeof crypto !== 'undefined' && crypto.randomUUID \n ? crypto.randomUUID() \n : `toast-${Date.now()}-${Math.floor(Math.random() * 10000)}`;\n\n setToasts((prev) => [...prev, { id, message, ...options }]);\n return id;\n }, []);\n\n const dismiss = useCallback((id: string) => {\n // We don't remove it from the array immediately. \n // Flagging it triggers the ToastItem's CSS exit animation, which then calls remove() safely.\n setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, isClosing: true } : t)));\n }, []);\n\n const remove = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ show, dismiss }}>\n {children}\n\n {isMounted && (\n <Portal>\n <div\n className=\"nui-toast-region\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n role=\"region\"\n aria-label=\"Notifications\"\n >\n {toasts.map((toast) => (\n <ToastItem \n key={toast.id} \n toast={toast} \n onDismiss={() => dismiss(toast.id)} \n onRemove={() => remove(toast.id)} \n />\n ))}\n </div>\n </Portal>\n )}\n </ToastContext.Provider>\n );\n}\n\n/* ============================================================\n * 2. Individual Toast Item (Smart Component)\n * ============================================================ */\n\ninterface ToastItemProps {\n toast: ToastData & { isClosing?: boolean };\n onDismiss: () => void;\n onRemove: () => void;\n}\n\nfunction ToastItem({ toast, onRemove }: ToastItemProps) {\n const [isExiting, setIsExiting] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Duration defaults to 4000ms. Set to Infinity to disable auto-close.\n const duration = toast.duration !== undefined ? toast.duration : 4000;\n\n // 1. Handle Animation and Removal\n const triggerExit = useCallback(() => {\n setIsExiting(true);\n // Wait for the CSS exit animation to finish before destroying the DOM node (matches CSS 0.2s duration)\n setTimeout(() => {\n onRemove();\n }, 200); \n }, [onRemove]);\n\n // If the provider tells us to close programmatically, trigger exit\n useEffect(() => {\n if (toast.isClosing) triggerExit();\n }, [toast.isClosing, triggerExit]);\n\n // 2. Timer Management (Pause on Hover)\n const startTimer = useCallback(() => {\n if (duration === Infinity || isExiting) return;\n timerRef.current = setTimeout(() => {\n triggerExit();\n }, duration);\n }, [duration, isExiting, triggerExit]);\n\n const clearTimer = useCallback(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n }, []);\n\n // Start timer on mount\n useEffect(() => {\n startTimer();\n return clearTimer;\n }, [startTimer, clearTimer]);\n\n // 3. Render\n // Critical WAI-ARIA logic: Errors must use role=\"alert\" to interrupt screen readers immediately.\n const role = toast.variant === 'error' ? 'alert' : 'status';\n\n return (\n <div\n className={cn(\n 'nui-toast',\n `nui-toast--${toast.variant || 'default'}`,\n )}\n data-state={isExiting ? 'closed' : 'open'}\n onMouseEnter={clearTimer}\n onMouseLeave={startTimer}\n role={role}\n >\n <div className=\"nui-toast__content\">\n <strong className=\"nui-toast__title\">{toast.message}</strong>\n {toast.description && (\n <p className=\"nui-toast__description\">{toast.description}</p>\n )}\n </div>\n\n <button\n type=\"button\"\n aria-label=\"Close notification\"\n className=\"nui-toast__close\"\n onClick={(e) => {\n e.preventDefault();\n clearTimer();\n triggerExit();\n }}\n >\n {/* Simple crisp SVG close icon */}\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n );\n}"],"names":["ToastContext","createContext","useToast","ctx","useContext","ToastProvider","children","toasts","setToasts","useState","isMounted","setIsMounted","useEffect","show","useCallback","message","options","id","prev","dismiss","t","remove","jsxs","Portal","jsx","toast","ToastItem","onRemove","isExiting","setIsExiting","timerRef","useRef","duration","triggerExit","startTimer","clearTimer","role","cn","e"],"mappings":"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"}
|