@12-apps/ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components-catalog.md +806 -0
- package/components-guidelines.md +347 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.js +77 -0
- package/package.json +247 -0
- package/src/__tests__/package-wiring.test.ts +37 -0
- package/src/__tests__/setup.ts +1 -0
- package/src/__tests__/social-login-button.test.tsx +186 -0
- package/src/__tests__/user-avatar.test.tsx +195 -0
- package/src/button.tsx +22 -0
- package/src/components/command/__tests__/command.test.tsx +112 -0
- package/src/components/data-display/Alert/Alert.md +209 -0
- package/src/components/data-display/Alert/Alert.stories.tsx +561 -0
- package/src/components/data-display/Alert/Alert.test.stories.tsx +709 -0
- package/src/components/data-display/Alert/Alert.tsx +449 -0
- package/src/components/data-display/Alert/Alert.types.ts +79 -0
- package/src/components/data-display/Alert/index.ts +2 -0
- package/src/components/data-display/AlertDialog/AlertDialog.md +408 -0
- package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +360 -0
- package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +753 -0
- package/src/components/data-display/AlertDialog/AlertDialog.tsx +273 -0
- package/src/components/data-display/AlertDialog/AlertDialog.types.ts +74 -0
- package/src/components/data-display/AlertDialog/index.ts +2 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +230 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +270 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +116 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.types.ts +70 -0
- package/src/components/data-display/AsyncStateContainer/index.ts +2 -0
- package/src/components/data-display/Avatar/Avatar.md +568 -0
- package/src/components/data-display/Avatar/Avatar.stories.tsx +718 -0
- package/src/components/data-display/Avatar/Avatar.test.stories.tsx +820 -0
- package/src/components/data-display/Avatar/Avatar.tsx +507 -0
- package/src/components/data-display/Avatar/Avatar.types.ts +88 -0
- package/src/components/data-display/Avatar/index.ts +2 -0
- package/src/components/data-display/Badge/Badge.md +469 -0
- package/src/components/data-display/Badge/Badge.stories.tsx +1136 -0
- package/src/components/data-display/Badge/Badge.test.stories.tsx +1193 -0
- package/src/components/data-display/Badge/Badge.tsx +606 -0
- package/src/components/data-display/Badge/Badge.types.ts +118 -0
- package/src/components/data-display/Badge/index.ts +2 -0
- package/src/components/data-display/Banner/Banner.stories.tsx +524 -0
- package/src/components/data-display/Banner/Banner.test.stories.tsx +503 -0
- package/src/components/data-display/Banner/Banner.tsx +350 -0
- package/src/components/data-display/Banner/Banner.types.ts +41 -0
- package/src/components/data-display/Banner/banner.md +141 -0
- package/src/components/data-display/Banner/index.ts +2 -0
- package/src/components/data-display/Carousel/Carousel.md +815 -0
- package/src/components/data-display/Carousel/Carousel.stories.tsx +607 -0
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +691 -0
- package/src/components/data-display/Carousel/Carousel.tsx +765 -0
- package/src/components/data-display/Carousel/Carousel.types.ts +79 -0
- package/src/components/data-display/Carousel/index.ts +8 -0
- package/src/components/data-display/Chart/Chart.md +352 -0
- package/src/components/data-display/Chart/Chart.stories.tsx +568 -0
- package/src/components/data-display/Chart/Chart.test.stories.tsx +174 -0
- package/src/components/data-display/Chart/Chart.tsx +520 -0
- package/src/components/data-display/Chart/Chart.types.ts +65 -0
- package/src/components/data-display/Chart/index.ts +2 -0
- package/src/components/data-display/Chip/Chip.stories.tsx +251 -0
- package/src/components/data-display/Chip/Chip.test.stories.tsx +263 -0
- package/src/components/data-display/Chip/Chip.tsx +134 -0
- package/src/components/data-display/Chip/Chip.types.ts +51 -0
- package/src/components/data-display/Chip/chip.md +395 -0
- package/src/components/data-display/Chip/index.ts +2 -0
- package/src/components/data-display/DataGrid/DataGrid.md +602 -0
- package/src/components/data-display/DataGrid/DataGrid.stories.tsx +515 -0
- package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +659 -0
- package/src/components/data-display/DataGrid/DataGrid.tsx +743 -0
- package/src/components/data-display/DataGrid/DataGrid.types.ts +171 -0
- package/src/components/data-display/DataGrid/index.ts +21 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.tsx +197 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.types.ts +46 -0
- package/src/components/data-display/DateTimeDisplay/index.ts +2 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.md +226 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +254 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.tsx +100 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.types.ts +1 -0
- package/src/components/data-display/DescriptionItem/index.ts +2 -0
- package/src/components/data-display/EmptyState/EmptyState.md +265 -0
- package/src/components/data-display/EmptyState/EmptyState.stories.tsx +282 -0
- package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +441 -0
- package/src/components/data-display/EmptyState/EmptyState.tsx +180 -0
- package/src/components/data-display/EmptyState/EmptyState.types.ts +31 -0
- package/src/components/data-display/EmptyState/index.ts +2 -0
- package/src/components/data-display/ErrorState/ErrorState.stories.tsx +110 -0
- package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +133 -0
- package/src/components/data-display/ErrorState/ErrorState.tsx +118 -0
- package/src/components/data-display/ErrorState/ErrorState.types.ts +45 -0
- package/src/components/data-display/ErrorState/index.ts +2 -0
- package/src/components/data-display/HoverCard/HoverCard.md +389 -0
- package/src/components/data-display/HoverCard/HoverCard.stories.tsx +648 -0
- package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +929 -0
- package/src/components/data-display/HoverCard/HoverCard.tsx +657 -0
- package/src/components/data-display/HoverCard/HoverCard.types.ts +116 -0
- package/src/components/data-display/HoverCard/index.ts +2 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.md +532 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +411 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +245 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.types.ts +64 -0
- package/src/components/data-display/InteractiveTooltip/index.ts +2 -0
- package/src/components/data-display/LazyImage/LazyImage.md +356 -0
- package/src/components/data-display/LazyImage/LazyImage.stories.tsx +387 -0
- package/src/components/data-display/LazyImage/LazyImage.tsx +323 -0
- package/src/components/data-display/LazyImage/LazyImage.types.ts +205 -0
- package/src/components/data-display/LazyImage/index.ts +2 -0
- package/src/components/data-display/Lightbox/Lightbox.stories.tsx +315 -0
- package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +605 -0
- package/src/components/data-display/Lightbox/Lightbox.tsx +666 -0
- package/src/components/data-display/Lightbox/Lightbox.types.ts +49 -0
- package/src/components/data-display/Lightbox/index.ts +2 -0
- package/src/components/data-display/Lightbox/lightbox.md +298 -0
- package/src/components/data-display/LoadingState/LoadingState.stories.tsx +124 -0
- package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +99 -0
- package/src/components/data-display/LoadingState/LoadingState.tsx +103 -0
- package/src/components/data-display/LoadingState/LoadingState.types.ts +37 -0
- package/src/components/data-display/LoadingState/index.ts +2 -0
- package/src/components/data-display/MapPreview/MapPreview.md +154 -0
- package/src/components/data-display/MapPreview/MapPreview.stories.tsx +458 -0
- package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +390 -0
- package/src/components/data-display/MapPreview/MapPreview.tsx +922 -0
- package/src/components/data-display/MapPreview/MapPreview.types.ts +56 -0
- package/src/components/data-display/MapPreview/index.ts +2 -0
- package/src/components/data-display/Popover/Popover.md +245 -0
- package/src/components/data-display/Popover/Popover.stories.tsx +295 -0
- package/src/components/data-display/Popover/Popover.test.stories.tsx +1168 -0
- package/src/components/data-display/Popover/Popover.tsx +132 -0
- package/src/components/data-display/Popover/Popover.types.ts +33 -0
- package/src/components/data-display/Popover/index.ts +2 -0
- package/src/components/data-display/Progress/Progress.md +450 -0
- package/src/components/data-display/Progress/Progress.stories.tsx +481 -0
- package/src/components/data-display/Progress/Progress.test.stories.tsx +2070 -0
- package/src/components/data-display/Progress/Progress.tsx +332 -0
- package/src/components/data-display/Progress/Progress.types.ts +61 -0
- package/src/components/data-display/Progress/index.ts +2 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.md +108 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +160 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +190 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +224 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +101 -0
- package/src/components/data-display/SectionOnboarding/index.ts +7 -0
- package/src/components/data-display/Sheet/Sheet.md +475 -0
- package/src/components/data-display/Sheet/Sheet.stories.tsx +883 -0
- package/src/components/data-display/Sheet/Sheet.test.stories.tsx +1101 -0
- package/src/components/data-display/Sheet/Sheet.tsx +978 -0
- package/src/components/data-display/Sheet/Sheet.types.ts +93 -0
- package/src/components/data-display/Sheet/index.ts +8 -0
- package/src/components/data-display/Stepper/Stepper.md +542 -0
- package/src/components/data-display/Stepper/Stepper.stories.tsx +540 -0
- package/src/components/data-display/Stepper/Stepper.test.stories.tsx +607 -0
- package/src/components/data-display/Stepper/Stepper.tsx +328 -0
- package/src/components/data-display/Stepper/Stepper.types.ts +97 -0
- package/src/components/data-display/Stepper/index.ts +2 -0
- package/src/components/data-display/Table/Table.md +243 -0
- package/src/components/data-display/Table/Table.stories.tsx +801 -0
- package/src/components/data-display/Table/Table.test.stories.tsx +369 -0
- package/src/components/data-display/Table/Table.tsx +831 -0
- package/src/components/data-display/Table/Table.types.ts +335 -0
- package/src/components/data-display/Table/index.ts +2 -0
- package/src/components/data-display/Timeline/Timeline.md +201 -0
- package/src/components/data-display/Timeline/Timeline.stories.tsx +444 -0
- package/src/components/data-display/Timeline/Timeline.test.stories.tsx +944 -0
- package/src/components/data-display/Timeline/Timeline.tsx +348 -0
- package/src/components/data-display/Timeline/Timeline.types.ts +26 -0
- package/src/components/data-display/Timeline/index.ts +2 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.md +162 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +475 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +734 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +399 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +19 -0
- package/src/components/data-display/TimingDiagram/index.ts +2 -0
- package/src/components/data-display/Tooltip/Tooltip.md +397 -0
- package/src/components/data-display/Tooltip/Tooltip.stories.tsx +465 -0
- package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +1168 -0
- package/src/components/data-display/Tooltip/Tooltip.tsx +161 -0
- package/src/components/data-display/Tooltip/Tooltip.types.ts +33 -0
- package/src/components/data-display/Tooltip/index.ts +2 -0
- package/src/components/data-display/index.ts +29 -0
- package/src/components/feedback/Dialog/Dialog.md +527 -0
- package/src/components/feedback/Dialog/Dialog.stories.tsx +833 -0
- package/src/components/feedback/Dialog/Dialog.styles.ts +171 -0
- package/src/components/feedback/Dialog/Dialog.test.stories.tsx +955 -0
- package/src/components/feedback/Dialog/Dialog.tsx +256 -0
- package/src/components/feedback/Dialog/Dialog.types.ts +46 -0
- package/src/components/feedback/Dialog/index.ts +9 -0
- package/src/components/feedback/Modal/Modal.md +629 -0
- package/src/components/feedback/Modal/Modal.stories.tsx +765 -0
- package/src/components/feedback/Modal/Modal.test.stories.tsx +251 -0
- package/src/components/feedback/Modal/Modal.tsx +279 -0
- package/src/components/feedback/Modal/Modal.types.ts +26 -0
- package/src/components/feedback/Modal/index.ts +7 -0
- package/src/components/feedback/Sonner/Sonner.stories.tsx +698 -0
- package/src/components/feedback/Sonner/Sonner.test.stories.tsx +896 -0
- package/src/components/feedback/Sonner/Sonner.tsx +493 -0
- package/src/components/feedback/Sonner/Sonner.types.ts +65 -0
- package/src/components/feedback/Sonner/index.ts +8 -0
- package/src/components/feedback/StackedModal/StackedModal.md +273 -0
- package/src/components/feedback/StackedModal/StackedModal.stories.tsx +1785 -0
- package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +975 -0
- package/src/components/feedback/StackedModal/StackedModal.tsx +664 -0
- package/src/components/feedback/StackedModal/StackedModal.types.ts +70 -0
- package/src/components/feedback/StackedModal/index.ts +11 -0
- package/src/components/feedback/Toast/Toast.md +547 -0
- package/src/components/feedback/Toast/Toast.stories.tsx +548 -0
- package/src/components/feedback/Toast/Toast.test.stories.tsx +834 -0
- package/src/components/feedback/Toast/Toast.tsx +279 -0
- package/src/components/feedback/Toast/Toast.types.ts +59 -0
- package/src/components/feedback/Toast/index.ts +8 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.md +610 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +691 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +634 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +554 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +30 -0
- package/src/components/feedback/TutorialOverlay/index.ts +2 -0
- package/src/components/feedback/index.ts +6 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.md +633 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +663 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +723 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.tsx +836 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +37 -0
- package/src/components/form/AddressAutocomplete/index.ts +2 -0
- package/src/components/form/Autocomplete/Autocomplete.helpers.ts +115 -0
- package/src/components/form/Autocomplete/Autocomplete.keys.ts +134 -0
- package/src/components/form/Autocomplete/Autocomplete.parts.tsx +337 -0
- package/src/components/form/Autocomplete/Autocomplete.stories.tsx +715 -0
- package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +825 -0
- package/src/components/form/Autocomplete/Autocomplete.tsx +166 -0
- package/src/components/form/Autocomplete/Autocomplete.types.ts +116 -0
- package/src/components/form/Autocomplete/autocomplete.md +789 -0
- package/src/components/form/Autocomplete/index.ts +8 -0
- package/src/components/form/Autocomplete/useAutocomplete.ts +311 -0
- package/src/components/form/Button/Button.md +411 -0
- package/src/components/form/Button/Button.stories.tsx +362 -0
- package/src/components/form/Button/Button.test.stories.tsx +603 -0
- package/src/components/form/Button/Button.tsx +326 -0
- package/src/components/form/Button/Button.types.ts +74 -0
- package/src/components/form/Button/index.ts +2 -0
- package/src/components/form/Calendar/Calendar.md +807 -0
- package/src/components/form/Calendar/Calendar.stories.tsx +349 -0
- package/src/components/form/Calendar/Calendar.test.stories.tsx +465 -0
- package/src/components/form/Calendar/Calendar.tsx +571 -0
- package/src/components/form/Calendar/Calendar.types.ts +81 -0
- package/src/components/form/Calendar/index.ts +11 -0
- package/src/components/form/Checkbox/Checkbox.md +200 -0
- package/src/components/form/Checkbox/Checkbox.stories.tsx +265 -0
- package/src/components/form/Checkbox/Checkbox.test.stories.tsx +181 -0
- package/src/components/form/Checkbox/Checkbox.tsx +170 -0
- package/src/components/form/Checkbox/Checkbox.types.ts +20 -0
- package/src/components/form/Checkbox/index.ts +2 -0
- package/src/components/form/CodeEditor/CodeEditor.md +350 -0
- package/src/components/form/CodeEditor/CodeEditor.stories.tsx +871 -0
- package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +575 -0
- package/src/components/form/CodeEditor/CodeEditor.tsx +415 -0
- package/src/components/form/CodeEditor/CodeEditor.types.ts +38 -0
- package/src/components/form/CodeEditor/index.ts +2 -0
- package/src/components/form/Command/Command.md +468 -0
- package/src/components/form/Command/Command.stories.tsx +580 -0
- package/src/components/form/Command/Command.test.stories.tsx +215 -0
- package/src/components/form/Command/Command.tsx +545 -0
- package/src/components/form/Command/Command.types.ts +116 -0
- package/src/components/form/Command/index.ts +12 -0
- package/src/components/form/CreatableSelect/CreatableSelect.md +114 -0
- package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +112 -0
- package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +134 -0
- package/src/components/form/CreatableSelect/CreatableSelect.tsx +149 -0
- package/src/components/form/CreatableSelect/CreatableSelect.types.ts +37 -0
- package/src/components/form/CreatableSelect/index.ts +2 -0
- package/src/components/form/Form/Form.md +325 -0
- package/src/components/form/Form/Form.stories.tsx +687 -0
- package/src/components/form/Form/Form.test.stories.tsx +601 -0
- package/src/components/form/Form/Form.tsx +136 -0
- package/src/components/form/Form/Form.types.ts +42 -0
- package/src/components/form/Form/index.ts +8 -0
- package/src/components/form/Input/Input.md +252 -0
- package/src/components/form/Input/Input.stories.tsx +256 -0
- package/src/components/form/Input/Input.test.stories.tsx +1184 -0
- package/src/components/form/Input/Input.tsx +263 -0
- package/src/components/form/Input/Input.types.ts +24 -0
- package/src/components/form/Input/index.ts +2 -0
- package/src/components/form/InputOTP/InputOTP.md +419 -0
- package/src/components/form/InputOTP/InputOTP.stories.tsx +774 -0
- package/src/components/form/InputOTP/InputOTP.test.stories.tsx +596 -0
- package/src/components/form/InputOTP/InputOTP.tsx +231 -0
- package/src/components/form/InputOTP/InputOTP.types.ts +68 -0
- package/src/components/form/InputOTP/index.ts +2 -0
- package/src/components/form/Label/Label.md +426 -0
- package/src/components/form/Label/Label.stories.tsx +473 -0
- package/src/components/form/Label/Label.test.stories.tsx +909 -0
- package/src/components/form/Label/Label.tsx +367 -0
- package/src/components/form/Label/Label.types.ts +35 -0
- package/src/components/form/Label/index.ts +2 -0
- package/src/components/form/Menubar/Menubar.md +275 -0
- package/src/components/form/Menubar/Menubar.stories.tsx +472 -0
- package/src/components/form/Menubar/Menubar.test.stories.tsx +588 -0
- package/src/components/form/Menubar/Menubar.tsx +467 -0
- package/src/components/form/Menubar/Menubar.types.ts +71 -0
- package/src/components/form/Menubar/index.ts +8 -0
- package/src/components/form/PasswordStrength/PasswordStrength.md +139 -0
- package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +562 -0
- package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +327 -0
- package/src/components/form/PasswordStrength/PasswordStrength.tsx +419 -0
- package/src/components/form/PasswordStrength/PasswordStrength.types.ts +18 -0
- package/src/components/form/PasswordStrength/index.ts +2 -0
- package/src/components/form/PhoneInput/PhoneInput.md +578 -0
- package/src/components/form/PhoneInput/PhoneInput.stories.tsx +495 -0
- package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +666 -0
- package/src/components/form/PhoneInput/PhoneInput.tsx +376 -0
- package/src/components/form/PhoneInput/PhoneInput.types.ts +25 -0
- package/src/components/form/PhoneInput/index.ts +2 -0
- package/src/components/form/RadioGroup/RadioGroup.md +477 -0
- package/src/components/form/RadioGroup/RadioGroup.stories.tsx +518 -0
- package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +685 -0
- package/src/components/form/RadioGroup/RadioGroup.tsx +664 -0
- package/src/components/form/RadioGroup/RadioGroup.types.ts +82 -0
- package/src/components/form/RadioGroup/index.ts +2 -0
- package/src/components/form/RichTextEditor/RichTextEditor.md +710 -0
- package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +261 -0
- package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +498 -0
- package/src/components/form/RichTextEditor/RichTextEditor.tsx +468 -0
- package/src/components/form/RichTextEditor/RichTextEditor.types.ts +72 -0
- package/src/components/form/RichTextEditor/index.ts +2 -0
- package/src/components/form/SearchPalette/SearchPalette.md +69 -0
- package/src/components/form/SearchPalette/SearchPalette.parts.tsx +358 -0
- package/src/components/form/SearchPalette/SearchPalette.stories.tsx +135 -0
- package/src/components/form/SearchPalette/SearchPalette.tsx +141 -0
- package/src/components/form/SearchPalette/SearchPalette.types.ts +82 -0
- package/src/components/form/SearchPalette/index.ts +7 -0
- package/src/components/form/Select/Select.md +254 -0
- package/src/components/form/Select/Select.stories.tsx +364 -0
- package/src/components/form/Select/Select.test.stories.tsx +977 -0
- package/src/components/form/Select/Select.tsx +239 -0
- package/src/components/form/Select/Select.types.ts +57 -0
- package/src/components/form/Select/index.ts +2 -0
- package/src/components/form/Slider/Slider.md +326 -0
- package/src/components/form/Slider/Slider.stories.tsx +418 -0
- package/src/components/form/Slider/Slider.test.stories.tsx +1044 -0
- package/src/components/form/Slider/Slider.tsx +374 -0
- package/src/components/form/Slider/Slider.types.ts +113 -0
- package/src/components/form/Slider/index.ts +2 -0
- package/src/components/form/Switch/Switch.md +565 -0
- package/src/components/form/Switch/Switch.stories.tsx +697 -0
- package/src/components/form/Switch/Switch.test.stories.tsx +597 -0
- package/src/components/form/Switch/Switch.tsx +578 -0
- package/src/components/form/Switch/Switch.types.ts +130 -0
- package/src/components/form/Switch/index.ts +2 -0
- package/src/components/form/Textarea/Textarea.stories.tsx +473 -0
- package/src/components/form/Textarea/Textarea.test.stories.tsx +708 -0
- package/src/components/form/Textarea/Textarea.tsx +678 -0
- package/src/components/form/Textarea/Textarea.types.ts +84 -0
- package/src/components/form/Textarea/index.ts +2 -0
- package/src/components/form/Toggle/Toggle.md +234 -0
- package/src/components/form/Toggle/Toggle.stories.tsx +638 -0
- package/src/components/form/Toggle/Toggle.test.stories.tsx +1167 -0
- package/src/components/form/Toggle/Toggle.tsx +265 -0
- package/src/components/form/Toggle/Toggle.types.ts +79 -0
- package/src/components/form/Toggle/index.ts +2 -0
- package/src/components/form/ToggleGroup/ToggleGroup.md +329 -0
- package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +617 -0
- package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +918 -0
- package/src/components/form/ToggleGroup/ToggleGroup.tsx +129 -0
- package/src/components/form/ToggleGroup/ToggleGroup.types.ts +53 -0
- package/src/components/form/ToggleGroup/index.ts +2 -0
- package/src/components/form/UploadButton/UploadButton.md +44 -0
- package/src/components/form/UploadButton/UploadButton.stories.tsx +366 -0
- package/src/components/form/UploadButton/UploadButton.test.stories.tsx +454 -0
- package/src/components/form/UploadButton/UploadButton.tsx +312 -0
- package/src/components/form/UploadButton/UploadButton.types.ts +58 -0
- package/src/components/form/UploadButton/index.ts +2 -0
- package/src/components/form/index.ts +25 -0
- package/src/components/form/total-form/Fields/SelectField.tsx +57 -0
- package/src/components/form/total-form/Fields/TextField.tsx +58 -0
- package/src/components/form/total-form/Fields/index.ts +4 -0
- package/src/components/form/total-form/FormContainer.tsx +104 -0
- package/src/components/form/total-form/FormContext.tsx +38 -0
- package/src/components/form/total-form/FormErrorSnackbar.tsx +35 -0
- package/src/components/form/total-form/SubmitButton.tsx +27 -0
- package/src/components/form/total-form/index.ts +12 -0
- package/src/components/form/total-form/total-form.test.tsx +97 -0
- package/src/components/index.ts +7 -0
- package/src/components/layout/Accordion/Accordion.md +725 -0
- package/src/components/layout/Accordion/Accordion.stories.tsx +690 -0
- package/src/components/layout/Accordion/Accordion.test.stories.tsx +1362 -0
- package/src/components/layout/Accordion/Accordion.tsx +242 -0
- package/src/components/layout/Accordion/Accordion.types.ts +32 -0
- package/src/components/layout/Accordion/index.ts +8 -0
- package/src/components/layout/Card/Card.md +533 -0
- package/src/components/layout/Card/Card.stories.tsx +593 -0
- package/src/components/layout/Card/Card.test.stories.tsx +1134 -0
- package/src/components/layout/Card/Card.tsx +404 -0
- package/src/components/layout/Card/Card.types.ts +57 -0
- package/src/components/layout/Card/index.ts +8 -0
- package/src/components/layout/Collapsible/Collapsible.md +135 -0
- package/src/components/layout/Collapsible/Collapsible.stories.tsx +180 -0
- package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +304 -0
- package/src/components/layout/Collapsible/Collapsible.tsx +198 -0
- package/src/components/layout/Collapsible/Collapsible.types.ts +35 -0
- package/src/components/layout/Collapsible/index.ts +6 -0
- package/src/components/layout/Container/Container.md +420 -0
- package/src/components/layout/Container/Container.stories.tsx +557 -0
- package/src/components/layout/Container/Container.test.stories.tsx +750 -0
- package/src/components/layout/Container/Container.tsx +72 -0
- package/src/components/layout/Container/Container.types.ts +11 -0
- package/src/components/layout/Container/index.ts +2 -0
- package/src/components/layout/ContentToolbar/ColumnsMenu.tsx +99 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.md +75 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +129 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +251 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +108 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +229 -0
- package/src/components/layout/ContentToolbar/FilterTrigger.tsx +71 -0
- package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +297 -0
- package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +334 -0
- package/src/components/layout/ContentToolbar/SortByDropdown.tsx +213 -0
- package/src/components/layout/ContentToolbar/ViewSelector.tsx +98 -0
- package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +39 -0
- package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +110 -0
- package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +99 -0
- package/src/components/layout/ContentToolbar/index.ts +24 -0
- package/src/components/layout/ContentToolbar/tests.md +42 -0
- package/src/components/layout/ContentToolbar/track.md +41 -0
- package/src/components/layout/Dashboard/Dashboard.md +71 -0
- package/src/components/layout/Dashboard/Dashboard.stories.tsx +104 -0
- package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +164 -0
- package/src/components/layout/Dashboard/Dashboard.tsx +297 -0
- package/src/components/layout/Dashboard/Dashboard.types.ts +157 -0
- package/src/components/layout/Dashboard/DashboardContext.tsx +47 -0
- package/src/components/layout/Dashboard/DashboardParts.tsx +216 -0
- package/src/components/layout/Dashboard/index.ts +18 -0
- package/src/components/layout/Dashboard/tests.md +46 -0
- package/src/components/layout/Dashboard/track.md +50 -0
- package/src/components/layout/Drawer/Drawer.md +479 -0
- package/src/components/layout/Drawer/Drawer.stories.tsx +660 -0
- package/src/components/layout/Drawer/Drawer.test.stories.tsx +1339 -0
- package/src/components/layout/Drawer/Drawer.tsx +150 -0
- package/src/components/layout/Drawer/Drawer.types.ts +34 -0
- package/src/components/layout/Drawer/index.ts +2 -0
- package/src/components/layout/Resizable/Resizable.md +308 -0
- package/src/components/layout/Resizable/Resizable.stories.tsx +1039 -0
- package/src/components/layout/Resizable/Resizable.test.stories.tsx +750 -0
- package/src/components/layout/Resizable/Resizable.tsx +190 -0
- package/src/components/layout/Resizable/Resizable.types.ts +34 -0
- package/src/components/layout/Resizable/index.ts +2 -0
- package/src/components/layout/ScrollArea/ScrollArea.md +122 -0
- package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +651 -0
- package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +619 -0
- package/src/components/layout/ScrollArea/ScrollArea.tsx +449 -0
- package/src/components/layout/ScrollArea/ScrollArea.types.ts +80 -0
- package/src/components/layout/ScrollArea/index.ts +7 -0
- package/src/components/layout/Separator/Separator.stories.tsx +563 -0
- package/src/components/layout/Separator/Separator.test.stories.tsx +527 -0
- package/src/components/layout/Separator/Separator.tsx +187 -0
- package/src/components/layout/Separator/Separator.types.ts +17 -0
- package/src/components/layout/Separator/index.ts +2 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.md +139 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.parts.tsx +357 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +194 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +175 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.tsx +69 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.types.ts +61 -0
- package/src/components/layout/SettingsLayout/index.ts +6 -0
- package/src/components/layout/Sidebar/Sidebar.md +367 -0
- package/src/components/layout/Sidebar/Sidebar.stories.tsx +611 -0
- package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +1326 -0
- package/src/components/layout/Sidebar/Sidebar.tsx +131 -0
- package/src/components/layout/Sidebar/Sidebar.types.ts +30 -0
- package/src/components/layout/Sidebar/index.ts +7 -0
- package/src/components/layout/Skeleton/Skeleton.md +240 -0
- package/src/components/layout/Skeleton/Skeleton.stories.tsx +689 -0
- package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +521 -0
- package/src/components/layout/Skeleton/Skeleton.tsx +166 -0
- package/src/components/layout/Skeleton/Skeleton.types.ts +19 -0
- package/src/components/layout/Skeleton/index.ts +2 -0
- package/src/components/layout/Spacer/Spacer.md +84 -0
- package/src/components/layout/Spacer/Spacer.stories.tsx +502 -0
- package/src/components/layout/Spacer/Spacer.test.stories.tsx +472 -0
- package/src/components/layout/Spacer/Spacer.tsx +68 -0
- package/src/components/layout/Spacer/Spacer.types.ts +12 -0
- package/src/components/layout/Spacer/index.ts +2 -0
- package/src/components/layout/TableFilter/TableFilter.md +55 -0
- package/src/components/layout/TableFilter/TableFilter.stories.tsx +82 -0
- package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +87 -0
- package/src/components/layout/TableFilter/TableFilter.tsx +383 -0
- package/src/components/layout/TableFilter/TableFilter.types.ts +87 -0
- package/src/components/layout/TableFilter/TableFilterContext.tsx +29 -0
- package/src/components/layout/TableFilter/index.ts +15 -0
- package/src/components/layout/TableFilter/tests.md +37 -0
- package/src/components/layout/TableFilter/track.md +36 -0
- package/src/components/layout/index.ts +14 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.md +558 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +640 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +1007 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +516 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +132 -0
- package/src/components/navigation/Breadcrumbs/index.ts +2 -0
- package/src/components/navigation/CommandPalette/CommandPalette.md +201 -0
- package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +384 -0
- package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +437 -0
- package/src/components/navigation/CommandPalette/CommandPalette.tsx +434 -0
- package/src/components/navigation/CommandPalette/CommandPalette.types.ts +25 -0
- package/src/components/navigation/CommandPalette/index.ts +2 -0
- package/src/components/navigation/ContextMenu/ContextMenu.md +535 -0
- package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +611 -0
- package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +850 -0
- package/src/components/navigation/ContextMenu/ContextMenu.tsx +254 -0
- package/src/components/navigation/ContextMenu/ContextMenu.types.ts +96 -0
- package/src/components/navigation/ContextMenu/index.ts +2 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.md +514 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +580 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +660 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +305 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.types.ts +116 -0
- package/src/components/navigation/DropdownMenu/index.ts +2 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.md +580 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +874 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.types.ts +135 -0
- package/src/components/navigation/NavigationMenu/index.ts +2 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +518 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +931 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +503 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +455 -0
- package/src/components/navigation/Pagination/Pagination.md +699 -0
- package/src/components/navigation/Pagination/Pagination.stories.tsx +604 -0
- package/src/components/navigation/Pagination/Pagination.test.stories.tsx +520 -0
- package/src/components/navigation/Pagination/Pagination.tsx +356 -0
- package/src/components/navigation/Pagination/Pagination.types.ts +129 -0
- package/src/components/navigation/Pagination/index.ts +2 -0
- package/src/components/navigation/Tabs/Tabs.md +774 -0
- package/src/components/navigation/Tabs/Tabs.stories.tsx +1006 -0
- package/src/components/navigation/Tabs/Tabs.test.stories.tsx +1225 -0
- package/src/components/navigation/Tabs/Tabs.tsx +433 -0
- package/src/components/navigation/Tabs/Tabs.types.ts +239 -0
- package/src/components/navigation/Tabs/index.ts +2 -0
- package/src/components/navigation/index.ts +7 -0
- package/src/components/typography/Blockquote/Blockquote.md +130 -0
- package/src/components/typography/Blockquote/Blockquote.stories.tsx +359 -0
- package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +432 -0
- package/src/components/typography/Blockquote/Blockquote.tsx +166 -0
- package/src/components/typography/Blockquote/Blockquote.types.ts +11 -0
- package/src/components/typography/Blockquote/index.ts +2 -0
- package/src/components/typography/Code/Code.md +182 -0
- package/src/components/typography/Code/Code.stories.tsx +686 -0
- package/src/components/typography/Code/Code.test.stories.tsx +703 -0
- package/src/components/typography/Code/Code.tsx +228 -0
- package/src/components/typography/Code/Code.types.ts +12 -0
- package/src/components/typography/Code/index.ts +2 -0
- package/src/components/typography/Heading/Heading.md +143 -0
- package/src/components/typography/Heading/Heading.stories.tsx +451 -0
- package/src/components/typography/Heading/Heading.test.stories.tsx +830 -0
- package/src/components/typography/Heading/Heading.tsx +178 -0
- package/src/components/typography/Heading/Heading.types.ts +11 -0
- package/src/components/typography/Heading/index.ts +2 -0
- package/src/components/typography/Paragraph/Paragraph.md +80 -0
- package/src/components/typography/Paragraph/Paragraph.stories.tsx +280 -0
- package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +238 -0
- package/src/components/typography/Paragraph/Paragraph.tsx +99 -0
- package/src/components/typography/Paragraph/Paragraph.types.ts +10 -0
- package/src/components/typography/Paragraph/index.ts +2 -0
- package/src/components/typography/Text/Text.md +129 -0
- package/src/components/typography/Text/Text.stories.tsx +359 -0
- package/src/components/typography/Text/Text.test.stories.tsx +762 -0
- package/src/components/typography/Text/Text.tsx +159 -0
- package/src/components/typography/Text/Text.types.ts +15 -0
- package/src/components/typography/Text/index.ts +2 -0
- package/src/components/typography/index.ts +5 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.md +359 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +947 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +596 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.tsx +595 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.types.ts +98 -0
- package/src/components/utility/AnimatedIcon/index.ts +2 -0
- package/src/components/utility/AspectRatio/AspectRatio.md +200 -0
- package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +414 -0
- package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +859 -0
- package/src/components/utility/AspectRatio/AspectRatio.tsx +76 -0
- package/src/components/utility/AspectRatio/AspectRatio.types.ts +13 -0
- package/src/components/utility/AspectRatio/index.ts +2 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.md +531 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +620 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +358 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +204 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +39 -0
- package/src/components/utility/InfiniteScroll/index.ts +6 -0
- package/src/components/utility/Portal/Portal.button-container.example.tsx +99 -0
- package/src/components/utility/Portal/Portal.md +593 -0
- package/src/components/utility/Portal/Portal.stories.tsx +340 -0
- package/src/components/utility/Portal/Portal.test.stories.tsx +2086 -0
- package/src/components/utility/Portal/Portal.tsx +39 -0
- package/src/components/utility/Portal/Portal.types.ts +7 -0
- package/src/components/utility/Portal/index.ts +2 -0
- package/src/components/utility/Transition/Transition.md +684 -0
- package/src/components/utility/Transition/Transition.stories.tsx +493 -0
- package/src/components/utility/Transition/Transition.test.stories.tsx +854 -0
- package/src/components/utility/Transition/Transition.tsx +140 -0
- package/src/components/utility/Transition/Transition.types.ts +14 -0
- package/src/components/utility/Transition/index.ts +6 -0
- package/src/components/utility/VirtualList/VirtualList.md +520 -0
- package/src/components/utility/VirtualList/VirtualList.stories.tsx +1073 -0
- package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +1074 -0
- package/src/components/utility/VirtualList/VirtualList.tsx +369 -0
- package/src/components/utility/VirtualList/VirtualList.types.ts +56 -0
- package/src/components/utility/VirtualList/index.ts +7 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.md +187 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +433 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +364 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.tsx +506 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.types.ts +133 -0
- package/src/components/utility/WorkflowStep/index.ts +13 -0
- package/src/components/utility/index.ts +7 -0
- package/src/index.ts +17 -0
- package/src/mui/AppBar.ts +2 -0
- package/src/mui/Box.ts +2 -0
- package/src/mui/CssBaseline.ts +2 -0
- package/src/mui/FormControl.ts +2 -0
- package/src/mui/FormControlLabel.ts +2 -0
- package/src/mui/Grid2.ts +2 -0
- package/src/mui/InputLabel.ts +2 -0
- package/src/mui/List.ts +2 -0
- package/src/mui/ListItem.ts +2 -0
- package/src/mui/ListItemButton.ts +2 -0
- package/src/mui/ListItemText.ts +2 -0
- package/src/mui/Stack.ts +2 -0
- package/src/mui/SvgIcon.ts +2 -0
- package/src/mui/Toolbar.ts +2 -0
- package/src/mui/styles.ts +2 -0
- package/src/mui/useMediaQuery.ts +1 -0
- package/src/social-login-button.tsx +199 -0
- package/src/user-avatar.tsx +102 -0
- package/src/utils/cn.ts +9 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
# DataGrid
|
|
2
|
+
|
|
3
|
+
> Canonical authoring guidelines for the **DataGrid** component in the Requisio design system.
|
|
4
|
+
> **Testing policy:** Use **Storybook Test stories + Storybook Test Runner** only. Do **not** add unit tests or `__tests__/`.
|
|
5
|
+
|
|
6
|
+
## 1) Purpose & Scope
|
|
7
|
+
|
|
8
|
+
A **DataGrid** presents large tabular datasets with high-performance rendering and rich interactions:
|
|
9
|
+
|
|
10
|
+
- Virtualized scrolling (rows + optional columns)
|
|
11
|
+
- Sorting, filtering, grouping (optional), and column pinning
|
|
12
|
+
- Pagination (client and server modes)
|
|
13
|
+
- Column resize/reorder/show-hide
|
|
14
|
+
- Row selection (single/multi), row expansion (details)
|
|
15
|
+
- Inline cell editing (optional)
|
|
16
|
+
- Keyboard navigation and full a11y for assistive tech
|
|
17
|
+
- Sticky headers/footers; responsive layout
|
|
18
|
+
|
|
19
|
+
## 2) Deliverables & File Layout
|
|
20
|
+
|
|
21
|
+
Create under `packages/ui/src/components/datagrid/`:
|
|
22
|
+
|
|
23
|
+
- `DataGrid.tsx` — component implementation (not included here)
|
|
24
|
+
- `datagrid.css.ts` — tokens/variants styling
|
|
25
|
+
- `index.ts` — re-exports
|
|
26
|
+
- `DataGrid.stories.tsx` — stories + test stories
|
|
27
|
+
- `track.md` — props/lint/types/progress
|
|
28
|
+
- `tests.md` — Storybook tests plan and PASS log
|
|
29
|
+
|
|
30
|
+
Add exports to `packages/ui/src/index.ts`.
|
|
31
|
+
|
|
32
|
+
## 3) Public API (Interfaces only)
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
export type GridSizeMode = 'auto' | 'fixed' | 'fill'; // column sizing strategy
|
|
36
|
+
export type GridDensity = 'compact' | 'comfortable' | 'spacious';
|
|
37
|
+
export type SortDirection = 'asc' | 'desc' | null;
|
|
38
|
+
export type SelectionMode = 'none' | 'single' | 'multi';
|
|
39
|
+
export type PaginationMode = 'client' | 'server';
|
|
40
|
+
export type SortMode = 'client' | 'server';
|
|
41
|
+
export type FilterMode = 'client' | 'server';
|
|
42
|
+
export type EditMode = 'none' | 'cell' | 'row';
|
|
43
|
+
|
|
44
|
+
export interface GridColumn<T = any> {
|
|
45
|
+
/** Unique column id (stable across renders) */
|
|
46
|
+
id: string;
|
|
47
|
+
/** Column header label (string or node) */
|
|
48
|
+
header: React.ReactNode;
|
|
49
|
+
/** Accessor: key or function to derive value from row */
|
|
50
|
+
accessor?: keyof T | ((row: T) => any);
|
|
51
|
+
/** Column type influences default formatting and editors */
|
|
52
|
+
type?: 'text' | 'number' | 'date' | 'datetime' | 'boolean' | 'currency' | 'actions';
|
|
53
|
+
/** Width hints (px) and min/max constraints */
|
|
54
|
+
width?: number;
|
|
55
|
+
minWidth?: number;
|
|
56
|
+
maxWidth?: number;
|
|
57
|
+
/** Column is initially hidden */
|
|
58
|
+
hidden?: boolean;
|
|
59
|
+
/** Pin to left/right (sticky) */
|
|
60
|
+
pin?: 'left' | 'right';
|
|
61
|
+
/** Enable/disable sort, filter, resize, reorder, edit per column */
|
|
62
|
+
enableSort?: boolean;
|
|
63
|
+
enableFilter?: boolean;
|
|
64
|
+
enableResize?: boolean;
|
|
65
|
+
enableReorder?: boolean;
|
|
66
|
+
enableEdit?: boolean;
|
|
67
|
+
/** Custom renderers */
|
|
68
|
+
cell?: (ctx: { value: any; row: T; rowIndex: number; col: GridColumn<T> }) => React.ReactNode;
|
|
69
|
+
headerCell?: (col: GridColumn<T>) => React.ReactNode;
|
|
70
|
+
/** Cell editor renderer (edit mode) */
|
|
71
|
+
editor?: (ctx: {
|
|
72
|
+
value: any;
|
|
73
|
+
row: T;
|
|
74
|
+
onChange: (next: any) => void;
|
|
75
|
+
commit: () => void;
|
|
76
|
+
cancel: () => void;
|
|
77
|
+
}) => React.ReactNode;
|
|
78
|
+
/** Column-specific filter UI and predicate (client mode) */
|
|
79
|
+
filterComponent?: (ctx: {
|
|
80
|
+
value: any;
|
|
81
|
+
setValue: (next: any) => void;
|
|
82
|
+
col: GridColumn<T>;
|
|
83
|
+
}) => React.ReactNode;
|
|
84
|
+
filterPredicate?: (value: any, filterValue: any, row: T) => boolean;
|
|
85
|
+
/** Accessibility label for header button controls */
|
|
86
|
+
ariaLabel?: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface GridSort {
|
|
90
|
+
id: string; // column id
|
|
91
|
+
dir: SortDirection; // asc | desc | null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface GridFilter {
|
|
95
|
+
id: string; // column id
|
|
96
|
+
value: any; // opaque filter value per column type
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface GridRowExpansion<T = any> {
|
|
100
|
+
/** Render expanded content */
|
|
101
|
+
render: (row: T, rowIndex: number) => React.ReactNode;
|
|
102
|
+
/** Controlled expanded row ids */
|
|
103
|
+
expandedRowIds?: Array<string | number>;
|
|
104
|
+
/** Uncontrolled defaults */
|
|
105
|
+
defaultExpandedRowIds?: Array<string | number>;
|
|
106
|
+
/** Row id equality uses `getRowId` */
|
|
107
|
+
onChangeExpanded?: (ids: Array<string | number>) => void;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface GridSelection {
|
|
111
|
+
mode?: SelectionMode; // none | single | multi
|
|
112
|
+
selectedRowIds?: Array<string | number>; // controlled
|
|
113
|
+
defaultSelectedRowIds?: Array<string | number>;
|
|
114
|
+
onChangeSelected?: (ids: Array<string | number>) => void;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface GridPagination {
|
|
118
|
+
mode?: PaginationMode; // client | server
|
|
119
|
+
pageIndex?: number; // controlled, 0-based
|
|
120
|
+
pageSize?: number; // rows per page
|
|
121
|
+
rowCount?: number; // total rows (server)
|
|
122
|
+
onChangePage?: (nextIndex: number) => void;
|
|
123
|
+
onChangePageSize?: (nextSize: number) => void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface GridSorting {
|
|
127
|
+
mode?: SortMode; // client | server
|
|
128
|
+
sortBy?: GridSort[]; // controlled
|
|
129
|
+
defaultSortBy?: GridSort[];
|
|
130
|
+
onChangeSortBy?: (next: GridSort[]) => void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface GridFiltering {
|
|
134
|
+
mode?: FilterMode; // client | server
|
|
135
|
+
filters?: GridFilter[]; // controlled
|
|
136
|
+
defaultFilters?: GridFilter[];
|
|
137
|
+
onChangeFilters?: (next: GridFilter[]) => void;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface GridEditing<T = any> {
|
|
141
|
+
mode?: EditMode; // none | cell | row
|
|
142
|
+
/** Called when a cell (or row) attempts to commit a value */
|
|
143
|
+
onEditCommit?: (ctx: {
|
|
144
|
+
rowId: string | number;
|
|
145
|
+
colId: string;
|
|
146
|
+
value: any;
|
|
147
|
+
row: T;
|
|
148
|
+
}) => Promise<void> | void;
|
|
149
|
+
/** Validation error message per cell (controlled) */
|
|
150
|
+
getCellError?: (rowId: string | number, colId: string) => string | undefined;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface DataGridProps<T = any> extends React.HTMLAttributes<HTMLElement> {
|
|
154
|
+
/** Dataset (client mode uses this array; server mode renders current page) */
|
|
155
|
+
rows: T[];
|
|
156
|
+
/** Stable row id accessor */
|
|
157
|
+
getRowId?: (row: T, index: number) => string | number;
|
|
158
|
+
/** Column definitions */
|
|
159
|
+
columns: GridColumn<T>[];
|
|
160
|
+
|
|
161
|
+
/** Sizing, density, and layout */
|
|
162
|
+
sizeMode?: GridSizeMode; // auto | fixed | fill
|
|
163
|
+
density?: GridDensity; // compact | comfortable | spacious
|
|
164
|
+
rowHeight?: number; // default row height (px)
|
|
165
|
+
headerHeight?: number; // default header height (px)
|
|
166
|
+
footerHeight?: number; // optional
|
|
167
|
+
|
|
168
|
+
/** Interaction features */
|
|
169
|
+
selection?: GridSelection;
|
|
170
|
+
pagination?: GridPagination;
|
|
171
|
+
sorting?: GridSorting;
|
|
172
|
+
filtering?: GridFiltering;
|
|
173
|
+
expansion?: GridRowExpansion<T>;
|
|
174
|
+
editing?: GridEditing<T>;
|
|
175
|
+
|
|
176
|
+
/** Virtualization toggles */
|
|
177
|
+
virtualizeRows?: boolean; // default: true for large datasets
|
|
178
|
+
virtualizeColumns?: boolean; // optional; default: false
|
|
179
|
+
|
|
180
|
+
/** Sticky headers/footers and pinned columns */
|
|
181
|
+
stickyHeader?: boolean;
|
|
182
|
+
stickyFooter?: boolean;
|
|
183
|
+
|
|
184
|
+
/** Empty/loading/error states */
|
|
185
|
+
loading?: boolean;
|
|
186
|
+
error?: React.ReactNode; // message or node for error state
|
|
187
|
+
emptyState?: React.ReactNode; // custom empty component
|
|
188
|
+
|
|
189
|
+
/** Server-fetch hooks (used by server modes) */
|
|
190
|
+
onRequestData?: (params: {
|
|
191
|
+
pageIndex?: number;
|
|
192
|
+
pageSize?: number;
|
|
193
|
+
sortBy?: GridSort[];
|
|
194
|
+
filters?: GridFilter[];
|
|
195
|
+
}) => void;
|
|
196
|
+
|
|
197
|
+
/** Accessibility */
|
|
198
|
+
ariaLabel?: string; // label for entire grid region
|
|
199
|
+
ariaDescription?: string;
|
|
200
|
+
|
|
201
|
+
/** Testing id passthrough */
|
|
202
|
+
'data-testid'?: string;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## 4) Accessibility & Semantics
|
|
207
|
+
|
|
208
|
+
- Root uses **ARIA grid pattern**:
|
|
209
|
+
- Container: `<div role="grid" aria-rowcount={...} aria-colcount={...}>`
|
|
210
|
+
- Header row: `role="row"` with header cells `role="columnheader"` (sortable headers include `aria-sort="ascending|descending|none"`).
|
|
211
|
+
- Body rows: `role="row"` with `role="gridcell"`; selected rows/cells set `aria-selected="true"`.
|
|
212
|
+
- Row headers (optional): `role="rowheader"`.
|
|
213
|
+
|
|
214
|
+
- **Keyboard**:
|
|
215
|
+
- Arrow keys move cell focus; Home/End go to first/last cell in row; PageUp/PageDown scroll by viewport.
|
|
216
|
+
- Ctrl/Cmd + Home/End moves to grid start/end.
|
|
217
|
+
- Space/Enter toggle selection or begin edit (edit mode).
|
|
218
|
+
- Esc cancels edit.
|
|
219
|
+
|
|
220
|
+
- **Focus management**:
|
|
221
|
+
- Use **roving tabindex** pattern; only one focusable cell at a time.
|
|
222
|
+
- Maintain focus visibility using `:focus-visible`.
|
|
223
|
+
|
|
224
|
+
- **Announcements**:
|
|
225
|
+
- Live region for operations (e.g., “Sorted by Amount, ascending”).
|
|
226
|
+
- Selection count updates announced for multi-select.
|
|
227
|
+
|
|
228
|
+
- **Headers/controls**:
|
|
229
|
+
- Sortable headers are buttons with clear `aria-label`.
|
|
230
|
+
- Resize handles have `aria-valuenow/min/max` when keyboard-resizable.
|
|
231
|
+
|
|
232
|
+
## 5) Behavior Rules
|
|
233
|
+
|
|
234
|
+
- **Sorting**:
|
|
235
|
+
- Controlled via `sorting.sortBy`; on header click cycles `asc → desc → none` (configurable).
|
|
236
|
+
- Server mode: never modify `rows`; emit `onRequestData`.
|
|
237
|
+
|
|
238
|
+
- **Filtering**:
|
|
239
|
+
- Controlled/Uncontrolled per `GridFiltering`; client mode uses `filterPredicate` or sensible defaults by type.
|
|
240
|
+
|
|
241
|
+
- **Pagination**:
|
|
242
|
+
- Client mode slices `rows`; server mode emits `onRequestData` and renders provided page.
|
|
243
|
+
|
|
244
|
+
- **Selection**:
|
|
245
|
+
- Respect `SelectionMode`; shift-click range selection (optional, nice-to-have).
|
|
246
|
+
- In multi-select, `Ctrl/Cmd` toggles without clearing.
|
|
247
|
+
|
|
248
|
+
- **Resize/Reorder/Pin**:
|
|
249
|
+
- Columns can be resized (drag + keyboard), reordered via drag, and pinned left/right (sticky).
|
|
250
|
+
|
|
251
|
+
- **Editing**:
|
|
252
|
+
- `EditMode='cell' | 'row'`; commit via Enter/blur; cancel via Esc.
|
|
253
|
+
- Call `onEditCommit`; show validation errors via `getCellError`.
|
|
254
|
+
|
|
255
|
+
- **Expansion**:
|
|
256
|
+
- Row expand/collapse before/after row; expanded region must be focusable and labelled.
|
|
257
|
+
|
|
258
|
+
## 6) Styling Contract (data attributes & slots)
|
|
259
|
+
|
|
260
|
+
- Root: `[data-ui="datagrid"]`
|
|
261
|
+
- Attributes on root:
|
|
262
|
+
- `data-density="compact|comfortable|spacious"`
|
|
263
|
+
- `data-size-mode="auto|fixed|fill"`
|
|
264
|
+
- `data-virtual-rows="true|false"`
|
|
265
|
+
- `data-virtual-cols="true|false"`
|
|
266
|
+
- `data-sticky-header="true|false"`
|
|
267
|
+
|
|
268
|
+
- Slots:
|
|
269
|
+
- `[data-slot="header"]` (row group)
|
|
270
|
+
- `[data-slot="header-row"]`
|
|
271
|
+
- `[data-slot="header-cell"]` (+ `data-sort="asc|desc|none"`)
|
|
272
|
+
- `[data-slot="body"]`
|
|
273
|
+
- `[data-slot="row"]` (+ `data-selected="true|false"`, `data-expanded="true|false"`)
|
|
274
|
+
- `[data-slot="cell"]` (+ `data-editing="true|false"`, `data-col-id="<id>"`)
|
|
275
|
+
- `[data-slot="footer"]`
|
|
276
|
+
- `[data-slot="resize-handle"]`
|
|
277
|
+
- `[data-slot="reorder-handle"]`
|
|
278
|
+
- `[data-slot="pinned-left"]`, `[data-slot="pinned-right"]`
|
|
279
|
+
- States: `data-loading="true|false"`, `data-error="true|false"`, shown via slots
|
|
280
|
+
|
|
281
|
+
Layout guidance:
|
|
282
|
+
|
|
283
|
+
- Use CSS variables for row heights, column widths, gaps, and colors.
|
|
284
|
+
- Ensure fixed header + virtualized body do not cause layout shifts.
|
|
285
|
+
- Avoid absolute positioning for focus rings; use outline/box-shadow tokens.
|
|
286
|
+
|
|
287
|
+
## 7) Tokens & Theming
|
|
288
|
+
|
|
289
|
+
Use Requisio tokens only:
|
|
290
|
+
|
|
291
|
+
- Typography: `--rs-font-size-*, --rs-line-height-*`
|
|
292
|
+
- Spacing: `--rs-space-*`
|
|
293
|
+
- Colors: `--rs-color-bg|fg|border-*`; state tokens for hover/selected/active/error
|
|
294
|
+
- Focus: `--rs-focus-ring`
|
|
295
|
+
- Elevation (optional for sticky header shadow): `--rs-shadow-sm`
|
|
296
|
+
- Density mapping adjusts `rowHeight`, paddings, and font sizes.
|
|
297
|
+
|
|
298
|
+
Dark mode:
|
|
299
|
+
|
|
300
|
+
- Verify AA contrast for header/body text, dividers, selected rows, and focus outlines.
|
|
301
|
+
|
|
302
|
+
## 8) Performance
|
|
303
|
+
|
|
304
|
+
- **Virtualization** is required for large datasets (default on for rows).
|
|
305
|
+
- Use translation-based row movement to avoid reflow; batch DOM updates.
|
|
306
|
+
- Avoid inline functions in hot paths; memoize row/cell renders.
|
|
307
|
+
- Refrain from measuring DOM per frame; rely on ResizeObserver for container.
|
|
308
|
+
|
|
309
|
+
## 9) Storybook Requirements (canonical tests)
|
|
310
|
+
|
|
311
|
+
Create stories for:
|
|
312
|
+
|
|
313
|
+
- **Docs**: overview, API, do/don’t; client vs server-mode examples.
|
|
314
|
+
- **Tests** (`DataDisplay/DataGrid/Tests/*`):
|
|
315
|
+
- Basic rendering & semantics (ARIA grid)
|
|
316
|
+
- Virtualization correctness (render window, keep indices)
|
|
317
|
+
- Sorting (client & server)
|
|
318
|
+
- Filtering (client & server)
|
|
319
|
+
- Pagination (client & server)
|
|
320
|
+
- Selection (single/multi), keyboard selection
|
|
321
|
+
- Column resize/reorder/pin
|
|
322
|
+
- Editing (start/commit/cancel, validation)
|
|
323
|
+
- Keyboard navigation (cell grid)
|
|
324
|
+
- Sticky header behavior
|
|
325
|
+
- Empty/loading/error states
|
|
326
|
+
- Dark mode contrast
|
|
327
|
+
- Performance smoke (1k–10k rows windowed)
|
|
328
|
+
|
|
329
|
+
## 10) Acceptance Criteria
|
|
330
|
+
|
|
331
|
+
- Props comply with interfaces above; defaults documented.
|
|
332
|
+
- A11y checks pass for key stories; keyboard navigation complete.
|
|
333
|
+
- Storybook tests **PASS** and are recorded in `tests.md`.
|
|
334
|
+
- `pnpm check:component data-display DataGrid` clean (lint/types/tests).
|
|
335
|
+
- Token-driven theming; no hard-coded colors.
|
|
336
|
+
- Virtualization proven in stories without jank.
|
|
337
|
+
|
|
338
|
+
## 11) Hand-off Checklist (`track.md`)
|
|
339
|
+
|
|
340
|
+
- Props table with defaults and required flags
|
|
341
|
+
- Lint/Type status
|
|
342
|
+
- Storybook Tests list (planned → completed) with timestamps
|
|
343
|
+
- Screenshots (light/dark; dense modes; pinned columns)
|
|
344
|
+
- Known issues / follow-ups
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
# datagrid.md
|
|
349
|
+
|
|
350
|
+
**Alias notice:** Lowercase alias pointing to the canonical spec in `DataGrid.md`.
|
|
351
|
+
|
|
352
|
+
- **Canonical spec:** `DataGrid.md`
|
|
353
|
+
- **Rationale:** Support pipelines/editors that expect lowercase filenames.
|
|
354
|
+
- **Instruction:** Follow API, behaviors, a11y, theming, and Storybook test requirements defined in `DataGrid.md`.
|
|
355
|
+
|
|
356
|
+
Quick links:
|
|
357
|
+
|
|
358
|
+
- Purpose & Scope → `DataGrid.md` §1
|
|
359
|
+
- Interfaces → `DataGrid.md` §3
|
|
360
|
+
- Accessibility → `DataGrid.md` §4
|
|
361
|
+
- Tokens & Theming → `DataGrid.md` §7
|
|
362
|
+
- Storybook Tests → `DataGrid.md` §9
|
|
363
|
+
- Acceptance Criteria → `DataGrid.md` §10
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Testing
|
|
368
|
+
|
|
369
|
+
### Test IDs
|
|
370
|
+
|
|
371
|
+
The DataGrid component includes `data-testid` attributes for reliable testing:
|
|
372
|
+
|
|
373
|
+
| Test ID | Element | Description |
|
|
374
|
+
|---------|---------|-------------|
|
|
375
|
+
| `{dataTestId}` | Root Box | Main container Box element with role="grid" |
|
|
376
|
+
|
|
377
|
+
**Note:** The `data-testid` is applied to the root container element. Additional test IDs can be applied to custom renderers, expansion content, and empty states via the respective props.
|
|
378
|
+
|
|
379
|
+
### Testing Best Practices
|
|
380
|
+
|
|
381
|
+
**Wait for DataGrid to Render:**
|
|
382
|
+
```typescript
|
|
383
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
384
|
+
expect(grid).toBeInTheDocument();
|
|
385
|
+
expect(grid).toHaveAttribute('role', 'grid');
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Test Grid Structure:**
|
|
389
|
+
```typescript
|
|
390
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
391
|
+
|
|
392
|
+
// Verify grid has proper ARIA attributes
|
|
393
|
+
expect(grid).toHaveAttribute('aria-rowcount');
|
|
394
|
+
expect(grid).toHaveAttribute('aria-colcount');
|
|
395
|
+
|
|
396
|
+
// Find table structure
|
|
397
|
+
const table = grid.querySelector('table');
|
|
398
|
+
expect(table).toBeInTheDocument();
|
|
399
|
+
|
|
400
|
+
// Verify headers
|
|
401
|
+
const headers = grid.querySelectorAll('[role="columnheader"]');
|
|
402
|
+
expect(headers.length).toBeGreaterThan(0);
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Test Rows Rendering:**
|
|
406
|
+
```typescript
|
|
407
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
408
|
+
const rows = grid.querySelectorAll('[role="row"]');
|
|
409
|
+
|
|
410
|
+
// First row is header, rest are data
|
|
411
|
+
expect(rows.length).toBe(expectedRowCount + 1);
|
|
412
|
+
|
|
413
|
+
// Check specific row content
|
|
414
|
+
const firstDataRow = rows[1];
|
|
415
|
+
const cells = firstDataRow.querySelectorAll('[role="gridcell"]');
|
|
416
|
+
expect(cells[0]).toHaveTextContent('Expected Value');
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Test Sorting:**
|
|
420
|
+
```typescript
|
|
421
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
422
|
+
|
|
423
|
+
// Find sortable column header
|
|
424
|
+
const headers = grid.querySelectorAll('[role="columnheader"]');
|
|
425
|
+
const sortableHeader = Array.from(headers).find(
|
|
426
|
+
h => h.querySelector('button')
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
await userEvent.click(sortableHeader!.querySelector('button')!);
|
|
430
|
+
|
|
431
|
+
// Verify sort indicator
|
|
432
|
+
await waitFor(() => {
|
|
433
|
+
expect(sortableHeader).toHaveAttribute('aria-sort', 'ascending');
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
// Click again for descending
|
|
437
|
+
await userEvent.click(sortableHeader!.querySelector('button')!);
|
|
438
|
+
await waitFor(() => {
|
|
439
|
+
expect(sortableHeader).toHaveAttribute('aria-sort', 'descending');
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Test Selection:**
|
|
444
|
+
```typescript
|
|
445
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
446
|
+
|
|
447
|
+
// Find selection checkboxes
|
|
448
|
+
const checkboxes = grid.querySelectorAll('input[type="checkbox"]');
|
|
449
|
+
const firstRowCheckbox = checkboxes[1]; // [0] is select-all
|
|
450
|
+
|
|
451
|
+
await userEvent.click(firstRowCheckbox);
|
|
452
|
+
|
|
453
|
+
// Verify row is selected
|
|
454
|
+
const selectedRow = firstRowCheckbox.closest('[role="row"]');
|
|
455
|
+
expect(selectedRow).toHaveAttribute('aria-selected', 'true');
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Test Pagination:**
|
|
459
|
+
```typescript
|
|
460
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
461
|
+
|
|
462
|
+
// Find pagination controls (typically below grid)
|
|
463
|
+
const nextButton = screen.getByLabelText(/next page/i);
|
|
464
|
+
await userEvent.click(nextButton);
|
|
465
|
+
|
|
466
|
+
expect(onChangePage).toHaveBeenCalledWith(1);
|
|
467
|
+
|
|
468
|
+
// Verify page indicator updates
|
|
469
|
+
const pageInfo = screen.getByText(/page 2/i);
|
|
470
|
+
expect(pageInfo).toBeInTheDocument();
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Test Column Filtering:**
|
|
474
|
+
```typescript
|
|
475
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
476
|
+
|
|
477
|
+
// Open filter for a column (implementation-specific)
|
|
478
|
+
const filterButton = grid.querySelector('[aria-label*="filter"]');
|
|
479
|
+
await userEvent.click(filterButton!);
|
|
480
|
+
|
|
481
|
+
// Enter filter value
|
|
482
|
+
const filterInput = screen.getByRole('textbox');
|
|
483
|
+
await userEvent.type(filterInput, 'search term');
|
|
484
|
+
|
|
485
|
+
// Verify onChangeFilters called
|
|
486
|
+
expect(onChangeFilters).toHaveBeenCalledWith(
|
|
487
|
+
expect.arrayContaining([
|
|
488
|
+
expect.objectContaining({ id: 'columnId', value: 'search term' })
|
|
489
|
+
])
|
|
490
|
+
);
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Test Empty State:**
|
|
494
|
+
```typescript
|
|
495
|
+
// Render grid with no rows
|
|
496
|
+
const grid = await canvas.findByTestId('empty-grid');
|
|
497
|
+
|
|
498
|
+
// Verify empty state shows
|
|
499
|
+
const emptyState = await canvas.findByTestId('custom-empty');
|
|
500
|
+
expect(emptyState).toBeInTheDocument();
|
|
501
|
+
expect(emptyState).toHaveTextContent('Custom empty message');
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Test Loading State:**
|
|
505
|
+
```typescript
|
|
506
|
+
const grid = await canvas.findByTestId('loading-grid');
|
|
507
|
+
|
|
508
|
+
// Verify loading indicator
|
|
509
|
+
const loadingSpinner = grid.querySelector('.MuiCircularProgress-root');
|
|
510
|
+
expect(loadingSpinner).toBeInTheDocument();
|
|
511
|
+
|
|
512
|
+
// Data rows should not be visible
|
|
513
|
+
const dataRows = grid.querySelectorAll('[role="row"]');
|
|
514
|
+
expect(dataRows.length).toBe(1); // Only header row
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Test Row Expansion:**
|
|
518
|
+
```typescript
|
|
519
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
520
|
+
|
|
521
|
+
// Find expand button
|
|
522
|
+
const expandButton = grid.querySelector('[aria-label*="expand"]');
|
|
523
|
+
await userEvent.click(expandButton!);
|
|
524
|
+
|
|
525
|
+
// Verify expansion content appears
|
|
526
|
+
const expansionContent = await canvas.findByTestId('expansion-row-1');
|
|
527
|
+
expect(expansionContent).toBeInTheDocument();
|
|
528
|
+
expect(expansionContent).toHaveTextContent('Details for');
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Test Keyboard Navigation:**
|
|
532
|
+
```typescript
|
|
533
|
+
const grid = await canvas.findByTestId('data-grid');
|
|
534
|
+
|
|
535
|
+
// Focus first data cell
|
|
536
|
+
const firstCell = grid.querySelector('[role="gridcell"]');
|
|
537
|
+
firstCell!.focus();
|
|
538
|
+
|
|
539
|
+
// Navigate with arrow keys
|
|
540
|
+
await userEvent.keyboard('{ArrowRight}');
|
|
541
|
+
const nextCell = document.activeElement;
|
|
542
|
+
expect(nextCell).toHaveAttribute('role', 'gridcell');
|
|
543
|
+
|
|
544
|
+
// Navigate down
|
|
545
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
546
|
+
const cellBelow = document.activeElement;
|
|
547
|
+
expect(cellBelow).toHaveAttribute('role', 'gridcell');
|
|
548
|
+
|
|
549
|
+
// Home/End navigation
|
|
550
|
+
await userEvent.keyboard('{Home}');
|
|
551
|
+
const firstCellInRow = document.activeElement;
|
|
552
|
+
expect(firstCellInRow).toBe(firstCell);
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**Test Cell Editing:**
|
|
556
|
+
```typescript
|
|
557
|
+
const grid = await canvas.findByTestId('editable-grid');
|
|
558
|
+
|
|
559
|
+
// Double-click cell to enter edit mode
|
|
560
|
+
const cell = grid.querySelector('[role="gridcell"]');
|
|
561
|
+
await userEvent.dblClick(cell!);
|
|
562
|
+
|
|
563
|
+
// Find editor input
|
|
564
|
+
const editor = cell!.querySelector('input');
|
|
565
|
+
expect(editor).toBeInTheDocument();
|
|
566
|
+
|
|
567
|
+
// Edit value
|
|
568
|
+
await userEvent.clear(editor!);
|
|
569
|
+
await userEvent.type(editor!, 'New Value');
|
|
570
|
+
await userEvent.keyboard('{Enter}');
|
|
571
|
+
|
|
572
|
+
// Verify commit callback
|
|
573
|
+
expect(onEditCommit).toHaveBeenCalledWith(
|
|
574
|
+
expect.objectContaining({
|
|
575
|
+
colId: 'columnId',
|
|
576
|
+
value: 'New Value'
|
|
577
|
+
})
|
|
578
|
+
);
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Common Test Scenarios
|
|
582
|
+
|
|
583
|
+
1. **Basic Rendering** - Verify grid renders with headers and data rows
|
|
584
|
+
2. **Grid Semantics** - Test ARIA grid pattern attributes (role, aria-rowcount, aria-colcount)
|
|
585
|
+
3. **Sorting** - Test column sorting (asc/desc/none cycle)
|
|
586
|
+
4. **Filtering** - Test client and server-side filtering
|
|
587
|
+
5. **Pagination** - Test page navigation and page size changes
|
|
588
|
+
6. **Selection** - Test single and multi-row selection
|
|
589
|
+
7. **Row Expansion** - Test expanding/collapsing detail rows
|
|
590
|
+
8. **Column Resize** - Test resizing columns via drag handles
|
|
591
|
+
9. **Column Reorder** - Test drag-and-drop column reordering
|
|
592
|
+
10. **Column Pinning** - Test pinning columns to left/right
|
|
593
|
+
11. **Cell Editing** - Test inline cell editing (start/commit/cancel)
|
|
594
|
+
12. **Keyboard Navigation** - Test arrow keys, Home/End, Page Up/Down
|
|
595
|
+
13. **Virtualization** - Test large datasets render correctly with windowing
|
|
596
|
+
14. **Loading State** - Test loading spinner and disabled interactions
|
|
597
|
+
15. **Empty State** - Test custom empty state rendering
|
|
598
|
+
16. **Error State** - Test error message display
|
|
599
|
+
17. **Sticky Header** - Test header remains visible on scroll
|
|
600
|
+
18. **Density Modes** - Test compact/comfortable/spacious row heights
|
|
601
|
+
19. **Dark Mode** - Test contrast and visibility in dark theme
|
|
602
|
+
20. **Accessibility** - Verify screen reader announcements and focus management
|