@m3-baseui/react-tailwind 1.1.0 → 1.3.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 (46) hide show
  1. package/dist/button-group.d.ts +48 -0
  2. package/dist/button-group.js +58 -0
  3. package/dist/button-group.js.map +1 -0
  4. package/dist/carousel.d.ts +115 -0
  5. package/dist/carousel.js +63 -0
  6. package/dist/carousel.js.map +1 -0
  7. package/dist/checkbox.js +5 -0
  8. package/dist/checkbox.js.map +1 -1
  9. package/dist/chip.d.ts +31 -0
  10. package/dist/chip.js +34 -7
  11. package/dist/chip.js.map +1 -1
  12. package/dist/date-picker.d.ts +188 -0
  13. package/dist/date-picker.js +151 -0
  14. package/dist/date-picker.js.map +1 -0
  15. package/dist/icon-button.js +4 -1
  16. package/dist/icon-button.js.map +1 -1
  17. package/dist/index.d.ts +9 -1
  18. package/dist/index.js +501 -29
  19. package/dist/index.js.map +1 -1
  20. package/dist/loading-indicator.d.ts +68 -0
  21. package/dist/loading-indicator.js +61 -0
  22. package/dist/loading-indicator.js.map +1 -0
  23. package/dist/navigation-bar.d.ts +5 -5
  24. package/dist/navigation-rail.d.ts +5 -5
  25. package/dist/radio.js +8 -3
  26. package/dist/radio.js.map +1 -1
  27. package/dist/search.d.ts +148 -0
  28. package/dist/search.js +105 -0
  29. package/dist/search.js.map +1 -0
  30. package/dist/segmented-button.d.ts +5 -5
  31. package/dist/slider.d.ts +33 -6
  32. package/dist/slider.js +16 -3
  33. package/dist/slider.js.map +1 -1
  34. package/dist/split-button.d.ts +201 -0
  35. package/dist/split-button.js +126 -0
  36. package/dist/split-button.js.map +1 -0
  37. package/dist/switch.js +4 -1
  38. package/dist/switch.js.map +1 -1
  39. package/dist/time-picker.d.ts +144 -0
  40. package/dist/time-picker.js +101 -0
  41. package/dist/time-picker.js.map +1 -0
  42. package/dist/toolbar.d.ts +73 -0
  43. package/dist/toolbar.js +55 -0
  44. package/dist/toolbar.js.map +1 -0
  45. package/package.json +41 -1
  46. package/styles/preset.css +15 -0
package/dist/slider.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as _m3_baseui_core from '@m3-baseui/core';
1
2
  import * as react from 'react';
2
3
  import * as _base_ui_react from '@base-ui/react';
3
4
  import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
@@ -12,6 +13,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
12
13
  indicator?: tailwind_variants.ClassValue;
13
14
  thumb?: tailwind_variants.ClassValue;
14
15
  control?: tailwind_variants.ClassValue;
16
+ tickList?: tailwind_variants.ClassValue;
17
+ tick?: tailwind_variants.ClassValue;
18
+ valueLabel?: tailwind_variants.ClassValue;
15
19
  };
16
20
  };
17
21
  } | {
@@ -23,6 +27,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
23
27
  indicator?: tailwind_variants.ClassValue;
24
28
  thumb?: tailwind_variants.ClassValue;
25
29
  control?: tailwind_variants.ClassValue;
30
+ tickList?: tailwind_variants.ClassValue;
31
+ tick?: tailwind_variants.ClassValue;
32
+ valueLabel?: tailwind_variants.ClassValue;
26
33
  };
27
34
  };
28
35
  } | {}, {
@@ -32,6 +39,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
32
39
  indicator: string[];
33
40
  thumb: string[];
34
41
  value: string;
42
+ tickList: string;
43
+ tick: string[];
44
+ valueLabel: string[];
35
45
  }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
36
46
  [key: string]: {
37
47
  [key: string]: tailwind_variants.ClassValue | {
@@ -41,6 +51,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
41
51
  indicator?: tailwind_variants.ClassValue;
42
52
  thumb?: tailwind_variants.ClassValue;
43
53
  control?: tailwind_variants.ClassValue;
54
+ tickList?: tailwind_variants.ClassValue;
55
+ tick?: tailwind_variants.ClassValue;
56
+ valueLabel?: tailwind_variants.ClassValue;
44
57
  };
45
58
  };
46
59
  } | {}>, {
@@ -52,6 +65,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
52
65
  indicator?: tailwind_variants.ClassValue;
53
66
  thumb?: tailwind_variants.ClassValue;
54
67
  control?: tailwind_variants.ClassValue;
68
+ tickList?: tailwind_variants.ClassValue;
69
+ tick?: tailwind_variants.ClassValue;
70
+ valueLabel?: tailwind_variants.ClassValue;
55
71
  };
56
72
  };
57
73
  } | {}, {
@@ -61,6 +77,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
61
77
  indicator: string[];
62
78
  thumb: string[];
63
79
  value: string;
80
+ tickList: string;
81
+ tick: string[];
82
+ valueLabel: string[];
64
83
  }, tailwind_variants.TVReturnType<unknown, {
65
84
  root: string;
66
85
  control: string;
@@ -68,6 +87,9 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
68
87
  indicator: string[];
69
88
  thumb: string[];
70
89
  value: string;
90
+ tickList: string;
91
+ tick: string[];
92
+ valueLabel: string[];
71
93
  }, undefined, tailwind_variants_dist_config_js.TVConfig<unknown, {
72
94
  [key: string]: {
73
95
  [key: string]: tailwind_variants.ClassValue | {
@@ -77,18 +99,23 @@ declare const sliderTv: tailwind_variants.TVReturnType<{
77
99
  indicator?: tailwind_variants.ClassValue;
78
100
  thumb?: tailwind_variants.ClassValue;
79
101
  control?: tailwind_variants.ClassValue;
102
+ tickList?: tailwind_variants.ClassValue;
103
+ tick?: tailwind_variants.ClassValue;
104
+ valueLabel?: tailwind_variants.ClassValue;
80
105
  };
81
106
  };
82
107
  } | {}>, unknown, unknown, undefined>>;
83
108
  declare const Slider: {
84
109
  Root: react.ForwardRefExoticComponent<Omit<_base_ui_react.SliderRoot.Props<number | readonly number[]> & {
85
110
  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>>;
111
+ }, "ref"> & react.RefAttributes<HTMLDivElement>>;
112
+ Control: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderControlProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
113
+ Track: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderTrackProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
114
+ Indicator: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderIndicatorProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
115
+ Thumb: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderThumbProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
116
+ Value: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.SliderValueProps, "ref"> & react.RefAttributes<HTMLOutputElement>, "ref"> & react.RefAttributes<HTMLOutputElement>>;
117
+ TickList: react.ForwardRefExoticComponent<_m3_baseui_core.SliderTickListProps & react.RefAttributes<HTMLDivElement>>;
118
+ ValueLabel: react.ForwardRefExoticComponent<_m3_baseui_core.SliderValueLabelProps & react.RefAttributes<HTMLSpanElement>>;
92
119
  };
93
120
 
94
121
  export { Slider, sliderTv };
package/dist/slider.js CHANGED
@@ -45,7 +45,7 @@ var sliderTv = tv({
45
45
  "group-data-[disabled]:bg-on-surface/[0.38]"
46
46
  ],
47
47
  thumb: [
48
- "relative size-5 rounded-full bg-primary outline-none",
48
+ "group/thumb relative size-5 rounded-full bg-primary outline-none",
49
49
  'before:content-[""] before:absolute before:left-1/2 before:top-1/2 before:-translate-x-1/2 before:-translate-y-1/2',
50
50
  "before:size-10 before:rounded-full before:bg-primary before:opacity-0 before:transition-opacity before:duration-100",
51
51
  "hover:before:opacity-[var(--md-sys-state-hover)]",
@@ -53,7 +53,17 @@ var sliderTv = tv({
53
53
  "data-[dragging]:before:opacity-[var(--md-sys-state-dragged)]",
54
54
  "group-data-[disabled]:bg-on-surface/[0.38]"
55
55
  ],
56
- value: "text-label-large text-on-surface-variant tabular-nums"
56
+ value: "text-label-large text-on-surface-variant tabular-nums",
57
+ tickList: "pointer-events-none absolute inset-0",
58
+ tick: [
59
+ "absolute size-1 -translate-x-1/2 -translate-y-1/2 rounded-full bg-on-surface-variant",
60
+ "data-[active]:bg-on-primary/[0.38]"
61
+ ],
62
+ valueLabel: [
63
+ "pointer-events-none absolute bottom-full left-1/2 mb-2 -translate-x-1/2 whitespace-nowrap rounded px-2 py-0.5",
64
+ "bg-primary text-label-large text-on-primary tabular-nums opacity-0",
65
+ "data-[visible]:opacity-100"
66
+ ]
57
67
  }
58
68
  });
59
69
  var s = sliderTv();
@@ -63,7 +73,10 @@ var Slider = createSlider({
63
73
  track: s.track(),
64
74
  indicator: s.indicator(),
65
75
  thumb: s.thumb(),
66
- value: s.value()
76
+ value: s.value(),
77
+ tickList: s.tickList(),
78
+ tick: s.tick(),
79
+ valueLabel: s.valueLabel()
67
80
  });
68
81
 
69
82
  export { Slider, sliderTv };
@@ -1 +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-dragged)]',\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"]}
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,kEAAA;AAAA,MACA,oHAAA;AAAA,MACA,qHAAA;AAAA,MACA,kDAAA;AAAA,MACA,0DAAA;AAAA,MACA,8DAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,KAAA,EAAO,uDAAA;AAAA,IACP,QAAA,EAAU,sCAAA;AAAA,IACV,IAAA,EAAM;AAAA,MACJ,sFAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,UAAA,EAAY;AAAA,MACV,+GAAA;AAAA,MACA,oEAAA;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,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,EAAM;AAAA,EACf,QAAA,EAAU,EAAE,QAAA,EAAS;AAAA,EACrB,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,EACb,UAAA,EAAY,EAAE,UAAA;AAChB,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 'group/thumb 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-dragged)]',\n 'group-data-[disabled]:bg-on-surface/[0.38]',\n ],\n value: 'text-label-large text-on-surface-variant tabular-nums',\n tickList: 'pointer-events-none absolute inset-0',\n tick: [\n 'absolute size-1 -translate-x-1/2 -translate-y-1/2 rounded-full bg-on-surface-variant',\n 'data-[active]:bg-on-primary/[0.38]',\n ],\n valueLabel: [\n 'pointer-events-none absolute bottom-full left-1/2 mb-2 -translate-x-1/2 whitespace-nowrap rounded px-2 py-0.5',\n 'bg-primary text-label-large text-on-primary tabular-nums opacity-0',\n 'data-[visible]:opacity-100',\n ],\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 tickList: s.tickList(),\n tick: s.tick(),\n valueLabel: s.valueLabel(),\n});\n"]}
@@ -0,0 +1,201 @@
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 from 'tailwind-variants';
5
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
6
+
7
+ declare const splitButtonTv: tailwind_variants.TVReturnType<{
8
+ variant: {
9
+ filled: {
10
+ leading: string[];
11
+ trailing: string[];
12
+ };
13
+ tonal: {
14
+ leading: string[];
15
+ trailing: string[];
16
+ };
17
+ outlined: {
18
+ leading: string[];
19
+ trailing: string[];
20
+ };
21
+ elevated: {
22
+ leading: string[];
23
+ trailing: string[];
24
+ };
25
+ text: {
26
+ leading: string[];
27
+ trailing: string[];
28
+ };
29
+ };
30
+ }, {
31
+ group: string;
32
+ leading: string[];
33
+ trailing: string[];
34
+ chevron: string[];
35
+ popup: string[];
36
+ item: string[];
37
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<{
38
+ variant: {
39
+ filled: {
40
+ leading: string[];
41
+ trailing: string[];
42
+ };
43
+ tonal: {
44
+ leading: string[];
45
+ trailing: string[];
46
+ };
47
+ outlined: {
48
+ leading: string[];
49
+ trailing: string[];
50
+ };
51
+ elevated: {
52
+ leading: string[];
53
+ trailing: string[];
54
+ };
55
+ text: {
56
+ leading: string[];
57
+ trailing: string[];
58
+ };
59
+ };
60
+ }, {
61
+ variant: {
62
+ filled: {
63
+ leading: string[];
64
+ trailing: string[];
65
+ };
66
+ tonal: {
67
+ leading: string[];
68
+ trailing: string[];
69
+ };
70
+ outlined: {
71
+ leading: string[];
72
+ trailing: string[];
73
+ };
74
+ elevated: {
75
+ leading: string[];
76
+ trailing: string[];
77
+ };
78
+ text: {
79
+ leading: string[];
80
+ trailing: string[];
81
+ };
82
+ };
83
+ }>, {
84
+ variant: {
85
+ filled: {
86
+ leading: string[];
87
+ trailing: string[];
88
+ };
89
+ tonal: {
90
+ leading: string[];
91
+ trailing: string[];
92
+ };
93
+ outlined: {
94
+ leading: string[];
95
+ trailing: string[];
96
+ };
97
+ elevated: {
98
+ leading: string[];
99
+ trailing: string[];
100
+ };
101
+ text: {
102
+ leading: string[];
103
+ trailing: string[];
104
+ };
105
+ };
106
+ }, {
107
+ group: string;
108
+ leading: string[];
109
+ trailing: string[];
110
+ chevron: string[];
111
+ popup: string[];
112
+ item: string[];
113
+ }, tailwind_variants.TVReturnType<{
114
+ variant: {
115
+ filled: {
116
+ leading: string[];
117
+ trailing: string[];
118
+ };
119
+ tonal: {
120
+ leading: string[];
121
+ trailing: string[];
122
+ };
123
+ outlined: {
124
+ leading: string[];
125
+ trailing: string[];
126
+ };
127
+ elevated: {
128
+ leading: string[];
129
+ trailing: string[];
130
+ };
131
+ text: {
132
+ leading: string[];
133
+ trailing: string[];
134
+ };
135
+ };
136
+ }, {
137
+ group: string;
138
+ leading: string[];
139
+ trailing: string[];
140
+ chevron: string[];
141
+ popup: string[];
142
+ item: string[];
143
+ }, undefined, tailwind_variants_dist_config_js.TVConfig<{
144
+ variant: {
145
+ filled: {
146
+ leading: string[];
147
+ trailing: string[];
148
+ };
149
+ tonal: {
150
+ leading: string[];
151
+ trailing: string[];
152
+ };
153
+ outlined: {
154
+ leading: string[];
155
+ trailing: string[];
156
+ };
157
+ elevated: {
158
+ leading: string[];
159
+ trailing: string[];
160
+ };
161
+ text: {
162
+ leading: string[];
163
+ trailing: string[];
164
+ };
165
+ };
166
+ }, {
167
+ variant: {
168
+ filled: {
169
+ leading: string[];
170
+ trailing: string[];
171
+ };
172
+ tonal: {
173
+ leading: string[];
174
+ trailing: string[];
175
+ };
176
+ outlined: {
177
+ leading: string[];
178
+ trailing: string[];
179
+ };
180
+ elevated: {
181
+ leading: string[];
182
+ trailing: string[];
183
+ };
184
+ text: {
185
+ leading: string[];
186
+ trailing: string[];
187
+ };
188
+ };
189
+ }>, unknown, unknown, undefined>>;
190
+ declare const SplitButton: {
191
+ Root: <Payload>(props: _base_ui_react.MenuRoot.Props<Payload>) => react.JSX.Element;
192
+ Group: react.ForwardRefExoticComponent<_m3_baseui_core.SplitButtonGroupOwnProps & react.HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
193
+ Leading: react.ForwardRefExoticComponent<_m3_baseui_core.SplitButtonLeadingOwnProps & react.ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
194
+ Trailing: react.ForwardRefExoticComponent<_m3_baseui_core.SplitButtonTrailingOwnProps & Omit<Omit<_base_ui_react.MenuTriggerProps<unknown> & react.RefAttributes<HTMLElement>, "ref">, "color"> & react.RefAttributes<HTMLButtonElement>>;
195
+ Portal: react.ForwardRefExoticComponent<Omit<_base_ui_react.ContextMenuPortalProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
196
+ Positioner: react.ForwardRefExoticComponent<Omit<_base_ui_react.ContextMenuPositionerProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
197
+ Popup: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ContextMenuPopupProps, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<unknown>>;
198
+ Item: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react.ContextMenuItemProps, "ref"> & react.RefAttributes<HTMLElement>, "ref"> & react.RefAttributes<unknown>>;
199
+ };
200
+
201
+ export { SplitButton, splitButtonTv };
@@ -0,0 +1,126 @@
1
+ "use client";
2
+ import { createSplitButton } from '@m3-baseui/core';
3
+ import { tv as tv$1 } from 'tailwind-variants';
4
+
5
+ // src/split-button.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/split-button.ts
35
+ var surface = [
36
+ "relative inline-flex items-center justify-center h-10 overflow-hidden cursor-pointer select-none border-0 outline-none",
37
+ "text-label-large",
38
+ "transition-[background-color,color,border-color] duration-200 ease-standard",
39
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
40
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
41
+ "focus-visible:before:opacity-[var(--md-sys-state-focus)]",
42
+ "active:before:opacity-[var(--md-sys-state-pressed)]",
43
+ "data-[pressed]:before:opacity-[var(--md-sys-state-pressed)]",
44
+ "focus-visible:outline-[3px] focus-visible:outline-offset-2 focus-visible:outline-secondary",
45
+ "disabled:pointer-events-none disabled:before:opacity-0",
46
+ "data-[disabled]:pointer-events-none data-[disabled]:before:opacity-0"
47
+ ];
48
+ var VARIANT_FILLED = [
49
+ "bg-primary text-on-primary",
50
+ "disabled:bg-on-surface/12 disabled:text-on-surface/38",
51
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38"
52
+ ];
53
+ var VARIANT_TONAL = [
54
+ "bg-secondary-container text-on-secondary-container",
55
+ "disabled:bg-on-surface/12 disabled:text-on-surface/38",
56
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38"
57
+ ];
58
+ var VARIANT_OUTLINED = [
59
+ "bg-transparent text-primary border border-outline",
60
+ "disabled:text-on-surface/38 disabled:border-on-surface/12",
61
+ "data-[disabled]:text-on-surface/38 data-[disabled]:border-on-surface/12"
62
+ ];
63
+ var VARIANT_ELEVATED = [
64
+ "bg-surface-container-low text-primary shadow-level1",
65
+ "disabled:bg-on-surface/12 disabled:text-on-surface/38 disabled:shadow-none",
66
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
67
+ ];
68
+ var VARIANT_TEXT = [
69
+ "bg-transparent text-primary",
70
+ "disabled:text-on-surface/38",
71
+ "data-[disabled]:text-on-surface/38"
72
+ ];
73
+ var splitButtonTv = tv({
74
+ slots: {
75
+ group: "inline-flex items-center gap-0.5",
76
+ // leading: outer (start) corner full, seam (end) corner reduced.
77
+ leading: [...surface, "gap-2 px-6 rounded-s-full rounded-e-small"],
78
+ // trailing: seam (start) corner reduced, outer (end) corner full.
79
+ trailing: [...surface, "group gap-1 px-3 rounded-s-small rounded-e-full"],
80
+ chevron: [
81
+ "inline-flex items-center justify-center shrink-0 [&>svg]:size-[18px]",
82
+ "transition-transform duration-200 ease-standard group-data-[popup-open]:rotate-180"
83
+ ],
84
+ popup: [
85
+ "min-w-[112px] max-w-[280px] py-2",
86
+ "bg-surface-container text-on-surface rounded-extra-small shadow-level2",
87
+ "origin-[var(--transform-origin)] transition-[opacity,transform] duration-150 ease-standard",
88
+ "data-[starting-style]:opacity-0 data-[starting-style]:scale-95",
89
+ "data-[ending-style]:opacity-0",
90
+ "focus:outline-none"
91
+ ],
92
+ item: [
93
+ "relative flex items-center gap-3 h-12 px-3 overflow-hidden cursor-pointer select-none outline-none",
94
+ "text-label-large text-on-surface",
95
+ "before:absolute before:inset-0 before:bg-current before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-100",
96
+ "hover:before:opacity-[var(--md-sys-state-hover)]",
97
+ "data-[highlighted]:before:opacity-[var(--md-sys-state-hover)]",
98
+ "active:before:opacity-[var(--md-sys-state-pressed)]",
99
+ "data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none"
100
+ ]
101
+ },
102
+ variants: {
103
+ variant: {
104
+ filled: { leading: VARIANT_FILLED, trailing: VARIANT_FILLED },
105
+ tonal: { leading: VARIANT_TONAL, trailing: VARIANT_TONAL },
106
+ outlined: { leading: VARIANT_OUTLINED, trailing: VARIANT_OUTLINED },
107
+ elevated: { leading: VARIANT_ELEVATED, trailing: VARIANT_ELEVATED },
108
+ text: { leading: VARIANT_TEXT, trailing: VARIANT_TEXT }
109
+ }
110
+ },
111
+ defaultVariants: {
112
+ variant: "filled"
113
+ }
114
+ });
115
+ var SplitButton = createSplitButton({
116
+ group: splitButtonTv().group(),
117
+ leading: (variant) => splitButtonTv({ variant }).leading(),
118
+ trailing: (variant) => splitButtonTv({ variant }).trailing(),
119
+ chevron: splitButtonTv().chevron(),
120
+ popup: splitButtonTv().popup(),
121
+ item: splitButtonTv().item()
122
+ });
123
+
124
+ export { SplitButton, splitButtonTv };
125
+ //# sourceMappingURL=split-button.js.map
126
+ //# sourceMappingURL=split-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tv.ts","../src/split-button.ts"],"names":["baseTv"],"mappings":"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","file":"split-button.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 * split-button.ts — tailwind-variants slots for the M3 SplitButton.\n *\n * Two 40dp surfaces joined by a 2dp seam: the leading primary-action button\n * keeps its outer (start) corner full and reduces the seam (end) corner; the\n * trailing menu trigger mirrors it. Both share the variant container color. The\n * trigger carries `group` so the default chevron can rotate via Base UI's\n * `data-[popup-open]`. The dropdown reuses the M3 menu surface. State layer is\n * the `::before` overlay; the pointer ripple is added by the factory. Same DOM\n * as the VE build.\n */\nimport { createSplitButton } from '@m3-baseui/core';\nimport { tv } from './tv';\n\n// Shared surface base for both the leading + trailing buttons.\nconst surface = [\n 'relative inline-flex items-center justify-center h-10 overflow-hidden cursor-pointer select-none border-0 outline-none',\n 'text-label-large',\n 'transition-[background-color,color,border-color] duration-200 ease-standard',\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 'focus-visible:outline-[3px] focus-visible:outline-offset-2 focus-visible:outline-secondary',\n 'disabled:pointer-events-none disabled:before:opacity-0',\n 'data-[disabled]:pointer-events-none data-[disabled]:before:opacity-0',\n];\n\n// Per-variant container colors (identical on both surfaces). M3 disabled is\n// per-token (container on-surface/12, label on-surface/38), not a blanket fade.\nconst VARIANT_FILLED = [\n 'bg-primary text-on-primary',\n 'disabled:bg-on-surface/12 disabled:text-on-surface/38',\n 'data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38',\n];\nconst VARIANT_TONAL = [\n 'bg-secondary-container text-on-secondary-container',\n 'disabled:bg-on-surface/12 disabled:text-on-surface/38',\n 'data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38',\n];\nconst VARIANT_OUTLINED = [\n 'bg-transparent text-primary border border-outline',\n 'disabled:text-on-surface/38 disabled:border-on-surface/12',\n 'data-[disabled]:text-on-surface/38 data-[disabled]:border-on-surface/12',\n];\nconst VARIANT_ELEVATED = [\n 'bg-surface-container-low text-primary shadow-level1',\n 'disabled:bg-on-surface/12 disabled:text-on-surface/38 disabled:shadow-none',\n 'data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none',\n];\nconst VARIANT_TEXT = [\n 'bg-transparent text-primary',\n 'disabled:text-on-surface/38',\n 'data-[disabled]:text-on-surface/38',\n];\n\nexport const splitButtonTv = tv({\n slots: {\n group: 'inline-flex items-center gap-0.5',\n // leading: outer (start) corner full, seam (end) corner reduced.\n leading: [...surface, 'gap-2 px-6 rounded-s-full rounded-e-small'],\n // trailing: seam (start) corner reduced, outer (end) corner full.\n trailing: [...surface, 'group gap-1 px-3 rounded-s-small rounded-e-full'],\n chevron: [\n 'inline-flex items-center justify-center shrink-0 [&>svg]:size-[18px]',\n 'transition-transform duration-200 ease-standard group-data-[popup-open]:rotate-180',\n ],\n popup: [\n 'min-w-[112px] max-w-[280px] py-2',\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 'relative flex items-center gap-3 h-12 px-3 overflow-hidden cursor-pointer select-none outline-none',\n 'text-label-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 'data-[disabled]:text-on-surface/[0.38] data-[disabled]:before:opacity-0 data-[disabled]:pointer-events-none',\n ],\n },\n variants: {\n variant: {\n filled: { leading: VARIANT_FILLED, trailing: VARIANT_FILLED },\n tonal: { leading: VARIANT_TONAL, trailing: VARIANT_TONAL },\n outlined: { leading: VARIANT_OUTLINED, trailing: VARIANT_OUTLINED },\n elevated: { leading: VARIANT_ELEVATED, trailing: VARIANT_ELEVATED },\n text: { leading: VARIANT_TEXT, trailing: VARIANT_TEXT },\n },\n },\n defaultVariants: {\n variant: 'filled',\n },\n});\n\nexport const SplitButton = createSplitButton({\n group: splitButtonTv().group(),\n leading: (variant) => splitButtonTv({ variant }).leading(),\n trailing: (variant) => splitButtonTv({ variant }).trailing(),\n chevron: splitButtonTv().chevron(),\n popup: splitButtonTv().popup(),\n item: splitButtonTv().item(),\n});\n"]}
package/dist/switch.js CHANGED
@@ -21,7 +21,10 @@ var switchTv = tv({
21
21
  "absolute top-1/2 -translate-y-1/2 left-[6px] size-4 rounded-full pointer-events-none",
22
22
  "flex items-center justify-center",
23
23
  "bg-outline text-on-surface",
24
- "transition-all duration-200 ease-standard",
24
+ // M3 spatial motion: the handle slides/grows with emphasized easing over
25
+ // 300ms (token-backed). emphasized is overshoot-free, so it stays safe for
26
+ // the handle's color transitions too (no spring flicker on background-color).
27
+ "transition-all ease-emphasized duration-[var(--md-sys-motion-duration-medium2)]",
25
28
  "data-[checked]:left-[22px] data-[checked]:size-6 data-[checked]:bg-on-primary data-[checked]:text-primary",
26
29
  // M3 with-icon: the unchecked handle grows to 24dp to fit its icon
27
30
  "data-[with-icon]:data-[unchecked]:left-1 data-[with-icon]:data-[unchecked]:size-6",
@@ -1 +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"]}
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;AAAA;AAAA;AAAA,MAIA,iFAAA;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 // M3 spatial motion: the handle slides/grows with emphasized easing over\n // 300ms (token-backed). emphasized is overshoot-free, so it stays safe for\n // the handle's color transitions too (no spring flicker on background-color).\n 'transition-all ease-emphasized duration-[var(--md-sys-motion-duration-medium2)]',\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"]}