@tempoxyz/ds 0.3.7 → 0.3.10

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.
Files changed (129) hide show
  1. package/dist/web/components/Accordion.js.zyzz.json +1 -1
  2. package/dist/web/components/AddressCard.js.zyzz.json +1 -1
  3. package/dist/web/components/AgentLogo.js.zyzz.json +1 -1
  4. package/dist/web/components/Alert.js.zyzz.json +1 -1
  5. package/dist/web/components/AlertDialog.js.zyzz.json +1 -1
  6. package/dist/web/components/Amount.js.zyzz.json +1 -1
  7. package/dist/web/components/AmountInput.js.zyzz.json +1 -1
  8. package/dist/web/components/AppShell.css +1 -1
  9. package/dist/web/components/AppShell.d.ts +23 -104
  10. package/dist/web/components/AppShell.d.ts.map +1 -1
  11. package/dist/web/components/AppShell.js +38 -44
  12. package/dist/web/components/AppShell.js.map +1 -1
  13. package/dist/web/components/AppShell.js.zyzz.json +1 -1
  14. package/dist/web/components/AssetChip.js.zyzz.json +1 -1
  15. package/dist/web/components/Autocomplete.js.zyzz.json +1 -1
  16. package/dist/web/components/Avatar.js.zyzz.json +1 -1
  17. package/dist/web/components/Badge.js.zyzz.json +1 -1
  18. package/dist/web/components/BadgedLogo.js.zyzz.json +1 -1
  19. package/dist/web/components/Banner.js.zyzz.json +1 -1
  20. package/dist/web/components/BarChart.js.zyzz.json +1 -1
  21. package/dist/web/components/Breadcrumbs.js.zyzz.json +1 -1
  22. package/dist/web/components/Button.js.zyzz.json +1 -1
  23. package/dist/web/components/ButtonGroup.js.zyzz.json +1 -1
  24. package/dist/web/components/Calendar.js.zyzz.json +1 -1
  25. package/dist/web/components/Callout.js.zyzz.json +1 -1
  26. package/dist/web/components/Checkbox.js.zyzz.json +1 -1
  27. package/dist/web/components/CheckboxGroup.js.zyzz.json +1 -1
  28. package/dist/web/components/ChoiceGroup.js.zyzz.json +1 -1
  29. package/dist/web/components/Choicebox.js.zyzz.json +1 -1
  30. package/dist/web/components/Code.js.zyzz.json +1 -1
  31. package/dist/web/components/Combobox.js.zyzz.json +1 -1
  32. package/dist/web/components/Container.js.zyzz.json +1 -1
  33. package/dist/web/components/CopyButton.js.zyzz.json +1 -1
  34. package/dist/web/components/DatePicker.js.zyzz.json +1 -1
  35. package/dist/web/components/Dialog.js.zyzz.json +1 -1
  36. package/dist/web/components/Drawer.js.zyzz.json +1 -1
  37. package/dist/web/components/Empty.js.zyzz.json +1 -1
  38. package/dist/web/components/Field.js.zyzz.json +1 -1
  39. package/dist/web/components/Fieldset.js.zyzz.json +1 -1
  40. package/dist/web/components/Frame.js.zyzz.json +1 -1
  41. package/dist/web/components/Gauge.js.zyzz.json +1 -1
  42. package/dist/web/components/GetStartedVisual.js.zyzz.json +1 -1
  43. package/dist/web/components/Grid.js.zyzz.json +1 -1
  44. package/dist/web/components/HeroVisual.js.zyzz.json +1 -1
  45. package/dist/web/components/Hex.js.zyzz.json +1 -1
  46. package/dist/web/components/IconTile.js.zyzz.json +1 -1
  47. package/dist/web/components/Identicon.js.zyzz.json +1 -1
  48. package/dist/web/components/Inline.js.zyzz.json +1 -1
  49. package/dist/web/components/Inset.js.zyzz.json +1 -1
  50. package/dist/web/components/Kbd.js.zyzz.json +1 -1
  51. package/dist/web/components/ListGroup.js.zyzz.json +1 -1
  52. package/dist/web/components/LoadingDots.js.zyzz.json +1 -1
  53. package/dist/web/components/Menu.js.zyzz.json +1 -1
  54. package/dist/web/components/NativeSelect.js.zyzz.json +1 -1
  55. package/dist/web/components/NetworkLogo.js.zyzz.json +1 -1
  56. package/dist/web/components/NumberField.js.zyzz.json +1 -1
  57. package/dist/web/components/OtpField.css +1 -1
  58. package/dist/web/components/OtpField.d.ts +1 -1
  59. package/dist/web/components/OtpField.d.ts.map +1 -1
  60. package/dist/web/components/OtpField.js +3 -4
  61. package/dist/web/components/OtpField.js.map +1 -1
  62. package/dist/web/components/OtpField.js.zyzz.json +1 -1
  63. package/dist/web/components/Pagination.js.zyzz.json +1 -1
  64. package/dist/web/components/Popover.js.zyzz.json +1 -1
  65. package/dist/web/components/Progress.js.zyzz.json +1 -1
  66. package/dist/web/components/Qr.js.zyzz.json +1 -1
  67. package/dist/web/components/RadioGroup.js.zyzz.json +1 -1
  68. package/dist/web/components/SecretValue.js.zyzz.json +1 -1
  69. package/dist/web/components/Select.js.zyzz.json +1 -1
  70. package/dist/web/components/Separator.js.zyzz.json +1 -1
  71. package/dist/web/components/SidebarMenu.d.ts +3 -2
  72. package/dist/web/components/SidebarMenu.d.ts.map +1 -1
  73. package/dist/web/components/SidebarMenu.js +2 -1
  74. package/dist/web/components/SidebarMenu.js.map +1 -1
  75. package/dist/web/components/SidebarMenu.js.zyzz.json +1 -1
  76. package/dist/web/components/Skeleton.js.zyzz.json +1 -1
  77. package/dist/web/components/Slider.js.zyzz.json +1 -1
  78. package/dist/web/components/Snippet.js.zyzz.json +1 -1
  79. package/dist/web/components/Spinner.js.zyzz.json +1 -1
  80. package/dist/web/components/SplitBar.js.zyzz.json +1 -1
  81. package/dist/web/components/SplitButton.js.zyzz.json +1 -1
  82. package/dist/web/components/Stack.js.zyzz.json +1 -1
  83. package/dist/web/components/StatusChip.js.zyzz.json +1 -1
  84. package/dist/web/components/StatusIndicator.js.zyzz.json +1 -1
  85. package/dist/web/components/StatusRow.js.zyzz.json +1 -1
  86. package/dist/web/components/Stepper.js.zyzz.json +1 -1
  87. package/dist/web/components/SuccessHero.js.zyzz.json +1 -1
  88. package/dist/web/components/Surface.js.zyzz.json +1 -1
  89. package/dist/web/components/Switch.js.zyzz.json +1 -1
  90. package/dist/web/components/Table.js.zyzz.json +1 -1
  91. package/dist/web/components/Tabs.css +1 -1
  92. package/dist/web/components/Tabs.d.ts +9 -18
  93. package/dist/web/components/Tabs.d.ts.map +1 -1
  94. package/dist/web/components/Tabs.js.map +1 -1
  95. package/dist/web/components/Tabs.js.zyzz.json +1 -1
  96. package/dist/web/components/TempoLogo.js.zyzz.json +1 -1
  97. package/dist/web/components/TextInput.js.zyzz.json +1 -1
  98. package/dist/web/components/Textarea.js.zyzz.json +1 -1
  99. package/dist/web/components/Toast.css +1 -1
  100. package/dist/web/components/Toast.d.ts.map +1 -1
  101. package/dist/web/components/Toast.js +6 -7
  102. package/dist/web/components/Toast.js.map +1 -1
  103. package/dist/web/components/Toast.js.zyzz.json +1 -1
  104. package/dist/web/components/Token.js.zyzz.json +1 -1
  105. package/dist/web/components/TokenLogo.js.zyzz.json +1 -1
  106. package/dist/web/components/Tooltip.js.zyzz.json +1 -1
  107. package/dist/web/components/VerificationCode.js.zyzz.json +1 -1
  108. package/dist/web/components/Visual.js.zyzz.json +1 -1
  109. package/dist/web/components/internal/Field.js.zyzz.json +1 -1
  110. package/dist/web/components/internal/InputGroup.js.zyzz.json +1 -1
  111. package/dist/web/components/internal/Listbox.js.zyzz.json +1 -1
  112. package/dist/web/components/internal/Streaks.js.zyzz.json +1 -1
  113. package/dist/web/components/internal/TabBar.d.ts +1 -1
  114. package/dist/web/index.js.zyzz.json +1 -1
  115. package/dist/web/vars.d.ts +16 -0
  116. package/dist/web/vars.d.ts.map +1 -1
  117. package/dist/web/vars.js.map +1 -1
  118. package/dist/web/vars.js.zyzz.json +1 -1
  119. package/dist/web/zyzz.config.d.ts +80 -0
  120. package/dist/web/zyzz.config.d.ts.map +1 -1
  121. package/dist/web/zyzz.config.js.zyzz.json +1 -1
  122. package/package.json +1 -1
  123. package/src/web/components/AppShell.tsx +46 -116
  124. package/src/web/components/OtpField.tsx +2 -24
  125. package/src/web/components/SidebarMenu.tsx +3 -2
  126. package/src/web/components/Tabs.tsx +10 -20
  127. package/src/web/components/Toast.tsx +3 -4
  128. package/src/web/components/internal/TabBar.ts +1 -1
  129. package/src/web/vars.ts +18 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tempoxyz/ds",
3
3
  "type": "module",
4
- "version": "0.3.7",
4
+ "version": "0.3.10",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "DESIGN.md",
@@ -54,7 +54,7 @@ function useShell() {
54
54
  * Application frame with a sticky sidebar beside a content column. `align="center"` centers both
55
55
  * on wide viewports, with the sidebar fill to the start edge and the header bar to the end edge.
56
56
  * `align="start"` pins the sidebar left with content filling the rest.
57
- * Below 1024px the sidebar moves into a drawer that `AppShell.Trigger` opens from the right edge.
57
+ * Below 1024px the sidebar moves into a drawer that `AppShell.Trigger` opens from the bottom bar.
58
58
  *
59
59
  * - Name the `Sidebar` with `aria-label`. It labels the `aside` on wide viewports and the drawer
60
60
  * dialog below 1024px.
@@ -68,9 +68,9 @@ function useShell() {
68
68
  * <AppShell.Main>
69
69
  * <AppShell.Header>
70
70
  * <AppShell.Title>API Keys</AppShell.Title>
71
- * <AppShell.Trigger />
72
71
  * </AppShell.Header>
73
72
  * </AppShell.Main>
73
+ * <AppShell.Trigger />
74
74
  * </AppShell.Root>
75
75
  *
76
76
  * @see {@link https://base-ui.com/react/components/drawer | Base UI Drawer}
@@ -81,8 +81,8 @@ function useShell() {
81
81
  */
82
82
  export namespace AppShell {
83
83
  /**
84
- * Renders the transparent 56px page header at the top of `Main`, holding the title, actions and
85
- * the compact-viewport `Trigger`. It spans the full width of `Main`.
84
+ * Renders the transparent page header at the top of `Main`, holding the title and actions. It
85
+ * spans the full width of `Main` and is at least 76px tall, so a one-row header centers on the sidebar account row.
86
86
  */
87
87
  export function Header(props: Header.Props) {
88
88
  const { className, vars, ...attributes } = props
@@ -160,8 +160,9 @@ export namespace AppShell {
160
160
  }}
161
161
  >
162
162
  <TabBar.Context.Provider value={tabBar}>
163
- {children}
163
+ {/* The bar is fixed to the bottom, so leading the DOM puts its menu button early in the tab order. */}
164
164
  <BottomBar />
165
+ {children}
165
166
  </TabBar.Context.Provider>
166
167
  </div>
167
168
  </context.Provider>
@@ -174,7 +175,7 @@ export namespace AppShell {
174
175
  /**
175
176
  * Collapses the inline sidebar to a 64px column of icons from 768px to 1023px, and opens
176
177
  * the drawer only below 768px. Give every `SidebarMenu.Item` an icon as its first child.
177
- * Absent, the sidebar opens as a drawer below 1024px.
178
+ * Absent, the sidebar opens as a drawer below 1024px, and the bottom bar shows there too.
178
179
  * @default false
179
180
  */
180
181
  collapse?: boolean | undefined
@@ -293,32 +294,26 @@ export namespace AppShell {
293
294
  }
294
295
 
295
296
  /**
296
- * Toggles the sidebar drawer from a button fixed to the top-right corner, above the drawer, whose
297
- * two bars turn into a close mark while it is open. Hidden from 1024px, where the sidebar is
298
- * always visible. It is named `Open menu` or `Close menu` and exposes `aria-expanded`. Pass
299
- * `aria-label` to replace the name, or `children` to replace the bars. With `tabBar`, the bottom
300
- * bar renders it as its floating action button below 768px instead of the top-right button.
297
+ * Adds the button that toggles the sidebar drawer to the bottom bar, after the `action` items,
298
+ * wherever the drawer replaces the sidebar. Its two bars turn into a close mark while the drawer
299
+ * is open, and the other items of the bar fade out. It is named `Open menu` or `Close menu` and
300
+ * exposes `aria-expanded`. Pass `aria-label` to replace the name, or `children` to replace the bars.
301
301
  *
302
302
  * @example
303
- * <AppShell.Trigger tabBar />
303
+ * <AppShell.Trigger />
304
304
  */
305
305
  export function Trigger(props: Trigger.Props) {
306
- const { children, className, ref, tabBar = false, vars, ...attributes } = props
307
- const shell = useShell()
306
+ const { children, ref, ...attributes } = props
308
307
  const store = use(TabBar.Context)
309
308
  const id = useId()
310
- // The bottom bar shows below 768px, so the ref follows whichever of the two buttons shows.
311
- const bar = useQuery('(max-width: 767px)') && tabBar
309
+ // Throws outside `Root`, like every other part, though the bottom bar renders the button.
310
+ useShell()
312
311
 
313
312
  // Registers on every render, so the bottom bar repeats the current props of the trigger.
314
313
  useLayoutEffect(() => {
315
- if (!store) return
316
- if (!tabBar) return store.delete(id)
317
-
318
- const { style: _, ...rest } = attributes
319
- store.set(id, {
314
+ store?.set(id, {
320
315
  active: false,
321
- attributes: { ...rest, ref: bar ? ref : undefined },
316
+ attributes: { ...attributes, ref },
322
317
  children,
323
318
  variant: 'menu',
324
319
  })
@@ -329,31 +324,12 @@ export namespace AppShell {
329
324
  return () => store.delete(id)
330
325
  }, [id, store])
331
326
 
332
- return (
333
- <BaseUi.Drawer.Trigger
334
- aria-label={shell.open ? 'Close menu' : 'Open menu'}
335
- {...attributes}
336
- {...styles.trigger({ className, style: props.style, vars })}
337
- data-app-shell-tab-bar={tabBar ? '' : undefined}
338
- handle={shell.handle}
339
- ref={bar ? undefined : ref}
340
- >
341
- {children ?? <Bars />}
342
- </BaseUi.Drawer.Trigger>
343
- )
327
+ return null
344
328
  }
345
329
 
346
330
  export namespace Trigger {
347
331
  export type Props = ComponentPropsWithRef<'button'> &
348
- zyzz.Props.Variants<typeof styles.trigger> &
349
- Pick<BaseUi.Drawer.Trigger.Props, 'nativeButton' | 'render'> & {
350
- /**
351
- * Renders the trigger as the floating action button of the bottom bar below 768px, after
352
- * the `action` items, in place of the top-right button. While the drawer is open, the
353
- * button stays above it as a close mark, and the other items of the bar fade out.
354
- */
355
- tabBar?: boolean | undefined
356
- }
332
+ Pick<BaseUi.Drawer.Trigger.Props, 'nativeButton' | 'render'>
357
333
  }
358
334
  }
359
335
 
@@ -368,9 +344,10 @@ function Bars() {
368
344
  }
369
345
 
370
346
  /**
371
- * Repeats the `SidebarMenu.Item`s that set `tabBar` in a bar fixed to the bottom edge below 768px:
347
+ * Repeats the `SidebarMenu.Item`s that set `tabBar` in a bar fixed to the bottom edge wherever the
348
+ * drawer replaces the sidebar, below 1024px or below 768px with `collapse`:
372
349
  * `tab` items as icons in a pill `<nav>`, then each `action` item as a floating action button, then
373
- * the `AppShell.Trigger` that sets `tabBar`. Renders nothing while nothing registers.
350
+ * the `AppShell.Trigger`. Renders nothing while nothing registers.
374
351
  */
375
352
  function BottomBar() {
376
353
  const store = use(TabBar.Context)!
@@ -423,16 +400,17 @@ function BottomBarItem(props: { entry: TabBar.Entry }) {
423
400
  })
424
401
  }
425
402
 
426
- /** Renders the `AppShell.Trigger` that sets `tabBar` as a floating action button. */
403
+ /** Renders the `AppShell.Trigger` as a floating action button. */
427
404
  function BottomBarTrigger(props: { entry: TabBar.Entry }) {
428
405
  const { entry } = props
406
+ const { className, style, ...attributes } = entry.attributes as AppShell.Trigger.Props
429
407
  const shell = useShell()
430
408
 
431
409
  return (
432
410
  <BaseUi.Drawer.Trigger
433
411
  aria-label={shell.open ? 'Close menu' : 'Open menu'}
434
- {...(entry.attributes as BaseUi.Drawer.Trigger.Props)}
435
- {...styles.action()}
412
+ {...(attributes as BaseUi.Drawer.Trigger.Props)}
413
+ {...styles.action({ className, style })}
436
414
  data-app-shell-menu-trigger=""
437
415
  handle={shell.handle}
438
416
  >
@@ -557,9 +535,13 @@ namespace styles {
557
535
  columnGap: '12',
558
536
  display: 'none',
559
537
  insetInline: '24',
538
+ // Without tabs the buttons end at the right edge, and the empty bar lets clicks reach the page.
539
+ justifyContent: 'flex-end',
540
+ pointerEvents: 'none',
560
541
  position: 'fixed',
561
542
  zIndex: '39 !custom',
562
543
  selectors: {
544
+ '& > *': { pointerEvents: 'auto' },
563
545
  // A bar that holds the trigger rises above the open drawer, so the trigger closes it. The
564
546
  // other items fade out and leave the drawer uncovered.
565
547
  '[data-state="open"] > &[data-app-shell-menu]': { zIndex: 'modal' },
@@ -569,6 +551,10 @@ namespace styles {
569
551
  },
570
552
  },
571
553
  '@media (max-width: 767px)': { display: 'flex' },
554
+ // A sidebar that does not collapse opens as the drawer up to 1023px, so its bar shows too.
555
+ '@media (min-width: 768px) and (max-width: 1023px)': {
556
+ selectors: { ':not([data-app-shell-collapse]) > &': { display: 'flex' } },
557
+ },
572
558
  },
573
559
  { id: 'tds/web/app-shell/bottom-bar' },
574
560
  )
@@ -632,17 +618,14 @@ namespace styles {
632
618
  marginBottom: '24',
633
619
  marginInline: '-16',
634
620
  marginTop: '-20',
635
- minHeight: '56',
621
+ // A 44px row under the sidebar header's 20px inset, so a one-row header centers on the account row.
622
+ minHeight: '4.75rem !custom',
636
623
  minWidth: '0',
624
+ paddingBottom: '12',
625
+ paddingTop: '20',
637
626
  paddingInline: '16',
638
627
  // The title starts on the 28px edge of the content below it, as the Page Header pads it.
639
628
  '@media (min-width: 640px)': { marginInline: '-1.75rem !custom', paddingInline: '28' },
640
- // Below 1024px the fixed trigger covers the end of the bar, so header actions end 8px
641
- // before it: its 40px plus its 16px inset. A collapsed sidebar hides it from 768px.
642
- '@media (max-width: 1023px)': { paddingInlineEnd: '64' },
643
- '@media (min-width: 768px) and (max-width: 1023px)': {
644
- selectors: { '[data-app-shell-collapse] > main > &': { paddingInlineEnd: '24' } },
645
- },
646
629
  },
647
630
  },
648
631
  { id: 'tds/web/app-shell/header' },
@@ -693,6 +676,13 @@ namespace styles {
693
676
  },
694
677
  },
695
678
  },
679
+ '@media (min-width: 768px) and (max-width: 1023px)': {
680
+ selectors: {
681
+ '&:not([data-app-shell-collapse]):has(> [data-app-shell-bottom-bar]) > main': {
682
+ paddingBottom: 'calc(5.5rem + env(safe-area-inset-bottom)) !custom',
683
+ },
684
+ },
685
+ },
696
686
  },
697
687
  defaultVariants: { align: 'center' },
698
688
  variants: {
@@ -854,7 +844,7 @@ namespace styles {
854
844
  )
855
845
 
856
846
  export const sidebarHeader = variants(
857
- { base: { flexShrink: '0 !custom', paddingTop: '32' } },
847
+ { base: { flexShrink: '0 !custom', paddingTop: '20' } },
858
848
  { id: 'tds/web/app-shell/sidebar-header' },
859
849
  )
860
850
 
@@ -954,66 +944,6 @@ namespace styles {
954
944
  { id: 'tds/web/app-shell/title' },
955
945
  )
956
946
 
957
- export const trigger = variants(
958
- {
959
- base: {
960
- alignItems: 'center',
961
- backgroundColor: 'background.elevated',
962
- borderColor: 'line.secondary',
963
- borderRadius: 'full',
964
- borderStyle: 'solid',
965
- borderWidth: 'regular',
966
- boxSizing: 'border-box',
967
- color: 'content.primary',
968
- cornerShape: 'round',
969
- cursor: 'pointer',
970
- display: 'inline-flex',
971
- height: '40',
972
- // Centers the button on the 56px header bar.
973
- insetBlockStart: '8',
974
- insetInlineEnd: '16',
975
- justifyContent: 'center',
976
- outlineColor: 'transparent !custom',
977
- outlineOffset: '0',
978
- outlineStyle: 'solid !custom',
979
- outlineWidth: '2',
980
- padding: '0',
981
- // Fixed above the drawer and its backdrop, so the same button closes what it opened.
982
- position: 'fixed',
983
- transitionDuration: '160',
984
- transitionProperty: 'background-color, outline-color, outline-offset, transform !custom',
985
- transitionTimingFunction: 'snappy',
986
- width: '40',
987
- zIndex: 'modal',
988
- selectors: {
989
- '&:active': { transform: 'scale(0.96) !custom' },
990
- '&:focus-visible': { outlineColor: 'border.focus', outlineOffset: '2' },
991
- '&:hover': { backgroundColor: 'container.regular' },
992
- // While open, the button rides out with the drawer and rests 8px outside its left edge,
993
- // so the close mark never covers the sidebar. The width matches the drawer's.
994
- '&[data-popup-open]': {
995
- transform: 'translateX(calc(8px - min(18rem, 85vw))) !custom',
996
- transitionDuration: '280',
997
- transitionTimingFunction: 'spring',
998
- },
999
- },
1000
- '@media (min-width: 1024px)': { display: 'none !custom' },
1001
- '@media (min-width: 768px) and (max-width: 1023px)': {
1002
- selectors: { '[data-app-shell-collapse] &': { display: 'none !custom' } },
1003
- },
1004
- // The bottom bar renders this trigger as its floating action button.
1005
- '@media (max-width: 767px)': {
1006
- selectors: { '&[data-app-shell-tab-bar]': { display: 'none !custom' } },
1007
- },
1008
- '@media (prefers-reduced-motion: reduce)': {
1009
- transitionProperty: 'background-color, outline-color, outline-offset !custom',
1010
- selectors: { '&:active': { transform: 'none !custom' } },
1011
- },
1012
- },
1013
- },
1014
- { id: 'tds/web/app-shell/trigger' },
1015
- )
1016
-
1017
947
  export const viewport = style(
1018
948
  {
1019
949
  display: 'flex',
@@ -9,7 +9,7 @@ const InvalidContext = createContext(false)
9
9
  /**
10
10
  * One-time passcode entry with a slot per character. Slots render by default from `length`.
11
11
  * Setting `invalid` fills the slots red and nudges them sideways. Setting `success` fills them
12
- * green and pops them in sequence.
12
+ * green.
13
13
  *
14
14
  * Base UI renders a `role="group"` of text inputs that accepts digits by default. Pasting a code
15
15
  * into a slot fills it and the slots after it. The first slot carries
@@ -124,14 +124,6 @@ const nudge = keyframes(
124
124
  { id: 'tds/web/otp-field/nudge' },
125
125
  )
126
126
 
127
- const pop = keyframes(
128
- {
129
- '0%, 100%': { transform: 'scale(1) !custom' },
130
- '45%': { transform: 'scale(1.12) !custom' },
131
- },
132
- { id: 'tds/web/otp-field/pop' },
133
- )
134
-
135
127
  namespace styles {
136
128
  export const input = style(
137
129
  {
@@ -158,21 +150,7 @@ namespace styles {
158
150
  '&:focus-visible': { backgroundColor: 'background.elevated', outlineColor: 'border.focus' },
159
151
  // Invalid and success fills follow focus, so a focused slot keeps its state fill.
160
152
  '&[data-invalid], [data-invalid] &': { backgroundColor: 'container.negative' },
161
- '[data-success] &': {
162
- animation: `${pop} 320ms ${vars.ease.overshoot} both !custom`,
163
- backgroundColor: 'container.positive',
164
- },
165
- // Delays follow the `animation` shorthand above, which would otherwise reset them.
166
- '[data-success] &:nth-child(2)': { animationDelay: '40ms !custom' },
167
- '[data-success] &:nth-child(3)': { animationDelay: '80ms !custom' },
168
- '[data-success] &:nth-child(4)': { animationDelay: '120ms !custom' },
169
- '[data-success] &:nth-child(5)': { animationDelay: '160ms !custom' },
170
- '[data-success] &:nth-child(6)': { animationDelay: '200ms !custom' },
171
- '[data-success] &:nth-child(7)': { animationDelay: '240ms !custom' },
172
- '[data-success] &:nth-child(8)': { animationDelay: '280ms !custom' },
173
- },
174
- '@media (prefers-reduced-motion: reduce)': {
175
- selectors: { '[data-success] &': { animation: 'none !custom' } },
153
+ '[data-success] &': { backgroundColor: 'container.positive' },
176
154
  },
177
155
  },
178
156
  { id: 'tds/web/otp-field/input' },
@@ -185,7 +185,8 @@ export namespace SidebarMenu {
185
185
  * with `aria-current="page"`, and sets its label in the strong weight. Keyboard focus draws a
186
186
  * 2px ring inside the row and moves its content 2px inward.
187
187
  *
188
- * Inside an `AppShell`, `tabBar` repeats the item in the bottom bar below 768px, with the same
188
+ * Inside an `AppShell`, `tabBar` repeats the item in the bottom bar wherever the drawer replaces
189
+ * the sidebar (below 1024px, or below 768px with `collapse`), with the same
189
190
  * `href`, `render` and handlers. In an `AppShell` with `collapse`, the sidebar shows only the
190
191
  * first element of each item from 768px to 1023px, such as its icon, and keeps its text as the
191
192
  * accessible name.
@@ -234,7 +235,7 @@ export namespace SidebarMenu {
234
235
  Omit<zyzz.Props.Variants<typeof styles.item>, 'active'> & {
235
236
  active?: boolean | undefined
236
237
  /**
237
- * Repeats the item in the bottom bar of an `AppShell` below 768px: `tab` as an icon in the
238
+ * Repeats the item in the bottom bar of an `AppShell` wherever the drawer replaces the sidebar: `tab` as an icon in the
238
239
  * tab bar, or `action` as the floating action button beside it. Give the tab bar up to
239
240
  * three items and one action. Absent, the item stays in the sidebar drawer only.
240
241
  */
@@ -212,8 +212,7 @@ namespace styles {
212
212
  position: 'relative',
213
213
  },
214
214
  // The pill sizes follow the Platform Tab: 48, 40 and 32px, padded by 32, 24 and 16px, with
215
- // a label in Pilat at the size and weight of B2 Strong, or of B3 Strong for small. Each
216
- // family follows its typography set, which sets the family of the body.
215
+ // an L2 label, or an L3 label for small.
217
216
  compoundVariants: [
218
217
  {
219
218
  when: { size: 'large', variant: 'pill' },
@@ -222,16 +221,13 @@ namespace styles {
222
221
  '& > [role="tab"]': {
223
222
  height: '48',
224
223
  paddingInline: '32',
225
- typography: 'body.b2Strong',
226
- fontFamily: 'heading',
224
+ typography: 'label.l2',
227
225
  },
228
226
  '& > [role="tab"]:is([data-active], [data-active]:hover)': {
229
- typography: 'body.b2Strong',
230
- fontFamily: 'heading',
227
+ typography: 'label.l2',
231
228
  },
232
229
  '& > [role="tab"] [data-reserve]': {
233
- typography: 'body.b2Strong',
234
- fontFamily: 'heading',
230
+ typography: 'label.l2',
235
231
  },
236
232
  },
237
233
  },
@@ -246,16 +242,13 @@ namespace styles {
246
242
  selectors: {
247
243
  '& > [role="tab"]': {
248
244
  paddingInline: '16',
249
- typography: 'body.b3Strong',
250
- fontFamily: 'heading',
245
+ typography: 'label.l3',
251
246
  },
252
247
  '& > [role="tab"]:is([data-active], [data-active]:hover)': {
253
- typography: 'body.b3Strong',
254
- fontFamily: 'heading',
248
+ typography: 'label.l3',
255
249
  },
256
250
  '& > [role="tab"] [data-reserve]': {
257
- typography: 'body.b3Strong',
258
- fontFamily: 'heading',
251
+ typography: 'label.l3',
259
252
  },
260
253
  },
261
254
  },
@@ -366,16 +359,13 @@ namespace styles {
366
359
  minWidth: '5rem !custom',
367
360
  outlineOffset: '2',
368
361
  transitionProperty: 'background-color, color, outline-color, scale',
369
- typography: 'body.b2Strong',
370
- fontFamily: 'heading',
362
+ typography: 'label.l2',
371
363
  },
372
364
  '& > [role="tab"]:is([data-active], [data-active]:hover)': {
373
- typography: 'body.b2Strong',
374
- fontFamily: 'heading',
365
+ typography: 'label.l2',
375
366
  },
376
367
  '& > [role="tab"] [data-reserve]': {
377
- typography: 'body.b2Strong',
378
- fontFamily: 'heading',
368
+ typography: 'label.l2',
379
369
  },
380
370
  // The fill marks the active tab, so the list hides the underline indicator.
381
371
  '& > span:not([role="tab"])': { display: 'none' },
@@ -284,10 +284,9 @@ namespace styles {
284
284
  { id: 'tds/web/toast/content' },
285
285
  )
286
286
 
287
- // The title and description set Pilat at the size of their typography set, so the family
288
- // follows the set, which sets the family of the body.
287
+ // The title and description set their Pilat labels through the label typography sets.
289
288
  export const description = style(
290
- { color: 'content.secondary', margin: '0', typography: 'body.b3Strong', fontFamily: 'heading' },
289
+ { color: 'content.secondary', margin: '0', typography: 'label.l3' },
291
290
  { id: 'tds/web/toast/description' },
292
291
  )
293
292
 
@@ -380,7 +379,7 @@ namespace styles {
380
379
  )
381
380
 
382
381
  export const title = style(
383
- { color: 'content.primary', margin: '0', typography: 'body.b2Strong', fontFamily: 'heading' },
382
+ { color: 'content.primary', margin: '0', typography: 'label.l2' },
384
383
  { id: 'tds/web/toast/title' },
385
384
  )
386
385
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Holds the `SidebarMenu.Item` entries that `AppShell` repeats in its bottom bar below 768px. The
2
+ * Holds the `SidebarMenu.Item` entries that `AppShell` repeats in its bottom bar. The
3
3
  * store lives outside React state, so an item that registers on every render updates the bar
4
4
  * without rendering the shell again.
5
5
  * @module
package/src/web/vars.ts CHANGED
@@ -683,6 +683,24 @@ export const variables = Vars.define(
683
683
  lineHeight: '20.7px',
684
684
  },
685
685
  },
686
+ // Labels set Pilat at the size and weight of B2 Strong and B3 Strong, tracked by 1% as the
687
+ // Platform Tab and Toast draw them.
688
+ label: {
689
+ l2: {
690
+ fontFamily: vars.fontFamily.heading,
691
+ fontSize: '14px',
692
+ fontWeight: 500,
693
+ letterSpacing: '.14px',
694
+ lineHeight: '20px',
695
+ },
696
+ l3: {
697
+ fontFamily: vars.fontFamily.heading,
698
+ fontSize: '12px',
699
+ fontWeight: 500,
700
+ letterSpacing: '.15px',
701
+ lineHeight: '16px',
702
+ },
703
+ },
686
704
  mono: {
687
705
  m1: {
688
706
  fontFamily: vars.fontFamily.mono,