@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,112 +0,0 @@
|
|
|
1
|
-
import type { ElementType, HTMLAttributes } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Grid types — discriminated union for container vs item role.
|
|
5
|
-
*
|
|
6
|
-
* Pattern is MUI v2: a single `<Grid>` component that switches role
|
|
7
|
-
* based on the `container` prop. Container exposes layout axes
|
|
8
|
-
* (cols, spacing, autoFlow). Item exposes per-breakpoint span axes
|
|
9
|
-
* (xs/sm/md/lg/xl).
|
|
10
|
-
*
|
|
11
|
-
* TypeScript-level enforcement (the key win over MUI):
|
|
12
|
-
* • `<Grid container xs={6}>` is a TYPE ERROR — `xs` doesn't exist
|
|
13
|
-
* on the container shape.
|
|
14
|
-
* • `<Grid xs={6} spacing={4}>` is a TYPE ERROR — `spacing` doesn't
|
|
15
|
-
* exist on the item shape.
|
|
16
|
-
* IntelliSense filters suggestions per role, so the developer never
|
|
17
|
-
* sees props that don't apply.
|
|
18
|
-
*
|
|
19
|
-
* Type-only file (no runtime). Lives separate from the variants so the
|
|
20
|
-
* union doesn't widen with the variant catalogue's enum unions.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Valid column-span values for a grid item, at any breakpoint.
|
|
25
|
-
* • 1..12 — explicit span count
|
|
26
|
-
* • 'auto' — content-sized (CSS Grid auto-track)
|
|
27
|
-
* • 'full' — `col-span-full` (spans all columns regardless of count)
|
|
28
|
-
*/
|
|
29
|
-
export type ColSpan =
|
|
30
|
-
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12
|
|
31
|
-
| 'auto'
|
|
32
|
-
| 'full';
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Token-scale spacing step. Mirror of Box.p / Stack.gap so the value
|
|
36
|
-
* space across primitives is identical — `<Grid container spacing={4}>`
|
|
37
|
-
* and `<Stack gap={4}>` produce visually equivalent gaps.
|
|
38
|
-
*/
|
|
39
|
-
export type GridSpacingStep =
|
|
40
|
-
| 0 | '0.5' | 1 | 2 | 3 | 4 | 6 | 8 | 12 | 16 | 24;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Container-role props. Discriminated on `container: true`.
|
|
44
|
-
*
|
|
45
|
-
* NOTE on `cols`: defaults to 12 in the component implementation
|
|
46
|
-
* (not in TV) — the MUI v2 convention. Override to 6/4/3/2/1 for
|
|
47
|
-
* dense dashboard layouts.
|
|
48
|
-
*/
|
|
49
|
-
export interface GridContainerProps {
|
|
50
|
-
/** Discriminator — `true` makes this a grid container. */
|
|
51
|
-
container: true;
|
|
52
|
-
/** Number of columns. Default 12. */
|
|
53
|
-
cols?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
54
|
-
/** Gap between cells. Shorthand for spacingX + spacingY. */
|
|
55
|
-
spacing?: GridSpacingStep;
|
|
56
|
-
/** Horizontal gap override (wins over `spacing`). */
|
|
57
|
-
spacingX?: GridSpacingStep;
|
|
58
|
-
/** Vertical gap override (wins over `spacing`). */
|
|
59
|
-
spacingY?: GridSpacingStep;
|
|
60
|
-
/** `grid-auto-flow` — useful for dense or column-major packing. */
|
|
61
|
-
autoFlow?: 'row' | 'col' | 'dense' | 'row-dense' | 'col-dense';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Item-role props. Discriminated on `container: false | undefined`.
|
|
66
|
-
*
|
|
67
|
-
* Each breakpoint accepts a `ColSpan`. The cascade is Tailwind-native
|
|
68
|
-
* mobile-first: `xs` is the base (no media query), `sm/md/lg/xl`
|
|
69
|
-
* override at the corresponding min-width.
|
|
70
|
-
*
|
|
71
|
-
* Default behaviour when no breakpoint is set: spans `full` — the
|
|
72
|
-
* "comfortable default" so a forgotten prop doesn't collapse the cell
|
|
73
|
-
* to 1/12th of a row.
|
|
74
|
-
*/
|
|
75
|
-
export interface GridItemProps {
|
|
76
|
-
/** Discriminator — absent (or `false`) makes this a grid item. */
|
|
77
|
-
container?: false;
|
|
78
|
-
/** Base breakpoint (no media query). Default `'full'`. */
|
|
79
|
-
xs?: ColSpan;
|
|
80
|
-
/** Span at sm breakpoint and up. */
|
|
81
|
-
sm?: ColSpan;
|
|
82
|
-
/** Span at md breakpoint and up. */
|
|
83
|
-
md?: ColSpan;
|
|
84
|
-
/** Span at lg breakpoint and up. */
|
|
85
|
-
lg?: ColSpan;
|
|
86
|
-
/** Span at xl breakpoint and up. */
|
|
87
|
-
xl?: ColSpan;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Common props shared by both roles. Kept in a separate intersection
|
|
92
|
-
* so the discriminated union stays narrow and IntelliSense fast.
|
|
93
|
-
*/
|
|
94
|
-
interface GridCommonProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className'> {
|
|
95
|
-
/** Override the rendered HTML tag. Default `'div'`. Ignored under `asChild`. */
|
|
96
|
-
as?: ElementType;
|
|
97
|
-
/**
|
|
98
|
-
* Render via Radix Slot onto the single child. Wins over `as`.
|
|
99
|
-
* Note: container Grids using `asChild` don't make sense for most
|
|
100
|
-
* cases — the Slot pattern collapses our wrapper, but Grid's
|
|
101
|
-
* `display:grid` only applies to direct children, so the child
|
|
102
|
-
* needs to BE a container with the right children.
|
|
103
|
-
*/
|
|
104
|
-
asChild?: boolean;
|
|
105
|
-
/** Utility-class override, merged via tailwind-merge. */
|
|
106
|
-
sx?: string;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* `<Grid>` props — discriminated union: container OR item, never both.
|
|
111
|
-
*/
|
|
112
|
-
export type GridProps = (GridContainerProps | GridItemProps) & GridCommonProps;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { tv, type VariantProps } from 'tailwind-variants';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* `gridVariants` — CSS Grid container + item, polymorphic in role.
|
|
5
|
-
*
|
|
6
|
-
* Architectural choice (planned with the user — F9 deep dive):
|
|
7
|
-
*
|
|
8
|
-
* Pattern is MUI Grid v2 from the API side (`<Grid container>` +
|
|
9
|
-
* `<Grid xs={6}>`), but engine is REAL CSS Grid under the hood
|
|
10
|
-
* (`display: grid` + `grid-template-columns: repeat(N, 1fr)` +
|
|
11
|
-
* `col-span-*`). MUI v2 uses flexbox + basis percentages — historical
|
|
12
|
-
* IE11 reasons. In 2026, CSS Grid is universally supported AND
|
|
13
|
-
* Tailwind ships `grid-cols-*` / `col-span-*` natively, so flexbox
|
|
14
|
-
* would be a downgrade.
|
|
15
|
-
*
|
|
16
|
-
* Two distinct shapes coexist in the same TV recipe:
|
|
17
|
-
*
|
|
18
|
-
* • container=true — display:grid + cols + gap + autoFlow
|
|
19
|
-
* • container=false — col-span at each breakpoint (xs/sm/md/lg/xl)
|
|
20
|
-
*
|
|
21
|
-
* The discriminated union lives in grid.types.ts (TypeScript-level);
|
|
22
|
-
* here the TV catalogue exposes every axis so the consumer's choice
|
|
23
|
-
* triggers the right classes regardless of which role the component
|
|
24
|
-
* is playing. Unused axes produce no classes (TV silently drops
|
|
25
|
-
* undefined variants), so a container Grid never accidentally emits
|
|
26
|
-
* `col-span-6` and an item Grid never accidentally emits `grid`.
|
|
27
|
-
*
|
|
28
|
-
* Mapping table size:
|
|
29
|
-
* • cols : 6 entries (12, 6, 4, 3, 2, 1)
|
|
30
|
-
* • autoFlow : 5 entries
|
|
31
|
-
* • span axes (5×14) : 70 entries (xs/sm/md/lg/xl × {1..12, auto, full})
|
|
32
|
-
* • gap / gapX / gapY : 33 entries (11 steps × 3 axes)
|
|
33
|
-
*
|
|
34
|
-
* Total: ~115 literal class names. All explicit, all Tailwind-scannable.
|
|
35
|
-
* Bundle CSS impact when fully exercised: ~3 KB gz (mostly the
|
|
36
|
-
* responsive col-span set).
|
|
37
|
-
*/
|
|
38
|
-
export const gridVariants = tv({
|
|
39
|
-
base: '',
|
|
40
|
-
|
|
41
|
-
variants: {
|
|
42
|
-
// ─── CONTAINER role ────────────────────────────────────────────────
|
|
43
|
-
container: { true: 'grid' },
|
|
44
|
-
|
|
45
|
-
cols: {
|
|
46
|
-
1: 'grid-cols-1',
|
|
47
|
-
2: 'grid-cols-2',
|
|
48
|
-
3: 'grid-cols-3',
|
|
49
|
-
4: 'grid-cols-4',
|
|
50
|
-
6: 'grid-cols-6',
|
|
51
|
-
12: 'grid-cols-12',
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
autoFlow: {
|
|
55
|
-
row: 'grid-flow-row',
|
|
56
|
-
col: 'grid-flow-col',
|
|
57
|
-
dense: 'grid-flow-dense',
|
|
58
|
-
'row-dense':'grid-flow-row-dense',
|
|
59
|
-
'col-dense':'grid-flow-col-dense',
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
/*
|
|
63
|
-
* Container gap — token-scale step. Same set as Box/Stack so muscle
|
|
64
|
-
* memory carries across primitives.
|
|
65
|
-
*/
|
|
66
|
-
spacing: {
|
|
67
|
-
0: 'gap-0', '0.5': 'gap-0.5', 1: 'gap-1', 2: 'gap-2', 3: 'gap-3',
|
|
68
|
-
4: 'gap-4', 6: 'gap-6', 8: 'gap-8', 12: 'gap-12', 16: 'gap-16',
|
|
69
|
-
24: 'gap-24',
|
|
70
|
-
},
|
|
71
|
-
spacingX: {
|
|
72
|
-
0: 'gap-x-0', '0.5': 'gap-x-0.5', 1: 'gap-x-1', 2: 'gap-x-2', 3: 'gap-x-3',
|
|
73
|
-
4: 'gap-x-4', 6: 'gap-x-6', 8: 'gap-x-8', 12: 'gap-x-12', 16: 'gap-x-16',
|
|
74
|
-
24: 'gap-x-24',
|
|
75
|
-
},
|
|
76
|
-
spacingY: {
|
|
77
|
-
0: 'gap-y-0', '0.5': 'gap-y-0.5', 1: 'gap-y-1', 2: 'gap-y-2', 3: 'gap-y-3',
|
|
78
|
-
4: 'gap-y-4', 6: 'gap-y-6', 8: 'gap-y-8', 12: 'gap-y-12', 16: 'gap-y-16',
|
|
79
|
-
24: 'gap-y-24',
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
// ─── ITEM role — col-span at each breakpoint ──────────────────────
|
|
83
|
-
/*
|
|
84
|
-
* `xs` is the base breakpoint (no prefix) — Tailwind's mobile-first
|
|
85
|
-
* convention. `sm/md/lg/xl` cascade up from there.
|
|
86
|
-
*
|
|
87
|
-
* Special values:
|
|
88
|
-
* • 'auto' → col-auto (content-sized)
|
|
89
|
-
* • 'full' → col-span-full (span all columns regardless of count)
|
|
90
|
-
*/
|
|
91
|
-
xs: {
|
|
92
|
-
1: 'col-span-1', 2: 'col-span-2', 3: 'col-span-3', 4: 'col-span-4',
|
|
93
|
-
5: 'col-span-5', 6: 'col-span-6', 7: 'col-span-7', 8: 'col-span-8',
|
|
94
|
-
9: 'col-span-9', 10: 'col-span-10', 11: 'col-span-11', 12: 'col-span-12',
|
|
95
|
-
auto: 'col-auto', full: 'col-span-full',
|
|
96
|
-
},
|
|
97
|
-
sm: {
|
|
98
|
-
1: 'sm:col-span-1', 2: 'sm:col-span-2', 3: 'sm:col-span-3', 4: 'sm:col-span-4',
|
|
99
|
-
5: 'sm:col-span-5', 6: 'sm:col-span-6', 7: 'sm:col-span-7', 8: 'sm:col-span-8',
|
|
100
|
-
9: 'sm:col-span-9', 10: 'sm:col-span-10', 11: 'sm:col-span-11', 12: 'sm:col-span-12',
|
|
101
|
-
auto: 'sm:col-auto', full: 'sm:col-span-full',
|
|
102
|
-
},
|
|
103
|
-
md: {
|
|
104
|
-
1: 'md:col-span-1', 2: 'md:col-span-2', 3: 'md:col-span-3', 4: 'md:col-span-4',
|
|
105
|
-
5: 'md:col-span-5', 6: 'md:col-span-6', 7: 'md:col-span-7', 8: 'md:col-span-8',
|
|
106
|
-
9: 'md:col-span-9', 10: 'md:col-span-10', 11: 'md:col-span-11', 12: 'md:col-span-12',
|
|
107
|
-
auto: 'md:col-auto', full: 'md:col-span-full',
|
|
108
|
-
},
|
|
109
|
-
lg: {
|
|
110
|
-
1: 'lg:col-span-1', 2: 'lg:col-span-2', 3: 'lg:col-span-3', 4: 'lg:col-span-4',
|
|
111
|
-
5: 'lg:col-span-5', 6: 'lg:col-span-6', 7: 'lg:col-span-7', 8: 'lg:col-span-8',
|
|
112
|
-
9: 'lg:col-span-9', 10: 'lg:col-span-10', 11: 'lg:col-span-11', 12: 'lg:col-span-12',
|
|
113
|
-
auto: 'lg:col-auto', full: 'lg:col-span-full',
|
|
114
|
-
},
|
|
115
|
-
xl: {
|
|
116
|
-
1: 'xl:col-span-1', 2: 'xl:col-span-2', 3: 'xl:col-span-3', 4: 'xl:col-span-4',
|
|
117
|
-
5: 'xl:col-span-5', 6: 'xl:col-span-6', 7: 'xl:col-span-7', 8: 'xl:col-span-8',
|
|
118
|
-
9: 'xl:col-span-9', 10: 'xl:col-span-10', 11: 'xl:col-span-11', 12: 'xl:col-span-12',
|
|
119
|
-
auto: 'xl:col-auto', full: 'xl:col-span-full',
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
/*
|
|
124
|
-
* No `defaultVariants`. The default semantics are role-dependent:
|
|
125
|
-
* • container Grid defaults to cols=12 (set in Grid.tsx)
|
|
126
|
-
* • item Grid defaults to xs="full" — full-width until a breakpoint
|
|
127
|
-
* prop overrides (also set in Grid.tsx)
|
|
128
|
-
* Encoding these defaults at the TV level would emit them even when
|
|
129
|
-
* irrelevant (e.g. an item Grid never wants `grid grid-cols-12`).
|
|
130
|
-
*/
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
export type GridVariants = VariantProps<typeof gridVariants>;
|
|
@@ -1,367 +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 { RbacProvider } from '@dashforge/rbac';
|
|
6
|
-
import type { RbacPolicy, Subject } from '@dashforge/rbac';
|
|
7
|
-
import { IconButton } from './IconButton.js';
|
|
8
|
-
|
|
9
|
-
void React;
|
|
10
|
-
afterEach(() => cleanup());
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* `<IconButton>` unit tests. Covers:
|
|
14
|
-
* - icon rendering, required aria-label, base layout primitives
|
|
15
|
-
* - variant × color × size matrix (5 variants × 5 colors × 3 sizes)
|
|
16
|
-
* — sampled, not exhaustive (the full matrix is covered by
|
|
17
|
-
* `<Button>`'s tests since IconButton reuses `buttonVariants`)
|
|
18
|
-
* - square geometry via SIZE_OVERRIDES + aspect-square
|
|
19
|
-
* - asChild polymorphism via Radix Slot
|
|
20
|
-
* - loading state (spinner + aria-busy + disabled)
|
|
21
|
-
* - disabled state (explicit + access.disabled + access.readonly)
|
|
22
|
-
* - access RBAC: hide / disable
|
|
23
|
-
* - click handler firing semantics
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
const TestIcon = () => (
|
|
27
|
-
<svg data-testid="test-icon" width={20} height={20} viewBox="0 0 20 20">
|
|
28
|
-
<circle cx="10" cy="10" r="8" />
|
|
29
|
-
</svg>
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const FULL_ACCESS_POLICY: RbacPolicy = {
|
|
33
|
-
roles: [
|
|
34
|
-
{
|
|
35
|
-
name: 'admin',
|
|
36
|
-
permissions: [{ resource: '*', action: '*', effect: 'allow' }],
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
};
|
|
40
|
-
const NO_ACCESS_POLICY: RbacPolicy = {
|
|
41
|
-
roles: [
|
|
42
|
-
{ name: 'guest', permissions: [] },
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
const adminSubject: Subject = { id: 'a', roles: ['admin'] };
|
|
46
|
-
const guestSubject: Subject = { id: 'g', roles: ['guest'] };
|
|
47
|
-
|
|
48
|
-
describe('<IconButton>', () => {
|
|
49
|
-
describe('rendering', () => {
|
|
50
|
-
it('renders the icon child', () => {
|
|
51
|
-
render(
|
|
52
|
-
<IconButton aria-label="x">
|
|
53
|
-
<TestIcon />
|
|
54
|
-
</IconButton>
|
|
55
|
-
);
|
|
56
|
-
expect(screen.getByTestId('test-icon')).toBeTruthy();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('applies the aria-label to the button element', () => {
|
|
60
|
-
render(
|
|
61
|
-
<IconButton aria-label="Open settings">
|
|
62
|
-
<TestIcon />
|
|
63
|
-
</IconButton>
|
|
64
|
-
);
|
|
65
|
-
expect(screen.getByRole('button', { name: /open settings/i })).toBeTruthy();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('renders as type="button" by default', () => {
|
|
69
|
-
render(
|
|
70
|
-
<IconButton aria-label="x">
|
|
71
|
-
<TestIcon />
|
|
72
|
-
</IconButton>
|
|
73
|
-
);
|
|
74
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
75
|
-
expect(btn.type).toBe('button');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('respects an explicit type prop', () => {
|
|
79
|
-
render(
|
|
80
|
-
<IconButton aria-label="x" type="submit">
|
|
81
|
-
<TestIcon />
|
|
82
|
-
</IconButton>
|
|
83
|
-
);
|
|
84
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
85
|
-
expect(btn.type).toBe('submit');
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
describe('layout primitives — square geometry', () => {
|
|
90
|
-
it('always applies aspect-square + inline-flex (layout base)', () => {
|
|
91
|
-
const { container } = render(
|
|
92
|
-
<IconButton aria-label="x">
|
|
93
|
-
<TestIcon />
|
|
94
|
-
</IconButton>
|
|
95
|
-
);
|
|
96
|
-
const btn = container.querySelector('button')!;
|
|
97
|
-
expect(btn.className).toContain('aspect-square');
|
|
98
|
-
expect(btn.className).toContain('inline-flex');
|
|
99
|
-
expect(btn.className).toContain('items-center');
|
|
100
|
-
expect(btn.className).toContain('justify-center');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('applies SIZE_OVERRIDES (w-N + px-0) for sm', () => {
|
|
104
|
-
const { container } = render(
|
|
105
|
-
<IconButton aria-label="x" size="sm">
|
|
106
|
-
<TestIcon />
|
|
107
|
-
</IconButton>
|
|
108
|
-
);
|
|
109
|
-
const btn = container.querySelector('button')!;
|
|
110
|
-
expect(btn.className).toContain('w-8');
|
|
111
|
-
expect(btn.className).toContain('px-0');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('applies SIZE_OVERRIDES for md (default)', () => {
|
|
115
|
-
const { container } = render(
|
|
116
|
-
<IconButton aria-label="x">
|
|
117
|
-
<TestIcon />
|
|
118
|
-
</IconButton>
|
|
119
|
-
);
|
|
120
|
-
const btn = container.querySelector('button')!;
|
|
121
|
-
expect(btn.className).toContain('w-10');
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('applies SIZE_OVERRIDES for lg', () => {
|
|
125
|
-
const { container } = render(
|
|
126
|
-
<IconButton aria-label="x" size="lg">
|
|
127
|
-
<TestIcon />
|
|
128
|
-
</IconButton>
|
|
129
|
-
);
|
|
130
|
-
const btn = container.querySelector('button')!;
|
|
131
|
-
expect(btn.className).toContain('w-12');
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe('variant × color (inherits buttonVariants)', () => {
|
|
136
|
-
it('renders solid + primary (token-driven, no hardcoded hex)', () => {
|
|
137
|
-
const { container } = render(
|
|
138
|
-
<IconButton aria-label="x" variant="solid" color="primary">
|
|
139
|
-
<TestIcon />
|
|
140
|
-
</IconButton>
|
|
141
|
-
);
|
|
142
|
-
const btn = container.querySelector('button')!;
|
|
143
|
-
expect(btn.className).toContain('bg-primary-500');
|
|
144
|
-
expect(btn.className).not.toMatch(/#[0-9a-fA-F]{3,8}/);
|
|
145
|
-
expect(btn.className).not.toMatch(/\bdark:/);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('renders outline + danger (border color comes through)', () => {
|
|
149
|
-
const { container } = render(
|
|
150
|
-
<IconButton aria-label="x" variant="outline" color="danger">
|
|
151
|
-
<TestIcon />
|
|
152
|
-
</IconButton>
|
|
153
|
-
);
|
|
154
|
-
const btn = container.querySelector('button')!;
|
|
155
|
-
expect(btn.className).toContain('border');
|
|
156
|
-
expect(btn.className).toContain('danger');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('ghost variant uses bg-transparent', () => {
|
|
160
|
-
const { container } = render(
|
|
161
|
-
<IconButton aria-label="x" variant="ghost">
|
|
162
|
-
<TestIcon />
|
|
163
|
-
</IconButton>
|
|
164
|
-
);
|
|
165
|
-
const btn = container.querySelector('button')!;
|
|
166
|
-
expect(btn.className).toContain('bg-transparent');
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
describe('asChild polymorphism', () => {
|
|
171
|
-
it('renders the child via Radix Slot when asChild=true', () => {
|
|
172
|
-
const { container } = render(
|
|
173
|
-
<IconButton asChild aria-label="Open">
|
|
174
|
-
<a href="/open" data-testid="anchor-child">
|
|
175
|
-
<TestIcon />
|
|
176
|
-
</a>
|
|
177
|
-
</IconButton>
|
|
178
|
-
);
|
|
179
|
-
// Should be an <a>, not a <button>
|
|
180
|
-
const anchor = container.querySelector('a[data-testid="anchor-child"]');
|
|
181
|
-
expect(anchor).toBeTruthy();
|
|
182
|
-
expect(container.querySelector('button')).toBeNull();
|
|
183
|
-
// Anchor carries the IconButton className
|
|
184
|
-
expect(anchor!.className).toContain('aspect-square');
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
describe('loading state', () => {
|
|
189
|
-
it('swaps the icon with a spinner', () => {
|
|
190
|
-
const { container } = render(
|
|
191
|
-
<IconButton aria-label="x" loading>
|
|
192
|
-
<TestIcon />
|
|
193
|
-
</IconButton>
|
|
194
|
-
);
|
|
195
|
-
// Icon child gone, replaced by Spinner (animate-spin is on the
|
|
196
|
-
// Spinner's outer <span> wrapper now, since Sprint 4.4 refactor
|
|
197
|
-
// delegated to the public <Spinner> component).
|
|
198
|
-
expect(screen.queryByTestId('test-icon')).toBeNull();
|
|
199
|
-
const spinner = container.querySelector('[class*="animate-spin"]');
|
|
200
|
-
expect(spinner).toBeTruthy();
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('sets aria-busy=true while loading', () => {
|
|
204
|
-
render(
|
|
205
|
-
<IconButton aria-label="x" loading>
|
|
206
|
-
<TestIcon />
|
|
207
|
-
</IconButton>
|
|
208
|
-
);
|
|
209
|
-
const btn = screen.getByRole('button');
|
|
210
|
-
expect(btn.getAttribute('aria-busy')).toBe('true');
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('is disabled while loading', () => {
|
|
214
|
-
render(
|
|
215
|
-
<IconButton aria-label="x" loading>
|
|
216
|
-
<TestIcon />
|
|
217
|
-
</IconButton>
|
|
218
|
-
);
|
|
219
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
220
|
-
expect(btn.disabled).toBe(true);
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
describe('disabled state', () => {
|
|
225
|
-
it('respects the explicit disabled prop', () => {
|
|
226
|
-
render(
|
|
227
|
-
<IconButton aria-label="x" disabled>
|
|
228
|
-
<TestIcon />
|
|
229
|
-
</IconButton>
|
|
230
|
-
);
|
|
231
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
232
|
-
expect(btn.disabled).toBe(true);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it('does not fire onClick when disabled', () => {
|
|
236
|
-
const onClick = vi.fn();
|
|
237
|
-
render(
|
|
238
|
-
<IconButton aria-label="x" disabled onClick={onClick}>
|
|
239
|
-
<TestIcon />
|
|
240
|
-
</IconButton>
|
|
241
|
-
);
|
|
242
|
-
fireEvent.click(screen.getByRole('button'));
|
|
243
|
-
expect(onClick).not.toHaveBeenCalled();
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
describe('access RBAC integration', () => {
|
|
248
|
-
it('hides the button when access.onUnauthorized=hide and subject lacks permission', () => {
|
|
249
|
-
const { container } = render(
|
|
250
|
-
<RbacProvider policy={NO_ACCESS_POLICY} subject={guestSubject}>
|
|
251
|
-
<IconButton
|
|
252
|
-
aria-label="x"
|
|
253
|
-
access={{
|
|
254
|
-
resource: 'article',
|
|
255
|
-
action: 'publish',
|
|
256
|
-
onUnauthorized: 'hide',
|
|
257
|
-
}}
|
|
258
|
-
>
|
|
259
|
-
<TestIcon />
|
|
260
|
-
</IconButton>
|
|
261
|
-
</RbacProvider>
|
|
262
|
-
);
|
|
263
|
-
expect(container.querySelector('button')).toBeNull();
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it('disables the button when access.onUnauthorized=disable and subject lacks permission', () => {
|
|
267
|
-
render(
|
|
268
|
-
<RbacProvider policy={NO_ACCESS_POLICY} subject={guestSubject}>
|
|
269
|
-
<IconButton
|
|
270
|
-
aria-label="x"
|
|
271
|
-
access={{
|
|
272
|
-
resource: 'article',
|
|
273
|
-
action: 'publish',
|
|
274
|
-
onUnauthorized: 'disable',
|
|
275
|
-
}}
|
|
276
|
-
>
|
|
277
|
-
<TestIcon />
|
|
278
|
-
</IconButton>
|
|
279
|
-
</RbacProvider>
|
|
280
|
-
);
|
|
281
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
282
|
-
expect(btn.disabled).toBe(true);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it('renders normally for an admin subject', () => {
|
|
286
|
-
render(
|
|
287
|
-
<RbacProvider policy={FULL_ACCESS_POLICY} subject={adminSubject}>
|
|
288
|
-
<IconButton
|
|
289
|
-
aria-label="x"
|
|
290
|
-
access={{
|
|
291
|
-
resource: 'article',
|
|
292
|
-
action: 'publish',
|
|
293
|
-
onUnauthorized: 'hide',
|
|
294
|
-
}}
|
|
295
|
-
>
|
|
296
|
-
<TestIcon />
|
|
297
|
-
</IconButton>
|
|
298
|
-
</RbacProvider>
|
|
299
|
-
);
|
|
300
|
-
expect(screen.getByRole('button')).toBeTruthy();
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
describe('click handler', () => {
|
|
305
|
-
it('fires onClick when clicked', () => {
|
|
306
|
-
const onClick = vi.fn();
|
|
307
|
-
render(
|
|
308
|
-
<IconButton aria-label="x" onClick={onClick}>
|
|
309
|
-
<TestIcon />
|
|
310
|
-
</IconButton>
|
|
311
|
-
);
|
|
312
|
-
fireEvent.click(screen.getByRole('button'));
|
|
313
|
-
expect(onClick).toHaveBeenCalledTimes(1);
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
describe('visibleWhen (engine-reactive, Sprint 4.4)', () => {
|
|
318
|
-
it('renders when visibleWhen returns true', () => {
|
|
319
|
-
const { container } = render(
|
|
320
|
-
<IconButton aria-label="x" visibleWhen={() => true}>
|
|
321
|
-
<TestIcon />
|
|
322
|
-
</IconButton>
|
|
323
|
-
);
|
|
324
|
-
expect(container.firstChild).toBeTruthy();
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
it('returns null when visibleWhen returns false', () => {
|
|
328
|
-
const { container } = render(
|
|
329
|
-
<IconButton aria-label="x" visibleWhen={() => false}>
|
|
330
|
-
<TestIcon />
|
|
331
|
-
</IconButton>
|
|
332
|
-
);
|
|
333
|
-
expect(container.firstChild).toBeNull();
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
it('renders normally when visibleWhen is omitted', () => {
|
|
337
|
-
const { container } = render(
|
|
338
|
-
<IconButton aria-label="x">
|
|
339
|
-
<TestIcon />
|
|
340
|
-
</IconButton>
|
|
341
|
-
);
|
|
342
|
-
expect(container.firstChild).toBeTruthy();
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
describe('overrides — sx + className', () => {
|
|
347
|
-
it('appends sx to the root className', () => {
|
|
348
|
-
const { container } = render(
|
|
349
|
-
<IconButton aria-label="x" sx="ring-2 ring-purple-500">
|
|
350
|
-
<TestIcon />
|
|
351
|
-
</IconButton>
|
|
352
|
-
);
|
|
353
|
-
const btn = container.querySelector('button')!;
|
|
354
|
-
expect(btn.className).toContain('ring-purple-500');
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it('appends className to the root', () => {
|
|
358
|
-
const { container } = render(
|
|
359
|
-
<IconButton aria-label="x" className="my-custom-icon-btn">
|
|
360
|
-
<TestIcon />
|
|
361
|
-
</IconButton>
|
|
362
|
-
);
|
|
363
|
-
const btn = container.querySelector('button')!;
|
|
364
|
-
expect(btn.className).toContain('my-custom-icon-btn');
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
});
|