@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
|
@@ -122,8 +122,8 @@ export namespace ListGroup {
|
|
|
122
122
|
/**
|
|
123
123
|
* Stacks a `ListGroup.Title` above a `ListGroup.Description`, beside a leading avatar or logo and a
|
|
124
124
|
* trailing control. A row that holds it pads 12px above and below. `large` sets a 16px title 2px
|
|
125
|
-
* above a monospace description,
|
|
126
|
-
* above its address. Defaults to `size="medium"`.
|
|
125
|
+
* above a monospace description, in a row that pads 8px above and below, for the row that
|
|
126
|
+
* introduces a `boxed` group, such as a wallet above its address. Defaults to `size="medium"`.
|
|
127
127
|
*/
|
|
128
128
|
export function Info(props: Info.Props) {
|
|
129
129
|
const { className, size, vars, ...attributes } = props
|
|
@@ -267,6 +267,7 @@ export namespace ListGroup {
|
|
|
267
267
|
*
|
|
268
268
|
* Rows are 36px with 12px text, which fits a 32px control. `dividers={false}` drops the line
|
|
269
269
|
* between rows, which `spaced` never draws. Variants default to `dividers`, `variant="plain"`.
|
|
270
|
+
* Inside a `Surface`, `plain` rows reach its edges and pad by its padding.
|
|
270
271
|
*/
|
|
271
272
|
export function Root(props: Root.Props) {
|
|
272
273
|
const { className, dividers, variant, vars, ...attributes } = props
|
|
@@ -275,6 +276,8 @@ export namespace ListGroup {
|
|
|
275
276
|
<RowsSize.Context value>
|
|
276
277
|
<div
|
|
277
278
|
{...attributes}
|
|
279
|
+
data-list-group=""
|
|
280
|
+
data-variant={variant ?? 'plain'}
|
|
278
281
|
{...styles.root({ className, dividers, style: props.style, variant, vars })}
|
|
279
282
|
/>
|
|
280
283
|
</RowsSize.Context>
|
|
@@ -288,9 +291,11 @@ export namespace ListGroup {
|
|
|
288
291
|
/**
|
|
289
292
|
* Renders a button when pressable, a `label` around a radio when it has a `value`, or a link or
|
|
290
293
|
* other element through `render`. `ref` and attributes reach that element. Children sit 12px
|
|
291
|
-
* apart, such as an `Avatar`, a `ListGroup.Info` and a trailing `Button`. A pressable row
|
|
292
|
-
*
|
|
294
|
+
* apart, such as an `Avatar`, a `ListGroup.Info` and a trailing `Button`. A pressable row stays
|
|
295
|
+
* flush with its content, and its hover fill and focus ring bleed 12px past it at each side. A static row that holds a control, such as a Copy
|
|
293
296
|
* `Button`, takes the same fill on hover and stays static, so the control is the only target.
|
|
297
|
+
* A `Select` in a row hugs its value at the row's end, in the row's type, 32px tall and without a
|
|
298
|
+
* fill of its own.
|
|
294
299
|
*
|
|
295
300
|
* A row with a `value` is a radio of the `ListGroup.RadioGroup` around it, in a 12px block with
|
|
296
301
|
* 16px sides. A press anywhere on the row selects it, and a 16px ring at its end shows the
|
|
@@ -385,8 +390,8 @@ export namespace ListGroup {
|
|
|
385
390
|
/** Content of the row, laid out 12px apart. */
|
|
386
391
|
children?: ReactNode | undefined
|
|
387
392
|
/**
|
|
388
|
-
* Dims the row to 40% and disables it: a button row sets `disabled`, a radio row
|
|
389
|
-
* its radio and ignores presses, and any other row sets `aria-disabled` and ignores
|
|
393
|
+
* Dims the row to 40% opacity and disables it: a button row sets `disabled`, a radio row
|
|
394
|
+
* disables its radio and ignores presses, and any other row sets `aria-disabled` and ignores
|
|
390
395
|
* presses. A static row also disables the native controls inside it, such as a Copy
|
|
391
396
|
* `Button`, and every `Switch` and `Checkbox`, which leave the Tab order and ignore presses
|
|
392
397
|
* and input. Its children receive no presses, and its text stays readable.
|
|
@@ -443,6 +448,30 @@ namespace styles {
|
|
|
443
448
|
minWidth: '0',
|
|
444
449
|
padding: '0',
|
|
445
450
|
textAlign: 'start',
|
|
451
|
+
selectors: {
|
|
452
|
+
// A select in a row reads as the row's value: it hugs its value at the end in the row's
|
|
453
|
+
// type, fits the row's 32px control height, and draws no fill, since the row draws the
|
|
454
|
+
// hover. A disabled or invalid trigger keeps its own fill. Its box ends on the content
|
|
455
|
+
// edge, so it never overflows the container, and its chevron sits 8px inside its focus
|
|
456
|
+
// ring. `:is(*, :focus-visible)` outweighs the trigger's focus padding, so focus never moves
|
|
457
|
+
// the value. `Select.Trigger` marks itself, so text-input comboboxes keep their field and a
|
|
458
|
+
// trigger rendered as another element still matches.
|
|
459
|
+
'& [data-select-trigger][role="combobox"]:is(*, :focus-visible)': {
|
|
460
|
+
flex: '0 1 auto !custom',
|
|
461
|
+
font: 'inherit !custom',
|
|
462
|
+
height: '32',
|
|
463
|
+
letterSpacing: 'inherit !custom',
|
|
464
|
+
marginInlineStart: 'auto !custom',
|
|
465
|
+
minWidth: '0',
|
|
466
|
+
paddingInline: '8',
|
|
467
|
+
width: 'auto !custom',
|
|
468
|
+
},
|
|
469
|
+
'& [data-select-trigger]:not(:disabled, [data-disabled], [data-invalid], [aria-invalid="true"])':
|
|
470
|
+
{
|
|
471
|
+
backgroundColor: 'transparent !custom',
|
|
472
|
+
},
|
|
473
|
+
'& [data-select-trigger] > [data-select-value]': { flex: '0 1 auto !custom' },
|
|
474
|
+
},
|
|
446
475
|
},
|
|
447
476
|
{ id: 'tds/web/list-group/content' },
|
|
448
477
|
)
|
|
@@ -623,12 +652,14 @@ namespace styles {
|
|
|
623
652
|
'& > [data-divider]:first-child::before': { display: 'none' },
|
|
624
653
|
// A title over a description pads 12px, which fits a 40px leading image.
|
|
625
654
|
'& [data-divider]:has([data-info])': { paddingBlock: '12' },
|
|
655
|
+
// A large title over a description pads 8px, which fits a 40px leading image in 56px.
|
|
656
|
+
'& [data-divider]:has([data-info][data-size="large"])': { paddingBlock: '8' },
|
|
626
657
|
// A row with a meter pads 10px, which centers a 24px agent logo in 44px.
|
|
627
658
|
'& [data-divider]:has([role="meter"])': { paddingBlock: '10' },
|
|
628
659
|
// A hovered row's fill would otherwise sit between two visible separators.
|
|
629
|
-
'& [data-divider]:is(a[href], button, [role="button"], :has(a[href], button, input, select, textarea)):not(:disabled, [data-disabled]):hover::before':
|
|
660
|
+
'& [data-divider]:is(a[href], button, [role="button"], :has(:where(a[href], :is(button, input, select, textarea, [data-select-trigger]):not(:disabled, [data-disabled])))):not(:disabled, [data-disabled]):hover::before':
|
|
630
661
|
{ display: 'none' },
|
|
631
|
-
'& [data-divider]:is(a[href], button, [role="button"], :has(a[href], button, input, select, textarea)):not(:disabled, [data-disabled]):hover + [data-divider]::before':
|
|
662
|
+
'& [data-divider]:is(a[href], button, [role="button"], :has(:where(a[href], :is(button, input, select, textarea, [data-select-trigger]):not(:disabled, [data-disabled])))):not(:disabled, [data-disabled]):hover + [data-divider]::before':
|
|
632
663
|
{ display: 'none' },
|
|
633
664
|
},
|
|
634
665
|
},
|
|
@@ -648,12 +679,6 @@ namespace styles {
|
|
|
648
679
|
borderWidth: 'regular',
|
|
649
680
|
paddingBlock: '8',
|
|
650
681
|
paddingInline: '16',
|
|
651
|
-
selectors: {
|
|
652
|
-
// A large title leads the group from the block's own top padding.
|
|
653
|
-
'& > [data-divider]:first-child:has([data-info][data-size="large"])': {
|
|
654
|
-
paddingBlockStart: '0',
|
|
655
|
-
},
|
|
656
|
-
},
|
|
657
682
|
},
|
|
658
683
|
plain: {},
|
|
659
684
|
spaced: {
|
|
@@ -693,36 +718,57 @@ namespace styles {
|
|
|
693
718
|
columnGap: '12',
|
|
694
719
|
display: 'flex',
|
|
695
720
|
font: 'inherit !custom',
|
|
721
|
+
// The row isolates its highlight, which paints below the content and above whatever is
|
|
722
|
+
// behind the row.
|
|
723
|
+
isolation: 'isolate !custom',
|
|
696
724
|
minHeight: '36',
|
|
697
725
|
outlineColor: 'transparent !custom',
|
|
698
|
-
outlineOffset: '0',
|
|
699
726
|
outlineStyle: 'solid !custom',
|
|
700
727
|
outlineWidth: '2',
|
|
701
728
|
paddingBlock: '2',
|
|
702
729
|
paddingInline: '0',
|
|
730
|
+
position: 'relative',
|
|
703
731
|
textAlign: 'start',
|
|
704
732
|
textDecoration: 'none !custom',
|
|
705
733
|
transitionDuration: '160',
|
|
706
|
-
transitionProperty: '
|
|
734
|
+
transitionProperty: 'opacity',
|
|
707
735
|
transitionTimingFunction: 'snappy',
|
|
708
736
|
width: '100% !custom',
|
|
709
737
|
selectors: {
|
|
710
|
-
// The
|
|
711
|
-
//
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
738
|
+
// The row keeps Figma's List Row geometry, flush with its content. Its highlight is a
|
|
739
|
+
// layer behind the content that bleeds 12px past the content at each side, rounds at
|
|
740
|
+
// 12px, and draws the hover fill and the focus ring. A dialog body scrolls and clips at
|
|
741
|
+
// its 4px padding, so the bleed there is 4px, except in a surface. A static row that
|
|
742
|
+
// holds an enabled control takes the same fill on hover, without becoming pressable.
|
|
743
|
+
'&[data-divider]::after': {
|
|
744
|
+
backgroundColor: 'transparent !custom',
|
|
745
|
+
borderRadius: 'xs',
|
|
746
|
+
content: '"" !custom',
|
|
747
|
+
insetBlock: '0',
|
|
748
|
+
insetInline: '-12',
|
|
749
|
+
outlineColor: 'transparent !custom',
|
|
750
|
+
outlineOffset: '-2',
|
|
751
|
+
outlineStyle: 'solid !custom',
|
|
752
|
+
outlineWidth: '2',
|
|
753
|
+
pointerEvents: 'none',
|
|
754
|
+
position: 'absolute',
|
|
755
|
+
transitionDuration: '160',
|
|
756
|
+
transitionProperty: 'background-color, outline-color',
|
|
757
|
+
transitionTimingFunction: 'snappy',
|
|
758
|
+
zIndex: '-1 !custom',
|
|
759
|
+
},
|
|
760
|
+
'&:is(a[href], button, [role="button"], :has(:where(a[href], :is(button, input, select, textarea, [data-select-trigger]):not(:disabled, [data-disabled])))):not(:disabled, [data-disabled], [data-radio]):hover::after':
|
|
715
761
|
{ backgroundColor: 'container.regular' },
|
|
716
762
|
'&:is(a[href], button, [role="button"]):not(:disabled, [data-disabled])': {
|
|
717
763
|
cursor: 'pointer',
|
|
718
764
|
},
|
|
719
|
-
'&:is(a[href], button, [role="button"]):not(:disabled, [data-disabled]):active':
|
|
720
|
-
backgroundColor: 'container.strong',
|
|
721
|
-
|
|
722
|
-
'&:is(a[href], button, [role="button"]):focus-visible': {
|
|
765
|
+
'&:is(a[href], button, [role="button"]):not(:disabled, [data-disabled], [data-radio]):active::after':
|
|
766
|
+
{ backgroundColor: 'container.strong' },
|
|
767
|
+
'&:is(a[href], button, [role="button"]):not([data-radio]):focus-visible::after': {
|
|
723
768
|
outlineColor: 'border.focus',
|
|
724
|
-
outlineOffset: '-2',
|
|
725
769
|
},
|
|
770
|
+
':is([data-dialog-body], [data-dialog-body] :not([data-surface-size])) > [data-list-group]:not([data-variant="boxed"]) > &[data-divider]::after':
|
|
771
|
+
{ insetInline: '-4' },
|
|
726
772
|
// A radio row is a bordered block whose border thickens when checked and focused, as
|
|
727
773
|
// Figma lays out its stroke, so the row grows by 1px a side for focus.
|
|
728
774
|
'&[data-radio]': {
|
|
@@ -752,13 +798,14 @@ namespace styles {
|
|
|
752
798
|
borderWidth: 'thick',
|
|
753
799
|
},
|
|
754
800
|
'&[data-radio]:active:not(:has(> [data-disabled]))': { scale: 'press' },
|
|
801
|
+
// The Platform designs dim a disabled row to 40%, as they dim a disabled button, above the
|
|
802
|
+
// 32% of opacity.disabled.
|
|
755
803
|
'&[data-disabled], &[data-radio]:has(> [data-disabled])': {
|
|
756
804
|
cursor: 'default',
|
|
757
|
-
opacity: '
|
|
805
|
+
opacity: '0.4 !custom',
|
|
758
806
|
},
|
|
759
807
|
},
|
|
760
808
|
'@media (prefers-reduced-motion: reduce)': {
|
|
761
|
-
transitionProperty: 'background-color, opacity, outline-color',
|
|
762
809
|
selectors: {
|
|
763
810
|
'&[data-radio]': { transitionProperty: 'background-color, border-color, opacity' },
|
|
764
811
|
'&[data-radio]:active': { scale: 'none !custom' },
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as BaseUi from '@base-ui/react/field'
|
|
2
|
+
import type { ComponentPropsWithRef } from 'react'
|
|
3
|
+
import type * as zyzz from 'zyzz'
|
|
4
|
+
import { ChevronDown } from '../icons/ChevronDown.js'
|
|
5
|
+
import { style } from '../zyzz.config.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A native `select` styled as a 48px field, with a chevron at its end. It registers as the control
|
|
9
|
+
* of the enclosing `Field.Root`, which supplies its label, description, error and disabled state.
|
|
10
|
+
* The browser draws the options in its own picker, so it fits forms that need the platform picker,
|
|
11
|
+
* such as on touch devices. Base UI has no primitive for a native `select`, so it renders the
|
|
12
|
+
* element through `Field.Control`.
|
|
13
|
+
*
|
|
14
|
+
* - Give it a visible `Field.Label`, or an `aria-label` when none fits.
|
|
15
|
+
* - Lead with a disabled, empty `option` that names the choice, such as "Select environment", and
|
|
16
|
+
* set `defaultValue=""` so it shows until a value is picked.
|
|
17
|
+
* - Use `Select` instead when the options need icons, groups with styling, or a custom popup.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* <Field.Root>
|
|
21
|
+
* <Field.Label>Environment</Field.Label>
|
|
22
|
+
* <NativeSelect defaultValue="">
|
|
23
|
+
* <option disabled value="">
|
|
24
|
+
* Select environment
|
|
25
|
+
* </option>
|
|
26
|
+
* <option value="production">Production</option>
|
|
27
|
+
* <option value="staging">Staging</option>
|
|
28
|
+
* </NativeSelect>
|
|
29
|
+
* </Field.Root>
|
|
30
|
+
*
|
|
31
|
+
* @see {@link https://base-ui.com/react/components/field | Base UI Field}
|
|
32
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select | MDN select element}
|
|
33
|
+
* @see {@link https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html | WCAG 2.2 Labels or Instructions}
|
|
34
|
+
* @see {@link https://www.w3.org/WAI/WCAG22/Understanding/error-identification.html | WCAG 2.2 Error Identification}
|
|
35
|
+
*/
|
|
36
|
+
export function NativeSelect(props: NativeSelect.Props) {
|
|
37
|
+
const { className, invalid = false, vars, ...attributes } = props
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<span {...styles.root()} data-native-select="">
|
|
41
|
+
{/* Field.Control sets aria-invalid for an invalid Field.Root, which an absent prop keeps. */}
|
|
42
|
+
<BaseUi.Field.Control
|
|
43
|
+
render={
|
|
44
|
+
<select
|
|
45
|
+
{...(invalid && { 'aria-invalid': true })}
|
|
46
|
+
{...attributes}
|
|
47
|
+
{...styles.select({ className, style: props.style, vars })}
|
|
48
|
+
/>
|
|
49
|
+
}
|
|
50
|
+
/>
|
|
51
|
+
<ChevronDown {...styles.icon()} />
|
|
52
|
+
</span>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export namespace NativeSelect {
|
|
57
|
+
export type Props = ComponentPropsWithRef<'select'> &
|
|
58
|
+
zyzz.Props.Variants<typeof styles.select> & {
|
|
59
|
+
/**
|
|
60
|
+
* Fills the field red with a 1px red border and sets `aria-invalid`. An invalid
|
|
61
|
+
* `Field.Root` sets it too.
|
|
62
|
+
*
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
invalid?: boolean | undefined
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
namespace styles {
|
|
70
|
+
// The chevron keeps the primary color, and a disabled field fades it to 40%, as the design does.
|
|
71
|
+
export const icon = style(
|
|
72
|
+
{
|
|
73
|
+
alignSelf: 'center',
|
|
74
|
+
color: 'content.primary',
|
|
75
|
+
fontSize: '16',
|
|
76
|
+
gridArea: '1 / 1 !custom',
|
|
77
|
+
justifySelf: 'end',
|
|
78
|
+
marginInlineEnd: '16',
|
|
79
|
+
pointerEvents: 'none',
|
|
80
|
+
transitionDuration: '160',
|
|
81
|
+
transitionProperty: 'opacity !custom',
|
|
82
|
+
transitionTimingFunction: 'snappy',
|
|
83
|
+
selectors: { ':has(> select:disabled) > &': { opacity: '0.4 !custom' } },
|
|
84
|
+
},
|
|
85
|
+
{ id: 'tds/web/native-select/icon' },
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
// The focus border is drawn over the field, so focus never moves the text past its 0.5px line.
|
|
89
|
+
export const root = style(
|
|
90
|
+
{
|
|
91
|
+
borderRadius: 'xs',
|
|
92
|
+
display: 'grid',
|
|
93
|
+
position: 'relative',
|
|
94
|
+
selectors: {
|
|
95
|
+
'&::after': {
|
|
96
|
+
borderColor: 'transparent !custom',
|
|
97
|
+
borderRadius: 'inherit !custom',
|
|
98
|
+
borderStyle: 'solid !custom',
|
|
99
|
+
borderWidth: 'regular',
|
|
100
|
+
boxSizing: 'border-box',
|
|
101
|
+
content: '"" !custom',
|
|
102
|
+
cornerShape: 'inherit !custom',
|
|
103
|
+
inset: '0',
|
|
104
|
+
pointerEvents: 'none',
|
|
105
|
+
position: 'absolute',
|
|
106
|
+
transitionDuration: '160',
|
|
107
|
+
transitionProperty: 'border-color !custom',
|
|
108
|
+
transitionTimingFunction: 'snappy',
|
|
109
|
+
},
|
|
110
|
+
'&:has(> select:focus-visible)::after': { borderColor: 'border.focus' },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{ id: 'tds/web/native-select' },
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
// The end padding holds the 16px chevron, 8px from the text and 16px from the edge.
|
|
117
|
+
export const select = style(
|
|
118
|
+
{
|
|
119
|
+
appearance: 'none !custom',
|
|
120
|
+
backgroundColor: 'background.elevated',
|
|
121
|
+
borderColor: 'line.secondary',
|
|
122
|
+
borderRadius: 'xs',
|
|
123
|
+
borderStyle: 'solid',
|
|
124
|
+
borderWidth: 'thin',
|
|
125
|
+
boxSizing: 'border-box',
|
|
126
|
+
color: 'content.primary',
|
|
127
|
+
cursor: 'pointer',
|
|
128
|
+
gridArea: '1 / 1 !custom',
|
|
129
|
+
height: '48',
|
|
130
|
+
margin: '0',
|
|
131
|
+
minWidth: '0',
|
|
132
|
+
// Forced colors paint transparent outlines, so this outline is the focus ring only there.
|
|
133
|
+
outlineColor: 'transparent !custom',
|
|
134
|
+
outlineOffset: '2',
|
|
135
|
+
outlineStyle: 'solid !custom',
|
|
136
|
+
outlineWidth: '2',
|
|
137
|
+
paddingBlock: '0',
|
|
138
|
+
paddingInlineEnd: '40',
|
|
139
|
+
paddingInlineStart: '16',
|
|
140
|
+
transitionDuration: '160',
|
|
141
|
+
transitionProperty: 'background-color, border-color, color, outline-color !custom',
|
|
142
|
+
transitionTimingFunction: 'snappy',
|
|
143
|
+
typography: 'body.b2',
|
|
144
|
+
width: '100% !custom',
|
|
145
|
+
selectors: {
|
|
146
|
+
'&:where(:hover:not(:disabled))': { borderColor: 'line.primary' },
|
|
147
|
+
'&[aria-invalid="true"], [data-invalid] &': {
|
|
148
|
+
backgroundColor: 'container.negative',
|
|
149
|
+
borderColor: 'border.negative',
|
|
150
|
+
borderWidth: 'regular',
|
|
151
|
+
},
|
|
152
|
+
// Chromium fades a disabled select to 70%, which the subtle fill replaces.
|
|
153
|
+
'&:disabled': {
|
|
154
|
+
backgroundColor: 'container.subtle',
|
|
155
|
+
color: 'content.tertiary',
|
|
156
|
+
cursor: 'default',
|
|
157
|
+
opacity: '1 !custom',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
'@media (forced-colors: active)': {
|
|
161
|
+
outlineStyle: 'none !custom',
|
|
162
|
+
selectors: { '&:focus-visible': { outlineStyle: 'solid !custom' } },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{ id: 'tds/web/native-select/select' },
|
|
166
|
+
)
|
|
167
|
+
}
|
|
@@ -164,17 +164,18 @@ namespace styles {
|
|
|
164
164
|
)
|
|
165
165
|
|
|
166
166
|
export const label = style(
|
|
167
|
-
{ color: 'content.primary', flex: '1 !custom', typography: 'body.
|
|
167
|
+
{ color: 'content.primary', flex: '1 !custom', typography: 'body.b3Strong' },
|
|
168
168
|
{ id: 'tds/web/progress/label' },
|
|
169
169
|
)
|
|
170
170
|
|
|
171
|
+
// The label row sits 12px above the track.
|
|
171
172
|
export const root = variants(
|
|
172
173
|
{
|
|
173
174
|
base: {
|
|
174
175
|
columnGap: '8',
|
|
175
176
|
display: 'flex',
|
|
176
177
|
flexWrap: 'wrap',
|
|
177
|
-
rowGap: '
|
|
178
|
+
rowGap: '12',
|
|
178
179
|
width: '100% !custom',
|
|
179
180
|
},
|
|
180
181
|
defaultVariants: { intent: 'neutral' },
|
|
@@ -91,7 +91,7 @@ export namespace RadioGroup {
|
|
|
91
91
|
namespace styles {
|
|
92
92
|
export const group = variants(
|
|
93
93
|
{
|
|
94
|
-
base: { display: 'flex', flexDirection: 'column', rowGap: '
|
|
94
|
+
base: { display: 'flex', flexDirection: 'column', rowGap: '16' },
|
|
95
95
|
defaultVariants: { size: 'medium' },
|
|
96
96
|
variants: {
|
|
97
97
|
// Every item is 16, 20 or 24px with a dot that scales with it. The hit area stays at least 36px.
|
|
@@ -273,6 +273,7 @@ export namespace Select {
|
|
|
273
273
|
})}
|
|
274
274
|
aria-invalid={invalid || attributes['aria-invalid']}
|
|
275
275
|
data-invalid={invalid || undefined}
|
|
276
|
+
data-select-trigger=""
|
|
276
277
|
/>
|
|
277
278
|
)
|
|
278
279
|
}
|
|
@@ -296,6 +297,7 @@ export namespace Select {
|
|
|
296
297
|
return (
|
|
297
298
|
<BaseUi.Select.Value
|
|
298
299
|
{...attributes}
|
|
300
|
+
data-select-value=""
|
|
299
301
|
{...styles.value({ className, style: props.style, vars })}
|
|
300
302
|
/>
|
|
301
303
|
)
|
|
@@ -349,9 +351,10 @@ namespace styles {
|
|
|
349
351
|
// a trigger that hugs its content grows 4px wider.
|
|
350
352
|
'&[role="combobox"]:focus-visible': { paddingInline: 'calc(1rem + 2px) !custom' },
|
|
351
353
|
'&[role="combobox"]:focus-visible::before': { borderWidth: 'thick' },
|
|
354
|
+
// The Platform select dims to 40%, past the 32% of the shared disabled opacity.
|
|
352
355
|
'&[role="combobox"]:is(:disabled, [data-disabled])': {
|
|
353
356
|
color: 'content.primary',
|
|
354
|
-
opacity: '
|
|
357
|
+
opacity: '0.4 !custom',
|
|
355
358
|
},
|
|
356
359
|
},
|
|
357
360
|
},
|
|
@@ -13,6 +13,8 @@ import type * as zyzz from 'zyzz'
|
|
|
13
13
|
import { ChevronDown } from '../icons/ChevronDown.js'
|
|
14
14
|
import { ChevronRight } from '../icons/ChevronRight.js'
|
|
15
15
|
import { style, variants } from '../zyzz.config.js'
|
|
16
|
+
import * as TabBar from './internal/TabBar.js'
|
|
17
|
+
import * as Text from './internal/Text.js'
|
|
16
18
|
|
|
17
19
|
// A group names itself after the ID of the label inside it, which a caller can set.
|
|
18
20
|
type GroupContext = { id: string; setLabel: (id: string | undefined) => void }
|
|
@@ -180,15 +182,44 @@ export namespace SidebarMenu {
|
|
|
180
182
|
* Renders a link by default. Pass `render` to use a router link. `active` marks the current page
|
|
181
183
|
* with `aria-current="page"`, and sets its label in the strong weight. Keyboard focus draws a
|
|
182
184
|
* 2px ring inside the row and moves its content 2px inward.
|
|
185
|
+
*
|
|
186
|
+
* Inside an `AppShell`, `tabBar` repeats the item in the bottom bar below 768px, with the same
|
|
187
|
+
* `href`, `render` and handlers. In an `AppShell` with `collapse`, the sidebar shows only the
|
|
188
|
+
* first element of each item from 768px to 1023px, such as its icon, and keeps its text as the
|
|
189
|
+
* accessible name.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* <SidebarMenu.Item active href="/" tabBar="tab">
|
|
193
|
+
* <Home />
|
|
194
|
+
* Home
|
|
195
|
+
* </SidebarMenu.Item>
|
|
183
196
|
*/
|
|
184
197
|
export function Item(props: Item.Props) {
|
|
185
|
-
const { active = false, className, ref, render, vars, ...attributes } = props
|
|
198
|
+
const { active = false, className, ref, render, tabBar, vars, ...attributes } = props
|
|
199
|
+
const store = use(TabBar.Context)
|
|
200
|
+
const id = useId()
|
|
201
|
+
|
|
202
|
+
// Registers on every render, so the bottom bar repeats the current props of the item.
|
|
203
|
+
useLayoutEffect(() => {
|
|
204
|
+
if (!store) return
|
|
205
|
+
if (!tabBar) return store.delete(id)
|
|
206
|
+
|
|
207
|
+
const { children, style: _, ...rest } = attributes
|
|
208
|
+
store.set(id, { active, attributes: rest, children, render, variant: tabBar })
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
useLayoutEffect(() => {
|
|
212
|
+
if (!store) return
|
|
213
|
+
return () => store.delete(id)
|
|
214
|
+
}, [id, store])
|
|
186
215
|
|
|
187
216
|
return useRender({
|
|
188
217
|
defaultTagName: 'a',
|
|
189
218
|
props: {
|
|
190
219
|
...attributes,
|
|
191
220
|
'aria-current': active ? 'page' : undefined,
|
|
221
|
+
// Text renders in a span, so the collapsed sidebar can hide it as an element.
|
|
222
|
+
children: Text.wrap(attributes.children),
|
|
192
223
|
...styles.item({ active, className, style: props.style, vars }),
|
|
193
224
|
},
|
|
194
225
|
ref,
|
|
@@ -200,6 +231,12 @@ export namespace SidebarMenu {
|
|
|
200
231
|
export type Props = Omit<useRender.ComponentProps<'a'>, 'color'> &
|
|
201
232
|
Omit<zyzz.Props.Variants<typeof styles.item>, 'active'> & {
|
|
202
233
|
active?: boolean | undefined
|
|
234
|
+
/**
|
|
235
|
+
* Repeats the item in the bottom bar of an `AppShell` below 768px: `tab` as an icon in the
|
|
236
|
+
* tab bar, or `action` as the floating action button beside it. Give the tab bar up to
|
|
237
|
+
* three items and one action. Absent, the item stays in the sidebar drawer only.
|
|
238
|
+
*/
|
|
239
|
+
tabBar?: TabBar.Variant | undefined
|
|
203
240
|
}
|
|
204
241
|
}
|
|
205
242
|
|
|
@@ -293,7 +330,8 @@ export namespace SidebarMenu {
|
|
|
293
330
|
{...attributes}
|
|
294
331
|
{...styles.item({ className, style: props.style, vars })}
|
|
295
332
|
>
|
|
296
|
-
{
|
|
333
|
+
{/* Text renders in a span, so the collapsed sidebar can hide it as an element. */}
|
|
334
|
+
{Text.wrap(children)}
|
|
297
335
|
<ChevronRight {...styles.chevron()} />
|
|
298
336
|
</BaseUi.Collapsible.Trigger>
|
|
299
337
|
)
|
|
@@ -330,6 +368,9 @@ namespace styles {
|
|
|
330
368
|
selectors: {
|
|
331
369
|
':hover > &, [data-popup-open] > &': { color: 'content.primary' },
|
|
332
370
|
},
|
|
371
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
372
|
+
selectors: { '[data-app-shell-rail] &': { display: 'none !custom' } },
|
|
373
|
+
},
|
|
333
374
|
},
|
|
334
375
|
{ id: 'tds/web/sidebar-menu/account-chevron' },
|
|
335
376
|
)
|
|
@@ -365,6 +406,15 @@ namespace styles {
|
|
|
365
406
|
export const accountRow = variants(
|
|
366
407
|
{
|
|
367
408
|
base: {
|
|
409
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
410
|
+
selectors: {
|
|
411
|
+
'[data-app-shell-rail] &': {
|
|
412
|
+
columnGap: '0',
|
|
413
|
+
justifyContent: 'center',
|
|
414
|
+
paddingInline: '0',
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
},
|
|
368
418
|
alignItems: 'center',
|
|
369
419
|
appearance: 'none !custom',
|
|
370
420
|
backgroundColor: 'transparent !custom',
|
|
@@ -398,8 +448,10 @@ namespace styles {
|
|
|
398
448
|
paddingInline: '10',
|
|
399
449
|
},
|
|
400
450
|
// Base UI triggers mark the row `data-popup-open` while their menu or popover is open.
|
|
401
|
-
'&:hover:not(:disabled, [data-disabled])
|
|
402
|
-
|
|
451
|
+
'&:hover:not(:disabled, [data-disabled])': { backgroundColor: 'container.regular' },
|
|
452
|
+
// An open row keeps the stronger fill while the pointer rests on it.
|
|
453
|
+
'&[data-popup-open]:not(:disabled, [data-disabled])': {
|
|
454
|
+
backgroundColor: 'container.strong',
|
|
403
455
|
},
|
|
404
456
|
'&:is(:disabled, [data-disabled])': { cursor: 'default', opacity: 'disabled' },
|
|
405
457
|
},
|
|
@@ -413,7 +465,24 @@ namespace styles {
|
|
|
413
465
|
)
|
|
414
466
|
|
|
415
467
|
export const accountText = style(
|
|
416
|
-
{
|
|
468
|
+
{
|
|
469
|
+
display: 'flex',
|
|
470
|
+
flex: '1 !custom',
|
|
471
|
+
flexDirection: 'column',
|
|
472
|
+
minWidth: '0',
|
|
473
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
474
|
+
selectors: {
|
|
475
|
+
'[data-app-shell-rail] &': {
|
|
476
|
+
clipPath: 'inset(50%) !custom',
|
|
477
|
+
height: '1px !custom',
|
|
478
|
+
overflow: 'hidden',
|
|
479
|
+
position: 'absolute',
|
|
480
|
+
whiteSpace: 'nowrap',
|
|
481
|
+
width: '1px !custom',
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
},
|
|
417
486
|
{ id: 'tds/web/sidebar-menu/account-text' },
|
|
418
487
|
)
|
|
419
488
|
|
|
@@ -457,6 +526,10 @@ namespace styles {
|
|
|
457
526
|
paddingInline: '8',
|
|
458
527
|
selectors: { '[data-sidebar-menu-size="large"] &': { paddingInline: '12' } },
|
|
459
528
|
typography: 'body.b3',
|
|
529
|
+
// The collapsed sidebar keeps the label for the name of its group without painting it.
|
|
530
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
531
|
+
selectors: { '[data-app-shell-rail] &': { display: 'none !custom' } },
|
|
532
|
+
},
|
|
460
533
|
},
|
|
461
534
|
},
|
|
462
535
|
{ id: 'tds/web/sidebar-menu/group-label' },
|
|
@@ -523,16 +596,39 @@ namespace styles {
|
|
|
523
596
|
transitionProperty: 'background-color, color, outline-color !custom',
|
|
524
597
|
selectors: { '&:active': { scale: 'none !custom' } },
|
|
525
598
|
},
|
|
599
|
+
// The collapsed sidebar centers the first element, such as the icon, in a 40px row. Its
|
|
600
|
+
// other elements and its text stay in the accessible name.
|
|
601
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
602
|
+
selectors: {
|
|
603
|
+
'[data-app-shell-rail] &': {
|
|
604
|
+
columnGap: '0',
|
|
605
|
+
justifyContent: 'center',
|
|
606
|
+
paddingInline: '0',
|
|
607
|
+
position: 'relative',
|
|
608
|
+
},
|
|
609
|
+
'[data-app-shell-rail] & > :not(:first-child)': {
|
|
610
|
+
clipPath: 'inset(50%) !custom',
|
|
611
|
+
height: '1px !custom',
|
|
612
|
+
overflow: 'hidden',
|
|
613
|
+
position: 'absolute',
|
|
614
|
+
whiteSpace: 'nowrap',
|
|
615
|
+
width: '1px !custom',
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
},
|
|
526
619
|
},
|
|
527
620
|
defaultVariants: { active: false },
|
|
528
621
|
variants: {
|
|
529
622
|
active: {
|
|
530
623
|
false: {},
|
|
531
624
|
true: {
|
|
532
|
-
backgroundColor: 'container.
|
|
625
|
+
backgroundColor: 'container.strong',
|
|
533
626
|
color: 'content.primary',
|
|
534
627
|
typography: 'body.b2Strong',
|
|
535
|
-
selectors: {
|
|
628
|
+
selectors: {
|
|
629
|
+
'&:hover': { backgroundColor: 'container.strong' },
|
|
630
|
+
'[data-sidebar-menu-size="large"] &': { typography: 'body.b1Strong' },
|
|
631
|
+
},
|
|
536
632
|
},
|
|
537
633
|
},
|
|
538
634
|
},
|
|
@@ -579,6 +675,9 @@ namespace styles {
|
|
|
579
675
|
'[data-sidebar-menu-size="large"] &': { paddingTop: '4', rowGap: '4' },
|
|
580
676
|
'[data-sidebar-menu-size="small"] &': { paddingInlineStart: '24' },
|
|
581
677
|
},
|
|
678
|
+
'@media (min-width: 768px) and (max-width: 1023px)': {
|
|
679
|
+
selectors: { '[data-app-shell-rail] &': { paddingInlineStart: '0' } },
|
|
680
|
+
},
|
|
582
681
|
},
|
|
583
682
|
{ id: 'tds/web/sidebar-menu/submenu-content' },
|
|
584
683
|
)
|