@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,175 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { type PointerEvent as ReactPointerEvent, type ReactNode, useRef } from 'react';
|
|
4
|
-
import { useMountTransition, usePrefersReducedMotion } from '../../motion';
|
|
5
|
-
import {
|
|
6
|
-
OVERLAY_MOTION_DURATION_MS,
|
|
7
|
-
useOverlayFocusCapture,
|
|
8
|
-
useOverlayKeyboardTrap,
|
|
9
|
-
useOverlayScrollLock,
|
|
10
|
-
} from '../../overlay-shell';
|
|
11
|
-
import { OverlayHeader } from '../OverlayHeader/OverlayHeader';
|
|
12
|
-
import styles from './Drawer.module.css';
|
|
13
|
-
|
|
14
|
-
export interface DrawerProps {
|
|
15
|
-
/** Whether the drawer is shown. When false, nothing renders. */
|
|
16
|
-
open: boolean;
|
|
17
|
-
/** Called on Esc, scrim click, or a swipe-down past the dismiss threshold. */
|
|
18
|
-
onClose: () => void;
|
|
19
|
-
/** Accessible name for the drawer panel (sets `aria-label`). */
|
|
20
|
-
'aria-label'?: string;
|
|
21
|
-
/** `'content'` (default) sizes to content, capped at 80dvh. `'half'` fixes
|
|
22
|
-
* the panel to 50dvh regardless of content — per the design-system's
|
|
23
|
-
* "half screen or less" convention for Drawer, this is the only other
|
|
24
|
-
* supported size; taller content should use `Sheet` instead. */
|
|
25
|
-
snapHeight?: 'content' | 'half';
|
|
26
|
-
/** Renders a built-in `OverlayHeader` (title + close) below the grab
|
|
27
|
-
* handle. Omit when the content supplies its own header, or none is
|
|
28
|
-
* needed at all — e.g. the mobile shell's Apps drawer, whose grab handle
|
|
29
|
-
* and swipe-down/scrim-tap dismissal are enough on their own. Mirrors
|
|
30
|
-
* `Sheet`'s identical `title` prop. */
|
|
31
|
-
title?: string;
|
|
32
|
-
children: ReactNode;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Downward drag distance (px) past which releasing dismisses the drawer
|
|
36
|
-
// instead of snapping back open. Distance-only, no velocity tracking — matches
|
|
37
|
-
// the swipe-to-reveal gesture already established in consuming plugins (see
|
|
38
|
-
// the mobile design-system plan), not a separate technique invented here.
|
|
39
|
-
const SWIPE_DISMISS_THRESHOLD_PX = 100;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Drawer — a dismissable bottom-sheet panel. Used by the mobile shell for
|
|
43
|
-
* plugin navigation; also available to plugins for any bottom-up surface.
|
|
44
|
-
*
|
|
45
|
-
* Behaviour: Esc, scrim click, or dragging the grab handle down past
|
|
46
|
-
* `SWIPE_DISMISS_THRESHOLD_PX` all dismiss; focus moves to the first
|
|
47
|
-
* focusable element on open and is restored on close; Tab is trapped within
|
|
48
|
-
* the panel. The panel respects `env(safe-area-inset-bottom)` so it clears
|
|
49
|
-
* the home indicator in standalone/fullscreen mode. Shares dismissal
|
|
50
|
-
* conventions and tokens (`--sv-color-scrim`, `--sv-shadow-overlay`) with
|
|
51
|
-
* `Dialog`.
|
|
52
|
-
*
|
|
53
|
-
* Animated open/close: slides up from the bottom, scrim fades. The `open`/
|
|
54
|
-
* `onClose` API is unchanged — closing stays mounted internally for the exit
|
|
55
|
-
* transition before actually unmounting; `prefers-reduced-motion: reduce`
|
|
56
|
-
* collapses it to near-instant.
|
|
57
|
-
*
|
|
58
|
-
* The grab handle is the *only* drag-initiation region (not the whole panel)
|
|
59
|
-
* — dragging from body content would fight that content's own internal
|
|
60
|
-
* scroll, the same reasoning behind the tasks plugin's edge-zone-only
|
|
61
|
-
* swipe-to-reveal technique.
|
|
62
|
-
*/
|
|
63
|
-
export function Drawer({
|
|
64
|
-
open,
|
|
65
|
-
onClose,
|
|
66
|
-
'aria-label': ariaLabel,
|
|
67
|
-
snapHeight = 'content',
|
|
68
|
-
title,
|
|
69
|
-
children,
|
|
70
|
-
}: DrawerProps) {
|
|
71
|
-
const panelRef = useRef<HTMLDivElement>(null);
|
|
72
|
-
const reducedMotion = usePrefersReducedMotion();
|
|
73
|
-
const { mounted, phase } = useMountTransition(
|
|
74
|
-
open,
|
|
75
|
-
reducedMotion ? 0 : OVERLAY_MOTION_DURATION_MS,
|
|
76
|
-
);
|
|
77
|
-
// Tracks an in-progress handle drag. Kept in a ref (not state) so pointermove
|
|
78
|
-
// updates the DOM directly at 60fps instead of re-rendering on every event —
|
|
79
|
-
// same technique as the tasks plugin's swipe-to-reveal rows.
|
|
80
|
-
const dragStartY = useRef<number | null>(null);
|
|
81
|
-
|
|
82
|
-
useOverlayScrollLock(mounted);
|
|
83
|
-
useOverlayFocusCapture(panelRef, open);
|
|
84
|
-
useOverlayKeyboardTrap(panelRef, open, onClose);
|
|
85
|
-
|
|
86
|
-
// Swipe-down-to-dismiss, initiated only from the grab handle (see the
|
|
87
|
-
// component doc comment for why not the whole panel). Drags the panel
|
|
88
|
-
// directly via inline style while active (transition: none, so it tracks
|
|
89
|
-
// the finger 1:1 with no lag) and lets go on release: clearing the inline
|
|
90
|
-
// transform in the same commit that re-enables the CSS transition makes
|
|
91
|
-
// the panel animate from wherever the drag ended to its resolved position
|
|
92
|
-
// — open (snap back) or closed (the exit transition, same as a
|
|
93
|
-
// programmatic close) — rather than jump-cutting there. Same technique as
|
|
94
|
-
// the tasks plugin's row swipe-to-reveal.
|
|
95
|
-
function handleHandlePointerDown(e: ReactPointerEvent) {
|
|
96
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
97
|
-
dragStartY.current = e.clientY;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function handleHandlePointerMove(e: ReactPointerEvent) {
|
|
101
|
-
const startY = dragStartY.current;
|
|
102
|
-
if (startY === null) return;
|
|
103
|
-
const dy = Math.max(0, e.clientY - startY); // upward drag has no effect — already fully open
|
|
104
|
-
const panel = panelRef.current;
|
|
105
|
-
if (!panel) return;
|
|
106
|
-
panel.style.transition = 'none';
|
|
107
|
-
panel.style.transform = `translateY(${dy}px)`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Releases the drag and resolves it to open (snap back) or closed, based on
|
|
111
|
-
// distance. Shared by pointerup (a completed gesture) and pointercancel
|
|
112
|
-
// (the browser took the gesture away, e.g. for a system gesture) — cancel
|
|
113
|
-
// always snaps back rather than honoring the distance, since it wasn't a
|
|
114
|
-
// deliberate release.
|
|
115
|
-
function releaseDrag(e: ReactPointerEvent, honorDistance: boolean) {
|
|
116
|
-
const startY = dragStartY.current;
|
|
117
|
-
dragStartY.current = null;
|
|
118
|
-
if (startY === null) return;
|
|
119
|
-
const dy = Math.max(0, e.clientY - startY);
|
|
120
|
-
const panel = panelRef.current;
|
|
121
|
-
if (panel) {
|
|
122
|
-
panel.style.transform = '';
|
|
123
|
-
panel.style.transition = '';
|
|
124
|
-
}
|
|
125
|
-
if (honorDistance && dy > SWIPE_DISMISS_THRESHOLD_PX) onClose();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!mounted) return null;
|
|
129
|
-
const isOpenPhase = phase === 'open';
|
|
130
|
-
|
|
131
|
-
return (
|
|
132
|
-
// role="presentation" removes the scrim from the AT (it is purely visual).
|
|
133
|
-
// e.target check lets clicks inside the panel bubble without triggering dismiss.
|
|
134
|
-
// No onKeyDown here — useOverlayKeyboardTrap above already owns Escape via a
|
|
135
|
-
// document-level listener; a second handler here used to double-fire onClose
|
|
136
|
-
// per keypress (see Dialog.tsx's identical fix for the full explanation).
|
|
137
|
-
<div
|
|
138
|
-
className={[styles.scrim, isOpenPhase ? styles.scrimOpen : ''].filter(Boolean).join(' ')}
|
|
139
|
-
role="presentation"
|
|
140
|
-
onClick={(e) => {
|
|
141
|
-
if (e.target === e.currentTarget) onClose();
|
|
142
|
-
}}
|
|
143
|
-
>
|
|
144
|
-
<div
|
|
145
|
-
ref={panelRef}
|
|
146
|
-
role="dialog"
|
|
147
|
-
aria-modal="true"
|
|
148
|
-
aria-label={ariaLabel}
|
|
149
|
-
tabIndex={-1}
|
|
150
|
-
className={[
|
|
151
|
-
styles.panel,
|
|
152
|
-
snapHeight === 'half' ? styles.panelHalf : '',
|
|
153
|
-
isOpenPhase ? styles.panelOpen : '',
|
|
154
|
-
]
|
|
155
|
-
.filter(Boolean)
|
|
156
|
-
.join(' ')}
|
|
157
|
-
>
|
|
158
|
-
{/* The only drag-initiation region for swipe-down-to-dismiss — see the
|
|
159
|
-
component doc comment for why not the whole panel. Decorative +
|
|
160
|
-
functional, so no aria-label of its own; Esc and the scrim remain
|
|
161
|
-
the accessible dismiss paths. */}
|
|
162
|
-
<div
|
|
163
|
-
className={styles.handle}
|
|
164
|
-
aria-hidden="true"
|
|
165
|
-
onPointerDown={handleHandlePointerDown}
|
|
166
|
-
onPointerMove={handleHandlePointerMove}
|
|
167
|
-
onPointerUp={(e) => releaseDrag(e, true)}
|
|
168
|
-
onPointerCancel={(e) => releaseDrag(e, false)}
|
|
169
|
-
/>
|
|
170
|
-
{title && <OverlayHeader title={title} onClose={onClose} />}
|
|
171
|
-
<div className={styles.body}>{children}</div>
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
|
4
|
-
import { Drawer } from '../Drawer';
|
|
5
|
-
|
|
6
|
-
// Drawer's exit animation reads prefers-reduced-motion via matchMedia, which
|
|
7
|
-
// jsdom does not implement. `matches: false` (motion enabled) exercises the
|
|
8
|
-
// normal animated path; the actual reduced-motion behaviour is covered by
|
|
9
|
-
// motion.ts's own tests.
|
|
10
|
-
function installMatchMedia() {
|
|
11
|
-
vi.stubGlobal(
|
|
12
|
-
'matchMedia',
|
|
13
|
-
vi.fn().mockImplementation((query: string) => ({
|
|
14
|
-
matches: false,
|
|
15
|
-
media: query,
|
|
16
|
-
addEventListener: vi.fn(),
|
|
17
|
-
removeEventListener: vi.fn(),
|
|
18
|
-
addListener: vi.fn(),
|
|
19
|
-
removeListener: vi.fn(),
|
|
20
|
-
dispatchEvent: vi.fn(),
|
|
21
|
-
})),
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// jsdom does not implement Element.setPointerCapture/releasePointerCapture
|
|
26
|
-
// (another documented gap, alongside matchMedia and HTMLDialogElement) — the
|
|
27
|
-
// grab handle's pointerdown handler calls setPointerCapture unconditionally.
|
|
28
|
-
function installPointerCapture() {
|
|
29
|
-
if (!Element.prototype.setPointerCapture) {
|
|
30
|
-
Element.prototype.setPointerCapture = () => {};
|
|
31
|
-
}
|
|
32
|
-
if (!Element.prototype.releasePointerCapture) {
|
|
33
|
-
Element.prototype.releasePointerCapture = () => {};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
describe('Drawer', () => {
|
|
38
|
-
beforeEach(() => {
|
|
39
|
-
installMatchMedia();
|
|
40
|
-
installPointerCapture();
|
|
41
|
-
});
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
vi.unstubAllGlobals();
|
|
44
|
-
cleanup();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('renders nothing when closed', () => {
|
|
48
|
-
render(
|
|
49
|
-
<Drawer open={false} onClose={() => {}}>
|
|
50
|
-
Body
|
|
51
|
-
</Drawer>,
|
|
52
|
-
);
|
|
53
|
-
expect(screen.queryByRole('dialog')).toBeNull();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('renders the panel with its accessible name when open', () => {
|
|
57
|
-
render(
|
|
58
|
-
<Drawer open onClose={() => {}} aria-label="Navigation">
|
|
59
|
-
Body
|
|
60
|
-
</Drawer>,
|
|
61
|
-
);
|
|
62
|
-
const panel = screen.getByRole('dialog', { name: 'Navigation' });
|
|
63
|
-
expect(panel.getAttribute('aria-modal')).toBe('true');
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('calls onClose exactly once on Escape with focus inside the panel', () => {
|
|
67
|
-
const onClose = vi.fn();
|
|
68
|
-
render(
|
|
69
|
-
<Drawer open onClose={onClose} aria-label="Panel">
|
|
70
|
-
<button>Focus me</button>
|
|
71
|
-
</Drawer>,
|
|
72
|
-
);
|
|
73
|
-
// Dispatched from the actually-focused element (matching real usage,
|
|
74
|
-
// where useOverlayFocusCapture moves focus into the panel on open) so the
|
|
75
|
-
// keydown bubbles through the scrim on its way to document — the exact
|
|
76
|
-
// path that used to trigger both the scrim's own (now-removed) Escape
|
|
77
|
-
// handler and useOverlayKeyboardTrap's document-level listener, double-
|
|
78
|
-
// firing onClose. Dispatching straight on `document` (the previous form
|
|
79
|
-
// of this test) skips that bubble path and would pass even if the bug
|
|
80
|
-
// were reintroduced.
|
|
81
|
-
const button = screen.getByRole('button', { name: 'Focus me' });
|
|
82
|
-
button.focus();
|
|
83
|
-
fireEvent.keyDown(button, { key: 'Escape' });
|
|
84
|
-
expect(onClose).toHaveBeenCalledOnce();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('calls onClose on scrim click but not on panel click', () => {
|
|
88
|
-
const onClose = vi.fn();
|
|
89
|
-
const { container } = render(
|
|
90
|
-
<Drawer open onClose={onClose} aria-label="Nav">
|
|
91
|
-
<button>Action</button>
|
|
92
|
-
</Drawer>,
|
|
93
|
-
);
|
|
94
|
-
// The scrim is the outermost div; the panel is a child.
|
|
95
|
-
fireEvent.click(screen.getByRole('dialog')); // panel — should not close
|
|
96
|
-
expect(onClose).not.toHaveBeenCalled();
|
|
97
|
-
// Click the scrim background (the container's first child).
|
|
98
|
-
const scrim = container.firstElementChild as HTMLElement;
|
|
99
|
-
fireEvent.click(scrim);
|
|
100
|
-
expect(onClose).toHaveBeenCalledOnce();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('applies the half snapHeight class', () => {
|
|
104
|
-
render(
|
|
105
|
-
<Drawer open onClose={() => {}} aria-label="Nav" snapHeight="half">
|
|
106
|
-
Body
|
|
107
|
-
</Drawer>,
|
|
108
|
-
);
|
|
109
|
-
expect(screen.getByRole('dialog').className).toMatch(/panelHalf/);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('does not apply the half snapHeight class by default (content-sized)', () => {
|
|
113
|
-
render(
|
|
114
|
-
<Drawer open onClose={() => {}} aria-label="Nav">
|
|
115
|
-
Body
|
|
116
|
-
</Drawer>,
|
|
117
|
-
);
|
|
118
|
-
expect(screen.getByRole('dialog').className).not.toMatch(/panelHalf/);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('does not render OverlayHeader when title is omitted (hidden by default)', () => {
|
|
122
|
-
render(
|
|
123
|
-
<Drawer open onClose={() => {}} aria-label="Nav">
|
|
124
|
-
<button type="button">Own action</button>
|
|
125
|
-
</Drawer>,
|
|
126
|
-
);
|
|
127
|
-
// Only the content's own button — no OverlayHeader close button.
|
|
128
|
-
expect(screen.getAllByRole('button')).toHaveLength(1);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('renders children inside a scrollable body, separate from the grab handle', () => {
|
|
132
|
-
// Regression test: the panel used to be the sole scroll container
|
|
133
|
-
// (overflow-y: auto on .panel itself), so a tall drawer scrolled the
|
|
134
|
-
// grab handle out of view along with the content. The handle must stay
|
|
135
|
-
// a sibling of the scrollable region, not a descendant of it.
|
|
136
|
-
render(
|
|
137
|
-
<Drawer open onClose={() => {}} aria-label="Nav">
|
|
138
|
-
<button type="button">Own action</button>
|
|
139
|
-
</Drawer>,
|
|
140
|
-
);
|
|
141
|
-
const panel = screen.getByRole('dialog');
|
|
142
|
-
const handle = panel.firstElementChild as HTMLElement;
|
|
143
|
-
const button = screen.getByRole('button', { name: 'Own action' });
|
|
144
|
-
const body = button.parentElement as HTMLElement;
|
|
145
|
-
expect(body).not.toBe(panel);
|
|
146
|
-
expect(body.contains(handle)).toBe(false);
|
|
147
|
-
expect(panel.contains(body)).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('renders OverlayHeader (title + close) when title is provided', () => {
|
|
151
|
-
const onClose = vi.fn();
|
|
152
|
-
render(
|
|
153
|
-
<Drawer open onClose={onClose} aria-label="Nav" title="Apps">
|
|
154
|
-
Body
|
|
155
|
-
</Drawer>,
|
|
156
|
-
);
|
|
157
|
-
expect(screen.getByText('Apps')).toBeTruthy();
|
|
158
|
-
fireEvent.click(screen.getByRole('button', { name: 'Close' }));
|
|
159
|
-
expect(onClose).toHaveBeenCalledOnce();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
describe('swipe-down-to-dismiss (grab handle)', () => {
|
|
163
|
-
// The handle is the panel's first child, aria-hidden and unlabeled —
|
|
164
|
-
// same "select via DOM position" approach the scrim-click test above
|
|
165
|
-
// already uses for a similarly unlabeled element.
|
|
166
|
-
function getHandle() {
|
|
167
|
-
return screen.getByRole('dialog').firstElementChild as HTMLElement;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
it('dismisses when dragged past the threshold', () => {
|
|
171
|
-
const onClose = vi.fn();
|
|
172
|
-
render(
|
|
173
|
-
<Drawer open onClose={onClose} aria-label="Nav">
|
|
174
|
-
Body
|
|
175
|
-
</Drawer>,
|
|
176
|
-
);
|
|
177
|
-
const handle = getHandle();
|
|
178
|
-
fireEvent.pointerDown(handle, { clientY: 0 });
|
|
179
|
-
fireEvent.pointerMove(handle, { clientY: 150 });
|
|
180
|
-
fireEvent.pointerUp(handle, { clientY: 150 }); // 150px > 100px threshold
|
|
181
|
-
expect(onClose).toHaveBeenCalledOnce();
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it('snaps back without dismissing when released under the threshold', () => {
|
|
185
|
-
const onClose = vi.fn();
|
|
186
|
-
render(
|
|
187
|
-
<Drawer open onClose={onClose} aria-label="Nav">
|
|
188
|
-
Body
|
|
189
|
-
</Drawer>,
|
|
190
|
-
);
|
|
191
|
-
const handle = getHandle();
|
|
192
|
-
fireEvent.pointerDown(handle, { clientY: 0 });
|
|
193
|
-
fireEvent.pointerMove(handle, { clientY: 40 });
|
|
194
|
-
fireEvent.pointerUp(handle, { clientY: 40 }); // 40px < 100px threshold
|
|
195
|
-
expect(onClose).not.toHaveBeenCalled();
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('snaps back without dismissing on pointercancel, regardless of distance', () => {
|
|
199
|
-
const onClose = vi.fn();
|
|
200
|
-
render(
|
|
201
|
-
<Drawer open onClose={onClose} aria-label="Nav">
|
|
202
|
-
Body
|
|
203
|
-
</Drawer>,
|
|
204
|
-
);
|
|
205
|
-
const handle = getHandle();
|
|
206
|
-
fireEvent.pointerDown(handle, { clientY: 0 });
|
|
207
|
-
fireEvent.pointerMove(handle, { clientY: 200 }); // well past the threshold
|
|
208
|
-
fireEvent.pointerCancel(handle, { clientY: 200 });
|
|
209
|
-
expect(onClose).not.toHaveBeenCalled();
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('ignores upward drags (already fully open)', () => {
|
|
213
|
-
const onClose = vi.fn();
|
|
214
|
-
render(
|
|
215
|
-
<Drawer open onClose={onClose} aria-label="Nav">
|
|
216
|
-
Body
|
|
217
|
-
</Drawer>,
|
|
218
|
-
);
|
|
219
|
-
const handle = getHandle();
|
|
220
|
-
fireEvent.pointerDown(handle, { clientY: 100 });
|
|
221
|
-
fireEvent.pointerMove(handle, { clientY: 0 }); // upward
|
|
222
|
-
fireEvent.pointerUp(handle, { clientY: 0 });
|
|
223
|
-
expect(onClose).not.toHaveBeenCalled();
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
.root {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
align-items: center;
|
|
5
|
-
justify-content: center;
|
|
6
|
-
gap: var(--sv-space-3);
|
|
7
|
-
padding: var(--sv-space-12) var(--sv-space-6);
|
|
8
|
-
text-align: center;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.icon {
|
|
12
|
-
color: var(--sv-color-text-subtle);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.heading {
|
|
16
|
-
margin: 0;
|
|
17
|
-
font-size: var(--sv-font-size-md);
|
|
18
|
-
font-weight: var(--sv-font-weight-semibold);
|
|
19
|
-
color: var(--sv-color-text-primary);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.description {
|
|
23
|
-
margin: 0;
|
|
24
|
-
font-size: var(--sv-font-size-sm);
|
|
25
|
-
color: var(--sv-color-text-muted);
|
|
26
|
-
max-width: 36ch;
|
|
27
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import { Icon } from '../Icon/Icon';
|
|
3
|
-
import type { IconName } from '../Icon/Icon';
|
|
4
|
-
import styles from './EmptyState.module.css';
|
|
5
|
-
|
|
6
|
-
export interface EmptyStateProps {
|
|
7
|
-
icon?: IconName;
|
|
8
|
-
heading: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
action?: ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function EmptyState({ icon, heading, description, action, className }: EmptyStateProps) {
|
|
15
|
-
return (
|
|
16
|
-
<div className={[styles.root, className].filter(Boolean).join(' ')}>
|
|
17
|
-
{icon && (
|
|
18
|
-
<span className={styles.icon}>
|
|
19
|
-
<Icon name={icon} size="lg" aria-hidden={true} />
|
|
20
|
-
</span>
|
|
21
|
-
)}
|
|
22
|
-
<h2 className={styles.heading}>{heading}</h2>
|
|
23
|
-
{description && <p className={styles.description}>{description}</p>}
|
|
24
|
-
{action}
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
.dropzone {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
gap: var(--sv-space-4);
|
|
5
|
-
width: 100%;
|
|
6
|
-
box-sizing: border-box;
|
|
7
|
-
padding: var(--sv-space-4) var(--sv-space-5);
|
|
8
|
-
border: 1.5px dashed var(--sv-color-border);
|
|
9
|
-
border-radius: var(--sv-radius-md);
|
|
10
|
-
background-color: var(--sv-color-surface-raised);
|
|
11
|
-
cursor: pointer;
|
|
12
|
-
transition:
|
|
13
|
-
background-color 0.12s ease,
|
|
14
|
-
border-color 0.12s ease;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@media (hover: hover) {
|
|
18
|
-
.dropzone:hover {
|
|
19
|
-
background-color: var(--sv-color-surface-sunken);
|
|
20
|
-
border-color: var(--sv-color-border-strong);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.dropzoneActive {
|
|
25
|
-
background-color: var(--sv-color-surface-sunken);
|
|
26
|
-
border-color: var(--sv-color-border-strong);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.dropzoneDisabled {
|
|
30
|
-
opacity: 0.5;
|
|
31
|
-
cursor: not-allowed;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.icon {
|
|
35
|
-
display: inline-flex;
|
|
36
|
-
flex-shrink: 0;
|
|
37
|
-
color: var(--sv-color-text-muted);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.text {
|
|
41
|
-
display: flex;
|
|
42
|
-
flex-direction: column;
|
|
43
|
-
gap: 2px;
|
|
44
|
-
min-width: 0;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.title {
|
|
48
|
-
font-size: var(--sv-font-size-sm);
|
|
49
|
-
font-weight: var(--sv-font-weight-medium);
|
|
50
|
-
color: var(--sv-color-text-primary);
|
|
51
|
-
overflow: hidden;
|
|
52
|
-
text-overflow: ellipsis;
|
|
53
|
-
white-space: nowrap;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.hint {
|
|
57
|
-
font-size: var(--sv-font-size-xs);
|
|
58
|
-
color: var(--sv-color-text-muted);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.hiddenInput {
|
|
62
|
-
display: none;
|
|
63
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import type { DragEvent, ReactNode } from 'react';
|
|
4
|
-
import { useRef, useState } from 'react';
|
|
5
|
-
import { Icon } from '../Icon/Icon';
|
|
6
|
-
import styles from './FileDropzone.module.css';
|
|
7
|
-
|
|
8
|
-
export interface FileDropzoneProps {
|
|
9
|
-
/** Native `<input type="file">` `name` attribute — set this to submit the
|
|
10
|
-
* file as part of a native `<form action={...}>` (Server Action) request. */
|
|
11
|
-
name?: string;
|
|
12
|
-
/** Native `<input type="file">` `accept` attribute, e.g. `".zip,application/zip"`. */
|
|
13
|
-
accept?: string;
|
|
14
|
-
/** Icon shown beside the label — a file-type glyph. Defaults to a generic file icon. */
|
|
15
|
-
icon?: ReactNode;
|
|
16
|
-
/** Primary label — e.g. "Choose a ZIP file", or the selected file's name. */
|
|
17
|
-
label: string;
|
|
18
|
-
/** Secondary hint — e.g. "or drag and drop here", or the selected file's size. */
|
|
19
|
-
hint?: string;
|
|
20
|
-
/** Called with the picked or dropped file, or `null` if the input is cleared. */
|
|
21
|
-
onFileSelect: (file: File | null) => void;
|
|
22
|
-
/** Accessible name for the control — describe what will be uploaded. */
|
|
23
|
-
ariaLabel: string;
|
|
24
|
-
disabled?: boolean;
|
|
25
|
-
className?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* A styled drag-and-drop file picker: a dashed-border dropzone wrapping a
|
|
30
|
-
* visually-hidden native `<input type="file">`, so the native picker still
|
|
31
|
-
* opens on click and the field participates in normal form semantics. A
|
|
32
|
-
* dropped file is written into the input's own `FileList` (via `DataTransfer`)
|
|
33
|
-
* so `name` + native `<form action>` submission sees it exactly like a
|
|
34
|
-
* click-picked file — not just the `onFileSelect` callback.
|
|
35
|
-
*
|
|
36
|
-
* Caller owns the selected-file state and passes `label`/`hint` accordingly
|
|
37
|
-
* (e.g. swap to the picked file's name/size) — this component is otherwise
|
|
38
|
-
* uncontrolled and stateless beyond its own drag-hover visual.
|
|
39
|
-
*
|
|
40
|
-
* Do not pass `required` through to a wrapping form's validation via this
|
|
41
|
-
* field — `display: none` on the hidden input does not exempt it from HTML5
|
|
42
|
-
* constraint validation, so a `required` hidden input can block submission
|
|
43
|
-
* with no visible field for the user to focus. Validate `onFileSelect`'s
|
|
44
|
-
* result in application code instead.
|
|
45
|
-
*/
|
|
46
|
-
export function FileDropzone({
|
|
47
|
-
name,
|
|
48
|
-
accept,
|
|
49
|
-
icon,
|
|
50
|
-
label,
|
|
51
|
-
hint,
|
|
52
|
-
onFileSelect,
|
|
53
|
-
ariaLabel,
|
|
54
|
-
disabled,
|
|
55
|
-
className,
|
|
56
|
-
}: FileDropzoneProps) {
|
|
57
|
-
const [dragging, setDragging] = useState(false);
|
|
58
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<label
|
|
62
|
-
className={[
|
|
63
|
-
styles.dropzone,
|
|
64
|
-
dragging ? styles.dropzoneActive : '',
|
|
65
|
-
disabled ? styles.dropzoneDisabled : '',
|
|
66
|
-
className,
|
|
67
|
-
]
|
|
68
|
-
.filter(Boolean)
|
|
69
|
-
.join(' ')}
|
|
70
|
-
onDragOver={(event: DragEvent) => {
|
|
71
|
-
if (disabled) return;
|
|
72
|
-
event.preventDefault();
|
|
73
|
-
setDragging(true);
|
|
74
|
-
}}
|
|
75
|
-
onDragLeave={() => setDragging(false)}
|
|
76
|
-
onDrop={(event: DragEvent) => {
|
|
77
|
-
if (disabled) return;
|
|
78
|
-
event.preventDefault();
|
|
79
|
-
setDragging(false);
|
|
80
|
-
const dropped = event.dataTransfer.files[0];
|
|
81
|
-
if (!dropped) return;
|
|
82
|
-
if (inputRef.current && typeof DataTransfer !== 'undefined') {
|
|
83
|
-
const transfer = new DataTransfer();
|
|
84
|
-
transfer.items.add(dropped);
|
|
85
|
-
inputRef.current.files = transfer.files;
|
|
86
|
-
}
|
|
87
|
-
onFileSelect(dropped);
|
|
88
|
-
}}
|
|
89
|
-
>
|
|
90
|
-
<span className={styles.icon} aria-hidden="true">
|
|
91
|
-
{icon ?? <Icon name="file" size="lg" aria-hidden />}
|
|
92
|
-
</span>
|
|
93
|
-
<span className={styles.text}>
|
|
94
|
-
<span className={styles.title}>{label}</span>
|
|
95
|
-
{hint && <span className={styles.hint}>{hint}</span>}
|
|
96
|
-
</span>
|
|
97
|
-
<input
|
|
98
|
-
ref={inputRef}
|
|
99
|
-
type="file"
|
|
100
|
-
name={name}
|
|
101
|
-
aria-label={ariaLabel}
|
|
102
|
-
accept={accept}
|
|
103
|
-
disabled={disabled}
|
|
104
|
-
onChange={(event) => onFileSelect(event.target.files?.[0] ?? null)}
|
|
105
|
-
className={styles.hiddenInput}
|
|
106
|
-
/>
|
|
107
|
-
</label>
|
|
108
|
-
);
|
|
109
|
-
}
|