@m3-baseui/react-tailwind 1.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 (82) hide show
  1. package/dist/badge.d.ts +45 -0
  2. package/dist/badge.js +50 -0
  3. package/dist/badge.js.map +1 -0
  4. package/dist/button.d.ts +69 -0
  5. package/dist/button.js +74 -0
  6. package/dist/button.js.map +1 -0
  7. package/dist/card.d.ts +80 -0
  8. package/dist/card.js +77 -0
  9. package/dist/card.js.map +1 -0
  10. package/dist/checkbox.d.ts +63 -0
  11. package/dist/checkbox.js +60 -0
  12. package/dist/checkbox.js.map +1 -0
  13. package/dist/chip.d.ts +165 -0
  14. package/dist/chip.js +76 -0
  15. package/dist/chip.js.map +1 -0
  16. package/dist/dialog.d.ts +86 -0
  17. package/dist/dialog.js +68 -0
  18. package/dist/dialog.js.map +1 -0
  19. package/dist/divider.d.ts +83 -0
  20. package/dist/divider.js +34 -0
  21. package/dist/divider.js.map +1 -0
  22. package/dist/fab.d.ts +104 -0
  23. package/dist/fab.js +43 -0
  24. package/dist/fab.js.map +1 -0
  25. package/dist/icon-button.d.ts +174 -0
  26. package/dist/icon-button.js +121 -0
  27. package/dist/icon-button.js.map +1 -0
  28. package/dist/index.d.ts +29 -0
  29. package/dist/index.js +1157 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/item.d.ts +94 -0
  32. package/dist/item.js +62 -0
  33. package/dist/item.js.map +1 -0
  34. package/dist/list.d.ts +163 -0
  35. package/dist/list.js +94 -0
  36. package/dist/list.js.map +1 -0
  37. package/dist/menu.d.ts +119 -0
  38. package/dist/menu.js +114 -0
  39. package/dist/menu.js.map +1 -0
  40. package/dist/navigation-bar.d.ts +91 -0
  41. package/dist/navigation-bar.js +48 -0
  42. package/dist/navigation-bar.js.map +1 -0
  43. package/dist/navigation-drawer.d.ts +86 -0
  44. package/dist/navigation-drawer.js +78 -0
  45. package/dist/navigation-drawer.js.map +1 -0
  46. package/dist/progress.d.ts +118 -0
  47. package/dist/progress.js +41 -0
  48. package/dist/progress.js.map +1 -0
  49. package/dist/radio.d.ts +56 -0
  50. package/dist/radio.js +47 -0
  51. package/dist/radio.js.map +1 -0
  52. package/dist/segmented-button.d.ts +83 -0
  53. package/dist/segmented-button.js +71 -0
  54. package/dist/segmented-button.js.map +1 -0
  55. package/dist/select.d.ts +125 -0
  56. package/dist/select.js +99 -0
  57. package/dist/select.js.map +1 -0
  58. package/dist/slider.d.ts +94 -0
  59. package/dist/slider.js +71 -0
  60. package/dist/slider.js.map +1 -0
  61. package/dist/snackbar.d.ts +108 -0
  62. package/dist/snackbar.js +57 -0
  63. package/dist/snackbar.js.map +1 -0
  64. package/dist/switch.d.ts +72 -0
  65. package/dist/switch.js +66 -0
  66. package/dist/switch.js.map +1 -0
  67. package/dist/tabs.d.ts +118 -0
  68. package/dist/tabs.js +97 -0
  69. package/dist/tabs.js.map +1 -0
  70. package/dist/textfield.d.ts +127 -0
  71. package/dist/textfield.js +83 -0
  72. package/dist/textfield.js.map +1 -0
  73. package/dist/tooltip.d.ts +61 -0
  74. package/dist/tooltip.js +52 -0
  75. package/dist/tooltip.js.map +1 -0
  76. package/dist/tv.d.ts +19 -0
  77. package/dist/tv.js +35 -0
  78. package/dist/tv.js.map +1 -0
  79. package/package.json +171 -0
  80. package/styles/preset.css +30 -0
  81. package/styles/theme.css +213 -0
  82. package/styles/tokens.css +361 -0
package/dist/select.js ADDED
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { createSelect } from '@m3-baseui/core';
3
+ import { tv as tv$1 } from 'tailwind-variants';
4
+
5
+ // src/select.ts
6
+ var TYPESCALE = [
7
+ "display-large",
8
+ "display-medium",
9
+ "display-small",
10
+ "headline-large",
11
+ "headline-medium",
12
+ "headline-small",
13
+ "title-large",
14
+ "title-medium",
15
+ "title-small",
16
+ "body-large",
17
+ "body-medium",
18
+ "body-small",
19
+ "label-large",
20
+ "label-medium",
21
+ "label-small"
22
+ ];
23
+ var tv = (options, config) => tv$1(options, {
24
+ ...config,
25
+ twMergeConfig: {
26
+ extend: {
27
+ classGroups: {
28
+ "font-size": [{ text: [...TYPESCALE] }]
29
+ }
30
+ }
31
+ }
32
+ });
33
+
34
+ // src/select.ts
35
+ var selectTv = tv({
36
+ slots: {
37
+ trigger: [
38
+ "group relative inline-flex items-center justify-between gap-2 box-border",
39
+ "h-14 min-w-[200px] px-4 rounded-extra-small border border-outline bg-transparent",
40
+ "text-on-surface text-body-large cursor-pointer outline-none text-left",
41
+ "transition-colors duration-150 ease-standard",
42
+ // focus/open = 3dp primary outline; padding drops 2px to keep content steady
43
+ "data-[popup-open]:border-primary data-[popup-open]:border-[3px] data-[popup-open]:px-[14px]",
44
+ "focus-visible:border-primary focus-visible:border-[3px] focus-visible:px-[14px]",
45
+ "data-[disabled]:border-on-surface/[0.12] data-[disabled]:text-on-surface/[0.38] data-[disabled]:pointer-events-none"
46
+ ],
47
+ value: "flex-1 truncate",
48
+ icon: "flex text-on-surface-variant transition-transform duration-150 group-data-[popup-open]:rotate-180 group-data-[disabled]:text-on-surface/[0.38]",
49
+ popup: [
50
+ "min-w-[var(--anchor-width)] max-h-[var(--available-height)] py-2 overflow-auto",
51
+ "bg-surface-container text-on-surface rounded-extra-small shadow-level2",
52
+ "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
53
+ "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
54
+ "data-[ending-style]:opacity-0",
55
+ "focus:outline-none"
56
+ ],
57
+ item: [
58
+ "group relative grid grid-cols-[24px_1fr_auto] items-center gap-2 h-12 px-3 overflow-hidden",
59
+ "cursor-pointer select-none outline-none text-body-large text-on-surface",
60
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
61
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
62
+ "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
63
+ "active:before:opacity-[var(--md-sys-state-pressed)]",
64
+ // M3 disabled (per-token, not a blanket fade): label + trailing supporting
65
+ // text on-surface/0.38, no state layer.
66
+ "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none",
67
+ "data-[disabled]:[&_[data-slot=select-trailing]]:text-on-surface/[0.38]",
68
+ // M3 trailing supporting text (e.g. meta) sits in the last column.
69
+ "[&_[data-slot=select-trailing]]:pl-4 [&_[data-slot=select-trailing]]:text-label-large [&_[data-slot=select-trailing]]:text-on-surface-variant"
70
+ ],
71
+ itemIndicator: "inline-flex items-center justify-center text-primary invisible group-data-[selected]:visible group-data-[disabled]:text-on-surface/[0.38]",
72
+ groupLabel: "px-3 py-2 text-label-small text-on-surface-variant",
73
+ // Sticky scroll affordances at the popup edges; surface-tinted with a chevron.
74
+ scrollUpArrow: [
75
+ "sticky top-0 z-[1] flex items-center justify-center h-6 cursor-default",
76
+ "bg-surface-container text-on-surface-variant [&>svg]:size-5"
77
+ ],
78
+ scrollDownArrow: [
79
+ "sticky bottom-0 z-[1] flex items-center justify-center h-6 cursor-default",
80
+ "bg-surface-container text-on-surface-variant [&>svg]:size-5"
81
+ ]
82
+ }
83
+ });
84
+ var s = selectTv();
85
+ var Select = createSelect({
86
+ trigger: s.trigger(),
87
+ value: s.value(),
88
+ icon: s.icon(),
89
+ popup: s.popup(),
90
+ item: s.item(),
91
+ itemIndicator: s.itemIndicator(),
92
+ groupLabel: s.groupLabel(),
93
+ scrollUpArrow: s.scrollUpArrow(),
94
+ scrollDownArrow: s.scrollDownArrow()
95
+ });
96
+
97
+ export { Select, selectTv };
98
+ //# sourceMappingURL=select.js.map
99
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tv.ts","../src/select.ts"],"names":["baseTv"],"mappings":";;;;;AAeA,IAAM,SAAA,GAAY;AAAA,EAChB,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAEO,IAAM,EAAA,GAAS,CAAC,OAAA,EAAS,MAAA,KAC9BA,KAAO,OAAA,EAAS;AAAA,EACd,GAAG,MAAA;AAAA,EACH,aAAA,EAAe;AAAA,IACb,MAAA,EAAQ;AAAA,MACN,WAAA,EAAa;AAAA,QACX,WAAA,EAAa,CAAC,EAAE,IAAA,EAAM,CAAC,GAAG,SAAS,GAAG;AAAA;AACxC;AACF;AAEJ,CAAC,CAAA;;;AC7BI,IAAM,WAAW,EAAA,CAAG;AAAA,EACzB,KAAA,EAAO;AAAA,IACL,OAAA,EAAS;AAAA,MACP,0EAAA;AAAA,MACA,kFAAA;AAAA,MACA,uEAAA;AAAA,MACA,8CAAA;AAAA;AAAA,MAEA,6FAAA;AAAA,MACA,iFAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO,iBAAA;AAAA,IACP,IAAA,EAAM,gJAAA;AAAA,IACN,KAAA,EAAO;AAAA,MACL,gFAAA;AAAA,MACA,wEAAA;AAAA,MACA,4FAAA;AAAA,MACA,gEAAA;AAAA,MACA,+BAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,4FAAA;AAAA,MACA,yEAAA;AAAA,MACA,4IAAA;AAAA,MACA,kDAAA;AAAA,MACA,+DAAA;AAAA,MACA,qDAAA;AAAA;AAAA;AAAA,MAGA,6GAAA;AAAA,MACA,wEAAA;AAAA;AAAA,MAEA;AAAA,KACF;AAAA,IACA,aAAA,EACE,2IAAA;AAAA,IACF,UAAA,EAAY,oDAAA;AAAA;AAAA,IAEZ,aAAA,EAAe;AAAA,MACb,wEAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,2EAAA;AAAA,MACA;AAAA;AACF;AAEJ,CAAC;AAED,IAAM,IAAI,QAAA,EAAS;AACZ,IAAM,SAAS,YAAA,CAAa;AAAA,EACjC,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,EACnB,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,aAAA,EAAe,EAAE,aAAA,EAAc;AAAA,EAC/B,UAAA,EAAY,EAAE,UAAA,EAAW;AAAA,EACzB,aAAA,EAAe,EAAE,aAAA,EAAc;AAAA,EAC/B,eAAA,EAAiB,EAAE,eAAA;AACrB,CAAC","file":"select.js","sourcesContent":["/**\n * tv.ts — a tailwind-variants factory pre-configured for the M3 typescale.\n *\n * The Tailwind v4 preset exposes the 15 typescale roles as `text-<role>`\n * font-size utilities (e.g. `text-body-small`, `text-label-large`). Stock\n * tailwind-merge does not know these custom names, so it groups them with the\n * `text-<color>` utilities and drops one when a slot sets both a color *and* a\n * typescale (the common M3 case). That silently strips either the color or the\n * type, breaking token compliance.\n *\n * Teaching tailwind-merge that the typescale names belong to the `font-size`\n * group keeps color and type independent, so both survive the merge.\n */\nimport { type TV, tv as baseTv } from 'tailwind-variants';\n\nconst TYPESCALE = [\n 'display-large',\n 'display-medium',\n 'display-small',\n 'headline-large',\n 'headline-medium',\n 'headline-small',\n 'title-large',\n 'title-medium',\n 'title-small',\n 'body-large',\n 'body-medium',\n 'body-small',\n 'label-large',\n 'label-medium',\n 'label-small',\n] as const;\n\nexport const tv: TV = (options, config) =>\n baseTv(options, {\n ...config,\n twMergeConfig: {\n extend: {\n classGroups: {\n 'font-size': [{ text: [...TYPESCALE] }],\n },\n },\n },\n });\n","/**\n * select.ts — Tailwind classes for the M3 Select.\n *\n * Trigger = outlined field (56dp; 3dp primary border when open/focused, per the\n * M3 outlined-field focus-outline-width). Popup = M3 menu surface sized to the\n * anchor. Items mirror the Menu item (state layer + ripple) with a leading check\n * indicator. Same DOM as the VE build.\n *\n * Disabled follows the M3 outlined-field per-token opacities (not a blanket\n * fade): outline on-surface/0.12, label/value + icon on-surface/0.38.\n */\nimport { createSelect } from '@m3-baseui/core';\nimport { tv } from './tv';\n\nexport const selectTv = tv({\n slots: {\n trigger: [\n 'group relative inline-flex items-center justify-between gap-2 box-border',\n 'h-14 min-w-[200px] px-4 rounded-extra-small border border-outline bg-transparent',\n 'text-on-surface text-body-large cursor-pointer outline-none text-left',\n 'transition-colors duration-150 ease-standard',\n // focus/open = 3dp primary outline; padding drops 2px to keep content steady\n 'data-[popup-open]:border-primary data-[popup-open]:border-[3px] data-[popup-open]:px-[14px]',\n 'focus-visible:border-primary focus-visible:border-[3px] focus-visible:px-[14px]',\n 'data-[disabled]:border-on-surface/[0.12] data-[disabled]:text-on-surface/[0.38] data-[disabled]:pointer-events-none',\n ],\n value: 'flex-1 truncate',\n icon: 'flex text-on-surface-variant transition-transform duration-150 group-data-[popup-open]:rotate-180 group-data-[disabled]:text-on-surface/[0.38]',\n popup: [\n 'min-w-[var(--anchor-width)] max-h-[var(--available-height)] py-2 overflow-auto',\n 'bg-surface-container text-on-surface rounded-extra-small shadow-level2',\n 'origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard',\n 'data-[starting-style]:opacity-0 data-[starting-style]:scale-95',\n 'data-[ending-style]:opacity-0',\n 'focus:outline-none',\n ],\n item: [\n 'group relative grid grid-cols-[24px_1fr_auto] items-center gap-2 h-12 px-3 overflow-hidden',\n 'cursor-pointer select-none outline-none text-body-large text-on-surface',\n 'before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100',\n 'hover:before:opacity-[var(--md-sys-state-hover)]',\n 'data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]',\n 'active:before:opacity-[var(--md-sys-state-pressed)]',\n // M3 disabled (per-token, not a blanket fade): label + trailing supporting\n // text on-surface/0.38, no state layer.\n 'data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none',\n 'data-[disabled]:[&_[data-slot=select-trailing]]:text-on-surface/[0.38]',\n // M3 trailing supporting text (e.g. meta) sits in the last column.\n '[&_[data-slot=select-trailing]]:pl-4 [&_[data-slot=select-trailing]]:text-label-large [&_[data-slot=select-trailing]]:text-on-surface-variant',\n ],\n itemIndicator:\n 'inline-flex items-center justify-center text-primary invisible group-data-[selected]:visible group-data-[disabled]:text-on-surface/[0.38]',\n groupLabel: 'px-3 py-2 text-label-small text-on-surface-variant',\n // Sticky scroll affordances at the popup edges; surface-tinted with a chevron.\n scrollUpArrow: [\n 'sticky top-0 z-[1] flex items-center justify-center h-6 cursor-default',\n 'bg-surface-container text-on-surface-variant [&>svg]:size-5',\n ],\n scrollDownArrow: [\n 'sticky bottom-0 z-[1] flex items-center justify-center h-6 cursor-default',\n 'bg-surface-container text-on-surface-variant [&>svg]:size-5',\n ],\n },\n});\n\nconst s = selectTv();\nexport const Select = createSelect({\n trigger: s.trigger(),\n value: s.value(),\n icon: s.icon(),\n popup: s.popup(),\n item: s.item(),\n itemIndicator: s.itemIndicator(),\n groupLabel: s.groupLabel(),\n scrollUpArrow: s.scrollUpArrow(),\n scrollDownArrow: s.scrollDownArrow(),\n});\n"]}
@@ -0,0 +1,94 @@
1
+ import * as react from 'react';
2
+ import * as _base_ui_react from '@base-ui/react';
3
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
4
+ import * as tailwind_variants from 'tailwind-variants';
5
+
6
+ declare const sliderTv: tailwind_variants.TVReturnType<{
7
+ [key: string]: {
8
+ [key: string]: tailwind_variants.ClassValue | {
9
+ value?: tailwind_variants.ClassValue;
10
+ track?: tailwind_variants.ClassValue;
11
+ root?: tailwind_variants.ClassValue;
12
+ indicator?: tailwind_variants.ClassValue;
13
+ thumb?: tailwind_variants.ClassValue;
14
+ control?: tailwind_variants.ClassValue;
15
+ };
16
+ };
17
+ } | {
18
+ [x: string]: {
19
+ [x: string]: tailwind_variants.ClassValue | {
20
+ value?: tailwind_variants.ClassValue;
21
+ track?: tailwind_variants.ClassValue;
22
+ root?: tailwind_variants.ClassValue;
23
+ indicator?: tailwind_variants.ClassValue;
24
+ thumb?: tailwind_variants.ClassValue;
25
+ control?: tailwind_variants.ClassValue;
26
+ };
27
+ };
28
+ } | {}, {
29
+ root: string;
30
+ control: string;
31
+ track: string[];
32
+ indicator: string[];
33
+ thumb: string[];
34
+ value: string;
35
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
36
+ [key: string]: {
37
+ [key: string]: tailwind_variants.ClassValue | {
38
+ value?: tailwind_variants.ClassValue;
39
+ track?: tailwind_variants.ClassValue;
40
+ root?: tailwind_variants.ClassValue;
41
+ indicator?: tailwind_variants.ClassValue;
42
+ thumb?: tailwind_variants.ClassValue;
43
+ control?: tailwind_variants.ClassValue;
44
+ };
45
+ };
46
+ } | {}>, {
47
+ [key: string]: {
48
+ [key: string]: tailwind_variants.ClassValue | {
49
+ value?: tailwind_variants.ClassValue;
50
+ track?: tailwind_variants.ClassValue;
51
+ root?: tailwind_variants.ClassValue;
52
+ indicator?: tailwind_variants.ClassValue;
53
+ thumb?: tailwind_variants.ClassValue;
54
+ control?: tailwind_variants.ClassValue;
55
+ };
56
+ };
57
+ } | {}, {
58
+ root: string;
59
+ control: string;
60
+ track: string[];
61
+ indicator: string[];
62
+ thumb: string[];
63
+ value: string;
64
+ }, tailwind_variants.TVReturnType<unknown, {
65
+ root: string;
66
+ control: string;
67
+ track: string[];
68
+ indicator: string[];
69
+ thumb: string[];
70
+ value: string;
71
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
72
+ [key: string]: {
73
+ [key: string]: tailwind_variants.ClassValue | {
74
+ value?: tailwind_variants.ClassValue;
75
+ track?: tailwind_variants.ClassValue;
76
+ root?: tailwind_variants.ClassValue;
77
+ indicator?: tailwind_variants.ClassValue;
78
+ thumb?: tailwind_variants.ClassValue;
79
+ control?: tailwind_variants.ClassValue;
80
+ };
81
+ };
82
+ } | {}>, unknown, unknown, undefined>>;
83
+ declare const Slider: {
84
+ Root: react.ForwardRefExoticComponent<Omit<_base_ui_react.SliderRoot.Props<number | readonly number[]> & {
85
+ ref?: React.Ref<HTMLDivElement> | undefined;
86
+ }, "ref"> & react.RefAttributes<unknown>>;
87
+ Control: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderControlProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
88
+ Track: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderTrackProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
89
+ Indicator: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderIndicatorProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
90
+ Thumb: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderThumbProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
91
+ Value: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderValueProps, "ref"> & react.RefAttributes<HTMLOutputElement>, "ref"> & react.RefAttributes<unknown>>;
92
+ };
93
+
94
+ export { Slider, sliderTv };
package/dist/slider.js ADDED
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { createSlider } from '@m3-baseui/core';
3
+ import { tv as tv$1 } from 'tailwind-variants';
4
+
5
+ // src/slider.ts
6
+ var TYPESCALE = [
7
+ "display-large",
8
+ "display-medium",
9
+ "display-small",
10
+ "headline-large",
11
+ "headline-medium",
12
+ "headline-small",
13
+ "title-large",
14
+ "title-medium",
15
+ "title-small",
16
+ "body-large",
17
+ "body-medium",
18
+ "body-small",
19
+ "label-large",
20
+ "label-medium",
21
+ "label-small"
22
+ ];
23
+ var tv = (options, config) => tv$1(options, {
24
+ ...config,
25
+ twMergeConfig: {
26
+ extend: {
27
+ classGroups: {
28
+ "font-size": [{ text: [...TYPESCALE] }]
29
+ }
30
+ }
31
+ }
32
+ });
33
+
34
+ // src/slider.ts
35
+ var sliderTv = tv({
36
+ slots: {
37
+ root: "group relative flex items-center select-none w-full touch-none",
38
+ control: "relative flex items-center w-full h-10",
39
+ track: [
40
+ "relative w-full h-1 rounded-full bg-surface-container-highest",
41
+ "group-data-[disabled]:bg-on-surface/[0.12]"
42
+ ],
43
+ indicator: [
44
+ "absolute h-1 rounded-full bg-primary",
45
+ "group-data-[disabled]:bg-on-surface/[0.38]"
46
+ ],
47
+ thumb: [
48
+ "relative size-5 rounded-full bg-primary outline-none",
49
+ 'before:content-[""] before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2',
50
+ "before:size-10 before:rounded-full before:bg-primary before:opacity-0 before:transition-opacity before:duration-100",
51
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
52
+ "focus-visible:before:opacity-[var(--md-sys-state-focus)]",
53
+ "data-[dragging]:before:opacity-[var(--md-sys-state-pressed)]",
54
+ "group-data-[disabled]:bg-on-surface/[0.38]"
55
+ ],
56
+ value: "text-label-large text-on-surface-variant tabular-nums"
57
+ }
58
+ });
59
+ var s = sliderTv();
60
+ var Slider = createSlider({
61
+ root: s.root(),
62
+ control: s.control(),
63
+ track: s.track(),
64
+ indicator: s.indicator(),
65
+ thumb: s.thumb(),
66
+ value: s.value()
67
+ });
68
+
69
+ export { Slider, sliderTv };
70
+ //# sourceMappingURL=slider.js.map
71
+ //# sourceMappingURL=slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tv.ts","../src/slider.ts"],"names":["baseTv"],"mappings":";;;;;AAeA,IAAM,SAAA,GAAY;AAAA,EAChB,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAEO,IAAM,EAAA,GAAS,CAAC,OAAA,EAAS,MAAA,KAC9BA,KAAO,OAAA,EAAS;AAAA,EACd,GAAG,MAAA;AAAA,EACH,aAAA,EAAe;AAAA,IACb,MAAA,EAAQ;AAAA,MACN,WAAA,EAAa;AAAA,QACX,WAAA,EAAa,CAAC,EAAE,IAAA,EAAM,CAAC,GAAG,SAAS,GAAG;AAAA;AACxC;AACF;AAEJ,CAAC,CAAA;;;AC9BI,IAAM,WAAW,EAAA,CAAG;AAAA,EACzB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,gEAAA;AAAA,IACN,OAAA,EAAS,wCAAA;AAAA,IACT,KAAA,EAAO;AAAA,MACL,+DAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA,EAAW;AAAA,MACT,sCAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO;AAAA,MACL,sDAAA;AAAA,MACA,oHAAA;AAAA,MACA,qHAAA;AAAA,MACA,kDAAA;AAAA,MACA,0DAAA;AAAA,MACA,8DAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO;AAAA;AAEX,CAAC;AAED,IAAM,IAAI,QAAA,EAAS;AACZ,IAAM,SAAS,YAAA,CAAa;AAAA,EACjC,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,EACnB,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,SAAA,EAAW,EAAE,SAAA,EAAU;AAAA,EACvB,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,KAAA,EAAO,EAAE,KAAA;AACX,CAAC","file":"slider.js","sourcesContent":["/**\n * tv.ts — a tailwind-variants factory pre-configured for the M3 typescale.\n *\n * The Tailwind v4 preset exposes the 15 typescale roles as `text-<role>`\n * font-size utilities (e.g. `text-body-small`, `text-label-large`). Stock\n * tailwind-merge does not know these custom names, so it groups them with the\n * `text-<color>` utilities and drops one when a slot sets both a color *and* a\n * typescale (the common M3 case). That silently strips either the color or the\n * type, breaking token compliance.\n *\n * Teaching tailwind-merge that the typescale names belong to the `font-size`\n * group keeps color and type independent, so both survive the merge.\n */\nimport { type TV, tv as baseTv } from 'tailwind-variants';\n\nconst TYPESCALE = [\n 'display-large',\n 'display-medium',\n 'display-small',\n 'headline-large',\n 'headline-medium',\n 'headline-small',\n 'title-large',\n 'title-medium',\n 'title-small',\n 'body-large',\n 'body-medium',\n 'body-small',\n 'label-large',\n 'label-medium',\n 'label-small',\n] as const;\n\nexport const tv: TV = (options, config) =>\n baseTv(options, {\n ...config,\n twMergeConfig: {\n extend: {\n classGroups: {\n 'font-size': [{ text: [...TYPESCALE] }],\n },\n },\n },\n });\n","/**\n * slider.ts — Tailwind classes for the M3 Slider.\n *\n * 4dp rail (surface-container-highest) with a primary active indicator and a\n * 20dp primary thumb carrying a 40dp circular state layer (hover/focus/drag).\n *\n * Disabled follows M3 per-token opacities (not a blanket fade): inactive track\n * on-surface/0.12, active track + handle on-surface/0.38. The root carries a\n * `group` so the descendant parts can react to Base UI's data-disabled on Root.\n */\nimport { createSlider } from '@m3-baseui/core';\nimport { tv } from './tv';\n\nexport const sliderTv = tv({\n slots: {\n root: 'group relative flex items-center select-none w-full touch-none',\n control: 'relative flex items-center w-full h-10',\n track: [\n 'relative w-full h-1 rounded-full bg-surface-container-highest',\n 'group-data-[disabled]:bg-on-surface/[0.12]',\n ],\n indicator: [\n 'absolute h-1 rounded-full bg-primary',\n 'group-data-[disabled]:bg-on-surface/[0.38]',\n ],\n thumb: [\n 'relative size-5 rounded-full bg-primary outline-none',\n 'before:content-[\"\"] before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2',\n 'before:size-10 before:rounded-full before:bg-primary before:opacity-0 before:transition-opacity before:duration-100',\n 'hover:before:opacity-[var(--md-sys-state-hover)]',\n 'focus-visible:before:opacity-[var(--md-sys-state-focus)]',\n 'data-[dragging]:before:opacity-[var(--md-sys-state-pressed)]',\n 'group-data-[disabled]:bg-on-surface/[0.38]',\n ],\n value: 'text-label-large text-on-surface-variant tabular-nums',\n },\n});\n\nconst s = sliderTv();\nexport const Slider = createSlider({\n root: s.root(),\n control: s.control(),\n track: s.track(),\n indicator: s.indicator(),\n thumb: s.thumb(),\n value: s.value(),\n});\n"]}
@@ -0,0 +1,108 @@
1
+ import * as react from 'react';
2
+ import * as _base_ui_react from '@base-ui/react';
3
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
4
+ import * as tailwind_variants from 'tailwind-variants';
5
+ export { useSnackbar } from '@m3-baseui/core';
6
+
7
+ declare const snackbarTv: tailwind_variants.TVReturnType<{
8
+ [key: string]: {
9
+ [key: string]: tailwind_variants.ClassValue | {
10
+ title?: tailwind_variants.ClassValue;
11
+ content?: tailwind_variants.ClassValue;
12
+ close?: tailwind_variants.ClassValue;
13
+ action?: tailwind_variants.ClassValue;
14
+ description?: tailwind_variants.ClassValue;
15
+ root?: tailwind_variants.ClassValue;
16
+ viewport?: tailwind_variants.ClassValue;
17
+ };
18
+ };
19
+ } | {
20
+ [x: string]: {
21
+ [x: string]: tailwind_variants.ClassValue | {
22
+ title?: tailwind_variants.ClassValue;
23
+ content?: tailwind_variants.ClassValue;
24
+ close?: tailwind_variants.ClassValue;
25
+ action?: tailwind_variants.ClassValue;
26
+ description?: tailwind_variants.ClassValue;
27
+ root?: tailwind_variants.ClassValue;
28
+ viewport?: tailwind_variants.ClassValue;
29
+ };
30
+ };
31
+ } | {}, {
32
+ viewport: string[];
33
+ root: string[];
34
+ content: string;
35
+ title: string;
36
+ description: string;
37
+ action: string[];
38
+ close: string[];
39
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
40
+ [key: string]: {
41
+ [key: string]: tailwind_variants.ClassValue | {
42
+ title?: tailwind_variants.ClassValue;
43
+ content?: tailwind_variants.ClassValue;
44
+ close?: tailwind_variants.ClassValue;
45
+ action?: tailwind_variants.ClassValue;
46
+ description?: tailwind_variants.ClassValue;
47
+ root?: tailwind_variants.ClassValue;
48
+ viewport?: tailwind_variants.ClassValue;
49
+ };
50
+ };
51
+ } | {}>, {
52
+ [key: string]: {
53
+ [key: string]: tailwind_variants.ClassValue | {
54
+ title?: tailwind_variants.ClassValue;
55
+ content?: tailwind_variants.ClassValue;
56
+ close?: tailwind_variants.ClassValue;
57
+ action?: tailwind_variants.ClassValue;
58
+ description?: tailwind_variants.ClassValue;
59
+ root?: tailwind_variants.ClassValue;
60
+ viewport?: tailwind_variants.ClassValue;
61
+ };
62
+ };
63
+ } | {}, {
64
+ viewport: string[];
65
+ root: string[];
66
+ content: string;
67
+ title: string;
68
+ description: string;
69
+ action: string[];
70
+ close: string[];
71
+ }, tailwind_variants.TVReturnType<unknown, {
72
+ viewport: string[];
73
+ root: string[];
74
+ content: string;
75
+ title: string;
76
+ description: string;
77
+ action: string[];
78
+ close: string[];
79
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
80
+ [key: string]: {
81
+ [key: string]: tailwind_variants.ClassValue | {
82
+ title?: tailwind_variants.ClassValue;
83
+ content?: tailwind_variants.ClassValue;
84
+ close?: tailwind_variants.ClassValue;
85
+ action?: tailwind_variants.ClassValue;
86
+ description?: tailwind_variants.ClassValue;
87
+ root?: tailwind_variants.ClassValue;
88
+ viewport?: tailwind_variants.ClassValue;
89
+ };
90
+ };
91
+ } | {}>, unknown, unknown, undefined>>;
92
+ declare const Snackbar: {
93
+ Provider: react.FC<_base_ui_react.ToastProviderProps>;
94
+ Portal: react.ComponentType<react.HTMLAttributes<HTMLDivElement> & {
95
+ container?: HTMLElement | ShadowRoot | null | React.RefObject<HTMLElement | ShadowRoot | null>;
96
+ keepMounted?: boolean;
97
+ render?: React.ReactElement | ((props: Record<string, unknown>, state: Record<string, unknown>) => React.ReactElement);
98
+ }>;
99
+ Viewport: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastViewportProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
100
+ Root: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastRootProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
101
+ Content: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastContentProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
102
+ Title: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastTitleProps, "ref"> & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<unknown>>;
103
+ Description: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastDescriptionProps, "ref"> & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<unknown>>;
104
+ Action: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastActionProps, "ref"> & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<unknown>>;
105
+ Close: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ToastCloseProps, "ref"> & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<unknown>>;
106
+ };
107
+
108
+ export { Snackbar, snackbarTv };
@@ -0,0 +1,57 @@
1
+ "use client";
2
+ import { createSnackbar } from '@m3-baseui/core';
3
+ export { useSnackbar } from '@m3-baseui/core';
4
+ import { tv } from 'tailwind-variants';
5
+
6
+ // src/snackbar.ts
7
+ var snackbarTv = tv({
8
+ slots: {
9
+ viewport: [
10
+ "fixed bottom-4 left-1/2 -translate-x-1/2 z-50",
11
+ "flex flex-col gap-2 w-[min(560px,calc(100vw-32px))]"
12
+ ],
13
+ root: [
14
+ "relative flex items-center gap-2 min-h-12 box-border pl-4 pr-2 py-2",
15
+ "rounded-extra-small bg-inverse-surface text-inverse-on-surface shadow-level3",
16
+ "text-body-medium",
17
+ "transition-[opacity,transform] duration-200 ease-emphasized",
18
+ "data-[starting-style]:opacity-0 data-[starting-style]:translate-y-2",
19
+ "data-[ending-style]:opacity-0"
20
+ ],
21
+ content: "flex flex-col flex-1 min-w-0 gap-0.5",
22
+ title: "text-body-medium",
23
+ description: "text-body-small opacity-90",
24
+ action: [
25
+ "relative inline-flex items-center justify-center shrink-0 h-9 px-3 overflow-hidden",
26
+ "rounded-extra-small bg-transparent border-0 cursor-pointer outline-none",
27
+ "text-inverse-primary text-label-large",
28
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
29
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
30
+ "focus-visible:before:opacity-[var(--md-sys-state-focus)]",
31
+ "active:before:opacity-[var(--md-sys-state-pressed)]"
32
+ ],
33
+ close: [
34
+ "relative inline-flex items-center justify-center shrink-0 size-8 rounded-full overflow-hidden",
35
+ "bg-transparent border-0 cursor-pointer text-inverse-on-surface outline-none",
36
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
37
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
38
+ "focus-visible:before:opacity-[var(--md-sys-state-focus)]",
39
+ "active:before:opacity-[var(--md-sys-state-pressed)]",
40
+ "data-[pressed]:before:opacity-[var(--md-sys-state-pressed)]"
41
+ ]
42
+ }
43
+ });
44
+ var s = snackbarTv();
45
+ var Snackbar = createSnackbar({
46
+ viewport: s.viewport(),
47
+ root: s.root(),
48
+ content: s.content(),
49
+ title: s.title(),
50
+ description: s.description(),
51
+ action: s.action(),
52
+ close: s.close()
53
+ });
54
+
55
+ export { Snackbar, snackbarTv };
56
+ //# sourceMappingURL=snackbar.js.map
57
+ //# sourceMappingURL=snackbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/snackbar.ts"],"names":[],"mappings":";;;;;;AAYO,IAAM,aAAa,EAAA,CAAG;AAAA,EAC3B,KAAA,EAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,+CAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,qEAAA;AAAA,MACA,8EAAA;AAAA,MACA,kBAAA;AAAA,MACA,6DAAA;AAAA,MACA,qEAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,OAAA,EAAS,sCAAA;AAAA,IACT,KAAA,EAAO,kBAAA;AAAA,IACP,WAAA,EAAa,4BAAA;AAAA,IACb,MAAA,EAAQ;AAAA,MACN,oFAAA;AAAA,MACA,yEAAA;AAAA,MACA,uCAAA;AAAA,MACA,4IAAA;AAAA,MACA,kDAAA;AAAA,MACA,0DAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO;AAAA,MACL,+FAAA;AAAA,MACA,6EAAA;AAAA,MACA,4IAAA;AAAA,MACA,kDAAA;AAAA,MACA,0DAAA;AAAA,MACA,qDAAA;AAAA,MACA;AAAA;AACF;AAEJ,CAAC;AAED,IAAM,IAAI,UAAA,EAAW;AACd,IAAM,WAAW,cAAA,CAAe;AAAA,EACrC,QAAA,EAAU,EAAE,QAAA,EAAS;AAAA,EACrB,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,EACnB,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,WAAA,EAAa,EAAE,WAAA,EAAY;AAAA,EAC3B,MAAA,EAAQ,EAAE,MAAA,EAAO;AAAA,EACjB,KAAA,EAAO,EAAE,KAAA;AACX,CAAC","file":"snackbar.js","sourcesContent":["/**\n * snackbar.ts — tailwind-variants slots for the M3 Snackbar.\n *\n * Inverse-surface container, extra-small corners, elevation level3. The Action\n * is an inverse-primary text button with a state layer + ripple. Enter/exit key\n * off Toast's `data-starting-style` / `data-ending-style`. Same DOM as VE.\n */\nimport { createSnackbar } from '@m3-baseui/core';\nimport { tv } from 'tailwind-variants';\n\nexport { useSnackbar } from '@m3-baseui/core';\n\nexport const snackbarTv = tv({\n slots: {\n viewport: [\n 'fixed bottom-4 left-1/2 -translate-x-1/2 z-50',\n 'flex flex-col gap-2 w-[min(560px,calc(100vw-32px))]',\n ],\n root: [\n 'relative flex items-center gap-2 min-h-12 box-border pl-4 pr-2 py-2',\n 'rounded-extra-small bg-inverse-surface text-inverse-on-surface shadow-level3',\n 'text-body-medium',\n 'transition-[opacity,transform] duration-200 ease-emphasized',\n 'data-[starting-style]:opacity-0 data-[starting-style]:translate-y-2',\n 'data-[ending-style]:opacity-0',\n ],\n content: 'flex flex-col flex-1 min-w-0 gap-0.5',\n title: 'text-body-medium',\n description: 'text-body-small opacity-90',\n action: [\n 'relative inline-flex items-center justify-center shrink-0 h-9 px-3 overflow-hidden',\n 'rounded-extra-small bg-transparent border-0 cursor-pointer outline-none',\n 'text-inverse-primary text-label-large',\n 'before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100',\n 'hover:before:opacity-[var(--md-sys-state-hover)]',\n 'focus-visible:before:opacity-[var(--md-sys-state-focus)]',\n 'active:before:opacity-[var(--md-sys-state-pressed)]',\n ],\n close: [\n 'relative inline-flex items-center justify-center shrink-0 size-8 rounded-full overflow-hidden',\n 'bg-transparent border-0 cursor-pointer text-inverse-on-surface outline-none',\n 'before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100',\n 'hover:before:opacity-[var(--md-sys-state-hover)]',\n 'focus-visible:before:opacity-[var(--md-sys-state-focus)]',\n 'active:before:opacity-[var(--md-sys-state-pressed)]',\n 'data-[pressed]:before:opacity-[var(--md-sys-state-pressed)]',\n ],\n },\n});\n\nconst s = snackbarTv();\nexport const Snackbar = createSnackbar({\n viewport: s.viewport(),\n root: s.root(),\n content: s.content(),\n title: s.title(),\n description: s.description(),\n action: s.action(),\n close: s.close(),\n});\n"]}
@@ -0,0 +1,72 @@
1
+ import * as _m3_baseui_core from '@m3-baseui/core';
2
+ import * as react from 'react';
3
+ import * as _base_ui_react from '@base-ui/react';
4
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
5
+ import * as tailwind_variants from 'tailwind-variants';
6
+
7
+ declare const switchTv: tailwind_variants.TVReturnType<{
8
+ [key: string]: {
9
+ [key: string]: tailwind_variants.ClassValue | {
10
+ root?: tailwind_variants.ClassValue;
11
+ thumb?: tailwind_variants.ClassValue;
12
+ iconChecked?: tailwind_variants.ClassValue;
13
+ iconUnchecked?: tailwind_variants.ClassValue;
14
+ };
15
+ };
16
+ } | {
17
+ [x: string]: {
18
+ [x: string]: tailwind_variants.ClassValue | {
19
+ root?: tailwind_variants.ClassValue;
20
+ thumb?: tailwind_variants.ClassValue;
21
+ iconChecked?: tailwind_variants.ClassValue;
22
+ iconUnchecked?: tailwind_variants.ClassValue;
23
+ };
24
+ };
25
+ } | {}, {
26
+ root: string[];
27
+ thumb: string[];
28
+ iconChecked: string[];
29
+ iconUnchecked: string[];
30
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
31
+ [key: string]: {
32
+ [key: string]: tailwind_variants.ClassValue | {
33
+ root?: tailwind_variants.ClassValue;
34
+ thumb?: tailwind_variants.ClassValue;
35
+ iconChecked?: tailwind_variants.ClassValue;
36
+ iconUnchecked?: tailwind_variants.ClassValue;
37
+ };
38
+ };
39
+ } | {}>, {
40
+ [key: string]: {
41
+ [key: string]: tailwind_variants.ClassValue | {
42
+ root?: tailwind_variants.ClassValue;
43
+ thumb?: tailwind_variants.ClassValue;
44
+ iconChecked?: tailwind_variants.ClassValue;
45
+ iconUnchecked?: tailwind_variants.ClassValue;
46
+ };
47
+ };
48
+ } | {}, {
49
+ root: string[];
50
+ thumb: string[];
51
+ iconChecked: string[];
52
+ iconUnchecked: string[];
53
+ }, tailwind_variants.TVReturnType<unknown, {
54
+ root: string[];
55
+ thumb: string[];
56
+ iconChecked: string[];
57
+ iconUnchecked: string[];
58
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
59
+ [key: string]: {
60
+ [key: string]: tailwind_variants.ClassValue | {
61
+ root?: tailwind_variants.ClassValue;
62
+ thumb?: tailwind_variants.ClassValue;
63
+ iconChecked?: tailwind_variants.ClassValue;
64
+ iconUnchecked?: tailwind_variants.ClassValue;
65
+ };
66
+ };
67
+ } | {}>, unknown, unknown, undefined>>;
68
+ declare const Switch: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SwitchRootProps, "ref"> & react.RefAttributes<HTMLElement>, "ref"> & {
69
+ icons?: _m3_baseui_core.SwitchIcons;
70
+ } & react.RefAttributes<HTMLElement>>;
71
+
72
+ export { Switch, switchTv };
package/dist/switch.js ADDED
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ import { createSwitch } from '@m3-baseui/core';
3
+ import { tv } from 'tailwind-variants';
4
+
5
+ // src/switch.ts
6
+ var switchTv = tv({
7
+ slots: {
8
+ root: [
9
+ "group relative inline-flex shrink-0 w-[52px] h-8 rounded-full border-2 box-border cursor-pointer",
10
+ "bg-surface-container-highest border-outline",
11
+ "transition-colors duration-200 ease-standard",
12
+ "data-[checked]:bg-primary data-[checked]:border-primary",
13
+ "focus-visible:outline-[3px] focus-visible:outline-offset-2 focus-visible:outline-secondary",
14
+ "data-[disabled]:pointer-events-none",
15
+ // M3 disabled: faint track + outline (unselected); on-surface/12 track,
16
+ // no outline (selected). Not a blanket element opacity.
17
+ "data-[disabled]:bg-surface-container-highest/12 data-[disabled]:border-on-surface/12",
18
+ "data-[disabled]:data-[checked]:bg-on-surface/12 data-[disabled]:data-[checked]:border-transparent"
19
+ ],
20
+ thumb: [
21
+ "absolute top-1/2 -translate-y-1/2 left-[6px] size-4 rounded-full pointer-events-none",
22
+ "flex items-center justify-center",
23
+ "bg-outline text-on-surface",
24
+ "transition-all duration-200 ease-standard",
25
+ "data-[checked]:left-[22px] data-[checked]:size-6 data-[checked]:bg-on-primary data-[checked]:text-primary",
26
+ // M3 with-icon: the unchecked handle grows to 24dp to fit its icon
27
+ "data-[with-icon]:data-[unchecked]:left-1 data-[with-icon]:data-[unchecked]:size-6",
28
+ // M3 handle interaction colors: unselected outline→on-surface-variant,
29
+ // selected on-primary→primary-container on hover/focus/press
30
+ "group-hover:bg-on-surface-variant group-focus-visible:bg-on-surface-variant group-active:bg-on-surface-variant",
31
+ "group-hover:data-[checked]:bg-primary-container group-focus-visible:data-[checked]:bg-primary-container group-active:data-[checked]:bg-primary-container",
32
+ // M3 squish: handle grows to 28px while pressed, staying on its side
33
+ "group-active:left-0 group-active:size-7",
34
+ "group-active:data-[checked]:left-5 group-active:data-[checked]:size-7",
35
+ // M3 disabled handle: on-surface/38 (unselected), surface (selected)
36
+ "group-data-[disabled]:bg-on-surface/38",
37
+ "group-data-[disabled]:data-[checked]:bg-surface",
38
+ // 40dp circular state layer centered on the thumb
39
+ 'before:content-[""] before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2',
40
+ "before:size-10 before:rounded-full before:bg-current before:opacity-0 before:transition-opacity before:duration-100",
41
+ "group-hover:before:opacity-[var(--md-sys-state-hover)]",
42
+ "group-focus-visible:before:opacity-[var(--md-sys-state-focus)]",
43
+ "group-active:before:opacity-[var(--md-sys-state-pressed)]"
44
+ ],
45
+ // Handle icons (16dp). Both stay mounted; the root's data-checked reveals one.
46
+ iconChecked: [
47
+ "hidden group-data-[checked]:inline-flex items-center justify-center",
48
+ "text-on-primary-container [&>svg]:size-4"
49
+ ],
50
+ iconUnchecked: [
51
+ "inline-flex group-data-[checked]:hidden items-center justify-center",
52
+ "text-surface-container-highest [&>svg]:size-4"
53
+ ]
54
+ }
55
+ });
56
+ var s = switchTv();
57
+ var Switch = createSwitch({
58
+ root: s.root(),
59
+ thumb: s.thumb(),
60
+ iconChecked: s.iconChecked(),
61
+ iconUnchecked: s.iconUnchecked()
62
+ });
63
+
64
+ export { Switch, switchTv };
65
+ //# sourceMappingURL=switch.js.map
66
+ //# sourceMappingURL=switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/switch.ts"],"names":[],"mappings":";;;;;AAUO,IAAM,WAAW,EAAA,CAAG;AAAA,EACzB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM;AAAA,MACJ,kGAAA;AAAA,MACA,6CAAA;AAAA,MACA,8CAAA;AAAA,MACA,yDAAA;AAAA,MACA,4FAAA;AAAA,MACA,qCAAA;AAAA;AAAA;AAAA,MAGA,sFAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO;AAAA,MACL,sFAAA;AAAA,MACA,kCAAA;AAAA,MACA,4BAAA;AAAA,MACA,2CAAA;AAAA,MACA,2GAAA;AAAA;AAAA,MAEA,mFAAA;AAAA;AAAA;AAAA,MAGA,gHAAA;AAAA,MACA,0JAAA;AAAA;AAAA,MAEA,yCAAA;AAAA,MACA,uEAAA;AAAA;AAAA,MAEA,wCAAA;AAAA,MACA,iDAAA;AAAA;AAAA,MAEA,oHAAA;AAAA,MACA,qHAAA;AAAA,MACA,wDAAA;AAAA,MACA,gEAAA;AAAA,MACA;AAAA,KACF;AAAA;AAAA,IAEA,WAAA,EAAa;AAAA,MACX,qEAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,aAAA,EAAe;AAAA,MACb,qEAAA;AAAA,MACA;AAAA;AACF;AAEJ,CAAC;AAED,IAAM,IAAI,QAAA,EAAS;AACZ,IAAM,SAAS,YAAA,CAAa;AAAA,EACjC,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,EACf,WAAA,EAAa,EAAE,WAAA,EAAY;AAAA,EAC3B,aAAA,EAAe,EAAE,aAAA;AACnB,CAAC","file":"switch.js","sourcesContent":["/**\n * switch.ts — tailwind-variants slots for the M3 Switch.\n *\n * Track + handle styled off Base UI's data-checked/data-disabled state. The\n * thumb grows and slides when checked; a 40dp circular state layer (`before:`)\n * reacts to hover/focus/press on the root via the `group` utility.\n */\nimport { createSwitch } from '@m3-baseui/core';\nimport { tv } from 'tailwind-variants';\n\nexport const switchTv = tv({\n slots: {\n root: [\n 'group relative inline-flex shrink-0 w-[52px] h-8 rounded-full border-2 box-border cursor-pointer',\n 'bg-surface-container-highest border-outline',\n 'transition-colors duration-200 ease-standard',\n 'data-[checked]:bg-primary data-[checked]:border-primary',\n 'focus-visible:outline-[3px] focus-visible:outline-offset-2 focus-visible:outline-secondary',\n 'data-[disabled]:pointer-events-none',\n // M3 disabled: faint track + outline (unselected); on-surface/12 track,\n // no outline (selected). Not a blanket element opacity.\n 'data-[disabled]:bg-surface-container-highest/12 data-[disabled]:border-on-surface/12',\n 'data-[disabled]:data-[checked]:bg-on-surface/12 data-[disabled]:data-[checked]:border-transparent',\n ],\n thumb: [\n 'absolute top-1/2 -translate-y-1/2 left-[6px] size-4 rounded-full pointer-events-none',\n 'flex items-center justify-center',\n 'bg-outline text-on-surface',\n 'transition-all duration-200 ease-standard',\n 'data-[checked]:left-[22px] data-[checked]:size-6 data-[checked]:bg-on-primary data-[checked]:text-primary',\n // M3 with-icon: the unchecked handle grows to 24dp to fit its icon\n 'data-[with-icon]:data-[unchecked]:left-1 data-[with-icon]:data-[unchecked]:size-6',\n // M3 handle interaction colors: unselected outline→on-surface-variant,\n // selected on-primary→primary-container on hover/focus/press\n 'group-hover:bg-on-surface-variant group-focus-visible:bg-on-surface-variant group-active:bg-on-surface-variant',\n 'group-hover:data-[checked]:bg-primary-container group-focus-visible:data-[checked]:bg-primary-container group-active:data-[checked]:bg-primary-container',\n // M3 squish: handle grows to 28px while pressed, staying on its side\n 'group-active:left-0 group-active:size-7',\n 'group-active:data-[checked]:left-5 group-active:data-[checked]:size-7',\n // M3 disabled handle: on-surface/38 (unselected), surface (selected)\n 'group-data-[disabled]:bg-on-surface/38',\n 'group-data-[disabled]:data-[checked]:bg-surface',\n // 40dp circular state layer centered on the thumb\n 'before:content-[\"\"] before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2',\n 'before:size-10 before:rounded-full before:bg-current before:opacity-0 before:transition-opacity before:duration-100',\n 'group-hover:before:opacity-[var(--md-sys-state-hover)]',\n 'group-focus-visible:before:opacity-[var(--md-sys-state-focus)]',\n 'group-active:before:opacity-[var(--md-sys-state-pressed)]',\n ],\n // Handle icons (16dp). Both stay mounted; the root's data-checked reveals one.\n iconChecked: [\n 'hidden group-data-[checked]:inline-flex items-center justify-center',\n 'text-on-primary-container [&>svg]:size-4',\n ],\n iconUnchecked: [\n 'inline-flex group-data-[checked]:hidden items-center justify-center',\n 'text-surface-container-highest [&>svg]:size-4',\n ],\n },\n});\n\nconst s = switchTv();\nexport const Switch = createSwitch({\n root: s.root(),\n thumb: s.thumb(),\n iconChecked: s.iconChecked(),\n iconUnchecked: s.iconUnchecked(),\n});\n"]}