@kanso-labs/kanso-ui 0.11.21 → 0.12.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 (89) hide show
  1. package/README.md +32 -8
  2. package/dist/components/app-bar/index.d.ts +2 -2
  3. package/dist/components/app-bar/index.js +1 -1
  4. package/dist/components/app-bar/index.js.map +1 -1
  5. package/dist/components/avatar/index.d.ts +4 -4
  6. package/dist/components/avatar/index.js +21 -15
  7. package/dist/components/avatar/index.js.map +1 -1
  8. package/dist/components/badge/index.d.ts +2 -2
  9. package/dist/components/badge/index.js +1 -1
  10. package/dist/components/badge/index.js.map +1 -1
  11. package/dist/components/button/index.d.ts +32 -21
  12. package/dist/components/button/index.js +75 -19
  13. package/dist/components/button/index.js.map +1 -1
  14. package/dist/components/card/index.d.ts +2 -2
  15. package/dist/components/card/index.js +1 -1
  16. package/dist/components/card/index.js.map +1 -1
  17. package/dist/components/chip/index.d.ts +5 -5
  18. package/dist/components/chip/index.js +5 -5
  19. package/dist/components/chip/index.js.map +1 -1
  20. package/dist/components/code/index.d.ts +2 -2
  21. package/dist/components/code/index.js +1 -1
  22. package/dist/components/code/index.js.map +1 -1
  23. package/dist/components/container/index.d.ts +2 -2
  24. package/dist/components/container/index.js +1 -1
  25. package/dist/components/container/index.js.map +1 -1
  26. package/dist/components/copy-field/index.js +1 -1
  27. package/dist/components/currency/index.d.ts +2 -2
  28. package/dist/components/currency/index.js +1 -1
  29. package/dist/components/currency/index.js.map +1 -1
  30. package/dist/components/feed/index.d.ts +2 -2
  31. package/dist/components/feed/index.js +1 -1
  32. package/dist/components/feed/index.js.map +1 -1
  33. package/dist/components/icon-button/index.d.ts +24 -18
  34. package/dist/components/icon-button/index.js +62 -15
  35. package/dist/components/icon-button/index.js.map +1 -1
  36. package/dist/components/index.d.ts +2 -1
  37. package/dist/components/keycap/index.d.ts +2 -2
  38. package/dist/components/keycap/index.js +1 -1
  39. package/dist/components/keycap/index.js.map +1 -1
  40. package/dist/components/link/index.d.ts +2 -2
  41. package/dist/components/link/index.js +1 -1
  42. package/dist/components/link/index.js.map +1 -1
  43. package/dist/components/list-detail/index.d.ts +2 -2
  44. package/dist/components/list-detail/index.js +1 -1
  45. package/dist/components/list-detail/index.js.map +1 -1
  46. package/dist/components/popover/index.d.ts +105 -0
  47. package/dist/components/popover/index.js +246 -0
  48. package/dist/components/popover/index.js.map +1 -0
  49. package/dist/components/product-icon/index.d.ts +3 -3
  50. package/dist/components/product-icon/index.js +23 -17
  51. package/dist/components/product-icon/index.js.map +1 -1
  52. package/dist/components/separator/index.d.ts +14 -4
  53. package/dist/components/separator/index.js +23 -9
  54. package/dist/components/separator/index.js.map +1 -1
  55. package/dist/components/sheet/index.d.ts +26 -28
  56. package/dist/components/sheet/index.js +47 -82
  57. package/dist/components/sheet/index.js.map +1 -1
  58. package/dist/components/stack/index.d.ts +2 -2
  59. package/dist/components/stack/index.js +1 -1
  60. package/dist/components/stack/index.js.map +1 -1
  61. package/dist/components/supporting-pane/index.d.ts +2 -2
  62. package/dist/components/supporting-pane/index.js +1 -1
  63. package/dist/components/supporting-pane/index.js.map +1 -1
  64. package/dist/components/tabs/index.d.ts +15 -8
  65. package/dist/components/tabs/index.js +133 -45
  66. package/dist/components/tabs/index.js.map +1 -1
  67. package/dist/components/text/index.d.ts +2 -2
  68. package/dist/components/text/index.js +1 -1
  69. package/dist/components/text/index.js.map +1 -1
  70. package/dist/components/text-field/index.d.ts +12 -5
  71. package/dist/components/text-field/index.js +48 -33
  72. package/dist/components/text-field/index.js.map +1 -1
  73. package/dist/hooks/useImageLoadingStatus.js +53 -0
  74. package/dist/hooks/useImageLoadingStatus.js.map +1 -0
  75. package/dist/hooks/useRipple.js +1 -1
  76. package/dist/hooks/useRipple.js.map +1 -1
  77. package/dist/index.d.ts +2 -1
  78. package/dist/index.js +2 -1
  79. package/dist/render/aria.js +66 -0
  80. package/dist/render/aria.js.map +1 -0
  81. package/dist/render/useRender.d.ts +28 -0
  82. package/dist/render/useRender.js +132 -0
  83. package/dist/render/useRender.js.map +1 -0
  84. package/dist/styles/merge.js +14 -8
  85. package/dist/styles/merge.js.map +1 -1
  86. package/dist/styles.css +88 -36
  87. package/package.json +4 -4
  88. package/dist/render/nativeButton.js +0 -26
  89. package/dist/render/nativeButton.js.map +0 -1
@@ -1,26 +1,92 @@
1
1
  import { mergeStatefulStyles } from "../../styles/merge.js";
2
+ import { createContext, useContext, useEffect, useState } from "react";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  import { c } from "react/compiler-runtime";
4
- import { Tabs } from "@base-ui/react/tabs";
5
+ import { Tab, TabList, TabPanel, Tabs } from "react-aria-components";
5
6
  //#region src/components/tabs/index.tsx
7
+ const NO_PANELS = /* @__PURE__ */ new Set();
8
+ const PanelsContext = createContext(NO_PANELS);
9
+ const RegisterPanelContext = createContext(() => () => {});
10
+ function tabRenderer(hasPanel, render) {
11
+ return (domProps, state) => {
12
+ const adjusted = hasPanel ? domProps : {
13
+ ...domProps,
14
+ "aria-controls": void 0
15
+ };
16
+ if (render !== void 0) return render(adjusted, state);
17
+ if ("href" in adjusted) return /* @__PURE__ */ jsx("a", { ...adjusted });
18
+ return /* @__PURE__ */ jsx("div", { ...adjusted });
19
+ };
20
+ }
6
21
  /**
7
- * A tab strip and its panels. Selection is Base UI's `value`: pass `value`
8
- * with `onValueChange` to control it, or `defaultValue` to let it keep its
9
- * own.
22
+ * A tab strip and its panels. Selection is React Aria's `selectedKey`: pass
23
+ * it with `onSelectionChange` to control it, or `defaultSelectedKey` to let
24
+ * it keep its own. Each `Tabs.Tab` names the `Tabs.Panel` it controls through
25
+ * a shared `id`, and a strip may stand alone without panels.
10
26
  *
11
27
  * Composed rather than configured by props, because the number of tabs and
12
28
  * what each panel holds are the call site's to decide — the parts are
13
29
  * `Tabs.List`, `Tabs.Tab`, and `Tabs.Panel`.
14
30
  */
15
- function Tabs$1(props) {
16
- const $ = c(2);
17
- let t0;
18
- if ($[0] !== props) {
19
- t0 = /* @__PURE__ */ jsx(Tabs.Root, { ...props });
20
- $[0] = props;
21
- $[1] = t0;
22
- } else t0 = $[1];
23
- return t0;
31
+ function Tabs$1(t0) {
32
+ const $ = c(10);
33
+ let children;
34
+ let props;
35
+ if ($[0] !== t0) {
36
+ ({children, ...props} = t0);
37
+ $[0] = t0;
38
+ $[1] = children;
39
+ $[2] = props;
40
+ } else {
41
+ children = $[1];
42
+ props = $[2];
43
+ }
44
+ const [panels, setPanels] = useState(NO_PANELS);
45
+ let t1;
46
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
47
+ t1 = (id) => {
48
+ setPanels((previous) => {
49
+ if (previous.has(id)) return previous;
50
+ const next = new Set(previous);
51
+ next.add(id);
52
+ return next;
53
+ });
54
+ return () => {
55
+ setPanels((previous_0) => {
56
+ if (!previous_0.has(id)) return previous_0;
57
+ const next_0 = new Set(previous_0);
58
+ next_0.delete(id);
59
+ return next_0;
60
+ });
61
+ };
62
+ };
63
+ $[3] = t1;
64
+ } else t1 = $[3];
65
+ const register = t1;
66
+ let t2;
67
+ if ($[4] !== children || $[5] !== panels) {
68
+ t2 = /* @__PURE__ */ jsx(RegisterPanelContext, {
69
+ value: register,
70
+ children: /* @__PURE__ */ jsx(PanelsContext, {
71
+ value: panels,
72
+ children
73
+ })
74
+ });
75
+ $[4] = children;
76
+ $[5] = panels;
77
+ $[6] = t2;
78
+ } else t2 = $[6];
79
+ let t3;
80
+ if ($[7] !== props || $[8] !== t2) {
81
+ t3 = /* @__PURE__ */ jsx(Tabs, {
82
+ ...props,
83
+ children: t2
84
+ });
85
+ $[7] = props;
86
+ $[8] = t2;
87
+ $[9] = t3;
88
+ } else t3 = $[9];
89
+ return t3;
24
90
  }
25
91
  function TabsList(props) {
26
92
  const $ = c(5);
@@ -32,7 +98,7 @@ function TabsList(props) {
32
98
  } else t0 = $[1];
33
99
  let t1;
34
100
  if ($[2] !== props || $[3] !== t0) {
35
- t1 = /* @__PURE__ */ jsx(Tabs.List, {
101
+ t1 = /* @__PURE__ */ jsx(TabList, {
36
102
  ...props,
37
103
  ...t0
38
104
  });
@@ -43,44 +109,66 @@ function TabsList(props) {
43
109
  return t1;
44
110
  }
45
111
  function TabsPanel(props) {
46
- const $ = c(5);
112
+ const $ = c(9);
113
+ const register = useContext(RegisterPanelContext);
114
+ const { id } = props;
47
115
  let t0;
48
- if ($[0] !== props) {
49
- t0 = mergeStatefulStyles({ className: "x9f619 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn" }, props);
50
- $[0] = props;
51
- $[1] = t0;
52
- } else t0 = $[1];
53
116
  let t1;
54
- if ($[2] !== props || $[3] !== t0) {
55
- t1 = /* @__PURE__ */ jsx(Tabs.Panel, {
117
+ if ($[0] !== id || $[1] !== register) {
118
+ t0 = () => {
119
+ if (id === void 0) return;
120
+ return register(id);
121
+ };
122
+ t1 = [id, register];
123
+ $[0] = id;
124
+ $[1] = register;
125
+ $[2] = t0;
126
+ $[3] = t1;
127
+ } else {
128
+ t0 = $[2];
129
+ t1 = $[3];
130
+ }
131
+ useEffect(t0, t1);
132
+ let t2;
133
+ if ($[4] !== props) {
134
+ t2 = mergeStatefulStyles({ className: "x9f619 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn" }, props);
135
+ $[4] = props;
136
+ $[5] = t2;
137
+ } else t2 = $[5];
138
+ let t3;
139
+ if ($[6] !== props || $[7] !== t2) {
140
+ t3 = /* @__PURE__ */ jsx(TabPanel, {
56
141
  ...props,
57
- ...t0
142
+ ...t2
58
143
  });
59
- $[2] = props;
60
- $[3] = t0;
61
- $[4] = t1;
62
- } else t1 = $[4];
63
- return t1;
144
+ $[6] = props;
145
+ $[7] = t2;
146
+ $[8] = t3;
147
+ } else t3 = $[8];
148
+ return t3;
64
149
  }
65
- function TabsTab(props) {
150
+ function TabsTab(t0) {
66
151
  const $ = c(5);
67
- let t0;
68
- if ($[0] !== props) {
69
- t0 = mergeStatefulStyles(tabStyles, props);
70
- $[0] = props;
71
- $[1] = t0;
72
- } else t0 = $[1];
73
- let t1;
74
- if ($[2] !== props || $[3] !== t0) {
75
- t1 = /* @__PURE__ */ jsx(Tabs.Tab, {
152
+ const { render, ...props } = t0;
153
+ const panels = useContext(PanelsContext);
154
+ const hasPanel = props.id !== void 0 && panels.has(props.id);
155
+ const T0 = Tab;
156
+ const t1 = tabRenderer(hasPanel, render);
157
+ const t2 = mergeStatefulStyles(tabStyles, props);
158
+ let t3;
159
+ if ($[0] !== T0 || $[1] !== props || $[2] !== t1 || $[3] !== t2) {
160
+ t3 = /* @__PURE__ */ jsx(T0, {
76
161
  ...props,
77
- ...t0
162
+ render: t1,
163
+ ...t2
78
164
  });
79
- $[2] = props;
80
- $[3] = t0;
81
- $[4] = t1;
82
- } else t1 = $[4];
83
- return t1;
165
+ $[0] = T0;
166
+ $[1] = props;
167
+ $[2] = t1;
168
+ $[3] = t2;
169
+ $[4] = t3;
170
+ } else t3 = $[4];
171
+ return t3;
84
172
  }
85
173
  function tabStyles(state) {
86
174
  return {
@@ -88,7 +176,7 @@ function tabStyles(state) {
88
176
  2: { className: "x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 x1hei0q8 xp89om9 xscdzaa" },
89
177
  1: { className: "x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc" },
90
178
  3: { className: "x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc" }
91
- }[!!state.active << 1 | !!state.disabled << 0];
179
+ }[!!state.isSelected << 1 | !!state.isDisabled << 0];
92
180
  }
93
181
  Tabs$1.List = TabsList;
94
182
  Tabs$1.Panel = TabsPanel;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/tabs/index.tsx"],"sourcesContent":["import type { TabsListProps as BaseUITabsListProps, TabsPanelProps as BaseUITabsPanelProps, TabsRootProps as BaseUITabsRootProps, TabsTabProps as BaseUITabsTabProps, TabsTabState as BaseUITabsTabState } from '@base-ui/react/tabs';\nimport { Tabs as BaseUITabs } from '@base-ui/react/tabs';\nimport * as stylex from '@stylexjs/stylex';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// A tinted pill marks the active tab, not the underline Material draws. That\n// is what the source design uses, and the two are different controls wearing\n// the same name: an underline belongs to a full-width tab bar, while a row of\n// pills reads as a segmented control sitting inside a section.\n//\n// The pill takes the same height, radius, and type as Chip. Both are\n// pill-shaped selection controls, and a row of tabs above a row of chips\n// looks wrong the moment the two disagree about either.\n\n/**\n * A tab strip and its panels. Selection is Base UI's `value`: pass `value`\n * with `onValueChange` to control it, or `defaultValue` to let it keep its\n * own.\n *\n * Composed rather than configured by props, because the number of tabs and\n * what each panel holds are the call site's to decide — the parts are\n * `Tabs.List`, `Tabs.Tab`, and `Tabs.Panel`.\n */\nfunction Tabs(props: BaseUITabsRootProps) {\n return <BaseUITabs.Root {...props} />;\n}\nfunction TabsList(props: BaseUITabsListProps) {\n return <BaseUITabs.List {...props} {...mergeStatefulStyles({\n className: \"x9f619 x78zum5 x14qo01y\"\n }, props)} />;\n}\nfunction TabsPanel(props: BaseUITabsPanelProps) {\n return <BaseUITabs.Panel {...props} {...mergeStatefulStyles({\n className: \"x9f619 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn\"\n }, props)} />;\n}\nfunction TabsTab(props: BaseUITabsTabProps) {\n return <BaseUITabs.Tab {...props} {...mergeStatefulStyles(tabStyles, props)} />;\n}\n\n// StyleX cannot target [data-selected] on the element it is styling, so the\n// active pill cannot be chosen in CSS. Base UI's answer is a className that is\n// a function of the tab's own state, the same mechanism Chip uses —\n// mergeStatefulStyles wraps this one so a tab still keeps a className the call\n// site passed.\nfunction tabStyles(state: BaseUITabsTabState) {\n return {\n 0: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 x1p2om7n xjbqb8w x1w5n3ug\"\n },\n 2: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 x1hei0q8 xp89om9 xscdzaa\"\n },\n 1: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc\"\n },\n 3: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc\"\n }\n }[!!state.active << 1 | !!state.disabled << 0];\n}\nTabs.List = TabsList;\nTabs.Panel = TabsPanel;\nTabs.Tab = TabsTab;\ntype TabsListProps = BaseUITabsListProps;\ntype TabsPanelProps = BaseUITabsPanelProps;\ntype TabsProps = BaseUITabsRootProps;\ntype TabsTabProps = BaseUITabsTabProps;\nexport type { TabsListProps, TabsPanelProps, TabsProps, TabsTabProps };\nexport default Tabs;"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAA,OAAA,OAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA;EACS,KAAA,oBAAA,KAAA,MAAA,EAAA,GAAqB,MAAK,CAAA;EAAI,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAA9B;AAA8B;AAEvC,SAAA,SAAA,OAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA;EACyC,KAAA,oBAAoB,EAAA,WAC9C,0BACb,GAAG,KAAK;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,IAAA;EAFF,KAAA,oBAAA,KAAA,MAAA;GAAA,GAAqB;GAAK,GAAM;EAE9B,CAAA;EAAI,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAFN;AAEM;AAEf,SAAA,UAAA,OAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA;EAC0C,KAAA,oBAAoB,EAAA,WAC/C,oDACb,GAAG,KAAK;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,IAAA;EAFF,KAAA,oBAAA,KAAA,OAAA;GAAA,GAAsB;GAAK,GAAM;EAE/B,CAAA;EAAI,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAFN;AAEM;AAEf,SAAA,QAAA,OAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA;EACwC,KAAA,oBAAoB,WAAW,KAAK;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,IAAA;EAApE,KAAA,oBAAA,KAAA,KAAA;GAAA,GAAoB;GAAK,GAAM;EAAqC,CAAA;EAAI,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAAxE;AAAwE;AAQjF,SAAS,UAAU,OAA2B;CAC5C,OAAO;EACL,GAAG,EACD,WAAW,uOACb;EACA,GAAG,EACD,WAAW,sOACb;EACA,GAAG,EACD,WAAW,8NACb;EACA,GAAG,EACD,WAAW,8NACb;CACF,EAAE,CAAC,CAAC,MAAM,UAAU,IAAI,CAAC,CAAC,MAAM,YAAY;AAC9C;AACA,OAAK,OAAO;AACZ,OAAK,QAAQ;AACb,OAAK,MAAM"}
1
+ {"version":3,"file":"index.js","names":["previous","next","register","panels","children"],"sources":["../../../src/components/tabs/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { Key, TabsProps as RACTabsProps, TabListProps, TabPanelProps, TabProps, TabRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, useCallback, useContext, useEffect, useState } from 'react';\nimport { Tabs as RACTabs, Tab, TabList, TabPanel } from 'react-aria-components';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// A tinted pill marks the active tab, not the underline Material draws. That\n// is what the source design uses, and the two are different controls wearing\n// the same name: an underline belongs to a full-width tab bar, while a row of\n// pills reads as a segmented control sitting inside a section.\n//\n// The pill takes the same height, radius, and type as Chip. Both are\n// pill-shaped selection controls, and a row of tabs above a row of chips\n// looks wrong the moment the two disagree about either.\n\nconst NO_PANELS: ReadonlySet<Key> = new Set();\n\n// Which panels are mounted, by id. React Aria points a selected tab's\n// `aria-controls` at the panel it would control whether or not one exists,\n// and a strip used on its own — tabs that filter the content below rather\n// than swapping a panel — then references an id nothing carries, which axe\n// reports as an invalid attribute value. Each panel registers itself here so\n// a tab can leave the attribute off when its panel is not there.\nconst PanelsContext = createContext<ReadonlySet<Key>>(NO_PANELS);\nconst RegisterPanelContext = createContext<(id: Key) => () => void>(() => () => {});\n\n// `children` is narrowed to nodes. React Aria also accepts a function there,\n// to hand the children the tabs' render state, and that form cannot be\n// wrapped in a context provider without calling it first — which would be\n// doing React Aria's job with none of its state. Nothing here needs it, so\n// the narrower type says so rather than leaving a signature that type-checks\n// and then fails to render.\ntype TabsProps = Omit<RACTabsProps, 'children'> & {\n children?: ReactNode;\n};\n\n// React Aria renders a tab with `href` as an anchor and any other as a div,\n// and expects a `render` function to return the same element it would have.\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler memoises\n// the result on its two inputs. See PanelsContext for why the attribute is\n// dropped.\nfunction tabRenderer(hasPanel: boolean, render: TabProps['render']): NonNullable<TabProps['render']> {\n return (domProps, state) => {\n const adjusted = hasPanel ? domProps : {\n ...domProps,\n 'aria-controls': undefined\n };\n if (render !== undefined) {\n return render(adjusted, state);\n }\n if ('href' in adjusted) {\n // oxlint-disable-next-line jsx-a11y/anchor-has-content -- filled by React Aria\n return <a {...adjusted} />;\n }\n return <div {...adjusted} />;\n };\n}\n\n/**\n * A tab strip and its panels. Selection is React Aria's `selectedKey`: pass\n * it with `onSelectionChange` to control it, or `defaultSelectedKey` to let\n * it keep its own. Each `Tabs.Tab` names the `Tabs.Panel` it controls through\n * a shared `id`, and a strip may stand alone without panels.\n *\n * Composed rather than configured by props, because the number of tabs and\n * what each panel holds are the call site's to decide — the parts are\n * `Tabs.List`, `Tabs.Tab`, and `Tabs.Panel`.\n */\nfunction Tabs({\n children,\n ...props\n}: TabsProps) {\n const [panels, setPanels] = useState<ReadonlySet<Key>>(NO_PANELS);\n const register = useCallback((id: Key) => {\n setPanels(previous => {\n if (previous.has(id)) {\n return previous;\n }\n const next = new Set(previous);\n next.add(id);\n return next;\n });\n return () => {\n setPanels(previous => {\n if (!previous.has(id)) {\n return previous;\n }\n const next = new Set(previous);\n next.delete(id);\n return next;\n });\n };\n }, []);\n return <RACTabs {...props}>\n <RegisterPanelContext value={register}>\n <PanelsContext value={panels}>{children}</PanelsContext>\n </RegisterPanelContext>\n </RACTabs>;\n}\nfunction TabsList(props: TabsListProps) {\n return <TabList {...props} {...mergeStatefulStyles({\n className: \"x9f619 x78zum5 x14qo01y\"\n }, props)} />;\n}\nfunction TabsPanel(props: TabsPanelProps) {\n const register = useContext(RegisterPanelContext);\n const {\n id\n } = props;\n useEffect(() => {\n if (id === undefined) {\n return undefined;\n }\n return register(id);\n }, [id, register]);\n return <TabPanel {...props} {...mergeStatefulStyles({\n className: \"x9f619 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn\"\n }, props)} />;\n}\nfunction TabsTab({\n render,\n ...props\n}: TabsTabProps) {\n const panels = useContext(PanelsContext);\n const hasPanel = props.id !== undefined && panels.has(props.id);\n return <Tab {...props} render={tabRenderer(hasPanel, render)} {...mergeStatefulStyles(tabStyles, props)} />;\n}\n\n// StyleX cannot target [data-selected] on the element it is styling, so the\n// active pill cannot be chosen in CSS. React Aria's answer is a className that\n// is a function of the tab's own state, the same mechanism Chip uses —\n// mergeStatefulStyles wraps this one so a tab still keeps a className the call\n// site passed.\nfunction tabStyles(state: TabRenderProps) {\n return {\n 0: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 x1p2om7n xjbqb8w x1w5n3ug\"\n },\n 2: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 x1hei0q8 xp89om9 xscdzaa\"\n },\n 1: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc\"\n },\n 3: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 xc342km x9f619 x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo xl56j7k x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh xs2xxs2 xpc4ca7 xjbqb8w x1xj74d8 x1h6gzvc\"\n }\n }[!!state.isSelected << 1 | !!state.isDisabled << 0];\n}\nTabs.List = TabsList;\nTabs.Panel = TabsPanel;\nTabs.Tab = TabsTab;\ntype TabsListProps = TabListProps<object>;\ntype TabsPanelProps = TabPanelProps;\ntype TabsTabProps = TabProps;\nexport type { TabsListProps, TabsPanelProps, TabsProps, TabsTabProps };\nexport default Tabs;"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { useRender } from "@base-ui/react/use-render";
1
+ import { RenderComponentProps } from "../../render/useRender.js";
2
2
  //#region src/components/text/index.d.ts
3
- type TextProps = useRender.ComponentProps<'span'> & {
3
+ type TextProps = RenderComponentProps<'span'> & {
4
4
  /**
5
5
  * Renders a `<p>` rather than the default `<span>`, for a block of prose
6
6
  * rather than a run of text inside one.
@@ -1,6 +1,6 @@
1
1
  import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { useRender } from "../../render/useRender.js";
2
3
  import { mergeStyles } from "../../styles/merge.js";
3
- import { useRender } from "@base-ui/react/use-render";
4
4
  //#region src/components/text/index.tsx
5
5
  const styles = {
6
6
  base: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/text/index.tsx"],"sourcesContent":["import { useRender } from '@base-ui/react/use-render';\nimport * as stylex from '@stylexjs/stylex';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, typography } from '../../tokens/design.tokens.stylex';\n\n// One key per style in the 15-entry type scale, named exactly as the token\n// group names it, so `styles[variant]` indexes straight off the prop with no\n// lookup table to keep in sync. Every style sets all five fields the scale\n// defines rather than inheriting any of them: a Text nested inside another\n// Text would otherwise pick up the outer line-height or tracking, which is\n// the kind of drift the scale exists to prevent.\n//\n// `margin: 0` is the one UA reset here. Text renders a <span> by default, but\n// `block` renders a <p> and `render` is how a consumer reaches for any other\n// semantic markup — `<Text render={<h2 />}>` — and the UA margin on either\n// would then vary the spacing around otherwise identical type. The space\n// between two blocks of text is the job of whatever holds them, which is\n// where it can come from the spacing scale.\nconst styles = {\n base: {\n kB7OPa: \"x9f619\",\n kogj98: \"x1ghz6dp\",\n $$css: true\n },\n bodyLarge: {\n kMv6JI: \"x16svsjw\",\n kGuDYH: \"x1848etk\",\n k63SB2: \"x1c52epr\",\n kb6lSQ: \"x1qn8t5l\",\n kLWn49: \"xh7dzej\",\n $$css: true\n },\n bodyMedium: {\n kMv6JI: \"xpo2rfv\",\n kGuDYH: \"x193rfdd\",\n k63SB2: \"x1hews6w\",\n kb6lSQ: \"xn43zvd\",\n kLWn49: \"xv61bfh\",\n $$css: true\n },\n bodySmall: {\n kMv6JI: \"x1yicsit\",\n kGuDYH: \"x1b35g6e\",\n k63SB2: \"x9d6959\",\n kb6lSQ: \"xwth0xh\",\n kLWn49: \"xybisxh\",\n $$css: true\n },\n displayLarge: {\n kMv6JI: \"xjaampf\",\n kGuDYH: \"xuyiek4\",\n k63SB2: \"x1n2oj23\",\n kb6lSQ: \"x1hxa6v5\",\n kLWn49: \"x1iwmiir\",\n $$css: true\n },\n displayMedium: {\n kMv6JI: \"x1gi70vc\",\n kGuDYH: \"xlzzeuu\",\n k63SB2: \"xh9quta\",\n kb6lSQ: \"x148mp24\",\n kLWn49: \"xs5hucj\",\n $$css: true\n },\n displaySmall: {\n kMv6JI: \"x1eslvzl\",\n kGuDYH: \"x1g52wnc\",\n k63SB2: \"x1x664hp\",\n kb6lSQ: \"x1rnjaw4\",\n kLWn49: \"x92ldg4\",\n $$css: true\n },\n headlineLarge: {\n kMv6JI: \"x1vsmgmf\",\n kGuDYH: \"xh9c4x\",\n k63SB2: \"x1y15vu6\",\n kb6lSQ: \"xoqu3bc\",\n kLWn49: \"x10x9d6x\",\n $$css: true\n },\n headlineMedium: {\n kMv6JI: \"x18s19nt\",\n kGuDYH: \"xcohea8\",\n k63SB2: \"x1mtpwof\",\n kb6lSQ: \"x1kuyk5j\",\n kLWn49: \"xucx483\",\n $$css: true\n },\n headlineSmall: {\n kMv6JI: \"x1fz0g89\",\n kGuDYH: \"xkb6epg\",\n k63SB2: \"x76yrz5\",\n kb6lSQ: \"x1s1qhaa\",\n kLWn49: \"x1voeury\",\n $$css: true\n },\n labelLarge: {\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n $$css: true\n },\n labelMedium: {\n kMv6JI: \"xp6n8n2\",\n kGuDYH: \"xkucv67\",\n k63SB2: \"x14hhc5u\",\n kb6lSQ: \"x12utw95\",\n kLWn49: \"xvzb9hk\",\n $$css: true\n },\n labelSmall: {\n kMv6JI: \"xs1w0rn\",\n kGuDYH: \"x1n35her\",\n k63SB2: \"x1su64ma\",\n kb6lSQ: \"xdlnduh\",\n kLWn49: \"xaomhve\",\n $$css: true\n },\n titleLarge: {\n kMv6JI: \"xdy5w5q\",\n kGuDYH: \"xete2z3\",\n k63SB2: \"x14ijtet\",\n kb6lSQ: \"xug9e1u\",\n kLWn49: \"x2divse\",\n $$css: true\n },\n titleMedium: {\n kMv6JI: \"x46eyla\",\n kGuDYH: \"x5ehqhr\",\n k63SB2: \"xrf6cl6\",\n kb6lSQ: \"x1g135zh\",\n kLWn49: \"x1ggk5va\",\n $$css: true\n },\n titleSmall: {\n kMv6JI: \"xrgwony\",\n kGuDYH: \"x12s497w\",\n k63SB2: \"x1szcwkt\",\n kb6lSQ: \"xo803ec\",\n kLWn49: \"xyl1r0q\",\n $$css: true\n }\n};\n\n// Tone is a separate axis from variant so the two compose freely — any of the\n// 15 scale styles in any of these colors. Kept to the roles text actually\n// takes on a surface; a consumer needing something outside this set uses\n// `inherit` and colors the parent, rather than this growing a case per role.\nconst tones = {\n default: {\n kMwMTN: \"x139gbkf\",\n $$css: true\n },\n error: {\n kMwMTN: \"x4ii1qj\",\n $$css: true\n },\n inherit: {\n kMwMTN: \"x1heor9g\",\n $$css: true\n },\n muted: {\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n negative: {\n kMwMTN: \"x12gp0t\",\n $$css: true\n },\n positive: {\n kMwMTN: \"x4no3js\",\n $$css: true\n },\n primary: {\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n }\n};\ntype TextProps = useRender.ComponentProps<'span'> & {\n /**\n * Renders a `<p>` rather than the default `<span>`, for a block of prose\n * rather than a run of text inside one.\n *\n * The paragraph carries no margin of its own, the same as every other Text.\n * The space between two paragraphs belongs to whatever holds both of them,\n * which is where it can be a step of the spacing scale rather than a\n * browser default.\n *\n * Ignored when `render` is given, since that names the element outright.\n * @default false\n */\n block?: boolean;\n /**\n * The color role to render in. `inherit` takes the color of the nearest\n * colored ancestor instead of setting one.\n * @default 'default'\n */\n tone?: 'default' | 'error' | 'inherit' | 'muted' | 'negative' | 'positive' | 'primary';\n /**\n * Which style of the type scale to render.\n * @default 'bodyMedium'\n */\n variant?: 'bodyLarge' | 'bodyMedium' | 'bodySmall' | 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall';\n};\nfunction Text({\n block = false,\n render,\n tone = 'default',\n variant = 'bodyMedium',\n ...props\n}: TextProps) {\n return useRender({\n // Card switches its default element the same way, and the props type\n // stays the span's for the same reason: the two differ only in the ref's\n // element interface, and neither adds anything a call site reaches for.\n defaultTagName: block ? 'p' : 'span',\n props: {\n ...props,\n ...mergeStyles(stylex.props(styles.base, styles[variant], tones[tone]), props)\n },\n render\n });\n}\nexport type { TextProps };\nexport default Text;"],"mappings":";;;;AAmBA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,WAAW;EACT,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,WAAW;EACT,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,cAAc;EACZ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,cAAc;EACZ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,gBAAgB;EACd,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;AACF;AAMA,MAAM,QAAQ;CACZ,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;AACF;AA2BA,SAAS,KAAK,EACZ,QAAQ,OACR,QACA,OAAO,WACP,UAAU,cACV,GAAG,WACS;CACZ,OAAO,UAAU;EAIf,gBAAgB,QAAQ,MAAM;EAC9B,OAAO;GACL,GAAG;GACH,GAAG,YAAY,MAAa,OAAO,MAAM,OAAO,UAAU,MAAM,KAAK,GAAG,OAAK;EAC/E;EACA;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/text/index.tsx"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { useRender } from '../../render/useRender';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, typography } from '../../tokens/design.tokens.stylex';\n\n// One key per style in the 15-entry type scale, named exactly as the token\n// group names it, so `styles[variant]` indexes straight off the prop with no\n// lookup table to keep in sync. Every style sets all five fields the scale\n// defines rather than inheriting any of them: a Text nested inside another\n// Text would otherwise pick up the outer line-height or tracking, which is\n// the kind of drift the scale exists to prevent.\n//\n// `margin: 0` is the one UA reset here. Text renders a <span> by default, but\n// `block` renders a <p> and `render` is how a consumer reaches for any other\n// semantic markup — `<Text render={<h2 />}>` — and the UA margin on either\n// would then vary the spacing around otherwise identical type. The space\n// between two blocks of text is the job of whatever holds them, which is\n// where it can come from the spacing scale.\nconst styles = {\n base: {\n kB7OPa: \"x9f619\",\n kogj98: \"x1ghz6dp\",\n $$css: true\n },\n bodyLarge: {\n kMv6JI: \"x16svsjw\",\n kGuDYH: \"x1848etk\",\n k63SB2: \"x1c52epr\",\n kb6lSQ: \"x1qn8t5l\",\n kLWn49: \"xh7dzej\",\n $$css: true\n },\n bodyMedium: {\n kMv6JI: \"xpo2rfv\",\n kGuDYH: \"x193rfdd\",\n k63SB2: \"x1hews6w\",\n kb6lSQ: \"xn43zvd\",\n kLWn49: \"xv61bfh\",\n $$css: true\n },\n bodySmall: {\n kMv6JI: \"x1yicsit\",\n kGuDYH: \"x1b35g6e\",\n k63SB2: \"x9d6959\",\n kb6lSQ: \"xwth0xh\",\n kLWn49: \"xybisxh\",\n $$css: true\n },\n displayLarge: {\n kMv6JI: \"xjaampf\",\n kGuDYH: \"xuyiek4\",\n k63SB2: \"x1n2oj23\",\n kb6lSQ: \"x1hxa6v5\",\n kLWn49: \"x1iwmiir\",\n $$css: true\n },\n displayMedium: {\n kMv6JI: \"x1gi70vc\",\n kGuDYH: \"xlzzeuu\",\n k63SB2: \"xh9quta\",\n kb6lSQ: \"x148mp24\",\n kLWn49: \"xs5hucj\",\n $$css: true\n },\n displaySmall: {\n kMv6JI: \"x1eslvzl\",\n kGuDYH: \"x1g52wnc\",\n k63SB2: \"x1x664hp\",\n kb6lSQ: \"x1rnjaw4\",\n kLWn49: \"x92ldg4\",\n $$css: true\n },\n headlineLarge: {\n kMv6JI: \"x1vsmgmf\",\n kGuDYH: \"xh9c4x\",\n k63SB2: \"x1y15vu6\",\n kb6lSQ: \"xoqu3bc\",\n kLWn49: \"x10x9d6x\",\n $$css: true\n },\n headlineMedium: {\n kMv6JI: \"x18s19nt\",\n kGuDYH: \"xcohea8\",\n k63SB2: \"x1mtpwof\",\n kb6lSQ: \"x1kuyk5j\",\n kLWn49: \"xucx483\",\n $$css: true\n },\n headlineSmall: {\n kMv6JI: \"x1fz0g89\",\n kGuDYH: \"xkb6epg\",\n k63SB2: \"x76yrz5\",\n kb6lSQ: \"x1s1qhaa\",\n kLWn49: \"x1voeury\",\n $$css: true\n },\n labelLarge: {\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n $$css: true\n },\n labelMedium: {\n kMv6JI: \"xp6n8n2\",\n kGuDYH: \"xkucv67\",\n k63SB2: \"x14hhc5u\",\n kb6lSQ: \"x12utw95\",\n kLWn49: \"xvzb9hk\",\n $$css: true\n },\n labelSmall: {\n kMv6JI: \"xs1w0rn\",\n kGuDYH: \"x1n35her\",\n k63SB2: \"x1su64ma\",\n kb6lSQ: \"xdlnduh\",\n kLWn49: \"xaomhve\",\n $$css: true\n },\n titleLarge: {\n kMv6JI: \"xdy5w5q\",\n kGuDYH: \"xete2z3\",\n k63SB2: \"x14ijtet\",\n kb6lSQ: \"xug9e1u\",\n kLWn49: \"x2divse\",\n $$css: true\n },\n titleMedium: {\n kMv6JI: \"x46eyla\",\n kGuDYH: \"x5ehqhr\",\n k63SB2: \"xrf6cl6\",\n kb6lSQ: \"x1g135zh\",\n kLWn49: \"x1ggk5va\",\n $$css: true\n },\n titleSmall: {\n kMv6JI: \"xrgwony\",\n kGuDYH: \"x12s497w\",\n k63SB2: \"x1szcwkt\",\n kb6lSQ: \"xo803ec\",\n kLWn49: \"xyl1r0q\",\n $$css: true\n }\n};\n\n// Tone is a separate axis from variant so the two compose freely — any of the\n// 15 scale styles in any of these colors. Kept to the roles text actually\n// takes on a surface; a consumer needing something outside this set uses\n// `inherit` and colors the parent, rather than this growing a case per role.\nconst tones = {\n default: {\n kMwMTN: \"x139gbkf\",\n $$css: true\n },\n error: {\n kMwMTN: \"x4ii1qj\",\n $$css: true\n },\n inherit: {\n kMwMTN: \"x1heor9g\",\n $$css: true\n },\n muted: {\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n negative: {\n kMwMTN: \"x12gp0t\",\n $$css: true\n },\n positive: {\n kMwMTN: \"x4no3js\",\n $$css: true\n },\n primary: {\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n }\n};\ntype TextProps = RenderComponentProps<'span'> & {\n /**\n * Renders a `<p>` rather than the default `<span>`, for a block of prose\n * rather than a run of text inside one.\n *\n * The paragraph carries no margin of its own, the same as every other Text.\n * The space between two paragraphs belongs to whatever holds both of them,\n * which is where it can be a step of the spacing scale rather than a\n * browser default.\n *\n * Ignored when `render` is given, since that names the element outright.\n * @default false\n */\n block?: boolean;\n /**\n * The color role to render in. `inherit` takes the color of the nearest\n * colored ancestor instead of setting one.\n * @default 'default'\n */\n tone?: 'default' | 'error' | 'inherit' | 'muted' | 'negative' | 'positive' | 'primary';\n /**\n * Which style of the type scale to render.\n * @default 'bodyMedium'\n */\n variant?: 'bodyLarge' | 'bodyMedium' | 'bodySmall' | 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall';\n};\nfunction Text({\n block = false,\n render,\n tone = 'default',\n variant = 'bodyMedium',\n ...props\n}: TextProps) {\n return useRender({\n // Card switches its default element the same way, and the props type\n // stays the span's for the same reason: the two differ only in the ref's\n // element interface, and neither adds anything a call site reaches for.\n defaultTagName: block ? 'p' : 'span',\n props: {\n ...props,\n ...mergeStyles(stylex.props(styles.base, styles[variant], tones[tone]), props)\n },\n render\n });\n}\nexport type { TextProps };\nexport default Text;"],"mappings":";;;;AAoBA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,WAAW;EACT,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,WAAW;EACT,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,cAAc;EACZ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,cAAc;EACZ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,gBAAgB;EACd,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,eAAe;EACb,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;AACF;AAMA,MAAM,QAAQ;CACZ,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;AACF;AA2BA,SAAS,KAAK,EACZ,QAAQ,OACR,QACA,OAAO,WACP,UAAU,cACV,GAAG,WACS;CACZ,OAAO,UAAU;EAIf,gBAAgB,QAAQ,MAAM;EAC9B,OAAO;GACL,GAAG;GACH,GAAG,YAAY,MAAa,OAAO,MAAM,OAAO,UAAU,MAAM,KAAK,GAAG,OAAK;EAC/E;EACA;CACF,CAAC;AACH"}
@@ -1,6 +1,6 @@
1
- import { FieldControlProps } from "@base-ui/react/field";
1
+ import { TextFieldProps } from "react-aria-components";
2
2
  //#region src/components/text-field/index.d.ts
3
- type TextFieldProps = {
3
+ type TextFieldProps$1 = {
4
4
  /**
5
5
  * A hint shown under the field. Replaced by `error` when there is one, so
6
6
  * the two never stack.
@@ -23,8 +23,15 @@ type TextFieldProps = {
23
23
  * @default false
24
24
  */
25
25
  numeric?: boolean;
26
- } & Omit<FieldControlProps, 'render'>;
27
- declare function TextField({ description, disabled, error, label, numeric, ...props }: TextFieldProps): import("react").JSX.Element;
26
+ } & Omit<TextFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;
27
+ /**
28
+ * A labelled single-line input. Its value is React Aria's: pass `value` with
29
+ * `onChange` to control it, or `defaultValue` to let it keep its own — and
30
+ * `onChange` is handed the string, not the event. The call site's
31
+ * `className` and `style` land on the field as a whole, which is the element
32
+ * a layout positions.
33
+ */
34
+ declare function TextField$1({ description, error, isDisabled, label, numeric, ...props }: TextFieldProps$1): import("react").JSX.Element;
28
35
  //#endregion
29
- export { type TextFieldProps, TextField as default };
36
+ export { type TextFieldProps$1 as TextFieldProps, TextField$1 as default };
30
37
  //# sourceMappingURL=index.d.ts.map
@@ -1,54 +1,69 @@
1
1
  import { mergeStatefulStyles } from "../../styles/merge.js";
2
+ import { useCallback, useState } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback } from "react";
4
- import { Field } from "@base-ui/react/field";
4
+ import { Input, Label, Text, TextField } from "react-aria-components";
5
5
  //#region src/components/text-field/index.tsx
6
- function TextField({ description, disabled = false, error, label, numeric = false, ...props }) {
6
+ /**
7
+ * A labelled single-line input. Its value is React Aria's: pass `value` with
8
+ * `onChange` to control it, or `defaultValue` to let it keep its own — and
9
+ * `onChange` is handed the string, not the event. The call site's
10
+ * `className` and `style` land on the field as a whole, which is the element
11
+ * a layout positions.
12
+ */
13
+ function TextField$1({ description, error, isDisabled = false, label, numeric = false, ...props }) {
7
14
  const invalid = error !== void 0;
8
- const labelClassName = useCallback((state) => ({
9
- 0: { className: "x1w5n3ug xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7" },
10
- 4: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1xj74d8" },
11
- 2: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj" },
12
- 6: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj" },
13
- 1: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
14
- 5: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
15
- 3: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
16
- 7: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" }
17
- })[!!disabled << 2 | !!invalid << 1 | !!(!disabled && !invalid && state.focused) << 0].className, [disabled, invalid]);
18
- return /* @__PURE__ */ jsxs(Field.Root, {
19
- disabled,
20
- invalid,
21
- className: "x9f619 x78zum5 xdt5ytf",
15
+ const [focused, setFocused] = useState(false);
16
+ const handleFocus = useCallback(() => {
17
+ setFocused(true);
18
+ }, []);
19
+ const handleBlur = useCallback(() => {
20
+ setFocused(false);
21
+ }, []);
22
+ return /* @__PURE__ */ jsxs(TextField, {
23
+ isDisabled,
24
+ isInvalid: invalid,
25
+ validationBehavior: "aria",
26
+ ...props,
27
+ ...mergeStatefulStyles({ className: "x9f619 x78zum5 xdt5ytf" }, props),
22
28
  children: [/* @__PURE__ */ jsxs("div", {
29
+ onBlur: handleBlur,
30
+ onFocus: handleFocus,
23
31
  ...{
24
32
  0: { className: "x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x89kqus x18rfq6m x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7" },
25
33
  2: { className: "x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 x1lxxh4i x1d6xoej" },
26
34
  1: { className: "xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1" },
27
35
  3: { className: "xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1" }
28
- }[!!invalid << 1 | !!disabled << 0],
29
- children: [/* @__PURE__ */ jsx(Field.Label, {
30
- className: labelClassName,
36
+ }[!!invalid << 1 | !!isDisabled << 0],
37
+ children: [/* @__PURE__ */ jsx(Label, {
38
+ ...{
39
+ 0: { className: "x1w5n3ug xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7" },
40
+ 4: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1xj74d8" },
41
+ 2: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj" },
42
+ 6: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj" },
43
+ 1: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
44
+ 5: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
45
+ 3: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" },
46
+ 7: { className: "xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y" }
47
+ }[!!isDisabled << 2 | !!invalid << 1 | !!(!isDisabled && !invalid && focused) << 0],
31
48
  children: label
32
- }), /* @__PURE__ */ jsx(Field.Control, {
33
- ...props,
34
- ...mergeStatefulStyles({
35
- 0: { className: "xjbqb8w xc342km x9f619 x139gbkf x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv" },
36
- 2: { className: "xjbqb8w xc342km x9f619 x139gbkf x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b" },
37
- 1: { className: "xjbqb8w xc342km x9f619 x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv x1xj74d8" },
38
- 3: { className: "xjbqb8w xc342km x9f619 x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b x1xj74d8" }
39
- }[!!numeric << 1 | !!disabled << 0], props)
40
- })]
41
- }), invalid ? /* @__PURE__ */ jsx(Field.Error, {
42
- match: true,
49
+ }), /* @__PURE__ */ jsx(Input, { ...{
50
+ 0: { className: "xjbqb8w xc342km x9f619 x139gbkf x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv" },
51
+ 2: { className: "xjbqb8w xc342km x9f619 x139gbkf x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b" },
52
+ 1: { className: "xjbqb8w xc342km x9f619 x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv x1xj74d8" },
53
+ 3: { className: "xjbqb8w xc342km x9f619 x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b x1xj74d8" }
54
+ }[!!numeric << 1 | !!isDisabled << 0] })]
55
+ }), invalid ? /* @__PURE__ */ jsx(Text, {
56
+ slot: "errorMessage",
43
57
  className: "x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi x4ii1qj",
44
58
  children: error
45
- }) : description === void 0 ? null : /* @__PURE__ */ jsx(Field.Description, {
59
+ }) : description === void 0 ? null : /* @__PURE__ */ jsx(Text, {
60
+ slot: "description",
46
61
  className: "x1w5n3ug x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi",
47
62
  children: description
48
63
  })]
49
64
  });
50
65
  }
51
66
  //#endregion
52
- export { TextField as default };
67
+ export { TextField$1 as default };
53
68
 
54
69
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/text-field/index.tsx"],"sourcesContent":["import type { FieldControlProps as BaseUIFieldControlProps, FieldLabelState as BaseUIFieldLabelState } from '@base-ui/react/field';\nimport { Field as BaseUIField } from '@base-ui/react/field';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback } from 'react';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The focus indicator is an inset box-shadow on the bottom edge rather than a\n// border that thickens. A real border going 1px -> 2px on focus grows the\n// box, which pushes every sibling below it down by a pixel — so a form\n// twitches each time focus moves between its fields. A shadow is drawn inside\n// the box and changes nothing about its size.\n//\n// The label sits at a fixed size at the top rather than floating up out of\n// the input on focus: the design draws it small and in place at all times, so\n// there is no transition between two positions to get right.\n\ntype TextFieldProps = {\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message, the red underline, and\n * `aria-invalid` all follow from it.\n */\n error?: string;\n /**\n * What the field is for. Required rather than optional: a text field with\n * no label is a box a screen reader cannot name.\n */\n label: string;\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column.\n * @default false\n */\n numeric?: boolean;\n} & Omit<BaseUIFieldControlProps, 'render'>;\nfunction TextField({\n description,\n disabled = false,\n error,\n label,\n numeric = false,\n ...props\n}: TextFieldProps) {\n const invalid = error !== undefined;\n\n // The label's colour follows the field's focus, which is a state only Base\n // UI knows StyleX cannot express `.box:focus-within .label`, because the\n // label is the input's sibling rather than its ancestor. useCallback keeps\n // it one reference between renders, which is what react-perf is after.\n const labelClassName = useCallback((state: BaseUIFieldLabelState) => ({\n 0: {\n className: \"x1w5n3ug xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7\"\n },\n 4: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1xj74d8\"\n },\n 2: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj\"\n },\n 6: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj\"\n },\n 1: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 5: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 3: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 7: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n }\n })[!!disabled << 2 | !!invalid << 1 | !!(!disabled && !invalid && state.focused) << 0].className, [disabled, invalid]);\n return <BaseUIField.Root disabled={disabled} invalid={invalid} className=\"x9f619 x78zum5 xdt5ytf\">\n <div {...{\n 0: {\n className: \"x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x89kqus x18rfq6m x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7\"\n },\n 2: {\n className: \"x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 x1lxxh4i x1d6xoej\"\n },\n 1: {\n className: \"xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1\"\n },\n 3: {\n className: \"xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1\"\n }\n }[!!invalid << 1 | !!disabled << 0]}>\n <BaseUIField.Label className={labelClassName}>\n {label}\n </BaseUIField.Label>\n {/* `props` is the control's, which is what TextFieldProps extends,\n so a className or style from the call site lands on the <input>\n rather than on the wrapper around it. */}\n <BaseUIField.Control {...props} {...mergeStatefulStyles({\n 0: {\n className: \"xjbqb8w xc342km x9f619 x139gbkf x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv\"\n },\n 2: {\n className: \"xjbqb8w xc342km x9f619 x139gbkf x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b\"\n },\n 1: {\n className: \"xjbqb8w xc342km x9f619 x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv x1xj74d8\"\n },\n 3: {\n className: \"xjbqb8w xc342km x9f619 x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b x1xj74d8\"\n }\n }[!!numeric << 1 | !!disabled << 0], props)} />\n </div>\n {invalid ? <BaseUIField.Error match className=\"x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi x4ii1qj\">\n {error}\n </BaseUIField.Error> : description === undefined ? null : <BaseUIField.Description className=\"x1w5n3ug x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi\">\n {description}\n </BaseUIField.Description>}\n </BaseUIField.Root>;\n}\nexport type { TextFieldProps };\nexport default TextField;"],"mappings":";;;;;AA0CA,SAAS,UAAU,EACjB,aACA,WAAW,OACX,OACA,OACA,UAAU,OACV,GAAG,SACc;CACjB,MAAM,UAAU,UAAU,KAAA;CAM1B,MAAM,iBAAiB,aAAa,WAAkC;EACpE,GAAG,EACD,WAAW,yGACb;EACA,GAAG,EACD,WAAW,yGACb;EACA,GAAG,EACD,WAAW,wGACb;EACA,GAAG,EACD,WAAW,wGACb;EACA,GAAG,EACD,WAAW,yGACb;EACA,GAAG,EACD,WAAW,yGACb;EACA,GAAG,EACD,WAAW,yGACb;EACA,GAAG,EACD,WAAW,yGACb;CACF,EAAA,CAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,MAAM,YAAY,EAAE,CAAC,WAAW,CAAC,UAAU,OAAO,CAAC;CACrH,OAAO,qBAAC,MAAY,MAAb;EAA4B;EAAmB;EAAS,WAAU;EAAlE,UAAA,CACH,qBAAC,OAAD;GAAK,GAAI;IACT,GAAG,EACD,WAAW,uIACb;IACA,GAAG,EACD,WAAW,wIACb;IACA,GAAG,EACD,WAAW,8HACb;IACA,GAAG,EACD,WAAW,8HACb;GACF,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY;GAb/B,UAAA,CAcE,oBAAC,MAAY,OAAb;IAAmB,WAAW;IAC3B,UAAA;GACgB,CAAA,GAInB,oBAAC,MAAY,SAAb;IAAqB,GAAI;IAAO,GAAI,oBAAoB;KACxD,GAAG,EACD,WAAW,iHACb;KACA,GAAG,EACD,WAAW,wHACb;KACA,GAAG,EACD,WAAW,iHACb;KACA,GAAG,EACD,WAAW,wHACb;IACF,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,IAAI,KAAK;GAAE,CAAA,CACvC;EACJ,CAAA,GAAA,UAAU,oBAAC,MAAY,OAAb;GAAmB,OAAA;GAAM,WAAU;GACzC,UAAA;EACgB,CAAA,IAAI,gBAAgB,KAAA,IAAY,OAAO,oBAAC,MAAY,aAAb;GAAyB,WAAU;GAC1F,UAAA;EACsB,CAAA,CACX;;AACtB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/text-field/index.tsx"],"sourcesContent":["import type { TextFieldProps as RACTextFieldProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback, useState } from 'react';\nimport { Input, Label, TextField as RACTextField, Text } from 'react-aria-components';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The focus indicator is an inset box-shadow on the bottom edge rather than a\n// border that thickens. A real border going 1px -> 2px on focus grows the\n// box, which pushes every sibling below it down by a pixel — so a form\n// twitches each time focus moves between its fields. A shadow is drawn inside\n// the box and changes nothing about its size.\n//\n// The label sits at a fixed size at the top rather than floating up out of\n// the input on focus: the design draws it small and in place at all times, so\n// there is no transition between two positions to get right.\n//\n// The label's colour follows the input's focus, which no selector on the\n// label alone can express — the label is the input's sibling, not its\n// ancestor. The box tracks whether focus is within it, through the focus\n// events React bubbles, and the label takes `labelFocused` from that state.\n\ntype TextFieldProps = {\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message, the red underline, and\n * `aria-invalid` all follow from it.\n */\n error?: string;\n /**\n * What the field is for. Required rather than optional: a text field with\n * no label is a box a screen reader cannot name.\n */\n label: string;\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column.\n * @default false\n */\n numeric?: boolean;\n} & Omit<RACTextFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n/**\n * A labelled single-line input. Its value is React Aria's: pass `value` with\n * `onChange` to control it, or `defaultValue` to let it keep its own — and\n * `onChange` is handed the string, not the event. The call site's\n * `className` and `style` land on the field as a whole, which is the element\n * a layout positions.\n */\nfunction TextField({\n description,\n error,\n isDisabled = false,\n label,\n numeric = false,\n ...props\n}: TextFieldProps) {\n const invalid = error !== undefined;\n\n // Focus events bubble in React, so the box hears its input gain and lose\n // focus without the input being told anything.\n const [focused, setFocused] = useState(false);\n const handleFocus = useCallback(() => {\n setFocused(true);\n }, []);\n const handleBlur = useCallback(() => {\n setFocused(false);\n }, []);\n return <RACTextField isDisabled={isDisabled} isInvalid={invalid}\n // The message is this component's to show, so validation only marks\n // the control rather than surfacing the browser's own constraint UI.\n validationBehavior=\"aria\" {...props} {...mergeStatefulStyles({\n className: \"x9f619 x78zum5 xdt5ytf\"\n }, props)}>\n <div onBlur={handleBlur} onFocus={handleFocus} {...{\n 0: {\n className: \"x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x89kqus x18rfq6m x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7\"\n },\n 2: {\n className: \"x1rrhr5q xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 x1lxxh4i x1d6xoej\"\n },\n 1: {\n className: \"xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1\"\n },\n 3: {\n className: \"xnnlda6 x16uus16 xbiv7yw xirz1nw xzcck0f x9f619 x18d9i69 xi7mcox x790zyz x1n2onr6 x1qno0dh xkdsq27 xpc4ca7 xepofeg x1pqbjc1\"\n }\n }[!!invalid << 1 | !!isDisabled << 0]}>\n <Label {...{\n 0: {\n className: \"x1w5n3ug xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7\"\n },\n 4: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1xj74d8\"\n },\n 2: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj\"\n },\n 6: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x4ii1qj\"\n },\n 1: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 5: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 3: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n },\n 7: {\n className: \"xp6n8n2 xkucv67 x14hhc5u x1we8soy x19v39ok x12utw95 xvzb9hk x10l6tqk x1qno0dh xt3l3uh xpc4ca7 x1mxwv8y\"\n }\n }[!!isDisabled << 2 | !!invalid << 1 | !!(!isDisabled && !invalid && focused) << 0]}>\n {label}\n </Label>\n <Input {...{\n 0: {\n className: \"xjbqb8w xc342km x9f619 x139gbkf x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv\"\n },\n 2: {\n className: \"xjbqb8w xc342km x9f619 x139gbkf x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b\"\n },\n 1: {\n className: \"xjbqb8w xc342km x9f619 x16svsjw x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv x1xj74d8\"\n },\n 3: {\n className: \"xjbqb8w xc342km x9f619 x1848etk x1c52epr xh8yej3 x1qn8t5l xh7dzej x1hmvnq2 x1t137rt x1717udv xbppi91 xss6m8b x1xj74d8\"\n }\n }[!!numeric << 1 | !!isDisabled << 0]} />\n </div>\n {invalid ? <Text slot=\"errorMessage\" className=\"x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi x4ii1qj\">\n {error}\n </Text> : description === undefined ? null : <Text slot=\"description\" className=\"x1w5n3ug x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh x10im51j x1y88zpp xboopgi\">\n {description}\n </Text>}\n </RACTextField>;\n}\nexport type { TextFieldProps };\nexport default TextField;"],"mappings":";;;;;;;;;;;;AAuDA,SAAS,YAAU,EACjB,aACA,OACA,aAAa,OACb,OACA,UAAU,OACV,GAAG,SACc;CACjB,MAAM,UAAU,UAAU,KAAA;CAI1B,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,cAAc,kBAAkB;EACpC,WAAW,IAAI;CACjB,GAAG,CAAA,CAAE;CACL,MAAM,aAAa,kBAAkB;EACnC,WAAW,KAAK;CAClB,GAAG,CAAA,CAAE;CACL,OAAO,qBAAC,WAAD;EAA0B;EAAY,WAAW;EAGxD,oBAAmB;EAAO,GAAI;EAAO,GAAI,oBAAoB,EAC3D,WAAW,yBACb,GAAG,KAAK;EALD,UAAA,CAMH,qBAAC,OAAD;GAAK,QAAQ;GAAY,SAAS;GAAa,GAAI;IACnD,GAAG,EACD,WAAW,uIACb;IACA,GAAG,EACD,WAAW,wIACb;IACA,GAAG,EACD,WAAW,8HACb;IACA,GAAG,EACD,WAAW,8HACb;GACF,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,cAAc;GAbjC,UAAA,CAcE,oBAAC,OAAD;IAAO,GAAI;KACX,GAAG,EACD,WAAW,yGACb;KACA,GAAG,EACD,WAAW,yGACb;KACA,GAAG,EACD,WAAW,wGACb;KACA,GAAG,EACD,WAAW,wGACb;KACA,GAAG,EACD,WAAW,yGACb;KACA,GAAG,EACD,WAAW,yGACb;KACA,GAAG,EACD,WAAW,yGACb;KACA,GAAG,EACD,WAAW,yGACb;IACF,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,WAAW,YAAY;IAC5E,UAAA;GACI,CAAA,GACP,oBAAC,OAAD,EAAO,GAAI;IACX,GAAG,EACD,WAAW,iHACb;IACA,GAAG,EACD,WAAW,wHACb;IACA,GAAG,EACD,WAAW,iHACb;IACA,GAAG,EACD,WAAW,wHACb;GACF,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,cAAc,GAAG,CAAA,CACjC;EACJ,CAAA,GAAA,UAAU,oBAAC,MAAD;GAAM,MAAK;GAAe,WAAU;GAC1C,UAAA;EACG,CAAA,IAAI,gBAAgB,KAAA,IAAY,OAAO,oBAAC,MAAD;GAAM,MAAK;GAAc,WAAU;GAC7E,UAAA;EACG,CAAA,CACI;;AAClB"}
@@ -0,0 +1,53 @@
1
+ import { useEffect, useState } from "react";
2
+ import { c } from "react/compiler-runtime";
3
+ //#region src/hooks/useImageLoadingStatus.ts
4
+ /**
5
+ * Whether an image at `src` can be shown yet. It is loaded off-screen first,
6
+ * so a component can keep its fallback in place until the picture is ready
7
+ * and bring the fallback back if the picture fails — an `<img>` swapped in
8
+ * as soon as `src` is known would show the browser's broken-image glyph in
9
+ * between.
10
+ *
11
+ * No `src` counts as a failure, since the outcome is the same: the fallback
12
+ * shows. What settled is remembered against the `src` it settled for, so a
13
+ * change of `src` reads as loading again rather than as the old outcome.
14
+ */
15
+ function useImageLoadingStatus(src) {
16
+ const $ = c(3);
17
+ const [settled, setSettled] = useState(null);
18
+ let t0;
19
+ let t1;
20
+ if ($[0] !== src) {
21
+ t0 = () => {
22
+ if (src === void 0) return;
23
+ let mounted = true;
24
+ const settle = (status) => () => {
25
+ if (mounted) setSettled({
26
+ src,
27
+ status
28
+ });
29
+ };
30
+ const image = new window.Image();
31
+ image.addEventListener("load", settle("loaded"), { once: true });
32
+ image.addEventListener("error", settle("error"), { once: true });
33
+ image.src = src;
34
+ return () => {
35
+ mounted = false;
36
+ };
37
+ };
38
+ t1 = [src];
39
+ $[0] = src;
40
+ $[1] = t0;
41
+ $[2] = t1;
42
+ } else {
43
+ t0 = $[1];
44
+ t1 = $[2];
45
+ }
46
+ useEffect(t0, t1);
47
+ if (src === void 0) return "error";
48
+ return settled?.src === src ? settled.status : "loading";
49
+ }
50
+ //#endregion
51
+ export { useImageLoadingStatus };
52
+
53
+ //# sourceMappingURL=useImageLoadingStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useImageLoadingStatus.js","names":["mounted"],"sources":["../../src/hooks/useImageLoadingStatus.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\n\ntype ImageLoadingStatus = 'error' | 'loaded' | 'loading'\n\ninterface Settled {\n src: string\n status: 'error' | 'loaded'\n}\n\n/**\n * Whether an image at `src` can be shown yet. It is loaded off-screen first,\n * so a component can keep its fallback in place until the picture is ready\n * and bring the fallback back if the picture fails — an `<img>` swapped in\n * as soon as `src` is known would show the browser's broken-image glyph in\n * between.\n *\n * No `src` counts as a failure, since the outcome is the same: the fallback\n * shows. What settled is remembered against the `src` it settled for, so a\n * change of `src` reads as loading again rather than as the old outcome.\n */\nfunction useImageLoadingStatus(src: string | undefined): ImageLoadingStatus {\n const [settled, setSettled] = useState<null | Settled>(null)\n\n useEffect(() => {\n if (src === undefined) {\n return undefined\n }\n\n let mounted = true\n const settle = (status: Settled['status']) => () => {\n if (mounted) {\n setSettled({ src, status })\n }\n }\n\n const image = new window.Image()\n image.addEventListener('load', settle('loaded'), { once: true })\n image.addEventListener('error', settle('error'), { once: true })\n image.src = src\n\n return () => {\n mounted = false\n }\n }, [src])\n\n if (src === undefined) {\n return 'error'\n }\n return settled?.src === src ? settled.status : 'loading'\n}\n\nexport type { ImageLoadingStatus }\n\nexport { useImageLoadingStatus }\n"],"mappings":";;;;;;;;;;;;;;AAoBA,SAAA,sBAAA,KAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CACE,MAAA,CAAA,SAAA,cAA8B,SAAyB,IAAI;CAAC,IAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,KAAA;EAElD,WAAA;GACR,IAAI,QAAQ,KAAA,GAAS;GAIrB,IAAA,UAAc;GACd,MAAA,UAAe,iBAA+B;IAC5C,IAAI,SACF,WAAW;KAAA;KAAA;IAAc,CAAC;GAC3B;GAGH,MAAA,QAAc,IAAI,OAAM,MAAO;GAC/B,MAAK,iBAAkB,QAAQ,OAAO,QAAQ,GAAG,EAAA,MAAQ,KAAK,CAAC;GAC/D,MAAK,iBAAkB,SAAS,OAAO,OAAO,GAAG,EAAA,MAAQ,KAAK,CAAC;GAC/D,MAAK,MAAO;GAAH,aAEF;IACL,UAAUA;GAAH;EACR;EACA,KAAA,CAAC,GAAG;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;CAAA;CApBR,UAAU,IAoBP,EAAK;CAER,IAAI,QAAQ,KAAA,GAAS,OACZ;CACR,OACM,SAAO,QAAU,MAAM,QAAO,SAA9B;AAAiD"}
@@ -1,9 +1,9 @@
1
1
  import { props } from "../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { rippleStyles as styles } from "../styles/ripple.js";
3
3
  import { motionDurationMs, motionEasing, spacingPx } from "../tokens/values.js";
4
+ import { useRef, useState } from "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  import { c } from "react/compiler-runtime";
6
- import { useRef, useState } from "react";
7
7
  //#region src/hooks/useRipple.tsx
8
8
  /** How far the ripple grows past the host's corners. `spacing.sm`. */
9
9
  const PADDING = spacingPx.sm;