@kanso-labs/kanso-ui 0.40.5 → 0.40.7

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 (100) hide show
  1. package/dist/button/hooks.js +37 -1
  2. package/dist/button/hooks.js.map +1 -1
  3. package/dist/button/index.d.ts +57 -1
  4. package/dist/button/index.js +153 -96
  5. package/dist/button/index.js.map +1 -1
  6. package/dist/button/toggle.js +17 -0
  7. package/dist/button/toggle.js.map +1 -0
  8. package/dist/calendar/index.js +69 -58
  9. package/dist/calendar/index.js.map +1 -1
  10. package/dist/calendar/styles.js +29 -6
  11. package/dist/calendar/styles.js.map +1 -1
  12. package/dist/chip/index.js +3 -4
  13. package/dist/chip/index.js.map +1 -1
  14. package/dist/chip/styles.js +2 -6
  15. package/dist/chip/styles.js.map +1 -1
  16. package/dist/collection/empty.js +7 -0
  17. package/dist/collection/empty.js.map +1 -0
  18. package/dist/collection/index.js +125 -2
  19. package/dist/collection/index.js.map +1 -1
  20. package/dist/collection/styles.js +14 -0
  21. package/dist/collection/styles.js.map +1 -1
  22. package/dist/components/app-bar/index.d.ts +26 -23
  23. package/dist/components/app-bar/index.js +89 -72
  24. package/dist/components/app-bar/index.js.map +1 -1
  25. package/dist/components/autocomplete/index.d.ts +6 -4
  26. package/dist/components/autocomplete/index.js +23 -14
  27. package/dist/components/autocomplete/index.js.map +1 -1
  28. package/dist/components/button/index.d.ts +15 -35
  29. package/dist/components/button/index.js +102 -74
  30. package/dist/components/button/index.js.map +1 -1
  31. package/dist/components/calendar/index.d.ts +9 -3
  32. package/dist/components/calendar/index.js +51 -42
  33. package/dist/components/calendar/index.js.map +1 -1
  34. package/dist/components/card/index.js +43 -27
  35. package/dist/components/card/index.js.map +1 -1
  36. package/dist/components/carousel/index.js +1 -1
  37. package/dist/components/checkbox/index.d.ts +9 -0
  38. package/dist/components/checkbox/index.js +47 -35
  39. package/dist/components/checkbox/index.js.map +1 -1
  40. package/dist/components/checkbox-group/index.js +1 -1
  41. package/dist/components/chip/index.d.ts +9 -4
  42. package/dist/components/chip/index.js.map +1 -1
  43. package/dist/components/chip-group/index.js +51 -37
  44. package/dist/components/chip-group/index.js.map +1 -1
  45. package/dist/components/copy-field/index.d.ts +28 -6
  46. package/dist/components/copy-field/index.js +140 -54
  47. package/dist/components/copy-field/index.js.map +1 -1
  48. package/dist/components/currency/index.d.ts +6 -2
  49. package/dist/components/currency/index.js +74 -46
  50. package/dist/components/currency/index.js.map +1 -1
  51. package/dist/components/dialog/index.js +13 -13
  52. package/dist/components/disclosure/index.js +1 -1
  53. package/dist/components/icon-button/index.d.ts +6 -31
  54. package/dist/components/icon-button/index.js +64 -52
  55. package/dist/components/icon-button/index.js.map +1 -1
  56. package/dist/components/index.d.ts +2 -1
  57. package/dist/components/list/index.js +2 -2
  58. package/dist/components/list-box/index.d.ts +14 -2
  59. package/dist/components/list-box/index.js +16 -8
  60. package/dist/components/list-box/index.js.map +1 -1
  61. package/dist/components/list-item/index.js +1 -1
  62. package/dist/components/menu/index.d.ts +14 -1
  63. package/dist/components/menu/index.js +32 -17
  64. package/dist/components/menu/index.js.map +1 -1
  65. package/dist/components/navigation-tree/index.js +12 -12
  66. package/dist/components/radio-group/index.d.ts +4 -0
  67. package/dist/components/radio-group/index.js +12 -12
  68. package/dist/components/radio-group/index.js.map +1 -1
  69. package/dist/components/range-calendar/index.d.ts +9 -3
  70. package/dist/components/range-calendar/index.js +51 -42
  71. package/dist/components/range-calendar/index.js.map +1 -1
  72. package/dist/components/search-view/index.js +1 -1
  73. package/dist/components/segmented-button/index.d.ts +5 -4
  74. package/dist/components/segmented-button/index.js +3 -3
  75. package/dist/components/segmented-button/index.js.map +1 -1
  76. package/dist/components/sheet/index.js +12 -12
  77. package/dist/components/split-button/index.d.ts +1 -1
  78. package/dist/components/split-button/index.js.map +1 -1
  79. package/dist/components/switch/index.d.ts +9 -2
  80. package/dist/components/switch/index.js +2 -2
  81. package/dist/components/switch/index.js.map +1 -1
  82. package/dist/components/table/index.js +3 -3
  83. package/dist/components/time-picker/index.js +1 -1
  84. package/dist/components/tree/index.js +8 -8
  85. package/dist/control/index.js +55 -17
  86. package/dist/control/index.js.map +1 -1
  87. package/dist/field/index.js +59 -51
  88. package/dist/field/index.js.map +1 -1
  89. package/dist/hooks/useAppBarScroll.d.ts +52 -0
  90. package/dist/hooks/useAppBarScroll.js +75 -0
  91. package/dist/hooks/useAppBarScroll.js.map +1 -0
  92. package/dist/i18n/index.js +2 -0
  93. package/dist/i18n/index.js.map +1 -1
  94. package/dist/i18n/messages.js +68 -0
  95. package/dist/i18n/messages.js.map +1 -1
  96. package/dist/index.d.ts +2 -1
  97. package/dist/index.js +3 -2
  98. package/dist/render/name.d.ts +22 -0
  99. package/dist/styles.css +83 -24
  100. package/package.json +5 -5
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
3
+ import { spacing } from "../../tokens/design.tokens.stylex.js";
3
4
  import { hasContent } from "../../render/content.js";
4
5
  import { useRender } from "../../render/useRender.js";
5
6
  import { mergeStyles } from "../../styles/merge.js";
@@ -8,8 +9,7 @@ import { c } from "react/compiler-runtime";
8
9
  import { createElement } from "react";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region src/components/app-bar/index.tsx
11
- const HEADLINE_OFFSET = "12px";
12
- const DEFAULT_CONTENT_INSET = "16px";
12
+ const GLYPH_INSET = `(48px - 24px) / 2`;
13
13
  const HEIGHTS = {
14
14
  lg: {
15
15
  plain: "120px",
@@ -20,8 +20,8 @@ const HEIGHTS = {
20
20
  withSubtitle: "136px"
21
21
  },
22
22
  sm: {
23
- plain: "64px",
24
- withSubtitle: "64px"
23
+ plain: `64px`,
24
+ withSubtitle: `64px`
25
25
  }
26
26
  };
27
27
  const COLLAPSED_HEIGHT = HEIGHTS.sm.plain;
@@ -80,13 +80,21 @@ const _temp = {
80
80
  const heightStyles = { root: (minBlockSize) => [_temp, { "--x-minBlockSize": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(minBlockSize) }] };
81
81
  const _temp2 = {
82
82
  ks0D6T: "x13i5qev",
83
- kg3NbH: "x30g6up",
84
83
  "$$css": true
85
84
  };
86
- const rowStyles = { root: (contentInset, maxInlineSize) => [_temp2, {
87
- "--x-maxInlineSize": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(maxInlineSize),
88
- "--x-paddingInline": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(`calc(${contentInset} - ${HEADLINE_OFFSET})`)
89
- }] };
85
+ const rowStyles = { root: (start, end, maxInlineSize) => [
86
+ _temp2,
87
+ {
88
+ kwRFfy: end != null ? "x120eax6" : end,
89
+ kZCmMZ: start != null ? "xnvo3vl" : start,
90
+ $$css: true
91
+ },
92
+ {
93
+ "--x-maxInlineSize": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(maxInlineSize),
94
+ "--x-paddingInlineEnd": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(end),
95
+ "--x-paddingInlineStart": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(start)
96
+ }
97
+ ] };
90
98
  /**
91
99
  * Material Design's app bar: the container at the top of a page carrying its
92
100
  * title, one or two actions, and the way back out.
@@ -101,7 +109,7 @@ const rowStyles = { root: (contentInset, maxInlineSize) => [_temp2, {
101
109
  * element scrolls, so both are set from its own scroll handler.
102
110
  */
103
111
  function AppBar(t0) {
104
- const $ = c(40);
112
+ const $ = c(39);
105
113
  let render;
106
114
  let t1;
107
115
  let t2;
@@ -113,7 +121,7 @@ function AppBar(t0) {
113
121
  render = t11;
114
122
  const align = t6 === void 0 ? "start" : t6;
115
123
  const collapsed = t7 === void 0 ? false : t7;
116
- const contentInset = t8 === void 0 ? DEFAULT_CONTENT_INSET : t8;
124
+ const contentInset = t8 === void 0 ? spacing.lg : t8;
117
125
  const contentMaxInlineSize = t9 === void 0 ? "none" : t9;
118
126
  const headingLevel = t10 === void 0 ? 1 : t10;
119
127
  const scrolled = t12 === void 0 ? false : t12;
@@ -121,81 +129,79 @@ function AppBar(t0) {
121
129
  const collapse = collapsed && size !== "sm";
122
130
  const expandedHeight = hasContent(subtitle) ? HEIGHTS[size].withSubtitle : HEIGHTS[size].plain;
123
131
  const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;
132
+ const hasLeading = hasContent(leading);
133
+ const hasTrailing = hasContent(trailing);
124
134
  t5 = useRender;
125
135
  t4 = "header";
126
136
  t1 = props$1;
127
- let t14;
128
- if ($[7] !== contentInset || $[8] !== contentMaxInlineSize) {
129
- t14 = props(styles.row, rowStyles.root(contentInset, contentMaxInlineSize));
130
- $[7] = contentInset;
131
- $[8] = contentMaxInlineSize;
132
- $[9] = t14;
133
- } else t14 = $[9];
137
+ const t14 = props(styles.row, rowStyles.root(edgePadding(contentInset, hasLeading), edgePadding(contentInset, hasTrailing), contentMaxInlineSize));
134
138
  let t15;
135
- if ($[10] !== leading) {
136
- t15 = !hasContent(leading) ? null : /* @__PURE__ */ jsx("div", {
137
- className: "x6s0dn4 x78zum5 x2lah0s xzoy561",
139
+ if ($[7] !== hasLeading || $[8] !== leading) {
140
+ t15 = !hasLeading ? null : /* @__PURE__ */ jsx("div", {
141
+ className: "x6s0dn4 x9f619 x78zum5 x2lah0s x1r8zjiw x1let9r4",
138
142
  children: leading
139
143
  });
140
- $[10] = leading;
141
- $[11] = t15;
142
- } else t15 = $[11];
144
+ $[7] = hasLeading;
145
+ $[8] = leading;
146
+ $[9] = t15;
147
+ } else t15 = $[9];
143
148
  let t16;
144
- if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
149
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
145
150
  t16 = {
146
- 0: { className: "x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll xaope02" },
147
- 1: { className: "x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll xaope02 x2b8uid" }
151
+ 0: { className: "x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll" },
152
+ 1: { className: "x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll x2b8uid" }
148
153
  };
149
- $[12] = t16;
150
- } else t16 = $[12];
154
+ $[10] = t16;
155
+ } else t16 = $[10];
151
156
  const t17 = t16[!!(align === "center") << 0];
152
157
  let t18;
153
- if ($[13] !== collapse || $[14] !== headingLevel || $[15] !== headline || $[16] !== size) {
158
+ if ($[11] !== collapse || $[12] !== headingLevel || $[13] !== headline || $[14] !== size) {
154
159
  t18 = !hasContent(headline) ? null : /* @__PURE__ */ jsx(Text, {
155
160
  className: "x12w9bfk xioksi3 x1nxaspg x1seskgd",
156
161
  render: heading(headingLevel),
157
162
  variant: collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size],
158
163
  children: headline
159
164
  });
160
- $[13] = collapse;
161
- $[14] = headingLevel;
162
- $[15] = headline;
163
- $[16] = size;
164
- $[17] = t18;
165
- } else t18 = $[17];
165
+ $[11] = collapse;
166
+ $[12] = headingLevel;
167
+ $[13] = headline;
168
+ $[14] = size;
169
+ $[15] = t18;
170
+ } else t18 = $[15];
166
171
  let t19;
167
- if ($[18] !== collapse || $[19] !== subtitle) {
172
+ if ($[16] !== collapse || $[17] !== subtitle) {
168
173
  t19 = !hasContent(subtitle) || collapse ? null : /* @__PURE__ */ jsx(Text, {
169
174
  render: PARAGRAPH,
170
175
  tone: "muted",
171
176
  variant: "bodyMedium",
172
177
  children: subtitle
173
178
  });
174
- $[18] = collapse;
175
- $[19] = subtitle;
176
- $[20] = t19;
177
- } else t19 = $[20];
179
+ $[16] = collapse;
180
+ $[17] = subtitle;
181
+ $[18] = t19;
182
+ } else t19 = $[18];
178
183
  let t20;
179
- if ($[21] !== t17 || $[22] !== t18 || $[23] !== t19) {
184
+ if ($[19] !== t17 || $[20] !== t18 || $[21] !== t19) {
180
185
  t20 = /* @__PURE__ */ jsxs("div", {
181
186
  ...t17,
182
187
  children: [t18, t19]
183
188
  });
184
- $[21] = t17;
185
- $[22] = t18;
186
- $[23] = t19;
187
- $[24] = t20;
188
- } else t20 = $[24];
189
+ $[19] = t17;
190
+ $[20] = t18;
191
+ $[21] = t19;
192
+ $[22] = t20;
193
+ } else t20 = $[22];
189
194
  let t21;
190
- if ($[25] !== trailing) {
191
- t21 = !hasContent(trailing) ? null : /* @__PURE__ */ jsx("div", {
192
- className: "x6s0dn4 x78zum5 x2lah0s xzoy561",
195
+ if ($[23] !== hasTrailing || $[24] !== trailing) {
196
+ t21 = !hasTrailing ? null : /* @__PURE__ */ jsx("div", {
197
+ className: "x6s0dn4 x9f619 x78zum5 x2lah0s x1r8zjiw x1let9r4",
193
198
  children: trailing
194
199
  });
195
- $[25] = trailing;
196
- $[26] = t21;
197
- } else t21 = $[26];
198
- if ($[27] !== t14 || $[28] !== t15 || $[29] !== t20 || $[30] !== t21) {
200
+ $[23] = hasTrailing;
201
+ $[24] = trailing;
202
+ $[25] = t21;
203
+ } else t21 = $[25];
204
+ if ($[26] !== t14 || $[27] !== t15 || $[28] !== t20 || $[29] !== t21) {
199
205
  t2 = /* @__PURE__ */ jsxs("div", {
200
206
  ...t14,
201
207
  children: [
@@ -204,12 +210,12 @@ function AppBar(t0) {
204
210
  t21
205
211
  ]
206
212
  });
207
- $[27] = t14;
208
- $[28] = t15;
209
- $[29] = t20;
210
- $[30] = t21;
211
- $[31] = t2;
212
- } else t2 = $[31];
213
+ $[26] = t14;
214
+ $[27] = t15;
215
+ $[28] = t20;
216
+ $[29] = t21;
217
+ $[30] = t2;
218
+ } else t2 = $[30];
213
219
  t3 = mergeStyles(props(styles.root, heightStyles.root(height), scrolled && styles.scrolled), props$1);
214
220
  $[0] = t0;
215
221
  $[1] = render;
@@ -227,31 +233,42 @@ function AppBar(t0) {
227
233
  t5 = $[6];
228
234
  }
229
235
  let t6;
230
- if ($[32] !== t1 || $[33] !== t2 || $[34] !== t3) {
236
+ if ($[31] !== t1 || $[32] !== t2 || $[33] !== t3) {
231
237
  t6 = {
232
238
  ...t1,
233
239
  children: t2,
234
240
  ...t3
235
241
  };
236
- $[32] = t1;
237
- $[33] = t2;
238
- $[34] = t3;
239
- $[35] = t6;
240
- } else t6 = $[35];
242
+ $[31] = t1;
243
+ $[32] = t2;
244
+ $[33] = t3;
245
+ $[34] = t6;
246
+ } else t6 = $[34];
241
247
  let t7;
242
- if ($[36] !== render || $[37] !== t4 || $[38] !== t6) {
248
+ if ($[35] !== render || $[36] !== t4 || $[37] !== t6) {
243
249
  t7 = {
244
250
  defaultTagName: t4,
245
251
  props: t6,
246
252
  render
247
253
  };
248
- $[36] = render;
249
- $[37] = t4;
250
- $[38] = t6;
251
- $[39] = t7;
252
- } else t7 = $[39];
254
+ $[35] = render;
255
+ $[36] = t4;
256
+ $[37] = t6;
257
+ $[38] = t7;
258
+ } else t7 = $[38];
253
259
  return t5(t7);
254
260
  }
261
+ /**
262
+ * The row's padding on one edge, for the inset the call site gave.
263
+ *
264
+ * A bare `0` is the one length CSS accepts without a unit, and the one it
265
+ * rejects inside `max()`, where it reads as a number, so it is given its
266
+ * unit before the arithmetic sees it.
267
+ */
268
+ function edgePadding(contentInset, hasSlot) {
269
+ const inset = contentInset.trim() === "0" ? "0px" : contentInset;
270
+ return hasSlot ? `max(0px, ${inset} - ${GLYPH_INSET})` : inset;
271
+ }
255
272
  //#endregion
256
273
  export { AppBar as default };
257
274
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","stylex","createElement","RenderComponentProps","hasContent","useRender","mergeStyles","colors","motion","spacing","Text","HEADLINE_OFFSET","DEFAULT_CONTENT_INSET","HEIGHTS","lg","plain","withSubtitle","md","sm","const","COLLAPSED_HEIGHT","FORCED_COLORS","styles","root","k6CgDc","kGNEyG","kWkggS","kB7OPa","k1xSpc","kjj79g","kIyJzY","k1ekBW","kAMwcw","$$css","row","kOIVth","kzqmXN","kUOVxO","scrolled","kL6WhQ","kfdmCh","kt9PQ7","HEADLINE_VARIANT","HEADINGS","heading","level","index","Math","min","max","round","length","PARAGRAPH","_temp","kAzted","heightStyles","minBlockSize","val","undefined","_temp2","ks0D6T","kg3NbH","rowStyles","contentInset","maxInlineSize","AppBarProps","Omit","align","collapsed","contentMaxInlineSize","headingLevel","headline","leading","size","subtitle","trailing","AppBar","t0","$","render","t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13","props","collapse","expandedHeight","height","t14","t15","t16","Symbol","for","0","className","1","t17","t18","t19","t20","t21","children","defaultTagName","_c","props","stylex.props"],"sources":["../../../src/components/app-bar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement } from 'react';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { hasContent } from '../../render/content';\nimport { useRender } from '../../render/useRender';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, spacing } from '../../tokens/design.tokens.stylex';\nimport Text from '../text';\n\n// Material Design's app bar, in the three sizes the spec recommends.\n//\n// `md` and `lg` are Material Design's medium and large *flexible* bars, the\n// newer of the two sets the spec gives and the one it recommends, which is why\n// those two steps are theirs.\n//\n// Material Design also merged the old center-aligned variant into small as a\n// configuration rather than a variant, which is why alignment is a prop here\n// and applies to every size.\n//\n// Heights are Material Design's, and they are minimums rather than fixed. The\n// spec says the flexible bars \"hug the text contents\" and gives them multi-line\n// support and text wrapping, so a headline long enough to wrap has to be able\n// to make its bar taller. Fixing the height would truncate exactly the case\n// the variant was redesigned for.\n\n// How far the headline sits inside whatever comes before it, and the figure\n// an icon button's glyph is inset from the edge of its own touch target.\n// Material Design leans on the two agreeing, which is what makes a bar with a\n// leading icon and one without start their text in the same place.\nconst HEADLINE_OFFSET = '12px';\n\n// Where the bar's visible content starts by default, which is Material\n// Design's own margin for a top app bar and the same margin its body content\n// takes.\nconst DEFAULT_CONTENT_INSET = '16px';\nconst HEIGHTS = {\n lg: {\n plain: '120px',\n withSubtitle: '152px'\n },\n md: {\n plain: '112px',\n withSubtitle: '136px'\n },\n sm: {\n plain: '64px',\n withSubtitle: '64px'\n }\n} as const;\n\n// What a flexible bar collapses to, which is the small bar exactly. Material\n// Design does not describe the collapsed large bar as a state of its own — it\n// describes it as becoming the small bar, which is why this reads off the same\n// table rather than being a fourth height.\nconst COLLAPSED_HEIGHT = HEIGHTS.sm.plain;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n root: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"x14s9m32\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"xioksi3\",\n k1ekBW: \"x8u3r54\",\n kAMwcw: \"x1seskgd\",\n $$css: true\n },\n row: {\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kOIVth: \"xzoy561\",\n kzqmXN: \"xh8yej3\",\n kUOVxO: \"xvueqy4\",\n $$css: true\n },\n scrolled: {\n kWkggS: \"x1mjdul6\",\n kL6WhQ: \"xszdk7l\",\n kfdmCh: \"xe3zi7u\",\n kt9PQ7: \"x15anc7y\",\n $$css: true\n }\n};\n\n// One entry per size, and each names a type role rather than a figure.\n// Material Design's own tokens are `md.comp.app-bar.<size>.title.font`,\n// aliases onto the type scale rather than sizes of their own, so this maps to\n// the scale the same way and lets Text apply it.\nconst HEADLINE_VARIANT = {\n lg: 'headlineMedium',\n md: 'headlineSmall',\n sm: 'titleLarge'\n} as const;\n\n// The headline is the page's title in Material Design's model, so it is the\n// page's <h1> unless the call site says otherwise. `headingLevel` is what says\n// otherwise, and a bar drawn beside another bar — one per pane in a\n// `ListDetail` or a `SupportingPane` — or under a page heading of its own\n// should lower it.\n//\n// Built here rather than kept as a constant per level: `headline` becomes the\n// heading's children, so a call site cannot demote the heading by passing one\n// of its own. `headline={<h2>…</h2>}` renders an h2 inside the h1 — two\n// headings where one was wanted, which React does not warn about.\n//\n// The level is looked up rather than interpolated into a tag name. `h7` is a\n// custom element as far as React is concerned, so it renders without a word\n// said and leaves the outline worse than the default would have. Disclosure's\n// own `headingLevel` hands the number to React Aria, which is why that one\n// needs no equivalent.\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\nfunction heading(level: number) {\n const index = Math.min(Math.max(Math.round(level), 1), HEADINGS.length) - 1;\n return createElement(HEADINGS[index]);\n}\nconst PARAGRAPH = <p />;\n\n// Height is the one value the call site does not choose, and it depends on two\n// props at once, so it is a function style rather than one key per\n// combination. StyleX writes it to a custom property inline, the same\n// mechanism Feed uses for its cell minimum.\nconst _temp = {\n kAzted: \"x1chvrdh\",\n \"$$css\": true\n};\nconst heightStyles = {\n root: (minBlockSize: string) => [_temp, {\n \"--x-minBlockSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(minBlockSize)\n }]\n};\n\n// The row's measure and inset both come from the call site, so both are\n// function styles too. The inset is where the bar's visible content starts,\n// and the row carries `contentInset` minus the offset the text block already\n// holds — which is what keeps a leading icon's glyph and a headline with no\n// icon before it starting in the same place.\nconst _temp2 = {\n ks0D6T: \"x13i5qev\",\n kg3NbH: \"x30g6up\",\n \"$$css\": true\n};\nconst rowStyles = {\n root: (contentInset: string, maxInlineSize: string) => [_temp2, {\n \"--x-maxInlineSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(maxInlineSize),\n \"--x-paddingInline\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(`calc(${contentInset} - ${HEADLINE_OFFSET})`)\n }]\n};\ntype AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {\n /**\n * Which of Material Design's alignments the text takes. `center` is the\n * configuration that replaced the old center-aligned variant.\n * @default 'start'\n */\n align?: 'center' | 'start';\n /**\n * Collapses a flexible bar to the height and headline of the small one, for\n * a pinned bar over content that has been scrolled. Material Design\n * specifies it for the flexible sizes, and without it a pinned `lg` costs\n * 152px of the viewport for as long as the page is open.\n *\n * Controlled, and for the same reason `scrolled` is: only the app knows\n * which element scrolls, and how far into it the bar should have finished\n * collapsing. Usually set from the same handler.\n *\n * Ignored on `sm`, which is already the height this collapses to. The\n * subtitle goes with the height, since there is no room for a second line\n * in the small bar.\n *\n * **The scroll container needs `overflow-anchor: none`.** Collapsing hands\n * the page back the height the bar gives up, and browsers answer a change\n * in height above the viewport by moving the scroll offset by exactly that\n * amount, so the content underneath stays where it was. That offset is\n * what the call site derived `collapsed` from, so it lands back under the\n * threshold, the bar expands, the offset is restored, and the two take\n * turns for as long as the reader stays in that band. Turning anchoring off\n * is what breaks the loop, and it is also the movement you want: the\n * content follows the bar's bottom edge up rather than standing still while\n * the bar shrinks behind it.\n *\n * No threshold avoids this on its own. The unstable band is as tall as the\n * height the bar gives back and it sits directly above wherever the\n * threshold is put, so moving the threshold moves the band with it.\n * @default false\n */\n collapsed?: boolean;\n /**\n * Where the bar's content starts, measured to the headline. A leading slot\n * sits 12px before that, which is the room an icon button's own padding\n * fills around its glyph — Material Design's arrangement, and what makes a\n * bar with an icon and one without start their text in the same place.\n *\n * The default is Material Design's own margin for a top app bar, which is\n * also the margin it gives body content, so a bar and the page beneath line\n * up without either being told about the other. Set it to the page's gutter\n * where that differs.\n * @default '16px'\n */\n contentInset?: string;\n /**\n * How wide the bar's contents may run before they stop growing, with the\n * row centred in whatever is left. The bar's own surface still paints edge\n * to edge.\n *\n * This is what lines a full-bleed bar up with a page whose content sits in\n * a measure: give it the page's measure, and `contentInset` the page's\n * gutter. Unset, the row is as wide as the bar.\n */\n contentMaxInlineSize?: string;\n /**\n * Where the headline sits in the page's outline. A screen reader moves\n * between headings, so a bar drawn beside another bar, or under a page\n * heading of its own, should lower it.\n * @default 1\n */\n headingLevel?: number;\n /** The page's title. Wraps rather than truncating, and grows the bar with it. */\n headline?: ReactNode;\n /** Usually a back or menu icon button. Sits before the text. */\n leading?: ReactNode;\n /**\n * Whether the content beneath has been scrolled. Material Design separates\n * a bar from scrolled content with a fill colour rather than a shadow, and\n * this is what applies it.\n *\n * Controlled, with no listener of its own: only the app knows which element\n * scrolls, and a bar that watched the window would be wrong inside every\n * pane and dialog that scrolls independently.\n * @default false\n */\n scrolled?: boolean;\n /**\n * Height and headline size, as steps of the library's size scale. `sm` is\n * Material Design's small bar, a fixed 64px; `md` and `lg` are its medium\n * and large flexible bars, which hug their text.\n * @default 'sm'\n */\n size?: 'lg' | 'md' | 'sm';\n /** A second line under the headline. Makes `md` and `lg` taller. */\n subtitle?: ReactNode;\n /** Actions, at the far end. Usually icon buttons. */\n trailing?: ReactNode;\n};\n\n/**\n * Material Design's app bar: the container at the top of a page carrying its\n * title, one or two actions, and the way back out.\n *\n * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;\n * `md` and `lg` are the flexible bars, which give the headline a larger\n * type role and grow to fit a subtitle or a headline that wraps.\n *\n * It paints its own surface, unlike the layout components, because separating\n * itself from the content beneath is the job — which is also why `scrolled`\n * and `collapsed` exist. Neither watches the page: only the app knows which\n * element scrolls, so both are set from its own scroll handler.\n */\nfunction AppBar({\n align = 'start',\n collapsed = false,\n contentInset = DEFAULT_CONTENT_INSET,\n contentMaxInlineSize = 'none',\n headingLevel = 1,\n headline,\n leading,\n render,\n scrolled = false,\n size = 'sm',\n subtitle,\n trailing,\n ...props\n}: AppBarProps) {\n // `sm` is already what the flexible bars collapse to, so collapsing it is\n // a no-op rather than an error. A bar whose size is chosen at the call site\n // from a breakpoint would otherwise have to guard the prop as well.\n const collapse = collapsed && size !== 'sm';\n const expandedHeight = hasContent(subtitle) ? HEIGHTS[size].withSubtitle : HEIGHTS[size].plain;\n const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;\n return useRender({\n defaultTagName: 'header',\n props: {\n ...props,\n children: <div {...stylex.props(styles.row, rowStyles.root(contentInset, contentMaxInlineSize))}>\n {!hasContent(leading) ? null : <div className=\"x6s0dn4 x78zum5 x2lah0s xzoy561\">{leading}</div>}\n <div {...{\n 0: {\n className: \"x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll xaope02\"\n },\n 1: {\n className: \"x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll xaope02 x2b8uid\"\n }\n }[!!(align === 'center') << 0]}>\n {!hasContent(headline) ? null : <Text className=\"x12w9bfk xioksi3 x1nxaspg x1seskgd\" render={heading(headingLevel)} variant={collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size]}>\n {headline}\n </Text>}\n {!hasContent(subtitle) || collapse ? null : <Text render={PARAGRAPH} tone=\"muted\" variant=\"bodyMedium\">\n {subtitle}\n </Text>}\n </div>\n {!hasContent(trailing) ? null : <div className=\"x6s0dn4 x78zum5 x2lah0s xzoy561\">{trailing}</div>}\n </div>,\n ...mergeStyles(stylex.props(styles.root, heightStyles.root(height), scrolled && styles.scrolled), props)\n },\n render\n });\n}\nexport type { AppBarProps };\nexport default AppBar;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","stylex","createElement","RenderComponentProps","COLLAPSED_BLOCK_SIZE","hasContent","useRender","mergeStyles","colors","motion","sizing","spacing","Text","ICON_BUTTON_TARGET","ICON_SIZE","GLYPH_INSET","HEIGHTS","lg","plain","withSubtitle","md","sm","const","COLLAPSED_HEIGHT","FORCED_COLORS","styles","root","k6CgDc","kGNEyG","kWkggS","kB7OPa","k1xSpc","kjj79g","kIyJzY","k1ekBW","kAMwcw","$$css","row","kOIVth","kzqmXN","kUOVxO","scrolled","kL6WhQ","kfdmCh","kt9PQ7","HEADLINE_VARIANT","HEADINGS","heading","level","index","Math","min","max","round","length","PARAGRAPH","_temp","kAzted","heightStyles","minBlockSize","val","undefined","_temp2","ks0D6T","rowStyles","start","end","maxInlineSize","kwRFfy","kZCmMZ","AppBarProps","Omit","align","collapsed","contentInset","contentMaxInlineSize","headingLevel","headline","leading","size","subtitle","trailing","AppBar","t0","$","render","t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13","props","collapse","expandedHeight","height","hasLeading","hasTrailing","t14","edgePadding","t15","t16","Symbol","for","0","className","1","t17","t18","t19","t20","t21","children","defaultTagName","hasSlot","inset","trim","_c","props","stylex.props"],"sources":["../../../src/components/app-bar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement } from 'react';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { COLLAPSED_BLOCK_SIZE } from '../../hooks/useAppBarScroll';\nimport { hasContent } from '../../render/content';\nimport { useRender } from '../../render/useRender';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, sizing, spacing } from '../../tokens/design.tokens.stylex';\nimport Text from '../text';\n\n// Material Design's app bar, in the three sizes the spec recommends.\n//\n// `md` and `lg` are Material Design's medium and large *flexible* bars, the\n// newer of the two sets the spec gives and the one it recommends, which is why\n// those two steps are theirs.\n//\n// Material Design also merged the old center-aligned variant into small as a\n// configuration rather than a variant, which is why alignment is a prop here\n// and applies to every size.\n//\n// Heights are Material Design's, and they are minimums rather than fixed. The\n// spec says the flexible bars \"hug the text contents\" and gives them multi-line\n// support and text wrapping, so a headline long enough to wrap has to be able\n// to make its bar taller. Fixing the height would truncate exactly the case\n// the variant was redesigned for.\n\n// The geometry Material Design lays a bar's icon buttons out on. Its tokens\n// give a 4dp leading and trailing space between the bar's edge and the first\n// button's 48dp target, no space between one target and the next, and a 24dp\n// icon centred in each — so a glyph lands 4 + 12 = 16dp in, on the page's own\n// margin.\n//\n// The library's icon button draws a 40dp box with its 48dp target out of\n// flow, so a slot pads half the difference either side and puts the whole\n// difference between two buttons, which lays the targets edge to edge as the\n// tokens do. The target is IconButton's TARGET_SIZE, a literal there for the\n// reason it gives: it is a floor the page states, not a step of the control\n// scale.\nconst ICON_BUTTON_TARGET = '48px';\nconst ICON_SIZE = '24px';\n\n// How far an icon sits inside its target, which is how much less than the\n// content inset the row is padded on an edge that holds a slot. That is what\n// puts a leading glyph, rather than the edge of its target, at the inset.\nconst GLYPH_INSET = `(${ICON_BUTTON_TARGET} - ${ICON_SIZE}) / 2`;\nconst HEIGHTS = {\n lg: {\n plain: '120px',\n withSubtitle: '152px'\n },\n md: {\n plain: '112px',\n withSubtitle: '136px'\n },\n sm: {\n plain: `${COLLAPSED_BLOCK_SIZE}px`,\n withSubtitle: `${COLLAPSED_BLOCK_SIZE}px`\n }\n} as const;\n\n// What a flexible bar collapses to, which is the small bar exactly. Material\n// Design does not describe the collapsed large bar as a state of its own — it\n// describes it as becoming the small bar, which is why this reads off the same\n// table rather than being a fourth height.\nconst COLLAPSED_HEIGHT = HEIGHTS.sm.plain;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n root: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"x14s9m32\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"xioksi3\",\n k1ekBW: \"x8u3r54\",\n kAMwcw: \"x1seskgd\",\n $$css: true\n },\n row: {\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kOIVth: \"xzoy561\",\n kzqmXN: \"xh8yej3\",\n kUOVxO: \"xvueqy4\",\n $$css: true\n },\n scrolled: {\n kWkggS: \"x1mjdul6\",\n kL6WhQ: \"xszdk7l\",\n kfdmCh: \"xe3zi7u\",\n kt9PQ7: \"x15anc7y\",\n $$css: true\n }\n};\n\n// One entry per size, and each names a type role rather than a figure.\n// Material Design's own tokens are `md.comp.app-bar.<size>.title.font`,\n// aliases onto the type scale rather than sizes of their own, so this maps to\n// the scale the same way and lets Text apply it.\nconst HEADLINE_VARIANT = {\n lg: 'headlineMedium',\n md: 'headlineSmall',\n sm: 'titleLarge'\n} as const;\n\n// The headline is the page's title in Material Design's model, so it is the\n// page's <h1> unless the call site says otherwise. `headingLevel` is what says\n// otherwise, and a bar drawn beside another bar — one per pane in a\n// `ListDetail` or a `SupportingPane` — or under a page heading of its own\n// should lower it.\n//\n// Built here rather than kept as a constant per level: `headline` becomes the\n// heading's children, so a call site cannot demote the heading by passing one\n// of its own. `headline={<h2>…</h2>}` renders an h2 inside the h1 — two\n// headings where one was wanted, which React does not warn about.\n//\n// The level is looked up rather than interpolated into a tag name. `h7` is a\n// custom element as far as React is concerned, so it renders without a word\n// said and leaves the outline worse than the default would have. Disclosure's\n// own `headingLevel` hands the number to React Aria, which is why that one\n// needs no equivalent.\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\nfunction heading(level: number) {\n const index = Math.min(Math.max(Math.round(level), 1), HEADINGS.length) - 1;\n return createElement(HEADINGS[index]);\n}\nconst PARAGRAPH = <p />;\n\n// Height is the one value the call site does not choose, and it depends on two\n// props at once, so it is a function style rather than one key per\n// combination. StyleX writes it to a custom property inline, the same\n// mechanism Feed uses for its cell minimum.\nconst _temp = {\n kAzted: \"x1chvrdh\",\n \"$$css\": true\n};\nconst heightStyles = {\n root: (minBlockSize: string) => [_temp, {\n \"--x-minBlockSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(minBlockSize)\n }]\n};\n\n// The row's measure and inset both come from the call site, so both are\n// function styles too. Each edge is worked out on its own: where it holds a\n// slot the row stops short of the inset by GLYPH_INSET, so the glyph rather\n// than its target is what sits at the inset, and where it holds none the\n// headline itself starts there. Clamped at zero, since an inset smaller than\n// a glyph's own room would otherwise ask for a negative padding, which CSS\n// throws away whole.\nconst _temp2 = {\n ks0D6T: \"x13i5qev\",\n \"$$css\": true\n};\nconst rowStyles = {\n root: (start: string, end: string, maxInlineSize: string) => [_temp2, {\n kwRFfy: end != null ? \"x120eax6\" : end,\n kZCmMZ: start != null ? \"xnvo3vl\" : start,\n $$css: true\n }, {\n \"--x-maxInlineSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(maxInlineSize),\n \"--x-paddingInlineEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(end),\n \"--x-paddingInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(start)\n }]\n};\ntype AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {\n /**\n * Which of Material Design's alignments the text takes. `center` is the\n * configuration that replaced the old center-aligned variant.\n * @default 'start'\n */\n align?: 'center' | 'start';\n /**\n * Collapses a flexible bar to the height and headline of the small one, for\n * a pinned bar over content that has been scrolled. Material Design\n * specifies it for the flexible sizes, and without it a pinned `lg` costs\n * 152px of the viewport for as long as the page is open.\n *\n * Controlled, and for the same reason `scrolled` is: only the app knows\n * which element scrolls, and how far into it the bar should have finished\n * collapsing. `useAppBarScroll` derives both from that element's scroll,\n * and is the way to set them unless the app needs a rule of its own.\n *\n * Ignored on `sm`, which is already the height this collapses to. The\n * subtitle goes with the height, since there is no room for a second line\n * in the small bar.\n *\n * Collapsing hands the page back the height the bar gives up, and a bar\n * whose state is read off the scroll offset can then undo itself in two\n * ways. Both move the offset back under the threshold, so the bar expands,\n * the page regains its height, and the two take turns for as long as the\n * reader stays there.\n *\n * - **Scroll anchoring.** Browsers answer a change in height above the\n * viewport by moving the offset by the same amount, to keep the content\n * in place. Give the scroll container `overflow-anchor: none`, which is\n * also the movement you want: the content follows the bar's bottom edge\n * up rather than standing still while the bar shrinks behind it.\n * - **The shorter page.** A page that overflows by less than the threshold\n * plus the height the bar gives back cannot scroll that far once the bar\n * has collapsed, so the browser pulls the offset back inside it. No\n * threshold avoids this, since the band moves with it; what does is not\n * collapsing on such a page, which is the rule `useAppBarScroll` applies.\n * @default false\n */\n collapsed?: boolean;\n /**\n * Where the bar's content starts on each edge: the headline where nothing\n * comes before it, and the leading icon's glyph where something does, with\n * the headline after the icon button's target. The trailing edge is the\n * same mirrored. Any length works, `0` included, for a bar drawn flush.\n *\n * The default is Material Design's own margin for a top app bar, the\n * spacing scale's `lg` step, which is also the margin it gives body\n * content, so a bar and the page beneath line up without either being told\n * about the other. Set it to the page's gutter where that differs.\n * @default spacing.lg\n */\n contentInset?: string;\n /**\n * How wide the bar's contents may run before they stop growing, with the\n * row centred in whatever is left. The bar's own surface still paints edge\n * to edge.\n *\n * This is what lines a full-bleed bar up with a page whose content sits in\n * a measure: give it the page's measure, and `contentInset` the page's\n * gutter. Unset, the row is as wide as the bar.\n */\n contentMaxInlineSize?: string;\n /**\n * Where the headline sits in the page's outline. A screen reader moves\n * between headings, so a bar drawn beside another bar, or under a page\n * heading of its own, should lower it.\n * @default 1\n */\n headingLevel?: number;\n /** The page's title. Wraps rather than truncating, and grows the bar with it. */\n headline?: ReactNode;\n /** Usually a back or menu icon button. Sits before the text. */\n leading?: ReactNode;\n /**\n * Whether the content beneath has been scrolled. Material Design separates\n * a bar from scrolled content with a fill colour rather than a shadow, and\n * this is what applies it.\n *\n * Controlled, with no listener of its own: only the app knows which element\n * scrolls, and a bar that watched the window would be wrong inside every\n * pane and dialog that scrolls independently.\n * @default false\n */\n scrolled?: boolean;\n /**\n * Height and headline size, as steps of the library's size scale. `sm` is\n * Material Design's small bar, a fixed 64px; `md` and `lg` are its medium\n * and large flexible bars, which hug their text.\n * @default 'sm'\n */\n size?: 'lg' | 'md' | 'sm';\n /** A second line under the headline. Makes `md` and `lg` taller. */\n subtitle?: ReactNode;\n /** Actions, at the far end. Usually icon buttons. */\n trailing?: ReactNode;\n};\n\n/**\n * Material Design's app bar: the container at the top of a page carrying its\n * title, one or two actions, and the way back out.\n *\n * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;\n * `md` and `lg` are the flexible bars, which give the headline a larger\n * type role and grow to fit a subtitle or a headline that wraps.\n *\n * It paints its own surface, unlike the layout components, because separating\n * itself from the content beneath is the job — which is also why `scrolled`\n * and `collapsed` exist. Neither watches the page: only the app knows which\n * element scrolls, so both are set from its own scroll handler.\n */\nfunction AppBar({\n align = 'start',\n collapsed = false,\n contentInset = spacing.lg,\n contentMaxInlineSize = 'none',\n headingLevel = 1,\n headline,\n leading,\n render,\n scrolled = false,\n size = 'sm',\n subtitle,\n trailing,\n ...props\n}: AppBarProps) {\n // `sm` is already what the flexible bars collapse to, so collapsing it is\n // a no-op rather than an error. A bar whose size is chosen at the call site\n // from a breakpoint would otherwise have to guard the prop as well.\n const collapse = collapsed && size !== 'sm';\n const expandedHeight = hasContent(subtitle) ? HEIGHTS[size].withSubtitle : HEIGHTS[size].plain;\n const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;\n const hasLeading = hasContent(leading);\n const hasTrailing = hasContent(trailing);\n return useRender({\n defaultTagName: 'header',\n props: {\n ...props,\n children: <div {...stylex.props(styles.row, rowStyles.root(edgePadding(contentInset, hasLeading), edgePadding(contentInset, hasTrailing), contentMaxInlineSize))}>\n {!hasLeading ? null : <div className=\"x6s0dn4 x9f619 x78zum5 x2lah0s x1r8zjiw x1let9r4\">{leading}</div>}\n <div {...{\n 0: {\n className: \"x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll\"\n },\n 1: {\n className: \"x9f619 x78zum5 xdt5ytf x1iyjqo2 xkjl1po xl56j7k xeuugli xj0a0fe x1cmllll x2b8uid\"\n }\n }[!!(align === 'center') << 0]}>\n {!hasContent(headline) ? null : <Text className=\"x12w9bfk xioksi3 x1nxaspg x1seskgd\" render={heading(headingLevel)} variant={collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size]}>\n {headline}\n </Text>}\n {!hasContent(subtitle) || collapse ? null : <Text render={PARAGRAPH} tone=\"muted\" variant=\"bodyMedium\">\n {subtitle}\n </Text>}\n </div>\n {!hasTrailing ? null : <div className=\"x6s0dn4 x9f619 x78zum5 x2lah0s x1r8zjiw x1let9r4\">{trailing}</div>}\n </div>,\n ...mergeStyles(stylex.props(styles.root, heightStyles.root(height), scrolled && styles.scrolled), props)\n },\n render\n });\n}\n\n/**\n * The row's padding on one edge, for the inset the call site gave.\n *\n * A bare `0` is the one length CSS accepts without a unit, and the one it\n * rejects inside `max()`, where it reads as a number, so it is given its\n * unit before the arithmetic sees it.\n */\nfunction edgePadding(contentInset: string, hasSlot: boolean) {\n const inset = contentInset.trim() === '0' ? '0px' : contentInset;\n return hasSlot ? `max(0px, ${inset} - ${GLYPH_INSET})` : inset;\n}\nexport type { AppBarProps };\nexport default AppBar;"],"mappings":"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"}
@@ -30,10 +30,12 @@ type AutocompleteProps$1<T extends object = object> = {
30
30
  * </Autocomplete>
31
31
  * ```
32
32
  *
33
- * It renders no element of its own, so the input and the collection sit
34
- * wherever the page puts them — side by side in a panel, in a `Menu.Content`,
35
- * or in a `Dialog` as a command palette. That is also why it takes no
36
- * `className` or `style`: there is nothing for them to land on.
33
+ * It renders no box of its own, so the input and the collection sit wherever
34
+ * the page puts them — side by side in a panel, in a `Menu.Content`, or in a
35
+ * `Dialog` as a command palette. That is also why it takes no `className` or
36
+ * `style`: there is nothing for them to land on. What it does render is a
37
+ * visually hidden status after its children, which tells a screen reader
38
+ * when a search leaves the collection empty.
37
39
  *
38
40
  * Keyboard focus stays in the input while the arrow keys move through the
39
41
  * collection, which is React Aria's virtual focus. `disableVirtualFocus`
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { CollectionStatus } from "../../collection/index.js";
2
3
  import { c } from "react/compiler-runtime";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  import { Autocomplete, useFilter } from "react-aria-components";
@@ -17,17 +18,19 @@ import { Autocomplete, useFilter } from "react-aria-components";
17
18
  * </Autocomplete>
18
19
  * ```
19
20
  *
20
- * It renders no element of its own, so the input and the collection sit
21
- * wherever the page puts them — side by side in a panel, in a `Menu.Content`,
22
- * or in a `Dialog` as a command palette. That is also why it takes no
23
- * `className` or `style`: there is nothing for them to land on.
21
+ * It renders no box of its own, so the input and the collection sit wherever
22
+ * the page puts them — side by side in a panel, in a `Menu.Content`, or in a
23
+ * `Dialog` as a command palette. That is also why it takes no `className` or
24
+ * `style`: there is nothing for them to land on. What it does render is a
25
+ * visually hidden status after its children, which tells a screen reader
26
+ * when a search leaves the collection empty.
24
27
  *
25
28
  * Keyboard focus stays in the input while the arrow keys move through the
26
29
  * collection, which is React Aria's virtual focus. `disableVirtualFocus`
27
30
  * turns that off and makes the collection tabbable instead.
28
31
  */
29
32
  function Autocomplete$1(t0) {
30
- const $ = c(12);
33
+ const $ = c(14);
31
34
  let children;
32
35
  let filter;
33
36
  let props;
@@ -56,18 +59,24 @@ function Autocomplete$1(t0) {
56
59
  $[7] = t2;
57
60
  } else t2 = $[7];
58
61
  let t3;
59
- if ($[8] !== children || $[9] !== props || $[10] !== t2) {
60
- t3 = /* @__PURE__ */ jsx(Autocomplete, {
62
+ if ($[8] !== children) {
63
+ t3 = /* @__PURE__ */ jsx(CollectionStatus, { children });
64
+ $[8] = children;
65
+ $[9] = t3;
66
+ } else t3 = $[9];
67
+ let t4;
68
+ if ($[10] !== props || $[11] !== t2 || $[12] !== t3) {
69
+ t4 = /* @__PURE__ */ jsx(Autocomplete, {
61
70
  filter: t2,
62
71
  ...props,
63
- children
72
+ children: t3
64
73
  });
65
- $[8] = children;
66
- $[9] = props;
67
- $[10] = t2;
68
- $[11] = t3;
69
- } else t3 = $[11];
70
- return t3;
74
+ $[10] = props;
75
+ $[11] = t2;
76
+ $[12] = t3;
77
+ $[13] = t4;
78
+ } else t4 = $[13];
79
+ return t4;
71
80
  }
72
81
  function containsFilter(contains) {
73
82
  return (textValue, inputValue) => contains(textValue, inputValue);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","AutocompleteProps","RACAutocompleteProps","Autocomplete","RACAutocomplete","useFilter","AutocompleteFilter","NonNullable","T","children","filter","Omit","t0","$","props","t1","Symbol","for","sensitivity","contains","t2","containsFilter","t3","textValue","inputValue","Autocomplete","_c","RACAutocomplete"],"sources":["../../../src/components/autocomplete/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport type { AutocompleteProps as RACAutocompleteProps } from 'react-aria-components'\n\nimport {\n Autocomplete as RACAutocomplete,\n useFilter,\n} from 'react-aria-components'\n\n// The search page's search with suggestions, as the wrapper React Aria makes\n// it: a search input over a collection, where typing narrows what the\n// collection shows. It draws nothing of its own — the input is SearchField,\n// the collection is ListBox or Menu, and where the two sit is the page's\n// business, which is what lets the same wrapper be a searchable list, a\n// filtered menu and a command palette inside a Dialog.\n//\n// Every other component here is a shape; this one is a behaviour, so it\n// renders no element and takes no `className` or `style`. There is nothing\n// for them to land on, and a wrapper element added to give them somewhere\n// would be a layout decision this component has no business making — the\n// three shapes above want three different ones.\n//\n// One thing is added to React Aria's. **Filtering is on by default.** Their\n// wrapper filters nothing unless it is handed a predicate, on the grounds\n// that a collection fed from a server may already be filtered. A collection\n// written out in the page is the common case here, and a search box that\n// does not search is a puzzle rather than a default, so `filter` falls back\n// to the same locale-aware contains match ComboBox uses. A collection that\n// filters itself passes a predicate that always returns true.\n\n// React Aria's own filter signature. Taken from the prop rather than written\n// out, since its third parameter is a collection node whose type this package\n// does not depend on directly.\ntype AutocompleteFilter<T extends object = object> = NonNullable<\n RACAutocompleteProps<T>['filter']\n>\n\ntype AutocompleteProps<T extends object = object> = {\n /**\n * The search input and the collection it filters, in whatever the page\n * puts around them. React Aria needs both somewhere inside.\n */\n children?: ReactNode\n /**\n * Which options a search keeps. Defaults to a locale-aware contains match\n * on each option's text — React Aria's own default is to filter nothing,\n * which is right for a collection that arrives filtered and wrong for one\n * written out in the page.\n */\n filter?: AutocompleteFilter<T>\n} & Omit<RACAutocompleteProps<T>, 'children' | 'filter'>\n\n/**\n * A search input that filters the collection under it. Its value is React\n * Aria's: pass `inputValue` with `onInputChange` to control what has been\n * typed, or `defaultInputValue` to let it keep its own.\n *\n * ```tsx\n * <Autocomplete>\n * <SearchField label=\"Search\" placeholder=\"Search\" />\n * <ListBox aria-label=\"Results\">\n * <ListBox.Item id=\"first\">First item</ListBox.Item>\n * </ListBox>\n * </Autocomplete>\n * ```\n *\n * It renders no element of its own, so the input and the collection sit\n * wherever the page puts them — side by side in a panel, in a `Menu.Content`,\n * or in a `Dialog` as a command palette. That is also why it takes no\n * `className` or `style`: there is nothing for them to land on.\n *\n * Keyboard focus stays in the input while the arrow keys move through the\n * collection, which is React Aria's virtual focus. `disableVirtualFocus`\n * turns that off and makes the collection tabbable instead.\n */\nfunction Autocomplete<T extends object = object>({\n children,\n filter,\n ...props\n}: AutocompleteProps<T>) {\n const { contains } = useFilter({ sensitivity: 'base' })\n\n return (\n <RACAutocomplete<T> filter={filter ?? containsFilter(contains)} {...props}>\n {children}\n </RACAutocomplete>\n )\n}\n\n// React Aria's filter is handed the node as well as the two strings, which a\n// contains match has no use for. Built by a call rather than written inline\n// at the prop, which is what react-perf's no-new-function-as-prop is after;\n// the React Compiler memoises the result on its input.\nfunction containsFilter(\n contains: (textValue: string, inputValue: string) => boolean,\n) {\n return (textValue: string, inputValue: string) =>\n contains(textValue, inputValue)\n}\n\nexport type { AutocompleteFilter, AutocompleteProps }\n\nexport default Autocomplete\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,SAAAK,eAAAS,IAAA;CAAA,MAAAC,IAAAd,EAAA,EAAA;CAAA,IAAAU;CAAA,IAAAC;CAAA,IAAAI;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAiD,CAAA,CAAAH,UAAAC,QAAA,GAAAI,SAAAF;EAI1BC,EAAA,KAAAD;EAAAC,EAAA,KAAAJ;EAAAI,EAAA,KAAAH;EAAAG,EAAA,KAAAC;CAAA,OAAA;EAAAL,WAAAI,EAAA;EAAAH,SAAAG,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACUF,KAAA,EAAAG,aAAe,OAAO;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAtD,MAAA,EAAAM,aAAqBd,UAAUU,EAAuB;CAAC,IAAAK;CAAA,IAAAP,EAAA,OAAAM,YAAAN,EAAA,OAAAH,QAAA;EAGzBU,KAAAV,UAAUW,eAAeF,QAAQ;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAH;EAAAG,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAJ,YAAAI,EAAA,OAAAC,SAAAD,EAAA,QAAAO,IAAA;EAA9DE,KAAA,oBAACK,cAAD;GAA4B,QAAAP;GAAkC,GAAMN;GACjEL;EADa,CAAA;EAEEI,EAAA,KAAAJ;EAAAI,EAAA,KAAAC;EAAAD,EAAA,MAAAO;EAAAP,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAFlBS;AAEkB;AAQtB,SAASD,eACPF,UACA;CACA,QAAQI,WAAmBC,eACzBL,SAASI,WAAWC,UAAU;AAClC"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","AutocompleteProps","RACAutocompleteProps","Autocomplete","RACAutocomplete","useFilter","CollectionStatus","AutocompleteFilter","NonNullable","T","children","filter","Omit","t0","$","props","t1","Symbol","for","sensitivity","contains","t2","containsFilter","t3","t4","textValue","inputValue","Autocomplete","_c","RACAutocomplete"],"sources":["../../../src/components/autocomplete/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport type { AutocompleteProps as RACAutocompleteProps } from 'react-aria-components'\n\nimport {\n Autocomplete as RACAutocomplete,\n useFilter,\n} from 'react-aria-components'\n\nimport { CollectionStatus } from '../../collection'\n\n// The search page's search with suggestions, as the wrapper React Aria makes\n// it: a search input over a collection, where typing narrows what the\n// collection shows. It draws nothing of its own — the input is SearchField,\n// the collection is ListBox or Menu, and where the two sit is the page's\n// business, which is what lets the same wrapper be a searchable list, a\n// filtered menu and a command palette inside a Dialog.\n//\n// Every other component here is a shape; this one is a behaviour, so it\n// renders no box and takes no `className` or `style`. There is nothing for\n// them to land on, and a wrapper element added to give them somewhere would\n// be a layout decision this component has no business making — the three\n// shapes above want three different ones.\n//\n// Two things are added to React Aria's. **A search that empties the\n// collection is announced.** A ListBox or Menu left with nothing shows a\n// \"No results\" row, and the status rendered after the children says the\n// same to a screen reader — visually hidden and out of the flow, so it takes\n// no place in whatever the page lays the two out in. See `CollectionStatus`\n// in `src/collection`.\n//\n// **Filtering is on by default.** Their\n// wrapper filters nothing unless it is handed a predicate, on the grounds\n// that a collection fed from a server may already be filtered. A collection\n// written out in the page is the common case here, and a search box that\n// does not search is a puzzle rather than a default, so `filter` falls back\n// to the same locale-aware contains match ComboBox uses. A collection that\n// filters itself passes a predicate that always returns true.\n\n// React Aria's own filter signature. Taken from the prop rather than written\n// out, since its third parameter is a collection node whose type this package\n// does not depend on directly.\ntype AutocompleteFilter<T extends object = object> = NonNullable<\n RACAutocompleteProps<T>['filter']\n>\n\ntype AutocompleteProps<T extends object = object> = {\n /**\n * The search input and the collection it filters, in whatever the page\n * puts around them. React Aria needs both somewhere inside.\n */\n children?: ReactNode\n /**\n * Which options a search keeps. Defaults to a locale-aware contains match\n * on each option's text — React Aria's own default is to filter nothing,\n * which is right for a collection that arrives filtered and wrong for one\n * written out in the page.\n */\n filter?: AutocompleteFilter<T>\n} & Omit<RACAutocompleteProps<T>, 'children' | 'filter'>\n\n/**\n * A search input that filters the collection under it. Its value is React\n * Aria's: pass `inputValue` with `onInputChange` to control what has been\n * typed, or `defaultInputValue` to let it keep its own.\n *\n * ```tsx\n * <Autocomplete>\n * <SearchField label=\"Search\" placeholder=\"Search\" />\n * <ListBox aria-label=\"Results\">\n * <ListBox.Item id=\"first\">First item</ListBox.Item>\n * </ListBox>\n * </Autocomplete>\n * ```\n *\n * It renders no box of its own, so the input and the collection sit wherever\n * the page puts them — side by side in a panel, in a `Menu.Content`, or in a\n * `Dialog` as a command palette. That is also why it takes no `className` or\n * `style`: there is nothing for them to land on. What it does render is a\n * visually hidden status after its children, which tells a screen reader\n * when a search leaves the collection empty.\n *\n * Keyboard focus stays in the input while the arrow keys move through the\n * collection, which is React Aria's virtual focus. `disableVirtualFocus`\n * turns that off and makes the collection tabbable instead.\n */\nfunction Autocomplete<T extends object = object>({\n children,\n filter,\n ...props\n}: AutocompleteProps<T>) {\n const { contains } = useFilter({ sensitivity: 'base' })\n\n return (\n <RACAutocomplete<T> filter={filter ?? containsFilter(contains)} {...props}>\n <CollectionStatus>{children}</CollectionStatus>\n </RACAutocomplete>\n )\n}\n\n// React Aria's filter is handed the node as well as the two strings, which a\n// contains match has no use for. Built by a call rather than written inline\n// at the prop, which is what react-perf's no-new-function-as-prop is after;\n// the React Compiler memoises the result on its input.\nfunction containsFilter(\n contains: (textValue: string, inputValue: string) => boolean,\n) {\n return (textValue: string, inputValue: string) =>\n contains(textValue, inputValue)\n}\n\nexport type { AutocompleteFilter, AutocompleteProps }\n\nexport default Autocomplete\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,SAAAK,eAAAU,IAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAW;CAAA,IAAAC;CAAA,IAAAI;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAiD,CAAA,CAAAH,UAAAC,QAAA,GAAAI,SAAAF;EAI1BC,EAAA,KAAAD;EAAAC,EAAA,KAAAJ;EAAAI,EAAA,KAAAH;EAAAG,EAAA,KAAAC;CAAA,OAAA;EAAAL,WAAAI,EAAA;EAAAH,SAAAG,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACUF,KAAA,EAAAG,aAAe,OAAO;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAtD,MAAA,EAAAM,aAAqBf,UAAUW,EAAuB;CAAC,IAAAK;CAAA,IAAAP,EAAA,OAAAM,YAAAN,EAAA,OAAAH,QAAA;EAGzBU,KAAAV,UAAUW,eAAeF,QAAQ;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAH;EAAAG,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAJ,UAAA;EAC5Da,KAAA,oBAAC,kBAAD,EAAmBb,SAAF,CAAA;EAA8BI,EAAA,KAAAJ;EAAAI,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAU;CAAA,IAAAV,EAAA,QAAAC,SAAAD,EAAA,QAAAO,MAAAP,EAAA,QAAAS,IAAA;EADjDC,KAAA,oBAACK,cAAD;GAA4B,QAAAR;GAAkC,GAAMN;GAClEQ,UAAAA;EADc,CAAA;EAEET,EAAA,MAAAC;EAAAD,EAAA,MAAAO;EAAAP,EAAA,MAAAS;EAAAT,EAAA,MAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,OAFlBU;AAEkB;AAQtB,SAASF,eACPF,UACA;CACA,QAAQK,WAAmBC,eACzBN,SAASK,WAAWC,UAAU;AAClC"}
@@ -1,31 +1,23 @@
1
- import { ButtonDOMProps, ButtonState } from "../../button/index.js";
1
+ import { ButtonDOMProps, ButtonLinkForm, ButtonPressForm, ButtonState, ButtonToggleForm } from "../../button/index.js";
2
2
  import { ReactNode, RefAttributes } from "react";
3
3
  import { ClassNameOrFunction, StyleOrFunction } from "react-aria-components";
4
4
  //#region src/components/button/index.d.ts
5
- type ButtonProps$1 = {
5
+ type ButtonProps$1 = ButtonDOMProps & (ButtonLinkForm | ButtonPressForm | (ButtonToggleForm & {
6
+ /**
7
+ * A toggle takes any variant but `text`, which the page gives no
8
+ * selected colours.
9
+ */
10
+ variant?: Exclude<ButtonVariant, 'text'>;
11
+ })) & {
6
12
  children?: ReactNode;
7
13
  /** A function may compute the class from the button's render state. */
8
14
  className?: ClassNameOrFunction<ButtonState>;
9
- /**
10
- * Whether a toggle starts selected, when it keeps its own state. Passing
11
- * this, `isSelected` or `onChange` is what makes the button a toggle —
12
- * except a `text` button, which the page gives no selected colours, so it
13
- * stays a plain button.
14
- */
15
- defaultSelected?: boolean;
16
15
  /**
17
16
  * Disables the press ripple. The hover/pressed background state layer is
18
17
  * unaffected.
19
18
  * @default false
20
19
  */
21
20
  disableRipple?: boolean;
22
- /**
23
- * Where the button leads. Given one, the button is rendered as a link —
24
- * an `<a>`, announced as the link it is — with the same styles and ripple.
25
- * `render`, `type`, and the form and pending props apply to the button
26
- * form only, and a toggle is never a link.
27
- */
28
- href?: string;
29
21
  /**
30
22
  * An icon before the label, at the page's icon size for the button's size:
31
23
  * 20px at `xs` and `md`, 24px at `lg`, 32px at `xl` and 40px at `xxl`. Draw
@@ -33,26 +25,12 @@ type ButtonProps$1 = {
33
25
  * Hidden with the label while the button is pending.
34
26
  */
35
27
  icon?: ReactNode;
36
- /**
37
- * Whether a toggle is selected, when the call site holds the state. Pass
38
- * it with `onChange`; passing this, `defaultSelected` or `onChange` is what
39
- * makes the button a toggle, `text` excepted.
40
- */
41
- isSelected?: boolean;
42
- /**
43
- * Called with the new state when a toggle is pressed. Passing this,
44
- * `isSelected` or `defaultSelected` is what makes the button a toggle,
45
- * `text` excepted.
46
- */
47
- onChange?: (isSelected: boolean) => void;
48
28
  /**
49
29
  * The name of the ring shown while the button is pending, for a screen
50
30
  * reader. The label it replaces is hidden while it shows. Left out, it is
51
31
  * the word for it in the I18nProvider's locale — "Loading" in English.
52
32
  */
53
33
  pendingLabel?: string;
54
- /** The link's `rel`, when `href` is set. */
55
- rel?: string;
56
34
  /**
57
35
  * The corner the button rests at: `round` is the pill, `square` the
58
36
  * page's rounded rectangle, 12px up to `md`, 16px at `lg` and 28px above.
@@ -70,8 +48,6 @@ type ButtonProps$1 = {
70
48
  size?: ButtonSize;
71
49
  /** A function may compute the style from the button's render state. */
72
50
  style?: StyleOrFunction<ButtonState>;
73
- /** The link's `target`, when `href` is set. */
74
- target?: string;
75
51
  /**
76
52
  * How much weight the button pulls. `filled` and `tonal` carry a container
77
53
  * of their own; `outlined` and `text` sit on the page; `elevated` sits on
@@ -80,7 +56,7 @@ type ButtonProps$1 = {
80
56
  * @default 'filled'
81
57
  */
82
58
  variant?: ButtonVariant;
83
- } & ButtonDOMProps;
59
+ };
84
60
  type ButtonShape = 'round' | 'square';
85
61
  type ButtonSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl';
86
62
  type ButtonVariant = 'elevated' | 'filled' | 'outlined' | 'text' | 'tonal';
@@ -92,8 +68,12 @@ type ButtonVariant = 'elevated' | 'filled' | 'outlined' | 'text' | 'tonal';
92
68
  *
93
69
  * Given `isSelected`, `defaultSelected` or `onChange` it is a toggle, which
94
70
  * reports its state through `aria-pressed` and draws the page's second pair
95
- * of colour roles for its variant. A toggle takes neither `href` nor the
96
- * pending props, and a `text` button never toggles.
71
+ * of colour roles for its variant. The three forms are exclusive, so a toggle
72
+ * given `href` does not compile, and nor does a `text` toggle, which the page
73
+ * gives no selected colours — a `text` button in a selecting `ButtonGroup`
74
+ * is the one that toggles, for the group's sake. A toggle may be pending,
75
+ * for a state saved somewhere slow: the ring replaces its label and a press
76
+ * changes nothing until it clears.
97
77
  *
98
78
  * ```tsx
99
79
  * <Button defaultSelected variant="tonal">