@tempoxyz/ds 0.3.0 → 0.3.2
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/dist/web/components/Accordion.css +1 -1
- package/dist/web/components/Accordion.js.zyzz.json +1 -1
- package/dist/web/components/AddressCard.css +1 -0
- package/dist/web/components/AddressCard.d.ts +85 -0
- package/dist/web/components/AddressCard.d.ts.map +1 -0
- package/dist/web/components/AddressCard.js +79 -0
- package/dist/web/components/AddressCard.js.map +1 -0
- package/dist/web/components/AddressCard.js.zyzz.json +1 -0
- package/dist/web/components/AgentLogo.js +1 -1
- package/dist/web/components/AgentLogo.js.map +1 -1
- package/dist/web/components/AgentLogo.js.zyzz.json +1 -1
- package/dist/web/components/Alert.css +1 -1
- package/dist/web/components/Alert.d.ts +7 -2
- package/dist/web/components/Alert.d.ts.map +1 -1
- package/dist/web/components/Alert.js +12 -7
- package/dist/web/components/Alert.js.map +1 -1
- package/dist/web/components/Alert.js.zyzz.json +1 -1
- package/dist/web/components/AlertDialog.js.zyzz.json +1 -1
- package/dist/web/components/Amount.css +1 -1
- package/dist/web/components/Amount.js.zyzz.json +1 -1
- package/dist/web/components/AmountInput.css +1 -1
- package/dist/web/components/AmountInput.d.ts +1 -1
- package/dist/web/components/AmountInput.d.ts.map +1 -1
- package/dist/web/components/AmountInput.js.zyzz.json +1 -1
- package/dist/web/components/AppShell.css +1 -1
- package/dist/web/components/AppShell.d.ts +128 -2
- package/dist/web/components/AppShell.d.ts.map +1 -1
- package/dist/web/components/AppShell.js +122 -32
- package/dist/web/components/AppShell.js.map +1 -1
- package/dist/web/components/AppShell.js.zyzz.json +1 -1
- package/dist/web/components/AssetChip.css +1 -1
- package/dist/web/components/AssetChip.d.ts.map +1 -1
- package/dist/web/components/AssetChip.js.map +1 -1
- package/dist/web/components/AssetChip.js.zyzz.json +1 -1
- package/dist/web/components/Autocomplete.js.zyzz.json +1 -1
- package/dist/web/components/Avatar.css +1 -1
- package/dist/web/components/Avatar.d.ts +68 -6
- package/dist/web/components/Avatar.d.ts.map +1 -1
- package/dist/web/components/Avatar.js +27 -7
- package/dist/web/components/Avatar.js.map +1 -1
- package/dist/web/components/Avatar.js.zyzz.json +1 -1
- package/dist/web/components/Badge.css +1 -1
- package/dist/web/components/Badge.d.ts +49 -1
- package/dist/web/components/Badge.d.ts.map +1 -1
- package/dist/web/components/Badge.js +5 -3
- package/dist/web/components/Badge.js.map +1 -1
- package/dist/web/components/Badge.js.zyzz.json +1 -1
- package/dist/web/components/Banner.css +1 -1
- package/dist/web/components/Banner.js.zyzz.json +1 -1
- package/dist/web/components/BarChart.css +1 -1
- package/dist/web/components/BarChart.js.zyzz.json +1 -1
- package/dist/web/components/Breadcrumbs.css +1 -1
- package/dist/web/components/Breadcrumbs.js.zyzz.json +1 -1
- package/dist/web/components/Button.css +1 -1
- package/dist/web/components/Button.d.ts +82 -12
- package/dist/web/components/Button.d.ts.map +1 -1
- package/dist/web/components/Button.js +6 -3
- package/dist/web/components/Button.js.map +1 -1
- package/dist/web/components/Button.js.zyzz.json +1 -1
- package/dist/web/components/ButtonGroup.js.zyzz.json +1 -1
- package/dist/web/components/Calendar.css +1 -1
- package/dist/web/components/Calendar.js.zyzz.json +1 -1
- package/dist/web/components/Callout.css +1 -0
- package/dist/web/components/Callout.d.ts +23 -0
- package/dist/web/components/Callout.d.ts.map +1 -0
- package/dist/web/components/Callout.js +26 -0
- package/dist/web/components/Callout.js.map +1 -0
- package/dist/web/components/Callout.js.zyzz.json +1 -0
- package/dist/web/components/Checkbox.css +1 -1
- package/dist/web/components/Checkbox.js.zyzz.json +1 -1
- package/dist/web/components/CheckboxGroup.js.zyzz.json +1 -1
- package/dist/web/components/ChoiceGroup.css +1 -1
- package/dist/web/components/ChoiceGroup.d.ts +17 -10
- package/dist/web/components/ChoiceGroup.d.ts.map +1 -1
- package/dist/web/components/ChoiceGroup.js +5 -5
- package/dist/web/components/ChoiceGroup.js.map +1 -1
- package/dist/web/components/ChoiceGroup.js.zyzz.json +1 -1
- package/dist/web/components/Choicebox.css +1 -1
- package/dist/web/components/Choicebox.js.zyzz.json +1 -1
- package/dist/web/components/Code.css +1 -0
- package/dist/web/components/Code.d.ts +25 -0
- package/dist/web/components/Code.d.ts.map +1 -0
- package/dist/web/components/Code.js +28 -0
- package/dist/web/components/Code.js.map +1 -0
- package/dist/web/components/Code.js.zyzz.json +1 -0
- package/dist/web/components/Combobox.css +1 -1
- package/dist/web/components/Combobox.js.zyzz.json +1 -1
- package/dist/web/components/Container.js.zyzz.json +1 -1
- package/dist/web/components/CopyButton.d.ts +8 -1
- package/dist/web/components/CopyButton.d.ts.map +1 -1
- package/dist/web/components/CopyButton.js.map +1 -1
- package/dist/web/components/CopyButton.js.zyzz.json +1 -1
- package/dist/web/components/DatePicker.css +1 -1
- package/dist/web/components/DatePicker.js.zyzz.json +1 -1
- package/dist/web/components/Dialog.css +1 -1
- package/dist/web/components/Dialog.d.ts.map +1 -1
- package/dist/web/components/Dialog.js +2 -1
- package/dist/web/components/Dialog.js.map +1 -1
- package/dist/web/components/Dialog.js.zyzz.json +1 -1
- package/dist/web/components/Drawer.js.zyzz.json +1 -1
- package/dist/web/components/Empty.css +1 -1
- package/dist/web/components/Empty.js.zyzz.json +1 -1
- package/dist/web/components/Field.css +1 -1
- package/dist/web/components/Field.d.ts +41 -5
- package/dist/web/components/Field.d.ts.map +1 -1
- package/dist/web/components/Field.js +19 -13
- package/dist/web/components/Field.js.map +1 -1
- package/dist/web/components/Field.js.zyzz.json +1 -1
- package/dist/web/components/Fieldset.js.zyzz.json +1 -1
- package/dist/web/components/Frame.css +1 -1
- package/dist/web/components/Frame.js.zyzz.json +1 -1
- package/dist/web/components/Gauge.js.zyzz.json +1 -1
- package/dist/web/components/GetStartedVisual.css +1 -0
- package/dist/web/components/GetStartedVisual.d.ts +59 -0
- package/dist/web/components/GetStartedVisual.d.ts.map +1 -0
- package/dist/web/components/GetStartedVisual.js +31 -0
- package/dist/web/components/GetStartedVisual.js.map +1 -0
- package/dist/web/components/GetStartedVisual.js.zyzz.json +1 -0
- package/dist/web/components/Grid.js.zyzz.json +1 -1
- package/dist/web/components/HeroVisual.css +1 -0
- package/dist/web/components/HeroVisual.d.ts +96 -0
- package/dist/web/components/HeroVisual.d.ts.map +1 -0
- package/dist/web/components/HeroVisual.js +202 -0
- package/dist/web/components/HeroVisual.js.map +1 -0
- package/dist/web/components/HeroVisual.js.zyzz.json +1 -0
- package/dist/web/components/Hex.css +1 -1
- package/dist/web/components/Hex.js.zyzz.json +1 -1
- package/dist/web/components/IconTile.css +1 -1
- package/dist/web/components/IconTile.js.zyzz.json +1 -1
- package/dist/web/components/Identicon.js.zyzz.json +1 -1
- package/dist/web/components/Inline.js.zyzz.json +1 -1
- package/dist/web/components/Inset.js.zyzz.json +1 -1
- package/dist/web/components/Kbd.css +1 -1
- package/dist/web/components/Kbd.d.ts +8 -7
- package/dist/web/components/Kbd.d.ts.map +1 -1
- package/dist/web/components/Kbd.js +1 -1
- package/dist/web/components/Kbd.js.map +1 -1
- package/dist/web/components/Kbd.js.zyzz.json +1 -1
- package/dist/web/components/ListGroup.css +1 -1
- package/dist/web/components/ListGroup.d.ts +39 -22
- package/dist/web/components/ListGroup.d.ts.map +1 -1
- package/dist/web/components/ListGroup.js +24 -21
- package/dist/web/components/ListGroup.js.map +1 -1
- package/dist/web/components/ListGroup.js.zyzz.json +1 -1
- package/dist/web/components/LoadingDots.js.zyzz.json +1 -1
- package/dist/web/components/Menu.css +1 -1
- package/dist/web/components/Menu.js.zyzz.json +1 -1
- package/dist/web/components/NativeSelect.css +1 -0
- package/dist/web/components/NativeSelect.d.ts +50 -0
- package/dist/web/components/NativeSelect.d.ts.map +1 -0
- package/dist/web/components/NativeSelect.js +50 -0
- package/dist/web/components/NativeSelect.js.map +1 -0
- package/dist/web/components/NativeSelect.js.zyzz.json +1 -0
- package/dist/web/components/NetworkLogo.js.zyzz.json +1 -1
- package/dist/web/components/NumberField.css +1 -1
- package/dist/web/components/NumberField.js.zyzz.json +1 -1
- package/dist/web/components/OtpField.css +1 -1
- package/dist/web/components/OtpField.js.zyzz.json +1 -1
- package/dist/web/components/Pagination.css +1 -1
- package/dist/web/components/Pagination.js.zyzz.json +1 -1
- package/dist/web/components/Popover.css +1 -1
- package/dist/web/components/Popover.js.zyzz.json +1 -1
- package/dist/web/components/Progress.css +1 -1
- package/dist/web/components/Progress.d.ts +1 -1
- package/dist/web/components/Progress.d.ts.map +1 -1
- package/dist/web/components/Progress.js +2 -1
- package/dist/web/components/Progress.js.map +1 -1
- package/dist/web/components/Progress.js.zyzz.json +1 -1
- package/dist/web/components/Qr.js.zyzz.json +1 -1
- package/dist/web/components/RadioGroup.css +1 -1
- package/dist/web/components/RadioGroup.d.ts +1 -1
- package/dist/web/components/RadioGroup.js.zyzz.json +1 -1
- package/dist/web/components/SecretValue.css +1 -1
- package/dist/web/components/SecretValue.js.zyzz.json +1 -1
- package/dist/web/components/Select.css +1 -1
- package/dist/web/components/Select.d.ts +1 -1
- package/dist/web/components/Select.d.ts.map +1 -1
- package/dist/web/components/Select.js +2 -2
- package/dist/web/components/Select.js.map +1 -1
- package/dist/web/components/Select.js.zyzz.json +1 -1
- package/dist/web/components/Separator.css +1 -1
- package/dist/web/components/Separator.js.zyzz.json +1 -1
- package/dist/web/components/SidebarMenu.css +1 -1
- package/dist/web/components/SidebarMenu.d.ts +60 -2
- package/dist/web/components/SidebarMenu.d.ts.map +1 -1
- package/dist/web/components/SidebarMenu.js +47 -16
- package/dist/web/components/SidebarMenu.js.map +1 -1
- package/dist/web/components/SidebarMenu.js.zyzz.json +1 -1
- package/dist/web/components/Skeleton.css +1 -1
- package/dist/web/components/Skeleton.js.zyzz.json +1 -1
- package/dist/web/components/Slider.css +1 -1
- package/dist/web/components/Slider.js.zyzz.json +1 -1
- package/dist/web/components/Snippet.css +1 -1
- package/dist/web/components/Snippet.js.zyzz.json +1 -1
- package/dist/web/components/Spinner.js.zyzz.json +1 -1
- package/dist/web/components/SplitBar.css +1 -1
- package/dist/web/components/SplitBar.js.zyzz.json +1 -1
- package/dist/web/components/SplitButton.css +1 -1
- package/dist/web/components/SplitButton.d.ts +3 -1
- package/dist/web/components/SplitButton.d.ts.map +1 -1
- package/dist/web/components/SplitButton.js +2 -2
- package/dist/web/components/SplitButton.js.map +1 -1
- package/dist/web/components/SplitButton.js.zyzz.json +1 -1
- package/dist/web/components/Stack.js.zyzz.json +1 -1
- package/dist/web/components/StatusChip.css +1 -1
- package/dist/web/components/StatusChip.js.zyzz.json +1 -1
- package/dist/web/components/StatusIndicator.css +1 -0
- package/dist/web/components/StatusIndicator.d.ts +74 -0
- package/dist/web/components/StatusIndicator.d.ts.map +1 -0
- package/dist/web/components/StatusIndicator.js +32 -0
- package/dist/web/components/StatusIndicator.js.map +1 -0
- package/dist/web/components/StatusIndicator.js.zyzz.json +1 -0
- package/dist/web/components/StatusRow.css +1 -1
- package/dist/web/components/StatusRow.js.zyzz.json +1 -1
- package/dist/web/components/Stepper.js.zyzz.json +1 -1
- package/dist/web/components/SuccessHero.css +1 -0
- package/dist/web/components/SuccessHero.d.ts +74 -0
- package/dist/web/components/SuccessHero.d.ts.map +1 -0
- package/dist/web/components/SuccessHero.js +167 -0
- package/dist/web/components/SuccessHero.js.map +1 -0
- package/dist/web/components/SuccessHero.js.zyzz.json +1 -0
- package/dist/web/components/Surface.css +1 -1
- package/dist/web/components/Surface.d.ts +86 -0
- package/dist/web/components/Surface.d.ts.map +1 -1
- package/dist/web/components/Surface.js +6 -3
- package/dist/web/components/Surface.js.map +1 -1
- package/dist/web/components/Surface.js.zyzz.json +1 -1
- package/dist/web/components/Switch.css +1 -1
- package/dist/web/components/Switch.d.ts +6 -6
- package/dist/web/components/Switch.d.ts.map +1 -1
- package/dist/web/components/Switch.js +3 -2
- package/dist/web/components/Switch.js.map +1 -1
- package/dist/web/components/Switch.js.zyzz.json +1 -1
- package/dist/web/components/Table.css +1 -1
- package/dist/web/components/Table.d.ts +85 -0
- package/dist/web/components/Table.d.ts.map +1 -1
- package/dist/web/components/Table.js +14 -6
- package/dist/web/components/Table.js.map +1 -1
- package/dist/web/components/Table.js.zyzz.json +1 -1
- package/dist/web/components/Tabs.css +1 -1
- package/dist/web/components/Tabs.d.ts +183 -6
- package/dist/web/components/Tabs.d.ts.map +1 -1
- package/dist/web/components/Tabs.js +18 -13
- package/dist/web/components/Tabs.js.map +1 -1
- package/dist/web/components/Tabs.js.zyzz.json +1 -1
- package/dist/web/components/TempoLogo.js +1 -1
- package/dist/web/components/TempoLogo.js.map +1 -1
- package/dist/web/components/TempoLogo.js.zyzz.json +1 -1
- package/dist/web/components/TextInput.css +1 -1
- package/dist/web/components/TextInput.d.ts +80 -2
- package/dist/web/components/TextInput.d.ts.map +1 -1
- package/dist/web/components/TextInput.js +19 -7
- package/dist/web/components/TextInput.js.map +1 -1
- package/dist/web/components/TextInput.js.zyzz.json +1 -1
- package/dist/web/components/Textarea.css +1 -1
- package/dist/web/components/Textarea.d.ts +7 -1
- package/dist/web/components/Textarea.d.ts.map +1 -1
- package/dist/web/components/Textarea.js +3 -2
- package/dist/web/components/Textarea.js.map +1 -1
- package/dist/web/components/Textarea.js.zyzz.json +1 -1
- package/dist/web/components/Toast.css +1 -1
- package/dist/web/components/Toast.d.ts +16 -3
- package/dist/web/components/Toast.d.ts.map +1 -1
- package/dist/web/components/Toast.js +29 -17
- package/dist/web/components/Toast.js.map +1 -1
- package/dist/web/components/Toast.js.zyzz.json +1 -1
- package/dist/web/components/Token.css +1 -1
- package/dist/web/components/Token.js.zyzz.json +1 -1
- package/dist/web/components/TokenLogo.js.zyzz.json +1 -1
- package/dist/web/components/Tooltip.css +1 -1
- package/dist/web/components/Tooltip.d.ts.map +1 -1
- package/dist/web/components/Tooltip.js +3 -2
- package/dist/web/components/Tooltip.js.map +1 -1
- package/dist/web/components/Tooltip.js.zyzz.json +1 -1
- package/dist/web/components/VerificationCode.css +1 -1
- package/dist/web/components/VerificationCode.js.zyzz.json +1 -1
- package/dist/web/components/Visual.js.zyzz.json +1 -1
- package/dist/web/components/internal/Field.css +1 -1
- package/dist/web/components/internal/Field.js.zyzz.json +1 -1
- package/dist/web/components/internal/GetStartedArtwork.d.ts +10 -0
- package/dist/web/components/internal/GetStartedArtwork.d.ts.map +1 -0
- package/dist/web/components/internal/GetStartedArtwork.js +11 -0
- package/dist/web/components/internal/GetStartedArtwork.js.map +1 -0
- package/dist/web/components/internal/InputGroup.css +1 -1
- package/dist/web/components/internal/InputGroup.js.zyzz.json +1 -1
- package/dist/web/components/internal/Listbox.css +1 -1
- package/dist/web/components/internal/Listbox.js.zyzz.json +1 -1
- package/dist/web/components/internal/Streaks.css +1 -0
- package/dist/web/components/internal/Streaks.d.ts +48 -0
- package/dist/web/components/internal/Streaks.d.ts.map +1 -0
- package/dist/web/components/internal/Streaks.js +48 -0
- package/dist/web/components/internal/Streaks.js.map +1 -0
- package/dist/web/components/internal/Streaks.js.zyzz.json +1 -0
- package/dist/web/components/internal/TabBar.d.ts +37 -0
- package/dist/web/components/internal/TabBar.d.ts.map +1 -0
- package/dist/web/components/internal/TabBar.js +30 -0
- package/dist/web/components/internal/TabBar.js.map +1 -0
- package/dist/web/components/internal/Text.d.ts +9 -0
- package/dist/web/components/internal/Text.d.ts.map +1 -0
- package/dist/web/components/internal/Text.js +35 -0
- package/dist/web/components/internal/Text.js.map +1 -0
- package/dist/web/index.d.ts +8 -0
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +8 -0
- package/dist/web/index.js.map +1 -1
- package/dist/web/index.js.zyzz.json +1 -1
- package/dist/web/vars.d.ts +51 -6
- package/dist/web/vars.d.ts.map +1 -1
- package/dist/web/vars.js.map +1 -1
- package/dist/web/vars.js.zyzz.json +1 -1
- package/dist/web/zyzz.config.d.ts +255 -30
- package/dist/web/zyzz.config.d.ts.map +1 -1
- package/dist/web/zyzz.config.js.zyzz.json +1 -1
- package/package.json +1 -1
- package/src/web/components/AddressCard.tsx +216 -0
- package/src/web/components/AgentLogo.tsx +1 -1
- package/src/web/components/Alert.tsx +25 -5
- package/src/web/components/AmountInput.tsx +1 -1
- package/src/web/components/AppShell.tsx +383 -22
- package/src/web/components/AssetChip.tsx +4 -1
- package/src/web/components/Avatar.tsx +73 -6
- package/src/web/components/Badge.tsx +43 -5
- package/src/web/components/Button.tsx +78 -21
- package/src/web/components/Callout.tsx +45 -0
- package/src/web/components/ChoiceGroup.tsx +26 -12
- package/src/web/components/Code.tsx +42 -0
- package/src/web/components/CopyButton.tsx +8 -4
- package/src/web/components/Dialog.tsx +9 -2
- package/src/web/components/Field.tsx +53 -20
- package/src/web/components/GetStartedVisual.tsx +66 -0
- package/src/web/components/HeroVisual.tsx +304 -0
- package/src/web/components/Kbd.tsx +16 -9
- package/src/web/components/ListGroup.tsx +75 -28
- package/src/web/components/NativeSelect.tsx +167 -0
- package/src/web/components/Progress.tsx +3 -2
- package/src/web/components/RadioGroup.tsx +1 -1
- package/src/web/components/Select.tsx +4 -1
- package/src/web/components/SidebarMenu.tsx +106 -7
- package/src/web/components/SplitButton.tsx +11 -4
- package/src/web/components/StatusIndicator.tsx +94 -0
- package/src/web/components/SuccessHero.tsx +249 -0
- package/src/web/components/Surface.tsx +107 -1
- package/src/web/components/Switch.tsx +18 -25
- package/src/web/components/Table.tsx +69 -1
- package/src/web/components/Tabs.tsx +172 -10
- package/src/web/components/TempoLogo.tsx +1 -1
- package/src/web/components/TextInput.tsx +87 -5
- package/src/web/components/Textarea.tsx +9 -1
- package/src/web/components/Toast.tsx +67 -34
- package/src/web/components/Tooltip.tsx +6 -4
- package/src/web/components/internal/GetStartedArtwork.tsx +356 -0
- package/src/web/components/internal/Streaks.tsx +173 -0
- package/src/web/components/internal/TabBar.ts +56 -0
- package/src/web/components/internal/Text.ts +39 -0
- package/src/web/components/visuals/GetStartedConnect.svg +36 -0
- package/src/web/components/visuals/GetStartedFunds.svg +31 -0
- package/src/web/components/visuals/GetStartedPasskey.svg +34 -0
- package/src/web/components/visuals/README.md +15 -0
- package/src/web/index.ts +8 -0
- package/src/web/logos/README.md +1 -1
- package/src/web/vars.ts +34 -10
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import * as BaseUi from '@base-ui/react/drawer'
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render'
|
|
2
3
|
import {
|
|
3
4
|
type ComponentPropsWithRef,
|
|
4
5
|
createContext,
|
|
5
6
|
use,
|
|
7
|
+
useId,
|
|
8
|
+
useLayoutEffect,
|
|
6
9
|
useState,
|
|
7
10
|
useSyncExternalStore,
|
|
8
11
|
} from 'react'
|
|
9
12
|
import type * as zyzz from 'zyzz'
|
|
10
13
|
import { keyframes } from 'zyzz/web'
|
|
11
14
|
import { style, variants, vars } from '../zyzz.config.js'
|
|
15
|
+
import * as TabBar from './internal/TabBar.js'
|
|
16
|
+
import * as Text from './internal/Text.js'
|
|
12
17
|
|
|
13
18
|
type Context = {
|
|
19
|
+
collapse: boolean
|
|
14
20
|
container: HTMLDivElement | null
|
|
15
21
|
handle: BaseUi.Drawer.Handle<unknown>
|
|
16
22
|
open: boolean
|
|
@@ -19,21 +25,25 @@ type Context = {
|
|
|
19
25
|
|
|
20
26
|
const context = createContext<Context | undefined>(undefined)
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// The viewport breakpoint is a literal because media queries cannot read CSS variables.
|
|
25
|
-
function useCompact() {
|
|
28
|
+
/** Reads a media query, and `false` on the server and during hydration. */
|
|
29
|
+
function useQuery(query: string) {
|
|
26
30
|
return useSyncExternalStore(
|
|
27
31
|
(notify) => {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
return () =>
|
|
32
|
+
const list = window.matchMedia(query)
|
|
33
|
+
list.addEventListener('change', notify)
|
|
34
|
+
return () => list.removeEventListener('change', notify)
|
|
31
35
|
},
|
|
32
|
-
() => window.matchMedia(
|
|
36
|
+
() => window.matchMedia(query).matches,
|
|
33
37
|
() => false,
|
|
34
38
|
)
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
// The sidebar opens as a drawer below 1024px, or below 768px when it collapses to its icons from
|
|
42
|
+
// 768px to 1023px. The breakpoints are literals because media queries cannot read CSS variables.
|
|
43
|
+
function useCompact(collapse: boolean) {
|
|
44
|
+
return useQuery(collapse ? '(max-width: 767px)' : '(max-width: 1023px)')
|
|
45
|
+
}
|
|
46
|
+
|
|
37
47
|
function useShell() {
|
|
38
48
|
const value = use(context)
|
|
39
49
|
if (!value) throw new Error('AppShell parts must render inside AppShell.Root')
|
|
@@ -112,7 +122,9 @@ export namespace AppShell {
|
|
|
112
122
|
export function Root(props: Root.Props) {
|
|
113
123
|
const {
|
|
114
124
|
align,
|
|
125
|
+
children,
|
|
115
126
|
className,
|
|
127
|
+
collapse = false,
|
|
116
128
|
defaultOpen = false,
|
|
117
129
|
onOpenChange,
|
|
118
130
|
open,
|
|
@@ -121,6 +133,7 @@ export namespace AppShell {
|
|
|
121
133
|
...attributes
|
|
122
134
|
} = props
|
|
123
135
|
const [handle] = useState(() => BaseUi.Drawer.createHandle<unknown>())
|
|
136
|
+
const [tabBar] = useState(TabBar.create)
|
|
124
137
|
const [uncontrolled, setUncontrolled] = useState(defaultOpen)
|
|
125
138
|
const [container, setContainer] = useState<HTMLDivElement | null>(null)
|
|
126
139
|
const current = open ?? uncontrolled
|
|
@@ -128,6 +141,7 @@ export namespace AppShell {
|
|
|
128
141
|
return (
|
|
129
142
|
<context.Provider
|
|
130
143
|
value={{
|
|
144
|
+
collapse,
|
|
131
145
|
container,
|
|
132
146
|
handle,
|
|
133
147
|
open: current,
|
|
@@ -140,13 +154,19 @@ export namespace AppShell {
|
|
|
140
154
|
<div
|
|
141
155
|
{...attributes}
|
|
142
156
|
{...styles.root({ align, className, style: props.style, vars })}
|
|
157
|
+
data-app-shell-collapse={collapse ? '' : undefined}
|
|
143
158
|
data-state={current ? 'open' : 'closed'}
|
|
144
159
|
ref={(node) => {
|
|
145
160
|
setContainer(node)
|
|
146
161
|
if (typeof ref === 'function') ref(node)
|
|
147
162
|
else if (ref) ref.current = node
|
|
148
163
|
}}
|
|
149
|
-
|
|
164
|
+
>
|
|
165
|
+
<TabBar.Context.Provider value={tabBar}>
|
|
166
|
+
{children}
|
|
167
|
+
<BottomBar />
|
|
168
|
+
</TabBar.Context.Provider>
|
|
169
|
+
</div>
|
|
150
170
|
</context.Provider>
|
|
151
171
|
)
|
|
152
172
|
}
|
|
@@ -154,6 +174,14 @@ export namespace AppShell {
|
|
|
154
174
|
export namespace Root {
|
|
155
175
|
export type Props = ComponentPropsWithRef<'div'> &
|
|
156
176
|
zyzz.Props.Variants<typeof styles.root> & {
|
|
177
|
+
/**
|
|
178
|
+
* Collapses the inline sidebar to a 64px column of icons from 768px to 1023px, and opens
|
|
179
|
+
* the drawer only below 768px. Give every `SidebarMenu.Item` an icon as its first child.
|
|
180
|
+
* Absent, the sidebar opens as a drawer below 1024px.
|
|
181
|
+
* @default false
|
|
182
|
+
*/
|
|
183
|
+
collapse?: boolean | undefined
|
|
184
|
+
|
|
157
185
|
/**
|
|
158
186
|
* Initial drawer state when `open` is uncontrolled.
|
|
159
187
|
* @default false
|
|
@@ -177,10 +205,18 @@ export namespace AppShell {
|
|
|
177
205
|
export function Sidebar(props: Sidebar.Props) {
|
|
178
206
|
const { className, vars, ...attributes } = props
|
|
179
207
|
const shell = useShell()
|
|
180
|
-
const compact = useCompact()
|
|
208
|
+
const compact = useCompact(shell.collapse)
|
|
181
209
|
const sidebar = styles.sidebar({ className, style: props.style, vars })
|
|
182
210
|
|
|
183
|
-
if (!compact)
|
|
211
|
+
if (!compact)
|
|
212
|
+
return (
|
|
213
|
+
<aside
|
|
214
|
+
{...attributes}
|
|
215
|
+
{...styles.inline(sidebar)}
|
|
216
|
+
data-app-shell-rail={shell.collapse ? '' : undefined}
|
|
217
|
+
data-app-shell-sidebar="inline"
|
|
218
|
+
/>
|
|
219
|
+
)
|
|
184
220
|
|
|
185
221
|
return (
|
|
186
222
|
<BaseUi.Drawer.Root
|
|
@@ -189,7 +225,8 @@ export namespace AppShell {
|
|
|
189
225
|
open={shell.open}
|
|
190
226
|
swipeDirection="right"
|
|
191
227
|
>
|
|
192
|
-
|
|
228
|
+
{/* The closed drawer stays mounted, so its items register in the bottom bar. */}
|
|
229
|
+
<BaseUi.Drawer.Portal container={shell.container} keepMounted>
|
|
193
230
|
<BaseUi.Drawer.Backdrop {...styles.backdrop()} />
|
|
194
231
|
<BaseUi.Drawer.Viewport {...styles.viewport()}>
|
|
195
232
|
<BaseUi.Drawer.Popup
|
|
@@ -262,25 +299,49 @@ export namespace AppShell {
|
|
|
262
299
|
* Toggles the sidebar drawer from a button fixed to the top-right corner, above the drawer, whose
|
|
263
300
|
* two bars turn into a close mark while it is open. Hidden from 1024px, where the sidebar is
|
|
264
301
|
* always visible. It is named `Open menu` or `Close menu` and exposes `aria-expanded`. Pass
|
|
265
|
-
* `aria-label` to replace the name, or `children` to replace the bars.
|
|
302
|
+
* `aria-label` to replace the name, or `children` to replace the bars. With `tabBar`, the bottom
|
|
303
|
+
* bar renders it as its floating action button below 768px instead of the top-right button.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* <AppShell.Trigger tabBar />
|
|
266
307
|
*/
|
|
267
308
|
export function Trigger(props: Trigger.Props) {
|
|
268
|
-
const { children, className, vars, ...attributes } = props
|
|
309
|
+
const { children, className, ref, tabBar = false, vars, ...attributes } = props
|
|
269
310
|
const shell = useShell()
|
|
311
|
+
const store = use(TabBar.Context)
|
|
312
|
+
const id = useId()
|
|
313
|
+
// The bottom bar shows below 768px, so the ref follows whichever of the two buttons shows.
|
|
314
|
+
const bar = useQuery('(max-width: 767px)') && tabBar
|
|
315
|
+
|
|
316
|
+
// Registers on every render, so the bottom bar repeats the current props of the trigger.
|
|
317
|
+
useLayoutEffect(() => {
|
|
318
|
+
if (!store) return
|
|
319
|
+
if (!tabBar) return store.delete(id)
|
|
320
|
+
|
|
321
|
+
const { style: _, ...rest } = attributes
|
|
322
|
+
store.set(id, {
|
|
323
|
+
active: false,
|
|
324
|
+
attributes: { ...rest, ref: bar ? ref : undefined },
|
|
325
|
+
children,
|
|
326
|
+
variant: 'menu',
|
|
327
|
+
})
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
useLayoutEffect(() => {
|
|
331
|
+
if (!store) return
|
|
332
|
+
return () => store.delete(id)
|
|
333
|
+
}, [id, store])
|
|
270
334
|
|
|
271
335
|
return (
|
|
272
336
|
<BaseUi.Drawer.Trigger
|
|
273
337
|
aria-label={shell.open ? 'Close menu' : 'Open menu'}
|
|
274
338
|
{...attributes}
|
|
275
339
|
{...styles.trigger({ className, style: props.style, vars })}
|
|
340
|
+
data-app-shell-tab-bar={tabBar ? '' : undefined}
|
|
276
341
|
handle={shell.handle}
|
|
342
|
+
ref={bar ? undefined : ref}
|
|
277
343
|
>
|
|
278
|
-
{children ??
|
|
279
|
-
<span aria-hidden="true" {...styles.bars()}>
|
|
280
|
-
<span {...styles.bar()} />
|
|
281
|
-
<span {...styles.bar()} />
|
|
282
|
-
</span>
|
|
283
|
-
)}
|
|
344
|
+
{children ?? <Bars />}
|
|
284
345
|
</BaseUi.Drawer.Trigger>
|
|
285
346
|
)
|
|
286
347
|
}
|
|
@@ -288,10 +349,101 @@ export namespace AppShell {
|
|
|
288
349
|
export namespace Trigger {
|
|
289
350
|
export type Props = ComponentPropsWithRef<'button'> &
|
|
290
351
|
zyzz.Props.Variants<typeof styles.trigger> &
|
|
291
|
-
Pick<BaseUi.Drawer.Trigger.Props, 'nativeButton' | 'render'>
|
|
352
|
+
Pick<BaseUi.Drawer.Trigger.Props, 'nativeButton' | 'render'> & {
|
|
353
|
+
/**
|
|
354
|
+
* Renders the trigger as the floating action button of the bottom bar below 768px, after
|
|
355
|
+
* the `action` items, in place of the top-right button. While the drawer is open, the
|
|
356
|
+
* button stays above it as a close mark, and the other items of the bar fade out.
|
|
357
|
+
*/
|
|
358
|
+
tabBar?: boolean | undefined
|
|
359
|
+
}
|
|
292
360
|
}
|
|
293
361
|
}
|
|
294
362
|
|
|
363
|
+
/** The two bars of a trigger, which cross into a close mark while the drawer is open. */
|
|
364
|
+
function Bars() {
|
|
365
|
+
return (
|
|
366
|
+
<span aria-hidden="true" {...styles.bars()}>
|
|
367
|
+
<span {...styles.bar()} />
|
|
368
|
+
<span {...styles.bar()} />
|
|
369
|
+
</span>
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Repeats the `SidebarMenu.Item`s that set `tabBar` in a bar fixed to the bottom edge below 768px:
|
|
375
|
+
* `tab` items as icons in a pill `<nav>`, then each `action` item as a floating action button, then
|
|
376
|
+
* the `AppShell.Trigger` that sets `tabBar`. Renders nothing while nothing registers.
|
|
377
|
+
*/
|
|
378
|
+
function BottomBar() {
|
|
379
|
+
const store = use(TabBar.Context)!
|
|
380
|
+
const entries = useSyncExternalStore(store.subscribe, store.snapshot, store.snapshot)
|
|
381
|
+
const tabs = entries.filter(([, entry]) => entry.variant === 'tab')
|
|
382
|
+
const actions = entries.filter(([, entry]) => entry.variant === 'action')
|
|
383
|
+
const menus = entries.filter(([, entry]) => entry.variant === 'menu')
|
|
384
|
+
|
|
385
|
+
if (entries.length === 0) return null
|
|
386
|
+
|
|
387
|
+
return (
|
|
388
|
+
<div
|
|
389
|
+
{...styles.bottomBar()}
|
|
390
|
+
data-app-shell-bottom-bar=""
|
|
391
|
+
data-app-shell-menu={menus.length > 0 ? '' : undefined}
|
|
392
|
+
>
|
|
393
|
+
{tabs.length > 0 && (
|
|
394
|
+
<nav aria-label="Main" {...styles.tabBar()}>
|
|
395
|
+
{tabs.map(([id, entry]) => (
|
|
396
|
+
<BottomBarItem entry={entry} key={id} />
|
|
397
|
+
))}
|
|
398
|
+
</nav>
|
|
399
|
+
)}
|
|
400
|
+
{actions.map(([id, entry]) => (
|
|
401
|
+
<BottomBarItem entry={entry} key={id} />
|
|
402
|
+
))}
|
|
403
|
+
{menus.map(([id, entry]) => (
|
|
404
|
+
<BottomBarTrigger entry={entry} key={id} />
|
|
405
|
+
))}
|
|
406
|
+
</div>
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Renders the element of a `SidebarMenu.Item` with the attributes and `render` of the item, and
|
|
412
|
+
* shows only its first element, such as its icon. Its text stays in the accessible name.
|
|
413
|
+
*/
|
|
414
|
+
function BottomBarItem(props: { entry: TabBar.Entry }) {
|
|
415
|
+
const { entry } = props
|
|
416
|
+
|
|
417
|
+
return useRender({
|
|
418
|
+
defaultTagName: 'a',
|
|
419
|
+
props: {
|
|
420
|
+
...entry.attributes,
|
|
421
|
+
'aria-current': entry.active ? 'page' : undefined,
|
|
422
|
+
...(entry.variant === 'tab' ? styles.tab({ active: entry.active }) : styles.action()),
|
|
423
|
+
children: Text.wrap(entry.children, styles.label()),
|
|
424
|
+
},
|
|
425
|
+
render: entry.render,
|
|
426
|
+
})
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** Renders the `AppShell.Trigger` that sets `tabBar` as a floating action button. */
|
|
430
|
+
function BottomBarTrigger(props: { entry: TabBar.Entry }) {
|
|
431
|
+
const { entry } = props
|
|
432
|
+
const shell = useShell()
|
|
433
|
+
|
|
434
|
+
return (
|
|
435
|
+
<BaseUi.Drawer.Trigger
|
|
436
|
+
aria-label={shell.open ? 'Close menu' : 'Open menu'}
|
|
437
|
+
{...(entry.attributes as BaseUi.Drawer.Trigger.Props)}
|
|
438
|
+
{...styles.action()}
|
|
439
|
+
data-app-shell-menu-trigger=""
|
|
440
|
+
handle={shell.handle}
|
|
441
|
+
>
|
|
442
|
+
{entry.children ?? <Bars />}
|
|
443
|
+
</BaseUi.Drawer.Trigger>
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
295
447
|
const fadeIn = keyframes(
|
|
296
448
|
{ from: { opacity: 0 }, to: { opacity: 1 } },
|
|
297
449
|
{ id: 'tds/web/app-shell/fade-in' },
|
|
@@ -303,6 +455,54 @@ const fadeOut = keyframes(
|
|
|
303
455
|
)
|
|
304
456
|
|
|
305
457
|
namespace styles {
|
|
458
|
+
// The 56px circle of the Platform Floating Action Button.
|
|
459
|
+
export const action = style(
|
|
460
|
+
{
|
|
461
|
+
alignItems: 'center',
|
|
462
|
+
backgroundColor: 'inverse.background.secondary',
|
|
463
|
+
borderRadius: 'full',
|
|
464
|
+
boxShadow: 'large',
|
|
465
|
+
boxSizing: 'border-box',
|
|
466
|
+
color: 'inverse.content.primary',
|
|
467
|
+
cornerShape: 'round',
|
|
468
|
+
cursor: 'pointer',
|
|
469
|
+
display: 'flex',
|
|
470
|
+
flexShrink: '0 !custom',
|
|
471
|
+
height: '56',
|
|
472
|
+
justifyContent: 'center',
|
|
473
|
+
outlineColor: 'transparent !custom',
|
|
474
|
+
outlineOffset: '0',
|
|
475
|
+
outlineStyle: 'solid !custom',
|
|
476
|
+
outlineWidth: '2',
|
|
477
|
+
position: 'relative',
|
|
478
|
+
textDecoration: 'none !custom',
|
|
479
|
+
transitionDuration: '160',
|
|
480
|
+
transitionProperty: 'opacity, outline-color, scale !custom',
|
|
481
|
+
transitionTimingFunction: 'snappy',
|
|
482
|
+
width: '56',
|
|
483
|
+
selectors: {
|
|
484
|
+
'& > :first-child': { flexShrink: '0 !custom', fontSize: '24' },
|
|
485
|
+
'& > :not(:first-child)': {
|
|
486
|
+
clipPath: 'inset(50%) !custom',
|
|
487
|
+
height: '1px !custom',
|
|
488
|
+
overflow: 'hidden',
|
|
489
|
+
position: 'absolute',
|
|
490
|
+
whiteSpace: 'nowrap',
|
|
491
|
+
width: '1px !custom',
|
|
492
|
+
},
|
|
493
|
+
'&:active': { scale: 'press', transitionDuration: '100' },
|
|
494
|
+
'&:focus-visible': { outlineColor: 'border.focus' },
|
|
495
|
+
// The design dims the button to 88% under the pointer, which no opacity token sets.
|
|
496
|
+
'&:hover': { opacity: '0.88 !custom' },
|
|
497
|
+
},
|
|
498
|
+
'@media (prefers-reduced-motion: reduce)': {
|
|
499
|
+
transitionProperty: 'opacity, outline-color !custom',
|
|
500
|
+
selectors: { '&:active': { scale: 'none !custom' } },
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
{ id: 'tds/web/app-shell/action' },
|
|
504
|
+
)
|
|
505
|
+
|
|
306
506
|
export const backdrop = style(
|
|
307
507
|
{
|
|
308
508
|
backgroundColor: 'neutral.100',
|
|
@@ -350,6 +550,31 @@ namespace styles {
|
|
|
350
550
|
{ id: 'tds/web/app-shell/bar' },
|
|
351
551
|
)
|
|
352
552
|
|
|
553
|
+
// Floats over the content, inset by the 24px page margin of the Mobile layout and 16px from the
|
|
554
|
+
// bottom edge. It sits below the drawer and its backdrop.
|
|
555
|
+
export const bottomBar = style(
|
|
556
|
+
{
|
|
557
|
+
alignItems: 'center',
|
|
558
|
+
bottom: 'calc(1rem + env(safe-area-inset-bottom)) !custom',
|
|
559
|
+
columnGap: '12',
|
|
560
|
+
display: 'none',
|
|
561
|
+
insetInline: '24',
|
|
562
|
+
position: 'fixed',
|
|
563
|
+
zIndex: '39 !custom',
|
|
564
|
+
selectors: {
|
|
565
|
+
// A bar that holds the trigger rises above the open drawer, so the trigger closes it. The
|
|
566
|
+
// other items fade out and leave the drawer uncovered.
|
|
567
|
+
'[data-state="open"] > &[data-app-shell-menu]': { zIndex: 'modal' },
|
|
568
|
+
'[data-state="open"] > &[data-app-shell-menu] > :not([data-app-shell-menu-trigger])': {
|
|
569
|
+
opacity: '0 !custom',
|
|
570
|
+
pointerEvents: 'none',
|
|
571
|
+
},
|
|
572
|
+
},
|
|
573
|
+
'@media (max-width: 767px)': { display: 'flex' },
|
|
574
|
+
},
|
|
575
|
+
{ id: 'tds/web/app-shell/bottom-bar' },
|
|
576
|
+
)
|
|
577
|
+
|
|
353
578
|
export const bars = style(
|
|
354
579
|
{ display: 'block', height: '16', position: 'relative', width: '16' },
|
|
355
580
|
{ id: 'tds/web/app-shell/bars' },
|
|
@@ -375,6 +600,14 @@ namespace styles {
|
|
|
375
600
|
},
|
|
376
601
|
'&[data-starting-style]': { transform: 'translateX(100%) !custom' },
|
|
377
602
|
'&[data-swiping]': { transitionDuration: '0', userSelect: 'none' },
|
|
603
|
+
// The trigger in the bottom bar stays above the open drawer, so the drawer ends 16px above
|
|
604
|
+
// it, and its footer stays uncovered.
|
|
605
|
+
'[data-state]:has(> [data-app-shell-bottom-bar][data-app-shell-menu]) &': {
|
|
606
|
+
paddingBlockEnd: 'calc(5.5rem + env(safe-area-inset-bottom)) !custom',
|
|
607
|
+
},
|
|
608
|
+
// The closed drawer stays mounted with the `hidden` attribute, which the flex layout of
|
|
609
|
+
// the sidebar would override.
|
|
610
|
+
'&[hidden]': { display: 'none !custom' },
|
|
378
611
|
},
|
|
379
612
|
'@media (prefers-reduced-motion: reduce)': {
|
|
380
613
|
transitionProperty: 'opacity !custom',
|
|
@@ -411,8 +644,11 @@ namespace styles {
|
|
|
411
644
|
paddingInline: '16',
|
|
412
645
|
'@media (min-width: 640px)': { marginInline: '-2rem !custom', paddingInline: '24' },
|
|
413
646
|
// Below 1024px the fixed trigger covers the end of the bar, so header actions end 8px
|
|
414
|
-
// before it: its 40px plus its 16px inset.
|
|
647
|
+
// before it: its 40px plus its 16px inset. A collapsed sidebar hides it from 768px.
|
|
415
648
|
'@media (max-width: 1023px)': { paddingInlineEnd: '64' },
|
|
649
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
650
|
+
selectors: { '[data-app-shell-collapse] > main > &': { paddingInlineEnd: '24' } },
|
|
651
|
+
},
|
|
416
652
|
},
|
|
417
653
|
},
|
|
418
654
|
{ id: 'tds/web/app-shell/header' },
|
|
@@ -454,6 +690,15 @@ namespace styles {
|
|
|
454
690
|
'@media (max-width: 1023px)': {
|
|
455
691
|
selectors: { '&::after, &::before': { display: 'none !custom' } },
|
|
456
692
|
},
|
|
693
|
+
// The bottom bar covers the end of the page, so content can scroll clear of it: 16px
|
|
694
|
+
// below the bar, its 56px, and 16px above it.
|
|
695
|
+
'@media (max-width: 767px)': {
|
|
696
|
+
selectors: {
|
|
697
|
+
'&:has(> [data-app-shell-bottom-bar]) > main': {
|
|
698
|
+
paddingBottom: 'calc(5.5rem + env(safe-area-inset-bottom)) !custom',
|
|
699
|
+
},
|
|
700
|
+
},
|
|
701
|
+
},
|
|
457
702
|
},
|
|
458
703
|
defaultVariants: { align: 'center' },
|
|
459
704
|
variants: {
|
|
@@ -504,6 +749,19 @@ namespace styles {
|
|
|
504
749
|
{ id: 'tds/web/app-shell/sidebar' },
|
|
505
750
|
)
|
|
506
751
|
|
|
752
|
+
// Keeps the label of a bottom bar item in its accessible name without painting it.
|
|
753
|
+
export const label = style(
|
|
754
|
+
{
|
|
755
|
+
clipPath: 'inset(50%) !custom',
|
|
756
|
+
height: '1px !custom',
|
|
757
|
+
overflow: 'hidden',
|
|
758
|
+
position: 'absolute',
|
|
759
|
+
whiteSpace: 'nowrap',
|
|
760
|
+
width: '1px !custom',
|
|
761
|
+
},
|
|
762
|
+
{ id: 'tds/web/app-shell/label' },
|
|
763
|
+
)
|
|
764
|
+
|
|
507
765
|
// Follows `sidebar`, so its compact `display: none` overrides the sidebar's `display: flex` in
|
|
508
766
|
// server-rendered markup, which always emits the wide layout.
|
|
509
767
|
export const inline = style(
|
|
@@ -517,6 +775,12 @@ namespace styles {
|
|
|
517
775
|
position: 'sticky',
|
|
518
776
|
width: 'var(--sidebar-width, 16rem) !custom',
|
|
519
777
|
'@media (max-width: 1023px)': { display: 'none !custom' },
|
|
778
|
+
// A collapsed sidebar stays inline as a column of icons, which `SidebarMenu` centers.
|
|
779
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
780
|
+
selectors: {
|
|
781
|
+
'&[data-app-shell-rail]': { display: 'flex !custom', width: '4rem !custom' },
|
|
782
|
+
},
|
|
783
|
+
},
|
|
520
784
|
},
|
|
521
785
|
{ id: 'tds/web/app-shell/inline' },
|
|
522
786
|
)
|
|
@@ -538,6 +802,15 @@ namespace styles {
|
|
|
538
802
|
// Classic scrollbars keep their own lane instead of covering content at the edge.
|
|
539
803
|
scrollbarGutter: 'stable',
|
|
540
804
|
scrollbarWidth: 'thin',
|
|
805
|
+
// The collapsed sidebar has no room for a scrollbar lane beside its 40px icons.
|
|
806
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
807
|
+
selectors: {
|
|
808
|
+
'[data-app-shell-rail] &': {
|
|
809
|
+
scrollbarGutter: 'auto !custom',
|
|
810
|
+
scrollbarWidth: 'none !custom',
|
|
811
|
+
},
|
|
812
|
+
},
|
|
813
|
+
},
|
|
541
814
|
selectors: {
|
|
542
815
|
// Curtains fade content into the sidebar at whichever end has more to scroll.
|
|
543
816
|
'&::after, &::before': {
|
|
@@ -598,6 +871,86 @@ namespace styles {
|
|
|
598
871
|
{ id: 'tds/web/app-shell/sidebar-header' },
|
|
599
872
|
)
|
|
600
873
|
|
|
874
|
+
// An icon-only item of the Platform Tab Bar, which fills its share of the pill.
|
|
875
|
+
export const tab = variants(
|
|
876
|
+
{
|
|
877
|
+
base: {
|
|
878
|
+
alignItems: 'center',
|
|
879
|
+
borderRadius: 'full',
|
|
880
|
+
boxSizing: 'border-box',
|
|
881
|
+
color: 'content.secondary',
|
|
882
|
+
cornerShape: 'round',
|
|
883
|
+
cursor: 'pointer',
|
|
884
|
+
display: 'flex',
|
|
885
|
+
flex: '1 !custom',
|
|
886
|
+
height: '100% !custom',
|
|
887
|
+
justifyContent: 'center',
|
|
888
|
+
minWidth: '0',
|
|
889
|
+
outlineColor: 'transparent !custom',
|
|
890
|
+
outlineOffset: '-2',
|
|
891
|
+
outlineStyle: 'solid !custom',
|
|
892
|
+
outlineWidth: '2',
|
|
893
|
+
position: 'relative',
|
|
894
|
+
textDecoration: 'none !custom',
|
|
895
|
+
transitionDuration: '160',
|
|
896
|
+
transitionProperty: 'background-color, color, outline-color, scale !custom',
|
|
897
|
+
transitionTimingFunction: 'snappy',
|
|
898
|
+
selectors: {
|
|
899
|
+
'& > :first-child': { flexShrink: '0 !custom', fontSize: '24' },
|
|
900
|
+
'& > :not(:first-child)': {
|
|
901
|
+
clipPath: 'inset(50%) !custom',
|
|
902
|
+
height: '1px !custom',
|
|
903
|
+
overflow: 'hidden',
|
|
904
|
+
position: 'absolute',
|
|
905
|
+
whiteSpace: 'nowrap',
|
|
906
|
+
width: '1px !custom',
|
|
907
|
+
},
|
|
908
|
+
'&:active': { scale: 'press', transitionDuration: '100' },
|
|
909
|
+
'&:focus-visible': { outlineColor: 'border.focus' },
|
|
910
|
+
'&:hover': { color: 'content.primary' },
|
|
911
|
+
},
|
|
912
|
+
'@media (prefers-reduced-motion: reduce)': {
|
|
913
|
+
transitionProperty: 'background-color, color, outline-color !custom',
|
|
914
|
+
selectors: { '&:active': { scale: 'none !custom' } },
|
|
915
|
+
},
|
|
916
|
+
},
|
|
917
|
+
defaultVariants: { active: false },
|
|
918
|
+
variants: {
|
|
919
|
+
active: {
|
|
920
|
+
false: {},
|
|
921
|
+
true: { backgroundColor: 'container.strong', color: 'content.primary' },
|
|
922
|
+
},
|
|
923
|
+
},
|
|
924
|
+
},
|
|
925
|
+
{ id: 'tds/web/app-shell/tab' },
|
|
926
|
+
)
|
|
927
|
+
|
|
928
|
+
// The 56px pill of the Platform Tab Bar, which takes the width beside the action button. Its 48px
|
|
929
|
+
// items sit 4px inside the 1px border at either end and 3px inside it at the top and bottom.
|
|
930
|
+
export const tabBar = style(
|
|
931
|
+
{
|
|
932
|
+
alignItems: 'center',
|
|
933
|
+
backgroundColor: 'background.elevated',
|
|
934
|
+
borderColor: 'line.secondary',
|
|
935
|
+
borderRadius: 'full',
|
|
936
|
+
borderStyle: 'solid',
|
|
937
|
+
borderWidth: 'regular',
|
|
938
|
+
boxShadow: 'regular',
|
|
939
|
+
boxSizing: 'border-box',
|
|
940
|
+
cornerShape: 'round',
|
|
941
|
+
display: 'flex',
|
|
942
|
+
flex: '1 !custom',
|
|
943
|
+
height: '56',
|
|
944
|
+
minWidth: '0',
|
|
945
|
+
paddingBlock: '3',
|
|
946
|
+
paddingInline: '4',
|
|
947
|
+
transitionDuration: '200',
|
|
948
|
+
transitionProperty: 'opacity !custom',
|
|
949
|
+
transitionTimingFunction: 'snappy',
|
|
950
|
+
},
|
|
951
|
+
{ id: 'tds/web/app-shell/tab-bar' },
|
|
952
|
+
)
|
|
953
|
+
|
|
601
954
|
export const title = variants(
|
|
602
955
|
{
|
|
603
956
|
base: {
|
|
@@ -654,6 +1007,13 @@ namespace styles {
|
|
|
654
1007
|
},
|
|
655
1008
|
},
|
|
656
1009
|
'@media (min-width: 1024px)': { display: 'none !custom' },
|
|
1010
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
1011
|
+
selectors: { '[data-app-shell-collapse] &': { display: 'none !custom' } },
|
|
1012
|
+
},
|
|
1013
|
+
// The bottom bar renders this trigger as its floating action button.
|
|
1014
|
+
'@media (max-width: 767px)': {
|
|
1015
|
+
selectors: { '&[data-app-shell-tab-bar]': { display: 'none !custom' } },
|
|
1016
|
+
},
|
|
657
1017
|
'@media (prefers-reduced-motion: reduce)': {
|
|
658
1018
|
transitionProperty: 'background-color, outline-color, outline-offset !custom',
|
|
659
1019
|
selectors: { '&:active': { transform: 'none !custom' } },
|
|
@@ -670,6 +1030,7 @@ namespace styles {
|
|
|
670
1030
|
justifyContent: 'flex-end',
|
|
671
1031
|
position: 'fixed',
|
|
672
1032
|
zIndex: 'popover',
|
|
1033
|
+
selectors: { '&[hidden]': { display: 'none !custom' } },
|
|
673
1034
|
},
|
|
674
1035
|
{ id: 'tds/web/app-shell/viewport' },
|
|
675
1036
|
)
|
|
@@ -96,7 +96,10 @@ namespace styles {
|
|
|
96
96
|
'&:is(button):not([data-selected], :disabled):hover': {
|
|
97
97
|
backgroundColor: 'container.strong',
|
|
98
98
|
},
|
|
99
|
-
'&[data-selected]': {
|
|
99
|
+
'&[data-selected]': {
|
|
100
|
+
backgroundColor: 'inverse.background.primary',
|
|
101
|
+
color: 'inverse.content.primary',
|
|
102
|
+
},
|
|
100
103
|
// An inside ring would vanish into the selected fill, so a selected chip draws it outside.
|
|
101
104
|
'&[data-selected]:focus-visible': { outlineOffset: '2' },
|
|
102
105
|
},
|