@kanso-labs/kanso-ui 0.40.8 → 0.41.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 (54) hide show
  1. package/dist/color-scheme.d.ts +6 -0
  2. package/dist/color-scheme.js +9 -2
  3. package/dist/color-scheme.js.map +1 -1
  4. package/dist/components/app-bar/index.d.ts +11 -2
  5. package/dist/components/app-bar/index.js +53 -46
  6. package/dist/components/app-bar/index.js.map +1 -1
  7. package/dist/components/avatar/index.d.ts +7 -0
  8. package/dist/components/avatar/index.js.map +1 -1
  9. package/dist/components/badge/index.js +7 -3
  10. package/dist/components/badge/index.js.map +1 -1
  11. package/dist/components/card/index.d.ts +12 -1
  12. package/dist/components/card/index.js +136 -66
  13. package/dist/components/card/index.js.map +1 -1
  14. package/dist/components/dialog/index.js +3 -2
  15. package/dist/components/dialog/index.js.map +1 -1
  16. package/dist/components/popover/index.d.ts +4 -1
  17. package/dist/components/popover/index.js +241 -138
  18. package/dist/components/popover/index.js.map +1 -1
  19. package/dist/components/product-icon/index.d.ts +3 -1
  20. package/dist/components/product-icon/index.js.map +1 -1
  21. package/dist/components/progress-indicator/index.js +1 -1
  22. package/dist/components/progress-indicator/index.js.map +1 -1
  23. package/dist/components/search-field/index.js +7 -3
  24. package/dist/components/search-field/index.js.map +1 -1
  25. package/dist/components/segmented-button/index.d.ts +20 -1
  26. package/dist/components/segmented-button/index.js +253 -114
  27. package/dist/components/segmented-button/index.js.map +1 -1
  28. package/dist/components/separator/index.js +2 -2
  29. package/dist/components/separator/index.js.map +1 -1
  30. package/dist/components/sheet/index.js +17 -16
  31. package/dist/components/sheet/index.js.map +1 -1
  32. package/dist/components/snackbar/index.d.ts +10 -3
  33. package/dist/components/snackbar/index.js +32 -12
  34. package/dist/components/snackbar/index.js.map +1 -1
  35. package/dist/components/switch/index.js +12 -3
  36. package/dist/components/switch/index.js.map +1 -1
  37. package/dist/components/toolbar/index.d.ts +3 -2
  38. package/dist/components/toolbar/index.js +3 -2
  39. package/dist/components/toolbar/index.js.map +1 -1
  40. package/dist/field/index.js +67 -61
  41. package/dist/field/index.js.map +1 -1
  42. package/dist/field/press.js +27 -0
  43. package/dist/field/press.js.map +1 -0
  44. package/dist/mark/initials.js +41 -26
  45. package/dist/mark/initials.js.map +1 -1
  46. package/dist/overlay/index.js +24 -0
  47. package/dist/overlay/index.js.map +1 -0
  48. package/dist/styles/scheme.js +19 -0
  49. package/dist/styles/scheme.js.map +1 -0
  50. package/dist/styles.css +106 -34
  51. package/dist/theme-scope.d.ts +5 -2
  52. package/dist/theme-scope.js +2 -1
  53. package/dist/theme-scope.js.map +1 -1
  54. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { CloseGlyph } from "../../glyphs/index.js";
5
5
  import { useRipple } from "../../hooks/useRipple.js";
6
6
  import { useBottomEdgeClearance } from "../../hooks/useBottomEdge.js";
7
7
  import { c } from "react/compiler-runtime";
8
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Button, Text, UNSTABLE_Toast, UNSTABLE_ToastContent, UNSTABLE_ToastQueue, UNSTABLE_ToastRegion } from "react-aria-components";
10
10
  //#region src/components/snackbar/index.tsx
11
11
  const MESSAGE_MS = 5e3;
@@ -17,12 +17,17 @@ const _temp = {
17
17
  };
18
18
  const styles = {
19
19
  action: {
20
+ kgeoSG: "x1cpjm7i",
21
+ kGOzcv: "xun2zgk",
22
+ kpsdNU: "xm4btww",
23
+ kEoFBp: "x1hmns74",
20
24
  kMwMTN: "x16bex6i",
21
25
  kMv6JI: "xkknnkr",
22
26
  kGuDYH: "x14zspaw",
23
27
  k63SB2: "x1v9cpvo",
24
28
  kb6lSQ: "x155f00i",
25
29
  kLWn49: "x1lz68p4",
30
+ kAzted: "x1cio8j0",
26
31
  k8WAf4: "x1cmllll",
27
32
  kg3NbH: "x18fpw6u",
28
33
  $$css: true
@@ -45,10 +50,9 @@ const styles = {
45
50
  kmuXW: "x2lah0s",
46
51
  kjj79g: "xl56j7k",
47
52
  kjBf7l: "x14ytart",
48
- kInvED: "x1hl8ikr",
53
+ kInvED: "xr2mjdv",
49
54
  k3XXqK: "x9v5kkp x1t137rt",
50
55
  kMeerF: "x1de99jn",
51
- kVQacm: "xb3r6kr",
52
56
  kVAEAm: "x1n2onr6",
53
57
  $$css: true
54
58
  },
@@ -103,26 +107,35 @@ var SnackbarQueue = class {
103
107
  * package's API — read it and an upstream release may break the call site.
104
108
  */
105
109
  rac;
110
+ #open = /* @__PURE__ */ new Set();
106
111
  constructor() {
107
112
  this.rac = new UNSTABLE_ToastQueue({ maxVisibleToasts: 1 });
108
113
  }
109
114
  /**
110
- * Shows a message, and returns the key that closes it.
115
+ * Shows a message in place of the one on screen, and returns the key that
116
+ * closes it. The message it replaces is closed, so its `onClose` runs, and
117
+ * it does not come back.
111
118
  */
112
119
  add(message, options = {}) {
113
120
  const { action, onClose, showCloseButton = false, timeout } = options;
114
- return this.rac.add({
121
+ this.clear();
122
+ const key = this.rac.add({
115
123
  action,
116
124
  message,
117
125
  showCloseButton
118
126
  }, {
119
- onClose,
127
+ onClose: () => {
128
+ this.#open.delete(key);
129
+ onClose?.();
130
+ },
120
131
  timeout: timeout ?? (action === void 0 ? MESSAGE_MS : UNTIL_CLOSED)
121
132
  });
133
+ this.#open.add(key);
134
+ return key;
122
135
  }
123
- /** Closes every snackbar, shown or waiting. */
136
+ /** Closes the snackbar on screen, running its `onClose`. */
124
137
  clear() {
125
- this.rac.clear();
138
+ for (const key of this.#open) this.rac.close(key);
126
139
  }
127
140
  /** Closes one snackbar, by the key `add` returned. */
128
141
  close(key) {
@@ -250,10 +263,14 @@ function snackbarContent(queue, closeLabel) {
250
263
  toast
251
264
  });
252
265
  }
253
- /** The action, the close button, or nothing, after the message. */
266
+ /**
267
+ * The action, the close button, or nothing, after the message — together, so
268
+ * they move beneath it together.
269
+ */
254
270
  function SnackbarControls(t0) {
255
271
  const $ = c(9);
256
272
  const { action, close, closeLabel, showCloseButton } = t0;
273
+ if (action === void 0 && !showCloseButton) return null;
257
274
  let t1;
258
275
  if ($[0] !== action || $[1] !== close) {
259
276
  t1 = action === void 0 ? null : /* @__PURE__ */ jsx(SnackbarButton, {
@@ -279,7 +296,10 @@ function SnackbarControls(t0) {
279
296
  } else t2 = $[5];
280
297
  let t3;
281
298
  if ($[6] !== t1 || $[7] !== t2) {
282
- t3 = /* @__PURE__ */ jsxs(Fragment, { children: [t1, t2] });
299
+ t3 = /* @__PURE__ */ jsxs("div", {
300
+ className: "x6s0dn4 x9f619 x78zum5 x2lah0s xvc5jky",
301
+ children: [t1, t2]
302
+ });
283
303
  $[6] = t1;
284
304
  $[7] = t2;
285
305
  $[8] = t3;
@@ -294,7 +314,7 @@ function SnackbarToast(t0) {
294
314
  let t1;
295
315
  if ($[0] !== message) {
296
316
  t1 = /* @__PURE__ */ jsx(UNSTABLE_ToastContent, {
297
- className: "x9f619 x1girmi0 x1iyjqo2 xpo2rfv x193rfdd x1hews6w xn43zvd xv61bfh xz158ff xeuugli xxlmvz2",
317
+ className: "x9f619 x1girmi0 x4pfjvb x1iyjqo2 xpo2rfv x193rfdd x1hews6w xkjl1po xn43zvd xv61bfh xz158ff xeuugli xj0a0fe xxlmvz2",
298
318
  children: /* @__PURE__ */ jsx(Text, {
299
319
  slot: "title",
300
320
  children: message
@@ -321,7 +341,7 @@ function SnackbarToast(t0) {
321
341
  if ($[7] !== t1 || $[8] !== t2 || $[9] !== toast) {
322
342
  t3 = /* @__PURE__ */ jsxs(UNSTABLE_Toast, {
323
343
  toast,
324
- className: "x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1w1tqly x1tfhd1 xx61lck x13rsnn2 x1udv5rz x9f619 x78zum5 xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w",
344
+ className: "x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1w1tqly x1tfhd1 xx61lck x13rsnn2 x1udv5rz x9f619 x78zum5 x1a02dak xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur xr2mjdv x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w",
325
345
  children: [t1, t2]
326
346
  });
327
347
  $[7] = t1;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","FocusableElement","ToastRegionProps","RACToastRegionProps","ToastRegionRenderProps","stylex","Button","RACButton","UNSTABLE_Toast","RACToast","UNSTABLE_ToastContent","RACToastContent","UNSTABLE_ToastQueue","RACToastQueue","UNSTABLE_ToastRegion","RACToastRegion","Text","CloseGlyph","useBottomEdgeClearance","useRipple","layers","mergeStatefulStyles","colors","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","MESSAGE_MS","UNTIL_CLOSED","WIDE","rise","FORCED_COLORS","_temp","krVfgx","kGO01o","styles","action","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","k8WAf4","kg3NbH","$$css","close","kZKoxP","kzqmXN","kmVPX3","control","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kVQacm","kVAEAm","controlFocused","controlHovered","controlPressed","region","kXwgrk","kOIVth","kkqhue","kLKAdn","kE3dHu","kpe85a","kfzvcC","kY2c9j","risen","clearance","val","undefined","SnackbarAction","label","onPress","SnackbarMessage","message","showCloseButton","SnackbarOptions","onClose","timeout","SnackbarProps","className","closeLabel","queue","SnackbarQueue","style","Omit","SnackbarToastItem","rac","constructor","maxVisibleToasts","add","options","clear","key","actionPress","closeToast","controlClassName","StyleXStyles","state","isFocusVisible","isHovered","isPressed","props","Snackbar","t0","$","T0","t1","t2","t3","snackbarContent","t4","SnackbarButton","children","ripple","handlers","surface","toast","SnackbarControls","SnackbarToast","content","Queue","SnackbarRegionRenderProps","RACToastQueue","stylex.props","_c","props","RACToastRegion","RACButton","RACToastContent","RACToast"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { FocusableElement, ToastRegionProps as RACToastRegionProps, ToastRegionRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, UNSTABLE_Toast as RACToast, UNSTABLE_ToastContent as RACToastContent, UNSTABLE_ToastQueue as RACToastQueue, UNSTABLE_ToastRegion as RACToastRegion, Text } from 'react-aria-components';\nimport { CloseGlyph } from '../../glyphs';\nimport { useBottomEdgeClearance } from '../../hooks/useBottomEdge';\nimport { useRipple } from '../../hooks/useRipple';\nimport '../../styles/layers.stylex';\nimport { layers } from '../../styles/layers.stylex';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that. The\n// page's container is the inverse surface at a 4dp corner and elevation 3,\n// its supporting text is body-medium in inverse on surface, its action label\n// is inverse primary, and its close icon takes the supporting text's colour.\n// The measurements are the page's too: 8dp of margin from the edges of the\n// screen, 8dp of padding inside the container with another 8dp either side\n// of the message, 14dp above and below on a single line, and between 320 and\n// 576dp wide above the page's 600dp breakpoint — full width below it.\n//\n// One at a time. The page shows a single snackbar and replaces it rather\n// than stacking, which is `maxVisibleToasts: 1` on the queue.\n//\n// React Aria's toast is the behaviour: the region is a landmark that holds\n// the message, moves focus into it for a keyboard, and pauses every timer\n// while it is hovered or focused, so a message never expires while it is\n// being read or acted on.\n//\n// Three things are decided here rather than taken from React Aria or from\n// the page.\n//\n// **The queue is ours, not React Aria's.** React Aria's toast is still\n// `UNSTABLE_`, and `SnackbarQueue` is what keeps that name out of a\n// consumer's code — an upstream rename is this file rather than every call\n// site. It wraps their queue, defaults it to one visible message, and takes\n// the message and its options as one call.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton.** The page colours them inverse primary and inverse\n// on surface, which no variant of either carries, and a colour pushed in\n// from outside through `className` is the merge hazard AGENTS.md describes:\n// StyleX decides between two atomic classes by their order in the compiled\n// stylesheet, not by the order they are applied. Both are React Aria's\n// `Button` with the same ripple and the same state layers, over\n// `currentColor` so each takes the colour the snackbar gives it.\n//\n// **There is no `container` prop.** Every other overlay here takes one,\n// because React Aria's `Modal` and `Popover` accept a portal container, and\n// `src/components/portal-container.test.tsx` is what keeps that true.\n// Its toast region does not: it reads a portal provider that\n// `react-aria-components` does not export, so the region always lands at the\n// end of `<body>`. An app that scopes its StyleX theme to a subtree has to\n// put the theme on `:root` for the snackbar to be drawn in it.\n\n// How long a message is shown when the call site names no `timeout`. The\n// specs page gives no duration, so these come from the snackbar's guidelines\n// and accessibility pages.\n//\n// A message alone leaves after five seconds. The pages allow four to ten, and\n// React Aria's toast docs set five as the least a reader should be given.\n//\n// A message with an action stays until the action is taken or something\n// closes it, as the pages ask of every actionable snackbar. No timer can know\n// how long a reader needs to act: a screen reader user hears the message\n// first and has to reach the region before the action is any use, and the\n// pause while the region is hovered or focused only starts once they have.\n// Android's snackbar can keep shorter defaults because the platform lengthens\n// them from each user's accessibility settings, and the web has no such\n// setting to read.\nconst MESSAGE_MS = 5000;\nconst UNTIL_CLOSED = 0;\n\n// Below the page's 600dp breakpoint the snackbar runs the width of the\n// screen; above it, it takes between 320 and 576.\nconst WIDE = '@media (min-width: 600px)';\n\n// The page's own is a fade. It rises a little as it arrives too, which is\n// what the page draws and what says the message came from the edge of the\n// screen rather than appearing over it.\nconst rise = \"x15b941j-B\";\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 _temp = {\n krVfgx: \"xiicpxy\",\n kGO01o: \"xqf7pud\",\n \"$$css\": true\n};\nconst styles = {\n action: {\n kMwMTN: \"x16bex6i\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x18fpw6u\",\n $$css: true\n },\n close: {\n kZKoxP: \"xbg5kjn\",\n kMwMTN: \"x1girmi0\",\n kzqmXN: \"xoqf9c6\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n control: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"x14ytart\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n controlFocused: {\n kWkggS: \"x1mbb5iu\",\n $$css: true\n },\n controlHovered: {\n kWkggS: \"x930l3l\",\n $$css: true\n },\n controlPressed: {\n kWkggS: \"xsykwg8\",\n $$css: true\n },\n region: {\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kOIVth: \"x126z3so\",\n krVfgx: \"x1ey2m1c\",\n kkqhue: \"x17y0mx6\",\n k3XXqK: \"x1t137rt\",\n kGO01o: \"x1u7mh7p\",\n kLKAdn: \"xi7mcox\",\n kE3dHu: \"xbpsoft\",\n kpe85a: \"xq5vm52\",\n kfzvcC: \"x47corl\",\n kVAEAm: \"xixxii4\",\n kY2c9j: \"x1bk8fjm\",\n $$css: true\n },\n risen: (clearance: string) => [_temp, {\n \"--x-insetBlockEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(clearance)\n }]\n};\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n label: string;\n /** Run when the action is pressed, just before the snackbar closes. */\n onPress: () => void;\n};\n\n/** What a snackbar carries: its message, and what may sit beside it. */\ntype SnackbarMessage = {\n action: SnackbarAction | undefined;\n message: ReactNode;\n showCloseButton: boolean;\n};\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n action?: SnackbarAction;\n /** Run when the snackbar closes, however it was closed. */\n onClose?: () => void;\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n *\n * Named for what it draws rather than `isDismissable`, which on `Sheet`,\n * `Dialog` and React Aria's modals is whether a press outside them closes\n * them — a snackbar has no outside to press.\n * @default false\n */\n showCloseButton?: boolean;\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to five seconds\n * for a message alone. A message with an action defaults to `0` and stays\n * until the action is taken or something closes it, as Material Design asks\n * of an actionable snackbar, since a reader may need longer to reach the\n * action than any timer allows. The timer is paused while the region is\n * hovered or focused, so a message never expires while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `showCloseButton`, or there is no\n * way to be rid of it.\n */\n timeout?: number;\n};\ntype SnackbarProps = {\n /**\n * What a screen reader calls the region holding the snackbar. Left out,\n * React Aria names the region itself: a count of the messages it holds, in\n * the reader's own locale — \"1 notification.\" in English, and one of some\n * thirty languages otherwise. Pass a name only to replace that, and pass a\n * translated one, since whatever is passed is read as written.\n */\n 'aria-label'?: string;\n /** A function may compute the class from the region's render state. */\n className?: RACToastRegionProps<SnackbarMessage>['className'];\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message, so putting it there would make every `add` call repeat it. Left\n * out, React Aria names it in the reader's locale — \"Close\" in English.\n */\n closeLabel?: string;\n /** The queue the region shows messages from. */\n queue: SnackbarQueue;\n /** A function may compute the style from the region's render state. */\n style?: RACToastRegionProps<SnackbarMessage>['style'];\n} & Omit<RACToastRegionProps<SnackbarMessage>, 'children' | 'className' | 'queue' | 'style'>;\n\n// One entry of the queue, as React Aria hands it to the region's render\n// function. Taken from its render state rather than imported from\n// `react-stately`, which this package does not depend on.\ntype SnackbarToastItem = ToastRegionRenderProps<SnackbarMessage>['visibleToasts'][number];\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it —\n * a module of its own is the usual place — mount `Snackbar` once with it,\n * and call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n *\n * It wraps React Aria's toast queue rather than exposing it, which is what\n * keeps that API's `UNSTABLE_` name out of a consumer's code.\n */\nclass SnackbarQueue {\n /**\n * React Aria's queue, which `Snackbar` subscribes to. Not part of the\n * package's API — read it and an upstream release may break the call site.\n */\n readonly rac: RACToastQueue<SnackbarMessage>;\n constructor() {\n // One at a time, which is what the page shows: a second message replaces\n // the first rather than stacking under it.\n this.rac = new RACToastQueue<SnackbarMessage>({\n maxVisibleToasts: 1\n });\n }\n\n /**\n * Shows a message, and returns the key that closes it.\n */\n add(message: ReactNode, options: SnackbarOptions = {}) {\n const {\n action,\n onClose,\n showCloseButton = false,\n timeout\n } = options;\n return this.rac.add({\n action,\n message,\n showCloseButton\n }, {\n onClose,\n timeout: timeout ?? (action === undefined ? MESSAGE_MS : UNTIL_CLOSED)\n });\n }\n\n /** Closes every snackbar, shown or waiting. */\n clear() {\n this.rac.clear();\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n this.rac.close(key);\n }\n}\n\n// The three handlers the snackbar hands to something below it, each built by\n// a call rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result on\n// its inputs.\nfunction actionPress(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress();\n close();\n };\n}\nfunction closeToast(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key);\n };\n}\n\n// A control's classes, from its own render state — see `controlFocused`.\nfunction controlClassName(style: stylex.StyleXStyles) {\n return (state: {\n isFocusVisible: boolean;\n isHovered: boolean;\n isPressed: boolean;\n }) => stylex.props(styles.control, style, state.isHovered && styles.controlHovered, state.isFocusVisible && styles.controlFocused, state.isPressed && styles.controlPressed).className ?? '';\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action. Mount\n * one of these with a `Snackbar.Queue`, and call the queue's `add` to show a\n * message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * The region is portalled to the end of `<body>` and renders nothing while\n * the queue is empty. It is one region rather than one per message, so mount\n * it once, near the root.\n *\n * The call site's `className` and `style` land on that region, which is the\n * element a layout positions.\n *\n * While a full-screen `Dialog` or a `Sheet` with a footer is open, the region\n * rises to sit above those actions rather than over them, since they share\n * the bottom edge of the window and the snackbar is drawn above both.\n */\nfunction Snackbar({\n closeLabel,\n queue,\n ...props\n}: RefAttributes<HTMLDivElement> & SnackbarProps) {\n const clearance = useBottomEdgeClearance();\n return <RACToastRegion<SnackbarMessage> queue={queue.rac} {...props} {...mergeStatefulStyles(stylex.props(styles.region, clearance > 0 && styles.risen(`${clearance}px`)), props)}>\n {snackbarContent(queue, closeLabel)}\n </RACToastRegion>;\n}\n\n/**\n * One of the snackbar's two controls. React Aria's `Button` rather than the\n * library's, for the colour reason in the comment at the top of this file;\n * the ripple and the state layers are the same ones every other control\n * here draws, over `currentColor`.\n */\nfunction SnackbarButton({\n children,\n style,\n ...props\n}: {\n 'aria-label'?: string;\n children: ReactNode;\n onPress?: () => void;\n slot?: string;\n style: stylex.StyleXStyles;\n}) {\n const ripple = useRipple<FocusableElement>();\n return <RACButton {...ripple.handlers} {...props} className={controlClassName(style)}>\n {children}\n {ripple.surface}\n </RACButton>;\n}\nfunction snackbarContent(queue: SnackbarQueue, closeLabel: string | undefined) {\n return ({\n toast\n }: {\n toast: SnackbarToastItem;\n }) => <SnackbarToast close={closeToast(queue, toast.key)} closeLabel={closeLabel} toast={toast} />;\n}\n\n/** The action, the close button, or nothing, after the message. */\nfunction SnackbarControls({\n action,\n close,\n closeLabel,\n showCloseButton\n}: {\n action: SnackbarAction | undefined;\n close: () => void;\n closeLabel: string | undefined;\n showCloseButton: boolean;\n}) {\n return <>\n {action === undefined ? null : <SnackbarButton onPress={actionPress(action, close)} style={styles.action}>\n {action.label}\n </SnackbarButton>}\n {showCloseButton ? <SnackbarButton aria-label={closeLabel} slot=\"close\" style={styles.close}>\n <CloseGlyph className=\"xxk0z11 xvy4d1p\" />\n </SnackbarButton> : null}\n </>;\n}\n\n/** One snackbar: its message, then whatever sits after it. */\nfunction SnackbarToast({\n close,\n closeLabel,\n toast\n}: {\n close: () => void;\n closeLabel: string | undefined;\n toast: SnackbarToastItem;\n}) {\n const {\n action,\n message,\n showCloseButton\n } = toast.content;\n return <RACToast toast={toast} className=\"x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1w1tqly x1tfhd1 xx61lck x13rsnn2 x1udv5rz x9f619 x78zum5 xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w\">\n <RACToastContent className=\"x9f619 x1girmi0 x1iyjqo2 xpo2rfv x193rfdd x1hews6w xn43zvd xv61bfh xz158ff xeuugli xxlmvz2\">\n <Text slot=\"title\">{message}</Text>\n </RACToastContent>\n <SnackbarControls action={action} close={close} closeLabel={closeLabel} showCloseButton={showCloseButton} />\n </RACToast>;\n}\nSnackbar.Queue = SnackbarQueue;\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component: this file would otherwise export something that is not a\n// component, which is what turns fast refresh off for it.\nexport type { SnackbarAction, SnackbarMessage, SnackbarOptions, SnackbarProps, SnackbarQueue, ToastRegionRenderProps as SnackbarRegionRenderProps };\nexport default Snackbar;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","FocusableElement","ToastRegionProps","RACToastRegionProps","ToastRegionRenderProps","stylex","Button","RACButton","UNSTABLE_Toast","RACToast","UNSTABLE_ToastContent","RACToastContent","UNSTABLE_ToastQueue","RACToastQueue","UNSTABLE_ToastRegion","RACToastRegion","Text","CloseGlyph","useBottomEdgeClearance","useRipple","layers","mergeStatefulStyles","colors","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","MESSAGE_MS","UNTIL_CLOSED","WIDE","rise","FORCED_COLORS","TARGET_SIZE","_temp","krVfgx","kGO01o","styles","action","kgeoSG","kGOzcv","kpsdNU","kEoFBp","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","kAzted","k8WAf4","kg3NbH","$$css","close","kZKoxP","kzqmXN","kmVPX3","control","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kVAEAm","controlFocused","controlHovered","controlPressed","region","kXwgrk","kOIVth","kkqhue","kLKAdn","kE3dHu","kpe85a","kfzvcC","kY2c9j","risen","clearance","val","undefined","SnackbarAction","label","onPress","SnackbarMessage","message","showCloseButton","SnackbarOptions","onClose","timeout","SnackbarProps","className","closeLabel","queue","SnackbarQueue","style","Omit","SnackbarToastItem","rac","open","Set","constructor","maxVisibleToasts","add","options","clear","key","delete","actionPress","closeToast","controlClassName","StyleXStyles","state","isFocusVisible","isHovered","isPressed","props","Snackbar","t0","$","T0","t1","t2","t3","snackbarContent","t4","SnackbarButton","children","ripple","handlers","surface","toast","SnackbarControls","SnackbarToast","content","Queue","SnackbarRegionRenderProps","RACToastQueue","stylex.props","_c","props","RACToastRegion","RACButton","RACToastContent","RACToast"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { FocusableElement, ToastRegionProps as RACToastRegionProps, ToastRegionRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, UNSTABLE_Toast as RACToast, UNSTABLE_ToastContent as RACToastContent, UNSTABLE_ToastQueue as RACToastQueue, UNSTABLE_ToastRegion as RACToastRegion, Text } from 'react-aria-components';\nimport { CloseGlyph } from '../../glyphs';\nimport { useBottomEdgeClearance } from '../../hooks/useBottomEdge';\nimport { useRipple } from '../../hooks/useRipple';\nimport '../../styles/layers.stylex';\nimport { layers } from '../../styles/layers.stylex';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that. The\n// page's container is the inverse surface at a 4dp corner and elevation 3,\n// its supporting text is body-medium in inverse on surface, its action label\n// is inverse primary, and its close icon takes the supporting text's colour.\n// The measurements are the page's too: 8dp of margin from the edges of the\n// screen, 8dp of padding inside the container with another 8dp either side\n// of the message, 14dp above and below on a single line, and between 320 and\n// 576dp wide above the page's 600dp breakpoint — full width below it.\n//\n// One at a time. The page shows a single snackbar and replaces it rather\n// than stacking, so a message added while another is up closes that one —\n// its `onClose` runs — and takes its place. Nothing waits behind it: React\n// Aria's queue, left to itself, kept every message and showed the one it had\n// replaced again once the newer closed, so an Undo could come back long after\n// the thing it undid.\n//\n// React Aria's toast is the behaviour: the region is a landmark that holds\n// the message, moves focus into it for a keyboard, and pauses every timer\n// while it is hovered or focused, so a message never expires while it is\n// being read or acted on.\n//\n// Three things are decided here rather than taken from React Aria or from\n// the page.\n//\n// **The queue is ours, not React Aria's.** React Aria's toast is still\n// `UNSTABLE_`, and `SnackbarQueue` is what keeps that name out of a\n// consumer's code — an upstream rename is this file rather than every call\n// site. It wraps their queue, defaults it to one visible message, and takes\n// the message and its options as one call.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton.** The page colours them inverse primary and inverse\n// on surface, which no variant of either carries, and a colour pushed in\n// from outside through `className` is the merge hazard AGENTS.md describes:\n// StyleX decides between two atomic classes by their order in the compiled\n// stylesheet, not by the order they are applied. Both are React Aria's\n// `Button` with the same ripple and the same state layers, over\n// `currentColor` so each takes the colour the snackbar gives it.\n//\n// **There is no `container` prop.** Every other overlay here takes one,\n// because React Aria's `Modal` and `Popover` accept a portal container, and\n// `src/components/portal-container.test.tsx` is what keeps that true.\n// Its toast region does not: it reads a portal provider that\n// `react-aria-components` does not export, so the region always lands at the\n// end of `<body>`. An app that scopes its StyleX theme to a subtree has to\n// put the theme on `:root` for the snackbar to be drawn in it.\n\n// How long a message is shown when the call site names no `timeout`. The\n// specs page gives no duration, so these come from the snackbar's guidelines\n// and accessibility pages.\n//\n// A message alone leaves after five seconds. The pages allow four to ten, and\n// React Aria's toast docs set five as the least a reader should be given.\n//\n// A message with an action stays until the action is taken or something\n// closes it, as the pages ask of every actionable snackbar. No timer can know\n// how long a reader needs to act: a screen reader user hears the message\n// first and has to reach the region before the action is any use, and the\n// pause while the region is hovered or focused only starts once they have.\n// Android's snackbar can keep shorter defaults because the platform lengthens\n// them from each user's accessibility settings, and the web has no such\n// setting to read.\nconst MESSAGE_MS = 5000;\nconst UNTIL_CLOSED = 0;\n\n// Below the page's 600dp breakpoint the snackbar runs the width of the\n// screen; above it, it takes between 320 and 576.\nconst WIDE = '@media (min-width: 600px)';\n\n// The page's own is a fade. It rises a little as it arrives too, which is\n// what the page draws and what says the message came from the edge of the\n// screen rather than appearing over it.\nconst rise = \"x15b941j-B\";\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)';\n\n// The least press area the action keeps, as Button's medium size does. A\n// literal rather than a token, for the reason Button's `TARGET_SIZE` gives: a\n// consumer resizing their controls should not shrink a floor the page states.\nconst TARGET_SIZE = '48px';\nconst _temp = {\n krVfgx: \"xiicpxy\",\n kGO01o: \"xqf7pud\",\n \"$$css\": true\n};\nconst styles = {\n action: {\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"xun2zgk\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n kMwMTN: \"x16bex6i\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n kAzted: \"x1cio8j0\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x18fpw6u\",\n $$css: true\n },\n close: {\n kZKoxP: \"xbg5kjn\",\n kMwMTN: \"x1girmi0\",\n kzqmXN: \"xoqf9c6\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n control: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"x14ytart\",\n kInvED: \"xr2mjdv\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n controlFocused: {\n kWkggS: \"x1mbb5iu\",\n $$css: true\n },\n controlHovered: {\n kWkggS: \"x930l3l\",\n $$css: true\n },\n controlPressed: {\n kWkggS: \"xsykwg8\",\n $$css: true\n },\n region: {\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kOIVth: \"x126z3so\",\n krVfgx: \"x1ey2m1c\",\n kkqhue: \"x17y0mx6\",\n k3XXqK: \"x1t137rt\",\n kGO01o: \"x1u7mh7p\",\n kLKAdn: \"xi7mcox\",\n kE3dHu: \"xbpsoft\",\n kpe85a: \"xq5vm52\",\n kfzvcC: \"x47corl\",\n kVAEAm: \"xixxii4\",\n kY2c9j: \"x1bk8fjm\",\n $$css: true\n },\n risen: (clearance: string) => [_temp, {\n \"--x-insetBlockEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(clearance)\n }]\n};\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n label: string;\n /** Run when the action is pressed, just before the snackbar closes. */\n onPress: () => void;\n};\n\n/** What a snackbar carries: its message, and what may sit beside it. */\ntype SnackbarMessage = {\n action: SnackbarAction | undefined;\n message: ReactNode;\n showCloseButton: boolean;\n};\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n action?: SnackbarAction;\n /**\n * Run when the snackbar closes, however it was closed: by its timer, its\n * action or close button, `close`, `clear`, or a newer message added in its\n * place.\n */\n onClose?: () => void;\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n *\n * Named for what it draws rather than `isDismissable`, which on `Sheet`,\n * `Dialog` and React Aria's modals is whether a press outside them closes\n * them — a snackbar has no outside to press.\n * @default false\n */\n showCloseButton?: boolean;\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to five seconds\n * for a message alone. A message with an action defaults to `0` and stays\n * until the action is taken or something closes it, as Material Design asks\n * of an actionable snackbar, since a reader may need longer to reach the\n * action than any timer allows. The timer is paused while the region is\n * hovered or focused, so a message never expires while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `showCloseButton`, or there is no\n * way to be rid of it.\n */\n timeout?: number;\n};\ntype SnackbarProps = {\n /**\n * What a screen reader calls the region holding the snackbar. Left out,\n * React Aria names the region itself: a count of the messages it holds, in\n * the reader's own locale — \"1 notification.\" in English, and one of some\n * thirty languages otherwise. Pass a name only to replace that, and pass a\n * translated one, since whatever is passed is read as written.\n */\n 'aria-label'?: string;\n /** A function may compute the class from the region's render state. */\n className?: RACToastRegionProps<SnackbarMessage>['className'];\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message, so putting it there would make every `add` call repeat it. Left\n * out, React Aria names it in the reader's locale — \"Close\" in English.\n */\n closeLabel?: string;\n /** The queue the region shows messages from. */\n queue: SnackbarQueue;\n /** A function may compute the style from the region's render state. */\n style?: RACToastRegionProps<SnackbarMessage>['style'];\n} & Omit<RACToastRegionProps<SnackbarMessage>, 'children' | 'className' | 'queue' | 'style'>;\n\n// One entry of the queue, as React Aria hands it to the region's render\n// function. Taken from its render state rather than imported from\n// `react-stately`, which this package does not depend on.\ntype SnackbarToastItem = ToastRegionRenderProps<SnackbarMessage>['visibleToasts'][number];\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it —\n * a module of its own is the usual place — mount `Snackbar` once with it,\n * and call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n *\n * It wraps React Aria's toast queue rather than exposing it, which is what\n * keeps that API's `UNSTABLE_` name out of a consumer's code.\n */\nclass SnackbarQueue {\n /**\n * React Aria's queue, which `Snackbar` subscribes to. Not part of the\n * package's API — read it and an upstream release may break the call site.\n */\n readonly rac: RACToastQueue<SnackbarMessage>;\n\n // The keys of the snackbars not yet closed, which `add` and `clear` close.\n // Kept here because React Aria keeps its own list private, and its own\n // `clear` empties that list without running a single `onClose`.\n readonly #open = new Set<string>();\n constructor() {\n // One at a time, which is what the page shows. `add` closes whatever is\n // up before it adds, so nothing is ever left waiting for this to hold\n // back; it says the same thing to React Aria in its own terms.\n this.rac = new RACToastQueue<SnackbarMessage>({\n maxVisibleToasts: 1\n });\n }\n\n /**\n * Shows a message in place of the one on screen, and returns the key that\n * closes it. The message it replaces is closed, so its `onClose` runs, and\n * it does not come back.\n */\n add(message: ReactNode, options: SnackbarOptions = {}) {\n const {\n action,\n onClose,\n showCloseButton = false,\n timeout\n } = options;\n this.clear();\n const key = this.rac.add({\n action,\n message,\n showCloseButton\n }, {\n // However it closes — its timer runs inside React Aria's queue,\n // past this one — it leaves the open set on the way out.\n onClose: () => {\n this.#open.delete(key);\n onClose?.();\n },\n timeout: timeout ?? (action === undefined ? MESSAGE_MS : UNTIL_CLOSED)\n });\n this.#open.add(key);\n return key;\n }\n\n /** Closes the snackbar on screen, running its `onClose`. */\n clear() {\n // Each close runs that message's `onClose`, which deletes its own key\n // from the set — the entry being visited, which a Set allows.\n for (const key of this.#open) {\n this.rac.close(key);\n }\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n this.rac.close(key);\n }\n}\n\n// The three handlers the snackbar hands to something below it, each built by\n// a call rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result on\n// its inputs.\nfunction actionPress(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress();\n close();\n };\n}\nfunction closeToast(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key);\n };\n}\n\n// A control's classes, from its own render state — see `controlFocused`.\nfunction controlClassName(style: stylex.StyleXStyles) {\n return (state: {\n isFocusVisible: boolean;\n isHovered: boolean;\n isPressed: boolean;\n }) => stylex.props(styles.control, style, state.isHovered && styles.controlHovered, state.isFocusVisible && styles.controlFocused, state.isPressed && styles.controlPressed).className ?? '';\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action. Mount\n * one of these with a `Snackbar.Queue`, and call the queue's `add` to show a\n * message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * The region is portalled to the end of `<body>` and renders nothing while\n * the queue is empty. It is one region rather than one per message, so mount\n * it once, near the root.\n *\n * The call site's `className` and `style` land on that region, which is the\n * element a layout positions.\n *\n * While a full-screen `Dialog` or a `Sheet` with a footer is open, the region\n * rises to sit above those actions rather than over them, since they share\n * the bottom edge of the window and the snackbar is drawn above both.\n */\nfunction Snackbar({\n closeLabel,\n queue,\n ...props\n}: RefAttributes<HTMLDivElement> & SnackbarProps) {\n const clearance = useBottomEdgeClearance();\n return <RACToastRegion<SnackbarMessage> queue={queue.rac} {...props} {...mergeStatefulStyles(stylex.props(styles.region, clearance > 0 && styles.risen(`${clearance}px`)), props)}>\n {snackbarContent(queue, closeLabel)}\n </RACToastRegion>;\n}\n\n/**\n * One of the snackbar's two controls. React Aria's `Button` rather than the\n * library's, for the colour reason in the comment at the top of this file;\n * the ripple and the state layers are the same ones every other control\n * here draws, over `currentColor`.\n */\nfunction SnackbarButton({\n children,\n style,\n ...props\n}: {\n 'aria-label'?: string;\n children: ReactNode;\n onPress?: () => void;\n slot?: string;\n style: stylex.StyleXStyles;\n}) {\n const ripple = useRipple<FocusableElement>();\n return <RACButton {...ripple.handlers} {...props} className={controlClassName(style)}>\n {children}\n {ripple.surface}\n </RACButton>;\n}\nfunction snackbarContent(queue: SnackbarQueue, closeLabel: string | undefined) {\n return ({\n toast\n }: {\n toast: SnackbarToastItem;\n }) => <SnackbarToast close={closeToast(queue, toast.key)} closeLabel={closeLabel} toast={toast} />;\n}\n\n/**\n * The action, the close button, or nothing, after the message — together, so\n * they move beneath it together.\n */\nfunction SnackbarControls({\n action,\n close,\n closeLabel,\n showCloseButton\n}: {\n action: SnackbarAction | undefined;\n close: () => void;\n closeLabel: string | undefined;\n showCloseButton: boolean;\n}) {\n if (action === undefined && !showCloseButton) {\n return null;\n }\n return <div className=\"x6s0dn4 x9f619 x78zum5 x2lah0s xvc5jky\">\n {action === undefined ? null : <SnackbarButton onPress={actionPress(action, close)} style={styles.action}>\n {action.label}\n </SnackbarButton>}\n {showCloseButton ? <SnackbarButton aria-label={closeLabel} slot=\"close\" style={styles.close}>\n <CloseGlyph className=\"xxk0z11 xvy4d1p\" />\n </SnackbarButton> : null}\n </div>;\n}\n\n/** One snackbar: its message, then whatever sits after it. */\nfunction SnackbarToast({\n close,\n closeLabel,\n toast\n}: {\n close: () => void;\n closeLabel: string | undefined;\n toast: SnackbarToastItem;\n}) {\n const {\n action,\n message,\n showCloseButton\n } = toast.content;\n return <RACToast toast={toast} className=\"x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1w1tqly x1tfhd1 xx61lck x13rsnn2 x1udv5rz x9f619 x78zum5 x1a02dak xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur xr2mjdv x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w\">\n <RACToastContent className=\"x9f619 x1girmi0 x4pfjvb x1iyjqo2 xpo2rfv x193rfdd x1hews6w xkjl1po xn43zvd xv61bfh xz158ff xeuugli xj0a0fe xxlmvz2\">\n <Text slot=\"title\">{message}</Text>\n </RACToastContent>\n <SnackbarControls action={action} close={close} closeLabel={closeLabel} showCloseButton={showCloseButton} />\n </RACToast>;\n}\nSnackbar.Queue = SnackbarQueue;\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component: this file would otherwise export something that is not a\n// component, which is what turns fast refresh off for it.\nexport type { SnackbarAction, SnackbarMessage, SnackbarOptions, SnackbarProps, SnackbarQueue, ToastRegionRenderProps as SnackbarRegionRenderProps };\nexport default Snackbar;"],"mappings":"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"}
@@ -185,7 +185,8 @@ const pressedLayers = {
185
185
  }
186
186
  };
187
187
  const TRAVEL = 20;
188
- const DRAG_SLOP = TRAVEL / 4;
188
+ const MOUSE_SLOP = TRAVEL / 4;
189
+ const TOUCH_SLOP = TRAVEL / 2;
189
190
  function buttonContent(children, icon, ripple, drag) {
190
191
  return (state) => {
191
192
  const interactive = !state.isDisabled && !state.isReadOnly;
@@ -316,6 +317,9 @@ function Switch(t0) {
316
317
  * A press that moves no further than the slop is left alone entirely, so a
317
318
  * tap flips the switch however still the pointer was — a drag starts only
318
319
  * once the pointer passes it, and from then on the handle follows every move.
320
+ * The slop is the pointer's own: a finger and a pen drift further on a tap
321
+ * than a mouse does. A mouse or pen drag then focuses the input, as a tap
322
+ * does.
319
323
  *
320
324
  * The guard for the click after a drag is cleared by the next press, not by
321
325
  * that click, since the click may never come: a touch dragged past the
@@ -355,7 +359,7 @@ function useHandleDrag() {
355
359
  const from = origin.current;
356
360
  if (from === null) return;
357
361
  const along = from.rtl ? from.x - event_0.clientX : event_0.clientX - from.x;
358
- if (settled.current === null && Math.abs(along) <= DRAG_SLOP) return;
362
+ if (settled.current === null && Math.abs(along) <= from.slop) return;
359
363
  const next = Math.min(TRAVEL, Math.max(0, from.base + along));
360
364
  settled.current = next;
361
365
  setOffset(next);
@@ -379,8 +383,10 @@ function useHandleDrag() {
379
383
  pointerType: event_1.pointerType
380
384
  }));
381
385
  cancelClick.current = true;
386
+ const input = seat.closest("label")?.querySelector("input");
387
+ if (from_0.focuses) input?.focus({ preventScroll: true });
382
388
  if (stopped > TRAVEL / 2 === from_0.on) return;
383
- (seat.closest("label")?.querySelector("input"))?.click();
389
+ input?.click();
384
390
  };
385
391
  $[3] = t3;
386
392
  } else t3 = $[3];
@@ -393,10 +399,13 @@ function useHandleDrag() {
393
399
  onPointerDown: (event_2) => {
394
400
  cancelClick.current = false;
395
401
  if (event_2.pointerType === "mouse" && event_2.button !== 0) return;
402
+ const touch = event_2.pointerType === "touch";
396
403
  origin.current = {
397
404
  base: on ? TRAVEL : 0,
405
+ focuses: !touch,
398
406
  on,
399
407
  rtl: getComputedStyle(event_2.currentTarget).direction === "rtl",
408
+ slop: touch || event_2.pointerType === "pen" ? TOUCH_SLOP : MOUSE_SLOP,
400
409
  x: event_2.clientX
401
410
  };
402
411
  settled.current = null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","MouseEvent","ReactMouseEvent","ReactNode","PointerEvent","ReactPointerEvent","RefAttributes","SwitchFieldProps","RACSwitchFieldProps","SwitchButtonRenderProps","stylex","useCallback","useRef","useState","SwitchButton","SwitchField","AccessibleName","ControlLabel","controlStyles","FieldMessage","invalidFrom","useFieldValidationBehavior","CheckGlyph","useRipple","focus","mergeStatefulStyles","colors","motion","radii","stateLayerOpacity","FORCED_COLORS","_temp","kLqNvP","styles","control","kgeoSG","kGOzcv","kpsdNU","kEoFBp","kGNEyG","kZKoxP","kB7OPa","kkrTdU","k1xSpc","kmuXW","kzqmXN","kjj79g","kVAEAm","$$css","handle","k6CgDc","kWkggS","kaIpWk","kMwMTN","kIyJzY","k1ekBW","kAMwcw","handleActive","handleDisabled","handleOn","handleOnActive","handleOnDisabled","handlePressed","layer","kpwlN0","seat","k87sOh","seatAt","offset","val","undefined","seatDraggable","kFalU9","seatDragging","seatOn","track","kVAM5u","ksu8eU","kMzoRj","trackDisabled","trackOn","trackOnDisabled","hoverLayers","off","on","focusLayers","pressedLayers","TRAVEL","DRAG_SLOP","Drag","ReturnType","useHandleDrag","Ripple","HTMLSpanElement","SwitchProps","children","description","error","icon","Omit","buttonContent","ripple","drag","state","interactive","isDisabled","isReadOnly","isSelected","dragging","active","isHovered","isPressed","isFocusVisible","props","controlReadOnly","controlDisabled","ringVisible","handlers","surface","Switch","t0","$","t1","validationBehavior","T0","t2","t3","field","t4","t5","t6","Symbol","for","messages","t7","t8","setOffset","origin","settled","cancelClick","current","onPointerCancel","event","preventDefault","stopPropagation","onClickCapture","event_0","from","along","rtl","x","clientX","Math","abs","next","min","max","base","onPointerMove","event_1","from_0","stopped","currentTarget","dispatchEvent","bubbles","pointerId","pointerType","input","closest","querySelector","click","onPointerUp","onPointerDown","event_2","button","getComputedStyle","direction","setPointerCapture","stylex.props","_c","props"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["'use client';\n\n// React's event types are aliased because `useHandleDrag` also constructs a\n// DOM `PointerEvent`. Imported unaliased, the name shadows that constructor:\n// TypeScript still resolves the call to the global, since a type-only import\n// takes no value name, but a reader and a static analyser alike read it as\n// React's type, which has no runtime value behind it at all.\nimport type { MouseEvent as ReactMouseEvent, ReactNode, PointerEvent as ReactPointerEvent, RefAttributes } from 'react';\nimport type { SwitchFieldProps as RACSwitchFieldProps, SwitchButtonRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback, useRef, useState } from 'react';\nimport { SwitchButton, SwitchField } from 'react-aria-components';\nimport type { AccessibleName } from '../../render/name';\nimport { ControlLabel } from '../../control';\nimport { controlStyles } from '../../control/styles';\nimport { FieldMessage } from '../../field';\nimport { invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// The switch page: a 52 by 32dp track with a 2dp outline and a full corner,\n// a handle that is 16dp off, 24dp on and 28dp while pressed, a 16dp icon in\n// the handle when asked for, a 40dp state layer around the handle and a 48dp\n// target. Off, the track is surface container highest inside an outline\n// rule and the handle is outline, turning on surface variant while hovered,\n// pressed or focused; on, the track is primary and the handle on primary,\n// turning primary container in the same states, with the icon in on primary\n// container. Disabled, the track and its rule are on surface at the\n// disabled container opacity and the handle on surface at the disabled\n// content opacity, or surface when on. The state layer is on surface off and\n// primary on.\n//\n// React Aria's `SwitchField` is the root, a div holding the description and\n// error slots; its `SwitchButton` is the label around a visually hidden\n// input, and everything drawn is that label's children, chosen from the\n// render state React Aria hands them. The field is the two-column grid the\n// checkbox uses, with the label `display: contents`, so the description and\n// error line up under the text.\n//\n// The handle travels between the two ends of the track and grows between\n// its three sizes on the same transition, `motion.durationShort2` with the\n// standard easing; the state layer and the ripple sit on a 40dp disc centred\n// on the handle, so they move with it. The adjacent label is body-large on\n// surface, which the page keeps the same whichever way the switch is.\n//\n// The page's pressed handle follows the pointer: it grows, travels with the\n// drag, and the switch flips when it is released past the middle of the\n// track or springs back when it is not. React Aria's `SwitchButton` has no\n// drag of its own, so the travel is this component's — see `useHandleDrag`.\n//\n// Under forced colours the switch names system colours for its fills. That\n// mode paints an author's fill in the page's own `Canvas`, so the handle\n// vanished and on and off drew the same empty pill; a system colour is kept\n// rather than repainted. Off is a `ButtonText` handle in an empty track with\n// a `ButtonText` rule. On is a `HighlightText` handle in a track filled with\n// `Highlight`, the pair the mode gives whatever is chosen, with the check in\n// `Highlight` over the handle. Disabled, the same shapes are `GrayText`, and\n// the handle of a switch that is on is emptied to `Canvas` so it still shows\n// against its track. Every style that sets a fill repeats its branch, since\n// one written without the query replaces the property whole, branch and all.\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 _temp = {\n kLqNvP: \"x1lxsm33\",\n \"$$css\": true\n};\nconst styles = {\n control: {\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"x1fb0czk\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1vqgdyp\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n handle: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xp2scj5 x1tt9vl1\",\n kZKoxP: \"xlup9mm\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"xscdzaa x6jt684\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1kky2od\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x7okvu4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n handleActive: {\n kWkggS: \"x1ccu2yh x1tt9vl1\",\n $$css: true\n },\n handleDisabled: {\n kWkggS: \"x1crcgwy x1o55y2u\",\n $$css: true\n },\n handleOn: {\n kWkggS: \"x1ntwmx2 x1sir5s4\",\n kZKoxP: \"xxk0z11\",\n kzqmXN: \"xvy4d1p\",\n $$css: true\n },\n handleOnActive: {\n kWkggS: \"xp89om9 x1sir5s4\",\n $$css: true\n },\n handleOnDisabled: {\n kWkggS: \"x14s9m32 x9yvj25\",\n kMwMTN: \"x1gpw424 x1bhcspo\",\n $$css: true\n },\n handlePressed: {\n kZKoxP: \"x1fgtraw\",\n kzqmXN: \"xgd8bvy\",\n $$css: true\n },\n layer: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1vqgdyp\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kzqmXN: \"x100vrsf\",\n kpwlN0: \"x1qx2jxi\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seat: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1fgtraw\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"xgd8bvy\",\n k87sOh: \"x13vifvy\",\n kLqNvP: \"x1o0tod\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x2hifos\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seatAt: (offset: number) => [_temp, {\n \"--x-insetInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(`${offset}px`)\n }],\n seatDraggable: {\n kFalU9: \"x5ve5x3\",\n $$css: true\n },\n seatDragging: {\n kIyJzY: \"x1mq3mr6\",\n $$css: true\n },\n seatOn: {\n kLqNvP: \"x1n8ud3w\",\n $$css: true\n },\n track: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"x1rrhr5q x9yvj25\",\n kZKoxP: \"x10w6t97\",\n kVAM5u: \"x1fwvt7v x1ylmb6m\",\n kaIpWk: \"x1dkaolv\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xdh2fpr\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xts7igz\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n trackDisabled: {\n kWkggS: \"x1trd85j x9yvj25\",\n kVAM5u: \"xrh88j3 xmnqt3w\",\n $$css: true\n },\n trackOn: {\n kWkggS: \"xnety89 x1jzqe4\",\n kVAM5u: \"x1uajy3w x1n2ykn\",\n $$css: true\n },\n trackOnDisabled: {\n kWkggS: \"x19v6zzp x1o55y2u\",\n kVAM5u: \"x9r1u3d xmnqt3w\",\n $$css: true\n }\n};\n\n// The state layer over the handle: on surface while the switch is off and\n// primary while it is on, at the hover or the pressed opacity.\nconst hoverLayers = {\n off: {\n kWkggS: \"x1b18xnh\",\n $$css: true\n },\n on: {\n kWkggS: \"x659ado\",\n $$css: true\n }\n};\n\n// A keyboard's focus draws the hover layer's colour at the focus opacity.\nconst focusLayers = {\n off: {\n kWkggS: \"xwqhyid\",\n $$css: true\n },\n on: {\n kWkggS: \"x1sog3nf\",\n $$css: true\n }\n};\nconst pressedLayers = {\n off: {\n kWkggS: \"xjeeohs\",\n $$css: true\n },\n on: {\n kWkggS: \"x1dvjsmr\",\n $$css: true\n }\n};\n\n// How far the seat travels: the track's 48dp inside its 2dp rule, less the\n// seat's own 28dp.\nconst TRAVEL = 20;\n\n// How far a press has to move before it is a drag: a quarter of the travel.\n// A finger, a mouse and a pen all move a pixel or two between pressing and\n// lifting, and a press inside this is still a tap, which flips the switch.\nconst DRAG_SLOP = TRAVEL / 4;\ntype Drag = ReturnType<typeof useHandleDrag>;\ntype Ripple = ReturnType<typeof useRipple<HTMLSpanElement>>;\ntype SwitchProps = {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` or `aria-labelledby` instead — one\n * of the three is required, since a switch with none is announced as an\n * unnamed switch.\n *\n * A link or a button in it acts on its own, as in a native label, and\n * leaves the switch as it was. A press anywhere else in the label toggles\n * it.\n */\n children?: ReactNode;\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * Draws the check in the handle while the switch is on, the page's\n * \"icon on selected switch\" form.\n * @default false\n */\n icon?: boolean;\n} & AccessibleName & Omit<RACSwitchFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n// What the label draws, chosen from the render state React Aria hands it.\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 inputs. The ripple's handlers and surface go on the\n// state layer while the switch can change, and are left off while it\n// cannot, since a press that changes nothing should not look like one.\nfunction buttonContent(children: ReactNode, icon: boolean, ripple: Ripple, drag: Drag) {\n return (state: SwitchButtonRenderProps) => {\n const interactive = !state.isDisabled && !state.isReadOnly;\n const on = state.isSelected;\n const dragging = interactive && drag.offset !== null;\n const active = interactive && (state.isHovered || state.isPressed || state.isFocusVisible);\n return <>\n <span {...stylex.props(styles.control, state.isReadOnly && controlStyles.controlReadOnly, state.isDisabled && controlStyles.controlDisabled)}>\n <span {...stylex.props(styles.track, on && styles.trackOn, state.isDisabled && (on ? styles.trackOnDisabled : styles.trackDisabled), state.isFocusVisible && focus.ringVisible)}>\n <span {...interactive ? drag.handlers(on) : {}} {...stylex.props(styles.seat, on && styles.seatOn, interactive && styles.seatDraggable, dragging && styles.seatDragging, dragging && styles.seatAt(drag.offset ?? 0))}>\n <span {...interactive ? ripple.handlers : {}} {...stylex.props(styles.layer, interactive && state.isHovered && hoverLayers[on ? 'on' : 'off'], interactive && state.isFocusVisible && focusLayers[on ? 'on' : 'off'], interactive && state.isPressed && pressedLayers[on ? 'on' : 'off'])}>\n {interactive ? ripple.surface : null}\n </span>\n <span {...stylex.props(styles.handle, on && styles.handleOn, active && (on ? styles.handleOnActive : styles.handleActive), (dragging || interactive && state.isPressed) && styles.handlePressed, state.isDisabled && (on ? styles.handleOnDisabled : styles.handleDisabled))}>\n {icon && on ? <CheckGlyph className=\"xlup9mm x1lliihq x1kky2od\" /> : null}\n </span>\n </span>\n </span>\n </span>\n <ControlLabel state={state}>{children}</ControlLabel>\n </>;\n };\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Aria's: pass\n * `isSelected` with `onChange` to control it, or `defaultSelected` to let it\n * keep its own. A switch takes effect as it is flipped, which is what sets\n * it apart from a checkbox in a form.\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions.\n */\nfunction Switch({\n children,\n description,\n error,\n icon = false,\n ...props\n}: RefAttributes<HTMLDivElement> & SwitchProps) {\n const ripple = useRipple<HTMLSpanElement>();\n const drag = useHandleDrag();\n const validationBehavior = useFieldValidationBehavior();\n return <SwitchField isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(controlStyles.field), props)}>\n <SwitchButton className=\"xjp7ctv\">\n {buttonContent(children, icon, ripple, drag)}\n </SwitchButton>\n <div {...stylex.props(controlStyles.messages)}>\n <FieldMessage description={description} error={error} inset={false} />\n </div>\n </SwitchField>;\n}\n\n/**\n * The handle following a pointer across the track, as the switch page draws\n * a pressed switch. The seat's inset comes from the drag while one is under\n * way, and the switch settles from where the handle was let go: on past the\n * middle of the track, off before it.\n *\n * What flips the switch on an ordinary tap is React Aria's own press, which\n * ends on the pointer being released and pays no attention to where the\n * handle was dragged to — so a drag has to end that press before releasing,\n * which is what the pointer cancel is for, and settle the switch itself.\n * Settling means clicking the field's own input, the same element a tap\n * reaches in the end: the change goes through React Aria, and a controlled\n * switch stays controlled, since nothing here calls `onChange` or holds any\n * state of the switch's own. The click the pointer's release sends after\n * that is cancelled too, so nothing flips the switch a second time.\n *\n * A press that moves no further than the slop is left alone entirely, so a\n * tap flips the switch however still the pointer was — a drag starts only\n * once the pointer passes it, and from then on the handle follows every move.\n *\n * The guard for the click after a drag is cleared by the next press, not by\n * that click, since the click may never come: a touch dragged past the\n * browser's own slop sends none, and a guard left armed swallowed the next\n * tap instead.\n */\nfunction useHandleDrag() {\n const [offset, setOffset] = useState<null | number>(null);\n const origin = useRef<null | {\n base: number;\n on: boolean;\n rtl: boolean;\n x: number;\n }>(null);\n const settled = useRef<null | number>(null);\n const cancelClick = useRef(false);\n const onPointerCancel = useCallback(() => {\n origin.current = null;\n settled.current = null;\n setOffset(null);\n }, []);\n const onClickCapture = useCallback((event: ReactMouseEvent<HTMLSpanElement>) => {\n if (!cancelClick.current) {\n return;\n }\n cancelClick.current = false;\n // The label's activation is the browser's own, so this is what stops the\n // input being flipped by a drag that settled where it began.\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n if (from === null) {\n return;\n }\n const along = from.rtl ? from.x - event.clientX : event.clientX - from.x;\n if (settled.current === null && Math.abs(along) <= DRAG_SLOP) {\n return;\n }\n const next = Math.min(TRAVEL, Math.max(0, from.base + along));\n settled.current = next;\n setOffset(next);\n }, []);\n const onPointerUp = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n const stopped = settled.current;\n const seat = event.currentTarget;\n origin.current = null;\n settled.current = null;\n setOffset(null);\n // A press that never moved is a tap, which React Aria flips on its own.\n if (from === null || stopped === null) {\n return;\n }\n // React Aria's press is about to flip the switch from wherever it\n // started, so it is cancelled first — a pointer cancel is what ends a\n // press without firing it — and the drag settles the switch instead.\n seat.dispatchEvent(new PointerEvent('pointercancel', {\n bubbles: true,\n pointerId: event.pointerId,\n pointerType: event.pointerType\n }));\n // The pointer's own click follows this, by which time the switch has\n // already settled.\n cancelClick.current = true;\n if (stopped > TRAVEL / 2 === from.on) {\n return;\n }\n const input = seat.closest('label')?.querySelector('input');\n input?.click();\n }, []);\n const handlers = useCallback((on: boolean) => ({\n onClickCapture,\n onPointerCancel,\n onPointerDown: (event: ReactPointerEvent<HTMLSpanElement>) => {\n cancelClick.current = false;\n if (event.pointerType === 'mouse' && event.button !== 0) {\n return;\n }\n origin.current = {\n base: on ? TRAVEL : 0,\n on,\n rtl: getComputedStyle(event.currentTarget).direction === 'rtl',\n x: event.clientX\n };\n settled.current = null;\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // A pointer the browser is not tracking has no capture to take —\n // a synthetic event in a test, where the moves are dispatched on\n // this element anyway.\n }\n },\n onPointerMove,\n onPointerUp\n }), [onClickCapture, onPointerCancel, onPointerMove, onPointerUp]);\n return {\n handlers,\n offset\n };\n}\nexport type { SwitchProps };\nexport default Switch;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["c","_c","MouseEvent","ReactMouseEvent","ReactNode","PointerEvent","ReactPointerEvent","RefAttributes","SwitchFieldProps","RACSwitchFieldProps","SwitchButtonRenderProps","stylex","useCallback","useRef","useState","SwitchButton","SwitchField","AccessibleName","ControlLabel","controlStyles","FieldMessage","invalidFrom","useFieldValidationBehavior","CheckGlyph","useRipple","focus","mergeStatefulStyles","colors","motion","radii","stateLayerOpacity","FORCED_COLORS","_temp","kLqNvP","styles","control","kgeoSG","kGOzcv","kpsdNU","kEoFBp","kGNEyG","kZKoxP","kB7OPa","kkrTdU","k1xSpc","kmuXW","kzqmXN","kjj79g","kVAEAm","$$css","handle","k6CgDc","kWkggS","kaIpWk","kMwMTN","kIyJzY","k1ekBW","kAMwcw","handleActive","handleDisabled","handleOn","handleOnActive","handleOnDisabled","handlePressed","layer","kpwlN0","seat","k87sOh","seatAt","offset","val","undefined","seatDraggable","kFalU9","seatDragging","seatOn","track","kVAM5u","ksu8eU","kMzoRj","trackDisabled","trackOn","trackOnDisabled","hoverLayers","off","on","focusLayers","pressedLayers","TRAVEL","MOUSE_SLOP","TOUCH_SLOP","Drag","ReturnType","useHandleDrag","Ripple","HTMLSpanElement","SwitchProps","children","description","error","icon","Omit","buttonContent","ripple","drag","state","interactive","isDisabled","isReadOnly","isSelected","dragging","active","isHovered","isPressed","isFocusVisible","props","controlReadOnly","controlDisabled","ringVisible","handlers","surface","Switch","t0","$","t1","validationBehavior","T0","t2","t3","field","t4","t5","t6","Symbol","for","messages","t7","t8","setOffset","origin","settled","cancelClick","current","onPointerCancel","event","preventDefault","stopPropagation","onClickCapture","event_0","from","along","rtl","x","clientX","Math","abs","slop","next","min","max","base","onPointerMove","event_1","from_0","stopped","currentTarget","dispatchEvent","bubbles","pointerId","pointerType","input","closest","querySelector","focuses","preventScroll","click","onPointerUp","onPointerDown","event_2","button","touch","getComputedStyle","direction","setPointerCapture","stylex.props","_c","props"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["'use client';\n\n// React's event types are aliased because `useHandleDrag` also constructs a\n// DOM `PointerEvent`. Imported unaliased, the name shadows that constructor:\n// TypeScript still resolves the call to the global, since a type-only import\n// takes no value name, but a reader and a static analyser alike read it as\n// React's type, which has no runtime value behind it at all.\nimport type { MouseEvent as ReactMouseEvent, ReactNode, PointerEvent as ReactPointerEvent, RefAttributes } from 'react';\nimport type { SwitchFieldProps as RACSwitchFieldProps, SwitchButtonRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback, useRef, useState } from 'react';\nimport { SwitchButton, SwitchField } from 'react-aria-components';\nimport type { AccessibleName } from '../../render/name';\nimport { ControlLabel } from '../../control';\nimport { controlStyles } from '../../control/styles';\nimport { FieldMessage } from '../../field';\nimport { invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// The switch page: a 52 by 32dp track with a 2dp outline and a full corner,\n// a handle that is 16dp off, 24dp on and 28dp while pressed, a 16dp icon in\n// the handle when asked for, a 40dp state layer around the handle and a 48dp\n// target. Off, the track is surface container highest inside an outline\n// rule and the handle is outline, turning on surface variant while hovered,\n// pressed or focused; on, the track is primary and the handle on primary,\n// turning primary container in the same states, with the icon in on primary\n// container. Disabled, the track and its rule are on surface at the\n// disabled container opacity and the handle on surface at the disabled\n// content opacity, or surface when on. The state layer is on surface off and\n// primary on.\n//\n// React Aria's `SwitchField` is the root, a div holding the description and\n// error slots; its `SwitchButton` is the label around a visually hidden\n// input, and everything drawn is that label's children, chosen from the\n// render state React Aria hands them. The field is the two-column grid the\n// checkbox uses, with the label `display: contents`, so the description and\n// error line up under the text.\n//\n// The handle travels between the two ends of the track and grows between\n// its three sizes on the same transition, `motion.durationShort2` with the\n// standard easing; the state layer and the ripple sit on a 40dp disc centred\n// on the handle, so they move with it. The adjacent label is body-large on\n// surface, which the page keeps the same whichever way the switch is.\n//\n// The page's pressed handle follows the pointer: it grows, travels with the\n// drag, and the switch flips when it is released past the middle of the\n// track or springs back when it is not. React Aria's `SwitchButton` has no\n// drag of its own, so the travel is this component's — see `useHandleDrag`.\n//\n// Under forced colours the switch names system colours for its fills. That\n// mode paints an author's fill in the page's own `Canvas`, so the handle\n// vanished and on and off drew the same empty pill; a system colour is kept\n// rather than repainted. Off is a `ButtonText` handle in an empty track with\n// a `ButtonText` rule. On is a `HighlightText` handle in a track filled with\n// `Highlight`, the pair the mode gives whatever is chosen, with the check in\n// `Highlight` over the handle. Disabled, the same shapes are `GrayText`, and\n// the handle of a switch that is on is emptied to `Canvas` so it still shows\n// against its track. Every style that sets a fill repeats its branch, since\n// one written without the query replaces the property whole, branch and all.\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 _temp = {\n kLqNvP: \"x1lxsm33\",\n \"$$css\": true\n};\nconst styles = {\n control: {\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"x1fb0czk\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1vqgdyp\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n handle: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xp2scj5 x1tt9vl1\",\n kZKoxP: \"xlup9mm\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"xscdzaa x6jt684\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1kky2od\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x7okvu4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n handleActive: {\n kWkggS: \"x1ccu2yh x1tt9vl1\",\n $$css: true\n },\n handleDisabled: {\n kWkggS: \"x1crcgwy x1o55y2u\",\n $$css: true\n },\n handleOn: {\n kWkggS: \"x1ntwmx2 x1sir5s4\",\n kZKoxP: \"xxk0z11\",\n kzqmXN: \"xvy4d1p\",\n $$css: true\n },\n handleOnActive: {\n kWkggS: \"xp89om9 x1sir5s4\",\n $$css: true\n },\n handleOnDisabled: {\n kWkggS: \"x14s9m32 x9yvj25\",\n kMwMTN: \"x1gpw424 x1bhcspo\",\n $$css: true\n },\n handlePressed: {\n kZKoxP: \"x1fgtraw\",\n kzqmXN: \"xgd8bvy\",\n $$css: true\n },\n layer: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1vqgdyp\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kzqmXN: \"x100vrsf\",\n kpwlN0: \"x1qx2jxi\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seat: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1fgtraw\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"xgd8bvy\",\n k87sOh: \"x13vifvy\",\n kLqNvP: \"x1o0tod\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x2hifos\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seatAt: (offset: number) => [_temp, {\n \"--x-insetInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(`${offset}px`)\n }],\n seatDraggable: {\n kFalU9: \"x5ve5x3\",\n $$css: true\n },\n seatDragging: {\n kIyJzY: \"x1mq3mr6\",\n $$css: true\n },\n seatOn: {\n kLqNvP: \"x1n8ud3w\",\n $$css: true\n },\n track: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"x1rrhr5q x9yvj25\",\n kZKoxP: \"x10w6t97\",\n kVAM5u: \"x1fwvt7v x1ylmb6m\",\n kaIpWk: \"x1dkaolv\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xdh2fpr\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xts7igz\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n trackDisabled: {\n kWkggS: \"x1trd85j x9yvj25\",\n kVAM5u: \"xrh88j3 xmnqt3w\",\n $$css: true\n },\n trackOn: {\n kWkggS: \"xnety89 x1jzqe4\",\n kVAM5u: \"x1uajy3w x1n2ykn\",\n $$css: true\n },\n trackOnDisabled: {\n kWkggS: \"x19v6zzp x1o55y2u\",\n kVAM5u: \"x9r1u3d xmnqt3w\",\n $$css: true\n }\n};\n\n// The state layer over the handle: on surface while the switch is off and\n// primary while it is on, at the hover or the pressed opacity.\nconst hoverLayers = {\n off: {\n kWkggS: \"x1b18xnh\",\n $$css: true\n },\n on: {\n kWkggS: \"x659ado\",\n $$css: true\n }\n};\n\n// A keyboard's focus draws the hover layer's colour at the focus opacity.\nconst focusLayers = {\n off: {\n kWkggS: \"xwqhyid\",\n $$css: true\n },\n on: {\n kWkggS: \"x1sog3nf\",\n $$css: true\n }\n};\nconst pressedLayers = {\n off: {\n kWkggS: \"xjeeohs\",\n $$css: true\n },\n on: {\n kWkggS: \"x1dvjsmr\",\n $$css: true\n }\n};\n\n// How far the seat travels: the track's 48dp inside its 2dp rule, less the\n// seat's own 28dp.\nconst TRAVEL = 20;\n\n// How far a press has to move before it is a drag, by the pointer making it.\n// Anything moves a little between pressing and lifting, and a press inside\n// this is still a tap, which flips the switch. A mouse moves a pixel or two,\n// so a quarter of the travel is room enough. A finger drifts further on an\n// ordinary tap — 6 to 10px was common — and under that same 5px the tap was\n// read as a drag let go before the middle, which settled where it began and\n// dropped the tap without a sign. A finger and a pen take half the travel,\n// the platforms' own touch slop; a drag past it is past the middle too.\nconst MOUSE_SLOP = TRAVEL / 4;\nconst TOUCH_SLOP = TRAVEL / 2;\ntype Drag = ReturnType<typeof useHandleDrag>;\ntype Ripple = ReturnType<typeof useRipple<HTMLSpanElement>>;\ntype SwitchProps = {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` or `aria-labelledby` instead — one\n * of the three is required, since a switch with none is announced as an\n * unnamed switch.\n *\n * A link or a button in it acts on its own, as in a native label, and\n * leaves the switch as it was. A press anywhere else in the label toggles\n * it.\n */\n children?: ReactNode;\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * Draws the check in the handle while the switch is on, the page's\n * \"icon on selected switch\" form.\n * @default false\n */\n icon?: boolean;\n} & AccessibleName & Omit<RACSwitchFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n// What the label draws, chosen from the render state React Aria hands it.\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 inputs. The ripple's handlers and surface go on the\n// state layer while the switch can change, and are left off while it\n// cannot, since a press that changes nothing should not look like one.\nfunction buttonContent(children: ReactNode, icon: boolean, ripple: Ripple, drag: Drag) {\n return (state: SwitchButtonRenderProps) => {\n const interactive = !state.isDisabled && !state.isReadOnly;\n const on = state.isSelected;\n const dragging = interactive && drag.offset !== null;\n const active = interactive && (state.isHovered || state.isPressed || state.isFocusVisible);\n return <>\n <span {...stylex.props(styles.control, state.isReadOnly && controlStyles.controlReadOnly, state.isDisabled && controlStyles.controlDisabled)}>\n <span {...stylex.props(styles.track, on && styles.trackOn, state.isDisabled && (on ? styles.trackOnDisabled : styles.trackDisabled), state.isFocusVisible && focus.ringVisible)}>\n <span {...interactive ? drag.handlers(on) : {}} {...stylex.props(styles.seat, on && styles.seatOn, interactive && styles.seatDraggable, dragging && styles.seatDragging, dragging && styles.seatAt(drag.offset ?? 0))}>\n <span {...interactive ? ripple.handlers : {}} {...stylex.props(styles.layer, interactive && state.isHovered && hoverLayers[on ? 'on' : 'off'], interactive && state.isFocusVisible && focusLayers[on ? 'on' : 'off'], interactive && state.isPressed && pressedLayers[on ? 'on' : 'off'])}>\n {interactive ? ripple.surface : null}\n </span>\n <span {...stylex.props(styles.handle, on && styles.handleOn, active && (on ? styles.handleOnActive : styles.handleActive), (dragging || interactive && state.isPressed) && styles.handlePressed, state.isDisabled && (on ? styles.handleOnDisabled : styles.handleDisabled))}>\n {icon && on ? <CheckGlyph className=\"xlup9mm x1lliihq x1kky2od\" /> : null}\n </span>\n </span>\n </span>\n </span>\n <ControlLabel state={state}>{children}</ControlLabel>\n </>;\n };\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Aria's: pass\n * `isSelected` with `onChange` to control it, or `defaultSelected` to let it\n * keep its own. A switch takes effect as it is flipped, which is what sets\n * it apart from a checkbox in a form.\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions.\n */\nfunction Switch({\n children,\n description,\n error,\n icon = false,\n ...props\n}: RefAttributes<HTMLDivElement> & SwitchProps) {\n const ripple = useRipple<HTMLSpanElement>();\n const drag = useHandleDrag();\n const validationBehavior = useFieldValidationBehavior();\n return <SwitchField isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(controlStyles.field), props)}>\n <SwitchButton className=\"xjp7ctv\">\n {buttonContent(children, icon, ripple, drag)}\n </SwitchButton>\n <div {...stylex.props(controlStyles.messages)}>\n <FieldMessage description={description} error={error} inset={false} />\n </div>\n </SwitchField>;\n}\n\n/**\n * The handle following a pointer across the track, as the switch page draws\n * a pressed switch. The seat's inset comes from the drag while one is under\n * way, and the switch settles from where the handle was let go: on past the\n * middle of the track, off before it.\n *\n * What flips the switch on an ordinary tap is React Aria's own press, which\n * ends on the pointer being released and pays no attention to where the\n * handle was dragged to — so a drag has to end that press before releasing,\n * which is what the pointer cancel is for, and settle the switch itself.\n * Settling means clicking the field's own input, the same element a tap\n * reaches in the end: the change goes through React Aria, and a controlled\n * switch stays controlled, since nothing here calls `onChange` or holds any\n * state of the switch's own. The click the pointer's release sends after\n * that is cancelled too, so nothing flips the switch a second time.\n *\n * A press that moves no further than the slop is left alone entirely, so a\n * tap flips the switch however still the pointer was — a drag starts only\n * once the pointer passes it, and from then on the handle follows every move.\n * The slop is the pointer's own: a finger and a pen drift further on a tap\n * than a mouse does. A mouse or pen drag then focuses the input, as a tap\n * does.\n *\n * The guard for the click after a drag is cleared by the next press, not by\n * that click, since the click may never come: a touch dragged past the\n * browser's own slop sends none, and a guard left armed swallowed the next\n * tap instead.\n */\nfunction useHandleDrag() {\n const [offset, setOffset] = useState<null | number>(null);\n const origin = useRef<null | {\n base: number;\n focuses: boolean;\n on: boolean;\n rtl: boolean;\n slop: number;\n x: number;\n }>(null);\n const settled = useRef<null | number>(null);\n const cancelClick = useRef(false);\n const onPointerCancel = useCallback(() => {\n origin.current = null;\n settled.current = null;\n setOffset(null);\n }, []);\n const onClickCapture = useCallback((event: ReactMouseEvent<HTMLSpanElement>) => {\n if (!cancelClick.current) {\n return;\n }\n cancelClick.current = false;\n // The label's activation is the browser's own, so this is what stops the\n // input being flipped by a drag that settled where it began.\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n if (from === null) {\n return;\n }\n const along = from.rtl ? from.x - event.clientX : event.clientX - from.x;\n if (settled.current === null && Math.abs(along) <= from.slop) {\n return;\n }\n const next = Math.min(TRAVEL, Math.max(0, from.base + along));\n settled.current = next;\n setOffset(next);\n }, []);\n const onPointerUp = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n const stopped = settled.current;\n const seat = event.currentTarget;\n origin.current = null;\n settled.current = null;\n setOffset(null);\n // A press that never moved is a tap, which React Aria flips on its own.\n if (from === null || stopped === null) {\n return;\n }\n // React Aria's press is about to flip the switch from wherever it\n // started, so it is cancelled first — a pointer cancel is what ends a\n // press without firing it — and the drag settles the switch instead.\n seat.dispatchEvent(new PointerEvent('pointercancel', {\n bubbles: true,\n pointerId: event.pointerId,\n pointerType: event.pointerType\n }));\n // The pointer's own click follows this, by which time the switch has\n // already settled.\n cancelClick.current = true;\n const input = seat.closest('label')?.querySelector('input');\n // Where a tap leaves focus, a drag leaves it too, whichever side it\n // settles on. A tap reaches the input through the label, which focuses\n // it; the click below is programmatic and moves nothing, and React\n // Aria's press, which would, was cancelled above — so a mouse drag left\n // focus on the page, and a Space after it did nothing. A touch is left\n // alone, as a touch tap leaves no ring to find.\n if (from.focuses) {\n input?.focus({\n preventScroll: true\n });\n }\n if (stopped > TRAVEL / 2 === from.on) {\n return;\n }\n input?.click();\n }, []);\n const handlers = useCallback((on: boolean) => ({\n onClickCapture,\n onPointerCancel,\n onPointerDown: (event: ReactPointerEvent<HTMLSpanElement>) => {\n cancelClick.current = false;\n if (event.pointerType === 'mouse' && event.button !== 0) {\n return;\n }\n const touch = event.pointerType === 'touch';\n origin.current = {\n base: on ? TRAVEL : 0,\n focuses: !touch,\n on,\n rtl: getComputedStyle(event.currentTarget).direction === 'rtl',\n slop: touch || event.pointerType === 'pen' ? TOUCH_SLOP : MOUSE_SLOP,\n x: event.clientX\n };\n settled.current = null;\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // A pointer the browser is not tracking has no capture to take —\n // a synthetic event in a test, where the moves are dispatched on\n // this element anyway.\n }\n },\n onPointerMove,\n onPointerUp\n }), [onClickCapture, onPointerCancel, onPointerMove, onPointerUp]);\n return {\n handlers,\n offset\n };\n}\nexport type { SwitchProps };\nexport default Switch;"],"mappings":"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"}
@@ -40,8 +40,9 @@ type ToolbarTone = 'neutral' | 'vibrant';
40
40
  * you, and a toolbar with no name is a group a screen reader cannot announce.
41
41
  *
42
42
  * `orientation` is React Aria's, and it decides both which arrows move and
43
- * which way the bar runs. A `Separator` inside draws across that direction
44
- * without being told.
43
+ * which way the bar runs. A `Separator` among its controls draws across that
44
+ * direction without being told; one inside an overlay opened from the bar
45
+ * draws as it would anywhere else.
45
46
  *
46
47
  * The call site's `className` and `style` land on the container, which is
47
48
  * the element a layout positions.
@@ -64,8 +64,9 @@ const styles = {
64
64
  * you, and a toolbar with no name is a group a screen reader cannot announce.
65
65
  *
66
66
  * `orientation` is React Aria's, and it decides both which arrows move and
67
- * which way the bar runs. A `Separator` inside draws across that direction
68
- * without being told.
67
+ * which way the bar runs. A `Separator` among its controls draws across that
68
+ * direction without being told; one inside an overlay opened from the bar
69
+ * draws as it would anywhere else.
69
70
  *
70
71
  * The call site's `className` and `style` land on the container, which is
71
72
  * the element a layout positions.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","ToolbarProps","RACToolbarProps","SeparatorProps","stylex","useMemo","Toolbar","RACToolbar","SeparatorContext","mergeStatefulStyles","colors","radii","spacing","styles","base","kGNEyG","kaIpWk","kB7OPa","kMwMTN","k1xSpc","kOIVth","kjj79g","k3XXqK","$$css","horizontal","kXwgrk","kAzted","k8WAf4","kg3NbH","neutral","kWkggS","vertical","k7Eaqz","vibrant","Omit","children","className","style","tone","ToolbarTone","t0","$","T0","T1","t1","t2","t3","t4","orientation","t5","t6","props","undefined","t7","t8","separator","Toolbar","_c","props","RACToolbar","stylex.props"],"sources":["../../../src/components/toolbar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { ToolbarProps as RACToolbarProps, SeparatorProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useMemo } from 'react';\nimport { Toolbar as RACToolbar, SeparatorContext } from 'react-aria-components';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, spacing } from '../../tokens/design.tokens.stylex';\n\n// The toolbars page's container: a row of frequently used controls, on a\n// surface of its own, with the arrow keys moving between them rather than\n// Tab. The page calls it \"a container with configurable slots\", so nothing\n// here says what goes in one — an icon button, a button, a field or a rule\n// are all the call site's to place.\n//\n// The measurements are the page's, stated there in words: 64dp tall,\n// centred, 8dp between items and 16dp of padding outside them. The two\n// colour schemes are its own too — standard on surface container, vibrant on\n// primary container — and both put the muted content role on what they hold.\n// `tone` spells the standard one `neutral` rather than by the page's name,\n// since that is the word every `tone` in the library uses for its neutral\n// role.\n//\n// Two things are this component's own.\n//\n// **A rule inside it runs across the row, not along it.** React Aria's\n// `Toolbar` sets its orientation on itself and nowhere else, so a\n// `Separator` written among the controls would draw the way it does anywhere\n// else — along the row, where it is invisible. This provides React Aria's\n// separator context with the perpendicular orientation, and `Separator`\n// reads it, so a rule between two controls is correct without the call site\n// saying which way it runs.\n//\n// **Arrow-key navigation is React Aria's and is not wrapped.** The arrows\n// move between the controls, and — worth knowing, since the pattern usually\n// implies otherwise — React Aria leaves every control tabbable rather than\n// giving the bar a roving tabindex, so Tab still steps through them one by\n// one. What the bar adds is the toolbar role, which tells a screen reader\n// the controls belong together, and a second way to move between them.\n//\n// One departure, and it is about the shape. The page gives the container's\n// corner as a token its widget draws rather than writes, so there is no\n// value to read: what it states in words is the height, the alignment and\n// the padding, and nothing else. The fully rounded corner here, and the\n// inline box that goes with it, are the library's own choice for a bar that\n// floats over a page rather than docking to its edge — a docked one spans\n// its container and squares its corner, both from the call site.\n\nconst styles = {\n base: {\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x1dkaolv\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n k1xSpc: \"x3nfvp2\",\n kOIVth: \"x126z3so\",\n kjj79g: \"xl56j7k\",\n k3XXqK: \"x1t137rt\",\n $$css: true\n },\n horizontal: {\n kXwgrk: \"x1q0g3np\",\n kAzted: \"x8nclml\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n neutral: {\n kWkggS: \"x1mjdul6\",\n $$css: true\n },\n vertical: {\n kXwgrk: \"xdt5ytf\",\n k7Eaqz: \"x4m7ku4\",\n k8WAf4: \"xp6hjv6\",\n kg3NbH: \"xn60lsn\",\n $$css: true\n },\n vibrant: {\n kWkggS: \"xp89om9\",\n kMwMTN: \"xscdzaa\",\n $$css: true\n }\n};\ntype ToolbarProps = Omit<RACToolbarProps, 'children' | 'className' | 'style'> & {\n /** The controls, and any rule between them. */\n children?: ReactNode;\n /** A function may compute the class from the toolbar's render state. */\n className?: RACToolbarProps['className'];\n /** A function may compute the style from the toolbar's render state. */\n style?: RACToolbarProps['style'];\n /**\n * Which of the page's two colour schemes the bar takes. `neutral` is the\n * page's standard scheme, the surface container it draws by default;\n * `vibrant` moves it to primary container, for a bar meant to carry the\n * page's accent.\n * @default 'neutral'\n */\n tone?: ToolbarTone;\n};\ntype ToolbarTone = 'neutral' | 'vibrant';\n\n/**\n * A container for a set of controls, announced as a toolbar so a screen\n * reader reads them as one group, with the arrow keys moving between them.\n * Tab still steps through each control: React Aria's toolbar adds the arrows\n * rather than replacing what Tab does.\n *\n * ```tsx\n * <Toolbar aria-label=\"Label\">\n * <IconButton aria-label=\"First item\">\n * <FirstIcon />\n * </IconButton>\n * <Separator />\n * <IconButton aria-label=\"Second item\">\n * <SecondIcon />\n * </IconButton>\n * </Toolbar>\n * ```\n *\n * Name it with `aria-label` or `aria-labelledby` — nothing here labels it for\n * you, and a toolbar with no name is a group a screen reader cannot announce.\n *\n * `orientation` is React Aria's, and it decides both which arrows move and\n * which way the bar runs. A `Separator` inside draws across that direction\n * without being told.\n *\n * The call site's `className` and `style` land on the container, which is\n * the element a layout positions.\n */\nfunction Toolbar({\n orientation = 'horizontal',\n tone = 'neutral',\n ...props\n}: RefAttributes<HTMLDivElement> & ToolbarProps) {\n // The rule runs across the toolbar rather than along it. Memoised because\n // a fresh object here would be a new context value on every render, which\n // is what react-perf's no-new-object-as-prop is after.\n const separator = useMemo<SeparatorProps>(() => ({\n orientation: orientation === 'horizontal' ? 'vertical' : 'horizontal'\n }), [orientation]);\n return <SeparatorContext value={separator}>\n <RACToolbar orientation={orientation} {...props} {...mergeStatefulStyles(stylex.props(styles.base, styles[orientation], styles[tone]), props)} />\n </SeparatorContext>;\n}\nexport type { ToolbarProps, ToolbarTone };\nexport default Toolbar;"],"mappings":";;;;;;;;AAkDA,MAAMgB,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,YAAY;EACVC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRL,OAAO;CACT;CACAM,SAAS;EACPC,QAAQ;EACRP,OAAO;CACT;CACAQ,UAAU;EACRN,QAAQ;EACRO,QAAQ;EACRL,QAAQ;EACRC,QAAQ;EACRL,OAAO;CACT;CACAU,SAAS;EACPH,QAAQ;EACRZ,QAAQ;EACRK,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAAjB,UAAAkC,IAAA;CAAA,MAAAC,IAAA3C,EAAA,EAAA;CAAA,IAAA4C;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAD,IAAA;EAAiB,MAAA,EAAAQ,aAAAC,IAAAX,MAAAY,IAAA,GAAAC,YAAAX;EACf,MAAAQ,cAAAC,OAAAG,KAAAA,IAAA,eAAAH;EACA,MAAAX,OAAAY,OAAAE,KAAAA,IAAA,YAAAF;EAOe,MAAAG,KAAAL,gBAAgB,eAAhB,aAAA;EAAwD,IAAAM;EAAA,IAAAb,EAAA,OAAAY,IAAA;GADtBC,KAAA,EAAAN,aAClCK,GACf;GAACZ,EAAA,KAAAY;GAAAZ,EAAA,KAAAa;EAAA,OAAAA,KAAAb,EAAA;EAFD,MAAAc,YAAiDD;EAGzCX,KAAAnC;EAAwB+C,KAAAA;EAC3Bb,KAAAnC;EAAwByC,KAAAA;EAAiBG,KAAAA;EAAWL,KAAArC,oBAAoBL,MAAaS,OAAMC,MAAOD,OAAOmC,cAAcnC,OAAOyB,KAAK,GAAGa,OAAK;EAACV,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAL,KAAAD,EAAA;EAAAE,KAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAAA,IAAAQ;CAAA,IAAAR,EAAA,OAAAC,MAAAD,EAAA,QAAAG,MAAAH,EAAA,QAAAI,MAAAJ,EAAA,QAAAK,IAAA;EAA7IG,KAAA,oBAAC,IAAD;GAAyBD,aAAAA;GAAW,GAAMG;GAAK,GAAML;EAAwF,CAAA;EAAIL,EAAA,KAAAC;EAAAD,EAAA,MAAAG;EAAAH,EAAA,MAAAI;EAAAJ,EAAA,MAAAK;EAAAL,EAAA,MAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,QAAAE,MAAAF,EAAA,QAAAM,MAAAN,EAAA,QAAAQ,IAAA;EAD9IC,KAAA,oBAAC,IAAD;GAAyBK,OAAAA;GAC5BN,UAAAA;EADoB,CAAA;EAEHR,EAAA,MAAAE;EAAAF,EAAA,MAAAM;EAAAN,EAAA,MAAAQ;EAAAR,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAFdS;AAEc"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","ToolbarProps","RACToolbarProps","SeparatorProps","stylex","useMemo","Toolbar","RACToolbar","SeparatorContext","mergeStatefulStyles","colors","radii","spacing","styles","base","kGNEyG","kaIpWk","kB7OPa","kMwMTN","k1xSpc","kOIVth","kjj79g","k3XXqK","$$css","horizontal","kXwgrk","kAzted","k8WAf4","kg3NbH","neutral","kWkggS","vertical","k7Eaqz","vibrant","Omit","children","className","style","tone","ToolbarTone","t0","$","T0","T1","t1","t2","t3","t4","orientation","t5","t6","props","undefined","t7","t8","separator","Toolbar","_c","props","RACToolbar","stylex.props"],"sources":["../../../src/components/toolbar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { ToolbarProps as RACToolbarProps, SeparatorProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useMemo } from 'react';\nimport { Toolbar as RACToolbar, SeparatorContext } from 'react-aria-components';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, spacing } from '../../tokens/design.tokens.stylex';\n\n// The toolbars page's container: a row of frequently used controls, on a\n// surface of its own, with the arrow keys moving between them rather than\n// Tab. The page calls it \"a container with configurable slots\", so nothing\n// here says what goes in one — an icon button, a button, a field or a rule\n// are all the call site's to place.\n//\n// The measurements are the page's, stated there in words: 64dp tall,\n// centred, 8dp between items and 16dp of padding outside them. The two\n// colour schemes are its own too — standard on surface container, vibrant on\n// primary container — and both put the muted content role on what they hold.\n// `tone` spells the standard one `neutral` rather than by the page's name,\n// since that is the word every `tone` in the library uses for its neutral\n// role.\n//\n// Two things are this component's own.\n//\n// **A rule inside it runs across the row, not along it.** React Aria's\n// `Toolbar` sets its orientation on itself and nowhere else, so a\n// `Separator` written among the controls would draw the way it does anywhere\n// else — along the row, where it is invisible. This provides React Aria's\n// separator context with the perpendicular orientation, and `Separator`\n// reads it, so a rule between two controls is correct without the call site\n// saying which way it runs. The context reaches the bar's own controls and\n// stops at an overlay opened from one: React context crosses the portal a\n// popover, sheet or dialog renders through, so their content parts clear it\n// — see `src/overlay` — and a rule inside one runs across the overlay as it\n// does anywhere else.\n//\n// **Arrow-key navigation is React Aria's and is not wrapped.** The arrows\n// move between the controls, and — worth knowing, since the pattern usually\n// implies otherwise — React Aria leaves every control tabbable rather than\n// giving the bar a roving tabindex, so Tab still steps through them one by\n// one. What the bar adds is the toolbar role, which tells a screen reader\n// the controls belong together, and a second way to move between them.\n//\n// One departure, and it is about the shape. The page gives the container's\n// corner as a token its widget draws rather than writes, so there is no\n// value to read: what it states in words is the height, the alignment and\n// the padding, and nothing else. The fully rounded corner here, and the\n// inline box that goes with it, are the library's own choice for a bar that\n// floats over a page rather than docking to its edge — a docked one spans\n// its container and squares its corner, both from the call site.\n\nconst styles = {\n base: {\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x1dkaolv\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n k1xSpc: \"x3nfvp2\",\n kOIVth: \"x126z3so\",\n kjj79g: \"xl56j7k\",\n k3XXqK: \"x1t137rt\",\n $$css: true\n },\n horizontal: {\n kXwgrk: \"x1q0g3np\",\n kAzted: \"x8nclml\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n neutral: {\n kWkggS: \"x1mjdul6\",\n $$css: true\n },\n vertical: {\n kXwgrk: \"xdt5ytf\",\n k7Eaqz: \"x4m7ku4\",\n k8WAf4: \"xp6hjv6\",\n kg3NbH: \"xn60lsn\",\n $$css: true\n },\n vibrant: {\n kWkggS: \"xp89om9\",\n kMwMTN: \"xscdzaa\",\n $$css: true\n }\n};\ntype ToolbarProps = Omit<RACToolbarProps, 'children' | 'className' | 'style'> & {\n /** The controls, and any rule between them. */\n children?: ReactNode;\n /** A function may compute the class from the toolbar's render state. */\n className?: RACToolbarProps['className'];\n /** A function may compute the style from the toolbar's render state. */\n style?: RACToolbarProps['style'];\n /**\n * Which of the page's two colour schemes the bar takes. `neutral` is the\n * page's standard scheme, the surface container it draws by default;\n * `vibrant` moves it to primary container, for a bar meant to carry the\n * page's accent.\n * @default 'neutral'\n */\n tone?: ToolbarTone;\n};\ntype ToolbarTone = 'neutral' | 'vibrant';\n\n/**\n * A container for a set of controls, announced as a toolbar so a screen\n * reader reads them as one group, with the arrow keys moving between them.\n * Tab still steps through each control: React Aria's toolbar adds the arrows\n * rather than replacing what Tab does.\n *\n * ```tsx\n * <Toolbar aria-label=\"Label\">\n * <IconButton aria-label=\"First item\">\n * <FirstIcon />\n * </IconButton>\n * <Separator />\n * <IconButton aria-label=\"Second item\">\n * <SecondIcon />\n * </IconButton>\n * </Toolbar>\n * ```\n *\n * Name it with `aria-label` or `aria-labelledby` — nothing here labels it for\n * you, and a toolbar with no name is a group a screen reader cannot announce.\n *\n * `orientation` is React Aria's, and it decides both which arrows move and\n * which way the bar runs. A `Separator` among its controls draws across that\n * direction without being told; one inside an overlay opened from the bar\n * draws as it would anywhere else.\n *\n * The call site's `className` and `style` land on the container, which is\n * the element a layout positions.\n */\nfunction Toolbar({\n orientation = 'horizontal',\n tone = 'neutral',\n ...props\n}: RefAttributes<HTMLDivElement> & ToolbarProps) {\n // The rule runs across the toolbar rather than along it. Memoised because\n // a fresh object here would be a new context value on every render, which\n // is what react-perf's no-new-object-as-prop is after.\n const separator = useMemo<SeparatorProps>(() => ({\n orientation: orientation === 'horizontal' ? 'vertical' : 'horizontal'\n }), [orientation]);\n return <SeparatorContext value={separator}>\n <RACToolbar orientation={orientation} {...props} {...mergeStatefulStyles(stylex.props(styles.base, styles[orientation], styles[tone]), props)} />\n </SeparatorContext>;\n}\nexport type { ToolbarProps, ToolbarTone };\nexport default Toolbar;"],"mappings":";;;;;;;;AAsDA,MAAMgB,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,YAAY;EACVC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRL,OAAO;CACT;CACAM,SAAS;EACPC,QAAQ;EACRP,OAAO;CACT;CACAQ,UAAU;EACRN,QAAQ;EACRO,QAAQ;EACRL,QAAQ;EACRC,QAAQ;EACRL,OAAO;CACT;CACAU,SAAS;EACPH,QAAQ;EACRZ,QAAQ;EACRK,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAAjB,UAAAkC,IAAA;CAAA,MAAAC,IAAA3C,EAAA,EAAA;CAAA,IAAA4C;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAD,IAAA;EAAiB,MAAA,EAAAQ,aAAAC,IAAAX,MAAAY,IAAA,GAAAC,YAAAX;EACf,MAAAQ,cAAAC,OAAAG,KAAAA,IAAA,eAAAH;EACA,MAAAX,OAAAY,OAAAE,KAAAA,IAAA,YAAAF;EAOe,MAAAG,KAAAL,gBAAgB,eAAhB,aAAA;EAAwD,IAAAM;EAAA,IAAAb,EAAA,OAAAY,IAAA;GADtBC,KAAA,EAAAN,aAClCK,GACf;GAACZ,EAAA,KAAAY;GAAAZ,EAAA,KAAAa;EAAA,OAAAA,KAAAb,EAAA;EAFD,MAAAc,YAAiDD;EAGzCX,KAAAnC;EAAwB+C,KAAAA;EAC3Bb,KAAAnC;EAAwByC,KAAAA;EAAiBG,KAAAA;EAAWL,KAAArC,oBAAoBL,MAAaS,OAAMC,MAAOD,OAAOmC,cAAcnC,OAAOyB,KAAK,GAAGa,OAAK;EAACV,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAL,KAAAD,EAAA;EAAAE,KAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAAA,IAAAQ;CAAA,IAAAR,EAAA,OAAAC,MAAAD,EAAA,QAAAG,MAAAH,EAAA,QAAAI,MAAAJ,EAAA,QAAAK,IAAA;EAA7IG,KAAA,oBAAC,IAAD;GAAyBD,aAAAA;GAAW,GAAMG;GAAK,GAAML;EAAwF,CAAA;EAAIL,EAAA,KAAAC;EAAAD,EAAA,MAAAG;EAAAH,EAAA,MAAAI;EAAAJ,EAAA,MAAAK;EAAAL,EAAA,MAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,QAAAE,MAAAF,EAAA,QAAAM,MAAAN,EAAA,QAAAQ,IAAA;EAD9IC,KAAA,oBAAC,IAAD;GAAyBK,OAAAA;GAC5BN,UAAAA;EADoB,CAAA;EAEHR,EAAA,MAAAE;EAAAF,EAAA,MAAAM;EAAAN,EAAA,MAAAQ;EAAAR,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAFdS;AAEc"}