@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,64 +0,0 @@
|
|
|
1
|
-
import { tv } from 'tailwind-variants';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Structural slots for `<Calendar>`.
|
|
5
|
-
*
|
|
6
|
-
* Theme identity: every class is a bare neutral / brand token-backed
|
|
7
|
-
* Tailwind class. The `dashforgePreset()` CSS-variable swap auto-inverts
|
|
8
|
-
* the neutral palette, so there are NO `dark:` variants here (a `dark:` on
|
|
9
|
-
* a neutral class would double-invert — see `_shared/themeIdentity.test.ts`).
|
|
10
|
-
*/
|
|
11
|
-
export const calendarVariants = tv({
|
|
12
|
-
slots: {
|
|
13
|
-
root: 'inline-flex w-fit flex-col gap-2 rounded-lg border border-neutral-200 bg-neutral-50 p-3 select-none',
|
|
14
|
-
header: 'flex items-center justify-between gap-1',
|
|
15
|
-
navButton:
|
|
16
|
-
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-[1rem] text-neutral-600 transition-colors hover:bg-neutral-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 disabled:pointer-events-none disabled:opacity-40',
|
|
17
|
-
monthLabel: 'flex-1 text-center text-sm font-semibold text-neutral-900',
|
|
18
|
-
grid: 'flex flex-col gap-1 focus:outline-none',
|
|
19
|
-
weekdayRow: 'grid grid-cols-7 gap-1',
|
|
20
|
-
weekday:
|
|
21
|
-
'flex h-8 items-center justify-center text-xs font-semibold text-neutral-500',
|
|
22
|
-
weekRow: 'grid grid-cols-7 gap-1',
|
|
23
|
-
},
|
|
24
|
-
variants: {
|
|
25
|
-
disabled: {
|
|
26
|
-
true: { root: 'opacity-60' },
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
defaultVariants: {
|
|
30
|
-
disabled: false,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Per-day-cell recipe. Each of the 42 grid cells is rendered with its own
|
|
36
|
-
* state (`siblingMonth` / `today` / `selected` / `disabled`).
|
|
37
|
-
*/
|
|
38
|
-
export const calendarDayVariants = tv({
|
|
39
|
-
base: 'flex h-9 w-9 items-center justify-center rounded-md text-sm text-neutral-900 transition-colors hover:bg-neutral-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary-500',
|
|
40
|
-
variants: {
|
|
41
|
-
siblingMonth: {
|
|
42
|
-
true: 'text-neutral-400',
|
|
43
|
-
},
|
|
44
|
-
today: {
|
|
45
|
-
true: 'font-bold ring-1 ring-inset ring-primary-400',
|
|
46
|
-
},
|
|
47
|
-
selected: {
|
|
48
|
-
true: 'bg-primary-600 text-white hover:bg-primary-600',
|
|
49
|
-
},
|
|
50
|
-
disabled: {
|
|
51
|
-
true: 'cursor-default text-neutral-300 opacity-60 hover:bg-transparent',
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
compoundVariants: [
|
|
55
|
-
// A selected cell drops the "today" ring — the solid fill is enough.
|
|
56
|
-
{ selected: true, today: true, class: 'ring-0' },
|
|
57
|
-
],
|
|
58
|
-
defaultVariants: {
|
|
59
|
-
siblingMonth: false,
|
|
60
|
-
today: false,
|
|
61
|
-
selected: false,
|
|
62
|
-
disabled: false,
|
|
63
|
-
},
|
|
64
|
-
});
|
|
@@ -1,291 +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 { Card, CardContent, CardActionArea } from './Card.js';
|
|
8
|
-
|
|
9
|
-
void React;
|
|
10
|
-
afterEach(() => cleanup());
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Unit tests for the Card family. Covers:
|
|
14
|
-
* - <Card>: thin Box wrapper with restricted variant axis, inherits
|
|
15
|
-
* access + visibleWhen from Box (verified at integration level)
|
|
16
|
-
* - <CardContent>: padded inner box with default p=4 and override
|
|
17
|
-
* - <CardActionArea>: clickable wrapper (button or asChild), focus
|
|
18
|
-
* ring, selected aria-pressed, disabled state, access RBAC,
|
|
19
|
-
* visibleWhen predicate
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const ADMIN_POLICY: RbacPolicy = {
|
|
23
|
-
roles: [
|
|
24
|
-
{
|
|
25
|
-
name: 'admin',
|
|
26
|
-
permissions: [{ resource: '*', action: '*', effect: 'allow' }],
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
const NO_ACCESS_POLICY: RbacPolicy = {
|
|
31
|
-
roles: [{ name: 'guest', permissions: [] }],
|
|
32
|
-
};
|
|
33
|
-
const adminSubject: Subject = { id: 'a', roles: ['admin'] };
|
|
34
|
-
const guestSubject: Subject = { id: 'g', roles: ['guest'] };
|
|
35
|
-
|
|
36
|
-
describe('<Card>', () => {
|
|
37
|
-
describe('rendering', () => {
|
|
38
|
-
it('renders children', () => {
|
|
39
|
-
render(<Card data-testid="card">hello</Card>);
|
|
40
|
-
expect(screen.getByTestId('card')).toBeTruthy();
|
|
41
|
-
expect(screen.getByText('hello')).toBeTruthy();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('applies default outlined variant (border class from Box)', () => {
|
|
45
|
-
const { container } = render(<Card>x</Card>);
|
|
46
|
-
const root = container.firstElementChild!;
|
|
47
|
-
expect(root.className).toContain('border');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('applies default rounded="lg"', () => {
|
|
51
|
-
const { container } = render(<Card>x</Card>);
|
|
52
|
-
const root = container.firstElementChild!;
|
|
53
|
-
expect(root.className).toContain('rounded-lg');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('overrides default variant to elevated', () => {
|
|
57
|
-
const { container } = render(<Card variant="elevated">x</Card>);
|
|
58
|
-
const root = container.firstElementChild!;
|
|
59
|
-
// Elevated variant uses bg-white in light mode
|
|
60
|
-
expect(root.className).toContain('bg-white');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('respects elevation override', () => {
|
|
64
|
-
const { container } = render(<Card elevation={3}>x</Card>);
|
|
65
|
-
const root = container.firstElementChild!;
|
|
66
|
-
expect(root.className).toContain('shadow-md');
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('inherits visibleWhen from Box', () => {
|
|
70
|
-
const { container } = render(
|
|
71
|
-
<Card visibleWhen={() => false}>hidden</Card>
|
|
72
|
-
);
|
|
73
|
-
expect(container.firstChild).toBeNull();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('inherits access from Box (hide mode)', () => {
|
|
77
|
-
const { container } = render(
|
|
78
|
-
<RbacProvider policy={NO_ACCESS_POLICY} subject={guestSubject}>
|
|
79
|
-
<Card
|
|
80
|
-
access={{
|
|
81
|
-
resource: 'admin',
|
|
82
|
-
action: 'read',
|
|
83
|
-
onUnauthorized: 'hide',
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
admin-only
|
|
87
|
-
</Card>
|
|
88
|
-
</RbacProvider>
|
|
89
|
-
);
|
|
90
|
-
expect(container.firstChild).toBeNull();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('inherits access from Box (visible for authorized subject)', () => {
|
|
94
|
-
const { container } = render(
|
|
95
|
-
<RbacProvider policy={ADMIN_POLICY} subject={adminSubject}>
|
|
96
|
-
<Card
|
|
97
|
-
access={{
|
|
98
|
-
resource: 'admin',
|
|
99
|
-
action: 'read',
|
|
100
|
-
onUnauthorized: 'hide',
|
|
101
|
-
}}
|
|
102
|
-
>
|
|
103
|
-
shown
|
|
104
|
-
</Card>
|
|
105
|
-
</RbacProvider>
|
|
106
|
-
);
|
|
107
|
-
expect(container.firstChild).toBeTruthy();
|
|
108
|
-
expect(screen.getByText('shown')).toBeTruthy();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('<CardContent>', () => {
|
|
114
|
-
it('renders children inside a Box with default p=4', () => {
|
|
115
|
-
const { container } = render(
|
|
116
|
-
<CardContent>content</CardContent>
|
|
117
|
-
);
|
|
118
|
-
const root = container.firstElementChild!;
|
|
119
|
-
expect(root.className).toContain('p-4');
|
|
120
|
-
expect(screen.getByText('content')).toBeTruthy();
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('respects custom p value', () => {
|
|
124
|
-
const { container } = render(
|
|
125
|
-
<CardContent p={6}>spacious</CardContent>
|
|
126
|
-
);
|
|
127
|
-
const root = container.firstElementChild!;
|
|
128
|
-
expect(root.className).toContain('p-6');
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('respects p={0} for zero padding', () => {
|
|
132
|
-
const { container } = render(
|
|
133
|
-
<CardContent p={0}>flush</CardContent>
|
|
134
|
-
);
|
|
135
|
-
const root = container.firstElementChild!;
|
|
136
|
-
expect(root.className).toContain('p-0');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('appends className', () => {
|
|
140
|
-
const { container } = render(
|
|
141
|
-
<CardContent className="my-custom-content">x</CardContent>
|
|
142
|
-
);
|
|
143
|
-
const root = container.firstElementChild!;
|
|
144
|
-
expect(root.className).toContain('my-custom-content');
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe('<CardActionArea>', () => {
|
|
149
|
-
describe('rendering', () => {
|
|
150
|
-
it('renders as <button> by default', () => {
|
|
151
|
-
render(<CardActionArea>click me</CardActionArea>);
|
|
152
|
-
expect(screen.getByRole('button', { name: /click me/i })).toBeTruthy();
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('renders as the immediate child when asChild=true', () => {
|
|
156
|
-
const { container } = render(
|
|
157
|
-
<CardActionArea asChild>
|
|
158
|
-
<a href="/x" data-testid="anchor-child">link content</a>
|
|
159
|
-
</CardActionArea>
|
|
160
|
-
);
|
|
161
|
-
const anchor = container.querySelector('a[data-testid="anchor-child"]');
|
|
162
|
-
expect(anchor).toBeTruthy();
|
|
163
|
-
expect(container.querySelector('button')).toBeNull();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('applies base layout (block w-full)', () => {
|
|
167
|
-
const { container } = render(<CardActionArea>x</CardActionArea>);
|
|
168
|
-
const root = container.firstElementChild!;
|
|
169
|
-
expect(root.className).toContain('block');
|
|
170
|
-
expect(root.className).toContain('w-full');
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe('selected state', () => {
|
|
175
|
-
it('applies aria-pressed=true when selected', () => {
|
|
176
|
-
render(<CardActionArea selected>x</CardActionArea>);
|
|
177
|
-
expect(screen.getByRole('button').getAttribute('aria-pressed')).toBe('true');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('does NOT set aria-pressed when not selected', () => {
|
|
181
|
-
render(<CardActionArea>x</CardActionArea>);
|
|
182
|
-
expect(screen.getByRole('button').getAttribute('aria-pressed')).toBeNull();
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('applies primary ring class when selected', () => {
|
|
186
|
-
const { container } = render(<CardActionArea selected>x</CardActionArea>);
|
|
187
|
-
const btn = container.firstElementChild!;
|
|
188
|
-
expect(btn.className).toContain('ring-primary-500');
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('disabled state', () => {
|
|
193
|
-
it('respects explicit disabled prop', () => {
|
|
194
|
-
render(<CardActionArea disabled>x</CardActionArea>);
|
|
195
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
196
|
-
expect(btn.disabled).toBe(true);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('does NOT fire onClick when disabled', () => {
|
|
200
|
-
const onClick = vi.fn();
|
|
201
|
-
render(<CardActionArea disabled onClick={onClick}>x</CardActionArea>);
|
|
202
|
-
fireEvent.click(screen.getByRole('button'));
|
|
203
|
-
expect(onClick).not.toHaveBeenCalled();
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it('applies opacity-50 + cursor-not-allowed when disabled', () => {
|
|
207
|
-
const { container } = render(<CardActionArea disabled>x</CardActionArea>);
|
|
208
|
-
const btn = container.firstElementChild!;
|
|
209
|
-
expect(btn.className).toContain('opacity-50');
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
describe('click handler', () => {
|
|
214
|
-
it('fires onClick when clicked', () => {
|
|
215
|
-
const onClick = vi.fn();
|
|
216
|
-
render(<CardActionArea onClick={onClick}>x</CardActionArea>);
|
|
217
|
-
fireEvent.click(screen.getByRole('button'));
|
|
218
|
-
expect(onClick).toHaveBeenCalledTimes(1);
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
describe('access RBAC', () => {
|
|
223
|
-
it('hides when access.onUnauthorized=hide and subject lacks permission', () => {
|
|
224
|
-
const { container } = render(
|
|
225
|
-
<RbacProvider policy={NO_ACCESS_POLICY} subject={guestSubject}>
|
|
226
|
-
<CardActionArea
|
|
227
|
-
access={{
|
|
228
|
-
resource: 'admin',
|
|
229
|
-
action: 'read',
|
|
230
|
-
onUnauthorized: 'hide',
|
|
231
|
-
}}
|
|
232
|
-
>
|
|
233
|
-
admin-cta
|
|
234
|
-
</CardActionArea>
|
|
235
|
-
</RbacProvider>
|
|
236
|
-
);
|
|
237
|
-
expect(container.firstChild).toBeNull();
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('disables when access.onUnauthorized=disable', () => {
|
|
241
|
-
render(
|
|
242
|
-
<RbacProvider policy={NO_ACCESS_POLICY} subject={guestSubject}>
|
|
243
|
-
<CardActionArea
|
|
244
|
-
access={{
|
|
245
|
-
resource: 'admin',
|
|
246
|
-
action: 'read',
|
|
247
|
-
onUnauthorized: 'disable',
|
|
248
|
-
}}
|
|
249
|
-
>
|
|
250
|
-
disable-cta
|
|
251
|
-
</CardActionArea>
|
|
252
|
-
</RbacProvider>
|
|
253
|
-
);
|
|
254
|
-
const btn = screen.getByRole('button') as HTMLButtonElement;
|
|
255
|
-
expect(btn.disabled).toBe(true);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('renders normally for authorized subject', () => {
|
|
259
|
-
render(
|
|
260
|
-
<RbacProvider policy={ADMIN_POLICY} subject={adminSubject}>
|
|
261
|
-
<CardActionArea
|
|
262
|
-
access={{
|
|
263
|
-
resource: 'admin',
|
|
264
|
-
action: 'read',
|
|
265
|
-
onUnauthorized: 'hide',
|
|
266
|
-
}}
|
|
267
|
-
>
|
|
268
|
-
admin-cta
|
|
269
|
-
</CardActionArea>
|
|
270
|
-
</RbacProvider>
|
|
271
|
-
);
|
|
272
|
-
expect(screen.getByText('admin-cta')).toBeTruthy();
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
describe('visibleWhen', () => {
|
|
277
|
-
it('renders when predicate returns true', () => {
|
|
278
|
-
render(
|
|
279
|
-
<CardActionArea visibleWhen={() => true}>shown</CardActionArea>
|
|
280
|
-
);
|
|
281
|
-
expect(screen.getByText('shown')).toBeTruthy();
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('returns null when predicate returns false', () => {
|
|
285
|
-
const { container } = render(
|
|
286
|
-
<CardActionArea visibleWhen={() => false}>hidden</CardActionArea>
|
|
287
|
-
);
|
|
288
|
-
expect(container.firstChild).toBeNull();
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
});
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useContext } from 'react';
|
|
2
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
-
import { DashFormContext, useEngineVisibility } from '@dashforge/ui-core';
|
|
4
|
-
import { cn } from '../../utils/cn.js';
|
|
5
|
-
import { useAccessState } from '../../hooks/useAccessState.js';
|
|
6
|
-
import { Box } from '../Box/Box.js';
|
|
7
|
-
import type {
|
|
8
|
-
CardActionAreaProps,
|
|
9
|
-
CardContentProps,
|
|
10
|
-
CardProps,
|
|
11
|
-
} from './card.types.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* `<Card>` — opinionated surface preset over `<Box>`.
|
|
15
|
-
*
|
|
16
|
-
* Thin alias that pre-fills card-shaped Box defaults (`outlined`,
|
|
17
|
-
* `rounded='lg'`, `elevation=1`, no padding). Reads as `<Card>` in
|
|
18
|
-
* consumer code while reusing every Box affordance: surface variants,
|
|
19
|
-
* 7 intent colors, spacing scale, polymorphism, and the bridge
|
|
20
|
-
* integration (`access` + `visibleWhen`) retrofitted to Box in 1.1.0.
|
|
21
|
-
*
|
|
22
|
-
* Restricted variant axis: only `'outlined' | 'elevated' | 'plain'`.
|
|
23
|
-
* `'soft'` and `'solid'` are deliberately excluded — they belong to
|
|
24
|
-
* Box (as `<Alert>`-shaped callouts) and to banners, not to cards.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```tsx
|
|
28
|
-
* // Most common — outlined card with content padding via CardContent
|
|
29
|
-
* <Card>
|
|
30
|
-
* <CardContent>
|
|
31
|
-
* <Typography variant="h3">Title</Typography>
|
|
32
|
-
* <Typography variant="body">Body</Typography>
|
|
33
|
-
* </CardContent>
|
|
34
|
-
* </Card>
|
|
35
|
-
*
|
|
36
|
-
* // Elevated, clickable, gated by RBAC (inherits access from Box)
|
|
37
|
-
* <Card
|
|
38
|
-
* variant="elevated"
|
|
39
|
-
* elevation={2}
|
|
40
|
-
* access={{ resource: 'billing', action: 'read', onUnauthorized: 'hide' }}
|
|
41
|
-
* >
|
|
42
|
-
* <CardActionArea onClick={openBilling}>
|
|
43
|
-
* <CardContent>
|
|
44
|
-
* <Typography variant="h3">Revenue</Typography>
|
|
45
|
-
* </CardContent>
|
|
46
|
-
* </CardActionArea>
|
|
47
|
-
* </Card>
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export const Card = forwardRef<HTMLElement, CardProps>(function Card(
|
|
51
|
-
props,
|
|
52
|
-
ref
|
|
53
|
-
) {
|
|
54
|
-
const {
|
|
55
|
-
variant = 'outlined',
|
|
56
|
-
rounded = 'lg',
|
|
57
|
-
elevation = 1,
|
|
58
|
-
p = 0,
|
|
59
|
-
children,
|
|
60
|
-
...rest
|
|
61
|
-
} = props;
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<Box
|
|
65
|
-
ref={ref}
|
|
66
|
-
variant={variant}
|
|
67
|
-
rounded={rounded}
|
|
68
|
-
elevation={elevation}
|
|
69
|
-
p={p}
|
|
70
|
-
{...rest}
|
|
71
|
-
>
|
|
72
|
-
{children}
|
|
73
|
-
</Box>
|
|
74
|
-
);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
Card.displayName = 'Card';
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* `<CardContent>` — padded inner section of a Card.
|
|
81
|
-
*
|
|
82
|
-
* Semantic alias for an inner `<Box p={4}>`. The default padding step
|
|
83
|
-
* (4) maps to `--df-tw-spacing-4` (1rem) via the dashforgePreset,
|
|
84
|
-
* matching common card-content paddings across MUI / shadcn / Chakra.
|
|
85
|
-
* Override `p` to dial up/down per the spacing token scale.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```tsx
|
|
89
|
-
* <Card>
|
|
90
|
-
* <CardContent p={6}> {/* bigger inner padding *}/}
|
|
91
|
-
* <Typography variant="h3">Spacious card</Typography>
|
|
92
|
-
* </CardContent>
|
|
93
|
-
* </Card>
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
export function CardContent({
|
|
97
|
-
p = 4,
|
|
98
|
-
children,
|
|
99
|
-
className,
|
|
100
|
-
sx,
|
|
101
|
-
}: CardContentProps) {
|
|
102
|
-
return (
|
|
103
|
-
<Box p={p} sx={cn(className, sx as string | undefined)}>
|
|
104
|
-
{children}
|
|
105
|
-
</Box>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
CardContent.displayName = 'CardContent';
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* `<CardActionArea>` — clickable wrapper for Card content.
|
|
113
|
-
*
|
|
114
|
-
* Adds focus ring + hover tint + Radix Slot polymorphism. Renders as
|
|
115
|
-
* `<button type="button">` by default, or as the immediate child via
|
|
116
|
-
* `asChild` (typical pattern: wrap a router `<Link>`).
|
|
117
|
-
*
|
|
118
|
-
* Bridge integration is local — CardActionArea is an action trigger
|
|
119
|
-
* (not a surface), so it carries `access` + `visibleWhen` directly
|
|
120
|
-
* (rather than relying on the wrapping Card's props). This lets the
|
|
121
|
-
* consumer differentiate "the card is visible but not clickable" from
|
|
122
|
-
* "the card is not visible at all".
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* ```tsx
|
|
126
|
-
* // Card-as-CTA
|
|
127
|
-
* <Card>
|
|
128
|
-
* <CardActionArea onClick={navigate}>
|
|
129
|
-
* <CardContent>
|
|
130
|
-
* <Typography variant="h3">Open dashboard</Typography>
|
|
131
|
-
* <Typography variant="body">Hover to see the focus ring.</Typography>
|
|
132
|
-
* </CardContent>
|
|
133
|
-
* </CardActionArea>
|
|
134
|
-
* </Card>
|
|
135
|
-
*
|
|
136
|
-
* // Polymorphic — wrap a router Link
|
|
137
|
-
* <Card>
|
|
138
|
-
* <CardActionArea asChild>
|
|
139
|
-
* <Link to="/billing">
|
|
140
|
-
* <CardContent>
|
|
141
|
-
* <Typography variant="h3">Billing</Typography>
|
|
142
|
-
* </CardContent>
|
|
143
|
-
* </Link>
|
|
144
|
-
* </CardActionArea>
|
|
145
|
-
* </Card>
|
|
146
|
-
*
|
|
147
|
-
* // Selectable card (filter / option pattern)
|
|
148
|
-
* <CardActionArea
|
|
149
|
-
* selected={selected === 'monthly'}
|
|
150
|
-
* onClick={() => setSelected('monthly')}
|
|
151
|
-
* >
|
|
152
|
-
* <CardContent>Monthly plan</CardContent>
|
|
153
|
-
* </CardActionArea>
|
|
154
|
-
* ```
|
|
155
|
-
*/
|
|
156
|
-
export const CardActionArea = forwardRef<HTMLButtonElement, CardActionAreaProps>(
|
|
157
|
-
function CardActionArea(props, ref) {
|
|
158
|
-
const {
|
|
159
|
-
children,
|
|
160
|
-
asChild,
|
|
161
|
-
selected,
|
|
162
|
-
access,
|
|
163
|
-
visibleWhen,
|
|
164
|
-
disabled,
|
|
165
|
-
sx,
|
|
166
|
-
className,
|
|
167
|
-
onClick,
|
|
168
|
-
...rest
|
|
169
|
-
} = props;
|
|
170
|
-
|
|
171
|
-
// Bridge — both hooks called unconditionally (rules-of-hooks).
|
|
172
|
-
const bridge = useContext(DashFormContext);
|
|
173
|
-
const isVisible = useEngineVisibility(bridge?.engine, visibleWhen);
|
|
174
|
-
const accessState = useAccessState(access);
|
|
175
|
-
|
|
176
|
-
if (!isVisible || !accessState.visible) return null;
|
|
177
|
-
|
|
178
|
-
const isDisabled =
|
|
179
|
-
Boolean(disabled) || accessState.disabled || accessState.readonly;
|
|
180
|
-
|
|
181
|
-
// The action area must SPAN the parent Card so the entire surface
|
|
182
|
-
// is clickable. Includes focus ring, hover, and a subtle pressed
|
|
183
|
-
// tint via `data-pressed`. Token-driven via dashforgePreset.
|
|
184
|
-
const classes = cn(
|
|
185
|
-
'block w-full text-left',
|
|
186
|
-
'outline-none rounded-[inherit]',
|
|
187
|
-
'transition-colors',
|
|
188
|
-
// Hover — gentle bg tint on top of the card surface. Uses
|
|
189
|
-
// currentColor with 5% alpha so it composes with any Card
|
|
190
|
-
// variant/color without hardcoding.
|
|
191
|
-
'hover:bg-current/5',
|
|
192
|
-
// Focus ring — keyboard-navigable, primary tone, inset slightly
|
|
193
|
-
// so it traces the card's inherited radius.
|
|
194
|
-
'focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-1',
|
|
195
|
-
// Selected — adds a primary tone ring + soft tint so the card
|
|
196
|
-
// visually reads as "active option" without changing the parent
|
|
197
|
-
// Card's variant.
|
|
198
|
-
selected && 'ring-2 ring-primary-500 ring-offset-1 bg-primary-50/60 dark:bg-primary-950/40',
|
|
199
|
-
// Disabled — dims content and suppresses clicks.
|
|
200
|
-
isDisabled && 'opacity-50 cursor-not-allowed pointer-events-none',
|
|
201
|
-
sx,
|
|
202
|
-
className
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
|
206
|
-
if (isDisabled) return;
|
|
207
|
-
onClick?.(e);
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
if (asChild) {
|
|
211
|
-
return (
|
|
212
|
-
<Slot
|
|
213
|
-
ref={ref}
|
|
214
|
-
className={classes}
|
|
215
|
-
data-disabled={isDisabled || undefined}
|
|
216
|
-
aria-disabled={isDisabled || undefined}
|
|
217
|
-
aria-pressed={selected ? true : undefined}
|
|
218
|
-
onClick={handleClick}
|
|
219
|
-
>
|
|
220
|
-
{children}
|
|
221
|
-
</Slot>
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return (
|
|
226
|
-
<button
|
|
227
|
-
ref={ref}
|
|
228
|
-
type="button"
|
|
229
|
-
className={classes}
|
|
230
|
-
disabled={isDisabled}
|
|
231
|
-
aria-pressed={selected ? true : undefined}
|
|
232
|
-
onClick={handleClick}
|
|
233
|
-
{...rest}
|
|
234
|
-
>
|
|
235
|
-
{children}
|
|
236
|
-
</button>
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
CardActionArea.displayName = 'CardActionArea';
|