@dashforge/tw 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -1
- package/dist/index.esm.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/package.json +8 -3
- package/.swcrc +0 -29
- package/A11Y.md +0 -130
- package/CONSUMER-VALIDATION.md +0 -130
- package/COVERAGE.md +0 -63
- package/PARITY.md +0 -481
- package/PERFORMANCE.md +0 -227
- package/REFINEMENT-NOTES.md +0 -50
- package/THEME-AUDIT.md +0 -174
- package/dashforge-tw-1.0.0.tgz +0 -0
- package/eslint.config.mjs +0 -62
- package/project.json +0 -15
- package/rollup.config.cjs +0 -16
- package/src/components/Accordion/Accordion.test.tsx +0 -95
- package/src/components/Accordion/Accordion.tsx +0 -97
- package/src/components/Accordion/accordion.types.ts +0 -66
- package/src/components/Accordion/accordion.variants.ts +0 -32
- package/src/components/Alert/Alert.test.tsx +0 -302
- package/src/components/Alert/Alert.tsx +0 -186
- package/src/components/Alert/alert.types.ts +0 -144
- package/src/components/Alert/alert.variants.ts +0 -71
- package/src/components/AppShell/AppShell.test.tsx +0 -223
- package/src/components/AppShell/AppShell.tsx +0 -239
- package/src/components/AppShell/appShell.types.ts +0 -49
- package/src/components/AppShell/appShell.variants.ts +0 -54
- package/src/components/AspectRatio/AspectRatio.test.tsx +0 -173
- package/src/components/AspectRatio/AspectRatio.tsx +0 -73
- package/src/components/AspectRatio/aspectRatio.types.ts +0 -54
- package/src/components/Autocomplete/Autocomplete.perf.test.tsx +0 -225
- package/src/components/Autocomplete/Autocomplete.test.tsx +0 -556
- package/src/components/Autocomplete/Autocomplete.tsx +0 -1069
- package/src/components/Autocomplete/autocomplete.types.ts +0 -198
- package/src/components/Autocomplete/autocomplete.variants.ts +0 -141
- package/src/components/Avatar/Avatar.test.tsx +0 -287
- package/src/components/Avatar/Avatar.tsx +0 -304
- package/src/components/Avatar/avatar.types.ts +0 -205
- package/src/components/Avatar/avatar.variants.ts +0 -194
- package/src/components/Badge/Badge.test.tsx +0 -385
- package/src/components/Badge/Badge.tsx +0 -174
- package/src/components/Badge/badge.types.ts +0 -154
- package/src/components/Badge/badge.variants.ts +0 -161
- package/src/components/Box/Box.test.tsx +0 -391
- package/src/components/Box/Box.tsx +0 -112
- package/src/components/Box/box.types.ts +0 -116
- package/src/components/Box/box.variants.ts +0 -230
- package/src/components/Breadcrumbs/Breadcrumbs.perf.test.tsx +0 -128
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +0 -231
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +0 -203
- package/src/components/Breadcrumbs/breadcrumbs.types.ts +0 -87
- package/src/components/Breadcrumbs/breadcrumbs.variants.ts +0 -54
- package/src/components/Button/Button.test.tsx +0 -204
- package/src/components/Button/Button.tsx +0 -151
- package/src/components/Button/button.types.ts +0 -110
- package/src/components/Button/button.variants.ts +0 -159
- package/src/components/Calendar/Calendar.test.tsx +0 -75
- package/src/components/Calendar/Calendar.tsx +0 -264
- package/src/components/Calendar/calendar.types.ts +0 -65
- package/src/components/Calendar/calendar.variants.ts +0 -64
- package/src/components/Card/Card.test.tsx +0 -291
- package/src/components/Card/Card.tsx +0 -241
- package/src/components/Card/card.types.ts +0 -132
- package/src/components/Checkbox/Checkbox.test.tsx +0 -146
- package/src/components/Checkbox/Checkbox.tsx +0 -286
- package/src/components/Checkbox/checkbox.types.ts +0 -88
- package/src/components/Checkbox/checkbox.variants.ts +0 -68
- package/src/components/Chip/Chip.test.tsx +0 -316
- package/src/components/Chip/Chip.tsx +0 -224
- package/src/components/Chip/chip.types.ts +0 -128
- package/src/components/Chip/chip.variants.ts +0 -173
- package/src/components/ConfirmDialog/ConfirmDialog.perf.test.tsx +0 -172
- package/src/components/ConfirmDialog/ConfirmDialog.test.tsx +0 -311
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -252
- package/src/components/ConfirmDialog/confirmDialog.types.ts +0 -70
- package/src/components/ConfirmDialog/confirmDialog.variants.ts +0 -76
- package/src/components/Container/Container.test.tsx +0 -209
- package/src/components/Container/Container.tsx +0 -74
- package/src/components/Container/container.types.ts +0 -45
- package/src/components/Container/container.variants.ts +0 -81
- package/src/components/DataGrid/DataGrid.perf.test.tsx +0 -114
- package/src/components/DataGrid/DataGrid.test.tsx +0 -1153
- package/src/components/DataGrid/DataGrid.tsx +0 -1282
- package/src/components/DataGrid/dataGrid.types.ts +0 -238
- package/src/components/DataGrid/dataGrid.variants.ts +0 -152
- package/src/components/DataGrid/filters/ColumnFilters.test.tsx +0 -330
- package/src/components/DataGrid/filters/ColumnFilters.tsx +0 -456
- package/src/components/DataGrid/reorder/useColumnReorder.test.ts +0 -130
- package/src/components/DataGrid/reorder/useColumnReorder.ts +0 -144
- package/src/components/DataGrid/resize/useColumnResize.test.ts +0 -144
- package/src/components/DataGrid/resize/useColumnResize.ts +0 -135
- package/src/components/DataGrid/visibility/ColumnVisibilityMenu.tsx +0 -186
- package/src/components/DatePicker/DatePicker.test.tsx +0 -76
- package/src/components/DatePicker/DatePicker.tsx +0 -305
- package/src/components/DatePicker/datePicker.types.ts +0 -77
- package/src/components/DatePicker/datePicker.variants.ts +0 -50
- package/src/components/DateRangePicker/DateRangePicker.test.tsx +0 -92
- package/src/components/DateRangePicker/DateRangePicker.tsx +0 -510
- package/src/components/DateRangePicker/dateRangePicker.types.ts +0 -74
- package/src/components/DateRangePicker/dateRangePicker.variants.ts +0 -101
- package/src/components/DateTimePicker/DateTimePicker.test.tsx +0 -78
- package/src/components/DateTimePicker/DateTimePicker.tsx +0 -347
- package/src/components/DateTimePicker/dateTimePicker.types.ts +0 -79
- package/src/components/DateTimePicker/dateTimePicker.variants.ts +0 -55
- package/src/components/Dialog/Dialog.test.tsx +0 -96
- package/src/components/Dialog/Dialog.tsx +0 -102
- package/src/components/Dialog/dialog.types.ts +0 -62
- package/src/components/Dialog/dialog.variants.ts +0 -66
- package/src/components/Divider/Divider.test.tsx +0 -243
- package/src/components/Divider/Divider.tsx +0 -140
- package/src/components/Divider/divider.types.ts +0 -52
- package/src/components/Divider/divider.variants.ts +0 -116
- package/src/components/Grid/Grid.test.tsx +0 -321
- package/src/components/Grid/Grid.tsx +0 -148
- package/src/components/Grid/grid.types.ts +0 -112
- package/src/components/Grid/grid.variants.ts +0 -133
- package/src/components/IconButton/IconButton.test.tsx +0 -367
- package/src/components/IconButton/IconButton.tsx +0 -159
- package/src/components/IconButton/iconButton.types.ts +0 -106
- package/src/components/IconButton/iconButton.variants.ts +0 -31
- package/src/components/LeftNav/LeftNav.perf.test.tsx +0 -172
- package/src/components/LeftNav/LeftNav.test.tsx +0 -302
- package/src/components/LeftNav/LeftNav.tsx +0 -330
- package/src/components/LeftNav/leftNav.types.ts +0 -120
- package/src/components/LeftNav/leftNav.variants.ts +0 -107
- package/src/components/Menu/Menu.test.tsx +0 -408
- package/src/components/Menu/Menu.tsx +0 -335
- package/src/components/Menu/menu.types.ts +0 -221
- package/src/components/Menu/menu.variants.ts +0 -132
- package/src/components/NumberField/NumberField.test.tsx +0 -83
- package/src/components/NumberField/NumberField.tsx +0 -321
- package/src/components/NumberField/numberField.types.ts +0 -72
- package/src/components/NumberField/numberField.variants.ts +0 -94
- package/src/components/OTPField/OTPField.test.tsx +0 -121
- package/src/components/OTPField/OTPField.tsx +0 -250
- package/src/components/OTPField/otpField.types.ts +0 -58
- package/src/components/OTPField/otpField.variants.ts +0 -72
- package/src/components/Pagination/Pagination.test.tsx +0 -314
- package/src/components/Pagination/Pagination.tsx +0 -277
- package/src/components/Pagination/pagination.helpers.ts +0 -102
- package/src/components/Pagination/pagination.types.ts +0 -117
- package/src/components/Pagination/pagination.variants.ts +0 -117
- package/src/components/Popover/Popover.test.tsx +0 -72
- package/src/components/Popover/Popover.tsx +0 -55
- package/src/components/Popover/popover.types.ts +0 -42
- package/src/components/Popover/popover.variants.ts +0 -24
- package/src/components/RadioGroup/RadioGroup.test.tsx +0 -140
- package/src/components/RadioGroup/RadioGroup.tsx +0 -283
- package/src/components/RadioGroup/radioGroup.types.ts +0 -85
- package/src/components/RadioGroup/radioGroup.variants.ts +0 -87
- package/src/components/Skeleton/Skeleton.test.tsx +0 -127
- package/src/components/Skeleton/Skeleton.tsx +0 -49
- package/src/components/Skeleton/skeleton.types.ts +0 -59
- package/src/components/Skeleton/skeleton.variants.ts +0 -87
- package/src/components/Snackbar/Snackbar.perf.test.tsx +0 -144
- package/src/components/Snackbar/Snackbar.test.tsx +0 -327
- package/src/components/Snackbar/Snackbar.tsx +0 -316
- package/src/components/Snackbar/snackbar.types.ts +0 -127
- package/src/components/Snackbar/snackbar.variants.ts +0 -81
- package/src/components/Spinner/Spinner.test.tsx +0 -199
- package/src/components/Spinner/Spinner.tsx +0 -158
- package/src/components/Spinner/spinner.types.ts +0 -113
- package/src/components/Spinner/spinner.variants.ts +0 -83
- package/src/components/Stack/Stack.test.tsx +0 -309
- package/src/components/Stack/Stack.tsx +0 -115
- package/src/components/Stack/stack.types.ts +0 -68
- package/src/components/Stack/stack.variants.ts +0 -80
- package/src/components/Switch/Switch.test.tsx +0 -131
- package/src/components/Switch/Switch.tsx +0 -158
- package/src/components/Switch/switch.types.ts +0 -36
- package/src/components/Switch/switch.variants.ts +0 -70
- package/src/components/Table/Table.perf.test.tsx +0 -81
- package/src/components/Table/Table.test.tsx +0 -674
- package/src/components/Table/Table.tsx +0 -863
- package/src/components/Table/cells/RenderButton.tsx +0 -23
- package/src/components/Table/cells/RenderChip.tsx +0 -37
- package/src/components/Table/cells/RenderText.tsx +0 -37
- package/src/components/Table/cells/RenderTwoLine.tsx +0 -34
- package/src/components/Table/cells/RowActionsMenu.tsx +0 -147
- package/src/components/Table/cells/cells.test.tsx +0 -247
- package/src/components/Table/cells/index.ts +0 -14
- package/src/components/Table/table.types.ts +0 -438
- package/src/components/Table/table.variants.ts +0 -207
- package/src/components/Tabs/Tabs.test.tsx +0 -145
- package/src/components/Tabs/Tabs.tsx +0 -77
- package/src/components/Tabs/tabs.types.ts +0 -55
- package/src/components/Tabs/tabs.variants.ts +0 -69
- package/src/components/Tabs/useTabs.ts +0 -167
- package/src/components/TextField/TextField.test.tsx +0 -198
- package/src/components/TextField/TextField.tsx +0 -245
- package/src/components/TextField/textField.types.ts +0 -90
- package/src/components/TextField/textField.variants.ts +0 -105
- package/src/components/Textarea/Textarea.test.tsx +0 -75
- package/src/components/Textarea/Textarea.tsx +0 -190
- package/src/components/Textarea/textarea.types.ts +0 -60
- package/src/components/Textarea/textarea.variants.ts +0 -85
- package/src/components/TimePicker/TimePicker.test.tsx +0 -65
- package/src/components/TimePicker/TimePicker.tsx +0 -274
- package/src/components/TimePicker/timePicker.types.ts +0 -69
- package/src/components/TimePicker/timePicker.variants.ts +0 -53
- package/src/components/Tooltip/Tooltip.test.tsx +0 -73
- package/src/components/Tooltip/Tooltip.tsx +0 -70
- package/src/components/Tooltip/tooltip.types.ts +0 -44
- package/src/components/Tooltip/tooltip.variants.ts +0 -28
- package/src/components/TopBar/TopBar.test.tsx +0 -129
- package/src/components/TopBar/TopBar.tsx +0 -66
- package/src/components/TopBar/topBar.types.ts +0 -42
- package/src/components/TopBar/topBar.variants.ts +0 -38
- package/src/components/Typography/Typography.test.tsx +0 -247
- package/src/components/Typography/Typography.tsx +0 -112
- package/src/components/Typography/typography.types.ts +0 -65
- package/src/components/Typography/typography.variants.ts +0 -130
- package/src/components/VisuallyHidden/VisuallyHidden.test.tsx +0 -86
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +0 -59
- package/src/components/VisuallyHidden/visuallyHidden.types.ts +0 -45
- package/src/components/_shared/data/getNestedValue.test.ts +0 -50
- package/src/components/_shared/data/getNestedValue.ts +0 -32
- package/src/components/_shared/data/useColumnAutoDetect.test.ts +0 -123
- package/src/components/_shared/data/useColumnAutoDetect.ts +0 -100
- package/src/components/_shared/data/useControllableState.ts +0 -48
- package/src/components/_shared/data/useDebouncedValue.ts +0 -24
- package/src/components/_shared/data/useTableFilter.test.ts +0 -166
- package/src/components/_shared/data/useTableFilter.ts +0 -118
- package/src/components/_shared/data/useTableSearch.test.ts +0 -115
- package/src/components/_shared/data/useTableSearch.ts +0 -66
- package/src/components/_shared/data/useTableSelection.test.ts +0 -100
- package/src/components/_shared/data/useTableSelection.ts +0 -100
- package/src/components/_shared/data/useTableSort.test.ts +0 -150
- package/src/components/_shared/data/useTableSort.ts +0 -141
- package/src/components/_shared/data/useVirtualizer.test.ts +0 -158
- package/src/components/_shared/data/useVirtualizer.ts +0 -199
- package/src/components/_shared/resolveValidationState.ts +0 -60
- package/src/components/_shared/severity/index.ts +0 -33
- package/src/components/_shared/severity/severity.types.ts +0 -50
- package/src/components/_shared/severity/severityIcons.tsx +0 -104
- package/src/components/_shared/severity/severityVariants.test.ts +0 -136
- package/src/components/_shared/severity/severityVariants.ts +0 -115
- package/src/components/_shared/themeIdentity.test.ts +0 -113
- package/src/hooks/useAccessState.spec.tsx +0 -161
- package/src/hooks/useAccessState.ts +0 -81
- package/src/index.ts +0 -550
- package/src/utils/cn.spec.ts +0 -16
- package/src/utils/cn.ts +0 -29
- package/test-output/vitest/coverage/base.css +0 -224
- package/test-output/vitest/coverage/block-navigation.js +0 -87
- package/test-output/vitest/coverage/clover.xml +0 -2418
- package/test-output/vitest/coverage/coverage-final.json +0 -89
- package/test-output/vitest/coverage/favicon.png +0 -0
- package/test-output/vitest/coverage/index.html +0 -746
- package/test-output/vitest/coverage/prettify.css +0 -1
- package/test-output/vitest/coverage/prettify.js +0 -2
- package/test-output/vitest/coverage/sort-arrow-sprite.png +0 -0
- package/test-output/vitest/coverage/sorter.js +0 -210
- package/test-output/vitest/coverage/src/components/Accordion/Accordion.tsx.html +0 -376
- package/test-output/vitest/coverage/src/components/Accordion/accordion.variants.ts.html +0 -181
- package/test-output/vitest/coverage/src/components/Accordion/index.html +0 -131
- package/test-output/vitest/coverage/src/components/AppShell/AppShell.tsx.html +0 -802
- package/test-output/vitest/coverage/src/components/AppShell/appShell.variants.ts.html +0 -247
- package/test-output/vitest/coverage/src/components/AppShell/index.html +0 -131
- package/test-output/vitest/coverage/src/components/AspectRatio/AspectRatio.tsx.html +0 -304
- package/test-output/vitest/coverage/src/components/AspectRatio/index.html +0 -116
- package/test-output/vitest/coverage/src/components/Autocomplete/Autocomplete.tsx.html +0 -3292
- package/test-output/vitest/coverage/src/components/Autocomplete/autocomplete.variants.ts.html +0 -508
- package/test-output/vitest/coverage/src/components/Autocomplete/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Box/Box.tsx.html +0 -334
- package/test-output/vitest/coverage/src/components/Box/box.variants.ts.html +0 -775
- package/test-output/vitest/coverage/src/components/Box/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Breadcrumbs/Breadcrumbs.tsx.html +0 -694
- package/test-output/vitest/coverage/src/components/Breadcrumbs/breadcrumbs.variants.ts.html +0 -247
- package/test-output/vitest/coverage/src/components/Breadcrumbs/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Button/Button.tsx.html +0 -535
- package/test-output/vitest/coverage/src/components/Button/button.variants.ts.html +0 -562
- package/test-output/vitest/coverage/src/components/Button/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Checkbox/Checkbox.tsx.html +0 -943
- package/test-output/vitest/coverage/src/components/Checkbox/checkbox.variants.ts.html +0 -289
- package/test-output/vitest/coverage/src/components/Checkbox/index.html +0 -131
- package/test-output/vitest/coverage/src/components/ConfirmDialog/ConfirmDialog.tsx.html +0 -841
- package/test-output/vitest/coverage/src/components/ConfirmDialog/confirmDialog.variants.ts.html +0 -313
- package/test-output/vitest/coverage/src/components/ConfirmDialog/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Container/Container.tsx.html +0 -307
- package/test-output/vitest/coverage/src/components/Container/container.variants.ts.html +0 -328
- package/test-output/vitest/coverage/src/components/Container/index.html +0 -131
- package/test-output/vitest/coverage/src/components/DataGrid/DataGrid.tsx.html +0 -3937
- package/test-output/vitest/coverage/src/components/DataGrid/dataGrid.variants.ts.html +0 -541
- package/test-output/vitest/coverage/src/components/DataGrid/filters/ColumnFilters.tsx.html +0 -1453
- package/test-output/vitest/coverage/src/components/DataGrid/filters/index.html +0 -116
- package/test-output/vitest/coverage/src/components/DataGrid/index.html +0 -131
- package/test-output/vitest/coverage/src/components/DataGrid/reorder/index.html +0 -116
- package/test-output/vitest/coverage/src/components/DataGrid/reorder/useColumnReorder.ts.html +0 -517
- package/test-output/vitest/coverage/src/components/DataGrid/resize/index.html +0 -116
- package/test-output/vitest/coverage/src/components/DataGrid/resize/useColumnResize.ts.html +0 -490
- package/test-output/vitest/coverage/src/components/DataGrid/visibility/ColumnVisibilityMenu.tsx.html +0 -592
- package/test-output/vitest/coverage/src/components/DataGrid/visibility/index.html +0 -116
- package/test-output/vitest/coverage/src/components/DateTimePicker/DateTimePicker.tsx.html +0 -1042
- package/test-output/vitest/coverage/src/components/DateTimePicker/dateTimePicker.variants.ts.html +0 -337
- package/test-output/vitest/coverage/src/components/DateTimePicker/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Dialog/Dialog.tsx.html +0 -391
- package/test-output/vitest/coverage/src/components/Dialog/dialog.variants.ts.html +0 -283
- package/test-output/vitest/coverage/src/components/Dialog/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Divider/Divider.tsx.html +0 -505
- package/test-output/vitest/coverage/src/components/Divider/divider.variants.ts.html +0 -433
- package/test-output/vitest/coverage/src/components/Divider/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Grid/Grid.tsx.html +0 -529
- package/test-output/vitest/coverage/src/components/Grid/grid.variants.ts.html +0 -484
- package/test-output/vitest/coverage/src/components/Grid/index.html +0 -131
- package/test-output/vitest/coverage/src/components/LeftNav/LeftNav.tsx.html +0 -1075
- package/test-output/vitest/coverage/src/components/LeftNav/index.html +0 -131
- package/test-output/vitest/coverage/src/components/LeftNav/leftNav.variants.ts.html +0 -406
- package/test-output/vitest/coverage/src/components/NumberField/NumberField.tsx.html +0 -1048
- package/test-output/vitest/coverage/src/components/NumberField/index.html +0 -131
- package/test-output/vitest/coverage/src/components/NumberField/numberField.variants.ts.html +0 -367
- package/test-output/vitest/coverage/src/components/OTPField/OTPField.tsx.html +0 -835
- package/test-output/vitest/coverage/src/components/OTPField/index.html +0 -131
- package/test-output/vitest/coverage/src/components/OTPField/otpField.variants.ts.html +0 -301
- package/test-output/vitest/coverage/src/components/Pagination/Pagination.tsx.html +0 -916
- package/test-output/vitest/coverage/src/components/Pagination/index.html +0 -146
- package/test-output/vitest/coverage/src/components/Pagination/pagination.helpers.ts.html +0 -391
- package/test-output/vitest/coverage/src/components/Pagination/pagination.variants.ts.html +0 -436
- package/test-output/vitest/coverage/src/components/Popover/Popover.tsx.html +0 -250
- package/test-output/vitest/coverage/src/components/Popover/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Popover/popover.variants.ts.html +0 -157
- package/test-output/vitest/coverage/src/components/RadioGroup/RadioGroup.tsx.html +0 -934
- package/test-output/vitest/coverage/src/components/RadioGroup/index.html +0 -131
- package/test-output/vitest/coverage/src/components/RadioGroup/radioGroup.variants.ts.html +0 -346
- package/test-output/vitest/coverage/src/components/Skeleton/Skeleton.tsx.html +0 -232
- package/test-output/vitest/coverage/src/components/Skeleton/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Skeleton/skeleton.variants.ts.html +0 -346
- package/test-output/vitest/coverage/src/components/Snackbar/Snackbar.tsx.html +0 -979
- package/test-output/vitest/coverage/src/components/Snackbar/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Snackbar/snackbar.variants.ts.html +0 -307
- package/test-output/vitest/coverage/src/components/Stack/Stack.tsx.html +0 -430
- package/test-output/vitest/coverage/src/components/Stack/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Stack/stack.variants.ts.html +0 -325
- package/test-output/vitest/coverage/src/components/Switch/Switch.tsx.html +0 -559
- package/test-output/vitest/coverage/src/components/Switch/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Switch/switch.variants.ts.html +0 -295
- package/test-output/vitest/coverage/src/components/Table/Table.tsx.html +0 -2677
- package/test-output/vitest/coverage/src/components/Table/cells/RenderButton.tsx.html +0 -154
- package/test-output/vitest/coverage/src/components/Table/cells/RenderChip.tsx.html +0 -385
- package/test-output/vitest/coverage/src/components/Table/cells/RenderText.tsx.html +0 -196
- package/test-output/vitest/coverage/src/components/Table/cells/RenderTwoLine.tsx.html +0 -187
- package/test-output/vitest/coverage/src/components/Table/cells/RowActionsMenu.tsx.html +0 -526
- package/test-output/vitest/coverage/src/components/Table/cells/index.html +0 -191
- package/test-output/vitest/coverage/src/components/Table/cells/index.ts.html +0 -127
- package/test-output/vitest/coverage/src/components/Table/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Table/table.variants.ts.html +0 -706
- package/test-output/vitest/coverage/src/components/Tabs/Tabs.tsx.html +0 -283
- package/test-output/vitest/coverage/src/components/Tabs/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Tabs/tabs.variants.ts.html +0 -292
- package/test-output/vitest/coverage/src/components/TextField/TextField.tsx.html +0 -820
- package/test-output/vitest/coverage/src/components/TextField/index.html +0 -131
- package/test-output/vitest/coverage/src/components/TextField/textField.variants.ts.html +0 -400
- package/test-output/vitest/coverage/src/components/Textarea/Textarea.tsx.html +0 -655
- package/test-output/vitest/coverage/src/components/Textarea/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Textarea/textarea.variants.ts.html +0 -340
- package/test-output/vitest/coverage/src/components/Tooltip/Tooltip.tsx.html +0 -295
- package/test-output/vitest/coverage/src/components/Tooltip/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Tooltip/tooltip.variants.ts.html +0 -169
- package/test-output/vitest/coverage/src/components/TopBar/TopBar.tsx.html +0 -283
- package/test-output/vitest/coverage/src/components/TopBar/index.html +0 -131
- package/test-output/vitest/coverage/src/components/TopBar/topBar.variants.ts.html +0 -199
- package/test-output/vitest/coverage/src/components/Typography/Typography.tsx.html +0 -421
- package/test-output/vitest/coverage/src/components/Typography/index.html +0 -131
- package/test-output/vitest/coverage/src/components/Typography/typography.variants.ts.html +0 -436
- package/test-output/vitest/coverage/src/components/VisuallyHidden/VisuallyHidden.tsx.html +0 -262
- package/test-output/vitest/coverage/src/components/VisuallyHidden/index.html +0 -116
- package/test-output/vitest/coverage/src/components/_shared/data/getNestedValue.ts.html +0 -181
- package/test-output/vitest/coverage/src/components/_shared/data/index.html +0 -236
- package/test-output/vitest/coverage/src/components/_shared/data/useColumnAutoDetect.ts.html +0 -385
- package/test-output/vitest/coverage/src/components/_shared/data/useControllableState.ts.html +0 -229
- package/test-output/vitest/coverage/src/components/_shared/data/useDebouncedValue.ts.html +0 -157
- package/test-output/vitest/coverage/src/components/_shared/data/useTableFilter.ts.html +0 -439
- package/test-output/vitest/coverage/src/components/_shared/data/useTableSearch.ts.html +0 -283
- package/test-output/vitest/coverage/src/components/_shared/data/useTableSelection.ts.html +0 -385
- package/test-output/vitest/coverage/src/components/_shared/data/useTableSort.ts.html +0 -508
- package/test-output/vitest/coverage/src/components/_shared/data/useVirtualizer.ts.html +0 -682
- package/test-output/vitest/coverage/src/components/_shared/index.html +0 -116
- package/test-output/vitest/coverage/src/components/_shared/resolveValidationState.ts.html +0 -265
- package/test-output/vitest/coverage/src/hooks/index.html +0 -116
- package/test-output/vitest/coverage/src/hooks/useAccessState.ts.html +0 -328
- package/test-output/vitest/coverage/src/index.html +0 -116
- package/test-output/vitest/coverage/src/index.ts.html +0 -1153
- package/test-output/vitest/coverage/src/utils/cn.ts.html +0 -172
- package/test-output/vitest/coverage/src/utils/index.html +0 -116
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -58
- package/tsconfig.spec.json +0 -34
- package/vite.config.ts +0 -33
- package/vitest.config.mts +0 -29
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import * as RadixAccordion from '@radix-ui/react-accordion';
|
|
2
|
-
import { cn } from '../../utils/cn.js';
|
|
3
|
-
import { accordionVariants } from './accordion.variants.js';
|
|
4
|
-
import type {
|
|
5
|
-
AccordionProps,
|
|
6
|
-
AccordionItem,
|
|
7
|
-
AccordionSlotProps,
|
|
8
|
-
} from './accordion.types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Dashforge TW `<Accordion>` — collapsible section list.
|
|
12
|
-
*
|
|
13
|
-
* Built on `@radix-ui/react-accordion`:
|
|
14
|
-
* - APG accordion pattern: `role="region"` on content, header
|
|
15
|
-
* button with `aria-expanded` and `aria-controls` linked to
|
|
16
|
-
* the panel.
|
|
17
|
-
* - Keyboard support: Space / Enter toggle, ArrowDown / ArrowUp
|
|
18
|
-
* move focus between triggers, Home / End to extremes.
|
|
19
|
-
* - Two modes:
|
|
20
|
-
* - `type="single"` — at most one section open at a time;
|
|
21
|
-
* `collapsible` allows clicking the open section to close it
|
|
22
|
-
* (default true).
|
|
23
|
-
* - `type="multiple"` — multiple sections open simultaneously.
|
|
24
|
-
*
|
|
25
|
-
* The trigger renders a chevron that flips 180° via CSS
|
|
26
|
-
* (`data-state=open` selector) — no React state, no JS animation.
|
|
27
|
-
*/
|
|
28
|
-
export function Accordion(props: AccordionProps) {
|
|
29
|
-
const v = accordionVariants();
|
|
30
|
-
const { items, sx, slotProps } = props;
|
|
31
|
-
|
|
32
|
-
const renderItems = (items: AccordionItem[], slotProps?: AccordionSlotProps) =>
|
|
33
|
-
items.map((item) => (
|
|
34
|
-
<RadixAccordion.Item
|
|
35
|
-
key={item.value}
|
|
36
|
-
value={item.value}
|
|
37
|
-
disabled={item.disabled}
|
|
38
|
-
className={cn(v.item(), slotProps?.item?.className)}
|
|
39
|
-
>
|
|
40
|
-
<RadixAccordion.Header
|
|
41
|
-
className={cn(v.header(), slotProps?.header?.className)}
|
|
42
|
-
>
|
|
43
|
-
<RadixAccordion.Trigger
|
|
44
|
-
className={cn(v.trigger(), slotProps?.trigger?.className)}
|
|
45
|
-
>
|
|
46
|
-
{item.header}
|
|
47
|
-
<svg
|
|
48
|
-
className={cn(v.chevron(), slotProps?.chevron?.className)}
|
|
49
|
-
width="1em"
|
|
50
|
-
height="1em"
|
|
51
|
-
viewBox="0 0 16 16"
|
|
52
|
-
fill="none"
|
|
53
|
-
stroke="currentColor"
|
|
54
|
-
strokeWidth="1.5"
|
|
55
|
-
strokeLinecap="round"
|
|
56
|
-
strokeLinejoin="round"
|
|
57
|
-
aria-hidden="true"
|
|
58
|
-
>
|
|
59
|
-
<path d="M4 6l4 4 4-4" />
|
|
60
|
-
</svg>
|
|
61
|
-
</RadixAccordion.Trigger>
|
|
62
|
-
</RadixAccordion.Header>
|
|
63
|
-
<RadixAccordion.Content
|
|
64
|
-
className={cn(v.content(), slotProps?.content?.className)}
|
|
65
|
-
>
|
|
66
|
-
<div className="pb-3 pt-0">{item.content}</div>
|
|
67
|
-
</RadixAccordion.Content>
|
|
68
|
-
</RadixAccordion.Item>
|
|
69
|
-
));
|
|
70
|
-
|
|
71
|
-
if (props.type === 'multiple') {
|
|
72
|
-
return (
|
|
73
|
-
<RadixAccordion.Root
|
|
74
|
-
type="multiple"
|
|
75
|
-
value={props.value}
|
|
76
|
-
defaultValue={props.defaultValue}
|
|
77
|
-
onValueChange={props.onValueChange}
|
|
78
|
-
className={cn(v.root(), sx, slotProps?.root?.className)}
|
|
79
|
-
>
|
|
80
|
-
{renderItems(items, slotProps)}
|
|
81
|
-
</RadixAccordion.Root>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<RadixAccordion.Root
|
|
87
|
-
type="single"
|
|
88
|
-
collapsible={props.collapsible ?? true}
|
|
89
|
-
value={props.value}
|
|
90
|
-
defaultValue={props.defaultValue}
|
|
91
|
-
onValueChange={props.onValueChange}
|
|
92
|
-
className={cn(v.root(), sx, slotProps?.root?.className)}
|
|
93
|
-
>
|
|
94
|
-
{renderItems(items, slotProps)}
|
|
95
|
-
</RadixAccordion.Root>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
export interface AccordionSlotProps {
|
|
4
|
-
root?: { className?: string };
|
|
5
|
-
item?: { className?: string };
|
|
6
|
-
header?: { className?: string };
|
|
7
|
-
trigger?: { className?: string };
|
|
8
|
-
content?: { className?: string };
|
|
9
|
-
chevron?: { className?: string };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Single accordion section — paired `{ value, header, content }`.
|
|
14
|
-
* The `value` is the canonical id (used in `value` / `defaultValue`
|
|
15
|
-
* to control which sections are expanded).
|
|
16
|
-
*/
|
|
17
|
-
export interface AccordionItem {
|
|
18
|
-
value: string;
|
|
19
|
-
/** Trigger label (clickable to expand / collapse). */
|
|
20
|
-
header: ReactNode;
|
|
21
|
-
/** Section body, revealed when this item is expanded. */
|
|
22
|
-
content: ReactNode;
|
|
23
|
-
/** Per-item disabled flag. */
|
|
24
|
-
disabled?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface AccordionBaseProps {
|
|
28
|
-
items: AccordionItem[];
|
|
29
|
-
/** Root className shortcut. */
|
|
30
|
-
sx?: string;
|
|
31
|
-
/** Per-slot overrides. */
|
|
32
|
-
slotProps?: AccordionSlotProps;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Single-mode props — at most one section open at a time.
|
|
37
|
-
* `collapsible: true` (default) lets the user close the open
|
|
38
|
-
* section by clicking it again.
|
|
39
|
-
*/
|
|
40
|
-
export interface AccordionSingleProps extends AccordionBaseProps {
|
|
41
|
-
type?: 'single';
|
|
42
|
-
value?: string;
|
|
43
|
-
defaultValue?: string;
|
|
44
|
-
onValueChange?: (value: string) => void;
|
|
45
|
-
/** @default true */
|
|
46
|
-
collapsible?: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Multiple-mode props — any number of sections open simultaneously.
|
|
51
|
-
*/
|
|
52
|
-
export interface AccordionMultipleProps extends AccordionBaseProps {
|
|
53
|
-
type: 'multiple';
|
|
54
|
-
value?: string[];
|
|
55
|
-
defaultValue?: string[];
|
|
56
|
-
onValueChange?: (value: string[]) => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Props for `<Accordion>`.
|
|
61
|
-
*
|
|
62
|
-
* Built on `@radix-ui/react-accordion`. Discriminated by `type`:
|
|
63
|
-
* - `type="single"` (default) — `value` is `string`.
|
|
64
|
-
* - `type="multiple"` — `value` is `string[]`.
|
|
65
|
-
*/
|
|
66
|
-
export type AccordionProps = AccordionSingleProps | AccordionMultipleProps;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { tv, type VariantProps } from 'tailwind-variants';
|
|
2
|
-
|
|
3
|
-
export const accordionVariants = tv({
|
|
4
|
-
slots: {
|
|
5
|
-
root: 'w-full',
|
|
6
|
-
// Neutral palette auto-inverts via the dashforgePreset() CSS-var
|
|
7
|
-
// swap — no `dark:` variant needed (would double-invert).
|
|
8
|
-
item: 'border-b border-neutral-200',
|
|
9
|
-
header: 'flex',
|
|
10
|
-
trigger: [
|
|
11
|
-
'flex flex-1 items-center justify-between py-3 text-left',
|
|
12
|
-
'text-sm font-medium text-neutral-900',
|
|
13
|
-
'transition-all hover:underline',
|
|
14
|
-
'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:rounded',
|
|
15
|
-
'[&[data-state=open]>svg]:rotate-180',
|
|
16
|
-
'disabled:opacity-50 disabled:pointer-events-none',
|
|
17
|
-
'motion-reduce:transition-none',
|
|
18
|
-
],
|
|
19
|
-
content: [
|
|
20
|
-
'overflow-hidden text-sm text-neutral-700',
|
|
21
|
-
'data-[state=open]:animate-accordion-down',
|
|
22
|
-
'data-[state=closed]:animate-accordion-up',
|
|
23
|
-
'motion-reduce:animate-none',
|
|
24
|
-
],
|
|
25
|
-
chevron: [
|
|
26
|
-
'h-4 w-4 shrink-0 text-neutral-500 transition-transform duration-200',
|
|
27
|
-
'motion-reduce:transition-none motion-reduce:duration-0',
|
|
28
|
-
],
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export type AccordionVariants = VariantProps<typeof accordionVariants>;
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
4
|
-
import { render, screen, fireEvent, cleanup } from '@testing-library/react';
|
|
5
|
-
import { Alert, AlertTitle } from './Alert.js';
|
|
6
|
-
|
|
7
|
-
void React;
|
|
8
|
-
afterEach(() => cleanup());
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* `<Alert>` unit tests. Covers:
|
|
12
|
-
* - severity × variant matrix (12 combinations) — token classes
|
|
13
|
-
* actually emitted, role auto-derived, no `dark:` leaks
|
|
14
|
-
* - icon control (default per severity, custom override, false → none)
|
|
15
|
-
* - close button (onClose triggers, custom closeText label)
|
|
16
|
-
* - action slot (replaces close button when both set)
|
|
17
|
-
* - AlertTitle sub-component rendering
|
|
18
|
-
* - sx / className / slotProps overrides
|
|
19
|
-
* - bridge integration: visibleWhen + access return null when false
|
|
20
|
-
*
|
|
21
|
-
* NB: visibleWhen + access deep integration is covered by the
|
|
22
|
-
* underlying `useEngineVisibility` and `useAccessState` test suites;
|
|
23
|
-
* here we just verify Alert wires them correctly (return null when
|
|
24
|
-
* gated).
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
describe('<Alert>', () => {
|
|
28
|
-
describe('severity × variant matrix', () => {
|
|
29
|
-
const SEVERITIES = ['info', 'success', 'warning', 'danger'] as const;
|
|
30
|
-
const VARIANTS = ['standard', 'filled', 'outlined'] as const;
|
|
31
|
-
|
|
32
|
-
SEVERITIES.forEach((severity) => {
|
|
33
|
-
VARIANTS.forEach((variant) => {
|
|
34
|
-
it(`renders ${variant}/${severity} with token-driven utilities`, () => {
|
|
35
|
-
const { container } = render(
|
|
36
|
-
<Alert severity={severity} variant={variant}>
|
|
37
|
-
Body content
|
|
38
|
-
</Alert>
|
|
39
|
-
);
|
|
40
|
-
const root = container.firstChild as HTMLElement;
|
|
41
|
-
expect(root).toBeTruthy();
|
|
42
|
-
// Surface and border carry the severity name
|
|
43
|
-
const className = root.className;
|
|
44
|
-
expect(className).toContain(severity);
|
|
45
|
-
// No dark: variants — preset handles inversion via CSS vars
|
|
46
|
-
expect(className).not.toMatch(/\bdark:/);
|
|
47
|
-
// No hardcoded hex
|
|
48
|
-
expect(className).not.toMatch(/#[0-9a-fA-F]{3,8}/);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('defaults to standard variant when omitted', () => {
|
|
54
|
-
const { container } = render(<Alert severity="info">x</Alert>);
|
|
55
|
-
const root = container.firstChild as HTMLElement;
|
|
56
|
-
// Standard variant emits bg-info-50 + text-info-900
|
|
57
|
-
expect(root.className).toContain('bg-info-50');
|
|
58
|
-
expect(root.className).toContain('text-info-900');
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('ARIA role auto-derivation', () => {
|
|
63
|
-
it('uses role="alert" for warning', () => {
|
|
64
|
-
render(<Alert severity="warning">x</Alert>);
|
|
65
|
-
expect(screen.getByRole('alert')).toBeTruthy();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('uses role="alert" for danger', () => {
|
|
69
|
-
render(<Alert severity="danger">x</Alert>);
|
|
70
|
-
expect(screen.getByRole('alert')).toBeTruthy();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('uses role="status" for info', () => {
|
|
74
|
-
render(<Alert severity="info">x</Alert>);
|
|
75
|
-
expect(screen.getByRole('status')).toBeTruthy();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('uses role="status" for success', () => {
|
|
79
|
-
render(<Alert severity="success">x</Alert>);
|
|
80
|
-
expect(screen.getByRole('status')).toBeTruthy();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('allows explicit role override', () => {
|
|
84
|
-
render(
|
|
85
|
-
<Alert severity="danger" role="status">
|
|
86
|
-
downgraded to polite
|
|
87
|
-
</Alert>
|
|
88
|
-
);
|
|
89
|
-
// No "alert" role, only the overridden "status"
|
|
90
|
-
expect(screen.queryByRole('alert')).toBeFalsy();
|
|
91
|
-
expect(screen.getByRole('status')).toBeTruthy();
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('icon prop — tristate behaviour', () => {
|
|
96
|
-
it('renders a default icon SVG when icon is omitted', () => {
|
|
97
|
-
const { container } = render(<Alert severity="warning">x</Alert>);
|
|
98
|
-
const svg = container.querySelector('svg');
|
|
99
|
-
expect(svg).toBeTruthy();
|
|
100
|
-
expect(svg?.getAttribute('aria-hidden')).toBe('true');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('renders the consumer-provided icon when icon is a ReactNode', () => {
|
|
104
|
-
render(
|
|
105
|
-
<Alert severity="info" icon={<span data-testid="custom-icon">ᐅ</span>}>
|
|
106
|
-
x
|
|
107
|
-
</Alert>
|
|
108
|
-
);
|
|
109
|
-
expect(screen.getByTestId('custom-icon')).toBeTruthy();
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('renders no icon container when icon is false', () => {
|
|
113
|
-
const { container } = render(
|
|
114
|
-
<Alert severity="info" icon={false}>
|
|
115
|
-
x
|
|
116
|
-
</Alert>
|
|
117
|
-
);
|
|
118
|
-
// No SVG anywhere (the close button SVG only renders with onClose)
|
|
119
|
-
expect(container.querySelector('svg')).toBeNull();
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
describe('close button (onClose)', () => {
|
|
124
|
-
it('renders no close button when onClose is undefined', () => {
|
|
125
|
-
render(<Alert severity="info">x</Alert>);
|
|
126
|
-
expect(screen.queryByRole('button', { name: /close/i })).toBeNull();
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('renders a close button labelled "Close" by default when onClose is defined', () => {
|
|
130
|
-
const onClose = vi.fn();
|
|
131
|
-
render(
|
|
132
|
-
<Alert severity="warning" onClose={onClose}>
|
|
133
|
-
x
|
|
134
|
-
</Alert>
|
|
135
|
-
);
|
|
136
|
-
const btn = screen.getByRole('button', { name: /^close$/i });
|
|
137
|
-
expect(btn).toBeTruthy();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('fires onClose on click', () => {
|
|
141
|
-
const onClose = vi.fn();
|
|
142
|
-
render(
|
|
143
|
-
<Alert severity="warning" onClose={onClose}>
|
|
144
|
-
x
|
|
145
|
-
</Alert>
|
|
146
|
-
);
|
|
147
|
-
fireEvent.click(screen.getByRole('button', { name: /close/i }));
|
|
148
|
-
expect(onClose).toHaveBeenCalledTimes(1);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('respects custom closeText for the aria-label', () => {
|
|
152
|
-
const onClose = vi.fn();
|
|
153
|
-
render(
|
|
154
|
-
<Alert severity="warning" onClose={onClose} closeText="Dismiss alert">
|
|
155
|
-
x
|
|
156
|
-
</Alert>
|
|
157
|
-
);
|
|
158
|
-
expect(screen.getByRole('button', { name: /dismiss alert/i })).toBeTruthy();
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
describe('action slot', () => {
|
|
163
|
-
it('renders the action node when provided', () => {
|
|
164
|
-
render(
|
|
165
|
-
<Alert
|
|
166
|
-
severity="warning"
|
|
167
|
-
action={<button data-testid="renew-cta">Renew</button>}
|
|
168
|
-
>
|
|
169
|
-
Trial expires
|
|
170
|
-
</Alert>
|
|
171
|
-
);
|
|
172
|
-
expect(screen.getByTestId('renew-cta')).toBeTruthy();
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('action wins over onClose when both are provided (matches MUI)', () => {
|
|
176
|
-
const onClose = vi.fn();
|
|
177
|
-
render(
|
|
178
|
-
<Alert
|
|
179
|
-
severity="warning"
|
|
180
|
-
onClose={onClose}
|
|
181
|
-
action={<button data-testid="custom-action">Custom</button>}
|
|
182
|
-
>
|
|
183
|
-
x
|
|
184
|
-
</Alert>
|
|
185
|
-
);
|
|
186
|
-
// Custom action renders
|
|
187
|
-
expect(screen.getByTestId('custom-action')).toBeTruthy();
|
|
188
|
-
// No auto close button rendered alongside
|
|
189
|
-
expect(screen.queryByRole('button', { name: /^close$/i })).toBeNull();
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
describe('<AlertTitle>', () => {
|
|
194
|
-
it('renders title text', () => {
|
|
195
|
-
render(
|
|
196
|
-
<Alert severity="info">
|
|
197
|
-
<AlertTitle>Heads up</AlertTitle>
|
|
198
|
-
Body line below.
|
|
199
|
-
</Alert>
|
|
200
|
-
);
|
|
201
|
-
expect(screen.getByText('Heads up')).toBeTruthy();
|
|
202
|
-
expect(screen.getByText(/Body line below/i)).toBeTruthy();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('AlertTitle accepts className override', () => {
|
|
206
|
-
const { container } = render(
|
|
207
|
-
<AlertTitle className="custom-title-class">Title</AlertTitle>
|
|
208
|
-
);
|
|
209
|
-
const node = container.firstChild as HTMLElement;
|
|
210
|
-
expect(node.className).toContain('custom-title-class');
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
describe('overrides — sx / className / slotProps', () => {
|
|
215
|
-
it('applies sx to the root', () => {
|
|
216
|
-
const { container } = render(
|
|
217
|
-
<Alert severity="info" sx="mt-8">
|
|
218
|
-
x
|
|
219
|
-
</Alert>
|
|
220
|
-
);
|
|
221
|
-
const root = container.firstChild as HTMLElement;
|
|
222
|
-
expect(root.className).toContain('mt-8');
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('appends className to the root', () => {
|
|
226
|
-
const { container } = render(
|
|
227
|
-
<Alert severity="info" className="my-custom-class">
|
|
228
|
-
x
|
|
229
|
-
</Alert>
|
|
230
|
-
);
|
|
231
|
-
const root = container.firstChild as HTMLElement;
|
|
232
|
-
expect(root.className).toContain('my-custom-class');
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it('applies slotProps.root.className to the root', () => {
|
|
236
|
-
const { container } = render(
|
|
237
|
-
<Alert
|
|
238
|
-
severity="info"
|
|
239
|
-
slotProps={{ root: { className: 'slot-root-class' } }}
|
|
240
|
-
>
|
|
241
|
-
x
|
|
242
|
-
</Alert>
|
|
243
|
-
);
|
|
244
|
-
const root = container.firstChild as HTMLElement;
|
|
245
|
-
expect(root.className).toContain('slot-root-class');
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('applies slotProps.icon.className to the icon wrapper', () => {
|
|
249
|
-
const { container } = render(
|
|
250
|
-
<Alert
|
|
251
|
-
severity="warning"
|
|
252
|
-
slotProps={{ icon: { className: 'icon-custom' } }}
|
|
253
|
-
>
|
|
254
|
-
x
|
|
255
|
-
</Alert>
|
|
256
|
-
);
|
|
257
|
-
const iconSpan = container.querySelector('.icon-custom');
|
|
258
|
-
expect(iconSpan).toBeTruthy();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('applies slotProps.closeButton.className to the close button', () => {
|
|
262
|
-
const onClose = vi.fn();
|
|
263
|
-
render(
|
|
264
|
-
<Alert
|
|
265
|
-
severity="warning"
|
|
266
|
-
onClose={onClose}
|
|
267
|
-
slotProps={{ closeButton: { className: 'close-custom' } }}
|
|
268
|
-
>
|
|
269
|
-
x
|
|
270
|
-
</Alert>
|
|
271
|
-
);
|
|
272
|
-
const btn = screen.getByRole('button', { name: /close/i });
|
|
273
|
-
expect(btn.className).toContain('close-custom');
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
describe('bridge integration — visibleWhen', () => {
|
|
278
|
-
it('renders when visibleWhen returns true (no DashForm context)', () => {
|
|
279
|
-
const { container } = render(
|
|
280
|
-
<Alert severity="info" visibleWhen={() => true}>
|
|
281
|
-
shown
|
|
282
|
-
</Alert>
|
|
283
|
-
);
|
|
284
|
-
expect(container.firstChild).toBeTruthy();
|
|
285
|
-
expect(screen.getByText('shown')).toBeTruthy();
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it('returns null when visibleWhen returns false', () => {
|
|
289
|
-
const { container } = render(
|
|
290
|
-
<Alert severity="info" visibleWhen={() => false}>
|
|
291
|
-
hidden
|
|
292
|
-
</Alert>
|
|
293
|
-
);
|
|
294
|
-
expect(container.firstChild).toBeNull();
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it('renders normally when visibleWhen is omitted', () => {
|
|
298
|
-
const { container } = render(<Alert severity="info">always</Alert>);
|
|
299
|
-
expect(container.firstChild).toBeTruthy();
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
});
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { DashFormContext, useEngineVisibility } from '@dashforge/ui-core';
|
|
3
|
-
import { cn } from '../../utils/cn.js';
|
|
4
|
-
import { useAccessState } from '../../hooks/useAccessState.js';
|
|
5
|
-
import {
|
|
6
|
-
getSeverityClasses,
|
|
7
|
-
getSeverityRole,
|
|
8
|
-
} from '../_shared/severity/severityVariants.js';
|
|
9
|
-
import { getDefaultSeverityIcon } from '../_shared/severity/severityIcons.js';
|
|
10
|
-
import { alertVariants } from './alert.variants.js';
|
|
11
|
-
import type { AlertProps, AlertTitleProps } from './alert.types.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* `<AlertTitle>` — optional title block, rendered as the first child
|
|
15
|
-
* of `<Alert>`. Pattern mirrors MUI exactly (sub-component, not a
|
|
16
|
-
* prop), so the JSX shape ports 1:1 from `@mui/material`.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* <Alert severity="warning">
|
|
20
|
-
* <AlertTitle>Subscription expires soon</AlertTitle>
|
|
21
|
-
* Renew before 2026-06-20 to keep access.
|
|
22
|
-
* </Alert>
|
|
23
|
-
*/
|
|
24
|
-
export function AlertTitle({ children, className }: AlertTitleProps) {
|
|
25
|
-
const { titleSlot } = alertVariants();
|
|
26
|
-
return (
|
|
27
|
-
<div className={cn(titleSlot(), className)}>
|
|
28
|
-
{children}
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* `<Alert>` — inline persistent status surface.
|
|
35
|
-
*
|
|
36
|
-
* **API**: full MUI Alert parity (`severity`, `variant`, `icon`,
|
|
37
|
-
* `onClose`, `action`, `role`, `<AlertTitle>` sub-component). One
|
|
38
|
-
* deliberate divergence: `severity="danger"` instead of MUI's
|
|
39
|
-
* `severity="error"` — aligned to the `danger.*` token palette.
|
|
40
|
-
*
|
|
41
|
-
* **Bridge integration** (Dashforge extras):
|
|
42
|
-
* - `visibleWhen` — engine-reactive predicate (re-evaluated on
|
|
43
|
-
* every engine state change when mounted inside a `<DashForm>`)
|
|
44
|
-
* - `access` — RBAC gating via `@dashforge/rbac`
|
|
45
|
-
*
|
|
46
|
-
* **Token-driven**: every color class flows from `dashforgePreset()`
|
|
47
|
-
* via CSS variables. No hardcoded hex, no `dark:` variants. The
|
|
48
|
-
* 3×4 color matrix lives in `_shared/severity/severityVariants.ts`
|
|
49
|
-
* and is shared with the refactored `<Snackbar>` (and future Banner).
|
|
50
|
-
*
|
|
51
|
-
* **A11y**: `role="alert"` for assertive severities (warning, danger)
|
|
52
|
-
* and `role="status"` for polite ones (info, success). Override via
|
|
53
|
-
* the `role` prop. The icon is `aria-hidden` — the message text is
|
|
54
|
-
* the semantic carrier.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // Default — soft tinted surface, default icon
|
|
58
|
-
* <Alert severity="info">New feature: export to CSV is now in beta.</Alert>
|
|
59
|
-
*
|
|
60
|
-
* // With title (sub-component) + close button
|
|
61
|
-
* <Alert severity="warning" onClose={dismiss}>
|
|
62
|
-
* <AlertTitle>Subscription expires soon</AlertTitle>
|
|
63
|
-
* Your Pro plan ends in 3 days.
|
|
64
|
-
* </Alert>
|
|
65
|
-
*
|
|
66
|
-
* // Custom icon
|
|
67
|
-
* import { Bell } from 'lucide-react';
|
|
68
|
-
* <Alert severity="info" icon={<Bell size={20} />}>3 new notifications</Alert>
|
|
69
|
-
*
|
|
70
|
-
* // No icon — colored surface alone carries the severity
|
|
71
|
-
* <Alert severity="success" icon={false}>Saved 2 minutes ago.</Alert>
|
|
72
|
-
*
|
|
73
|
-
* // Custom action — CTA replaces the auto-close button
|
|
74
|
-
* <Alert severity="warning" action={<button onClick={renew}>Renew</button>}>
|
|
75
|
-
* Trial expires in 3 days.
|
|
76
|
-
* </Alert>
|
|
77
|
-
*
|
|
78
|
-
* // Filled variant — for high-priority callouts
|
|
79
|
-
* <Alert severity="danger" variant="filled">
|
|
80
|
-
* Couldn't save — 3 fields below contain validation errors.
|
|
81
|
-
* </Alert>
|
|
82
|
-
*/
|
|
83
|
-
export function Alert({
|
|
84
|
-
severity,
|
|
85
|
-
variant = 'standard',
|
|
86
|
-
children,
|
|
87
|
-
icon: iconProp,
|
|
88
|
-
onClose,
|
|
89
|
-
closeText = 'Close',
|
|
90
|
-
action,
|
|
91
|
-
role: roleProp,
|
|
92
|
-
visibleWhen,
|
|
93
|
-
access,
|
|
94
|
-
sx,
|
|
95
|
-
className,
|
|
96
|
-
slotProps,
|
|
97
|
-
}: AlertProps) {
|
|
98
|
-
// Bridge — both hooks safely return defaults outside a DashForm /
|
|
99
|
-
// RbacProvider, matching the TextField pattern.
|
|
100
|
-
const bridge = useContext(DashFormContext);
|
|
101
|
-
const isVisible = useEngineVisibility(bridge?.engine, visibleWhen);
|
|
102
|
-
const accessState = useAccessState(access);
|
|
103
|
-
|
|
104
|
-
if (!isVisible || !accessState.visible) return null;
|
|
105
|
-
|
|
106
|
-
const v = alertVariants();
|
|
107
|
-
const severityClasses = getSeverityClasses(variant, severity);
|
|
108
|
-
const role = roleProp ?? getSeverityRole(severity);
|
|
109
|
-
|
|
110
|
-
// Icon resolution:
|
|
111
|
-
// - false → no icon
|
|
112
|
-
// - undefined → default per severity (lib's inline SVG)
|
|
113
|
-
// - ReactNode → consumer's custom icon
|
|
114
|
-
const renderedIcon =
|
|
115
|
-
iconProp === false
|
|
116
|
-
? null
|
|
117
|
-
: iconProp !== undefined
|
|
118
|
-
? iconProp
|
|
119
|
-
: getDefaultSeverityIcon(severity);
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<div
|
|
123
|
-
role={role}
|
|
124
|
-
className={cn(
|
|
125
|
-
v.root(),
|
|
126
|
-
severityClasses.surface,
|
|
127
|
-
severityClasses.border,
|
|
128
|
-
sx,
|
|
129
|
-
className,
|
|
130
|
-
slotProps?.root?.className
|
|
131
|
-
)}
|
|
132
|
-
{...slotProps?.root}
|
|
133
|
-
>
|
|
134
|
-
{renderedIcon !== null && (
|
|
135
|
-
<span
|
|
136
|
-
className={cn(
|
|
137
|
-
v.icon(),
|
|
138
|
-
severityClasses.icon,
|
|
139
|
-
slotProps?.icon?.className
|
|
140
|
-
)}
|
|
141
|
-
{...slotProps?.icon}
|
|
142
|
-
>
|
|
143
|
-
{renderedIcon}
|
|
144
|
-
</span>
|
|
145
|
-
)}
|
|
146
|
-
|
|
147
|
-
<div
|
|
148
|
-
className={cn(v.content(), slotProps?.content?.className)}
|
|
149
|
-
{...slotProps?.content}
|
|
150
|
-
>
|
|
151
|
-
{children}
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
{action ? (
|
|
155
|
-
<div
|
|
156
|
-
className={cn(v.action(), slotProps?.action?.className)}
|
|
157
|
-
{...slotProps?.action}
|
|
158
|
-
>
|
|
159
|
-
{action}
|
|
160
|
-
</div>
|
|
161
|
-
) : onClose ? (
|
|
162
|
-
<button
|
|
163
|
-
type="button"
|
|
164
|
-
aria-label={closeText}
|
|
165
|
-
onClick={onClose}
|
|
166
|
-
className={cn(v.closeButton(), slotProps?.closeButton?.className)}
|
|
167
|
-
{...slotProps?.closeButton}
|
|
168
|
-
>
|
|
169
|
-
<svg
|
|
170
|
-
width="1em"
|
|
171
|
-
height="1em"
|
|
172
|
-
viewBox="0 0 20 20"
|
|
173
|
-
fill="none"
|
|
174
|
-
stroke="currentColor"
|
|
175
|
-
strokeWidth={1.5}
|
|
176
|
-
strokeLinecap="round"
|
|
177
|
-
strokeLinejoin="round"
|
|
178
|
-
aria-hidden="true"
|
|
179
|
-
>
|
|
180
|
-
<path d="m6 6 8 8M14 6l-8 8" />
|
|
181
|
-
</svg>
|
|
182
|
-
</button>
|
|
183
|
-
) : null}
|
|
184
|
-
</div>
|
|
185
|
-
);
|
|
186
|
-
}
|