@sovereignfs/ui 0.83.1 → 0.89.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -661
- package/NOTICE +8 -0
- package/README.md +4 -6
- package/dist/AppsLauncher.module.css +6 -0
- package/dist/Button.module.css +5 -0
- package/dist/Card.module.css +6 -0
- package/dist/CardTile.module.css +6 -0
- package/dist/CheckableListRow.module.css +8 -0
- package/dist/Checkbox.module.css +8 -0
- package/dist/CodeTextarea.module.css +6 -0
- package/dist/ColorPicker.module.css +6 -0
- package/dist/Combobox.module.css +6 -0
- package/dist/Command.module.css +6 -0
- package/dist/ConfirmDialog.module.css +6 -0
- package/dist/DatePicker.module.css +6 -0
- package/dist/Dialog.module.css +1 -1
- package/dist/DragHandleRow.module.css +6 -0
- package/dist/FileDropzone.module.css +25 -1
- package/dist/Header.module.css +6 -0
- package/dist/IconPicker.module.css +14 -4
- package/dist/Input.module.css +6 -0
- package/dist/LegalLinks.module.css +9 -2
- package/dist/Markdown.module.css +5 -0
- package/dist/Message.module.css +9 -0
- package/dist/MobileAppsDrawer.module.css +9 -5
- package/dist/MobileFooter.module.css +6 -0
- package/dist/NavList.module.css +11 -2
- package/dist/NavTabs.module.css +7 -1
- package/dist/NotificationsPanel.module.css +10 -0
- package/dist/QrCode.module.css +17 -0
- package/dist/QuantityStepper.module.css +4 -2
- package/dist/RadioGroup.module.css +6 -0
- package/dist/SegmentedControl.module.css +6 -0
- package/dist/Select.module.css +6 -0
- package/dist/Sheet.module.css +16 -1
- package/dist/SplitPane.module.css +1 -1
- package/dist/StepStrip.module.css +5 -3
- package/dist/SuggestionInput.module.css +12 -1
- package/dist/SwipableMobileCarouselDots.module.css +6 -0
- package/dist/SystemBanner.module.css +6 -0
- package/dist/Tabs.module.css +6 -0
- package/dist/TagInput.module.css +6 -0
- package/dist/Textarea.module.css +6 -0
- package/dist/Toast.module.css +5 -0
- package/dist/Toggle.module.css +7 -0
- package/dist/Tooltip.module.css +6 -0
- package/dist/UserMenu.module.css +5 -0
- package/dist/fonts/OFL.txt +93 -0
- package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
- package/dist/index.d.ts +121 -43
- package/dist/index.js +1410 -1152
- package/dist/tokens/fonts.css +53 -0
- package/dist/tokens/primitives.css +12 -12
- package/dist/tokens.css +2 -1
- package/package.json +24 -13
- package/src/__tests__/motion.test.tsx +0 -105
- package/src/__tests__/package-json.test.ts +0 -8
- package/src/components/Accordion/Accordion.module.css +0 -3
- package/src/components/Accordion/Accordion.stories.tsx +0 -110
- package/src/components/Accordion/Accordion.tsx +0 -53
- package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
- package/src/components/Alert/Alert.module.css +0 -62
- package/src/components/Alert/Alert.stories.tsx +0 -96
- package/src/components/Alert/Alert.tsx +0 -58
- package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
- package/src/components/AppsLauncher/AppsLauncher.module.css +0 -96
- package/src/components/AppsLauncher/AppsLauncher.stories.tsx +0 -58
- package/src/components/AppsLauncher/AppsLauncher.tsx +0 -117
- package/src/components/AppsLauncher/__tests__/AppsLauncher.test.tsx +0 -52
- package/src/components/AspectRatio/AspectRatio.module.css +0 -15
- package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
- package/src/components/AspectRatio/AspectRatio.tsx +0 -21
- package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
- package/src/components/Avatar/Avatar.module.css +0 -38
- package/src/components/Avatar/Avatar.tsx +0 -42
- package/src/components/Badge/Badge.module.css +0 -177
- package/src/components/Badge/Badge.stories.tsx +0 -238
- package/src/components/Badge/Badge.tsx +0 -84
- package/src/components/Badge/__tests__/Badge.test.tsx +0 -90
- package/src/components/BalanceChip/BalanceChip.module.css +0 -32
- package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
- package/src/components/BalanceChip/BalanceChip.tsx +0 -33
- package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
- package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
- package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
- package/src/components/Button/Button.module.css +0 -169
- package/src/components/Button/Button.stories.tsx +0 -83
- package/src/components/Button/Button.tsx +0 -52
- package/src/components/Button/__tests__/Button.test.tsx +0 -66
- package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
- package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
- package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
- package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
- package/src/components/Calendar/Calendar.module.css +0 -126
- package/src/components/Calendar/Calendar.tsx +0 -213
- package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
- package/src/components/Calendar/dateUtils.ts +0 -97
- package/src/components/Card/Card.module.css +0 -42
- package/src/components/Card/Card.tsx +0 -34
- package/src/components/CardTile/CardTile.module.css +0 -181
- package/src/components/CardTile/CardTile.stories.tsx +0 -86
- package/src/components/CardTile/CardTile.tsx +0 -128
- package/src/components/CardTile/__tests__/CardTile.test.tsx +0 -56
- package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
- package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
- package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
- package/src/components/Checkbox/Checkbox.module.css +0 -111
- package/src/components/Checkbox/Checkbox.tsx +0 -78
- package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
- package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
- package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
- package/src/components/Collapsible/Collapsible.module.css +0 -70
- package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
- package/src/components/Collapsible/Collapsible.tsx +0 -66
- package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
- package/src/components/ColorPicker/ColorPicker.module.css +0 -132
- package/src/components/ColorPicker/ColorPicker.stories.tsx +0 -80
- package/src/components/ColorPicker/ColorPicker.tsx +0 -157
- package/src/components/ColorPicker/__tests__/ColorPicker.test.tsx +0 -117
- package/src/components/Combobox/Combobox.module.css +0 -122
- package/src/components/Combobox/Combobox.stories.tsx +0 -79
- package/src/components/Combobox/Combobox.tsx +0 -186
- package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
- package/src/components/Command/Command.module.css +0 -80
- package/src/components/Command/Command.stories.tsx +0 -104
- package/src/components/Command/Command.tsx +0 -168
- package/src/components/Command/__tests__/Command.test.tsx +0 -162
- package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -150
- package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -214
- package/src/components/ConsentPrompt/ConsentPrompt.module.css +0 -21
- package/src/components/ConsentPrompt/ConsentPrompt.stories.tsx +0 -31
- package/src/components/ConsentPrompt/ConsentPrompt.tsx +0 -66
- package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
- package/src/components/ContextMenu/ContextMenu.tsx +0 -100
- package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
- package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
- package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
- package/src/components/DataTable/DataTable.module.css +0 -28
- package/src/components/DataTable/DataTable.stories.tsx +0 -74
- package/src/components/DataTable/DataTable.tsx +0 -154
- package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
- package/src/components/DatePicker/DatePicker.module.css +0 -61
- package/src/components/DatePicker/DatePicker.tsx +0 -103
- package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
- package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
- package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
- package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
- package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
- package/src/components/Dialog/Dialog.module.css +0 -335
- package/src/components/Dialog/Dialog.stories.tsx +0 -324
- package/src/components/Dialog/Dialog.tsx +0 -254
- package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -318
- package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
- package/src/components/DragHandleRow/DragHandleRow.tsx +0 -42
- package/src/components/Drawer/Drawer.module.css +0 -121
- package/src/components/Drawer/Drawer.stories.tsx +0 -132
- package/src/components/Drawer/Drawer.tsx +0 -175
- package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -226
- package/src/components/EmptyState/EmptyState.module.css +0 -27
- package/src/components/EmptyState/EmptyState.tsx +0 -27
- package/src/components/FileDropzone/FileDropzone.module.css +0 -63
- package/src/components/FileDropzone/FileDropzone.tsx +0 -109
- package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
- package/src/components/FormField/FormField.module.css +0 -33
- package/src/components/FormField/FormField.tsx +0 -78
- package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
- package/src/components/GripIcon/GripIcon.tsx +0 -27
- package/src/components/Header/Header.module.css +0 -62
- package/src/components/Header/Header.stories.tsx +0 -452
- package/src/components/Header/Header.tsx +0 -102
- package/src/components/Header/__tests__/Header.test.tsx +0 -104
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.module.css +0 -21
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.stories.tsx +0 -111
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.tsx +0 -54
- package/src/components/HeaderFooterLayout/__tests__/HeaderFooterLayout.test.tsx +0 -58
- package/src/components/HoverCard/HoverCard.module.css +0 -3
- package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
- package/src/components/HoverCard/HoverCard.tsx +0 -111
- package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
- package/src/components/Icon/Icon.module.css +0 -27
- package/src/components/Icon/Icon.stories.tsx +0 -95
- package/src/components/Icon/Icon.tsx +0 -43
- package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
- package/src/components/Icon/icons/activity.tsx +0 -20
- package/src/components/Icon/icons/alert-triangle.tsx +0 -22
- package/src/components/Icon/icons/apple.tsx +0 -21
- package/src/components/Icon/icons/arrow-left-right.tsx +0 -23
- package/src/components/Icon/icons/banana.tsx +0 -21
- package/src/components/Icon/icons/beef.tsx +0 -22
- package/src/components/Icon/icons/beer.tsx +0 -24
- package/src/components/Icon/icons/bell.tsx +0 -21
- package/src/components/Icon/icons/bold.tsx +0 -20
- package/src/components/Icon/icons/calendar.tsx +0 -23
- package/src/components/Icon/icons/candy.tsx +0 -24
- package/src/components/Icon/icons/carrot.tsx +0 -22
- package/src/components/Icon/icons/check.tsx +0 -20
- package/src/components/Icon/icons/chevron-down.tsx +0 -20
- package/src/components/Icon/icons/chevron-left.tsx +0 -20
- package/src/components/Icon/icons/chevron-right.tsx +0 -20
- package/src/components/Icon/icons/chevron-up.tsx +0 -20
- package/src/components/Icon/icons/circle-check.tsx +0 -21
- package/src/components/Icon/icons/circle-chevron-left.tsx +0 -21
- package/src/components/Icon/icons/circle-x.tsx +0 -22
- package/src/components/Icon/icons/code.tsx +0 -21
- package/src/components/Icon/icons/coffee.tsx +0 -23
- package/src/components/Icon/icons/cookie.tsx +0 -25
- package/src/components/Icon/icons/copy.tsx +0 -21
- package/src/components/Icon/icons/credit-card.tsx +0 -21
- package/src/components/Icon/icons/croissant.tsx +0 -24
- package/src/components/Icon/icons/cup-soda.tsx +0 -23
- package/src/components/Icon/icons/database.tsx +0 -22
- package/src/components/Icon/icons/download.tsx +0 -22
- package/src/components/Icon/icons/drumstick.tsx +0 -21
- package/src/components/Icon/icons/egg.tsx +0 -20
- package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
- package/src/components/Icon/icons/external-link.tsx +0 -22
- package/src/components/Icon/icons/eye-off.tsx +0 -23
- package/src/components/Icon/icons/eye.tsx +0 -21
- package/src/components/Icon/icons/file-text.tsx +0 -24
- package/src/components/Icon/icons/file.tsx +0 -21
- package/src/components/Icon/icons/fish.tsx +0 -25
- package/src/components/Icon/icons/folder-closed.tsx +0 -21
- package/src/components/Icon/icons/folder-open.tsx +0 -20
- package/src/components/Icon/icons/folder.tsx +0 -20
- package/src/components/Icon/icons/folders.tsx +0 -21
- package/src/components/Icon/icons/grid-2x2.tsx +0 -22
- package/src/components/Icon/icons/hat-glasses.tsx +0 -24
- package/src/components/Icon/icons/history.tsx +0 -22
- package/src/components/Icon/icons/house.tsx +0 -21
- package/src/components/Icon/icons/inbox.tsx +0 -21
- package/src/components/Icon/icons/index.ts +0 -394
- package/src/components/Icon/icons/info.tsx +0 -22
- package/src/components/Icon/icons/italic.tsx +0 -22
- package/src/components/Icon/icons/layers.tsx +0 -22
- package/src/components/Icon/icons/layout-dashboard.tsx +0 -23
- package/src/components/Icon/icons/layout-grid.tsx +0 -23
- package/src/components/Icon/icons/link.tsx +0 -21
- package/src/components/Icon/icons/list-ordered.tsx +0 -25
- package/src/components/Icon/icons/list.tsx +0 -25
- package/src/components/Icon/icons/lock.tsx +0 -21
- package/src/components/Icon/icons/log-out.tsx +0 -22
- package/src/components/Icon/icons/luggage.tsx +0 -24
- package/src/components/Icon/icons/mail.tsx +0 -21
- package/src/components/Icon/icons/map-pin.tsx +0 -21
- package/src/components/Icon/icons/menu.tsx +0 -22
- package/src/components/Icon/icons/milk.tsx +0 -22
- package/src/components/Icon/icons/minus.tsx +0 -20
- package/src/components/Icon/icons/package.tsx +0 -23
- package/src/components/Icon/icons/paint-bucket.tsx +0 -23
- package/src/components/Icon/icons/panel-left.tsx +0 -21
- package/src/components/Icon/icons/pencil.tsx +0 -21
- package/src/components/Icon/icons/pin.tsx +0 -21
- package/src/components/Icon/icons/pizza.tsx +0 -24
- package/src/components/Icon/icons/plus.tsx +0 -21
- package/src/components/Icon/icons/rectangle-ellipsis.tsx +0 -23
- package/src/components/Icon/icons/refresh-cw.tsx +0 -23
- package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
- package/src/components/Icon/icons/rotate-cw.tsx +0 -21
- package/src/components/Icon/icons/route.tsx +0 -22
- package/src/components/Icon/icons/salad.tsx +0 -24
- package/src/components/Icon/icons/search.tsx +0 -21
- package/src/components/Icon/icons/send.tsx +0 -21
- package/src/components/Icon/icons/settings.tsx +0 -21
- package/src/components/Icon/icons/share-2.tsx +0 -24
- package/src/components/Icon/icons/sheet.tsx +0 -24
- package/src/components/Icon/icons/shield.tsx +0 -20
- package/src/components/Icon/icons/shopping-basket.tsx +0 -26
- package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
- package/src/components/Icon/icons/smartphone.tsx +0 -21
- package/src/components/Icon/icons/snowflake.tsx +0 -31
- package/src/components/Icon/icons/spray-can.tsx +0 -29
- package/src/components/Icon/icons/square-kanban.tsx +0 -23
- package/src/components/Icon/icons/table.tsx +0 -23
- package/src/components/Icon/icons/trash-2.tsx +0 -24
- package/src/components/Icon/icons/upload.tsx +0 -22
- package/src/components/Icon/icons/user-round-plus.tsx +0 -23
- package/src/components/Icon/icons/user.tsx +0 -21
- package/src/components/Icon/icons/users.tsx +0 -23
- package/src/components/Icon/icons/wine.tsx +0 -23
- package/src/components/Icon/icons/x.tsx +0 -21
- package/src/components/IconPicker/IconPicker.module.css +0 -63
- package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
- package/src/components/IconPicker/IconPicker.tsx +0 -90
- package/src/components/Input/Input.module.css +0 -52
- package/src/components/Input/Input.stories.tsx +0 -86
- package/src/components/Input/Input.tsx +0 -20
- package/src/components/Input/__tests__/Input.test.tsx +0 -22
- package/src/components/Item/Item.module.css +0 -70
- package/src/components/Item/Item.stories.tsx +0 -62
- package/src/components/Item/Item.tsx +0 -54
- package/src/components/Item/__tests__/Item.test.tsx +0 -39
- package/src/components/Kbd/Kbd.module.css +0 -14
- package/src/components/Kbd/Kbd.stories.tsx +0 -32
- package/src/components/Kbd/Kbd.tsx +0 -12
- package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
- package/src/components/Label/Label.module.css +0 -11
- package/src/components/Label/Label.stories.tsx +0 -40
- package/src/components/Label/Label.tsx +0 -24
- package/src/components/Label/__tests__/Label.test.tsx +0 -32
- package/src/components/LegalLinks/LegalLinks.module.css +0 -24
- package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
- package/src/components/LegalLinks/LegalLinks.tsx +0 -40
- package/src/components/Markdown/Markdown.module.css +0 -73
- package/src/components/Markdown/Markdown.stories.tsx +0 -40
- package/src/components/Markdown/Markdown.tsx +0 -305
- package/src/components/Markdown/__tests__/Markdown.test.tsx +0 -144
- package/src/components/Marker/Marker.module.css +0 -33
- package/src/components/Marker/Marker.stories.tsx +0 -39
- package/src/components/Marker/Marker.tsx +0 -34
- package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
- package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
- package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
- package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
- package/src/components/Menu/Menu.module.css +0 -90
- package/src/components/Menu/Menu.tsx +0 -209
- package/src/components/Menu/__tests__/Menu.test.tsx +0 -227
- package/src/components/Menubar/Menubar.stories.tsx +0 -52
- package/src/components/Menubar/Menubar.tsx +0 -42
- package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
- package/src/components/Message/Message.module.css +0 -99
- package/src/components/Message/Message.stories.tsx +0 -79
- package/src/components/Message/Message.tsx +0 -41
- package/src/components/Message/__tests__/Message.test.tsx +0 -46
- package/src/components/MessageScroller/MessageScroller.module.css +0 -65
- package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
- package/src/components/MessageScroller/MessageScroller.tsx +0 -84
- package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -82
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
- package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
- package/src/components/MobileFooter/MobileFooter.module.css +0 -73
- package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
- package/src/components/MobileFooter/MobileFooter.tsx +0 -122
- package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -129
- package/src/components/MobileHeader/MobileHeader.module.css +0 -76
- package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
- package/src/components/MobileHeader/MobileHeader.tsx +0 -90
- package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -113
- package/src/components/NavList/NavList.module.css +0 -130
- package/src/components/NavList/NavList.tsx +0 -136
- package/src/components/NavList/__tests__/NavList.test.tsx +0 -109
- package/src/components/NavTabs/NavTabs.module.css +0 -50
- package/src/components/NavTabs/NavTabs.tsx +0 -61
- package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
- package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
- package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
- package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
- package/src/components/NotificationsPanel/NotificationsPanel.module.css +0 -258
- package/src/components/NotificationsPanel/NotificationsPanel.stories.tsx +0 -61
- package/src/components/NotificationsPanel/NotificationsPanel.tsx +0 -187
- package/src/components/NotificationsPanel/__tests__/NotificationsPanel.test.tsx +0 -78
- package/src/components/OfflineGate/OfflineGate.tsx +0 -44
- package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
- package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
- package/src/components/OverlayHeader/OverlayHeader.tsx +0 -77
- package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -69
- package/src/components/PageContainer/PageContainer.module.css +0 -82
- package/src/components/PageContainer/PageContainer.tsx +0 -64
- package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -70
- package/src/components/PageHeader/PageHeader.module.css +0 -86
- package/src/components/PageHeader/PageHeader.tsx +0 -176
- package/src/components/PageHeader/__tests__/PageHeader.test.tsx +0 -103
- package/src/components/PageLayout/PageLayout.module.css +0 -51
- package/src/components/PageLayout/PageLayout.stories.tsx +0 -73
- package/src/components/PageLayout/PageLayout.tsx +0 -51
- package/src/components/PageLayout/__tests__/PageLayout.test.tsx +0 -34
- package/src/components/Pagination/Pagination.module.css +0 -98
- package/src/components/Pagination/Pagination.stories.tsx +0 -49
- package/src/components/Pagination/Pagination.tsx +0 -87
- package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
- package/src/components/Popover/Popover.module.css +0 -74
- package/src/components/Popover/Popover.stories.tsx +0 -357
- package/src/components/Popover/Popover.tsx +0 -290
- package/src/components/Popover/__tests__/Popover.test.tsx +0 -263
- package/src/components/Progress/Progress.module.css +0 -20
- package/src/components/Progress/Progress.stories.tsx +0 -40
- package/src/components/Progress/Progress.tsx +0 -35
- package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
- package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
- package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
- package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
- package/src/components/RadioGroup/RadioGroup.module.css +0 -88
- package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
- package/src/components/RadioGroup/RadioGroup.tsx +0 -99
- package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
- package/src/components/Resizable/Resizable.module.css +0 -70
- package/src/components/Resizable/Resizable.stories.tsx +0 -82
- package/src/components/Resizable/Resizable.tsx +0 -313
- package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
- package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
- package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
- package/src/components/RootLayout/RootLayout.module.css +0 -12
- package/src/components/RootLayout/RootLayout.stories.tsx +0 -125
- package/src/components/RootLayout/RootLayout.tsx +0 -185
- package/src/components/RootLayout/__tests__/RootLayout.test.tsx +0 -161
- package/src/components/ScrollArea/ScrollArea.module.css +0 -20
- package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
- package/src/components/ScrollArea/ScrollArea.tsx +0 -27
- package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
- package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
- package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
- package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
- package/src/components/Select/Select.module.css +0 -82
- package/src/components/Select/Select.stories.tsx +0 -115
- package/src/components/Select/Select.tsx +0 -48
- package/src/components/Select/__tests__/Select.test.tsx +0 -59
- package/src/components/Sheet/Sheet.module.css +0 -58
- package/src/components/Sheet/Sheet.tsx +0 -109
- package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
- package/src/components/Slider/Slider.module.css +0 -95
- package/src/components/Slider/Slider.stories.tsx +0 -64
- package/src/components/Slider/Slider.tsx +0 -77
- package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
- package/src/components/Spinner/Spinner.module.css +0 -39
- package/src/components/Spinner/Spinner.tsx +0 -23
- package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
- package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
- package/src/components/SplitPane/SplitPane.module.css +0 -85
- package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
- package/src/components/SplitPane/SplitPane.tsx +0 -149
- package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
- package/src/components/StatusBadge/StatusBadge.module.css +0 -59
- package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
- package/src/components/StatusBadge/StatusBadge.tsx +0 -65
- package/src/components/StepStrip/StepStrip.module.css +0 -53
- package/src/components/StepStrip/StepStrip.tsx +0 -74
- package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
- package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
- package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -64
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -243
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -214
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
- package/src/components/SwipableMobileCarousel/context.ts +0 -13
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -64
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -73
- package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
- package/src/components/SwipeStack/SwipeStack.module.css +0 -101
- package/src/components/SwipeStack/SwipeStack.tsx +0 -199
- package/src/components/SwipeStack/SwipeStackCard.tsx +0 -22
- package/src/components/SwipeStack/__tests__/SwipeStack.test.tsx +0 -169
- package/src/components/SystemBanner/SystemBanner.module.css +0 -79
- package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
- package/src/components/SystemBanner/SystemBanner.tsx +0 -50
- package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
- package/src/components/Table/Table.module.css +0 -45
- package/src/components/Table/Table.stories.tsx +0 -125
- package/src/components/Table/Table.tsx +0 -51
- package/src/components/Table/__tests__/Table.test.tsx +0 -50
- package/src/components/Tabs/Tabs.module.css +0 -56
- package/src/components/Tabs/Tabs.stories.tsx +0 -100
- package/src/components/Tabs/Tabs.tsx +0 -46
- package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
- package/src/components/TagInput/TagInput.module.css +0 -141
- package/src/components/TagInput/TagInput.stories.tsx +0 -109
- package/src/components/TagInput/TagInput.tsx +0 -174
- package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
- package/src/components/Textarea/Textarea.module.css +0 -47
- package/src/components/Textarea/Textarea.tsx +0 -38
- package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -51
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.module.css +0 -35
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.stories.tsx +0 -152
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.tsx +0 -87
- package/src/components/ThreeColumnLayout/__tests__/ThreeColumnLayout.test.tsx +0 -78
- package/src/components/Toast/Toast.module.css +0 -191
- package/src/components/Toast/Toast.stories.tsx +0 -191
- package/src/components/Toast/Toast.tsx +0 -139
- package/src/components/Toggle/Toggle.module.css +0 -57
- package/src/components/Toggle/Toggle.stories.tsx +0 -95
- package/src/components/Toggle/Toggle.tsx +0 -39
- package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
- package/src/components/Tooltip/Tooltip.module.css +0 -56
- package/src/components/Tooltip/Tooltip.tsx +0 -30
- package/src/components/Typography/Typography.module.css +0 -47
- package/src/components/Typography/Typography.stories.tsx +0 -62
- package/src/components/Typography/Typography.tsx +0 -30
- package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
- package/src/components/UserMenu/UserMenu.module.css +0 -90
- package/src/components/UserMenu/UserMenu.stories.tsx +0 -49
- package/src/components/UserMenu/UserMenu.tsx +0 -132
- package/src/components/UserMenu/__tests__/UserMenu.test.tsx +0 -77
- package/src/css-modules.d.ts +0 -4
- package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
- package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
- package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
- package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
- package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
- package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
- package/src/hooks/__tests__/usePublishShellChromeHeight.test.tsx +0 -118
- package/src/hooks/__tests__/useReorderSensors.test.ts +0 -26
- package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
- package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -175
- package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
- package/src/hooks/__tests__/useSwipeStack.test.tsx +0 -155
- package/src/hooks/index.ts +0 -33
- package/src/hooks/useCarouselRouteSync.ts +0 -92
- package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
- package/src/hooks/useDoubleTap.ts +0 -91
- package/src/hooks/useIsMobile.ts +0 -33
- package/src/hooks/useIsOffline.ts +0 -41
- package/src/hooks/useLongPress.ts +0 -185
- package/src/hooks/useOfflineTileState.ts +0 -45
- package/src/hooks/usePublishShellChromeHeight.ts +0 -96
- package/src/hooks/useReorderSensors.ts +0 -88
- package/src/hooks/useResponsiveLayout.ts +0 -36
- package/src/hooks/useSnapCarousel.ts +0 -284
- package/src/hooks/useSwipeReveal.ts +0 -107
- package/src/hooks/useSwipeStack.ts +0 -235
- package/src/index.ts +0 -311
- package/src/motion.ts +0 -78
- package/src/overlay-shell.ts +0 -159
- package/src/scroll-lock.ts +0 -22
- package/src/stories/Avatar.stories.tsx +0 -44
- package/src/stories/Card.stories.tsx +0 -35
- package/src/stories/Checkbox.stories.tsx +0 -45
- package/src/stories/DesignSystemOverview.stories.tsx +0 -3793
- package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
- package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
- package/src/stories/DragHandleRow.stories.tsx +0 -41
- package/src/stories/EmptyState.stories.tsx +0 -33
- package/src/stories/FileDropzone.stories.tsx +0 -69
- package/src/stories/FormField.stories.tsx +0 -47
- package/src/stories/GripIcon.stories.tsx +0 -29
- package/src/stories/InteractionHooks.stories.tsx +0 -925
- package/src/stories/LayoutSystem.stories.tsx +0 -639
- package/src/stories/MenuEntries.stories.tsx +0 -86
- package/src/stories/MobilePatterns.stories.tsx +0 -1536
- package/src/stories/NavList.stories.tsx +0 -147
- package/src/stories/NavTabs.stories.tsx +0 -53
- package/src/stories/OfflineGate.stories.tsx +0 -42
- package/src/stories/PageContainer.stories.tsx +0 -82
- package/src/stories/PageHeader.stories.tsx +0 -95
- package/src/stories/ResponsiveSurface.stories.tsx +0 -47
- package/src/stories/Spinner.stories.tsx +0 -25
- package/src/stories/StepStrip.stories.tsx +0 -76
- package/src/stories/SwipableMobileCarousel.stories.tsx +0 -362
- package/src/stories/SwipeStack.stories.tsx +0 -200
- package/src/stories/Textarea.stories.tsx +0 -63
- package/src/stories/TokenGallery.stories.tsx +0 -652
- package/src/stories/Tooltip.stories.tsx +0 -59
- package/src/tokens/primitives.css +0 -168
- package/src/tokens/semantic.css +0 -162
- package/src/tokens/theme-presets.css +0 -33
- package/src/tokens/theme-presets.ts +0 -72
- package/src/tokens.css +0 -5
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { HeaderFooterLayout } from './HeaderFooterLayout';
|
|
3
|
-
|
|
4
|
-
function Bar({ label }: { label: string }) {
|
|
5
|
-
return (
|
|
6
|
-
<div
|
|
7
|
-
style={{
|
|
8
|
-
display: 'flex',
|
|
9
|
-
alignItems: 'center',
|
|
10
|
-
justifyContent: 'center',
|
|
11
|
-
height: '100%',
|
|
12
|
-
fontFamily: 'var(--sv-font-family)',
|
|
13
|
-
fontSize: 'var(--sv-font-size-sm)',
|
|
14
|
-
fontWeight: 600,
|
|
15
|
-
color: 'var(--sv-color-text-primary)',
|
|
16
|
-
background: 'var(--sv-color-surface-raised)',
|
|
17
|
-
borderBlock: '1px solid var(--sv-color-border)',
|
|
18
|
-
}}
|
|
19
|
-
>
|
|
20
|
-
{label}
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function ScrollableMain() {
|
|
26
|
-
return (
|
|
27
|
-
<div style={{ padding: 'var(--sv-space-4)', fontFamily: 'var(--sv-font-family)' }}>
|
|
28
|
-
{Array.from({ length: 30 }, (_, index) => (
|
|
29
|
-
<p key={index} style={{ color: 'var(--sv-color-text-primary)' }}>
|
|
30
|
-
Row {index + 1} — the main region scrolls independently; header and footer stay put.
|
|
31
|
-
</p>
|
|
32
|
-
))}
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const meta = {
|
|
38
|
-
title: 'Components/HeaderFooterLayout',
|
|
39
|
-
component: HeaderFooterLayout,
|
|
40
|
-
parameters: {
|
|
41
|
-
layout: 'fullscreen',
|
|
42
|
-
docs: {
|
|
43
|
-
description: {
|
|
44
|
-
component:
|
|
45
|
-
'Header + main + optional footer, both fixed-height and independently optional, with main always claiming the remaining height. The vertical counterpart to ThreeColumnLayout — a plain flex column, no color opinions, no responsive behavior of its own.',
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
args: {
|
|
50
|
-
children: <ScrollableMain />,
|
|
51
|
-
},
|
|
52
|
-
} satisfies Meta<typeof HeaderFooterLayout>;
|
|
53
|
-
|
|
54
|
-
export default meta;
|
|
55
|
-
type Story = StoryObj<typeof meta>;
|
|
56
|
-
|
|
57
|
-
/** The canonical usage — header + main + footer, all three present. */
|
|
58
|
-
export const Default: Story = {
|
|
59
|
-
render: () => (
|
|
60
|
-
<div style={{ height: '480px' }}>
|
|
61
|
-
<HeaderFooterLayout header={<Bar label="Header" />} footer={<Bar label="Footer" />}>
|
|
62
|
-
<ScrollableMain />
|
|
63
|
-
</HeaderFooterLayout>
|
|
64
|
-
</div>
|
|
65
|
-
),
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const HeaderOnly: Story = {
|
|
69
|
-
render: () => (
|
|
70
|
-
<div style={{ height: '480px' }}>
|
|
71
|
-
<HeaderFooterLayout header={<Bar label="Header" />}>
|
|
72
|
-
<ScrollableMain />
|
|
73
|
-
</HeaderFooterLayout>
|
|
74
|
-
</div>
|
|
75
|
-
),
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const FooterOnly: Story = {
|
|
79
|
-
render: () => (
|
|
80
|
-
<div style={{ height: '480px' }}>
|
|
81
|
-
<HeaderFooterLayout footer={<Bar label="Footer" />}>
|
|
82
|
-
<ScrollableMain />
|
|
83
|
-
</HeaderFooterLayout>
|
|
84
|
-
</div>
|
|
85
|
-
),
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export const MainOnly: Story = {
|
|
89
|
-
render: () => (
|
|
90
|
-
<div style={{ height: '480px' }}>
|
|
91
|
-
<HeaderFooterLayout>
|
|
92
|
-
<ScrollableMain />
|
|
93
|
-
</HeaderFooterLayout>
|
|
94
|
-
</div>
|
|
95
|
-
),
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export const CustomHeights: Story = {
|
|
99
|
-
render: () => (
|
|
100
|
-
<div style={{ height: '480px' }}>
|
|
101
|
-
<HeaderFooterLayout
|
|
102
|
-
header={<Bar label="Header (100px)" />}
|
|
103
|
-
footer={<Bar label="Footer (48px)" />}
|
|
104
|
-
headerHeight={100}
|
|
105
|
-
footerHeight={48}
|
|
106
|
-
>
|
|
107
|
-
<ScrollableMain />
|
|
108
|
-
</HeaderFooterLayout>
|
|
109
|
-
</div>
|
|
110
|
-
),
|
|
111
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from 'react';
|
|
4
|
-
import styles from './HeaderFooterLayout.module.css';
|
|
5
|
-
|
|
6
|
-
export interface HeaderFooterLayoutProps {
|
|
7
|
-
/** Main content — required, always fills whatever height header/footer don't claim. */
|
|
8
|
-
children: ReactNode;
|
|
9
|
-
header?: ReactNode;
|
|
10
|
-
footer?: ReactNode;
|
|
11
|
-
/** px. Fixed height of the header, when present. Default 60 (matches
|
|
12
|
-
* MobileHeader/--sv-shell-header-height's own default). */
|
|
13
|
-
headerHeight?: number;
|
|
14
|
-
/** px. Fixed height of the footer, when present. Default 60 (matches
|
|
15
|
-
* MobileFooter/--sv-shell-footer-height's own default). */
|
|
16
|
-
footerHeight?: number;
|
|
17
|
-
className?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* HeaderFooterLayout — header + main + optional footer, both fixed-height
|
|
22
|
-
* and independently optional, with main always claiming the remaining
|
|
23
|
-
* height. The vertical counterpart to ThreeColumnLayout: same purely
|
|
24
|
-
* structural approach (no color/background opinions, no awareness of what's
|
|
25
|
-
* inside each slot, no responsive behavior of its own — a plain flex
|
|
26
|
-
* column), just rotated. "Footer always at the bottom" falls out of flex
|
|
27
|
-
* layout alone; there is no position: fixed or safe-area handling here, so
|
|
28
|
-
* a caller composing this with the platform shell's own chrome still owns
|
|
29
|
-
* that separately.
|
|
30
|
-
*/
|
|
31
|
-
export function HeaderFooterLayout({
|
|
32
|
-
children,
|
|
33
|
-
header,
|
|
34
|
-
footer,
|
|
35
|
-
headerHeight = 60,
|
|
36
|
-
footerHeight = 60,
|
|
37
|
-
className,
|
|
38
|
-
}: HeaderFooterLayoutProps) {
|
|
39
|
-
return (
|
|
40
|
-
<div className={[styles.shell, className].filter(Boolean).join(' ')}>
|
|
41
|
-
{header && (
|
|
42
|
-
<div className={styles.header} style={{ height: headerHeight }}>
|
|
43
|
-
{header}
|
|
44
|
-
</div>
|
|
45
|
-
)}
|
|
46
|
-
<div className={styles.main}>{children}</div>
|
|
47
|
-
{footer && (
|
|
48
|
-
<div className={styles.footer} style={{ height: footerHeight }}>
|
|
49
|
-
{footer}
|
|
50
|
-
</div>
|
|
51
|
-
)}
|
|
52
|
-
</div>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { afterEach, describe, expect, it } from 'vitest';
|
|
3
|
-
import { cleanup, render, screen } from '@testing-library/react';
|
|
4
|
-
import { HeaderFooterLayout } from '../HeaderFooterLayout';
|
|
5
|
-
|
|
6
|
-
afterEach(cleanup);
|
|
7
|
-
|
|
8
|
-
describe('HeaderFooterLayout', () => {
|
|
9
|
-
it('renders main content with no header/footer by default', () => {
|
|
10
|
-
render(<HeaderFooterLayout>Main content</HeaderFooterLayout>);
|
|
11
|
-
|
|
12
|
-
expect(screen.getByText('Main content')).toBeDefined();
|
|
13
|
-
expect(screen.queryByText('Header')).toBeNull();
|
|
14
|
-
expect(screen.queryByText('Footer')).toBeNull();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('renders header and footer when given', () => {
|
|
18
|
-
render(
|
|
19
|
-
<HeaderFooterLayout header={<span>Header</span>} footer={<span>Footer</span>}>
|
|
20
|
-
Main content
|
|
21
|
-
</HeaderFooterLayout>,
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
expect(screen.getByText('Header')).toBeDefined();
|
|
25
|
-
expect(screen.getByText('Main content')).toBeDefined();
|
|
26
|
-
expect(screen.getByText('Footer')).toBeDefined();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('renders header without a footer', () => {
|
|
30
|
-
render(<HeaderFooterLayout header={<span>Header</span>}>Main content</HeaderFooterLayout>);
|
|
31
|
-
|
|
32
|
-
expect(screen.getByText('Header')).toBeDefined();
|
|
33
|
-
expect(screen.queryByText('Footer')).toBeNull();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('renders footer without a header', () => {
|
|
37
|
-
render(<HeaderFooterLayout footer={<span>Footer</span>}>Main content</HeaderFooterLayout>);
|
|
38
|
-
|
|
39
|
-
expect(screen.queryByText('Header')).toBeNull();
|
|
40
|
-
expect(screen.getByText('Footer')).toBeDefined();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('applies headerHeight and footerHeight as inline heights', () => {
|
|
44
|
-
render(
|
|
45
|
-
<HeaderFooterLayout
|
|
46
|
-
header={<span>Header</span>}
|
|
47
|
-
footer={<span>Footer</span>}
|
|
48
|
-
headerHeight={48}
|
|
49
|
-
footerHeight={72}
|
|
50
|
-
>
|
|
51
|
-
Main content
|
|
52
|
-
</HeaderFooterLayout>,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
expect(screen.getByText('Header').parentElement?.style.height).toBe('48px');
|
|
56
|
-
expect(screen.getByText('Footer').parentElement?.style.height).toBe('72px');
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { HoverCard } from './HoverCard';
|
|
3
|
-
import { Avatar } from '../Avatar/Avatar';
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'Components/HoverCard',
|
|
7
|
-
component: HoverCard,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: 'padded',
|
|
10
|
-
docs: {
|
|
11
|
-
description: {
|
|
12
|
-
component:
|
|
13
|
-
'Hover-triggered popover on desktop, tap-to-toggle on touch. Built on Popover for positioning/collision detection — this only adds hover-intent timing and the touch fallback. Opens on keyboard focus too.',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
args: { trigger: <span />, children: null, 'aria-label': 'Preview' },
|
|
18
|
-
} satisfies Meta<typeof HoverCard>;
|
|
19
|
-
|
|
20
|
-
export default meta;
|
|
21
|
-
type Story = StoryObj<typeof meta>;
|
|
22
|
-
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
|
|
25
|
-
export const Default: Story = {
|
|
26
|
-
render: () => (
|
|
27
|
-
<HoverCard
|
|
28
|
-
aria-label="User preview"
|
|
29
|
-
trigger={
|
|
30
|
-
<button
|
|
31
|
-
type="button"
|
|
32
|
-
style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer' }}
|
|
33
|
-
>
|
|
34
|
-
<Avatar name="Jane Smith" size="sm" />
|
|
35
|
-
</button>
|
|
36
|
-
}
|
|
37
|
-
>
|
|
38
|
-
<div style={{ padding: 'var(--sv-space-3)', fontSize: 14 }}>
|
|
39
|
-
<div style={{ fontWeight: 600 }}>Jane Smith</div>
|
|
40
|
-
<div style={{ color: 'var(--sv-color-text-muted)' }}>jane@example.com</div>
|
|
41
|
-
</div>
|
|
42
|
-
</HoverCard>
|
|
43
|
-
),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const WithLink: Story = {
|
|
47
|
-
render: () => (
|
|
48
|
-
<p style={{ fontSize: 14 }}>
|
|
49
|
-
Assigned to{' '}
|
|
50
|
-
<HoverCard
|
|
51
|
-
aria-label="Assignee preview"
|
|
52
|
-
trigger={
|
|
53
|
-
<a href="/console/users/jane-smith" style={{ color: 'var(--sv-color-text-primary)' }}>
|
|
54
|
-
Jane Smith
|
|
55
|
-
</a>
|
|
56
|
-
}
|
|
57
|
-
>
|
|
58
|
-
<div style={{ padding: 'var(--sv-space-3)', fontSize: 14 }}>
|
|
59
|
-
<div style={{ fontWeight: 600 }}>Jane Smith</div>
|
|
60
|
-
<div style={{ color: 'var(--sv-color-text-muted)' }}>12 tasks completed this month</div>
|
|
61
|
-
</div>
|
|
62
|
-
</HoverCard>
|
|
63
|
-
.
|
|
64
|
-
</p>
|
|
65
|
-
),
|
|
66
|
-
};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { cloneElement, useEffect, useRef, useState } from 'react';
|
|
4
|
-
import type { ReactElement, ReactNode } from 'react';
|
|
5
|
-
import { Popover } from '../Popover/Popover';
|
|
6
|
-
import styles from './HoverCard.module.css';
|
|
7
|
-
|
|
8
|
-
export interface HoverCardProps {
|
|
9
|
-
/** The element that opens the card — cloned with hover/focus handlers
|
|
10
|
-
* (desktop) or a tap handler (touch). */
|
|
11
|
-
trigger: ReactElement;
|
|
12
|
-
children: ReactNode;
|
|
13
|
-
align?: 'left' | 'right';
|
|
14
|
-
width?: number | 'trigger';
|
|
15
|
-
'aria-label': string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const OPEN_DELAY_MS = 400;
|
|
19
|
-
const CLOSE_DELAY_MS = 150;
|
|
20
|
-
|
|
21
|
-
/** Whether the primary pointer can hover. Distinct from viewport-width-based
|
|
22
|
-
* mobile detection: a touchscreen laptop with a mouse as its primary
|
|
23
|
-
* pointer should still get real hover behavior, and a large-viewport tablet
|
|
24
|
-
* with only touch should not — viewport width doesn't capture that, `(hover:
|
|
25
|
-
* hover)` does, matching the pointer-based gating this design system already
|
|
26
|
-
* uses in CSS (e.g. Button/Checkbox's touch-target expansion). Defaults to
|
|
27
|
-
* `true`: this only changes which event handlers get attached, not the
|
|
28
|
-
* initial DOM shape, so there's no hydration-mismatch risk to guard against
|
|
29
|
-
* the way `useIsMobile` does. */
|
|
30
|
-
function useHoverCapable(): boolean {
|
|
31
|
-
const [hoverCapable, setHoverCapable] = useState(true);
|
|
32
|
-
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
const mql = window.matchMedia('(hover: hover)');
|
|
35
|
-
setHoverCapable(mql.matches);
|
|
36
|
-
function handleChange(e: MediaQueryListEvent) {
|
|
37
|
-
setHoverCapable(e.matches);
|
|
38
|
-
}
|
|
39
|
-
mql.addEventListener('change', handleChange);
|
|
40
|
-
return () => mql.removeEventListener('change', handleChange);
|
|
41
|
-
}, []);
|
|
42
|
-
|
|
43
|
-
return hoverCapable;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* HoverCard — hover-triggered popover on desktop, tap-to-toggle on touch.
|
|
48
|
-
*
|
|
49
|
-
* Built on `Popover` rather than reimplementing positioning/collision
|
|
50
|
-
* detection: this only adds the hover-intent open/close timing (avoids
|
|
51
|
-
* flicker on an accidental mouse pass-over, and gives the pointer time to
|
|
52
|
-
* travel from the trigger to the card itself across the gap between them)
|
|
53
|
-
* and the touch fallback. Also opens on keyboard focus and closes on blur —
|
|
54
|
-
* a hover-only trigger is a WCAG failure, since keyboard users can't hover.
|
|
55
|
-
*/
|
|
56
|
-
export function HoverCard({
|
|
57
|
-
trigger,
|
|
58
|
-
children,
|
|
59
|
-
align,
|
|
60
|
-
width,
|
|
61
|
-
'aria-label': ariaLabel,
|
|
62
|
-
}: HoverCardProps) {
|
|
63
|
-
const [open, setOpen] = useState(false);
|
|
64
|
-
const hoverCapable = useHoverCapable();
|
|
65
|
-
const openTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
|
66
|
-
const closeTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
|
67
|
-
|
|
68
|
-
function scheduleOpen() {
|
|
69
|
-
clearTimeout(closeTimer.current);
|
|
70
|
-
openTimer.current = setTimeout(() => setOpen(true), OPEN_DELAY_MS);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function scheduleClose() {
|
|
74
|
-
clearTimeout(openTimer.current);
|
|
75
|
-
closeTimer.current = setTimeout(() => setOpen(false), CLOSE_DELAY_MS);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function cancelScheduledClose() {
|
|
79
|
-
clearTimeout(closeTimer.current);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const triggerHandlers = hoverCapable
|
|
83
|
-
? {
|
|
84
|
-
onMouseEnter: scheduleOpen,
|
|
85
|
-
onMouseLeave: scheduleClose,
|
|
86
|
-
onFocus: () => setOpen(true),
|
|
87
|
-
onBlur: scheduleClose,
|
|
88
|
-
}
|
|
89
|
-
: { onClick: () => setOpen((o) => !o) };
|
|
90
|
-
|
|
91
|
-
const wrappedTrigger = cloneElement(trigger, triggerHandlers);
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<div
|
|
95
|
-
className={styles.root}
|
|
96
|
-
onMouseEnter={hoverCapable ? cancelScheduledClose : undefined}
|
|
97
|
-
onMouseLeave={hoverCapable ? scheduleClose : undefined}
|
|
98
|
-
>
|
|
99
|
-
<Popover
|
|
100
|
-
trigger={wrappedTrigger}
|
|
101
|
-
open={open}
|
|
102
|
-
onClose={() => setOpen(false)}
|
|
103
|
-
align={align}
|
|
104
|
-
width={width}
|
|
105
|
-
aria-label={ariaLabel}
|
|
106
|
-
>
|
|
107
|
-
{children}
|
|
108
|
-
</Popover>
|
|
109
|
-
</div>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import { act, cleanup, render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
-
import { HoverCard } from '../HoverCard';
|
|
5
|
-
|
|
6
|
-
let matches = true;
|
|
7
|
-
|
|
8
|
-
function installMatchMedia() {
|
|
9
|
-
vi.stubGlobal(
|
|
10
|
-
'matchMedia',
|
|
11
|
-
vi.fn().mockImplementation((query: string) => ({
|
|
12
|
-
matches,
|
|
13
|
-
media: query,
|
|
14
|
-
addEventListener: vi.fn(),
|
|
15
|
-
removeEventListener: vi.fn(),
|
|
16
|
-
addListener: vi.fn(),
|
|
17
|
-
removeListener: vi.fn(),
|
|
18
|
-
dispatchEvent: vi.fn(),
|
|
19
|
-
})),
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('HoverCard', () => {
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
matches = true; // hover-capable by default
|
|
26
|
-
installMatchMedia();
|
|
27
|
-
vi.useFakeTimers();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
vi.runOnlyPendingTimers();
|
|
32
|
-
vi.useRealTimers();
|
|
33
|
-
vi.unstubAllGlobals();
|
|
34
|
-
cleanup();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('does not open immediately on mouse enter (hover-intent delay)', () => {
|
|
38
|
-
render(
|
|
39
|
-
<HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
|
|
40
|
-
Card content
|
|
41
|
-
</HoverCard>,
|
|
42
|
-
);
|
|
43
|
-
fireEvent.mouseEnter(screen.getByRole('button', { name: 'Profile' }));
|
|
44
|
-
expect(screen.queryByText('Card content')).toBeNull();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('opens after the hover-intent delay elapses', () => {
|
|
48
|
-
render(
|
|
49
|
-
<HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
|
|
50
|
-
Card content
|
|
51
|
-
</HoverCard>,
|
|
52
|
-
);
|
|
53
|
-
fireEvent.mouseEnter(screen.getByRole('button', { name: 'Profile' }));
|
|
54
|
-
act(() => {
|
|
55
|
-
vi.advanceTimersByTime(500);
|
|
56
|
-
});
|
|
57
|
-
expect(screen.getByText('Card content')).toBeDefined();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('cancels the open timer if the pointer leaves before the delay elapses', () => {
|
|
61
|
-
render(
|
|
62
|
-
<HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
|
|
63
|
-
Card content
|
|
64
|
-
</HoverCard>,
|
|
65
|
-
);
|
|
66
|
-
const trigger = screen.getByRole('button', { name: 'Profile' });
|
|
67
|
-
fireEvent.mouseEnter(trigger);
|
|
68
|
-
fireEvent.mouseLeave(trigger);
|
|
69
|
-
act(() => {
|
|
70
|
-
vi.advanceTimersByTime(1000);
|
|
71
|
-
});
|
|
72
|
-
expect(screen.queryByText('Card content')).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('opens immediately on keyboard focus, for keyboard accessibility', () => {
|
|
76
|
-
render(
|
|
77
|
-
<HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
|
|
78
|
-
Card content
|
|
79
|
-
</HoverCard>,
|
|
80
|
-
);
|
|
81
|
-
fireEvent.focus(screen.getByRole('button', { name: 'Profile' }));
|
|
82
|
-
expect(screen.getByText('Card content')).toBeDefined();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('falls back to tap-to-toggle when the pointer cannot hover', () => {
|
|
86
|
-
matches = false;
|
|
87
|
-
installMatchMedia();
|
|
88
|
-
render(
|
|
89
|
-
<HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
|
|
90
|
-
Card content
|
|
91
|
-
</HoverCard>,
|
|
92
|
-
);
|
|
93
|
-
const trigger = screen.getByRole('button', { name: 'Profile' });
|
|
94
|
-
fireEvent.click(trigger);
|
|
95
|
-
expect(screen.getByText('Card content')).toBeDefined();
|
|
96
|
-
fireEvent.click(trigger);
|
|
97
|
-
expect(screen.queryByText('Card content')).toBeNull();
|
|
98
|
-
});
|
|
99
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
.root {
|
|
2
|
-
display: inline-block;
|
|
3
|
-
flex-shrink: 0;
|
|
4
|
-
/* Prevent the inline-block from adding line-height whitespace below the SVG. */
|
|
5
|
-
line-height: 0;
|
|
6
|
-
/* Color follows the surrounding text via currentColor — no token needed. */
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.xs {
|
|
10
|
-
width: var(--sv-icon-size-xs);
|
|
11
|
-
height: var(--sv-icon-size-xs);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.sm {
|
|
15
|
-
width: var(--sv-icon-size-sm);
|
|
16
|
-
height: var(--sv-icon-size-sm);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.md {
|
|
20
|
-
width: var(--sv-icon-size-md);
|
|
21
|
-
height: var(--sv-icon-size-md);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.lg {
|
|
25
|
-
width: var(--sv-icon-size-lg);
|
|
26
|
-
height: var(--sv-icon-size-lg);
|
|
27
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { ICONS, type IconName } from './icons';
|
|
3
|
-
import { Icon } from './Icon';
|
|
4
|
-
|
|
5
|
-
const ALL_NAMES = Object.keys(ICONS) as IconName[];
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: 'Components/Icon',
|
|
9
|
-
component: Icon,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
docs: {
|
|
13
|
-
description: {
|
|
14
|
-
component:
|
|
15
|
-
'SVG icon primitive. Icons are either **decorative** (`aria-hidden`) or **meaningful** (`aria-label`). Size is controlled by `--sv-icon-size-*` tokens.',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
argTypes: {
|
|
20
|
-
name: { control: 'select', options: ALL_NAMES },
|
|
21
|
-
size: { control: 'select', options: ['xs', 'sm', 'md', 'lg'] },
|
|
22
|
-
},
|
|
23
|
-
} satisfies Meta<typeof Icon>;
|
|
24
|
-
|
|
25
|
-
export default meta;
|
|
26
|
-
type Story = StoryObj<typeof meta>;
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
|
|
30
|
-
export const Decorative: Story = {
|
|
31
|
-
args: { name: 'house', size: 'md', 'aria-hidden': true },
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const Meaningful: Story = {
|
|
35
|
-
args: { name: 'settings', size: 'md', 'aria-label': 'Open settings' },
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const SizeExtraSmall: Story = { args: { name: 'bell', size: 'xs', 'aria-hidden': true } };
|
|
39
|
-
export const SizeSmall: Story = { args: { name: 'bell', size: 'sm', 'aria-hidden': true } };
|
|
40
|
-
export const SizeMedium: Story = { args: { name: 'bell', size: 'md', 'aria-hidden': true } };
|
|
41
|
-
export const SizeLarge: Story = { args: { name: 'bell', size: 'lg', 'aria-hidden': true } };
|
|
42
|
-
|
|
43
|
-
/** Full icon grid — every name across all four sizes. */
|
|
44
|
-
export const AllIcons: Story = {
|
|
45
|
-
parameters: { layout: 'padded' },
|
|
46
|
-
args: { name: 'house', 'aria-hidden': true },
|
|
47
|
-
render: (_args) => (
|
|
48
|
-
<div>
|
|
49
|
-
{(['xs', 'sm', 'md', 'lg'] as const).map((sz) => (
|
|
50
|
-
<section key={sz} style={{ marginBottom: 32 }}>
|
|
51
|
-
<h3
|
|
52
|
-
style={{
|
|
53
|
-
fontFamily: 'system-ui',
|
|
54
|
-
fontSize: 13,
|
|
55
|
-
fontWeight: 600,
|
|
56
|
-
color: 'var(--sv-color-text-muted)',
|
|
57
|
-
textTransform: 'uppercase',
|
|
58
|
-
letterSpacing: '0.08em',
|
|
59
|
-
marginBottom: 12,
|
|
60
|
-
}}
|
|
61
|
-
>
|
|
62
|
-
Size: {sz}
|
|
63
|
-
</h3>
|
|
64
|
-
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 16 }}>
|
|
65
|
-
{ALL_NAMES.map((name) => (
|
|
66
|
-
<div
|
|
67
|
-
key={name}
|
|
68
|
-
style={{
|
|
69
|
-
display: 'flex',
|
|
70
|
-
flexDirection: 'column',
|
|
71
|
-
alignItems: 'center',
|
|
72
|
-
gap: 4,
|
|
73
|
-
width: 64,
|
|
74
|
-
}}
|
|
75
|
-
>
|
|
76
|
-
<Icon name={name} size={sz} aria-hidden />
|
|
77
|
-
<span
|
|
78
|
-
style={{
|
|
79
|
-
fontFamily: 'monospace',
|
|
80
|
-
fontSize: 10,
|
|
81
|
-
color: 'var(--sv-color-text-muted)',
|
|
82
|
-
textAlign: 'center',
|
|
83
|
-
wordBreak: 'break-word',
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
{name}
|
|
87
|
-
</span>
|
|
88
|
-
</div>
|
|
89
|
-
))}
|
|
90
|
-
</div>
|
|
91
|
-
</section>
|
|
92
|
-
))}
|
|
93
|
-
</div>
|
|
94
|
-
),
|
|
95
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ICONS, type IconName } from './icons';
|
|
2
|
-
import styles from './Icon.module.css';
|
|
3
|
-
|
|
4
|
-
export type { IconName };
|
|
5
|
-
|
|
6
|
-
/** Decorative icon — visually meaningful but described by surrounding text. */
|
|
7
|
-
type DecorativeProps = { 'aria-hidden': true; 'aria-label'?: never };
|
|
8
|
-
/** Meaningful icon — standalone affordance that requires a label for screen readers. */
|
|
9
|
-
type MeaningfulProps = { 'aria-label': string; 'aria-hidden'?: never };
|
|
10
|
-
|
|
11
|
-
export interface IconProps {
|
|
12
|
-
/** Name of the icon from the curated Sovereign set. */
|
|
13
|
-
name: IconName;
|
|
14
|
-
/** Visual size. Defaults to `"md"` (20 px). */
|
|
15
|
-
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
16
|
-
/** Additional CSS class applied to the SVG element. */
|
|
17
|
-
className?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* `<Icon>` — the Sovereign design system icon primitive.
|
|
22
|
-
*
|
|
23
|
-
* Icons are either **decorative** (described by surrounding text — pass `aria-hidden`)
|
|
24
|
-
* or **meaningful** (standalone affordance — pass `aria-label`):
|
|
25
|
-
*
|
|
26
|
-
* ```tsx
|
|
27
|
-
* <Icon name="house" aria-hidden /> // decorative
|
|
28
|
-
* <Icon name="log-out" aria-label="Sign out" /> // meaningful
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* Color follows `currentColor` so an icon automatically inherits the text color
|
|
32
|
-
* of its container and recolors with theme changes — no extra CSS required.
|
|
33
|
-
*/
|
|
34
|
-
export function Icon({
|
|
35
|
-
name,
|
|
36
|
-
size = 'md',
|
|
37
|
-
className,
|
|
38
|
-
...aria
|
|
39
|
-
}: IconProps & (DecorativeProps | MeaningfulProps)) {
|
|
40
|
-
const Svg = ICONS[name];
|
|
41
|
-
const classes = [styles.root, styles[size], className].filter(Boolean).join(' ');
|
|
42
|
-
return <Svg className={classes} role={aria['aria-label'] ? 'img' : undefined} {...aria} />;
|
|
43
|
-
}
|