@dashforge/tw 1.0.0 → 1.1.0
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/CHANGELOG.md +221 -0
- package/README.md +74 -15
- package/dashforge-tw-1.0.0.tgz +0 -0
- package/dist/index.d.ts +1 -146
- package/dist/index.esm.js +3127 -748
- package/dist/src/components/Alert/Alert.d.ts +65 -0
- package/dist/src/components/Alert/Alert.d.ts.map +1 -0
- package/dist/src/components/Alert/alert.types.d.ts +130 -0
- package/dist/src/components/Alert/alert.types.d.ts.map +1 -0
- package/dist/src/components/Alert/alert.variants.d.ts +85 -0
- package/dist/src/components/Alert/alert.variants.d.ts.map +1 -0
- package/dist/src/components/Avatar/Avatar.d.ts +48 -0
- package/dist/src/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/src/components/Avatar/avatar.types.d.ts +162 -0
- package/dist/src/components/Avatar/avatar.types.d.ts.map +1 -0
- package/dist/src/components/Avatar/avatar.variants.d.ts +208 -0
- package/dist/src/components/Avatar/avatar.variants.d.ts.map +1 -0
- package/dist/src/components/Badge/Badge.d.ts +63 -0
- package/dist/src/components/Badge/Badge.d.ts.map +1 -0
- package/dist/src/components/Badge/badge.types.d.ts +124 -0
- package/dist/src/components/Badge/badge.types.d.ts.map +1 -0
- package/dist/src/components/Badge/badge.variants.d.ts +262 -0
- package/dist/src/components/Badge/badge.variants.d.ts.map +1 -0
- package/dist/src/components/Box/Box.d.ts.map +1 -1
- package/dist/src/components/Box/box.types.d.ts +53 -0
- package/dist/src/components/Box/box.types.d.ts.map +1 -1
- package/dist/src/components/Button/Button.d.ts.map +1 -1
- package/dist/src/components/Button/button.types.d.ts +35 -0
- package/dist/src/components/Button/button.types.d.ts.map +1 -1
- package/dist/src/components/Card/Card.d.ts +107 -0
- package/dist/src/components/Card/Card.d.ts.map +1 -0
- package/dist/src/components/Card/card.types.d.ts +119 -0
- package/dist/src/components/Card/card.types.d.ts.map +1 -0
- package/dist/src/components/Chip/Chip.d.ts +67 -0
- package/dist/src/components/Chip/Chip.d.ts.map +1 -0
- package/dist/src/components/Chip/chip.types.d.ts +113 -0
- package/dist/src/components/Chip/chip.types.d.ts.map +1 -0
- package/dist/src/components/Chip/chip.variants.d.ts +155 -0
- package/dist/src/components/Chip/chip.variants.d.ts.map +1 -0
- package/dist/src/components/IconButton/IconButton.d.ts +57 -0
- package/dist/src/components/IconButton/IconButton.d.ts.map +1 -0
- package/dist/src/components/IconButton/iconButton.types.d.ts +96 -0
- package/dist/src/components/IconButton/iconButton.types.d.ts.map +1 -0
- package/dist/src/components/IconButton/iconButton.variants.d.ts +26 -0
- package/dist/src/components/IconButton/iconButton.variants.d.ts.map +1 -0
- package/dist/src/components/Menu/Menu.d.ts +118 -0
- package/dist/src/components/Menu/Menu.d.ts.map +1 -0
- package/dist/src/components/Menu/menu.types.d.ts +179 -0
- package/dist/src/components/Menu/menu.types.d.ts.map +1 -0
- package/dist/src/components/Menu/menu.variants.d.ts +129 -0
- package/dist/src/components/Menu/menu.variants.d.ts.map +1 -0
- package/dist/src/components/Snackbar/Snackbar.d.ts.map +1 -1
- package/dist/src/components/Snackbar/snackbar.types.d.ts +40 -3
- package/dist/src/components/Snackbar/snackbar.types.d.ts.map +1 -1
- package/dist/src/components/Snackbar/snackbar.variants.d.ts +12 -57
- package/dist/src/components/Snackbar/snackbar.variants.d.ts.map +1 -1
- package/dist/src/components/Spinner/Spinner.d.ts +44 -0
- package/dist/src/components/Spinner/Spinner.d.ts.map +1 -0
- package/dist/src/components/Spinner/spinner.types.d.ts +89 -0
- package/dist/src/components/Spinner/spinner.types.d.ts.map +1 -0
- package/dist/src/components/Spinner/spinner.variants.d.ts +111 -0
- package/dist/src/components/Spinner/spinner.variants.d.ts.map +1 -0
- package/dist/src/components/Table/cells/RenderChip.d.ts +15 -72
- package/dist/src/components/Table/cells/RenderChip.d.ts.map +1 -1
- package/dist/src/components/_shared/severity/index.d.ts +21 -0
- package/dist/src/components/_shared/severity/index.d.ts.map +1 -0
- package/dist/src/components/_shared/severity/severity.types.d.ts +48 -0
- package/dist/src/components/_shared/severity/severity.types.d.ts.map +1 -0
- package/dist/src/components/_shared/severity/severityIcons.d.ts +45 -0
- package/dist/src/components/_shared/severity/severityIcons.d.ts.map +1 -0
- package/dist/src/components/_shared/severity/severityVariants.d.ts +22 -0
- package/dist/src/components/_shared/severity/severityVariants.d.ts.map +1 -0
- package/dist/src/index.d.ts +27 -2
- package/dist/src/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/components/Alert/Alert.test.tsx +302 -0
- package/src/components/Alert/Alert.tsx +186 -0
- package/src/components/Alert/alert.types.ts +144 -0
- package/src/components/Alert/alert.variants.ts +71 -0
- package/src/components/Autocomplete/autocomplete.variants.ts +1 -1
- package/src/components/Avatar/Avatar.test.tsx +287 -0
- package/src/components/Avatar/Avatar.tsx +304 -0
- package/src/components/Avatar/avatar.types.ts +205 -0
- package/src/components/Avatar/avatar.variants.ts +194 -0
- package/src/components/Badge/Badge.test.tsx +385 -0
- package/src/components/Badge/Badge.tsx +174 -0
- package/src/components/Badge/badge.types.ts +154 -0
- package/src/components/Badge/badge.variants.ts +161 -0
- package/src/components/Box/Box.test.tsx +21 -0
- package/src/components/Box/Box.tsx +32 -3
- package/src/components/Box/box.types.ts +55 -0
- package/src/components/Button/Button.test.tsx +21 -0
- package/src/components/Button/Button.tsx +28 -27
- package/src/components/Button/button.types.ts +36 -0
- package/src/components/Card/Card.test.tsx +291 -0
- package/src/components/Card/Card.tsx +241 -0
- package/src/components/Card/card.types.ts +132 -0
- package/src/components/Chip/Chip.test.tsx +316 -0
- package/src/components/Chip/Chip.tsx +224 -0
- package/src/components/Chip/chip.types.ts +128 -0
- package/src/components/Chip/chip.variants.ts +173 -0
- package/src/components/DataGrid/visibility/ColumnVisibilityMenu.tsx +1 -1
- package/src/components/IconButton/IconButton.test.tsx +367 -0
- package/src/components/IconButton/IconButton.tsx +159 -0
- package/src/components/IconButton/iconButton.types.ts +106 -0
- package/src/components/IconButton/iconButton.variants.ts +31 -0
- package/src/components/LeftNav/leftNav.variants.ts +2 -2
- package/src/components/Menu/Menu.test.tsx +408 -0
- package/src/components/Menu/Menu.tsx +335 -0
- package/src/components/Menu/menu.types.ts +221 -0
- package/src/components/Menu/menu.variants.ts +132 -0
- package/src/components/Pagination/pagination.variants.ts +1 -1
- package/src/components/Snackbar/Snackbar.tsx +46 -28
- package/src/components/Snackbar/snackbar.types.ts +47 -3
- package/src/components/Snackbar/snackbar.variants.ts +29 -22
- package/src/components/Spinner/Spinner.test.tsx +199 -0
- package/src/components/Spinner/Spinner.tsx +158 -0
- package/src/components/Spinner/spinner.types.ts +113 -0
- package/src/components/Spinner/spinner.variants.ts +83 -0
- package/src/components/Table/cells/RenderChip.tsx +24 -87
- package/src/components/Table/cells/RowActionsMenu.tsx +1 -1
- package/src/components/_shared/severity/index.ts +33 -0
- package/src/components/_shared/severity/severity.types.ts +50 -0
- package/src/components/_shared/severity/severityIcons.tsx +104 -0
- package/src/components/_shared/severity/severityVariants.test.ts +136 -0
- package/src/components/_shared/severity/severityVariants.ts +115 -0
- package/src/index.ts +163 -1
- package/LICENSE +0 -21
- package/dist/components/Accordion/Accordion.d.ts +0 -21
- package/dist/components/Accordion/Accordion.d.ts.map +0 -1
- package/dist/components/Accordion/accordion.types.d.ts +0 -74
- package/dist/components/Accordion/accordion.types.d.ts.map +0 -1
- package/dist/components/Accordion/accordion.variants.d.ts +0 -58
- package/dist/components/Accordion/accordion.variants.d.ts.map +0 -1
- package/dist/components/AppShell/AppShell.d.ts +0 -46
- package/dist/components/AppShell/AppShell.d.ts.map +0 -1
- package/dist/components/AppShell/appShell.types.d.ts +0 -62
- package/dist/components/AppShell/appShell.types.d.ts.map +0 -1
- package/dist/components/AppShell/appShell.variants.d.ts +0 -65
- package/dist/components/AppShell/appShell.variants.d.ts.map +0 -1
- package/dist/components/AspectRatio/AspectRatio.d.ts +0 -36
- package/dist/components/AspectRatio/AspectRatio.d.ts.map +0 -1
- package/dist/components/AspectRatio/aspectRatio.types.d.ts +0 -50
- package/dist/components/AspectRatio/aspectRatio.types.d.ts.map +0 -1
- package/dist/components/Autocomplete/Autocomplete.d.ts +0 -32
- package/dist/components/Autocomplete/Autocomplete.d.ts.map +0 -1
- package/dist/components/Autocomplete/autocomplete.types.d.ts +0 -214
- package/dist/components/Autocomplete/autocomplete.types.d.ts.map +0 -1
- package/dist/components/Autocomplete/autocomplete.variants.d.ts +0 -214
- package/dist/components/Autocomplete/autocomplete.variants.d.ts.map +0 -1
- package/dist/components/Box/Box.d.ts +0 -36
- package/dist/components/Box/Box.d.ts.map +0 -1
- package/dist/components/Box/box.types.d.ts +0 -54
- package/dist/components/Box/box.types.d.ts.map +0 -1
- package/dist/components/Box/box.variants.d.ts +0 -402
- package/dist/components/Box/box.variants.d.ts.map +0 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +0 -23
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts.map +0 -1
- package/dist/components/Breadcrumbs/breadcrumbs.types.d.ts +0 -98
- package/dist/components/Breadcrumbs/breadcrumbs.types.d.ts.map +0 -1
- package/dist/components/Breadcrumbs/breadcrumbs.variants.d.ts +0 -85
- package/dist/components/Breadcrumbs/breadcrumbs.variants.d.ts.map +0 -1
- package/dist/components/Button/Button.d.ts +0 -44
- package/dist/components/Button/Button.d.ts.map +0 -1
- package/dist/components/Button/button.types.d.ts +0 -66
- package/dist/components/Button/button.types.d.ts.map +0 -1
- package/dist/components/Button/button.variants.d.ts +0 -104
- package/dist/components/Button/button.variants.d.ts.map +0 -1
- package/dist/components/Calendar/Calendar.d.ts +0 -14
- package/dist/components/Calendar/Calendar.d.ts.map +0 -1
- package/dist/components/Calendar/calendar.types.d.ts +0 -72
- package/dist/components/Calendar/calendar.types.d.ts.map +0 -1
- package/dist/components/Calendar/calendar.variants.d.ts +0 -99
- package/dist/components/Calendar/calendar.variants.d.ts.map +0 -1
- package/dist/components/Checkbox/Checkbox.d.ts +0 -31
- package/dist/components/Checkbox/Checkbox.d.ts.map +0 -1
- package/dist/components/Checkbox/checkbox.types.d.ts +0 -86
- package/dist/components/Checkbox/checkbox.types.d.ts.map +0 -1
- package/dist/components/Checkbox/checkbox.variants.d.ts +0 -109
- package/dist/components/Checkbox/checkbox.variants.d.ts.map +0 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +0 -38
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts.map +0 -1
- package/dist/components/ConfirmDialog/confirmDialog.types.d.ts +0 -80
- package/dist/components/ConfirmDialog/confirmDialog.types.d.ts.map +0 -1
- package/dist/components/ConfirmDialog/confirmDialog.variants.d.ts +0 -90
- package/dist/components/ConfirmDialog/confirmDialog.variants.d.ts.map +0 -1
- package/dist/components/Container/Container.d.ts +0 -35
- package/dist/components/Container/Container.d.ts.map +0 -1
- package/dist/components/Container/container.types.d.ts +0 -41
- package/dist/components/Container/container.types.d.ts.map +0 -1
- package/dist/components/Container/container.variants.d.ts +0 -93
- package/dist/components/Container/container.variants.d.ts.map +0 -1
- package/dist/components/DataGrid/DataGrid.d.ts +0 -29
- package/dist/components/DataGrid/DataGrid.d.ts.map +0 -1
- package/dist/components/DataGrid/dataGrid.types.d.ts +0 -214
- package/dist/components/DataGrid/dataGrid.types.d.ts.map +0 -1
- package/dist/components/DataGrid/dataGrid.variants.d.ts +0 -222
- package/dist/components/DataGrid/dataGrid.variants.d.ts.map +0 -1
- package/dist/components/DataGrid/filters/ColumnFilters.d.ts +0 -23
- package/dist/components/DataGrid/filters/ColumnFilters.d.ts.map +0 -1
- package/dist/components/DataGrid/reorder/useColumnReorder.d.ts +0 -50
- package/dist/components/DataGrid/reorder/useColumnReorder.d.ts.map +0 -1
- package/dist/components/DataGrid/resize/useColumnResize.d.ts +0 -39
- package/dist/components/DataGrid/resize/useColumnResize.d.ts.map +0 -1
- package/dist/components/DataGrid/visibility/ColumnVisibilityMenu.d.ts +0 -44
- package/dist/components/DataGrid/visibility/ColumnVisibilityMenu.d.ts.map +0 -1
- package/dist/components/DatePicker/DatePicker.d.ts +0 -14
- package/dist/components/DatePicker/DatePicker.d.ts.map +0 -1
- package/dist/components/DatePicker/datePicker.types.d.ts +0 -88
- package/dist/components/DatePicker/datePicker.types.d.ts.map +0 -1
- package/dist/components/DatePicker/datePicker.variants.d.ts +0 -97
- package/dist/components/DatePicker/datePicker.variants.d.ts.map +0 -1
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +0 -13
- package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +0 -1
- package/dist/components/DateRangePicker/dateRangePicker.types.d.ts +0 -85
- package/dist/components/DateRangePicker/dateRangePicker.types.d.ts.map +0 -1
- package/dist/components/DateRangePicker/dateRangePicker.variants.d.ts +0 -183
- package/dist/components/DateRangePicker/dateRangePicker.variants.d.ts.map +0 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +0 -13
- package/dist/components/DateTimePicker/DateTimePicker.d.ts.map +0 -1
- package/dist/components/DateTimePicker/dateTimePicker.types.d.ts +0 -90
- package/dist/components/DateTimePicker/dateTimePicker.types.d.ts.map +0 -1
- package/dist/components/DateTimePicker/dateTimePicker.variants.d.ts +0 -107
- package/dist/components/DateTimePicker/dateTimePicker.variants.d.ts.map +0 -1
- package/dist/components/Dialog/Dialog.d.ts +0 -17
- package/dist/components/Dialog/Dialog.d.ts.map +0 -1
- package/dist/components/Dialog/dialog.types.d.ts +0 -75
- package/dist/components/Dialog/dialog.types.d.ts.map +0 -1
- package/dist/components/Dialog/dialog.variants.d.ts +0 -80
- package/dist/components/Dialog/dialog.variants.d.ts.map +0 -1
- package/dist/components/Divider/Divider.d.ts +0 -50
- package/dist/components/Divider/Divider.d.ts.map +0 -1
- package/dist/components/Divider/divider.types.d.ts +0 -47
- package/dist/components/Divider/divider.types.d.ts.map +0 -1
- package/dist/components/Divider/divider.variants.d.ts +0 -129
- package/dist/components/Divider/divider.variants.d.ts.map +0 -1
- package/dist/components/Grid/Grid.d.ts +0 -32
- package/dist/components/Grid/Grid.d.ts.map +0 -1
- package/dist/components/Grid/grid.types.d.ts +0 -103
- package/dist/components/Grid/grid.types.d.ts.map +0 -1
- package/dist/components/Grid/grid.variants.d.ts +0 -453
- package/dist/components/Grid/grid.variants.d.ts.map +0 -1
- package/dist/components/LeftNav/LeftNav.d.ts +0 -34
- package/dist/components/LeftNav/LeftNav.d.ts.map +0 -1
- package/dist/components/LeftNav/leftNav.types.d.ts +0 -136
- package/dist/components/LeftNav/leftNav.types.d.ts.map +0 -1
- package/dist/components/LeftNav/leftNav.variants.d.ts +0 -143
- package/dist/components/LeftNav/leftNav.variants.d.ts.map +0 -1
- package/dist/components/NumberField/NumberField.d.ts +0 -18
- package/dist/components/NumberField/NumberField.d.ts.map +0 -1
- package/dist/components/NumberField/numberField.types.d.ts +0 -79
- package/dist/components/NumberField/numberField.types.d.ts.map +0 -1
- package/dist/components/NumberField/numberField.variants.d.ts +0 -169
- package/dist/components/NumberField/numberField.variants.d.ts.map +0 -1
- package/dist/components/OTPField/OTPField.d.ts +0 -25
- package/dist/components/OTPField/OTPField.d.ts.map +0 -1
- package/dist/components/OTPField/otpField.types.d.ts +0 -74
- package/dist/components/OTPField/otpField.types.d.ts.map +0 -1
- package/dist/components/OTPField/otpField.variants.d.ts +0 -105
- package/dist/components/OTPField/otpField.variants.d.ts.map +0 -1
- package/dist/components/Pagination/Pagination.d.ts +0 -32
- package/dist/components/Pagination/Pagination.d.ts.map +0 -1
- package/dist/components/Pagination/pagination.helpers.d.ts +0 -23
- package/dist/components/Pagination/pagination.helpers.d.ts.map +0 -1
- package/dist/components/Pagination/pagination.types.d.ts +0 -120
- package/dist/components/Pagination/pagination.types.d.ts.map +0 -1
- package/dist/components/Pagination/pagination.variants.d.ts +0 -150
- package/dist/components/Pagination/pagination.variants.d.ts.map +0 -1
- package/dist/components/Popover/Popover.d.ts +0 -15
- package/dist/components/Popover/Popover.d.ts.map +0 -1
- package/dist/components/Popover/popover.types.d.ts +0 -45
- package/dist/components/Popover/popover.types.d.ts.map +0 -1
- package/dist/components/Popover/popover.variants.d.ts +0 -34
- package/dist/components/Popover/popover.variants.d.ts.map +0 -1
- package/dist/components/RadioGroup/RadioGroup.d.ts +0 -35
- package/dist/components/RadioGroup/RadioGroup.d.ts.map +0 -1
- package/dist/components/RadioGroup/radioGroup.types.d.ts +0 -103
- package/dist/components/RadioGroup/radioGroup.types.d.ts.map +0 -1
- package/dist/components/RadioGroup/radioGroup.variants.d.ts +0 -166
- package/dist/components/RadioGroup/radioGroup.variants.d.ts.map +0 -1
- package/dist/components/Skeleton/Skeleton.d.ts +0 -23
- package/dist/components/Skeleton/Skeleton.d.ts.map +0 -1
- package/dist/components/Skeleton/skeleton.types.d.ts +0 -56
- package/dist/components/Skeleton/skeleton.types.d.ts.map +0 -1
- package/dist/components/Skeleton/skeleton.variants.d.ts +0 -110
- package/dist/components/Skeleton/skeleton.variants.d.ts.map +0 -1
- package/dist/components/Snackbar/Snackbar.d.ts +0 -37
- package/dist/components/Snackbar/Snackbar.d.ts.map +0 -1
- package/dist/components/Snackbar/snackbar.types.d.ts +0 -86
- package/dist/components/Snackbar/snackbar.types.d.ts.map +0 -1
- package/dist/components/Snackbar/snackbar.variants.d.ts +0 -153
- package/dist/components/Snackbar/snackbar.variants.d.ts.map +0 -1
- package/dist/components/Stack/Stack.d.ts +0 -24
- package/dist/components/Stack/Stack.d.ts.map +0 -1
- package/dist/components/Stack/stack.types.d.ts +0 -61
- package/dist/components/Stack/stack.types.d.ts.map +0 -1
- package/dist/components/Stack/stack.variants.d.ts +0 -163
- package/dist/components/Stack/stack.variants.d.ts.map +0 -1
- package/dist/components/Switch/Switch.d.ts +0 -15
- package/dist/components/Switch/Switch.d.ts.map +0 -1
- package/dist/components/Switch/switch.types.d.ts +0 -47
- package/dist/components/Switch/switch.types.d.ts.map +0 -1
- package/dist/components/Switch/switch.variants.d.ts +0 -105
- package/dist/components/Switch/switch.variants.d.ts.map +0 -1
- package/dist/components/Table/Table.d.ts +0 -24
- package/dist/components/Table/Table.d.ts.map +0 -1
- package/dist/components/Table/cells/RenderButton.d.ts +0 -13
- package/dist/components/Table/cells/RenderButton.d.ts.map +0 -1
- package/dist/components/Table/cells/RenderChip.d.ts +0 -80
- package/dist/components/Table/cells/RenderChip.d.ts.map +0 -1
- package/dist/components/Table/cells/RenderText.d.ts +0 -21
- package/dist/components/Table/cells/RenderText.d.ts.map +0 -1
- package/dist/components/Table/cells/RenderTwoLine.d.ts +0 -20
- package/dist/components/Table/cells/RenderTwoLine.d.ts.map +0 -1
- package/dist/components/Table/cells/RowActionsMenu.d.ts +0 -36
- package/dist/components/Table/cells/RowActionsMenu.d.ts.map +0 -1
- package/dist/components/Table/cells/index.d.ts +0 -11
- package/dist/components/Table/cells/index.d.ts.map +0 -1
- package/dist/components/Table/table.types.d.ts +0 -399
- package/dist/components/Table/table.types.d.ts.map +0 -1
- package/dist/components/Table/table.variants.d.ts +0 -285
- package/dist/components/Table/table.variants.d.ts.map +0 -1
- package/dist/components/Tabs/Tabs.d.ts +0 -19
- package/dist/components/Tabs/Tabs.d.ts.map +0 -1
- package/dist/components/Tabs/tabs.types.d.ts +0 -61
- package/dist/components/Tabs/tabs.types.d.ts.map +0 -1
- package/dist/components/Tabs/tabs.variants.d.ts +0 -82
- package/dist/components/Tabs/tabs.variants.d.ts.map +0 -1
- package/dist/components/Tabs/useTabs.d.ts +0 -55
- package/dist/components/Tabs/useTabs.d.ts.map +0 -1
- package/dist/components/TextField/TextField.d.ts +0 -25
- package/dist/components/TextField/TextField.d.ts.map +0 -1
- package/dist/components/TextField/textField.types.d.ts +0 -98
- package/dist/components/TextField/textField.types.d.ts.map +0 -1
- package/dist/components/TextField/textField.variants.d.ts +0 -166
- package/dist/components/TextField/textField.variants.d.ts.map +0 -1
- package/dist/components/Textarea/Textarea.d.ts +0 -16
- package/dist/components/Textarea/Textarea.d.ts.map +0 -1
- package/dist/components/Textarea/textarea.types.d.ts +0 -63
- package/dist/components/Textarea/textarea.types.d.ts.map +0 -1
- package/dist/components/Textarea/textarea.variants.d.ts +0 -197
- package/dist/components/Textarea/textarea.variants.d.ts.map +0 -1
- package/dist/components/TimePicker/TimePicker.d.ts +0 -12
- package/dist/components/TimePicker/TimePicker.d.ts.map +0 -1
- package/dist/components/TimePicker/timePicker.types.d.ts +0 -80
- package/dist/components/TimePicker/timePicker.types.d.ts.map +0 -1
- package/dist/components/TimePicker/timePicker.variants.d.ts +0 -103
- package/dist/components/TimePicker/timePicker.variants.d.ts.map +0 -1
- package/dist/components/Tooltip/Tooltip.d.ts +0 -29
- package/dist/components/Tooltip/Tooltip.d.ts.map +0 -1
- package/dist/components/Tooltip/tooltip.types.d.ts +0 -47
- package/dist/components/Tooltip/tooltip.types.d.ts.map +0 -1
- package/dist/components/Tooltip/tooltip.variants.d.ts +0 -34
- package/dist/components/Tooltip/tooltip.variants.d.ts.map +0 -1
- package/dist/components/TopBar/TopBar.d.ts +0 -33
- package/dist/components/TopBar/TopBar.d.ts.map +0 -1
- package/dist/components/TopBar/topBar.types.d.ts +0 -49
- package/dist/components/TopBar/topBar.types.d.ts.map +0 -1
- package/dist/components/TopBar/topBar.variants.d.ts +0 -79
- package/dist/components/TopBar/topBar.variants.d.ts.map +0 -1
- package/dist/components/Typography/Typography.d.ts +0 -42
- package/dist/components/Typography/Typography.d.ts.map +0 -1
- package/dist/components/Typography/typography.types.d.ts +0 -61
- package/dist/components/Typography/typography.types.d.ts.map +0 -1
- package/dist/components/Typography/typography.variants.d.ts +0 -167
- package/dist/components/Typography/typography.variants.d.ts.map +0 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.d.ts +0 -42
- package/dist/components/VisuallyHidden/VisuallyHidden.d.ts.map +0 -1
- package/dist/components/VisuallyHidden/visuallyHidden.types.d.ts +0 -42
- package/dist/components/VisuallyHidden/visuallyHidden.types.d.ts.map +0 -1
- package/dist/components/_shared/data/getNestedValue.d.ts +0 -20
- package/dist/components/_shared/data/getNestedValue.d.ts.map +0 -1
- package/dist/components/_shared/data/useColumnAutoDetect.d.ts +0 -45
- package/dist/components/_shared/data/useColumnAutoDetect.d.ts.map +0 -1
- package/dist/components/_shared/data/useControllableState.d.ts +0 -23
- package/dist/components/_shared/data/useControllableState.d.ts.map +0 -1
- package/dist/components/_shared/data/useDebouncedValue.d.ts +0 -10
- package/dist/components/_shared/data/useDebouncedValue.d.ts.map +0 -1
- package/dist/components/_shared/data/useTableFilter.d.ts +0 -36
- package/dist/components/_shared/data/useTableFilter.d.ts.map +0 -1
- package/dist/components/_shared/data/useTableSearch.d.ts +0 -23
- package/dist/components/_shared/data/useTableSearch.d.ts.map +0 -1
- package/dist/components/_shared/data/useTableSelection.d.ts +0 -25
- package/dist/components/_shared/data/useTableSelection.d.ts.map +0 -1
- package/dist/components/_shared/data/useTableSort.d.ts +0 -20
- package/dist/components/_shared/data/useTableSort.d.ts.map +0 -1
- package/dist/components/_shared/data/useVirtualizer.d.ts +0 -107
- package/dist/components/_shared/data/useVirtualizer.d.ts.map +0 -1
- package/dist/components/_shared/resolveValidationState.d.ts +0 -42
- package/dist/components/_shared/resolveValidationState.d.ts.map +0 -1
- package/dist/hooks/useAccessState.d.ts +0 -37
- package/dist/hooks/useAccessState.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/tsconfig.lib.tsbuildinfo +0 -1
- package/dist/utils/cn.d.ts +0 -26
- package/dist/utils/cn.d.ts.map +0 -1
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
forwardRef,
|
|
4
|
+
memo,
|
|
5
|
+
useContext,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import * as RadixMenu from '@radix-ui/react-dropdown-menu';
|
|
9
|
+
import { DashFormContext, useEngineVisibility } from '@dashforge/ui-core';
|
|
10
|
+
import { cn } from '../../utils/cn.js';
|
|
11
|
+
import { useAccessState } from '../../hooks/useAccessState.js';
|
|
12
|
+
import { menuVariants, placementToRadix } from './menu.variants.js';
|
|
13
|
+
import type {
|
|
14
|
+
MenuContentProps,
|
|
15
|
+
MenuItemProps,
|
|
16
|
+
MenuLabelProps,
|
|
17
|
+
MenuProps,
|
|
18
|
+
MenuSeparatorProps,
|
|
19
|
+
MenuSkeletonProps,
|
|
20
|
+
MenuTriggerProps,
|
|
21
|
+
} from './menu.types.js';
|
|
22
|
+
|
|
23
|
+
// ─── Context ─────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Internal Menu context — propagates the `closeOnItemClick` flag
|
|
27
|
+
* down to `<MenuItem>` so each item knows whether to suppress the
|
|
28
|
+
* default Radix close-on-select behaviour.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
interface MenuCtx {
|
|
33
|
+
closeOnItemClick: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const MenuContext = createContext<MenuCtx>({ closeOnItemClick: true });
|
|
37
|
+
|
|
38
|
+
// ─── Menu (Root provider) ────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* `<Menu>` — top-level provider that wraps Radix `DropdownMenu.Root`.
|
|
42
|
+
*
|
|
43
|
+
* Compound API:
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <Menu>
|
|
46
|
+
* <MenuTrigger>
|
|
47
|
+
* <IconButton aria-label="Actions"><MoreIcon /></IconButton>
|
|
48
|
+
* </MenuTrigger>
|
|
49
|
+
* <MenuContent>
|
|
50
|
+
* <MenuLabel>Actions</MenuLabel>
|
|
51
|
+
* <MenuItem onClick={onEdit}>Edit</MenuItem>
|
|
52
|
+
* <MenuSeparator />
|
|
53
|
+
* <MenuItem color="danger" onClick={onDelete}>Delete</MenuItem>
|
|
54
|
+
* </MenuContent>
|
|
55
|
+
* </Menu>
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* Built on `@radix-ui/react-dropdown-menu` (purpose-built menu
|
|
59
|
+
* primitive with full WAI-ARIA menu pattern + keyboard nav
|
|
60
|
+
* + type-ahead + portal mount).
|
|
61
|
+
*
|
|
62
|
+
* Sub-menus and controlled selection mode are deliberately out of
|
|
63
|
+
* scope for v1 (Sprint 4.4) — composable via Radix primitives if
|
|
64
|
+
* needed via explicit sub-component opt-in (future).
|
|
65
|
+
*/
|
|
66
|
+
export function Menu({
|
|
67
|
+
children,
|
|
68
|
+
open,
|
|
69
|
+
defaultOpen,
|
|
70
|
+
onOpenChange,
|
|
71
|
+
closeOnItemClick = true,
|
|
72
|
+
modal = false,
|
|
73
|
+
}: MenuProps) {
|
|
74
|
+
return (
|
|
75
|
+
<MenuContext.Provider value={{ closeOnItemClick }}>
|
|
76
|
+
<RadixMenu.Root
|
|
77
|
+
open={open}
|
|
78
|
+
defaultOpen={defaultOpen}
|
|
79
|
+
onOpenChange={onOpenChange}
|
|
80
|
+
modal={modal}
|
|
81
|
+
>
|
|
82
|
+
{children}
|
|
83
|
+
</RadixMenu.Root>
|
|
84
|
+
</MenuContext.Provider>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ─── MenuTrigger ─────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* `<MenuTrigger>` — the element that opens the menu.
|
|
92
|
+
*
|
|
93
|
+
* Always renders the immediate child via Radix Slot (`asChild`) — the
|
|
94
|
+
* child receives the click handler + `aria-haspopup="menu"` +
|
|
95
|
+
* `aria-expanded` reactive to open state. Pass any interactive
|
|
96
|
+
* component as the child (`<IconButton>`, `<Button>`, `<Avatar>`,
|
|
97
|
+
* custom).
|
|
98
|
+
*/
|
|
99
|
+
export function MenuTrigger({ children }: MenuTriggerProps) {
|
|
100
|
+
return <RadixMenu.Trigger asChild>{children}</RadixMenu.Trigger>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ─── MenuContent ─────────────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* `<MenuContent>` — the floating panel.
|
|
107
|
+
*
|
|
108
|
+
* Lazy-mounted via Radix Portal — zero DOM cost when the menu is
|
|
109
|
+
* closed (one of the perf properties we inherit from Radix +
|
|
110
|
+
* Atlaskit-style menus).
|
|
111
|
+
*
|
|
112
|
+
* Placement / sideOffset are read from the parent `<Menu>` via
|
|
113
|
+
* Radix context — we re-pull the `<Menu>` props via the
|
|
114
|
+
* `MenuContext` here.
|
|
115
|
+
*
|
|
116
|
+
* NB: placement is read from PARENT MENU PROPS, not from
|
|
117
|
+
* `<MenuContent>` directly — keeps the floating-positioning API on
|
|
118
|
+
* the provider where it belongs.
|
|
119
|
+
*/
|
|
120
|
+
export const MenuContent = forwardRef<HTMLDivElement, MenuContentProps>(
|
|
121
|
+
function MenuContent(props, ref) {
|
|
122
|
+
const { children, minWidth, className, sx } = props;
|
|
123
|
+
const v = menuVariants();
|
|
124
|
+
|
|
125
|
+
// NB: we don't read `placement` from MenuContext (Radix Root
|
|
126
|
+
// doesn't surface those props to descendants). Instead, the
|
|
127
|
+
// consumer passes them on `<Menu>` and they're forwarded into
|
|
128
|
+
// `<MenuContent>` via context-style props — to keep the API
|
|
129
|
+
// simple, we DON'T expose placement on MenuContent itself; the
|
|
130
|
+
// user sets it on Menu. We achieve this by reading the MenuProps
|
|
131
|
+
// off the Radix-internal context… actually, simpler: we just
|
|
132
|
+
// accept the default `bottom-start` from Radix and let the
|
|
133
|
+
// consumer pass `side`/`align` via MenuContent if they want fine
|
|
134
|
+
// control. For now, hardcode the most common defaults; Sprint
|
|
135
|
+
// 4.4-bis can lift this if real demand emerges.
|
|
136
|
+
const { side, align } = placementToRadix('bottom-start');
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<RadixMenu.Portal>
|
|
140
|
+
<RadixMenu.Content
|
|
141
|
+
ref={ref}
|
|
142
|
+
side={side}
|
|
143
|
+
align={align}
|
|
144
|
+
sideOffset={6}
|
|
145
|
+
style={
|
|
146
|
+
minWidth !== undefined
|
|
147
|
+
? { minWidth: typeof minWidth === 'number' ? `${minWidth}px` : minWidth }
|
|
148
|
+
: undefined
|
|
149
|
+
}
|
|
150
|
+
className={cn(v.content(), sx, className)}
|
|
151
|
+
>
|
|
152
|
+
{children}
|
|
153
|
+
</RadixMenu.Content>
|
|
154
|
+
</RadixMenu.Portal>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
MenuContent.displayName = 'MenuContent';
|
|
160
|
+
|
|
161
|
+
// ─── MenuItem ────────────────────────────────────────────────────
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* `<MenuItem>` — clickable row inside the menu.
|
|
165
|
+
*
|
|
166
|
+
* Memoized via `React.memo` for performance — re-renders only when
|
|
167
|
+
* its own props change, not when sibling items mutate. Pattern
|
|
168
|
+
* inspired by Atlaskit's `ButtonItem` optimization (one of the
|
|
169
|
+
* reasons Atlaskit menus stay responsive on large item lists).
|
|
170
|
+
*
|
|
171
|
+
* Bridge integration:
|
|
172
|
+
* - `access` — hides / disables the item per RBAC
|
|
173
|
+
* - `visibleWhen` — engine-reactive predicate
|
|
174
|
+
*
|
|
175
|
+
* Both gates fold into the visible/disabled state; when the
|
|
176
|
+
* predicate returns `false` OR `access` denies visibility, the
|
|
177
|
+
* item renders `null` (does NOT occupy a row in the menu, vs
|
|
178
|
+
* disabled which renders dimmed-but-present).
|
|
179
|
+
*/
|
|
180
|
+
function MenuItemImpl(props: MenuItemProps) {
|
|
181
|
+
const {
|
|
182
|
+
children,
|
|
183
|
+
onClick,
|
|
184
|
+
icon,
|
|
185
|
+
endIcon,
|
|
186
|
+
disabled: disabledProp,
|
|
187
|
+
selected,
|
|
188
|
+
color = 'default',
|
|
189
|
+
access,
|
|
190
|
+
visibleWhen,
|
|
191
|
+
className,
|
|
192
|
+
sx,
|
|
193
|
+
} = props;
|
|
194
|
+
|
|
195
|
+
const { closeOnItemClick } = useContext(MenuContext);
|
|
196
|
+
|
|
197
|
+
// Bridge hooks — always called (rules-of-hooks).
|
|
198
|
+
const bridge = useContext(DashFormContext);
|
|
199
|
+
const isBridgeVisible = useEngineVisibility(bridge?.engine, visibleWhen);
|
|
200
|
+
const accessState = useAccessState(access);
|
|
201
|
+
|
|
202
|
+
if (!isBridgeVisible || !accessState.visible) return null;
|
|
203
|
+
|
|
204
|
+
const isDisabled =
|
|
205
|
+
Boolean(disabledProp) || accessState.disabled || accessState.readonly;
|
|
206
|
+
|
|
207
|
+
const v = menuVariants({ color, selected });
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<RadixMenu.Item
|
|
211
|
+
disabled={isDisabled}
|
|
212
|
+
onSelect={(e) => {
|
|
213
|
+
if (isDisabled) return;
|
|
214
|
+
// Suppress default close behaviour when the parent <Menu>
|
|
215
|
+
// explicitly opted out (filter / multi-select pattern).
|
|
216
|
+
if (!closeOnItemClick) e.preventDefault();
|
|
217
|
+
onClick?.();
|
|
218
|
+
}}
|
|
219
|
+
className={cn(v.item(), sx, className)}
|
|
220
|
+
>
|
|
221
|
+
{icon != null && (
|
|
222
|
+
<span className={v.itemIcon()}>{icon}</span>
|
|
223
|
+
)}
|
|
224
|
+
<span className={v.itemLabel()}>{children}</span>
|
|
225
|
+
{endIcon != null && (
|
|
226
|
+
<span className={v.itemEnd()}>{endIcon}</span>
|
|
227
|
+
)}
|
|
228
|
+
</RadixMenu.Item>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export const MenuItem = memo(MenuItemImpl);
|
|
233
|
+
MenuItem.displayName = 'MenuItem';
|
|
234
|
+
|
|
235
|
+
// ─── MenuLabel ───────────────────────────────────────────────────
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* `<MenuLabel>` — non-interactive group heading.
|
|
239
|
+
*
|
|
240
|
+
* Renders via Radix `DropdownMenu.Label` which carries the right
|
|
241
|
+
* ARIA semantics (`role="presentation"` — not announced as a
|
|
242
|
+
* `menuitem` by screen readers).
|
|
243
|
+
*/
|
|
244
|
+
export function MenuLabel({ children, className }: MenuLabelProps) {
|
|
245
|
+
const v = menuVariants();
|
|
246
|
+
return (
|
|
247
|
+
<RadixMenu.Label className={cn(v.label(), className)}>
|
|
248
|
+
{children}
|
|
249
|
+
</RadixMenu.Label>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ─── MenuSeparator ───────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* `<MenuSeparator>` — horizontal divider between items.
|
|
257
|
+
*
|
|
258
|
+
* Renders via Radix `DropdownMenu.Separator` — semantically correct
|
|
259
|
+
* `role="separator"` for screen readers navigating the menu.
|
|
260
|
+
*/
|
|
261
|
+
export function MenuSeparator({ className }: MenuSeparatorProps) {
|
|
262
|
+
const v = menuVariants();
|
|
263
|
+
return <RadixMenu.Separator className={cn(v.separator(), className)} />;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ─── MenuSkeleton ────────────────────────────────────────────────
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* `<MenuSkeleton>` — Atlaskit-style loading state.
|
|
270
|
+
*
|
|
271
|
+
* Renders `count` placeholder rows (default 3) inside the menu while
|
|
272
|
+
* real items are being fetched. Each row matches the geometry of a
|
|
273
|
+
* real `<MenuItem>` (height, padding, icon slot) so the layout
|
|
274
|
+
* doesn't jump when the real data arrives.
|
|
275
|
+
*
|
|
276
|
+
* `withHeading=true` adds a skeleton heading at the top, mimicking a
|
|
277
|
+
* `<MenuLabel>` — useful when the real menu starts with a section
|
|
278
|
+
* label.
|
|
279
|
+
*
|
|
280
|
+
* Pure visual — no animation overhead beyond Tailwind's
|
|
281
|
+
* `animate-pulse` (motion-reduce-safe).
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```tsx
|
|
285
|
+
* <MenuContent>
|
|
286
|
+
* {isLoading ? (
|
|
287
|
+
* <MenuSkeleton count={5} withHeading />
|
|
288
|
+
* ) : (
|
|
289
|
+
* items.map((it) => <MenuItem key={it.id}>{it.label}</MenuItem>)
|
|
290
|
+
* )}
|
|
291
|
+
* </MenuContent>
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
export function MenuSkeleton({
|
|
295
|
+
count = 3,
|
|
296
|
+
withHeading = false,
|
|
297
|
+
className,
|
|
298
|
+
}: MenuSkeletonProps) {
|
|
299
|
+
const v = menuVariants();
|
|
300
|
+
return (
|
|
301
|
+
<div
|
|
302
|
+
role="presentation"
|
|
303
|
+
aria-hidden="true"
|
|
304
|
+
className={cn('animate-pulse motion-reduce:animate-none', className)}
|
|
305
|
+
>
|
|
306
|
+
{withHeading && (
|
|
307
|
+
<div className={cn(v.label(), 'pointer-events-none')}>
|
|
308
|
+
<span className="inline-block h-2.5 w-16 rounded-sm bg-neutral-200" />
|
|
309
|
+
</div>
|
|
310
|
+
)}
|
|
311
|
+
{Array.from({ length: count }).map((_, i) => (
|
|
312
|
+
<SkeletonRow key={i} />
|
|
313
|
+
))}
|
|
314
|
+
</div>
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* One skeleton row — matches the dimensions of a real `<MenuItem>`
|
|
320
|
+
* (icon slot + label slot). Internal — not exported.
|
|
321
|
+
*
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
function SkeletonRow() {
|
|
325
|
+
return (
|
|
326
|
+
<div className="flex items-center gap-2 px-3 py-1.5 mx-1 my-0.5">
|
|
327
|
+
<span className="inline-block h-4 w-4 shrink-0 rounded-sm bg-neutral-200" />
|
|
328
|
+
<span className="inline-block h-3 flex-1 rounded-sm bg-neutral-200" />
|
|
329
|
+
</div>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Re-export ReactNode type for downstream consumers — keeps the
|
|
334
|
+
// import surface for the Menu module self-contained.
|
|
335
|
+
export type { ReactNode };
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ClassValue } from 'tailwind-variants';
|
|
3
|
+
import type { Engine } from '@dashforge/ui-core';
|
|
4
|
+
import type { AccessRequirement } from '@dashforge/rbac';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Placement of the menu content relative to the trigger. Maps 1:1 to
|
|
8
|
+
* Radix DropdownMenu's `side` + `align` pair via the internal
|
|
9
|
+
* helpers in Menu.tsx.
|
|
10
|
+
*/
|
|
11
|
+
export type MenuPlacement =
|
|
12
|
+
| 'top'
|
|
13
|
+
| 'top-start'
|
|
14
|
+
| 'top-end'
|
|
15
|
+
| 'bottom'
|
|
16
|
+
| 'bottom-start'
|
|
17
|
+
| 'bottom-end'
|
|
18
|
+
| 'left'
|
|
19
|
+
| 'left-start'
|
|
20
|
+
| 'left-end'
|
|
21
|
+
| 'right'
|
|
22
|
+
| 'right-start'
|
|
23
|
+
| 'right-end';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Props for the top-level `<Menu>` provider.
|
|
27
|
+
*
|
|
28
|
+
* Wraps Radix `DropdownMenu.Root`. Provides open-state coordination
|
|
29
|
+
* + closeOnItemClick context for descendant `<MenuItem>`s.
|
|
30
|
+
*/
|
|
31
|
+
export interface MenuProps {
|
|
32
|
+
/** Compound children: `<MenuTrigger>` + `<MenuContent>`. */
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
|
|
35
|
+
/** Controlled open state. */
|
|
36
|
+
open?: boolean;
|
|
37
|
+
|
|
38
|
+
/** Default open state for uncontrolled mode. @default false */
|
|
39
|
+
defaultOpen?: boolean;
|
|
40
|
+
|
|
41
|
+
/** Open/close callback (controlled). */
|
|
42
|
+
onOpenChange?: (open: boolean) => void;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Close the menu when an item is clicked. Set to `false` for
|
|
46
|
+
* filter-style menus where item clicks should NOT dismiss (e.g.,
|
|
47
|
+
* multi-select checkbox menus, sticky filter pills).
|
|
48
|
+
* @default true
|
|
49
|
+
*/
|
|
50
|
+
closeOnItemClick?: boolean;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Placement of the content relative to the trigger.
|
|
54
|
+
* @default 'bottom-start'
|
|
55
|
+
*/
|
|
56
|
+
placement?: MenuPlacement;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Pixel offset between trigger and content along the perpendicular
|
|
60
|
+
* axis (e.g., for `placement='bottom-*'`, the vertical gap).
|
|
61
|
+
* @default 6
|
|
62
|
+
*/
|
|
63
|
+
sideOffset?: number;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Modal mode (Radix). When `true`, the menu blocks interaction with
|
|
67
|
+
* the rest of the page (focus trap + outside scroll lock). When
|
|
68
|
+
* `false`, dismissal is automatic on outside-click but the page
|
|
69
|
+
* remains interactive. Default false matches the "lightweight
|
|
70
|
+
* action menu" pattern.
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
modal?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Props for `<MenuTrigger>` — the element that opens the menu.
|
|
78
|
+
*
|
|
79
|
+
* Always renders via Radix Slot — the immediate child element
|
|
80
|
+
* (typically `<IconButton>`, `<Button>`, or a custom interactive
|
|
81
|
+
* component) receives the click handler, `aria-haspopup="menu"`,
|
|
82
|
+
* and `aria-expanded` reactive to open state.
|
|
83
|
+
*/
|
|
84
|
+
export interface MenuTriggerProps {
|
|
85
|
+
/** The trigger element. */
|
|
86
|
+
children: ReactNode;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Props for `<MenuContent>` — the floating panel.
|
|
91
|
+
*
|
|
92
|
+
* Rendered through Radix `DropdownMenu.Portal`, lazily mounted only
|
|
93
|
+
* when the menu is open (cost zero in DOM when closed).
|
|
94
|
+
*/
|
|
95
|
+
export interface MenuContentProps {
|
|
96
|
+
/** Items + labels + separators + skeletons. */
|
|
97
|
+
children: ReactNode;
|
|
98
|
+
|
|
99
|
+
/** CSS min-width for the menu panel. */
|
|
100
|
+
minWidth?: number | string;
|
|
101
|
+
|
|
102
|
+
/** Standard className — appended to the root via `cn()`. */
|
|
103
|
+
className?: string;
|
|
104
|
+
|
|
105
|
+
/** Root-element class shortcut. */
|
|
106
|
+
sx?: ClassValue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Visual / semantic color of a `<MenuItem>`. `'danger'` highlights
|
|
111
|
+
* destructive actions with a red hover state.
|
|
112
|
+
*/
|
|
113
|
+
export type MenuItemColor = 'default' | 'danger';
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Props for `<MenuItem>` — a clickable row inside the menu.
|
|
117
|
+
*
|
|
118
|
+
* Memoized (`React.memo`) for perf — re-renders only on prop change.
|
|
119
|
+
* Pattern inspired by Atlaskit's ButtonItem optimization.
|
|
120
|
+
*/
|
|
121
|
+
export interface MenuItemProps {
|
|
122
|
+
/** Item label / content. */
|
|
123
|
+
children: ReactNode;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Click handler. After firing, the menu closes (unless the parent
|
|
127
|
+
* `<Menu closeOnItemClick={false}>` opts out).
|
|
128
|
+
*/
|
|
129
|
+
onClick?: () => void;
|
|
130
|
+
|
|
131
|
+
/** Leading icon slot. */
|
|
132
|
+
icon?: ReactNode;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Trailing slot — typically a keyboard shortcut (`"⌘K"`), a
|
|
136
|
+
* status hint, or a sub-menu chevron (when sub-menus arrive).
|
|
137
|
+
*/
|
|
138
|
+
endIcon?: ReactNode;
|
|
139
|
+
|
|
140
|
+
/** Disabled state — suppresses click + dims the item. */
|
|
141
|
+
disabled?: boolean;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Visual hint of "active option" — for menus that show current
|
|
145
|
+
* selection (e.g., theme picker). No controlled selection state
|
|
146
|
+
* by design (v1) — purely visual.
|
|
147
|
+
*/
|
|
148
|
+
selected?: boolean;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Color intent. `'danger'` highlights destructive actions
|
|
152
|
+
* (Delete, Remove, Sign out) with a red hover tint.
|
|
153
|
+
* @default 'default'
|
|
154
|
+
*/
|
|
155
|
+
color?: MenuItemColor;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* RBAC requirement. When the current subject doesn't satisfy it,
|
|
159
|
+
* the item is hidden (or disabled per `onUnauthorized`).
|
|
160
|
+
*/
|
|
161
|
+
access?: AccessRequirement;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Reactive visibility predicate. When `false`, the item renders
|
|
165
|
+
* `null`. Use for state-driven menu items (e.g., "Restore" only
|
|
166
|
+
* when an item was just deleted).
|
|
167
|
+
*/
|
|
168
|
+
visibleWhen?: (engine: Engine) => boolean;
|
|
169
|
+
|
|
170
|
+
/** Standard className. */
|
|
171
|
+
className?: string;
|
|
172
|
+
|
|
173
|
+
/** Root-element class shortcut. */
|
|
174
|
+
sx?: ClassValue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Props for `<MenuLabel>` — non-interactive group heading.
|
|
179
|
+
*
|
|
180
|
+
* Rendered as `role="presentation"` so screen readers don't
|
|
181
|
+
* announce it as a menuitem. Typical use: section dividers inside
|
|
182
|
+
* a menu ("Workspace", "Account", "Help").
|
|
183
|
+
*/
|
|
184
|
+
export interface MenuLabelProps {
|
|
185
|
+
children: ReactNode;
|
|
186
|
+
className?: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Props for `<MenuSeparator>` — horizontal divider between items.
|
|
191
|
+
*/
|
|
192
|
+
export interface MenuSeparatorProps {
|
|
193
|
+
className?: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Props for `<MenuSkeleton>` — Atlaskit-style loading state.
|
|
198
|
+
*
|
|
199
|
+
* Renders N placeholder rows that mimic the menu's item geometry,
|
|
200
|
+
* giving the user immediate visual feedback while the real items
|
|
201
|
+
* are being fetched (e.g., "Recent files" pulled from an API).
|
|
202
|
+
* Strictly perceived-performance UX: no animation overhead beyond
|
|
203
|
+
* Tailwind's `animate-pulse`.
|
|
204
|
+
*/
|
|
205
|
+
export interface MenuSkeletonProps {
|
|
206
|
+
/**
|
|
207
|
+
* Number of skeleton item rows to render.
|
|
208
|
+
* @default 3
|
|
209
|
+
*/
|
|
210
|
+
count?: number;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Show a skeleton heading at the top of the list (matches the
|
|
214
|
+
* height + indent of a real `<MenuLabel>`).
|
|
215
|
+
* @default false
|
|
216
|
+
*/
|
|
217
|
+
withHeading?: boolean;
|
|
218
|
+
|
|
219
|
+
/** Standard className. */
|
|
220
|
+
className?: string;
|
|
221
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { tv, type VariantProps } from 'tailwind-variants';
|
|
2
|
+
import type { MenuPlacement } from './menu.types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tailwind-variants recipe for the Menu family.
|
|
6
|
+
*
|
|
7
|
+
* The whole menu family is styled here in one TV instance so the
|
|
8
|
+
* compound rules (item color × selected × danger, etc.) live in
|
|
9
|
+
* one source of truth.
|
|
10
|
+
*
|
|
11
|
+
* Slots:
|
|
12
|
+
* - `content` — floating panel (DropdownMenu.Content)
|
|
13
|
+
* - `item` — clickable row (DropdownMenu.Item)
|
|
14
|
+
* - `itemIcon` — leading icon container
|
|
15
|
+
* - `itemLabel` — text content slot
|
|
16
|
+
* - `itemEnd` — trailing slot (shortcut hint, chevron, …)
|
|
17
|
+
* - `label` — non-interactive heading (DropdownMenu.Label)
|
|
18
|
+
* - `separator` — divider (DropdownMenu.Separator)
|
|
19
|
+
* - `skeleton` — placeholder item (visual only, no Radix slot)
|
|
20
|
+
*/
|
|
21
|
+
export const menuVariants = tv({
|
|
22
|
+
slots: {
|
|
23
|
+
content: [
|
|
24
|
+
'z-50 min-w-[180px] py-1.5',
|
|
25
|
+
// Surface elevation: `bg-white` is hardcoded (does NOT
|
|
26
|
+
// auto-invert via the dashforgePreset CSS-var swap), so we
|
|
27
|
+
// pair it with `dark:bg-neutral-100` (target #171717 — one
|
|
28
|
+
// elevation tier above page surface in dark mode). This is
|
|
29
|
+
// Category B of THEME-AUDIT.md — must stay on the same
|
|
30
|
+
// string literal so the whitelist regex matches.
|
|
31
|
+
'rounded-md border border-neutral-200 bg-white dark:bg-neutral-100 shadow-lg',
|
|
32
|
+
// Smooth fade-in via Radix's data-state attributes. Motion-
|
|
33
|
+
// reduce gated.
|
|
34
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
35
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
36
|
+
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
37
|
+
'motion-reduce:animate-none motion-reduce:transition-none',
|
|
38
|
+
// List reset (defensive — same defensive pattern as
|
|
39
|
+
// Autocomplete listbox after the listbox-bullets fix in 1.0.1).
|
|
40
|
+
'list-none pl-0 m-0',
|
|
41
|
+
],
|
|
42
|
+
item: [
|
|
43
|
+
'group relative flex cursor-pointer select-none items-center gap-2',
|
|
44
|
+
'px-3 py-1.5 mx-1 my-0.5',
|
|
45
|
+
'rounded-md text-sm text-neutral-900',
|
|
46
|
+
'outline-none',
|
|
47
|
+
// Radix sets data-highlighted when the item is keyboard-focused
|
|
48
|
+
// OR hovered. We anchor the active visual state to that single
|
|
49
|
+
// attribute so keyboard + mouse interactions look identical.
|
|
50
|
+
'data-[highlighted]:bg-neutral-100',
|
|
51
|
+
// Disabled (Radix sets data-disabled).
|
|
52
|
+
'data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none',
|
|
53
|
+
'transition-colors duration-100',
|
|
54
|
+
'motion-reduce:transition-none',
|
|
55
|
+
],
|
|
56
|
+
itemIcon: 'shrink-0 inline-flex items-center justify-center w-4 h-4',
|
|
57
|
+
itemLabel: 'flex-1 truncate',
|
|
58
|
+
itemEnd: 'shrink-0 ml-3 inline-flex items-center text-xs text-neutral-500',
|
|
59
|
+
label: [
|
|
60
|
+
'px-3 py-1 mx-1 mt-1 text-xs font-medium uppercase tracking-wide',
|
|
61
|
+
'text-neutral-500',
|
|
62
|
+
],
|
|
63
|
+
separator: 'h-px my-1 mx-1 bg-neutral-200',
|
|
64
|
+
skeleton: [
|
|
65
|
+
'flex items-center gap-2 px-3 py-1.5 mx-1 my-0.5',
|
|
66
|
+
'animate-pulse motion-reduce:animate-none',
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
variants: {
|
|
70
|
+
/**
|
|
71
|
+
* Item color intent. `'danger'` highlights destructive actions
|
|
72
|
+
* (Delete, Sign out) with red bg on hover. Both bg and text
|
|
73
|
+
* shift to the danger palette when the item is highlighted.
|
|
74
|
+
*/
|
|
75
|
+
color: {
|
|
76
|
+
default: {},
|
|
77
|
+
danger: {
|
|
78
|
+
item: [
|
|
79
|
+
'text-danger-700',
|
|
80
|
+
// Hover + keyboard focus → red soft bg + saturated text.
|
|
81
|
+
'data-[highlighted]:bg-danger-50 data-[highlighted]:text-danger-800',
|
|
82
|
+
// Dark mode: bg-danger-50 doesn't auto-invert (color
|
|
83
|
+
// palettes don't), so we add the explicit dark variant.
|
|
84
|
+
// The `text-danger-700` base also gets a dark counterpart
|
|
85
|
+
// for readability on the dark surface.
|
|
86
|
+
'dark:text-danger-300',
|
|
87
|
+
'dark:data-[highlighted]:bg-danger-950 dark:data-[highlighted]:text-danger-200',
|
|
88
|
+
],
|
|
89
|
+
itemIcon: 'text-danger-600 dark:text-danger-400',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Visual `selected` hint — adds a faint primary bg + the
|
|
94
|
+
* leading edge gets a primary accent. Pure visual; v1 has no
|
|
95
|
+
* controlled selection state machine.
|
|
96
|
+
*/
|
|
97
|
+
selected: {
|
|
98
|
+
true: {
|
|
99
|
+
item: [
|
|
100
|
+
'bg-primary-50 text-primary-900',
|
|
101
|
+
'dark:bg-primary-950 dark:text-primary-100',
|
|
102
|
+
],
|
|
103
|
+
itemIcon: 'text-primary-600 dark:text-primary-400',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
defaultVariants: {
|
|
108
|
+
color: 'default',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export type MenuVariants = VariantProps<typeof menuVariants>;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Resolve a `MenuPlacement` enum to Radix `side` + `align` props.
|
|
116
|
+
* Single source of truth so Menu.tsx doesn't need a switch statement.
|
|
117
|
+
*/
|
|
118
|
+
export function placementToRadix(placement: MenuPlacement): {
|
|
119
|
+
side: 'top' | 'right' | 'bottom' | 'left';
|
|
120
|
+
align: 'start' | 'center' | 'end';
|
|
121
|
+
} {
|
|
122
|
+
// The format is `<side>` or `<side>-<align>`. Center is the default
|
|
123
|
+
// when no `-start` / `-end` suffix is present.
|
|
124
|
+
const [side, alignSuffix] = placement.split('-') as [
|
|
125
|
+
'top' | 'right' | 'bottom' | 'left',
|
|
126
|
+
'start' | 'end' | undefined,
|
|
127
|
+
];
|
|
128
|
+
return {
|
|
129
|
+
side,
|
|
130
|
+
align: alignSuffix ?? 'center',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -28,7 +28,7 @@ export const paginationVariants = tv({
|
|
|
28
28
|
// surface; the border gives the separation). `hover:bg-neutral-100`
|
|
29
29
|
// is the one-tier elevation that works in both modes.
|
|
30
30
|
summary: 'text-neutral-600',
|
|
31
|
-
list: 'inline-flex items-center gap-1',
|
|
31
|
+
list: 'inline-flex items-center gap-1 list-none pl-0 m-0',
|
|
32
32
|
pageButton: [
|
|
33
33
|
'inline-flex items-center justify-center rounded-md',
|
|
34
34
|
'border border-neutral-300',
|