@m3-baseui/react-tailwind 1.3.0 → 2.0.0

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 (175) hide show
  1. package/dist/{badge.js → components/badge/index.js} +4 -4
  2. package/dist/components/badge/index.js.map +1 -0
  3. package/dist/{bottom-app-bar.d.ts → components/bottom-app-bar/index.d.ts} +22 -21
  4. package/dist/{bottom-app-bar.js → components/bottom-app-bar/index.js} +4 -4
  5. package/dist/components/bottom-app-bar/index.js.map +1 -0
  6. package/dist/{bottom-sheet.d.ts → components/bottom-sheet/index.d.ts} +37 -36
  7. package/dist/{bottom-sheet.js → components/bottom-sheet/index.js} +4 -4
  8. package/dist/components/bottom-sheet/index.js.map +1 -0
  9. package/dist/{button.js → components/button/index.js} +3 -3
  10. package/dist/components/button/index.js.map +1 -0
  11. package/dist/{button-group.js → components/button-group/index.js} +4 -4
  12. package/dist/components/button-group/index.js.map +1 -0
  13. package/dist/{card.js → components/card/index.js} +4 -4
  14. package/dist/components/card/index.js.map +1 -0
  15. package/dist/{carousel.js → components/carousel/index.js} +4 -4
  16. package/dist/components/carousel/index.js.map +1 -0
  17. package/dist/{checkbox.d.ts → components/checkbox/index.d.ts} +22 -21
  18. package/dist/{checkbox.js → components/checkbox/index.js} +3 -3
  19. package/dist/components/checkbox/index.js.map +1 -0
  20. package/dist/{chip.js → components/chip/index.js} +3 -3
  21. package/dist/components/chip/index.js.map +1 -0
  22. package/dist/components/date-picker/index.d.ts +189 -0
  23. package/dist/{date-picker.js → components/date-picker/index.js} +4 -4
  24. package/dist/components/date-picker/index.js.map +1 -0
  25. package/dist/components/dialog/index.d.ts +116 -0
  26. package/dist/components/dialog/index.js +103 -0
  27. package/dist/components/dialog/index.js.map +1 -0
  28. package/dist/{divider.js → components/divider/index.js} +3 -3
  29. package/dist/components/divider/index.js.map +1 -0
  30. package/dist/{fab.d.ts → components/fab/index.d.ts} +29 -15
  31. package/dist/components/fab/index.js +79 -0
  32. package/dist/components/fab/index.js.map +1 -0
  33. package/dist/{fab-menu.d.ts → components/fab-menu/index.d.ts} +0 -21
  34. package/dist/{fab-menu.js → components/fab-menu/index.js} +49 -18
  35. package/dist/components/fab-menu/index.js.map +1 -0
  36. package/dist/{icon-button.js → components/icon-button/index.js} +3 -3
  37. package/dist/components/icon-button/index.js.map +1 -0
  38. package/dist/components/item/index.d.ts +95 -0
  39. package/dist/{item.js → components/item/index.js} +12 -6
  40. package/dist/components/item/index.js.map +1 -0
  41. package/dist/{list.d.ts → components/list/index.d.ts} +4 -4
  42. package/dist/{list.js → components/list/index.js} +12 -6
  43. package/dist/components/list/index.js.map +1 -0
  44. package/dist/{loading-indicator.js → components/loading-indicator/index.js} +4 -4
  45. package/dist/components/loading-indicator/index.js.map +1 -0
  46. package/dist/{menu.d.ts → components/menu/index.d.ts} +61 -60
  47. package/dist/components/menu/index.js +179 -0
  48. package/dist/components/menu/index.js.map +1 -0
  49. package/dist/components/navigation-bar/index.d.ts +92 -0
  50. package/dist/{navigation-bar.js → components/navigation-bar/index.js} +3 -3
  51. package/dist/components/navigation-bar/index.js.map +1 -0
  52. package/dist/{navigation-drawer.js → components/navigation-drawer/index.js} +4 -4
  53. package/dist/components/navigation-drawer/index.js.map +1 -0
  54. package/dist/components/navigation-rail/index.d.ts +102 -0
  55. package/dist/{navigation-rail.js → components/navigation-rail/index.js} +4 -4
  56. package/dist/components/navigation-rail/index.js.map +1 -0
  57. package/dist/components/progress/index.d.ts +127 -0
  58. package/dist/components/progress/index.js +101 -0
  59. package/dist/components/progress/index.js.map +1 -0
  60. package/dist/{radio.d.ts → components/radio/index.d.ts} +17 -16
  61. package/dist/{radio.js → components/radio/index.js} +3 -3
  62. package/dist/components/radio/index.js.map +1 -0
  63. package/dist/{search.d.ts → components/search/index.d.ts} +62 -61
  64. package/dist/{search.js → components/search/index.js} +4 -4
  65. package/dist/components/search/index.js.map +1 -0
  66. package/dist/{segmented-button.d.ts → components/segmented-button/index.d.ts} +32 -31
  67. package/dist/{segmented-button.js → components/segmented-button/index.js} +4 -4
  68. package/dist/components/segmented-button/index.js.map +1 -0
  69. package/dist/components/select/index.d.ts +253 -0
  70. package/dist/components/select/index.js +271 -0
  71. package/dist/components/select/index.js.map +1 -0
  72. package/dist/{side-sheet.js → components/side-sheet/index.js} +4 -4
  73. package/dist/components/side-sheet/index.js.map +1 -0
  74. package/dist/{slider.d.ts → components/slider/index.d.ts} +52 -51
  75. package/dist/{slider.js → components/slider/index.js} +4 -4
  76. package/dist/components/slider/index.js.map +1 -0
  77. package/dist/{snackbar.d.ts → components/snackbar/index.d.ts} +42 -41
  78. package/dist/{snackbar.js → components/snackbar/index.js} +9 -4
  79. package/dist/components/snackbar/index.js.map +1 -0
  80. package/dist/{split-button.js → components/split-button/index.js} +4 -4
  81. package/dist/components/split-button/index.js.map +1 -0
  82. package/dist/components/switch/index.d.ts +73 -0
  83. package/dist/{switch.js → components/switch/index.js} +3 -3
  84. package/dist/components/switch/index.js.map +1 -0
  85. package/dist/{tabs.js → components/tabs/index.js} +4 -4
  86. package/dist/components/tabs/index.js.map +1 -0
  87. package/dist/{textfield.d.ts → components/textfield/index.d.ts} +7 -1
  88. package/dist/{textfield.js → components/textfield/index.js} +35 -13
  89. package/dist/components/textfield/index.js.map +1 -0
  90. package/dist/components/time-picker/index.d.ts +153 -0
  91. package/dist/{time-picker.js → components/time-picker/index.js} +28 -13
  92. package/dist/components/time-picker/index.js.map +1 -0
  93. package/dist/{toolbar.js → components/toolbar/index.js} +4 -4
  94. package/dist/components/toolbar/index.js.map +1 -0
  95. package/dist/components/tooltip/index.d.ts +143 -0
  96. package/dist/components/tooltip/index.js +80 -0
  97. package/dist/components/tooltip/index.js.map +1 -0
  98. package/dist/{top-app-bar.js → components/top-app-bar/index.js} +4 -4
  99. package/dist/components/top-app-bar/index.js.map +1 -0
  100. package/dist/index.d.ts +40 -39
  101. package/dist/index.js +489 -129
  102. package/dist/index.js.map +1 -1
  103. package/package.json +151 -151
  104. package/styles/preset.css +75 -7
  105. package/styles/theme.css +2 -0
  106. package/styles/tokens.css +2 -0
  107. package/dist/badge.js.map +0 -1
  108. package/dist/bottom-app-bar.js.map +0 -1
  109. package/dist/bottom-sheet.js.map +0 -1
  110. package/dist/button-group.js.map +0 -1
  111. package/dist/button.js.map +0 -1
  112. package/dist/card.js.map +0 -1
  113. package/dist/carousel.js.map +0 -1
  114. package/dist/checkbox.js.map +0 -1
  115. package/dist/chip.js.map +0 -1
  116. package/dist/date-picker.d.ts +0 -188
  117. package/dist/date-picker.js.map +0 -1
  118. package/dist/dialog.d.ts +0 -86
  119. package/dist/dialog.js +0 -68
  120. package/dist/dialog.js.map +0 -1
  121. package/dist/divider.js.map +0 -1
  122. package/dist/fab-menu.js.map +0 -1
  123. package/dist/fab.js +0 -47
  124. package/dist/fab.js.map +0 -1
  125. package/dist/icon-button.js.map +0 -1
  126. package/dist/item.d.ts +0 -94
  127. package/dist/item.js.map +0 -1
  128. package/dist/list.js.map +0 -1
  129. package/dist/loading-indicator.js.map +0 -1
  130. package/dist/menu.js +0 -114
  131. package/dist/menu.js.map +0 -1
  132. package/dist/navigation-bar.d.ts +0 -91
  133. package/dist/navigation-bar.js.map +0 -1
  134. package/dist/navigation-drawer.js.map +0 -1
  135. package/dist/navigation-rail.d.ts +0 -101
  136. package/dist/navigation-rail.js.map +0 -1
  137. package/dist/progress.d.ts +0 -118
  138. package/dist/progress.js +0 -41
  139. package/dist/progress.js.map +0 -1
  140. package/dist/radio.js.map +0 -1
  141. package/dist/search.js.map +0 -1
  142. package/dist/segmented-button.js.map +0 -1
  143. package/dist/select.d.ts +0 -125
  144. package/dist/select.js +0 -99
  145. package/dist/select.js.map +0 -1
  146. package/dist/side-sheet.js.map +0 -1
  147. package/dist/slider.js.map +0 -1
  148. package/dist/snackbar.js.map +0 -1
  149. package/dist/split-button.js.map +0 -1
  150. package/dist/switch.d.ts +0 -72
  151. package/dist/switch.js.map +0 -1
  152. package/dist/tabs.js.map +0 -1
  153. package/dist/textfield.js.map +0 -1
  154. package/dist/time-picker.d.ts +0 -144
  155. package/dist/time-picker.js.map +0 -1
  156. package/dist/toolbar.js.map +0 -1
  157. package/dist/tooltip.d.ts +0 -61
  158. package/dist/tooltip.js +0 -52
  159. package/dist/tooltip.js.map +0 -1
  160. package/dist/top-app-bar.js.map +0 -1
  161. /package/dist/{badge.d.ts → components/badge/index.d.ts} +0 -0
  162. /package/dist/{button.d.ts → components/button/index.d.ts} +0 -0
  163. /package/dist/{button-group.d.ts → components/button-group/index.d.ts} +0 -0
  164. /package/dist/{card.d.ts → components/card/index.d.ts} +0 -0
  165. /package/dist/{carousel.d.ts → components/carousel/index.d.ts} +0 -0
  166. /package/dist/{chip.d.ts → components/chip/index.d.ts} +0 -0
  167. /package/dist/{divider.d.ts → components/divider/index.d.ts} +0 -0
  168. /package/dist/{icon-button.d.ts → components/icon-button/index.d.ts} +0 -0
  169. /package/dist/{loading-indicator.d.ts → components/loading-indicator/index.d.ts} +0 -0
  170. /package/dist/{navigation-drawer.d.ts → components/navigation-drawer/index.d.ts} +0 -0
  171. /package/dist/{side-sheet.d.ts → components/side-sheet/index.d.ts} +0 -0
  172. /package/dist/{split-button.d.ts → components/split-button/index.d.ts} +0 -0
  173. /package/dist/{tabs.d.ts → components/tabs/index.d.ts} +0 -0
  174. /package/dist/{toolbar.d.ts → components/toolbar/index.d.ts} +0 -0
  175. /package/dist/{top-app-bar.d.ts → components/top-app-bar/index.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { createButton, createIconButton, createSwitch, createCheckbox, createRadio, createRadioGroup, createChip, createTooltip, createDialog, createMenu, createTabs, createSlider, createSelect, createTextField, createNavigationBar, createFab, createFabMenu, createDivider, createProgress, createLoadingIndicator, createList, createSnackbar, createItem, createBadge, createCard, createSegmentedButton, createButtonGroup, createSplitButton, createNavigationDrawer, createTopAppBar, createBottomAppBar, createNavigationRail, createBottomSheet, createSideSheet, createSearch, createDatePicker, createTimePicker, createToolbar, createCarousel } from '@m3-baseui/core';
3
- export { Ripple, ThemeProvider, applyScheme, generateScheme, schemeToCssText, useSnackbar, useTheme } from '@m3-baseui/core';
2
+ import { createButton, createIconButton, createSwitch, createCheckbox, createRadio, createRadioGroup, createChip, createTooltip, createRichTooltip, createDialog, createMenu, createTabs, createSlider, createSelect, createTextField, createNavigationBar, createFab, createFabMenu, createDivider, createProgress, createLoadingIndicator, createList, createSnackbar, createItem, createBadge, createCard, createSegmentedButton, createButtonGroup, createSplitButton, createNavigationDrawer, createTopAppBar, createBottomAppBar, createNavigationRail, createBottomSheet, createSideSheet, createSearch, createDatePicker, createTimePicker, createToolbar, createCarousel } from '@m3-baseui/core';
3
+ export { ITEM_LEADING_VARIANTS, LIST_LEADING_VARIANTS, Ripple, ThemeProvider, applyScheme, generateScheme, schemeToCssText, useSnackbar, useTheme } from '@m3-baseui/core';
4
4
  import { tv } from 'tailwind-variants';
5
5
 
6
- // src/button.ts
6
+ // src/components/button/button.ts
7
7
  var button = tv({
8
8
  base: [
9
9
  "relative inline-flex items-center justify-center gap-2",
@@ -465,21 +465,49 @@ var tv7 = (options, config) => tv(options, {
465
465
  }
466
466
  });
467
467
 
468
- // src/tooltip.ts
468
+ // src/components/tooltip/tooltip.ts
469
+ var transition = [
470
+ "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
471
+ "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
472
+ "data-[ending-style]:opacity-0 data-[ending-style]:scale-95"
473
+ ];
469
474
  var tooltipTv = tv7({
470
475
  slots: {
471
476
  popup: [
472
477
  "bg-inverse-surface text-inverse-on-surface text-body-small",
473
478
  "rounded-extra-small px-2 py-1 max-w-[224px] select-none",
474
- "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
475
- "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
476
- "data-[ending-style]:opacity-0 data-[ending-style]:scale-95"
479
+ ...transition
477
480
  ],
478
481
  arrow: ["text-inverse-surface"]
479
482
  }
480
483
  });
484
+ var richTooltipTv = tv7({
485
+ slots: {
486
+ popup: [
487
+ "bg-surface-container text-on-surface shadow-level2",
488
+ "rounded-medium px-4 py-3 max-w-[320px] flex flex-col gap-1",
489
+ "outline-none",
490
+ ...transition
491
+ ],
492
+ arrow: ["text-surface-container"],
493
+ subhead: ["text-title-small text-on-surface m-0"],
494
+ supportingText: ["text-body-medium text-on-surface-variant m-0"],
495
+ // M3 places rich-tooltip actions at the bottom-left (leading), not trailing
496
+ // like a dialog. -ml-2 pulls the text button so its label optically aligns
497
+ // with the content's left edge.
498
+ actions: ["flex flex-wrap items-center gap-2 mt-1 -ml-2"]
499
+ }
500
+ });
481
501
  var t = tooltipTv();
482
502
  var Tooltip = createTooltip({ popup: t.popup(), arrow: t.arrow() });
503
+ var r2 = richTooltipTv();
504
+ var RichTooltip = createRichTooltip({
505
+ popup: r2.popup(),
506
+ arrow: r2.arrow(),
507
+ subhead: r2.subhead(),
508
+ supportingText: r2.supportingText(),
509
+ actions: r2.actions()
510
+ });
483
511
  var dialogTv = tv7({
484
512
  slots: {
485
513
  backdrop: [
@@ -488,38 +516,159 @@ var dialogTv = tv7({
488
516
  "data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"
489
517
  ],
490
518
  popup: [
491
- "fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2",
492
- "w-[min(560px,calc(100vw-48px))] max-h-[calc(100vh-48px)] overflow-auto",
493
- "bg-surface-container-high text-on-surface rounded-extra-large shadow-level3",
494
- "p-6 flex flex-col gap-4",
519
+ "fixed z-50 box-border overflow-auto flex flex-col text-on-surface focus:outline-none",
495
520
  "origin-[var(--transform-origin)] transition-[opacity,transform] duration-200 ease-emphasized",
496
- "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
497
- "data-[ending-style]:opacity-0 data-[ending-style]:scale-95",
498
- "focus:outline-none"
521
+ // Icon present → center the headline + supporting text (M3 hero icon).
522
+ "has-[[data-slot=dialog-icon]]:text-center"
499
523
  ],
524
+ // Fullscreen header row: leading close icon + title (grows, but shrinks +
525
+ // ellipsizes instead of pushing the trailing action off-screen) + action.
526
+ header: [
527
+ "flex items-center gap-2 px-2 h-14 shrink-0",
528
+ "[&>*:nth-child(2)]:grow [&>*:nth-child(2)]:min-w-0 [&>*:nth-child(2)]:overflow-hidden [&>*:nth-child(2)]:text-ellipsis [&>*:nth-child(2)]:whitespace-nowrap"
529
+ ],
530
+ // Centered 24dp hero icon in the secondary color.
531
+ icon: ["inline-flex self-center text-secondary"],
500
532
  title: ["text-headline-small text-on-surface m-0"],
501
533
  description: ["text-body-medium text-on-surface-variant m-0"],
534
+ // 1dp outline-variant rule under the fullscreen header.
535
+ divider: ["h-px w-full bg-outline-variant shrink-0 m-0 border-0"],
536
+ // End-aligned action row: 8dp between buttons; the popup gap (16dp) + mt-2
537
+ // (8dp) totals the 24dp M3 spacing above the actions.
538
+ actions: ["flex justify-end items-center gap-2 mt-2"],
502
539
  close: ["inline-flex"]
540
+ },
541
+ variants: {
542
+ fullscreen: {
543
+ false: {
544
+ popup: [
545
+ "left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
546
+ "w-[min(560px,calc(100vw-48px))] min-w-[280px] max-h-[calc(100vh-48px)]",
547
+ "p-6 gap-4 rounded-extra-large bg-surface-container-high shadow-level3",
548
+ "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
549
+ "data-[ending-style]:opacity-0 data-[ending-style]:scale-95"
550
+ ]
551
+ },
552
+ true: {
553
+ popup: [
554
+ "inset-0 w-screen h-screen max-w-none rounded-none bg-surface",
555
+ "data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"
556
+ ]
557
+ }
558
+ }
559
+ },
560
+ defaultVariants: {
561
+ fullscreen: false
503
562
  }
504
563
  });
505
564
  var d = dialogTv();
506
565
  var Dialog = createDialog({
507
566
  backdrop: d.backdrop(),
508
- popup: d.popup(),
567
+ popup: ({ fullscreen }) => dialogTv({ fullscreen }).popup(),
568
+ header: d.header(),
569
+ icon: d.icon(),
509
570
  title: d.title(),
510
571
  description: d.description(),
572
+ divider: d.divider(),
573
+ actions: d.actions(),
511
574
  close: d.close()
512
575
  });
576
+
577
+ // src/components/menu/menu-selectable-item.ts
578
+ var menuSelectableItemStateLayer = [
579
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
580
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
581
+ "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
582
+ "active:before:opacity-[var(--md-sys-state-pressed)]"
583
+ ];
584
+ var menuSelectableItemSelectedFill = [
585
+ "data-[selected]:bg-secondary-container data-[selected]:text-on-secondary-container",
586
+ "data-[checked]:bg-secondary-container data-[checked]:text-on-secondary-container"
587
+ ];
588
+ var menuSelectableItemPositionShape = [
589
+ "data-[selected]:data-[position=only]:rounded-extra-small",
590
+ "data-[selected]:data-[position=first]:rounded-t-extra-small",
591
+ "data-[selected]:data-[position=middle]:rounded-none",
592
+ "data-[selected]:data-[position=last]:rounded-b-extra-small",
593
+ "data-[checked]:data-[position=only]:rounded-extra-small",
594
+ "data-[checked]:data-[position=first]:rounded-t-extra-small",
595
+ "data-[checked]:data-[position=middle]:rounded-none",
596
+ "data-[checked]:data-[position=last]:rounded-b-extra-small"
597
+ ];
598
+ var menuSelectableItemPositionShapeFallback = [
599
+ "data-[selected]:not([data-position]):rounded-extra-small",
600
+ "data-[checked]:not([data-position]):rounded-extra-small"
601
+ ];
602
+ var menuSelectableItemDisabled = [
603
+ "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none",
604
+ "data-[disabled]:data-[selected]:bg-transparent data-[disabled]:data-[selected]:text-on-surface/[0.38]",
605
+ "data-[disabled]:data-[checked]:bg-transparent data-[disabled]:data-[checked]:text-on-surface/[0.38]"
606
+ ];
607
+ var menuSelectableItemBase = [
608
+ "group relative cursor-pointer select-none outline-none text-label-large text-on-surface",
609
+ "h-12 px-3 overflow-hidden",
610
+ ...menuSelectableItemStateLayer,
611
+ ...menuSelectableItemSelectedFill,
612
+ ...menuSelectableItemPositionShape,
613
+ ...menuSelectableItemPositionShapeFallback,
614
+ ...menuSelectableItemDisabled
615
+ ];
616
+ var menuSelectableItemTv = tv7({
617
+ slots: {
618
+ /** Select row: check + label + optional trailing meta. */
619
+ selectItem: ["grid grid-cols-[24px_1fr_auto] items-center gap-3", ...menuSelectableItemBase],
620
+ /** Menu checkbox / radio row: check + label. */
621
+ menuSelectableItem: ["grid grid-cols-[24px_1fr] items-center gap-3", ...menuSelectableItemBase],
622
+ itemIndicator: [
623
+ "inline-flex items-center justify-center text-on-surface",
624
+ "invisible group-data-[selected]:visible group-data-[checked]:visible",
625
+ "group-data-[selected]:text-on-secondary-container group-data-[checked]:text-on-secondary-container",
626
+ "group-data-[disabled]:text-on-surface/[0.38]"
627
+ ]
628
+ }
629
+ });
630
+ var menuSelectableItem = menuSelectableItemTv();
631
+
632
+ // src/components/menu/menu-surface.ts
633
+ var menuSurfaceBase = [
634
+ "py-2",
635
+ "bg-surface-container text-on-surface rounded-extra-small shadow-level2",
636
+ "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
637
+ "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
638
+ "data-[ending-style]:opacity-0",
639
+ "focus:outline-none"
640
+ ];
641
+ var menuSurfaceTv = tv7({
642
+ slots: {
643
+ popup: ["max-w-[280px]", ...menuSurfaceBase],
644
+ groupLabel: "px-3 py-2 text-label-small text-on-surface-variant"
645
+ },
646
+ variants: {
647
+ width: {
648
+ /** Standalone Menu: 112–280dp. */
649
+ standard: { popup: "min-w-[112px]" },
650
+ /** Exposed Dropdown / Select: at least anchor width, capped at 280dp. */
651
+ anchor: { popup: "min-w-[max(112px,var(--anchor-width))]" }
652
+ },
653
+ scroll: {
654
+ none: {},
655
+ /** Select popup: clamp height and scroll the list. */
656
+ auto: { popup: "max-h-[var(--available-height)] overflow-auto" }
657
+ }
658
+ },
659
+ defaultVariants: {
660
+ width: "standard",
661
+ scroll: "none"
662
+ }
663
+ });
664
+ menuSurfaceTv();
665
+
666
+ // src/components/menu/menu.ts
667
+ var surface = menuSurfaceTv({ width: "standard", scroll: "none" });
668
+ var selectable = menuSelectableItem;
513
669
  var menuTv = tv7({
514
670
  slots: {
515
- popup: [
516
- "min-w-[112px] max-w-[280px] py-2",
517
- "bg-surface-container text-on-surface rounded-extra-small shadow-level2",
518
- "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
519
- "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
520
- "data-[ending-style]:opacity-0",
521
- "focus:outline-none"
522
- ],
671
+ popup: surface.popup(),
523
672
  item: [
524
673
  "relative flex items-center gap-3 h-12 px-3 overflow-hidden cursor-pointer select-none outline-none",
525
674
  "text-label-large text-on-surface",
@@ -536,7 +685,7 @@ var menuTv = tv7({
536
685
  "[&_[data-slot=menu-trailing]]:ml-auto [&_[data-slot=menu-trailing]]:pl-4 [&_[data-slot=menu-trailing]]:text-label-large [&_[data-slot=menu-trailing]]:text-on-surface-variant"
537
686
  ],
538
687
  separator: ["my-2 h-px border-0 bg-outline-variant"],
539
- groupLabel: ["px-3 py-2 text-label-small text-on-surface-variant"],
688
+ groupLabel: surface.groupLabel(),
540
689
  // Submenu trigger: item look + trailing chevron, highlighted while open.
541
690
  submenuTrigger: [
542
691
  "relative flex items-center justify-between gap-3 h-12 px-3 overflow-hidden cursor-pointer select-none outline-none",
@@ -551,28 +700,9 @@ var menuTv = tv7({
551
700
  "data-[disabled]:[&_[data-slot=menu-leading]]:text-on-surface/[0.38]",
552
701
  "[&_[data-slot=menu-leading]]:inline-flex [&_[data-slot=menu-leading]]:text-on-surface-variant [&_[data-slot=menu-leading]>svg]:size-6"
553
702
  ],
554
- // Selectable items: 24dp leading indicator column + label.
555
- checkboxItem: [
556
- "group relative grid grid-cols-[24px_1fr] items-center gap-3 h-12 px-3 overflow-hidden",
557
- "cursor-pointer select-none outline-none text-label-large text-on-surface",
558
- "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
559
- "hover:before:opacity-[var(--md-sys-state-hover)]",
560
- "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
561
- "active:before:opacity-[var(--md-sys-state-pressed)]",
562
- // M3 disabled (per-token): label on-surface/0.38, no state layer.
563
- "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none"
564
- ],
565
- radioItem: [
566
- "group relative grid grid-cols-[24px_1fr] items-center gap-3 h-12 px-3 overflow-hidden",
567
- "cursor-pointer select-none outline-none text-label-large text-on-surface",
568
- "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
569
- "hover:before:opacity-[var(--md-sys-state-hover)]",
570
- "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
571
- "active:before:opacity-[var(--md-sys-state-pressed)]",
572
- // M3 disabled (per-token): label on-surface/0.38, no state layer.
573
- "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none"
574
- ],
575
- itemIndicator: "inline-flex items-center justify-center text-on-surface invisible group-data-[checked]:visible group-data-[disabled]:text-on-surface/[0.38]"
703
+ checkboxItem: selectable.menuSelectableItem(),
704
+ radioItem: selectable.menuSelectableItem(),
705
+ itemIndicator: selectable.itemIndicator()
576
706
  }
577
707
  });
578
708
  var m = menuTv();
@@ -691,6 +821,8 @@ var Slider = createSlider({
691
821
  tick: s2.tick(),
692
822
  valueLabel: s2.valueLabel()
693
823
  });
824
+ var surface2 = menuSurfaceTv({ width: "anchor", scroll: "auto" });
825
+ var selectable2 = menuSelectableItem;
694
826
  var selectTv = tv7({
695
827
  slots: {
696
828
  trigger: [
@@ -705,30 +837,16 @@ var selectTv = tv7({
705
837
  ],
706
838
  value: "flex-1 truncate",
707
839
  icon: "flex text-on-surface-variant transition-transform duration-150 group-data-[popup-open]:rotate-180 group-data-[disabled]:text-on-surface/[0.38]",
708
- popup: [
709
- "min-w-[var(--anchor-width)] max-h-[var(--available-height)] py-2 overflow-auto",
710
- "bg-surface-container text-on-surface rounded-extra-small shadow-level2",
711
- "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
712
- "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
713
- "data-[ending-style]:opacity-0",
714
- "focus:outline-none"
715
- ],
840
+ popup: surface2.popup(),
716
841
  item: [
717
- "group relative grid grid-cols-[24px_1fr_auto] items-center gap-2 h-12 px-3 overflow-hidden",
718
- "cursor-pointer select-none outline-none text-body-large text-on-surface",
719
- "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
720
- "hover:before:opacity-[var(--md-sys-state-hover)]",
721
- "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
722
- "active:before:opacity-[var(--md-sys-state-pressed)]",
723
- // M3 disabled (per-token, not a blanket fade): label + trailing supporting
724
- // text on-surface/0.38, no state layer.
725
- "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none",
726
- "data-[disabled]:[&_[data-slot=select-trailing]]:text-on-surface/[0.38]",
842
+ selectable2.selectItem(),
727
843
  // M3 trailing supporting text (e.g. meta) sits in the last column.
728
- "[&_[data-slot=select-trailing]]:pl-4 [&_[data-slot=select-trailing]]:text-label-large [&_[data-slot=select-trailing]]:text-on-surface-variant"
844
+ "[&_[data-slot=select-trailing]]:pl-4 [&_[data-slot=select-trailing]]:text-label-large [&_[data-slot=select-trailing]]:text-on-surface-variant",
845
+ "data-[selected]:[&_[data-slot=select-trailing]]:text-on-secondary-container",
846
+ "data-[disabled]:[&_[data-slot=select-trailing]]:text-on-surface/[0.38]"
729
847
  ],
730
- itemIndicator: "inline-flex items-center justify-center text-primary invisible group-data-[selected]:visible group-data-[disabled]:text-on-surface/[0.38]",
731
- groupLabel: "px-3 py-2 text-label-small text-on-surface-variant",
848
+ itemIndicator: selectable2.itemIndicator(),
849
+ groupLabel: surface2.groupLabel(),
732
850
  // Sticky scroll affordances at the popup edges; surface-tinted with a chevron.
733
851
  scrollUpArrow: [
734
852
  "sticky top-0 z-[1] flex items-center justify-center h-6 cursor-default",
@@ -740,27 +858,123 @@ var selectTv = tv7({
740
858
  ]
741
859
  }
742
860
  });
743
- var s3 = selectTv();
744
- var Select = createSelect({
745
- trigger: s3.trigger(),
746
- value: s3.value(),
747
- icon: s3.icon(),
748
- popup: s3.popup(),
749
- item: s3.item(),
750
- itemIndicator: s3.itemIndicator(),
751
- groupLabel: s3.groupLabel(),
752
- scrollUpArrow: s3.scrollUpArrow(),
753
- scrollDownArrow: s3.scrollDownArrow()
861
+ var selectFieldTv = tv7({
862
+ slots: {
863
+ // The `group` hook lives here (not in engine-neutral core): supporting text
864
+ // keys its error color off Field.Root's `group-data-[invalid]`.
865
+ root: "group flex flex-col gap-1 min-w-[210px]",
866
+ field: [
867
+ "group/field relative flex items-stretch gap-3 h-14 px-4 box-border w-full",
868
+ "text-on-surface text-body-large cursor-pointer text-left outline-none",
869
+ "transition-[border-color,padding] duration-150 ease-standard",
870
+ "data-[disabled]:opacity-[0.38] data-[disabled]:pointer-events-none"
871
+ ],
872
+ inputWrap: "relative z-0 flex-1 flex items-center min-w-0 overflow-visible",
873
+ value: "flex-1 truncate text-body-large text-on-surface",
874
+ label: [
875
+ "absolute left-0 pointer-events-none origin-left",
876
+ "top-1/2 -translate-y-1/2 text-body-large text-on-surface-variant",
877
+ "transition-all duration-150 ease-standard",
878
+ "group-data-[focused]/field:text-primary group-data-[invalid]/field:text-error"
879
+ ],
880
+ icon: [
881
+ // Disabled dimming comes from the field's own opacity (0.38); no per-icon
882
+ // color override here, else it would compound to ~0.14.
883
+ "flex items-center text-on-surface-variant transition-transform duration-150 [&>svg]:size-6",
884
+ "group-data-[popup-open]/field:rotate-180"
885
+ ],
886
+ leadingIcon: "inline-flex items-center justify-center shrink-0 text-on-surface-variant [&>svg]:size-6",
887
+ supporting: [
888
+ "flex justify-between gap-4 px-4 text-body-small text-on-surface-variant",
889
+ "group-data-[invalid]:text-error"
890
+ ],
891
+ supportingText: "min-w-0"
892
+ },
893
+ variants: {
894
+ variant: {
895
+ filled: {
896
+ field: [
897
+ "overflow-hidden rounded-t-extra-small bg-surface-container-highest",
898
+ // M3 filled hover: state layer (on-surface × state-hover).
899
+ "before:absolute before:inset-0 before:rounded-[inherit] before:bg-current before:opacity-0 before:pointer-events-none",
900
+ "before:transition-opacity before:duration-100",
901
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
902
+ "data-[disabled]:before:opacity-0",
903
+ // M3 filled resting active-indicator: 1dp on-surface-variant.
904
+ "border-b border-on-surface-variant hover:border-on-surface",
905
+ // M3 filled focus-active-indicator-height is 3dp.
906
+ "data-[focused]:border-b-[3px] data-[focused]:border-primary",
907
+ "data-[popup-open]:border-b-[3px] data-[popup-open]:border-primary",
908
+ "data-[invalid]:border-error"
909
+ ],
910
+ value: "pt-3",
911
+ label: [
912
+ "group-data-[focused]/field:top-1.5 group-data-[focused]/field:translate-y-0 group-data-[focused]/field:text-body-small",
913
+ "group-data-[filled]/field:top-1.5 group-data-[filled]/field:translate-y-0 group-data-[filled]/field:text-body-small",
914
+ "group-data-[popup-open]/field:top-1.5 group-data-[popup-open]/field:translate-y-0 group-data-[popup-open]/field:text-body-small",
915
+ "group-data-[has-placeholder]/field:top-1.5 group-data-[has-placeholder]/field:translate-y-0 group-data-[has-placeholder]/field:text-body-small"
916
+ ]
917
+ },
918
+ outlined: {
919
+ field: [
920
+ "overflow-visible rounded-extra-small border border-outline hover:border-on-surface",
921
+ // M3 outlined focus-outline-width is 3dp; padding drops 2px so content
922
+ // stays steady as the 1dp border grows (matches the TextField anchor).
923
+ "data-[focused]:border-[3px] data-[focused]:border-primary data-[focused]:px-[14px]",
924
+ "data-[popup-open]:border-[3px] data-[popup-open]:border-primary data-[popup-open]:px-[14px]",
925
+ "data-[invalid]:border-error"
926
+ ],
927
+ label: [
928
+ "group-data-[focused]/field:top-0 group-data-[focused]/field:-translate-y-1/2 group-data-[focused]/field:z-[1] group-data-[focused]/field:text-body-small group-data-[focused]/field:bg-surface group-data-[focused]/field:px-1 group-data-[focused]/field:leading-none",
929
+ "group-data-[filled]/field:top-0 group-data-[filled]/field:-translate-y-1/2 group-data-[filled]/field:z-[1] group-data-[filled]/field:text-body-small group-data-[filled]/field:bg-surface group-data-[filled]/field:px-1 group-data-[filled]/field:leading-none",
930
+ "group-data-[popup-open]/field:top-0 group-data-[popup-open]/field:-translate-y-1/2 group-data-[popup-open]/field:z-[1] group-data-[popup-open]/field:text-body-small group-data-[popup-open]/field:bg-surface group-data-[popup-open]/field:px-1 group-data-[popup-open]/field:leading-none",
931
+ "group-data-[has-placeholder]/field:top-0 group-data-[has-placeholder]/field:-translate-y-1/2 group-data-[has-placeholder]/field:z-[1] group-data-[has-placeholder]/field:text-body-small group-data-[has-placeholder]/field:bg-surface group-data-[has-placeholder]/field:px-1 group-data-[has-placeholder]/field:leading-none"
932
+ ]
933
+ }
934
+ }
935
+ },
936
+ defaultVariants: {
937
+ variant: "outlined"
938
+ }
754
939
  });
940
+ var s3 = selectTv();
941
+ var Select = createSelect(
942
+ {
943
+ trigger: s3.trigger(),
944
+ value: s3.value(),
945
+ icon: s3.icon(),
946
+ popup: s3.popup(),
947
+ item: s3.item(),
948
+ itemIndicator: s3.itemIndicator(),
949
+ groupLabel: s3.groupLabel(),
950
+ scrollUpArrow: s3.scrollUpArrow(),
951
+ scrollDownArrow: s3.scrollDownArrow()
952
+ },
953
+ ({ variant }) => {
954
+ const f = selectFieldTv({ variant });
955
+ return {
956
+ root: f.root(),
957
+ field: f.field(),
958
+ inputWrap: f.inputWrap(),
959
+ value: f.value(),
960
+ label: f.label(),
961
+ icon: f.icon(),
962
+ leadingIcon: f.leadingIcon(),
963
+ supporting: f.supporting(),
964
+ supportingText: f.supportingText()
965
+ };
966
+ }
967
+ );
968
+ var iconVisual = "inline-flex items-center justify-center shrink-0 text-on-surface-variant [&>svg]:size-6";
755
969
  var textFieldTv = tv({
756
970
  slots: {
757
971
  root: "flex flex-col gap-1 min-w-[210px]",
758
972
  field: [
759
- "relative flex items-stretch gap-3 h-14 px-4 box-border",
973
+ "relative flex items-stretch gap-3 h-14 px-4 box-border text-on-surface",
760
974
  "transition-[border-color,padding] duration-150 ease-standard",
761
975
  "group-data-[disabled]:opacity-[0.38] group-data-[disabled]:pointer-events-none"
762
976
  ],
763
- inputWrap: "relative flex-1 flex items-center min-w-0",
977
+ inputWrap: "relative z-0 flex-1 flex items-center min-w-0 overflow-visible",
764
978
  input: [
765
979
  "peer w-full bg-transparent outline-none border-0 p-0 text-body-large text-on-surface",
766
980
  "placeholder:text-on-surface-variant"
@@ -771,8 +985,18 @@ var textFieldTv = tv({
771
985
  "transition-all duration-150 ease-standard",
772
986
  "group-data-[focused]:text-primary group-data-[invalid]:text-error"
773
987
  ],
774
- leadingIcon: "flex items-center shrink-0 text-on-surface-variant",
775
- trailingIcon: "flex items-center shrink-0 text-on-surface-variant",
988
+ leadingIcon: iconVisual,
989
+ trailingIcon: iconVisual,
990
+ leadingIconButton: [
991
+ iconVisual,
992
+ "relative size-12 p-0 border-0 bg-transparent cursor-pointer",
993
+ "group-data-[disabled]:pointer-events-none"
994
+ ],
995
+ trailingIconButton: [
996
+ iconVisual,
997
+ "relative size-12 p-0 border-0 bg-transparent cursor-pointer",
998
+ "group-data-[disabled]:pointer-events-none"
999
+ ],
776
1000
  supporting: [
777
1001
  "flex justify-between gap-4 px-4 text-body-small text-on-surface-variant",
778
1002
  "group-data-[invalid]:text-error"
@@ -784,9 +1008,15 @@ var textFieldTv = tv({
784
1008
  variant: {
785
1009
  filled: {
786
1010
  field: [
787
- "rounded-t-extra-small bg-surface-container-highest",
788
- "border-b-2 border-outline",
789
- // M3 filled focus-active-indicator-height is 3dp (resting/error stay 2dp).
1011
+ "overflow-hidden rounded-t-extra-small bg-surface-container-highest",
1012
+ // M3 filled hover: state layer (on-surface × state-hover) + indicator color.
1013
+ "before:absolute before:inset-0 before:rounded-[inherit] before:bg-current before:opacity-0 before:pointer-events-none",
1014
+ "before:transition-opacity before:duration-100",
1015
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
1016
+ "group-data-[disabled]:before:opacity-0",
1017
+ // M3 filled resting active-indicator: 1dp on-surface-variant.
1018
+ "border-b border-on-surface-variant hover:border-on-surface",
1019
+ // M3 filled focus-active-indicator-height is 3dp.
790
1020
  "group-data-[focused]:border-b-[3px] group-data-[focused]:border-primary group-data-[invalid]:border-error"
791
1021
  ],
792
1022
  input: "pt-3",
@@ -797,15 +1027,18 @@ var textFieldTv = tv({
797
1027
  },
798
1028
  outlined: {
799
1029
  field: [
800
- "rounded-extra-small border border-outline",
1030
+ // Outlined hover = outline color only (no container state layer per M3).
1031
+ "overflow-visible rounded-extra-small border border-outline hover:border-on-surface",
801
1032
  // M3 outlined focus-outline-width is 3dp (matches Select's trigger);
802
1033
  // padding drops 2px so content stays steady as the 1dp border grows.
803
1034
  "group-data-[focused]:border-[3px] group-data-[focused]:border-primary group-data-[focused]:px-[14px]",
804
1035
  "group-data-[invalid]:border-error"
805
1036
  ],
806
1037
  label: [
807
- "group-data-[focused]:top-0 group-data-[focused]:-translate-y-1/2 group-data-[focused]:text-body-small group-data-[focused]:bg-surface group-data-[focused]:px-1",
808
- "group-data-[filled]:top-0 group-data-[filled]:-translate-y-1/2 group-data-[filled]:text-body-small group-data-[filled]:bg-surface group-data-[filled]:px-1"
1038
+ "group-data-[focused]:top-0 group-data-[focused]:-translate-y-1/2 group-data-[focused]:z-[1]",
1039
+ "group-data-[focused]:text-body-small group-data-[focused]:bg-surface group-data-[focused]:px-1 group-data-[focused]:leading-none",
1040
+ "group-data-[filled]:top-0 group-data-[filled]:-translate-y-1/2 group-data-[filled]:z-[1]",
1041
+ "group-data-[filled]:text-body-small group-data-[filled]:bg-surface group-data-[filled]:px-1 group-data-[filled]:leading-none"
809
1042
  ]
810
1043
  }
811
1044
  }
@@ -824,6 +1057,8 @@ var TextField = createTextField(({ variant }) => {
824
1057
  label: c3.label(),
825
1058
  leadingIcon: c3.leadingIcon(),
826
1059
  trailingIcon: c3.trailingIcon(),
1060
+ leadingIconButton: c3.leadingIconButton(),
1061
+ trailingIconButton: c3.trailingIconButton(),
827
1062
  supporting: c3.supporting(),
828
1063
  supportingText: c3.supportingText(),
829
1064
  counter: c3.counter()
@@ -903,36 +1138,68 @@ var fabTv = tv({
903
1138
  "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38"
904
1139
  ],
905
1140
  variants: {
906
- size: {
907
- small: "size-10 rounded-medium [&_svg]:size-6",
908
- regular: "size-14 rounded-large [&_svg]:size-6",
909
- large: "size-24 rounded-extra-large [&_svg]:size-9",
910
- extended: "h-14 min-w-20 px-4 gap-3 rounded-large text-label-large [&_svg]:size-6"
911
- },
1141
+ // Geometry is set by compoundVariants (size × variant); these keys exist so
1142
+ // the resolver can accept them.
1143
+ size: { small: "", medium: "", large: "" },
1144
+ variant: { standard: "", extended: "" },
912
1145
  color: {
913
- surface: "bg-surface-container-high text-primary",
914
1146
  primary: "bg-primary-container text-on-primary-container",
915
1147
  secondary: "bg-secondary-container text-on-secondary-container",
916
1148
  tertiary: "bg-tertiary-container text-on-tertiary-container"
917
1149
  }
918
1150
  },
1151
+ compoundVariants: [
1152
+ // ---- Standard (icon-only square): container / corner / icon ----
1153
+ { size: "small", variant: "standard", class: "size-14 rounded-large [&_svg]:size-6" },
1154
+ // 56 / 16 / 24
1155
+ {
1156
+ size: "medium",
1157
+ variant: "standard",
1158
+ class: "size-20 rounded-large-increased [&_svg]:size-7"
1159
+ // 80 / 20 / 28
1160
+ },
1161
+ { size: "large", variant: "standard", class: "size-24 rounded-extra-large [&_svg]:size-8" },
1162
+ // 96 / 28 / 32
1163
+ // ---- Extended (icon + label pill): height / corner / icon / padding / gap / label ----
1164
+ // `min-w-*` keeps the pill affordance for short / text-only labels (wider
1165
+ // than tall), matching the pre-Expressive extended FAB which guarded this.
1166
+ {
1167
+ size: "small",
1168
+ variant: "extended",
1169
+ class: "h-14 min-w-20 px-4 gap-2 rounded-large text-title-medium [&_svg]:size-6"
1170
+ // 56 / 16 / 24 / 16 / 8
1171
+ },
1172
+ {
1173
+ size: "medium",
1174
+ variant: "extended",
1175
+ class: "h-20 min-w-28 px-[26px] gap-4 rounded-large-increased text-title-large [&_svg]:size-7"
1176
+ // 80 / 20 / 28 / 26 / 16
1177
+ },
1178
+ {
1179
+ size: "large",
1180
+ variant: "extended",
1181
+ class: "h-24 min-w-32 px-7 gap-5 rounded-extra-large text-headline-small [&_svg]:size-8"
1182
+ // 96 / 28 / 32 / 28 / 20
1183
+ }
1184
+ ],
919
1185
  defaultVariants: {
920
- size: "regular",
921
- color: "surface"
1186
+ size: "small",
1187
+ variant: "standard",
1188
+ color: "primary"
922
1189
  }
923
1190
  });
924
- var Fab = createFab(({ size, color }) => fabTv({ size, color }));
1191
+ var Fab = createFab(({ size, color, variant }) => fabTv({ size, color, variant }));
925
1192
  var fabMenuTv = tv7({
926
1193
  slots: {
927
1194
  popup: [
928
- "flex flex-col items-end gap-2 bg-transparent outline-none",
1195
+ "flex flex-col items-end gap-1 bg-transparent outline-none",
929
1196
  "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
930
1197
  "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
931
1198
  "data-[ending-style]:opacity-0"
932
1199
  ],
933
1200
  item: [
934
- "relative inline-flex items-center gap-3 h-14 px-4 overflow-hidden box-border",
935
- "cursor-pointer select-none outline-none rounded-full text-label-large",
1201
+ "relative inline-flex items-center gap-2 h-14 px-6 overflow-hidden box-border",
1202
+ "cursor-pointer select-none outline-none rounded-full text-title-medium",
936
1203
  "shadow-level3 hover:shadow-level4 transition-shadow duration-150 ease-standard",
937
1204
  "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
938
1205
  "hover:before:opacity-[var(--md-sys-state-hover)]",
@@ -948,7 +1215,6 @@ var fabMenuTv = tv7({
948
1215
  },
949
1216
  variants: {
950
1217
  color: {
951
- surface: { item: "bg-surface-container-high text-primary" },
952
1218
  primary: { item: "bg-primary-container text-on-primary-container" },
953
1219
  secondary: { item: "bg-secondary-container text-on-secondary-container" },
954
1220
  tertiary: { item: "bg-tertiary-container text-on-tertiary-container" }
@@ -990,34 +1256,94 @@ var dividerTv = tv({
990
1256
  var Divider = createDivider(({ inset, orientation }) => dividerTv({ inset, orientation }));
991
1257
  var linearTv = tv({
992
1258
  slots: {
993
- root: "group relative block w-full h-1 overflow-hidden rounded-full",
994
- track: "absolute inset-0 bg-surface-container-highest rounded-full",
1259
+ // The track-stop dot (primary, full track height) sits at the inline-end via
1260
+ // `after:`. It's a determinate-only M3 concept, so it's hidden while
1261
+ // indeterminate. Logical `end-0` mirrors with the indicator under `dir="rtl"`.
1262
+ // Height comes from the factory (inline) so `thickness` is honored.
1263
+ root: [
1264
+ "group relative block w-full overflow-hidden rounded-full",
1265
+ // The dot is `--m3-thickness` tall (stroke height) and centered, so it stays
1266
+ // correct when the wavy track grows taller than the stroke.
1267
+ "after:content-[''] after:absolute after:end-0 after:top-1/2 after:-translate-y-1/2",
1268
+ "after:h-[var(--m3-thickness,100%)] after:aspect-square after:rounded-full after:bg-primary",
1269
+ // Self variant (not `group-data-*`): the dot is on the root element itself,
1270
+ // which carries `data-indeterminate` — it isn't a descendant of `.group`.
1271
+ "data-[indeterminate]:after:hidden"
1272
+ ],
1273
+ // Positioning container only; the inactive track is the `before:` pseudo so a
1274
+ // 4dp gap separates it from the active indicator (`--m3-progress` + 4px). The
1275
+ // gap uses logical inline insets so it tracks the indicator (which Base UI
1276
+ // anchors at inline-start) under `dir="rtl"`. Indeterminate has no fraction,
1277
+ // so the inactive track spans the full width. The flat track stays
1278
+ // `--m3-thickness` tall and centered even when the wavy root is taller.
1279
+ track: [
1280
+ "absolute inset-0",
1281
+ "before:content-[''] before:absolute before:top-1/2 before:-translate-y-1/2 before:end-0",
1282
+ "before:h-[var(--m3-thickness,100%)]",
1283
+ "before:[inset-inline-start:calc(var(--m3-progress,0%)_+_4px)]",
1284
+ "before:bg-surface-container-highest before:rounded-full",
1285
+ "group-data-[indeterminate]:before:start-0"
1286
+ ],
1287
+ // Primary bar. Determinate: width from Base UI. Indeterminate: full width,
1288
+ // scaled + slid by the disjoint `primary` keyframe (origin at the start edge).
1289
+ // Wavy determinate: a scrolling sine tile masks the solid bar into a wave.
995
1290
  indicator: [
996
- "absolute inset-y-0 left-0 bg-primary rounded-full",
1291
+ "absolute inset-y-0 left-0 origin-left bg-primary rounded-full",
997
1292
  "transition-[width] duration-200 ease-standard",
998
- "group-data-[indeterminate]:w-2/5 group-data-[indeterminate]:transition-none",
999
- "group-data-[indeterminate]:animate-m3-linear-indeterminate"
1293
+ "group-data-[indeterminate]:w-full group-data-[indeterminate]:transition-none",
1294
+ "group-data-[indeterminate]:animate-m3-linear-primary",
1295
+ "group-data-[wavy]:rounded-none",
1296
+ "group-data-[wavy]:[-webkit-mask-image:var(--m3-wave)] group-data-[wavy]:[mask-image:var(--m3-wave)]",
1297
+ "group-data-[wavy]:[-webkit-mask-repeat:repeat-x] group-data-[wavy]:[mask-repeat:repeat-x]",
1298
+ "group-data-[wavy]:[-webkit-mask-size:40px_100%] group-data-[wavy]:[mask-size:40px_100%]",
1299
+ "group-data-[wavy]:animate-m3-wave-flow",
1300
+ // Reduced motion: freeze the loops and show a static ~40% bar / static wave.
1301
+ "motion-reduce:group-data-[indeterminate]:w-2/5",
1302
+ "motion-reduce:group-data-[indeterminate]:animate-none motion-reduce:group-data-[wavy]:animate-none"
1303
+ ],
1304
+ // Second disjoint bar: only present visually while indeterminate.
1305
+ indicatorSecondary: [
1306
+ "absolute inset-y-0 left-0 w-full origin-left bg-primary rounded-full hidden",
1307
+ "group-data-[indeterminate]:block group-data-[indeterminate]:animate-m3-linear-secondary",
1308
+ // Reduced motion: a single static bar reads better than two frozen ones.
1309
+ "motion-reduce:group-data-[indeterminate]:hidden"
1000
1310
  ]
1001
1311
  }
1002
1312
  });
1003
1313
  var circularTv = tv({
1004
1314
  slots: {
1315
+ // Size comes from the factory (inline width/height) so `size` is honored.
1316
+ // Indeterminate rotates the whole ring; the arc grows/shrinks via the
1317
+ // indicator's own `dash` animation (M3 "advance").
1005
1318
  root: [
1006
- "inline-flex items-center justify-center size-12",
1319
+ "group inline-flex items-center justify-center",
1007
1320
  "[&_svg]:block [&_svg]:size-full",
1008
- "data-[indeterminate]:animate-spin"
1321
+ "data-[indeterminate]:animate-m3-circular-rotate",
1322
+ "motion-reduce:data-[indeterminate]:animate-none"
1323
+ ],
1324
+ // Both ends are rounded (M3); the inactive track sits behind with a 4dp gap.
1325
+ track: [
1326
+ "stroke-surface-container-highest [stroke-linecap:round]",
1327
+ "transition-[stroke-dasharray,stroke-dashoffset] duration-300 ease-standard"
1009
1328
  ],
1010
- track: "stroke-surface-container-highest [stroke-width:4px]",
1011
1329
  indicator: [
1012
- "stroke-primary [stroke-width:4px] [stroke-linecap:round]",
1013
- "transition-[stroke-dashoffset] duration-300 ease-standard"
1330
+ "stroke-primary [stroke-linecap:round]",
1331
+ "transition-[stroke-dasharray,stroke-dashoffset] duration-300 ease-standard",
1332
+ "group-data-[indeterminate]:animate-m3-circular-dash group-data-[indeterminate]:transition-none",
1333
+ // Reduced motion: freeze the arc at its static 25% length (no rotation).
1334
+ "motion-reduce:group-data-[indeterminate]:animate-none"
1014
1335
  ]
1015
1336
  }
1016
1337
  });
1017
1338
  var l = linearTv();
1018
1339
  var c2 = circularTv();
1019
1340
  var Progress = createProgress({
1020
- linear: { root: l.root(), track: l.track(), indicator: l.indicator() },
1341
+ linear: {
1342
+ root: l.root(),
1343
+ track: l.track(),
1344
+ indicator: l.indicator(),
1345
+ indicatorSecondary: l.indicatorSecondary()
1346
+ },
1021
1347
  circular: { root: c2.root(), track: c2.track(), indicator: c2.indicator() }
1022
1348
  });
1023
1349
  var loadingIndicatorTv = tv7({
@@ -1050,7 +1376,14 @@ var listTv = tv7({
1050
1376
  "group relative flex w-full items-center gap-4 box-border px-4 text-left",
1051
1377
  "bg-transparent border-0 text-on-surface no-underline"
1052
1378
  ],
1053
- leading: "flex items-center justify-center shrink-0 text-on-surface-variant [&_svg]:size-6",
1379
+ leading: [
1380
+ "flex items-center justify-center shrink-0 overflow-hidden text-on-surface-variant",
1381
+ "[&_svg]:size-6 [&_img]:size-full [&_img]:object-cover",
1382
+ // M3 leading column widths, keyed on the factory's data-leading attribute.
1383
+ "data-[leading=avatar]:size-10 data-[leading=avatar]:rounded-full",
1384
+ "data-[leading=image]:size-14",
1385
+ "data-[leading=video]:w-25 data-[leading=video]:h-14"
1386
+ ],
1054
1387
  content: "flex flex-col min-w-0 flex-1",
1055
1388
  headline: "text-body-large text-on-surface group-data-[disabled]:text-on-surface/38",
1056
1389
  supporting: "text-body-medium text-on-surface-variant group-data-[disabled]:text-on-surface/38",
@@ -1103,10 +1436,15 @@ var snackbarTv = tv({
1103
1436
  slots: {
1104
1437
  viewport: [
1105
1438
  "fixed bottom-4 left-1/2 -translate-x-1/2 z-50",
1106
- "flex flex-col gap-2 w-[min(560px,calc(100vw-32px))]"
1439
+ // M3 container width: cap at 672dp, clamp to the viewport on small screens.
1440
+ // Center items so content-following (w-fit) snackbars stay under the anchor.
1441
+ "flex flex-col items-center gap-2 w-[calc(100vw-32px)] max-w-[672px]"
1107
1442
  ],
1108
1443
  root: [
1109
1444
  "relative flex items-center gap-2 min-h-12 box-border pl-4 pr-2 py-2",
1445
+ // M3 container width follows content within min 344dp / max 672dp. The
1446
+ // min is clamped by 100% so it never overflows a narrower viewport.
1447
+ "w-fit min-w-[min(344px,100%)] max-w-[672px]",
1110
1448
  "rounded-extra-small bg-inverse-surface text-inverse-on-surface shadow-level3",
1111
1449
  "text-body-medium",
1112
1450
  "transition-[opacity,transform] duration-200 ease-emphasized",
@@ -1152,7 +1490,14 @@ var itemTv = tv7({
1152
1490
  "relative flex w-full items-center gap-4 box-border px-4 py-3 min-h-14 text-left",
1153
1491
  "bg-transparent text-on-surface"
1154
1492
  ],
1155
- leading: "flex items-center justify-center shrink-0 text-on-surface-variant [&_svg]:size-6",
1493
+ leading: [
1494
+ "flex items-center justify-center shrink-0 overflow-hidden text-on-surface-variant",
1495
+ "[&_svg]:size-6 [&_img]:size-full [&_img]:object-cover",
1496
+ // M3 leading column widths, keyed on the factory's data-leading attribute.
1497
+ "data-[leading=avatar]:size-10 data-[leading=avatar]:rounded-full",
1498
+ "data-[leading=image]:size-14",
1499
+ "data-[leading=video]:w-25 data-[leading=video]:h-14"
1500
+ ],
1156
1501
  content: "flex flex-col min-w-0 flex-1",
1157
1502
  overline: "text-label-small text-on-surface-variant",
1158
1503
  headline: "text-body-large text-on-surface",
@@ -1281,7 +1626,7 @@ var buttonGroup = tv7({
1281
1626
  }
1282
1627
  });
1283
1628
  var ButtonGroup = createButtonGroup(({ variant }) => buttonGroup({ variant }));
1284
- var surface = [
1629
+ var surface3 = [
1285
1630
  "relative inline-flex items-center justify-center h-10 overflow-hidden cursor-pointer select-none border-0 outline-none",
1286
1631
  "text-label-large",
1287
1632
  "transition-[background-color,color,border-color] duration-200 ease-standard",
@@ -1323,9 +1668,9 @@ var splitButtonTv = tv7({
1323
1668
  slots: {
1324
1669
  group: "inline-flex items-center gap-0.5",
1325
1670
  // leading: outer (start) corner full, seam (end) corner reduced.
1326
- leading: [...surface, "gap-2 px-6 rounded-s-full rounded-e-small"],
1671
+ leading: [...surface3, "gap-2 px-6 rounded-s-full rounded-e-small"],
1327
1672
  // trailing: seam (start) corner reduced, outer (end) corner full.
1328
- trailing: [...surface, "group gap-1 px-3 rounded-s-small rounded-e-full"],
1673
+ trailing: [...surface3, "group gap-1 px-3 rounded-s-small rounded-e-full"],
1329
1674
  chevron: [
1330
1675
  "inline-flex items-center justify-center shrink-0 [&>svg]:size-[18px]",
1331
1676
  "transition-transform duration-200 ease-standard group-data-[popup-open]:rotate-180"
@@ -1770,32 +2115,46 @@ var DatePicker = createDatePicker({
1770
2115
  modalHeadline: dp.modalHeadline(),
1771
2116
  modalActions: dp.modalActions()
1772
2117
  });
2118
+ var stateLayerBase = [
2119
+ "overflow-hidden",
2120
+ 'before:content-[""] before:absolute before:inset-0 before:rounded-[inherit] before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100',
2121
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
2122
+ "focus-visible:before:opacity-[var(--md-sys-state-focus)]",
2123
+ "active:before:opacity-[var(--md-sys-state-pressed)]",
2124
+ "focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2"
2125
+ ];
1773
2126
  var timePickerTv = tv7({
1774
2127
  slots: {
1775
- root: ["inline-flex flex-col items-center gap-2 p-2 text-on-surface"],
1776
- header: ["flex items-center gap-2"],
2128
+ root: ["inline-flex flex-col items-center p-2 text-on-surface"],
2129
+ header: ["flex items-center gap-3 min-h-[98px]"],
2130
+ display: ["inline-flex items-center"],
1777
2131
  field: [
1778
- "inline-grid place-items-center w-24 h-20 rounded-small overflow-hidden box-border",
2132
+ "relative",
2133
+ ...stateLayerBase,
2134
+ "inline-grid place-items-center w-24 h-20 rounded-small box-border",
1779
2135
  "bg-surface-container-highest text-on-surface text-display-large cursor-pointer outline-none",
1780
2136
  "border border-transparent transition-colors duration-100",
1781
2137
  "data-[selected]:bg-primary-container data-[selected]:text-on-primary-container"
1782
2138
  ],
1783
- colon: ["text-display-large text-on-surface px-1 leading-none"],
2139
+ colon: ["text-display-large text-on-surface px-1 leading-none self-center"],
1784
2140
  periods: [
1785
- "inline-flex flex-col rounded-small overflow-hidden border border-outline self-stretch",
1786
- "m-0 p-0 min-w-0"
2141
+ "inline-flex flex-col shrink-0 rounded-small overflow-hidden border border-outline",
2142
+ "h-[98px] w-[52px] m-0 p-0 min-w-0 box-border"
1787
2143
  ],
1788
2144
  period: [
1789
- "flex-1 inline-flex items-center justify-center px-3 min-h-[38px] w-14",
2145
+ "relative",
2146
+ ...stateLayerBase,
2147
+ "flex-1 inline-flex items-center justify-center min-h-12 h-12 w-full",
1790
2148
  "border-0 bg-transparent",
1791
2149
  "text-title-medium text-on-surface-variant cursor-pointer outline-none",
1792
2150
  "data-[selected]:bg-secondary-container data-[selected]:text-on-secondary-container",
1793
2151
  "[&+&]:border-t [&+&]:border-outline"
1794
2152
  ],
1795
2153
  dial: [
1796
- "relative size-[256px] my-2 p-0 min-w-0 border-0 rounded-full bg-surface-container-highest"
2154
+ "relative size-[256px] mt-[28px] p-0 min-w-0 border-0 rounded-full bg-surface-container-highest"
1797
2155
  ],
1798
2156
  dialNumber: [
2157
+ ...stateLayerBase,
1799
2158
  "absolute -translate-x-1/2 -translate-y-1/2 inline-grid place-items-center size-12 rounded-full",
1800
2159
  "border-0 bg-transparent",
1801
2160
  "text-body-large text-on-surface cursor-pointer outline-none select-none",
@@ -1807,7 +2166,7 @@ var timePickerTv = tv7({
1807
2166
  dialCenter: [
1808
2167
  "absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary pointer-events-none"
1809
2168
  ],
1810
- inputs: ["flex items-start gap-2"],
2169
+ inputs: ["flex items-start gap-3"],
1811
2170
  inputBox: [
1812
2171
  "w-24 h-20 rounded-small box-border text-center",
1813
2172
  "bg-surface-container-highest text-on-surface text-display-large outline-none",
@@ -1821,6 +2180,7 @@ var tp = timePickerTv();
1821
2180
  var TimePicker = createTimePicker(() => ({
1822
2181
  root: tp.root(),
1823
2182
  header: tp.header(),
2183
+ display: tp.display(),
1824
2184
  field: tp.field(),
1825
2185
  colon: tp.colon(),
1826
2186
  periods: tp.periods(),
@@ -1876,6 +2236,6 @@ var Carousel = createCarousel((variant) => {
1876
2236
  return { root: s14.root(), item: s14.item() };
1877
2237
  });
1878
2238
 
1879
- export { Badge, BottomAppBar, BottomSheet, Button, ButtonGroup, Card, Carousel, Checkbox, Chip, DatePicker, Dialog, Divider, Fab, FabMenu, IconButton, Item, List, LoadingIndicator, Menu, NavigationBar, NavigationDrawer, NavigationRail, Progress, Radio, RadioGroup, Search, SegmentedButton, Select, SideSheet, Slider, Snackbar, SplitButton, Switch, Tabs, TextField, TimePicker, Toolbar, Tooltip, TopAppBar, badgeTv, bottomAppBarTv, bottomSheetTv, button, buttonGroup, cardTv, carouselTv, checkboxTv, chipTv, circularTv, datePickerTv, dialogTv, dividerTv, fabMenuTv, fabTv, iconButton, itemTv, linearTv, listTv, loadingIndicatorTv, menuTv, navigationBarTv, navigationDrawerTv, navigationRailTv, radioTv, searchTv, segmentedButtonTv, selectTv, sideSheetTv, sliderTv, snackbarTv, splitButtonTv, switchTv, tabsTv, textFieldTv, timePickerTv, toolbarTv, tooltipTv, topAppBarTv };
2239
+ export { Badge, BottomAppBar, BottomSheet, Button, ButtonGroup, Card, Carousel, Checkbox, Chip, DatePicker, Dialog, Divider, Fab, FabMenu, IconButton, Item, List, LoadingIndicator, Menu, NavigationBar, NavigationDrawer, NavigationRail, Progress, Radio, RadioGroup, RichTooltip, Search, SegmentedButton, Select, SideSheet, Slider, Snackbar, SplitButton, Switch, Tabs, TextField, TimePicker, Toolbar, Tooltip, TopAppBar, badgeTv, bottomAppBarTv, bottomSheetTv, button, buttonGroup, cardTv, carouselTv, checkboxTv, chipTv, circularTv, datePickerTv, dialogTv, dividerTv, fabMenuTv, fabTv, iconButton, itemTv, linearTv, listTv, loadingIndicatorTv, menuTv, navigationBarTv, navigationDrawerTv, navigationRailTv, radioTv, richTooltipTv, searchTv, segmentedButtonTv, selectFieldTv, selectTv, sideSheetTv, sliderTv, snackbarTv, splitButtonTv, switchTv, tabsTv, textFieldTv, timePickerTv, toolbarTv, tooltipTv, topAppBarTv };
1880
2240
  //# sourceMappingURL=index.js.map
1881
2241
  //# sourceMappingURL=index.js.map