@12-apps/ui 1.0.0 → 1.3.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 +14 -0
- package/package.json +42 -27
- package/src/__tests__/data-grid.test.tsx +125 -0
- package/src/__tests__/package-wiring.test.ts +12 -8
- package/src/__tests__/social-login-button.test.tsx +5 -5
- package/src/__tests__/viewport.test.ts +50 -0
- package/src/charts/index.ts +8 -0
- package/src/components/data-display/Alert/Alert.md +1 -1
- package/src/components/data-display/Alert/Alert.stories.tsx +5 -7
- package/src/components/data-display/Alert/Alert.styles.tsx +255 -0
- package/src/components/data-display/Alert/Alert.test.stories.tsx +11 -13
- package/src/components/data-display/Alert/Alert.tsx +135 -328
- package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +3 -1
- package/src/components/data-display/AlertDialog/AlertDialog.tsx +191 -78
- package/src/components/data-display/AlertDialog/AlertDialog.types.ts +8 -1
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +5 -5
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +44 -35
- package/src/components/data-display/Avatar/Avatar.stories.tsx +4 -1
- package/src/components/data-display/Avatar/Avatar.test.stories.tsx +5 -3
- package/src/components/data-display/Avatar/Avatar.tsx +154 -450
- package/src/components/data-display/Avatar/Avatar.view.tsx +396 -0
- package/src/components/data-display/Badge/Badge.animations.ts +67 -0
- package/src/components/data-display/Badge/Badge.helpers.ts +74 -0
- package/src/components/data-display/Badge/Badge.stories.tsx +14 -16
- package/src/components/data-display/Badge/Badge.styles.ts +261 -0
- package/src/components/data-display/Badge/Badge.test.stories.tsx +32 -31
- package/src/components/data-display/Badge/Badge.tsx +151 -557
- package/src/components/data-display/Badge/Badge.variants.ts +106 -0
- package/src/components/data-display/Badge/BadgeContent.tsx +107 -0
- package/src/components/data-display/Banner/Banner.stories.tsx +5 -1
- package/src/components/data-display/Banner/Banner.styles.ts +120 -0
- package/src/components/data-display/Banner/Banner.tsx +179 -224
- package/src/components/data-display/Chart/Chart.md +48 -1
- package/src/components/data-display/Chart/Chart.tsx +82 -500
- package/src/components/data-display/Chart/Chart.types.ts +2 -0
- package/src/components/data-display/Chart/ChartComposables.tsx +121 -0
- package/src/components/data-display/Chart/ChartSpec.types.ts +70 -0
- package/src/components/data-display/Chart/SpecChart.stories.tsx +150 -0
- package/src/components/data-display/Chart/SpecChart.test.stories.tsx +56 -0
- package/src/components/data-display/Chart/SpecChart.tsx +53 -0
- package/src/components/data-display/Chart/__tests__/SpecChart.test.tsx +60 -0
- package/src/components/data-display/Chart/__tests__/chart-format.test.ts +43 -0
- package/src/components/data-display/Chart/__tests__/chart-spec.test.ts +119 -0
- package/src/components/data-display/Chart/chart-format.ts +26 -0
- package/src/components/data-display/Chart/chart-internals.ts +148 -0
- package/src/components/data-display/Chart/chart-renderers.tsx +338 -0
- package/src/components/data-display/Chart/chart-spec-registry.ts +74 -0
- package/src/components/data-display/Chart/chart-spec.ts +171 -0
- package/src/components/data-display/Chart/index.ts +30 -0
- package/src/components/data-display/Chip/Chip.helpers.tsx +131 -0
- package/src/components/data-display/Chip/Chip.stories.tsx +2 -1
- package/src/components/data-display/Chip/Chip.test.stories.tsx +11 -8
- package/src/components/data-display/Chip/Chip.tsx +31 -94
- package/src/components/data-display/DataGrid/DataGrid.body.tsx +141 -0
- package/src/components/data-display/DataGrid/DataGrid.cells.tsx +238 -0
- package/src/components/data-display/DataGrid/DataGrid.model.ts +315 -0
- package/src/components/data-display/DataGrid/DataGrid.rows.ts +112 -0
- package/src/components/data-display/DataGrid/DataGrid.states.tsx +102 -0
- package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +6 -12
- package/src/components/data-display/DataGrid/DataGrid.tsx +129 -725
- package/src/components/data-display/DataViews/DataViewsGrid.tsx +187 -0
- package/src/components/data-display/DataViews/DataViewsTableBase.tsx +400 -0
- package/src/components/data-display/DataViews/ManageViewsDialog.tsx +140 -0
- package/src/components/data-display/DataViews/SaveViewModal.tsx +289 -0
- package/src/components/data-display/DataViews/__tests__/DataViewsGrid.test.tsx +271 -0
- package/src/components/data-display/DataViews/__tests__/DataViewsTableBase.test.tsx +134 -0
- package/src/components/data-display/DataViews/__tests__/SaveViewModal.test.tsx +83 -0
- package/src/components/data-display/DataViews/__tests__/data-views-filter.test.ts +115 -0
- package/src/components/data-display/DataViews/__tests__/data-views-preview.test.ts +53 -0
- package/src/components/data-display/DataViews/__tests__/range-pill.test.tsx +114 -0
- package/src/components/data-display/DataViews/base-card.stories.tsx +136 -0
- package/src/components/data-display/DataViews/base-card.tsx +278 -0
- package/src/components/data-display/DataViews/data-views-filter-panel.tsx +184 -0
- package/src/components/data-display/DataViews/data-views-filter.ts +138 -0
- package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +248 -0
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +400 -0
- package/src/components/data-display/DataViews/data-views-inline-bar.tsx +257 -0
- package/src/components/data-display/DataViews/data-views-layout-context.tsx +176 -0
- package/src/components/data-display/DataViews/data-views-pagination.tsx +31 -0
- package/src/components/data-display/DataViews/data-views-preview.ts +53 -0
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +277 -0
- package/src/components/data-display/DataViews/data-views-table-parts.tsx +150 -0
- package/src/components/data-display/DataViews/data-views-toolbar.tsx +149 -0
- package/src/components/data-display/DataViews/data-views-types.ts +312 -0
- package/src/components/data-display/DataViews/data-views-view-mutations.ts +68 -0
- package/src/components/data-display/DataViews/index.ts +33 -0
- package/src/components/data-display/DataViews/use-data-views-state.ts +349 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.hooks.ts +104 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.tsx +68 -118
- package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +1 -1
- package/src/components/data-display/DescriptionItem/DescriptionItem.tsx +52 -34
- package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +6 -6
- package/src/components/data-display/EmptyState/EmptyState.tsx +218 -135
- package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +2 -2
- package/src/components/data-display/ErrorState/ErrorState.tsx +83 -55
- package/src/components/data-display/HoverCard/HoverCard.stories.tsx +3 -1
- package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +5 -5
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts +99 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.styles.ts +87 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +28 -155
- package/src/components/data-display/LazyImage/LazyImage.hooks.ts +203 -0
- package/src/components/data-display/LazyImage/LazyImage.md +1 -1
- package/src/components/data-display/LazyImage/LazyImage.stories.tsx +3 -3
- package/src/components/data-display/LazyImage/LazyImage.tsx +144 -243
- package/src/components/data-display/Lightbox/Lightbox.constants.ts +53 -0
- package/src/components/data-display/Lightbox/Lightbox.helpers.ts +39 -0
- package/src/components/data-display/Lightbox/Lightbox.hooks.ts +259 -0
- package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +28 -35
- package/src/components/data-display/Lightbox/Lightbox.tsx +98 -658
- package/src/components/data-display/Lightbox/LightboxControls.tsx +152 -0
- package/src/components/data-display/Lightbox/LightboxCurrentMedia.tsx +50 -0
- package/src/components/data-display/Lightbox/LightboxMedia.tsx +76 -0
- package/src/components/data-display/Lightbox/LightboxOverlay.tsx +83 -0
- package/src/components/data-display/Lightbox/LightboxStage.tsx +97 -0
- package/src/components/data-display/Lightbox/LightboxThumbnails.tsx +83 -0
- package/src/components/data-display/Lightbox/useLightbox.ts +80 -0
- package/src/components/data-display/LoadingState/LoadingState.helpers.ts +52 -0
- package/src/components/data-display/LoadingState/LoadingState.tsx +117 -87
- package/src/components/data-display/MapPreview/MapControlBar.tsx +116 -0
- package/src/components/data-display/MapPreview/MapDecorations.tsx +155 -0
- package/src/components/data-display/MapPreview/MapLayers.tsx +70 -0
- package/src/components/data-display/MapPreview/MapMarkers.tsx +84 -0
- package/src/components/data-display/MapPreview/MapOverlays.tsx +68 -0
- package/src/components/data-display/MapPreview/MapPreview.constants.ts +19 -0
- package/src/components/data-display/MapPreview/MapPreview.helpers.ts +63 -0
- package/src/components/data-display/MapPreview/MapPreview.hooks.ts +265 -0
- package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +14 -10
- package/src/components/data-display/MapPreview/MapPreview.tsx +52 -882
- package/src/components/data-display/MapPreview/MapPreview.types.ts +8 -1
- package/src/components/data-display/MapPreview/MapSearchBar.tsx +64 -0
- package/src/components/data-display/MapPreview/MapTiles.tsx +70 -0
- package/src/components/data-display/MapPreview/StaticMapView.tsx +63 -0
- package/src/components/data-display/MapPreview/mapProjection.ts +52 -0
- package/src/components/data-display/MapPreview/mapSurface.ts +37 -0
- package/src/components/data-display/MapPreview/useMapPreview.ts +62 -0
- package/src/components/data-display/Popover/Popover.test.stories.tsx +13 -19
- package/src/components/data-display/Progress/Progress.helpers.ts +37 -0
- package/src/components/data-display/Progress/Progress.styles.ts +101 -0
- package/src/components/data-display/Progress/Progress.tsx +185 -213
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +1 -1
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +1 -1
- package/src/components/data-display/StatCard/StatCard.md +117 -0
- package/src/components/data-display/StatCard/StatCard.stories.tsx +167 -0
- package/src/components/data-display/StatCard/StatCard.test.stories.tsx +240 -0
- package/src/components/data-display/StatCard/StatCard.tsx +236 -0
- package/src/components/data-display/StatCard/StatCard.types.ts +62 -0
- package/src/components/data-display/StatCard/index.ts +7 -0
- package/src/components/data-display/Stepper/Stepper.test.stories.tsx +12 -19
- package/src/components/data-display/Stepper/Stepper.tsx +1 -1
- package/src/components/data-display/Table/Table.helpers.ts +31 -0
- package/src/components/data-display/Table/Table.hooks.ts +161 -0
- package/src/components/data-display/Table/Table.stories.tsx +3 -1
- package/src/components/data-display/Table/Table.styles.ts +223 -0
- package/src/components/data-display/Table/Table.test.stories.tsx +4 -4
- package/src/components/data-display/Table/Table.tsx +291 -748
- package/src/components/data-display/Table/TableParts.hooks.tsx +112 -0
- package/src/components/data-display/Table/TableParts.tsx +298 -0
- package/src/components/data-display/Table/TableStates.tsx +21 -0
- package/src/components/data-display/Timeline/Timeline.stories.tsx +10 -12
- package/src/components/data-display/Timeline/Timeline.test.stories.tsx +30 -44
- package/src/components/data-display/Timeline/Timeline.tsx +23 -284
- package/src/components/data-display/Timeline/TimelineRow.tsx +346 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +38 -311
- package/src/components/data-display/TimingDiagram/TimingDiagram.views.tsx +346 -0
- package/src/components/data-display/Tooltip/Tooltip.stories.tsx +4 -1
- package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +44 -58
- package/src/components/data-display/Tooltip/Tooltip.tsx +67 -62
- package/src/components/data-display/index.ts +1 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +96 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.md +140 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +154 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.stories.tsx +146 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.test.stories.tsx +114 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.tsx +46 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +111 -0
- package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +18 -0
- package/src/components/feedback/ConfirmAction/__tests__/confirm-action.test.tsx +288 -0
- package/src/components/feedback/ConfirmAction/index.ts +16 -0
- package/src/components/feedback/ConfirmAction/with-confirmation.tsx +112 -0
- package/src/components/feedback/Dialog/Dialog.styles.ts +4 -2
- package/src/components/feedback/Dialog/Dialog.tsx +26 -1
- package/src/components/feedback/Dialog/__tests__/dialog-content-spacing.test.tsx +66 -0
- package/src/components/feedback/Modal/Modal.md +1 -1
- package/src/components/feedback/Modal/Modal.stories.tsx +2 -2
- package/src/components/feedback/Sonner/Sonner.tsx +104 -288
- package/src/components/feedback/Sonner/Sonner.types.ts +7 -0
- package/src/components/feedback/Sonner/SonnerToast.tsx +216 -0
- package/src/components/feedback/StackedModal/StackedModal.hooks.ts +226 -0
- package/src/components/feedback/StackedModal/StackedModal.parts.tsx +311 -0
- package/src/components/feedback/StackedModal/StackedModal.stories.tsx +13 -15
- package/src/components/feedback/StackedModal/StackedModal.styles.ts +193 -0
- package/src/components/feedback/StackedModal/StackedModal.tsx +100 -619
- package/src/components/feedback/StackedModal/StackedModal.types.ts +17 -3
- package/src/components/feedback/StackedModal/__tests__/stacked-modal-viewport.test.tsx +104 -0
- package/src/components/feedback/StackedModal/modal-stack.tsx +119 -0
- package/src/components/feedback/Toast/Toast.tsx +92 -81
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.geometry.ts +65 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.hooks.ts +185 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +2 -2
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +156 -414
- package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +255 -0
- package/src/components/feedback/index.ts +1 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.helpers.ts +58 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.hooks.ts +93 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.mapper.ts +57 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +4 -2
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +20 -16
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.tsx +26 -829
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +11 -0
- package/src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx +86 -0
- package/src/components/form/AddressAutocomplete/AddressFallbackField.tsx +64 -0
- package/src/components/form/AddressAutocomplete/AddressInputField.tsx +80 -0
- package/src/components/form/AddressAutocomplete/AddressOption.tsx +83 -0
- package/src/components/form/AddressAutocomplete/AddressSuggestionsPaper.tsx +24 -0
- package/src/components/form/AddressAutocomplete/AddressTextField.tsx +43 -0
- package/src/components/form/AddressAutocomplete/mockPlaces.ts +208 -0
- package/src/components/form/AddressAutocomplete/useAddressPredictions.ts +136 -0
- package/src/components/form/AddressAutocomplete/useAddressSelection.ts +113 -0
- package/src/components/form/AddressAutocomplete/useCurrentLocation.ts +116 -0
- package/src/components/form/AddressAutocomplete/useGoogleMapsAPI.ts +75 -0
- package/src/components/form/Button/Button.helpers.ts +36 -0
- package/src/components/form/Button/Button.stories.tsx +4 -1
- package/src/components/form/Button/Button.styles.ts +225 -0
- package/src/components/form/Button/Button.test.stories.tsx +25 -21
- package/src/components/form/Button/Button.tsx +45 -252
- package/src/components/form/Calendar/Calendar.dates.ts +100 -0
- package/src/components/form/Calendar/Calendar.helpers.ts +32 -0
- package/src/components/form/Calendar/Calendar.hooks.ts +278 -0
- package/src/components/form/Calendar/Calendar.keyboard.ts +32 -0
- package/src/components/form/Calendar/Calendar.selection.ts +156 -0
- package/src/components/form/Calendar/Calendar.test.stories.tsx +33 -34
- package/src/components/form/Calendar/Calendar.tsx +63 -551
- package/src/components/form/Calendar/Calendar.types.ts +16 -0
- package/src/components/form/Calendar/CalendarDay.tsx +127 -0
- package/src/components/form/Calendar/CalendarDayCell.tsx +52 -0
- package/src/components/form/Calendar/CalendarMonth.tsx +128 -0
- package/src/components/form/CepField/CepField.md +138 -0
- package/src/components/form/CepField/CepField.stories.tsx +138 -0
- package/src/components/form/CepField/CepField.test.stories.tsx +281 -0
- package/src/components/form/CepField/CepField.tsx +211 -0
- package/src/components/form/CepField/CepField.types.ts +73 -0
- package/src/components/form/CepField/index.ts +2 -0
- package/src/components/form/Checkbox/Checkbox.helpers.ts +28 -0
- package/src/components/form/Checkbox/Checkbox.tsx +19 -16
- package/src/components/form/CodeEditor/CodeEditor.helpers.ts +45 -0
- package/src/components/form/CodeEditor/CodeEditor.hooks.ts +104 -0
- package/src/components/form/CodeEditor/CodeEditor.monaco.ts +109 -0
- package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +17 -18
- package/src/components/form/CodeEditor/CodeEditor.tsx +81 -330
- package/src/components/form/CodeEditor/CodeEditorToolbar.tsx +168 -0
- package/src/components/form/Command/Command.hooks.ts +207 -0
- package/src/components/form/Command/Command.parts.tsx +58 -0
- package/src/components/form/Command/Command.styles.ts +83 -0
- package/src/components/form/Command/Command.tsx +61 -270
- package/src/components/form/CreatableSelect/CreatableSelect.md +1 -1
- package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +1 -1
- package/src/components/form/CreatableSelect/CreatableSelect.tsx +152 -71
- package/src/components/form/CreatableSelect/CreatableSelect.types.ts +13 -0
- package/src/components/form/HeaderButton/HeaderButton.tsx +80 -0
- package/src/components/form/HeaderButton/index.ts +2 -0
- package/src/components/form/Input/Input.stories.tsx +5 -1
- package/src/components/form/Input/Input.styles.ts +176 -0
- package/src/components/form/Input/Input.test.stories.tsx +30 -23
- package/src/components/form/Input/Input.tsx +71 -211
- package/src/components/form/Input/Input.types.ts +11 -0
- package/src/components/form/InputOTP/InputOTP.test.stories.tsx +9 -17
- package/src/components/form/Menubar/Menubar.test.stories.tsx +4 -8
- package/src/components/form/PasswordStrength/PasswordStrength.helpers.tsx +117 -0
- package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +3 -3
- package/src/components/form/PasswordStrength/PasswordStrength.tsx +202 -255
- package/src/components/form/PhoneInput/PhoneInput.hooks.ts +134 -0
- package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +4 -4
- package/src/components/form/PhoneInput/PhoneInput.tsx +279 -292
- package/src/components/form/PhoneInput/countries.ts +54 -0
- package/src/components/form/PhoneInput/phone.ts +47 -0
- package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +9 -9
- package/src/components/form/RichTextEditor/RichTextEditor.dom.ts +124 -0
- package/src/components/form/RichTextEditor/RichTextEditor.format.ts +61 -0
- package/src/components/form/RichTextEditor/RichTextEditor.hooks.ts +142 -0
- package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +5 -12
- package/src/components/form/RichTextEditor/RichTextEditor.tsx +98 -410
- package/src/components/form/RichTextEditor/RichTextEditorToolbar.tsx +187 -0
- package/src/components/form/SearchPalette/SearchPalette.parts.tsx +22 -0
- package/src/components/form/SearchPalette/SearchPalette.tsx +13 -9
- package/src/components/form/Select/Select.test.stories.tsx +35 -27
- package/src/components/form/Slider/Slider.test.stories.tsx +9 -11
- package/src/components/form/Switch/Switch.md +2 -1
- package/src/components/form/Switch/Switch.test.stories.tsx +6 -6
- package/src/components/form/Textarea/Textarea.styles.ts +143 -0
- package/src/components/form/Textarea/Textarea.test.stories.tsx +20 -26
- package/src/components/form/Textarea/Textarea.tsx +114 -535
- package/src/components/form/Textarea/TextareaRichEditor.tsx +377 -0
- package/src/components/form/Toggle/Toggle.styles.ts +211 -0
- package/src/components/form/Toggle/Toggle.test.stories.tsx +19 -27
- package/src/components/form/Toggle/Toggle.tsx +10 -185
- package/src/components/form/UploadButton/UploadButton.hooks.ts +323 -0
- package/src/components/form/UploadButton/UploadButton.parts.tsx +210 -0
- package/src/components/form/UploadButton/UploadButton.stories.tsx +2 -1
- package/src/components/form/UploadButton/UploadButton.test.stories.tsx +123 -4
- package/src/components/form/UploadButton/UploadButton.tsx +76 -305
- package/src/components/form/UploadButton/UploadButton.types.ts +16 -0
- package/src/components/form/index.ts +1 -0
- package/src/components/form/total-form/Fields/CepField.tsx +143 -0
- package/src/components/form/total-form/Fields/ToggleField.tsx +61 -0
- package/src/components/form/total-form/Fields/index.ts +4 -0
- package/src/components/form/total-form/FormContainer.tsx +3 -3
- package/src/components/form/total-form/SubmitButton.tsx +25 -2
- package/src/components/form/total-form/total-form.test.tsx +118 -1
- package/src/components/layout/Accordion/Accordion.md +1 -1
- package/src/components/layout/Accordion/Accordion.stories.tsx +5 -1
- package/src/components/layout/Accordion/Accordion.styles.ts +80 -0
- package/src/components/layout/Accordion/Accordion.test.stories.tsx +32 -50
- package/src/components/layout/Accordion/Accordion.tsx +2 -75
- package/src/components/layout/Card/Card.helpers.ts +30 -0
- package/src/components/layout/Card/Card.stories.tsx +9 -11
- package/src/components/layout/Card/Card.styles.ts +182 -0
- package/src/components/layout/Card/Card.test.stories.tsx +46 -46
- package/src/components/layout/Card/Card.tsx +24 -241
- package/src/components/layout/CardGrid/CardGrid.md +96 -0
- package/src/components/layout/CardGrid/CardGrid.tsx +140 -0
- package/src/components/layout/CardGrid/__tests__/CardGrid.test.tsx +92 -0
- package/src/components/layout/CardGrid/index.ts +2 -0
- package/src/components/layout/Collapsible/Collapsible.helpers.ts +83 -0
- package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +7 -3
- package/src/components/layout/Collapsible/Collapsible.tsx +111 -107
- package/src/components/layout/Container/Container.test.stories.tsx +11 -16
- package/src/components/layout/ContentToolbar/ColumnsMenu.tsx +1 -1
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +120 -44
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +9 -0
- package/src/components/layout/ContentToolbar/FilterTrigger.tsx +1 -1
- package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +58 -43
- package/src/components/layout/ContentToolbar/MultiSelectTriggers.tsx +139 -0
- package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +10 -3
- package/src/components/layout/ContentToolbar/SortByDropdown.tsx +35 -11
- package/src/components/layout/ContentToolbar/ViewSelector.tsx +5 -6
- package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +21 -0
- package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +27 -1
- package/src/components/layout/Dashboard/Dashboard.tsx +27 -8
- package/src/components/layout/Dashboard/DashboardParts.tsx +12 -19
- package/src/components/layout/Dashboard/index.ts +2 -1
- package/src/components/layout/Drawer/Drawer.stories.tsx +8 -10
- package/src/components/layout/Drawer/Drawer.test.stories.tsx +18 -14
- package/src/components/layout/Drawer/Drawer.tsx +67 -53
- package/src/components/layout/Resizable/Resizable.helpers.ts +133 -0
- package/src/components/layout/Resizable/Resizable.hooks.ts +68 -0
- package/src/components/layout/Resizable/Resizable.tsx +38 -153
- package/src/components/layout/ScrollArea/ScrollArea.helpers.ts +51 -0
- package/src/components/layout/ScrollArea/ScrollArea.styles.ts +248 -0
- package/src/components/layout/ScrollArea/ScrollArea.tsx +183 -374
- package/src/components/layout/ScrollArea/ScrollAreaContent.tsx +70 -0
- package/src/components/layout/ScrollArea/ScrollViewport.tsx +90 -0
- package/src/components/layout/Separator/Separator.styles.ts +128 -0
- package/src/components/layout/Separator/Separator.test.stories.tsx +3 -12
- package/src/components/layout/Separator/Separator.tsx +6 -132
- package/src/components/layout/SettingsLayout/SettingsLayout.parts.tsx +2 -1
- package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +6 -8
- package/src/components/layout/Sidebar/Sidebar.stories.tsx +10 -12
- package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +35 -37
- package/src/components/layout/Skeleton/Skeleton.helpers.ts +33 -0
- package/src/components/layout/Skeleton/Skeleton.styles.ts +114 -0
- package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +3 -3
- package/src/components/layout/Skeleton/Skeleton.tsx +67 -155
- package/src/components/layout/TableFilter/TableFilter.tsx +2 -1
- package/src/components/navigation/Breadcrumbs/BreadcrumbEntry.tsx +305 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.md +2 -1
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +12 -14
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.styles.tsx +212 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +62 -61
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +116 -429
- package/src/components/navigation/CommandPalette/CommandPalette.helpers.ts +82 -0
- package/src/components/navigation/CommandPalette/CommandPalette.hooks.ts +202 -0
- package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +3 -1
- package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +3 -5
- package/src/components/navigation/CommandPalette/CommandPalette.tsx +108 -341
- package/src/components/navigation/CommandPalette/CommandPaletteResults.tsx +182 -0
- package/src/components/navigation/CommandPalette/ShortcutChip.tsx +18 -0
- package/src/components/navigation/ContextMenu/ContextMenu.md +3 -1
- package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +4 -1
- package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +19 -24
- package/src/components/navigation/ContextMenu/ContextMenu.tsx +70 -54
- package/src/components/navigation/DropdownMenu/DropdownMenu.md +3 -1
- package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +17 -19
- package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +26 -26
- package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +189 -111
- package/src/components/navigation/NavigationMenu/NavigationMegaSection.tsx +66 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.md +7 -2
- package/src/components/navigation/NavigationMenu/NavigationMenu.shell.tsx +218 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.styles.ts +223 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +119 -808
- package/src/components/navigation/NavigationMenu/NavigationMenuItem.hooks.ts +126 -0
- package/src/components/navigation/NavigationMenu/NavigationMenuItem.tsx +352 -0
- package/src/components/navigation/NavigationMenu/NavigationStandardBody.tsx +148 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +15 -17
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +27 -23
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +11 -13
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +9 -11
- package/src/components/navigation/Pagination/Pagination.helpers.tsx +85 -0
- package/src/components/navigation/Pagination/Pagination.md +2 -1
- package/src/components/navigation/Pagination/Pagination.stories.tsx +4 -6
- package/src/components/navigation/Pagination/Pagination.styles.ts +135 -0
- package/src/components/navigation/Pagination/Pagination.tsx +178 -313
- package/src/components/navigation/Pagination/PaginationParts.tsx +81 -0
- package/src/components/navigation/Tabs/Tabs.md +3 -1
- package/src/components/navigation/Tabs/Tabs.stories.tsx +21 -23
- package/src/components/navigation/Tabs/Tabs.styles.ts +163 -0
- package/src/components/navigation/Tabs/Tabs.test.stories.tsx +37 -37
- package/src/components/navigation/Tabs/Tabs.tsx +192 -361
- package/src/components/navigation/Tabs/TabsPanel.tsx +100 -0
- package/src/components/typography/Blockquote/Blockquote.tsx +1 -1
- package/src/components/typography/Code/Code.test.stories.tsx +5 -5
- package/src/components/typography/Code/Code.tsx +74 -49
- package/src/components/typography/Heading/Heading.test.stories.tsx +8 -8
- package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +5 -12
- package/src/components/typography/Text/Text.tsx +84 -77
- package/src/components/utility/AnimatedIcon/AnimatedIcon.md +4 -4
- package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +19 -21
- package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +19 -12
- package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +9 -9
- package/src/components/utility/InfiniteScroll/InfiniteScroll.hooks.ts +118 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +54 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +12 -9
- package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +29 -148
- package/src/components/utility/InstallPrompt/InstallPrompt.helpers.ts +124 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.md +113 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.stories.tsx +118 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.styles.ts +50 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.test.stories.tsx +83 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.tsx +192 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.types.ts +78 -0
- package/src/components/utility/InstallPrompt/__tests__/InstallPrompt.ios.test.tsx +65 -0
- package/src/components/utility/InstallPrompt/__tests__/usePwaInstall.test.tsx +271 -0
- package/src/components/utility/InstallPrompt/index.ts +10 -0
- package/src/components/utility/InstallPrompt/usePwaInstall.ts +171 -0
- package/src/components/utility/Transition/Transition.helpers.ts +40 -0
- package/src/components/utility/Transition/Transition.tsx +17 -68
- package/src/components/utility/VirtualList/VirtualList.hooks.ts +319 -0
- package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +49 -38
- package/src/components/utility/VirtualList/VirtualList.tsx +110 -315
- package/src/components/utility/WorkflowStep/WorkflowStep.helpers.ts +151 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.parts.tsx +371 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +9 -11
- package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +7 -7
- package/src/components/utility/WorkflowStep/WorkflowStep.tsx +51 -449
- package/src/components/utility/WorkflowStep/WorkflowStepRow.tsx +96 -0
- package/src/components/utility/index.ts +1 -0
- package/src/mui/Link.ts +2 -0
- package/src/utils/index.ts +2 -1
- package/src/utils/viewport.ts +65 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Box, useTheme } from '@mui/material';
|
|
2
|
+
import type { FC, ReactNode, UIEvent } from 'react';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { getOverflowStyle, getVariantStyles } from './ScrollArea.styles';
|
|
6
|
+
import type { ResolvedScrollAreaProps } from './ScrollArea.helpers';
|
|
7
|
+
|
|
8
|
+
export interface ScrollViewportProps
|
|
9
|
+
extends Pick<
|
|
10
|
+
ResolvedScrollAreaProps,
|
|
11
|
+
| 'height'
|
|
12
|
+
| 'maxHeight'
|
|
13
|
+
| 'orientation'
|
|
14
|
+
| 'scrollbarSize'
|
|
15
|
+
| 'scrollbarColor'
|
|
16
|
+
| 'scrollbarTrackColor'
|
|
17
|
+
| 'contentPadding'
|
|
18
|
+
| 'variant'
|
|
19
|
+
| 'disabled'
|
|
20
|
+
| 'loading'
|
|
21
|
+
| 'smoothScroll'
|
|
22
|
+
> {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
shouldShowScrollbar: boolean;
|
|
25
|
+
setScrollRef: (node: HTMLDivElement | null) => void;
|
|
26
|
+
onScroll: (event: UIEvent<HTMLDivElement>) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The element that actually scrolls: its own overflow and scrollbar styling,
|
|
30
|
+
// plus the disabled and loading treatments.
|
|
31
|
+
export const ScrollViewport: FC<ScrollViewportProps> = ({
|
|
32
|
+
children,
|
|
33
|
+
height,
|
|
34
|
+
maxHeight,
|
|
35
|
+
orientation,
|
|
36
|
+
scrollbarSize,
|
|
37
|
+
scrollbarColor,
|
|
38
|
+
scrollbarTrackColor,
|
|
39
|
+
contentPadding,
|
|
40
|
+
variant,
|
|
41
|
+
disabled,
|
|
42
|
+
loading,
|
|
43
|
+
smoothScroll,
|
|
44
|
+
shouldShowScrollbar,
|
|
45
|
+
setScrollRef,
|
|
46
|
+
onScroll,
|
|
47
|
+
}) => {
|
|
48
|
+
const theme = useTheme();
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Box
|
|
52
|
+
ref={setScrollRef}
|
|
53
|
+
onScroll={onScroll}
|
|
54
|
+
role="region"
|
|
55
|
+
aria-label="Scrollable content"
|
|
56
|
+
aria-busy={loading}
|
|
57
|
+
tabIndex={disabled ? -1 : 0}
|
|
58
|
+
sx={{
|
|
59
|
+
width: '100%',
|
|
60
|
+
height: '100%',
|
|
61
|
+
// Use an explicit maxHeight when height is 'auto', else inherit.
|
|
62
|
+
maxHeight: height === 'auto' && maxHeight ? maxHeight : '100%',
|
|
63
|
+
padding: contentPadding,
|
|
64
|
+
opacity: loading ? 0.5 : 1,
|
|
65
|
+
pointerEvents: disabled || loading ? 'none' : 'auto',
|
|
66
|
+
transition: 'opacity 0.3s ease',
|
|
67
|
+
'&:focus': {
|
|
68
|
+
outline: 'none',
|
|
69
|
+
'&:focus-visible': {
|
|
70
|
+
outline: `2px solid ${theme.palette.primary.main}`,
|
|
71
|
+
outlineOffset: -2,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
...getOverflowStyle({ disabled, orientation }),
|
|
75
|
+
...getVariantStyles({
|
|
76
|
+
theme,
|
|
77
|
+
variant,
|
|
78
|
+
orientation,
|
|
79
|
+
scrollbarSize,
|
|
80
|
+
scrollbarColor,
|
|
81
|
+
scrollbarTrackColor,
|
|
82
|
+
shouldShowScrollbar,
|
|
83
|
+
}),
|
|
84
|
+
}}
|
|
85
|
+
style={{ scrollBehavior: smoothScroll ? 'smooth' : 'auto' }}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
</Box>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { CSSObject, Theme } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
SeparatorOrientation,
|
|
5
|
+
SeparatorProps,
|
|
6
|
+
SeparatorSize,
|
|
7
|
+
SeparatorVariant,
|
|
8
|
+
} from './Separator.types';
|
|
9
|
+
|
|
10
|
+
const THICKNESS_PX: Record<SeparatorSize, number> = {
|
|
11
|
+
xs: 1,
|
|
12
|
+
sm: 2,
|
|
13
|
+
md: 3,
|
|
14
|
+
lg: 4,
|
|
15
|
+
xl: 6,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const MARGIN_PX: Record<SeparatorSize, number> = {
|
|
19
|
+
xs: 4,
|
|
20
|
+
sm: 8,
|
|
21
|
+
md: 16,
|
|
22
|
+
lg: 24,
|
|
23
|
+
xl: 32,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const separatorThickness = (size: SeparatorSize): number =>
|
|
27
|
+
THICKNESS_PX[size] ?? THICKNESS_PX.md;
|
|
28
|
+
|
|
29
|
+
/** An explicit `margin` wins; otherwise the size picks one. */
|
|
30
|
+
export const separatorMargin = (
|
|
31
|
+
size: SeparatorSize,
|
|
32
|
+
margin?: number | string,
|
|
33
|
+
): number | string => margin ?? MARGIN_PX[size] ?? MARGIN_PX.md;
|
|
34
|
+
|
|
35
|
+
// `gradient` paints a background rather than a border, so it draws its line as a
|
|
36
|
+
// solid border of zero visual consequence.
|
|
37
|
+
const borderStyleFor = (variant: SeparatorVariant): 'dashed' | 'dotted' | 'solid' => {
|
|
38
|
+
switch (variant) {
|
|
39
|
+
case 'dashed':
|
|
40
|
+
return 'dashed';
|
|
41
|
+
case 'dotted':
|
|
42
|
+
return 'dotted';
|
|
43
|
+
default:
|
|
44
|
+
return 'solid';
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const gradientBackground = (
|
|
49
|
+
variant: SeparatorVariant,
|
|
50
|
+
orientation: SeparatorOrientation,
|
|
51
|
+
color: string,
|
|
52
|
+
): string | undefined => {
|
|
53
|
+
if (variant !== 'gradient') return undefined;
|
|
54
|
+
const angle = orientation === 'horizontal' ? '90deg' : '180deg';
|
|
55
|
+
return `linear-gradient(${angle}, transparent 0%, ${color} 50%, transparent 100%)`;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Only the leading edge carries the rule; the other three are zeroed explicitly so
|
|
59
|
+
// a parent's border shorthand cannot leak through.
|
|
60
|
+
const borderEdges = (
|
|
61
|
+
isHorizontal: boolean,
|
|
62
|
+
thickness: number,
|
|
63
|
+
style: 'dashed' | 'dotted' | 'solid',
|
|
64
|
+
color: string,
|
|
65
|
+
): CSSObject => {
|
|
66
|
+
const leading = isHorizontal ? 'Top' : 'Left';
|
|
67
|
+
const blank: CSSObject = {
|
|
68
|
+
borderTopWidth: 0,
|
|
69
|
+
borderBottomWidth: 0,
|
|
70
|
+
borderLeftWidth: 0,
|
|
71
|
+
borderRightWidth: 0,
|
|
72
|
+
borderTopStyle: 'none',
|
|
73
|
+
borderBottomStyle: 'none',
|
|
74
|
+
borderLeftStyle: 'none',
|
|
75
|
+
borderRightStyle: 'none',
|
|
76
|
+
borderTopColor: 'transparent',
|
|
77
|
+
borderBottomColor: 'transparent',
|
|
78
|
+
borderLeftColor: 'transparent',
|
|
79
|
+
borderRightColor: 'transparent',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
...blank,
|
|
84
|
+
[`border${leading}Width`]: thickness,
|
|
85
|
+
[`border${leading}Style`]: style,
|
|
86
|
+
[`border${leading}Color`]: color,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
type SeparatorStyleArgs = Required<
|
|
91
|
+
Pick<SeparatorProps, 'variant' | 'orientation' | 'size'>
|
|
92
|
+
> &
|
|
93
|
+
Pick<SeparatorProps, 'color' | 'margin' | 'length'>;
|
|
94
|
+
|
|
95
|
+
export const separatorStyles = (
|
|
96
|
+
theme: Theme,
|
|
97
|
+
{ variant, orientation, size, color, margin, length }: SeparatorStyleArgs,
|
|
98
|
+
): CSSObject => {
|
|
99
|
+
const isHorizontal = orientation === 'horizontal';
|
|
100
|
+
const thickness = separatorThickness(size);
|
|
101
|
+
const resolvedColor = color || theme.palette.divider;
|
|
102
|
+
|
|
103
|
+
// A margin given as a string carries its own units; a number is pixels.
|
|
104
|
+
const marginValue = separatorMargin(size, margin);
|
|
105
|
+
const marginStr = typeof marginValue === 'string' ? marginValue : `${marginValue}px`;
|
|
106
|
+
|
|
107
|
+
const baseStyles: CSSObject = {
|
|
108
|
+
display: 'flex',
|
|
109
|
+
alignItems: 'center',
|
|
110
|
+
margin: isHorizontal ? `${marginStr} 0` : `0 ${marginStr}`,
|
|
111
|
+
width: isHorizontal ? length || '100%' : `${thickness}px`,
|
|
112
|
+
height: isHorizontal ? `${thickness}px` : length || '100%',
|
|
113
|
+
boxSizing: 'border-box',
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (variant === 'gradient') {
|
|
117
|
+
return {
|
|
118
|
+
...baseStyles,
|
|
119
|
+
background: gradientBackground(variant, orientation, resolvedColor),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
...baseStyles,
|
|
125
|
+
backgroundColor: 'transparent',
|
|
126
|
+
...borderEdges(isHorizontal, thickness, borderStyleFor(variant), resolvedColor),
|
|
127
|
+
};
|
|
128
|
+
};
|
|
@@ -486,22 +486,13 @@ export const Performance: Story = {
|
|
|
486
486
|
play: async ({ canvasElement, step }) => {
|
|
487
487
|
const canvas = within(canvasElement);
|
|
488
488
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
489
|
+
// This bracketed the query below with performance.now() and asserted a
|
|
490
|
+
// wall-clock budget. That measured the machine, not the component.
|
|
491
|
+
await step('Render multiple separators', async () => {
|
|
492
492
|
const separators = canvas.getAllByRole('separator');
|
|
493
493
|
|
|
494
|
-
const endTime = performance.now();
|
|
495
|
-
|
|
496
|
-
const renderTime = endTime - startTime;
|
|
497
|
-
// eslint-disable-next-line no-console
|
|
498
|
-
console.log(`Render time for ${separators.length} separators: ${renderTime}ms`);
|
|
499
|
-
|
|
500
494
|
// Verify all separators are rendered
|
|
501
495
|
await expect(separators.length).toBe(20);
|
|
502
|
-
|
|
503
|
-
// Assert reasonable render time (adjust threshold as needed)
|
|
504
|
-
await expect(renderTime).toBeLessThan(100);
|
|
505
496
|
});
|
|
506
497
|
|
|
507
498
|
await step('Test memory usage with many separators', async () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Box, Typography,useTheme } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
+
import { separatorMargin, separatorStyles } from './Separator.styles';
|
|
4
5
|
import type { SeparatorProps } from './Separator.types';
|
|
5
6
|
|
|
6
7
|
export const Separator: React.FC<SeparatorProps> = ({
|
|
@@ -15,134 +16,7 @@ export const Separator: React.FC<SeparatorProps> = ({
|
|
|
15
16
|
'data-testid': dataTestId,
|
|
16
17
|
}) => {
|
|
17
18
|
const theme = useTheme();
|
|
18
|
-
|
|
19
|
-
const getThickness = () => {
|
|
20
|
-
switch (size) {
|
|
21
|
-
case 'xs':
|
|
22
|
-
return 1;
|
|
23
|
-
case 'sm':
|
|
24
|
-
return 2;
|
|
25
|
-
case 'md':
|
|
26
|
-
return 3;
|
|
27
|
-
case 'lg':
|
|
28
|
-
return 4;
|
|
29
|
-
case 'xl':
|
|
30
|
-
return 6;
|
|
31
|
-
default:
|
|
32
|
-
return 3;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const getMargin = () => {
|
|
37
|
-
if (margin !== undefined) return margin;
|
|
38
|
-
switch (size) {
|
|
39
|
-
case 'xs':
|
|
40
|
-
return 4; // 0.5 * 8 = 4px
|
|
41
|
-
case 'sm':
|
|
42
|
-
return 8; // 1 * 8 = 8px
|
|
43
|
-
case 'md':
|
|
44
|
-
return 16; // 2 * 8 = 16px
|
|
45
|
-
case 'lg':
|
|
46
|
-
return 24; // 3 * 8 = 24px
|
|
47
|
-
case 'xl':
|
|
48
|
-
return 32; // 4 * 8 = 32px
|
|
49
|
-
default:
|
|
50
|
-
return 16;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const getBorderStyle = () => {
|
|
55
|
-
switch (variant) {
|
|
56
|
-
case 'dashed':
|
|
57
|
-
return 'dashed';
|
|
58
|
-
case 'dotted':
|
|
59
|
-
return 'dotted';
|
|
60
|
-
case 'gradient':
|
|
61
|
-
return 'solid';
|
|
62
|
-
default:
|
|
63
|
-
return 'solid';
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const getColor = () => {
|
|
68
|
-
if (color) return color;
|
|
69
|
-
return theme.palette.divider;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const getGradientBackground = () => {
|
|
73
|
-
if (variant !== 'gradient') return undefined;
|
|
74
|
-
|
|
75
|
-
if (orientation === 'horizontal') {
|
|
76
|
-
return `linear-gradient(90deg, transparent 0%, ${getColor()} 50%, transparent 100%)`;
|
|
77
|
-
} else {
|
|
78
|
-
return `linear-gradient(180deg, transparent 0%, ${getColor()} 50%, transparent 100%)`;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const getSeparatorStyles = () => {
|
|
83
|
-
const isHorizontal = orientation === 'horizontal';
|
|
84
|
-
const thickness = getThickness();
|
|
85
|
-
const marginValue = getMargin();
|
|
86
|
-
|
|
87
|
-
// Handle margin - if it's a string with units, use as-is, otherwise add px
|
|
88
|
-
const marginStr = typeof marginValue === 'string' ? marginValue : `${marginValue}px`;
|
|
89
|
-
|
|
90
|
-
const baseStyles = {
|
|
91
|
-
display: 'flex' as const,
|
|
92
|
-
alignItems: 'center' as const,
|
|
93
|
-
margin: isHorizontal ? `${marginStr} 0` : `0 ${marginStr}`,
|
|
94
|
-
width: isHorizontal ? length || '100%' : `${thickness}px`,
|
|
95
|
-
height: isHorizontal ? `${thickness}px` : length || '100%',
|
|
96
|
-
boxSizing: 'border-box' as const,
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
if (variant === 'gradient') {
|
|
100
|
-
return {
|
|
101
|
-
...baseStyles,
|
|
102
|
-
background: getGradientBackground(),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Apply border styles separately for better compatibility with MUI's sx prop
|
|
107
|
-
const borderStyle = getBorderStyle();
|
|
108
|
-
const borderColor = getColor();
|
|
109
|
-
|
|
110
|
-
const borderStyles = isHorizontal
|
|
111
|
-
? {
|
|
112
|
-
borderTopWidth: thickness,
|
|
113
|
-
borderTopStyle: borderStyle,
|
|
114
|
-
borderTopColor: borderColor,
|
|
115
|
-
borderBottomWidth: 0,
|
|
116
|
-
borderLeftWidth: 0,
|
|
117
|
-
borderRightWidth: 0,
|
|
118
|
-
borderBottomStyle: 'none',
|
|
119
|
-
borderLeftStyle: 'none',
|
|
120
|
-
borderRightStyle: 'none',
|
|
121
|
-
borderBottomColor: 'transparent',
|
|
122
|
-
borderLeftColor: 'transparent',
|
|
123
|
-
borderRightColor: 'transparent',
|
|
124
|
-
}
|
|
125
|
-
: {
|
|
126
|
-
borderLeftWidth: thickness,
|
|
127
|
-
borderLeftStyle: borderStyle,
|
|
128
|
-
borderLeftColor: borderColor,
|
|
129
|
-
borderTopWidth: 0,
|
|
130
|
-
borderBottomWidth: 0,
|
|
131
|
-
borderRightWidth: 0,
|
|
132
|
-
borderTopStyle: 'none',
|
|
133
|
-
borderBottomStyle: 'none',
|
|
134
|
-
borderRightStyle: 'none',
|
|
135
|
-
borderTopColor: 'transparent',
|
|
136
|
-
borderBottomColor: 'transparent',
|
|
137
|
-
borderRightColor: 'transparent',
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
...baseStyles,
|
|
142
|
-
backgroundColor: 'transparent' as const,
|
|
143
|
-
...borderStyles,
|
|
144
|
-
};
|
|
145
|
-
};
|
|
19
|
+
const styles = separatorStyles(theme, { variant, orientation, size, color, margin, length });
|
|
146
20
|
|
|
147
21
|
if (children) {
|
|
148
22
|
const isHorizontal = orientation === 'horizontal';
|
|
@@ -153,12 +27,12 @@ export const Separator: React.FC<SeparatorProps> = ({
|
|
|
153
27
|
sx={{
|
|
154
28
|
display: 'flex',
|
|
155
29
|
alignItems: 'center',
|
|
156
|
-
margin:
|
|
30
|
+
margin: separatorMargin(size, margin),
|
|
157
31
|
flexDirection: isHorizontal ? 'row' : 'column',
|
|
158
32
|
gap: theme.spacing(2),
|
|
159
33
|
}}
|
|
160
34
|
>
|
|
161
|
-
<Box sx={
|
|
35
|
+
<Box sx={styles} />
|
|
162
36
|
<Typography
|
|
163
37
|
variant="body2"
|
|
164
38
|
color="text.secondary"
|
|
@@ -170,7 +44,7 @@ export const Separator: React.FC<SeparatorProps> = ({
|
|
|
170
44
|
>
|
|
171
45
|
{children}
|
|
172
46
|
</Typography>
|
|
173
|
-
<Box sx={
|
|
47
|
+
<Box sx={styles} />
|
|
174
48
|
</Box>
|
|
175
49
|
);
|
|
176
50
|
}
|
|
@@ -178,7 +52,7 @@ export const Separator: React.FC<SeparatorProps> = ({
|
|
|
178
52
|
return (
|
|
179
53
|
<Box
|
|
180
54
|
className={className}
|
|
181
|
-
sx={
|
|
55
|
+
sx={styles}
|
|
182
56
|
role="separator"
|
|
183
57
|
aria-orientation={orientation}
|
|
184
58
|
data-testid={dataTestId}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
PersonOutlined,
|
|
8
|
-
} from '@mui/icons-material';
|
|
1
|
+
import LanguageOutlined from '@mui/icons-material/LanguageOutlined';
|
|
2
|
+
import LockOutlined from '@mui/icons-material/LockOutlined';
|
|
3
|
+
import NotificationsOutlined from '@mui/icons-material/NotificationsOutlined';
|
|
4
|
+
import PaletteOutlined from '@mui/icons-material/PaletteOutlined';
|
|
5
|
+
import PaymentOutlined from '@mui/icons-material/PaymentOutlined';
|
|
6
|
+
import PersonOutlined from '@mui/icons-material/PersonOutlined';
|
|
9
7
|
import { Box, Stack, Typography } from '@mui/material';
|
|
10
8
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
11
9
|
import React, { useState } from 'react';
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Star as StarIcon,
|
|
12
|
-
} from '@mui/icons-material';
|
|
1
|
+
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
|
2
|
+
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
|
3
|
+
import DashboardIcon from '@mui/icons-material/Dashboard';
|
|
4
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
5
|
+
import InboxIcon from '@mui/icons-material/Inbox';
|
|
6
|
+
import MenuIcon from '@mui/icons-material/Menu';
|
|
7
|
+
import PersonIcon from '@mui/icons-material/Person';
|
|
8
|
+
import SendIcon from '@mui/icons-material/Send';
|
|
9
|
+
import SettingsIcon from '@mui/icons-material/Settings';
|
|
10
|
+
import StarIcon from '@mui/icons-material/Star';
|
|
13
11
|
import {
|
|
14
12
|
Avatar,
|
|
15
13
|
Box,
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Star as StarIcon,
|
|
12
|
-
} from '@mui/icons-material';
|
|
1
|
+
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
|
2
|
+
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
|
3
|
+
import DashboardIcon from '@mui/icons-material/Dashboard';
|
|
4
|
+
import HomeIcon from '@mui/icons-material/Home';
|
|
5
|
+
import InboxIcon from '@mui/icons-material/Inbox';
|
|
6
|
+
import MenuIcon from '@mui/icons-material/Menu';
|
|
7
|
+
import PersonIcon from '@mui/icons-material/Person';
|
|
8
|
+
import SendIcon from '@mui/icons-material/Send';
|
|
9
|
+
import SettingsIcon from '@mui/icons-material/Settings';
|
|
10
|
+
import StarIcon from '@mui/icons-material/Star';
|
|
13
11
|
import {
|
|
14
12
|
Avatar,
|
|
15
13
|
Box,
|
|
@@ -265,35 +263,35 @@ export const KeyboardNavigation: Story = {
|
|
|
265
263
|
play: async ({ canvasElement }) => {
|
|
266
264
|
const canvas = within(canvasElement);
|
|
267
265
|
|
|
268
|
-
// Test Tab navigation through sidebar items
|
|
266
|
+
// Test Tab navigation through sidebar items. The first nav item is the
|
|
267
|
+
// first focusable node in the story, so tabbing in from the body reaches it
|
|
268
|
+
// — the old .focus() call asserted only that focus() works.
|
|
269
269
|
const firstNavItem = canvas.getByTestId('keyboard-nav-home');
|
|
270
|
-
|
|
271
|
-
await expect(firstNavItem).toHaveFocus();
|
|
270
|
+
await userEvent.tab();
|
|
271
|
+
await waitFor(() => expect(firstNavItem).toHaveFocus());
|
|
272
|
+
|
|
273
|
+
// Enter key activation, checked here while focus is already on the item
|
|
274
|
+
// rather than by re-focusing it at the end of the journey.
|
|
275
|
+
await userEvent.keyboard('{Enter}');
|
|
276
|
+
await expect(firstNavItem).toBeInTheDocument();
|
|
272
277
|
|
|
273
278
|
// Tab to next item
|
|
274
279
|
await userEvent.tab();
|
|
275
|
-
await expect(canvas.getByTestId('keyboard-nav-dashboard')).toHaveFocus();
|
|
280
|
+
await waitFor(() => expect(canvas.getByTestId('keyboard-nav-dashboard')).toHaveFocus());
|
|
276
281
|
|
|
277
282
|
// Tab to next item
|
|
278
283
|
await userEvent.tab();
|
|
279
|
-
await expect(canvas.getByTestId('keyboard-nav-inbox')).toHaveFocus();
|
|
284
|
+
await waitFor(() => expect(canvas.getByTestId('keyboard-nav-inbox')).toHaveFocus());
|
|
280
285
|
|
|
281
286
|
// Tab to footer button
|
|
282
287
|
await userEvent.tab();
|
|
283
288
|
await userEvent.tab();
|
|
284
289
|
await userEvent.tab();
|
|
285
|
-
await expect(canvas.getByTestId('footer-button')).toHaveFocus();
|
|
290
|
+
await waitFor(() => expect(canvas.getByTestId('footer-button')).toHaveFocus());
|
|
286
291
|
|
|
287
292
|
// Tab to main content
|
|
288
293
|
await userEvent.tab();
|
|
289
|
-
await expect(canvas.getByTestId('main-button')).toHaveFocus();
|
|
290
|
-
|
|
291
|
-
// Test Enter key activation
|
|
292
|
-
const homeItem = canvas.getByTestId('keyboard-nav-home');
|
|
293
|
-
homeItem.focus();
|
|
294
|
-
await userEvent.keyboard('{Enter}');
|
|
295
|
-
// Verify item is still accessible after Enter
|
|
296
|
-
await expect(homeItem).toBeInTheDocument();
|
|
294
|
+
await waitFor(() => expect(canvas.getByTestId('main-button')).toHaveFocus());
|
|
297
295
|
},
|
|
298
296
|
};
|
|
299
297
|
|
|
@@ -460,22 +458,22 @@ export const FocusManagement: Story = {
|
|
|
460
458
|
|
|
461
459
|
// Test initial focus on first sidebar item
|
|
462
460
|
const firstItem = canvas.getByTestId('focus-nav-home');
|
|
463
|
-
|
|
464
|
-
await expect(firstItem).toHaveFocus();
|
|
461
|
+
await userEvent.tab();
|
|
462
|
+
await waitFor(() => expect(firstItem).toHaveFocus());
|
|
465
463
|
|
|
466
464
|
// Test focus moves through sidebar elements
|
|
467
465
|
await userEvent.tab();
|
|
468
|
-
await expect(canvas.getByTestId('focus-nav-dashboard')).toHaveFocus();
|
|
466
|
+
await waitFor(() => expect(canvas.getByTestId('focus-nav-dashboard')).toHaveFocus());
|
|
469
467
|
|
|
470
468
|
await userEvent.tab();
|
|
471
|
-
await expect(canvas.getByTestId('focus-nav-inbox')).toHaveFocus();
|
|
469
|
+
await waitFor(() => expect(canvas.getByTestId('focus-nav-inbox')).toHaveFocus());
|
|
472
470
|
|
|
473
471
|
await userEvent.tab();
|
|
474
|
-
await expect(canvas.getByTestId('sidebar-action')).toHaveFocus();
|
|
472
|
+
await waitFor(() => expect(canvas.getByTestId('sidebar-action')).toHaveFocus());
|
|
475
473
|
|
|
476
474
|
// Test focus moves to main content
|
|
477
475
|
await userEvent.tab();
|
|
478
|
-
await expect(canvas.getByTestId('main-focus-button')).toHaveFocus();
|
|
476
|
+
await waitFor(() => expect(canvas.getByTestId('main-focus-button')).toHaveFocus());
|
|
479
477
|
|
|
480
478
|
// Test hiding sidebar
|
|
481
479
|
const hideButton = canvas.getByTestId('hide-sidebar-button');
|
|
@@ -791,8 +789,7 @@ export const VisualStates: Story = {
|
|
|
791
789
|
await expect(canvas.getByTestId('expanded-footer')).toBeInTheDocument();
|
|
792
790
|
|
|
793
791
|
// Test sidebar width when expanded
|
|
794
|
-
|
|
795
|
-
await expect(sidebarStyles.width).toBe('280px');
|
|
792
|
+
await expect(window.getComputedStyle(sidebar).width).toBe('280px');
|
|
796
793
|
|
|
797
794
|
// Test collapsing
|
|
798
795
|
const collapseToggle = canvas.getByTestId('collapse-toggle');
|
|
@@ -802,10 +799,11 @@ export const VisualStates: Story = {
|
|
|
802
799
|
expect(canvas.getByTestId('collapse-status')).toHaveTextContent('Sidebar is collapsed');
|
|
803
800
|
});
|
|
804
801
|
|
|
805
|
-
// Test sidebar width when collapsed
|
|
802
|
+
// Test sidebar width when collapsed. Read the computed style inside the
|
|
803
|
+
// waitFor rather than reassigning an outer variable from it — the callback
|
|
804
|
+
// reruns, so the shared binding held whichever value the last retry left.
|
|
806
805
|
await waitFor(() => {
|
|
807
|
-
|
|
808
|
-
expect(sidebarStyles.width).toBe('64px');
|
|
806
|
+
expect(window.getComputedStyle(sidebar).width).toBe('64px');
|
|
809
807
|
});
|
|
810
808
|
|
|
811
809
|
// Test collapsed avatar is visible
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SkeletonProps } from './Skeleton.types';
|
|
2
|
+
|
|
3
|
+
type SkeletonDefaultedKeys =
|
|
4
|
+
| 'variant'
|
|
5
|
+
| 'animation'
|
|
6
|
+
| 'count'
|
|
7
|
+
| 'spacing'
|
|
8
|
+
| 'intensity'
|
|
9
|
+
| 'glassmorphism'
|
|
10
|
+
| 'shimmer';
|
|
11
|
+
|
|
12
|
+
type ResolvedSkeletonProps = SkeletonProps &
|
|
13
|
+
Required<Pick<SkeletonProps, SkeletonDefaultedKeys>>;
|
|
14
|
+
|
|
15
|
+
const SKELETON_DEFAULTS: Pick<SkeletonProps, SkeletonDefaultedKeys> = {
|
|
16
|
+
variant: 'text',
|
|
17
|
+
animation: 'pulse',
|
|
18
|
+
count: 1,
|
|
19
|
+
spacing: 1,
|
|
20
|
+
intensity: 'medium',
|
|
21
|
+
glassmorphism: false,
|
|
22
|
+
shimmer: false,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Strips explicitly-undefined props before the merge, so `count={undefined}` still
|
|
26
|
+
// falls back to the default exactly as a destructuring default would.
|
|
27
|
+
const definedProps = (props: SkeletonProps): Partial<SkeletonProps> =>
|
|
28
|
+
Object.fromEntries(
|
|
29
|
+
Object.entries(props).filter(([, value]) => value !== undefined),
|
|
30
|
+
) as Partial<SkeletonProps>;
|
|
31
|
+
|
|
32
|
+
export const resolveSkeletonProps = (props: SkeletonProps): ResolvedSkeletonProps =>
|
|
33
|
+
({ ...SKELETON_DEFAULTS, ...definedProps(props) }) as ResolvedSkeletonProps;
|