@kanso-labs/kanso-ui 0.40.7 → 0.40.8

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 (43) hide show
  1. package/dist/badge/index.js +15 -0
  2. package/dist/badge/index.js.map +1 -0
  3. package/dist/components/badge/index.js +91 -47
  4. package/dist/components/badge/index.js.map +1 -1
  5. package/dist/components/dialog/index.d.ts +6 -1
  6. package/dist/components/dialog/index.js +54 -24
  7. package/dist/components/dialog/index.js.map +1 -1
  8. package/dist/components/form/index.d.ts +5 -4
  9. package/dist/components/form/index.js.map +1 -1
  10. package/dist/components/link/index.js +16 -5
  11. package/dist/components/link/index.js.map +1 -1
  12. package/dist/components/menu/index.js +29 -21
  13. package/dist/components/menu/index.js.map +1 -1
  14. package/dist/components/navigation-bar/index.js +134 -54
  15. package/dist/components/navigation-bar/index.js.map +1 -1
  16. package/dist/components/navigation-rail/index.js +56 -37
  17. package/dist/components/navigation-rail/index.js.map +1 -1
  18. package/dist/components/number-field/index.d.ts +13 -2
  19. package/dist/components/number-field/index.js +95 -84
  20. package/dist/components/number-field/index.js.map +1 -1
  21. package/dist/components/sheet/index.d.ts +8 -1
  22. package/dist/components/sheet/index.js +45 -29
  23. package/dist/components/sheet/index.js.map +1 -1
  24. package/dist/components/snackbar/index.d.ts +4 -0
  25. package/dist/components/snackbar/index.js +54 -49
  26. package/dist/components/snackbar/index.js.map +1 -1
  27. package/dist/field/index.js +303 -252
  28. package/dist/field/index.js.map +1 -1
  29. package/dist/field/root.js +8 -8
  30. package/dist/field/root.js.map +1 -1
  31. package/dist/field/styles.js +22 -0
  32. package/dist/field/styles.js.map +1 -1
  33. package/dist/hooks/useBottomEdge.js +83 -0
  34. package/dist/hooks/useBottomEdge.js.map +1 -0
  35. package/dist/navigation/context.js.map +1 -1
  36. package/dist/navigation/index.js +16 -4
  37. package/dist/navigation/index.js.map +1 -1
  38. package/dist/navigation/styles.js +35 -1
  39. package/dist/navigation/styles.js.map +1 -1
  40. package/dist/row/styles.js +2 -1
  41. package/dist/row/styles.js.map +1 -1
  42. package/dist/styles.css +90 -24
  43. package/package.json +2 -2
@@ -0,0 +1,15 @@
1
+ import { createContext } from "react";
2
+ //#region src/badge/index.ts
3
+ /**
4
+ * A style laid over a large badge's mark by what the badge is drawn in,
5
+ * after the mark's own, so it can move the mark out of its corner. A
6
+ * navigation destination sets its label beside its icon in its horizontal
7
+ * forms, and a count overhangs the icon by up to 22dp on that side: the
8
+ * destination puts the mark in the flow there, so the label starts after it
9
+ * rather than under it. See src/navigation/styles.ts.
10
+ */
11
+ const BadgeMarkContext = createContext(null);
12
+ //#endregion
13
+ export { BadgeMarkContext };
14
+
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["StyleXStyles","createContext","BadgeMarkContext"],"sources":["../../src/badge/index.ts"],"sourcesContent":["import type { StyleXStyles } from '@stylexjs/stylex';\nimport { createContext } from 'react';\n\n// What a component drawing a badge can say about where its large mark goes.\n// Apart from the badge itself for the reason src/row gives, and a module of\n// its own rather than a part of the one place that uses it, since the badge\n// imports it and that place imports the badge.\n\n/**\n * A style laid over a large badge's mark by what the badge is drawn in,\n * after the mark's own, so it can move the mark out of its corner. A\n * navigation destination sets its label beside its icon in its horizontal\n * forms, and a count overhangs the icon by up to 22dp on that side: the\n * destination puts the mark in the flow there, so the label starts after it\n * rather than under it. See src/navigation/styles.ts.\n */\nconst BadgeMarkContext = createContext<null | StyleXStyles>(null);\nexport { BadgeMarkContext };"],"mappings":";;;;;;;;;;AAgBA,MAAME,mBAAmBD,cAAmC,IAAI"}
@@ -1,10 +1,56 @@
1
1
  "use client";
2
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
3
  import { useRender } from "../../render/useRender.js";
3
4
  import { mergeStyles } from "../../styles/merge.js";
5
+ import { BadgeMarkContext } from "../../badge/index.js";
4
6
  import { c } from "react/compiler-runtime";
5
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { useContext } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
9
  import { useLocale } from "react-aria-components";
7
10
  //#region src/components/badge/index.tsx
11
+ const styles = {
12
+ inFlow: {
13
+ kVAEAm: "x1uhb9sk",
14
+ $$css: true
15
+ },
16
+ large: {
17
+ kGNEyG: "x6s0dn4",
18
+ kZKoxP: "xlup9mm",
19
+ kMwMTN: "x1l7c2jh",
20
+ k1xSpc: "x78zum5",
21
+ kMv6JI: "xs1w0rn",
22
+ kGuDYH: "x1n35her",
23
+ kcqcaj: "xss6m8b",
24
+ k63SB2: "x1su64ma",
25
+ k87sOh: "x1qiirwl",
26
+ kLqNvP: "xty0069",
27
+ kjj79g: "xl56j7k",
28
+ kb6lSQ: "xdlnduh",
29
+ kLWn49: "xaomhve",
30
+ k7Eaqz: "x15kz4h8",
31
+ kg3NbH: "ximhkdq",
32
+ khDVqt: "xuxw1ft",
33
+ $$css: true
34
+ },
35
+ mark: {
36
+ kWkggS: "xwi4nbo",
37
+ kVAM5u: "x1w1tqly",
38
+ kaIpWk: "x1dkaolv",
39
+ ksu8eU: "xx61lck",
40
+ kMzoRj: "x13rsnn2",
41
+ kB7OPa: "x9f619",
42
+ kfzvcC: "x47corl",
43
+ kVAEAm: "x10l6tqk",
44
+ $$css: true
45
+ },
46
+ small: {
47
+ kZKoxP: "xols6we",
48
+ kzqmXN: "x1v4s8kt",
49
+ k87sOh: "x13vifvy",
50
+ kt4wiu: "xtijo5x",
51
+ $$css: true
52
+ }
53
+ };
8
54
  /**
9
55
  * A badge on the corner of what it wraps, usually an icon: the small dot,
10
56
  * or with `count` the large badge holding a number. The mark is hidden from
@@ -26,10 +72,11 @@ import { useLocale } from "react-aria-components";
26
72
  * the badge is drawn on.
27
73
  */
28
74
  function Badge(t0) {
29
- const $ = c(18);
30
- const { children, count, max: t1, render, ...props } = t0;
75
+ const $ = c(21);
76
+ const { children, count, max: t1, render, ...props$1 } = t0;
31
77
  const max = t1 === void 0 ? 999 : t1;
32
78
  const { locale } = useLocale();
79
+ const placed = useContext(BadgeMarkContext);
33
80
  let t2;
34
81
  if ($[0] !== count || $[1] !== locale || $[2] !== max) {
35
82
  const numbers = new Intl.NumberFormat(locale);
@@ -41,60 +88,57 @@ function Badge(t0) {
41
88
  } else t2 = $[3];
42
89
  const label = t2;
43
90
  const t3 = "span";
44
- const t4 = mergeStyles({ className: "x9f619 x3nfvp2 x1n2onr6" }, props);
91
+ const t4 = mergeStyles({ className: "x9f619 x3nfvp2 x1n2onr6" }, props$1);
45
92
  let t5;
46
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
47
- t5 = {
48
- 0: { className: "xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x10l6tqk x6s0dn4 xlup9mm x1l7c2jh x78zum5 xs1w0rn x1n35her xss6m8b x1su64ma x1qiirwl xty0069 xl56j7k xdlnduh xaomhve x15kz4h8 ximhkdq xuxw1ft" },
49
- 2: { className: "xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x10l6tqk xols6we x1v4s8kt x13vifvy xtijo5x" },
50
- 1: { className: "xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x6s0dn4 xlup9mm x1l7c2jh x78zum5 xs1w0rn x1n35her xss6m8b x1su64ma x1qiirwl xty0069 xl56j7k xdlnduh xaomhve x15kz4h8 ximhkdq xuxw1ft x1uhb9sk" },
51
- 3: { className: "xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl xols6we x1v4s8kt x13vifvy xtijo5x x1uhb9sk" }
52
- };
53
- $[4] = t5;
54
- } else t5 = $[4];
55
- const t6 = t5[!!(label === void 0) << 1 | !!(children === void 0 || children === null) << 0];
56
- let t7;
57
- if ($[5] !== label || $[6] !== t6) {
58
- t7 = /* @__PURE__ */ jsx("span", {
93
+ if ($[4] !== children || $[5] !== label || $[6] !== placed) {
94
+ t5 = props(styles.mark, label === void 0 ? styles.small : styles.large, (children === void 0 || children === null) && styles.inFlow, label !== void 0 && placed);
95
+ $[4] = children;
96
+ $[5] = label;
97
+ $[6] = placed;
98
+ $[7] = t5;
99
+ } else t5 = $[7];
100
+ let t6;
101
+ if ($[8] !== label || $[9] !== t5) {
102
+ t6 = /* @__PURE__ */ jsx("span", {
59
103
  "aria-hidden": "true",
60
- ...t6,
104
+ ...t5,
61
105
  children: label
62
106
  });
63
- $[5] = label;
64
- $[6] = t6;
65
- $[7] = t7;
66
- } else t7 = $[7];
107
+ $[8] = label;
108
+ $[9] = t5;
109
+ $[10] = t6;
110
+ } else t6 = $[10];
111
+ let t7;
112
+ if ($[11] !== children || $[12] !== t6) {
113
+ t7 = /* @__PURE__ */ jsxs(Fragment$1, { children: [children, t6] });
114
+ $[11] = children;
115
+ $[12] = t6;
116
+ $[13] = t7;
117
+ } else t7 = $[13];
67
118
  let t8;
68
- if ($[8] !== children || $[9] !== t7) {
69
- t8 = /* @__PURE__ */ jsxs(Fragment, { children: [children, t7] });
70
- $[8] = children;
71
- $[9] = t7;
72
- $[10] = t8;
73
- } else t8 = $[10];
74
- let t9;
75
- if ($[11] !== props || $[12] !== t4 || $[13] !== t8) {
76
- t9 = {
77
- ...props,
119
+ if ($[14] !== props$1 || $[15] !== t4 || $[16] !== t7) {
120
+ t8 = {
121
+ ...props$1,
78
122
  ...t4,
79
- children: t8
123
+ children: t7
80
124
  };
81
- $[11] = props;
82
- $[12] = t4;
83
- $[13] = t8;
84
- $[14] = t9;
85
- } else t9 = $[14];
86
- let t10;
87
- if ($[15] !== render || $[16] !== t9) {
88
- t10 = {
125
+ $[14] = props$1;
126
+ $[15] = t4;
127
+ $[16] = t7;
128
+ $[17] = t8;
129
+ } else t8 = $[17];
130
+ let t9;
131
+ if ($[18] !== render || $[19] !== t8) {
132
+ t9 = {
89
133
  defaultTagName: t3,
90
- props: t9,
134
+ props: t8,
91
135
  render
92
136
  };
93
- $[15] = render;
94
- $[16] = t9;
95
- $[17] = t10;
96
- } else t10 = $[17];
97
- return useRender(t10);
137
+ $[18] = render;
138
+ $[19] = t8;
139
+ $[20] = t9;
140
+ } else t9 = $[20];
141
+ return useRender(t9);
98
142
  }
99
143
  //#endregion
100
144
  export { Badge as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","stylex","useLocale","RenderComponentProps","useRender","mergeStyles","colors","radii","spacing","typography","FORCED_COLORS","BadgeProps","count","max","Badge","t0","$","children","t1","render","props","undefined","locale","t2","numbers","Intl","NumberFormat","format","label","t3","t4","className","t5","Symbol","for","0","2","1","3","t6","t7","t8","t9","t10","defaultTagName","_c"],"sources":["../../../src/components/badge/index.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { useLocale } from 'react-aria-components';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { useRender } from '../../render/useRender';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, spacing, typography } from '../../tokens/design.tokens.stylex';\n\n// The badges page's badge: a mark on the corner of an icon that flags\n// something new there, either as the 6dp small badge or as the 16dp large\n// badge holding a count. Both are the error pair — the error role, with the\n// count in on error — on a full corner, and the count is label small, capped\n// at four characters with a plus, as \"999+\".\n//\n// The badge wraps what it is drawn on, usually an icon, and places the mark\n// against that element's box, which is what the page measures from. The\n// small badge fills the icon's top trailing 6dp square. The large badge's\n// bottom leading corner sits 14dp down and 12dp in from the icon's top\n// trailing corner, so it stands 2dp above the icon and grows toward the end\n// as its count lengthens, to the page's 34dp at \"999+\". Both are logical\n// insets, so the mark stays on the trailing corner under right-to-left.\n//\n// Given nothing to wrap, the badge is the mark alone, standing in the line\n// rather than over a corner. That is the form the tabs page draws after a\n// label with no icon above it.\n//\n// The mark is hidden from assistive technology. A count read on its own is a\n// number with no subject; it belongs in the name of the control it sits on,\n// where a reader meets it with what it counts — \"Notifications, 3 new\" — and\n// the stories show it there.\n//\n// Under forced colours the error fill is painted over in the mode's\n// background, which left the small badge as nothing at all. It takes a 1px\n// border there instead, which the mode keeps and paints in its text colour.\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)';\ntype BadgeProps = RenderComponentProps<'span'> & {\n /**\n * The number to show, which draws the page's large badge. Left out, the\n * badge is the small 6dp dot, which flags without counting. A count of 0\n * still draws, so leave the badge out when there is nothing to count.\n */\n count?: number;\n /**\n * The largest count drawn as itself. Above it the badge reads `max` and a\n * plus, which is the page's 999+ at the default.\n * @default 999\n */\n max?: number;\n};\n\n/**\n * A badge on the corner of what it wraps, usually an icon: the small dot,\n * or with `count` the large badge holding a number. The mark is hidden from\n * assistive technology, so put what it says in the name of the control it\n * sits on.\n *\n * ```tsx\n * <IconButton aria-label=\"Notifications, 3 new\">\n * <Badge count={3}>\n * <BellIcon />\n * </Badge>\n * </IconButton>\n * ```\n *\n * Given no children, the mark stands alone in the line, as a tab draws it\n * after its label.\n *\n * The call site's `className` and `style` land on the element wrapping what\n * the badge is drawn on.\n */\nfunction Badge({\n children,\n count,\n max = 999,\n render,\n ...props\n}: BadgeProps) {\n const {\n locale\n } = useLocale();\n const numbers = new Intl.NumberFormat(locale);\n const label = count === undefined ? undefined : count > max ? `${numbers.format(max)}+` : numbers.format(count);\n return useRender({\n defaultTagName: 'span',\n props: {\n ...props,\n ...mergeStyles({\n className: \"x9f619 x3nfvp2 x1n2onr6\"\n }, props),\n children: <>\n {children}\n <span aria-hidden=\"true\" {...{\n 0: {\n className: \"xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x10l6tqk x6s0dn4 xlup9mm x1l7c2jh x78zum5 xs1w0rn x1n35her xss6m8b x1su64ma x1qiirwl xty0069 xl56j7k xdlnduh xaomhve x15kz4h8 ximhkdq xuxw1ft\"\n },\n 2: {\n className: \"xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x10l6tqk xols6we x1v4s8kt x13vifvy xtijo5x\"\n },\n 1: {\n className: \"xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl x6s0dn4 xlup9mm x1l7c2jh x78zum5 xs1w0rn x1n35her xss6m8b x1su64ma x1qiirwl xty0069 xl56j7k xdlnduh xaomhve x15kz4h8 ximhkdq xuxw1ft x1uhb9sk\"\n },\n 3: {\n className: \"xwi4nbo x1w1tqly x1dkaolv xx61lck x13rsnn2 x9f619 x47corl xols6we x1v4s8kt x13vifvy xtijo5x x1uhb9sk\"\n }\n }[!!(label === undefined) << 1 | !!(children === undefined || children === null) << 0]}>\n {label}\n </span>\n </>\n },\n render\n });\n}\nexport type { BadgeProps };\nexport default Badge;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,SAAAe,MAAAC,IAAA;CAAA,MAAAC,IAAAhB,EAAA,EAAA;CAAe,MAAA,EAAAiB,UAAAL,OAAAC,KAAAK,IAAAC,QAAA,GAAAC,UAAAL;CAGb,MAAAF,MAAAK,OAAAG,KAAAA,IAAA,MAAAH;CAIA,MAAA,EAAAI,WAEIpB,UAAU;CAAE,IAAAqB;CAAA,IAAAP,EAAA,OAAAJ,SAAAI,EAAA,OAAAM,UAAAN,EAAA,OAAAH,KAAA;EAChB,MAAAW,UAAgB,IAAIC,KAAIC,aAAcJ,MAAM;EAC9BC,KAAAX,UAAUS,KAAAA,IAAVA,KAAAA,IAAkCT,QAAQC,MAAR,GAAiBW,QAAOG,OAAQd,GAAG,EAAC,KAAMW,QAAOG,OAAQf,KAAK;EAACI,EAAA,KAAAJ;EAAAI,EAAA,KAAAM;EAAAN,EAAA,KAAAH;EAAAG,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAA/G,MAAAY,QAAcL;CAEI,MAAAM,KAAA;CAGX,MAAAC,KAAAzB,YAAY,EAAA0B,WACF,0BACb,GAAGX,KAAK;CAAC,IAAAY;CAAA,IAAAhB,EAAA,OAAAiB,OAAAC,IAAA,2BAAA,GAAA;EAGwBF,KAAA;GAAAG,GAC1B,EAAAJ,WACU,0MACb;GAACK,GACE,EAAAL,WACU,uGACb;GAACM,GACE,EAAAN,WACU,0MACb;GAACO,GACE,EAAAP,WACU,uGACb;EACF;EAACf,EAAA,KAAAgB;CAAA,OAAAA,KAAAhB,EAAA;CAb8B,MAAAuB,KAAAP,GAa7B,CAAC,EAAEJ,UAAUP,KAAAA,MAAc,IAAI,CAAC,EAAEJ,aAAaI,KAAAA,KAAaJ,aAAa,SAAS;CAAE,IAAAuB;CAAA,IAAAxB,EAAA,OAAAY,SAAAZ,EAAA,OAAAuB,IAAA;EAbpFC,KAAA,oBAAA,QAAA;GAAkB,eAAA;GAAM,GAAKD;GAc1BX,UAAAA;EACI,CAAA;EAAAZ,EAAA,KAAAY;EAAAZ,EAAA,KAAAuB;EAAAvB,EAAA,KAAAwB;CAAA,OAAAA,KAAAxB,EAAA;CAAA,IAAAyB;CAAA,IAAAzB,EAAA,OAAAC,YAAAD,EAAA,OAAAwB,IAAA;EAjBDC,KAAA,qBAAA,UAAA,EAAA,UAAA,CACLxB,UACDuB,EAeO,EAAA,CAAA;EACNxB,EAAA,KAAAC;EAAAD,EAAA,KAAAwB;EAAAxB,EAAA,MAAAyB;CAAA,OAAAA,KAAAzB,EAAA;CAAA,IAAA0B;CAAA,IAAA1B,EAAA,QAAAI,SAAAJ,EAAA,QAAAc,MAAAd,EAAA,QAAAyB,IAAA;EAvBAC,KAAA;GAAA,GACFtB;GAAK,GACLU;GAEMb,UACCwB;EAmBZ;EAACzB,EAAA,MAAAI;EAAAJ,EAAA,MAAAc;EAAAd,EAAA,MAAAyB;EAAAzB,EAAA,MAAA0B;CAAA,OAAAA,KAAA1B,EAAA;CAAA,IAAA2B;CAAA,IAAA3B,EAAA,QAAAG,UAAAH,EAAA,QAAA0B,IAAA;EA1BcC,MAAA;GAAAC,gBACCf;GAAMT,OACfsB;GAwBNvB;EAEH;EAACH,EAAA,MAAAG;EAAAH,EAAA,MAAA0B;EAAA1B,EAAA,MAAA2B;CAAA,OAAAA,MAAA3B,EAAA;CAAA,OA5BMZ,UAAUuC,GA4BhB;AAAC"}
1
+ {"version":3,"file":"index.js","names":["c","_c","stylex","useContext","useLocale","RenderComponentProps","BadgeMarkContext","useRender","mergeStyles","colors","radii","spacing","typography","FORCED_COLORS","styles","inFlow","kVAEAm","$$css","large","kGNEyG","kZKoxP","kMwMTN","k1xSpc","kMv6JI","kGuDYH","kcqcaj","k63SB2","k87sOh","kLqNvP","kjj79g","kb6lSQ","kLWn49","k7Eaqz","kg3NbH","khDVqt","mark","kWkggS","kVAM5u","kaIpWk","ksu8eU","kMzoRj","kB7OPa","kfzvcC","small","kzqmXN","kt4wiu","BadgeProps","count","max","Badge","t0","$","children","t1","render","props","undefined","locale","placed","t2","numbers","Intl","NumberFormat","format","label","t3","t4","className","t5","t6","t7","t8","t9","defaultTagName","_c","props","stylex.props"],"sources":["../../../src/components/badge/index.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { useContext } from 'react';\nimport { useLocale } from 'react-aria-components';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { BadgeMarkContext } from '../../badge';\nimport { useRender } from '../../render/useRender';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, spacing, typography } from '../../tokens/design.tokens.stylex';\n\n// The badges page's badge: a mark on the corner of an icon that flags\n// something new there, either as the 6dp small badge or as the 16dp large\n// badge holding a count. Both are the error pair — the error role, with the\n// count in on error — on a full corner, and the count is label small, capped\n// at four characters with a plus, as \"999+\".\n//\n// The badge wraps what it is drawn on, usually an icon, and places the mark\n// against that element's box, which is what the page measures from. The\n// small badge fills the icon's top trailing 6dp square. The large badge's\n// bottom leading corner sits 14dp down and 12dp in from the icon's top\n// trailing corner, so it stands 2dp above the icon and grows toward the end\n// as its count lengthens, to the page's 34dp at \"999+\". Both are logical\n// insets, so the mark stays on the trailing corner under right-to-left.\n//\n// Given nothing to wrap, the badge is the mark alone, standing in the line\n// rather than over a corner. That is the form the tabs page draws after a\n// label with no icon above it.\n//\n// The mark is hidden from assistive technology. A count read on its own is a\n// number with no subject; it belongs in the name of the control it sits on,\n// where a reader meets it with what it counts — \"Notifications, 3 new\" — and\n// the stories show it there.\n//\n// Under forced colours the error fill is painted over in the mode's\n// background, which left the small badge as nothing at all. It takes a 1px\n// border there instead, which the mode keeps and paints in its text colour.\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n inFlow: {\n kVAEAm: \"x1uhb9sk\",\n $$css: true\n },\n large: {\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"xlup9mm\",\n kMwMTN: \"x1l7c2jh\",\n k1xSpc: \"x78zum5\",\n kMv6JI: \"xs1w0rn\",\n kGuDYH: \"x1n35her\",\n kcqcaj: \"xss6m8b\",\n k63SB2: \"x1su64ma\",\n k87sOh: \"x1qiirwl\",\n kLqNvP: \"xty0069\",\n kjj79g: \"xl56j7k\",\n kb6lSQ: \"xdlnduh\",\n kLWn49: \"xaomhve\",\n k7Eaqz: \"x15kz4h8\",\n kg3NbH: \"ximhkdq\",\n khDVqt: \"xuxw1ft\",\n $$css: true\n },\n mark: {\n kWkggS: \"xwi4nbo\",\n kVAM5u: \"x1w1tqly\",\n kaIpWk: \"x1dkaolv\",\n ksu8eU: \"xx61lck\",\n kMzoRj: \"x13rsnn2\",\n kB7OPa: \"x9f619\",\n kfzvcC: \"x47corl\",\n kVAEAm: \"x10l6tqk\",\n $$css: true\n },\n small: {\n kZKoxP: \"xols6we\",\n kzqmXN: \"x1v4s8kt\",\n k87sOh: \"x13vifvy\",\n kt4wiu: \"xtijo5x\",\n $$css: true\n }\n};\ntype BadgeProps = RenderComponentProps<'span'> & {\n /**\n * The number to show, which draws the page's large badge. Left out, the\n * badge is the small 6dp dot, which flags without counting. A count of 0\n * still draws, so leave the badge out when there is nothing to count.\n */\n count?: number;\n /**\n * The largest count drawn as itself. Above it the badge reads `max` and a\n * plus, which is the page's 999+ at the default.\n * @default 999\n */\n max?: number;\n};\n\n/**\n * A badge on the corner of what it wraps, usually an icon: the small dot,\n * or with `count` the large badge holding a number. The mark is hidden from\n * assistive technology, so put what it says in the name of the control it\n * sits on.\n *\n * ```tsx\n * <IconButton aria-label=\"Notifications, 3 new\">\n * <Badge count={3}>\n * <BellIcon />\n * </Badge>\n * </IconButton>\n * ```\n *\n * Given no children, the mark stands alone in the line, as a tab draws it\n * after its label.\n *\n * The call site's `className` and `style` land on the element wrapping what\n * the badge is drawn on.\n */\nfunction Badge({\n children,\n count,\n max = 999,\n render,\n ...props\n}: BadgeProps) {\n const {\n locale\n } = useLocale();\n const placed = useContext(BadgeMarkContext);\n const numbers = new Intl.NumberFormat(locale);\n const label = count === undefined ? undefined : count > max ? `${numbers.format(max)}+` : numbers.format(count);\n return useRender({\n defaultTagName: 'span',\n props: {\n ...props,\n ...mergeStyles({\n className: \"x9f619 x3nfvp2 x1n2onr6\"\n }, props),\n children: <>\n {children}\n <span aria-hidden=\"true\" {...stylex.props(styles.mark, label === undefined ? styles.small : styles.large, (children === undefined || children === null) && styles.inFlow,\n // What a destination drawing it asks of a count's mark — see\n // src/badge. The small mark stays inside its icon's box, so\n // nothing has to make room for it.\n label !== undefined && placed)}>\n {label}\n </span>\n </>\n },\n render\n });\n}\nexport type { BadgeProps };\nexport default Badge;"],"mappings":"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"}
@@ -63,7 +63,12 @@ declare function DialogBody({ ref: callerRef, ...props }: HTMLAttributes<HTMLDiv
63
63
  * over it, and React Aria's popovers and menus draw above both.
64
64
  */
65
65
  declare function DialogContent({ children, className, container, defaultOpen, isDismissable, isKeyboardDismissDisabled, isOpen, onOpenChange, ref, style, ...props }: DialogContentProps & RefAttributes<HTMLDivElement>): import("react").JSX.Element;
66
- declare function DialogFooter(props: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): import("react").JSX.Element;
66
+ /**
67
+ * The dialog's actions. Full screen they are the action bar on the window's
68
+ * bottom edge, which a toast rises clear of while the dialog is open, so a
69
+ * tap meant for one of them never lands on the toast's own action instead.
70
+ */
71
+ declare function DialogFooter({ ref: callerRef, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): import("react").JSX.Element;
67
72
  declare function DialogHeader(props: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): import("react").JSX.Element;
68
73
  /**
69
74
  * Names the dialog. Rendered through React Aria's title slot, which is what
@@ -3,12 +3,14 @@ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
3
3
  import { mergeRefs } from "../../render/ref.js";
4
4
  import { mergeStatefulStyles, mergeStyles } from "../../styles/merge.js";
5
5
  import { overlay } from "../../styles/overlay.js";
6
+ import { useHoldBottomEdge } from "../../hooks/useBottomEdge.js";
6
7
  import { useScrollable } from "../../hooks/useScrollable.js";
7
8
  import { c } from "react/compiler-runtime";
8
- import { createContext, useContext, useRef } from "react";
9
+ import { createContext, useContext, useRef, useSyncExternalStore } from "react";
9
10
  import { jsx } from "react/jsx-runtime";
10
11
  import { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } from "react-aria-components";
11
12
  //#region src/components/dialog/index.tsx
13
+ const FULL_SCREEN = "(width < 600px)";
12
14
  const styles = {
13
15
  body: {
14
16
  kB7OPa: "x9f619",
@@ -277,30 +279,42 @@ function DialogContent(t0) {
277
279
  } else t8 = $[37];
278
280
  return t8;
279
281
  }
280
- function DialogFooter(props) {
282
+ /**
283
+ * The dialog's actions. Full screen they are the action bar on the window's
284
+ * bottom edge, which a toast rises clear of while the dialog is open, so a
285
+ * tap meant for one of them never lands on the toast's own action instead.
286
+ */
287
+ function DialogFooter(t0) {
281
288
  const $ = c(6);
289
+ const { ref: callerRef, ...props } = t0;
282
290
  const isBasic = useContext(BasicContext);
283
- let t0;
284
- if ($[0] !== isBasic || $[1] !== props) {
285
- t0 = mergeStyles({
286
- 0: { className: "x6s0dn4 xt7dq6l xxcmccx x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl x8i8c5o x11d16zi x13h71tw x5ubeis xg0ps1x" },
287
- 1: { className: "x6s0dn4 x12smttz x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl xg0ps1x xt7dq6l x1ejq31n x8i8c5o x13h71tw" }
288
- }[!!isBasic << 0], props);
289
- $[0] = isBasic;
290
- $[1] = props;
291
- $[2] = t0;
292
- } else t0 = $[2];
293
- let t1;
294
- if ($[3] !== props || $[4] !== t0) {
295
- t1 = /* @__PURE__ */ jsx("div", {
291
+ const ref = useRef(null);
292
+ useHoldBottomEdge(ref, useFullScreen() && !isBasic);
293
+ const t1 = callerRef ?? void 0;
294
+ let t2;
295
+ if ($[0] !== t1) {
296
+ t2 = mergeRefs(ref, t1);
297
+ $[0] = t1;
298
+ $[1] = t2;
299
+ } else t2 = $[1];
300
+ const merged = t2;
301
+ const t3 = mergeStyles({
302
+ 0: { className: "x6s0dn4 x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x1a02dak x126z3so x13a6bvl xnvi70j x8i8c5o x1pr6p50 x13h71tw xs3zajk xg0ps1x" },
303
+ 1: { className: "x6s0dn4 x12smttz x178xt8z x9f619 x78zum5 x2lah0s x1a02dak x126z3so x13a6bvl xg0ps1x x1ejq31n x8i8c5o x13h71tw" }
304
+ }[!!isBasic << 0], props);
305
+ let t4;
306
+ if ($[2] !== merged || $[3] !== props || $[4] !== t3) {
307
+ t4 = /* @__PURE__ */ jsx("div", {
296
308
  ...props,
297
- ...t0
309
+ ref: merged,
310
+ ...t3
298
311
  });
312
+ $[2] = merged;
299
313
  $[3] = props;
300
- $[4] = t0;
301
- $[5] = t1;
302
- } else t1 = $[5];
303
- return t1;
314
+ $[4] = t3;
315
+ $[5] = t4;
316
+ } else t4 = $[5];
317
+ return t4;
304
318
  }
305
319
  function DialogHeader(props) {
306
320
  const $ = c(6);
@@ -308,8 +322,8 @@ function DialogHeader(props) {
308
322
  let t0;
309
323
  if ($[0] !== isBasic || $[1] !== props) {
310
324
  t0 = mergeStyles({
311
- 0: { className: "x6s0dn4 xt7dq6l xxcmccx x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xzfxn0k x11d16zi x13h71tw x5ubeis xg0ps1x" },
312
- 1: { className: "x6s0dn4 x1j6faob xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xg0ps1x xt7dq6l x1sy0etr xzfxn0k x13h71tw" }
325
+ 0: { className: "x6s0dn4 x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xnvi70j xzfxn0k x1pr6p50 x13h71tw xs3zajk xg0ps1x" },
326
+ 1: { className: "x6s0dn4 x1j6faob xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xg0ps1x x1sy0etr xzfxn0k x13h71tw" }
313
327
  }[!!isBasic << 0], props);
314
328
  $[0] = isBasic;
315
329
  $[1] = props;
@@ -338,8 +352,8 @@ function DialogTitle(props) {
338
352
  let t0;
339
353
  if ($[0] !== isBasic || $[1] !== props) {
340
354
  t0 = mergeStyles({
341
- 0: { className: "x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp" },
342
- 1: { className: "x9f619 x139gbkf x1ghz6dp x1fz0g89 xkb6epg x76yrz5 x1s1qhaa x1voeury" }
355
+ 0: { className: "x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp xeuugli xj0a0fe" },
356
+ 1: { className: "x9f619 x139gbkf x1ghz6dp xeuugli xj0a0fe x1fz0g89 xkb6epg x76yrz5 x1s1qhaa x1voeury" }
343
357
  }[!!isBasic << 0], props);
344
358
  $[0] = isBasic;
345
359
  $[1] = props;
@@ -358,6 +372,22 @@ function DialogTitle(props) {
358
372
  } else t1 = $[5];
359
373
  return t1;
360
374
  }
375
+ function isFullScreen() {
376
+ return window.matchMedia(FULL_SCREEN).matches;
377
+ }
378
+ function isFullScreenOnServer() {
379
+ return false;
380
+ }
381
+ function subscribeToFullScreen(listener) {
382
+ const query = window.matchMedia(FULL_SCREEN);
383
+ query.addEventListener("change", listener);
384
+ return () => {
385
+ query.removeEventListener("change", listener);
386
+ };
387
+ }
388
+ function useFullScreen() {
389
+ return useSyncExternalStore(subscribeToFullScreen, isFullScreen, isFullScreenOnServer);
390
+ }
361
391
  Dialog$1.Body = DialogBody;
362
392
  Dialog$1.Content = DialogContent;
363
393
  Dialog$1.Footer = DialogFooter;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","HTMLAttributes","ReactNode","RefAttributes","ClassNameOrFunction","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","DialogProps","RACDialogProps","StyleOrFunction","stylex","createContext","useContext","useMemo","useRef","DialogTrigger","Heading","Modal","ModalOverlay","Dialog","RACDialog","useScrollable","mergeRefs","mergeStatefulStyles","mergeStyles","overlay","colors","media","motion","radii","shadows","spacing","typography","FORCED_COLORS","scaleIn","slideInFromBottom","styles","body","kB7OPa","kMwMTN","k1xSpc","kXwgrk","kzQI83","kMv6JI","kGuDYH","k63SB2","kOIVth","kb6lSQ","kLWn49","kORKVm","kGO01o","kLKAdn","kg3NbH","$$css","centre","kGNEyG","kjj79g","kmVPX3","basic","BasicContext","Omit","children","t0","$","props","t1","DialogBody","ref","callerRef","isBasic","scrollable","undefined","t2","merged","t3","t4","modalBodyRing","t5","DialogContent","className","container","defaultOpen","isKeyboardDismissDisabled","isOpen","onOpenChange","style","isDismissable","role","scrim","0","1","Symbol","for","modalDialog","t6","t7","t8","DialogFooter","DialogHeader","DialogTitle","Body","Content","Footer","Header","Title","DialogContentProps","Element","Pick","DialogTitleProps","Dialog","_c","props","stylex.props","RACDialog"],"sources":["../../../src/components/dialog/index.tsx"],"sourcesContent":["'use client';\n\nimport type { HTMLAttributes, ReactNode, RefAttributes } from 'react';\nimport type { ClassNameOrFunction, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, DialogProps as RACDialogProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, useContext, useMemo, useRef } from 'react';\nimport { DialogTrigger, Heading, Modal, ModalOverlay, Dialog as RACDialog } from 'react-aria-components';\nimport { useScrollable } from '../../hooks/useScrollable';\nimport { mergeRefs } from '../../render/ref';\nimport { mergeStatefulStyles, mergeStyles } from '../../styles/merge';\nimport { overlay } from '../../styles/overlay';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, media, motion, radii, shadows, spacing, typography } from '../../tokens/design.tokens.stylex';\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 dialogs page's two dialogs, which are one component here for the same\n// reason Sheet's two presentations are: the page pairs them by window size\n// rather than offering a choice. Above the medium breakpoint it is the basic\n// dialog — a container on surface container high with a 28dp corner, between\n// 280 and 560dp wide, centred over the scrim, with 24dp of padding all round,\n// 16dp between the headline and the body and 24dp between the body and the\n// actions. Below it the same dialog fills the window as the page's\n// full-screen dialog: square corners, a 56dp header with the headline and a\n// divider under it, and a 56dp action bar with a divider over it.\n//\n// The pairing is for a dialog that is a task, which needs the room. An alert\n// dialog is a question with two or three answers, and the page keeps the\n// full-screen dialog for tasks, so `role=\"alertdialog\"` stays the basic dialog\n// at every width. Filled to a phone's window it read as a headline at the top\n// of the screen and its answers at the bottom, with nothing between them but\n// the chrome. The `basic` styles below are how: each restates, without the\n// breakpoint, the properties the paired styles change below it.\n//\n// The headline is headline-small on surface, the body body-medium on surface\n// variant, and the buttons are the call site's — the page draws text buttons\n// there, which is `Button`'s `text` variant.\n//\n// Two things the page draws are the call site's rather than the component's.\n// The optional icon above the headline, which the page centres the headline\n// and body with when it is there, is anything a `Dialog.Header` is given; a\n// dialog that wants it centres its own header. And the dividers a basic\n// dialog may show around a scrolling body are left out, since the page has\n// them only for that case and the body here scrolls with the header and\n// footer pinned either side of it, which is what they were marking.\n//\n// React Aria's overlay is three nested elements — the scrim, the container,\n// and the dialog inside it — so the styles split the same way, and the scrim\n// and the element carrying the dialog role are the ones every modal overlay\n// shares.\nconst scaleIn = \"xnirehn-B\";\nconst slideInFromBottom = \"x1itx4s0-B\";\nconst styles = {\n body: {\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kzQI83: \"x1iyjqo2\",\n kMv6JI: \"xpo2rfv\",\n kGuDYH: \"x193rfdd\",\n k63SB2: \"x1hews6w\",\n kOIVth: \"xxj4525\",\n kb6lSQ: \"xn43zvd\",\n kLWn49: \"xv61bfh\",\n kORKVm: \"x1odjw0f\",\n kGO01o: \"x1az23kl x18d9i69\",\n kLKAdn: \"x886u18 xexx8yu x3reb9c\",\n kg3NbH: \"xg0ps1x\",\n $$css: true\n },\n centre: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1apw6a7 xd76zvj\",\n $$css: true\n }\n};\n\n// The basic dialog at every width, for an alert dialog. Each entry is the\n// above-breakpoint value of every property its namesake in `styles` changes\n// below the breakpoint, laid over that namesake, so a property it leaves out\n// is the same in both presentations already. A value changed above the\n// breakpoint there has to change here too, which `index.test.tsx` checks by\n// comparing an alert dialog on a phone with any dialog on a desktop.\nconst basic = {\n body: {\n kLKAdn: \"x886u18 xexx8yu\",\n $$css: true\n },\n centre: {\n kmVPX3: \"x1apw6a7\",\n $$css: true\n }\n};\n\n// Whether this dialog is the basic one at every width. Content decides it from\n// the role and the parts read it, since each part carries its own share of\n// the full-screen presentation.\nconst BasicContext = createContext(false);\ntype DialogProps = Omit<DialogTriggerProps, 'children'> & {\n children?: ReactNode;\n};\n\n/**\n * A modal dialog centred over the page, and the same dialog filling the\n * window below the medium breakpoint — the dialogs page's basic and\n * full-screen dialogs, paired by window size as the page pairs them. An\n * alert dialog stays the basic one at every width. Open state is React\n * Aria's: pass `isOpen` with `onOpenChange` to control it, or\n * `defaultOpen` to let it keep its own.\n *\n * Composed rather than configured by props, as `Sheet` is, since a dialog's\n * header, body and actions all take arbitrary content — the parts are\n * `Dialog.Content`, `Dialog.Header`, `Dialog.Title`, `Dialog.Body` and\n * `Dialog.Footer`. A `Button` or `IconButton` placed directly inside\n * `Dialog` opens it, and one given `slot=\"close\"` anywhere inside the\n * content closes it; neither needs a part of its own.\n *\n * `Dialog` is the trigger's half, so a dialog nothing on the page opens — one\n * a route shows, or a menu item raises — leaves it out and passes `isOpen`\n * and `onOpenChange` to `Dialog.Content` instead. Wrapped in `Dialog` with no\n * button inside it, React Aria warns that its press responder found nothing\n * to press.\n */\nfunction Dialog({\n children,\n ...props\n}: DialogProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\nfunction DialogBody({\n ref: callerRef,\n ...props\n}: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n const ref = useRef<HTMLDivElement>(null);\n // A body its content runs past is a tab stop, so a keyboard can scroll it\n // when nothing inside it takes focus; a call site's own tabIndex still\n // wins. See useScrollable.\n const scrollable = useScrollable(ref);\n // The body measures itself through its own ref, and the call site's lands\n // on the same element.\n const merged = useMemo(() => mergeRefs(ref, callerRef ?? undefined), [callerRef]);\n return <div\n // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- a scroll container with nothing focusable inside is otherwise out of a keyboard's reach, which axe's scrollable-region-focusable reports\n tabIndex={scrollable ? 0 : undefined} {...props} ref={merged} {...mergeStyles(stylex.props(styles.body, isBasic && basic.body, overlay.modalBodyRing), props)} />;\n}\n\n/**\n * The dialog itself, and the scrim behind it. Everything the dialog shows\n * goes in here; the trigger stays outside it, since the trigger lives in the\n * page while this is portalled out to the end of the body.\n *\n * `role=\"alertdialog\"` is React Aria's, for a dialog interrupting with\n * something that has to be answered before the page carries on — a screen\n * reader announces it rather than waiting to be asked. It also keeps the\n * dialog the basic one below the medium breakpoint, centred and sized to its\n * content, where a dialog of the default role fills the window.\n *\n * A press on the scrim closes the dialog unless `isDismissable` says\n * otherwise, which is the same default `Sheet` takes and the reverse of\n * React Aria's own. Escape is a separate prop, `isKeyboardDismissDisabled`,\n * and `isDismissable` says nothing about it — so a dialog that has to be\n * answered from one of its actions, as an alert dialog usually does, turns\n * off both.\n *\n * Inside `Dialog`, the open state is the trigger's. On its own, with no\n * trigger, it is this part's: `isOpen` with `onOpenChange` controls it, and\n * a `slot=\"close\"` button, Escape and the scrim all report through\n * `onOpenChange`, as they would to `Dialog`.\n *\n * The scrim draws at `z-index: 900`, over any page content layered below\n * that, such as a sticky header, and the panel draws inside it. A\n * `Snackbar` draws at 1000, so a toast raised from inside the dialog is read\n * over it, and React Aria's popovers and menus draw above both.\n */\nfunction DialogContent({\n children,\n className,\n container,\n defaultOpen,\n isDismissable = true,\n isKeyboardDismissDisabled,\n isOpen,\n onOpenChange,\n ref,\n style,\n ...props\n}: DialogContentProps & RefAttributes<HTMLDivElement>) {\n const isBasic = props.role === 'alertdialog';\n return <BasicContext value={isBasic}>\n <ModalOverlay defaultOpen={defaultOpen} isDismissable={isDismissable} isKeyboardDismissDisabled={isKeyboardDismissDisabled} isOpen={isOpen} onOpenChange={onOpenChange}\n // oxlint-disable-next-line typescript/no-deprecated -- its replacement, UNSAFE_PortalProvider, is not exported by react-aria-components\n UNSTABLE_portalContainer={container} {...stylex.props(overlay.scrim, styles.centre, isBasic && basic.centre)}>\n <Modal\n // The panel, where the call site's class and style land, rather\n // than the dialog inside it, which takes the rest of the props.\n ref={ref} {...mergeStatefulStyles({\n 0: {\n className: \"x1n1nwrg x1u6grsq xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x1w1tqly x19pkqky x1f120ba xx61lck x1gb867b x13rsnn2 x1udv5rz x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r x27kpxv x6iovhr x1u2d2a2 xxzqys8 xb3r6kr x9xqwrn xg8iv3o x19b5e0v xsds98l\"\n },\n 1: {\n className: \"x1n1nwrg x1u6grsq x16dv9tl xvkjz1l x1w1tqly x13rsnn2 x1udv5rz x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r xb3r6kr xbhiib0 xt7dq6l x19pkqky xx61lck x27kpxv x1u2d2a2\"\n }\n }[!!isBasic << 0], {\n className,\n style\n })}>\n <RACDialog {...props} {...stylex.props(overlay.modalDialog)}>\n {children}\n </RACDialog>\n </Modal>\n </ModalOverlay>\n </BasicContext>;\n}\nfunction DialogFooter(props: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n return <div {...props} {...mergeStyles({\n 0: {\n className: \"x6s0dn4 xt7dq6l xxcmccx x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl x8i8c5o x11d16zi x13h71tw x5ubeis xg0ps1x\"\n },\n 1: {\n className: \"x6s0dn4 x12smttz x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl xg0ps1x xt7dq6l x1ejq31n x8i8c5o x13h71tw\"\n }\n }[!!isBasic << 0], props)} />;\n}\nfunction DialogHeader(props: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n return <div {...props} {...mergeStyles({\n 0: {\n className: \"x6s0dn4 xt7dq6l xxcmccx x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xzfxn0k x11d16zi x13h71tw x5ubeis xg0ps1x\"\n },\n 1: {\n className: \"x6s0dn4 x1j6faob xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xg0ps1x xt7dq6l x1sy0etr xzfxn0k x13h71tw\"\n }\n }[!!isBasic << 0], props)} />;\n}\n\n/**\n * Names the dialog. Rendered through React Aria's title slot, which is what\n * points the dialog's `aria-labelledby` at it — a dialog without one\n * announces itself unnamed.\n */\nfunction DialogTitle(props: DialogTitleProps & RefAttributes<HTMLHeadingElement>) {\n const isBasic = useContext(BasicContext);\n return <Heading slot=\"title\" {...props} {...mergeStyles({\n 0: {\n className: \"x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp\"\n },\n 1: {\n className: \"x9f619 x139gbkf x1ghz6dp x1fz0g89 xkb6epg x76yrz5 x1s1qhaa x1voeury\"\n }\n }[!!isBasic << 0], props)} />;\n}\nDialog.Body = DialogBody;\nDialog.Content = DialogContent;\nDialog.Footer = DialogFooter;\nDialog.Header = DialogHeader;\nDialog.Title = DialogTitle;\n\n// The dialog's own props, plus the scrim's open state and dismissal settings\n// and the container's styling. A call site has no reason to know there are\n// three elements: `className` and `style` reach the container, which is the\n// one worth restyling, the open state and the dismissal settings reach the\n// scrim, and everything else lands on the dialog.\n//\n// `isDismissable` is declared here rather than picked with its siblings,\n// since the picked one carries React Aria's documentation, whose default is\n// the reverse of this component's.\ntype DialogContentProps = {\n /** A function may compute the class from the container's render state. */\n className?: ClassNameOrFunction<ModalRenderProps>;\n /**\n * Where to portal the dialog and scrim. Defaults to the container of the\n * `ThemeScope` around it, which keeps the dialog on that scope's tokens, or\n * to the end of `<body>` where there is none. A subtree themed through the\n * `themeScope` class has no container of its own, so point this inside it, or\n * the dialog renders outside and keeps the page's tokens.\n */\n container?: Element;\n /**\n * Whether a press on the scrim, outside the container, closes the\n * dialog. `true` here where React Aria's own default is `false`, the\n * same default `Sheet` takes. Escape is `isKeyboardDismissDisabled`'s,\n * and this says nothing about it — an alert dialog, which has to be\n * answered from one of its actions, turns off both.\n * @default true\n */\n isDismissable?: boolean;\n /** A function may compute the style from the container's render state. */\n style?: StyleOrFunction<ModalRenderProps>;\n} & Omit<RACDialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'defaultOpen' | 'isKeyboardDismissDisabled' | 'isOpen' | 'onOpenChange'>;\ntype DialogTitleProps = HeadingProps;\nexport type { DialogContentProps, DialogProps, DialogTitleProps };\nexport { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle };\nexport default Dialog;"],"mappings":";;;;;;;;;;;AAwDA,MAAMuC,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,QAAQ;EACNC,QAAQ;EACRf,QAAQ;EACRgB,QAAQ;EACRC,QAAQ;EACRJ,OAAO;CACT;AACF;AAQA,MAAMK,QAAQ;CACZrB,MAAM;EACJc,QAAQ;EACRE,OAAO;CACT;CACAC,QAAQ;EACNG,QAAQ;EACRJ,OAAO;CACT;AACF;AAKA,MAAMM,eAAehD,cAAc,KAAK;;;;;;;;;;;;;;;;;;;;;;AA0BxC,SAAAQ,SAAA2C,IAAA;CAAA,MAAAC,IAAAjE,EAAA,CAAA;CAAA,IAAA+D;CAAA,IAAAG;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAgB,CAAA,CAAAD,UAAA,GAAAG,SAAAF;EAGFC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAC;CAAA,OAAA;EAAAH,WAAAE,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAF,YAAAE,EAAA,OAAAC,OAAA;EACLC,KAAA,oBAAC,eAAD;GAAc,GAAKD;GAAQH;EAAb,CAAA;EAAsCE,EAAA,KAAAF;EAAAE,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAApDE;AAAoD;AAE7D,SAAAC,WAAAJ,IAAA;CAAA,MAAAC,IAAAjE,EAAA,CAAA;CAAoB,MAAA,EAAAqE,KAAAC,WAAA,GAAAJ,YAAAF;CAIlB,MAAAO,UAAgBzD,WAAW+C,YAAY;CACvC,MAAAQ,MAAYrD,OAAuB,IAAI;CAIvC,MAAAwD,aAAmBjD,cAAc8C,GAAG;CAGQ,MAAAF,KAAAG,aAAAG,KAAAA;CAAsB,IAAAC;CAAA,IAAAT,EAAA,OAAAE,IAAA;EAArCO,KAAAlD,UAAU6C,KAAKF,EAAsB;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAnE,MAAAU,SAA6BD;CAGnB,MAAAE,KAAAJ,aAAA,IAAAC,KAAAA;CAAwD,MAAAI,KAAAnD,YAAYd,MAAa0B,OAAMC,MAAOgC,WAAWX,MAAKrB,MAAOZ,QAAOmD,aAAc,GAAGZ,OAAK;CAAC,IAAAa;CAAA,IAAAd,EAAA,OAAAU,UAAAV,EAAA,OAAAC,WAAAD,EAAA,OAAAW,MAAAX,EAAA,OAAAY,IAAA;EAFtJE,KAAA,oBAAA,OAAA;GAEG,UAAAH;GAA0B,GAAMV;GAAYS,KAAAA;GAAM,GAAME;EAA2F,CAAA;EAAIZ,EAAA,KAAAU;EAAAV,EAAA,KAAAC;EAAAD,EAAA,KAAAW;EAAAX,EAAA,KAAAY;EAAAZ,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAF1Jc;AAE0J;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BnK,SAAAC,cAAAhB,IAAA;CAAA,MAAAC,IAAAjE,EAAA,EAAA;CAAA,IAAA+D;CAAA,IAAAkB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAApB;CAAA,IAAAG;CAAA,IAAAkB;CAAA,IAAApB;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAuB,CAAA,CAAAD,UAAAkB,WAAAC,WAAAC,aAAAK,eAAArB,IAAAiB,2BAAAC,QAAAC,cAAAjB,KAAAkB,OAAA,GAAArB,WAAAF;EAY8BC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAgB;EAAAhB,EAAA,KAAAiB;EAAAjB,EAAA,KAAAkB;EAAAlB,EAAA,KAAAmB;EAAAnB,EAAA,KAAAoB;EAAApB,EAAA,KAAAqB;EAAArB,EAAA,KAAAC;EAAAD,EAAA,KAAAI;EAAAJ,EAAA,MAAAsB;EAAAtB,EAAA,MAAAE;CAAA,OAAA;EAAAJ,WAAAE,EAAA;EAAAgB,YAAAhB,EAAA;EAAAiB,YAAAjB,EAAA;EAAAkB,cAAAlB,EAAA;EAAAmB,4BAAAnB,EAAA;EAAAoB,SAAApB,EAAA;EAAAqB,eAAArB,EAAA;EAAAC,UAAAD,EAAA;EAAAI,MAAAJ,EAAA;EAAAsB,QAAAtB,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAPnD,MAAAuB,gBAAArB,OAAAM,KAAAA,IAAA,OAAAN;CAQA,MAAAI,UAAgBL,QAAKuB,SAAU;CAAc,IAAAf;CAAA,IAAAT,EAAA,QAAAM,SAAA;EAIFG,KAAA9D,MAAae,QAAO+D,OAAQpD,OAAMkB,QAASe,WAAWX,MAAKJ,MAAO;EAACS,EAAA,MAAAM;EAAAN,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAW;CAAA,IAAAX,EAAA,QAAAgB,aAAAhB,EAAA,QAAAM,WAAAN,EAAA,QAAAsB,OAAA;EAI5FX,KAAAnD,oBAAoB;GAAAkE,GAC7B,EAAAV,WACU,+PACb;GAACW,GACE,EAAAX,WACU,0KACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAI;GAAAU;GAAAM;EAGnB,CAAC;EAACtB,EAAA,MAAAgB;EAAAhB,EAAA,MAAAM;EAAAN,EAAA,MAAAsB;EAAAtB,EAAA,MAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,QAAA4B,OAAAC,IAAA,2BAAA,GAAA;EAC4BjB,KAAAjE,MAAae,QAAOoE,WAAY;EAAC9B,EAAA,MAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,IAAAc;CAAA,IAAAd,EAAA,QAAAF,YAAAE,EAAA,QAAAC,SAAA;EAA3Da,KAAA,oBAACoC,QAAD;GAAU,GAAKjD;GAAK,GAAMW;GACvBd;EADO,CAAA;EAEEE,EAAA,MAAAF;EAAAE,EAAA,MAAAC;EAAAD,EAAA,MAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,IAAA+B;CAAA,IAAA/B,EAAA,QAAAI,OAAAJ,EAAA,QAAAW,MAAAX,EAAA,QAAAc,IAAA;EAhBdiB,KAAA,oBAAC,OAAD;GAGG3B;GAAG,GAAMO;GAWVG,UAAAA;EAdI,CAAA;EAiBEd,EAAA,MAAAI;EAAAJ,EAAA,MAAAW;EAAAX,EAAA,MAAAc;EAAAd,EAAA,MAAA+B;CAAA,OAAAA,KAAA/B,EAAA;CAAA,IAAAgC;CAAA,IAAAhC,EAAA,QAAAiB,aAAAjB,EAAA,QAAAkB,eAAAlB,EAAA,QAAAuB,iBAAAvB,EAAA,QAAAmB,6BAAAnB,EAAA,QAAAoB,UAAApB,EAAA,QAAAqB,gBAAArB,EAAA,QAAAS,MAAAT,EAAA,QAAA+B,IAAA;EApBVC,KAAA,oBAAC,cAAD;GAA2Bd;GAA4BK;GAA0CJ;GAAmCC;GAAsBC;GAElIJ,0BAAAA;GAAS,GAAMR;GACrCsB,UAAAA;EAHW,CAAA;EAqBE/B,EAAA,MAAAiB;EAAAjB,EAAA,MAAAkB;EAAAlB,EAAA,MAAAuB;EAAAvB,EAAA,MAAAmB;EAAAnB,EAAA,MAAAoB;EAAApB,EAAA,MAAAqB;EAAArB,EAAA,MAAAS;EAAAT,EAAA,MAAA+B;EAAA/B,EAAA,MAAAgC;CAAA,OAAAA,KAAAhC,EAAA;CAAA,IAAAiC;CAAA,IAAAjC,EAAA,QAAAM,WAAAN,EAAA,QAAAgC,IAAA;EAtBZC,KAAA,oBAAC,cAAD;GAAqB3B,OAAAA;GACxB0B,UAAAA;EADgB,CAAA;EAuBHhC,EAAA,MAAAM;EAAAN,EAAA,MAAAgC;EAAAhC,EAAA,MAAAiC;CAAA,OAAAA,KAAAjC,EAAA;CAAA,OAvBViC;AAuBU;AAEnB,SAAAC,aAAAjC,OAAA;CAAA,MAAAD,IAAAjE,EAAA,CAAA;CACE,MAAAuE,UAAgBzD,WAAW+C,YAAY;CAAE,IAAAG;CAAA,IAAAC,EAAA,OAAAM,WAAAN,EAAA,OAAAC,OAAA;EACdF,KAAAtC,YAAY;GAAAiE,GAClC,EAAAV,WACU,iJACb;GAACW,GACE,EAAAX,WACU,+GACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;EAACD,EAAA,KAAAM;EAAAN,EAAA,KAAAC;EAAAD,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAC,SAAAD,EAAA,OAAAD,IAAA;EAPlBG,KAAA,oBAAA,OAAA;GAOsB,GAPbD;GAAK,GAAMF;EAOF,CAAA;EAAIC,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAPtBE;AAOsB;AAE/B,SAAAiC,aAAAlC,OAAA;CAAA,MAAAD,IAAAjE,EAAA,CAAA;CACE,MAAAuE,UAAgBzD,WAAW+C,YAAY;CAAE,IAAAG;CAAA,IAAAC,EAAA,OAAAM,WAAAN,EAAA,OAAAC,OAAA;EACdF,KAAAtC,YAAY;GAAAiE,GAClC,EAAAV,WACU,+IACb;GAACW,GACE,EAAAX,WACU,8GACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;EAACD,EAAA,KAAAM;EAAAN,EAAA,KAAAC;EAAAD,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAC,SAAAD,EAAA,OAAAD,IAAA;EAPlBG,KAAA,oBAAA,OAAA;GAOsB,GAPbD;GAAK,GAAMF;EAOF,CAAA;EAAIC,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAPtBE;AAOsB;;;;;;AAQ/B,SAAAkC,YAAAnC,OAAA;CAAA,MAAAD,IAAAjE,EAAA,CAAA;CACE,MAAAuE,UAAgBzD,WAAW+C,YAAY;CAAE,IAAAG;CAAA,IAAAC,EAAA,OAAAM,WAAAN,EAAA,OAAAC,OAAA;EACGF,KAAAtC,YAAY;GAAAiE,GACnD,EAAAV,WACU,+GACb;GAACW,GACE,EAAAX,WACU,sEACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;EAACD,EAAA,KAAAM;EAAAN,EAAA,KAAAC;EAAAD,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAC,SAAAD,EAAA,OAAAD,IAAA;EAPlBG,KAAA,oBAAC,SAAD;GAAc,MAAA;GAAO,GAAKD;GAAK,GAAMF;EAOnB,CAAA;EAAIC,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAPtBE;AAOsB;AAE/B9C,SAAOiF,OAAOlC;AACd/C,SAAOkF,UAAUvB;AACjB3D,SAAOmF,SAASL;AAChB9E,SAAOoF,SAASL;AAChB/E,SAAOqF,QAAQL"}
1
+ {"version":3,"file":"index.js","names":["c","_c","HTMLAttributes","ReactNode","RefAttributes","ClassNameOrFunction","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","DialogProps","RACDialogProps","StyleOrFunction","stylex","createContext","useContext","useMemo","useRef","useSyncExternalStore","DialogTrigger","Heading","Modal","ModalOverlay","Dialog","RACDialog","useHoldBottomEdge","useScrollable","mergeRefs","mergeStatefulStyles","mergeStyles","overlay","colors","media","motion","radii","shadows","spacing","typography","FORCED_COLORS","FULL_SCREEN","scaleIn","slideInFromBottom","styles","body","kB7OPa","kMwMTN","k1xSpc","kXwgrk","kzQI83","kMv6JI","kGuDYH","k63SB2","kOIVth","kb6lSQ","kLWn49","kORKVm","kGO01o","kLKAdn","kg3NbH","$$css","centre","kGNEyG","kjj79g","kmVPX3","basic","BasicContext","Omit","children","t0","$","props","t1","DialogBody","ref","callerRef","isBasic","scrollable","undefined","t2","merged","t3","t4","modalBodyRing","t5","DialogContent","className","container","defaultOpen","isKeyboardDismissDisabled","isOpen","onOpenChange","style","isDismissable","role","scrim","0","1","Symbol","for","modalDialog","t6","t7","t8","DialogFooter","useFullScreen","DialogHeader","DialogTitle","isFullScreen","window","matchMedia","matches","isFullScreenOnServer","subscribeToFullScreen","listener","query","addEventListener","removeEventListener","Body","Content","Footer","Header","Title","DialogContentProps","Element","Pick","DialogTitleProps","Dialog","_c","props","stylex.props","RACDialog"],"sources":["../../../src/components/dialog/index.tsx"],"sourcesContent":["'use client';\n\nimport type { HTMLAttributes, ReactNode, RefAttributes } from 'react';\nimport type { ClassNameOrFunction, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, DialogProps as RACDialogProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, useContext, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { DialogTrigger, Heading, Modal, ModalOverlay, Dialog as RACDialog } from 'react-aria-components';\nimport { useHoldBottomEdge } from '../../hooks/useBottomEdge';\nimport { useScrollable } from '../../hooks/useScrollable';\nimport { mergeRefs } from '../../render/ref';\nimport { mergeStatefulStyles, mergeStyles } from '../../styles/merge';\nimport { overlay } from '../../styles/overlay';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, media, motion, radii, shadows, spacing, typography } from '../../tokens/design.tokens.stylex';\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 window size the full-screen dialog is drawn at, which the styles read\n// as `media.belowMedium`. Spelled again for `matchMedia`, which is the one\n// thing in this file that has to know it outside a stylesheet: the footer\n// holds the window's bottom edge only there. See `useFullScreen`.\nconst FULL_SCREEN = '(width < 600px)';\n\n// The dialogs page's two dialogs, which are one component here for the same\n// reason Sheet's two presentations are: the page pairs them by window size\n// rather than offering a choice. Above the medium breakpoint it is the basic\n// dialog — a container on surface container high with a 28dp corner, between\n// 280 and 560dp wide, centred over the scrim, with 24dp of padding all round,\n// 16dp between the headline and the body and 24dp between the body and the\n// actions. Below it the same dialog fills the window as the page's\n// full-screen dialog: square corners, a 56dp header with the headline and a\n// divider under it, and a 56dp action bar with a divider over it.\n//\n// The pairing is for a dialog that is a task, which needs the room. An alert\n// dialog is a question with two or three answers, and the page keeps the\n// full-screen dialog for tasks, so `role=\"alertdialog\"` stays the basic dialog\n// at every width. Filled to a phone's window it read as a headline at the top\n// of the screen and its answers at the bottom, with nothing between them but\n// the chrome. The `basic` styles below are how: each restates, without the\n// breakpoint, the properties the paired styles change below it.\n//\n// The headline is headline-small on surface, the body body-medium on surface\n// variant, and the buttons are the call site's — the page draws text buttons\n// there, which is `Button`'s `text` variant.\n//\n// Two things the page draws are the call site's rather than the component's.\n// The optional icon above the headline, which the page centres the headline\n// and body with when it is there, is anything a `Dialog.Header` is given; a\n// dialog that wants it centres its own header. And the dividers a basic\n// dialog may show around a scrolling body are left out, since the page has\n// them only for that case and the body here scrolls with the header and\n// footer pinned either side of it, which is what they were marking.\n//\n// React Aria's overlay is three nested elements — the scrim, the container,\n// and the dialog inside it — so the styles split the same way, and the scrim\n// and the element carrying the dialog role are the ones every modal overlay\n// shares.\nconst scaleIn = \"xnirehn-B\";\nconst slideInFromBottom = \"x1itx4s0-B\";\nconst styles = {\n body: {\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kzQI83: \"x1iyjqo2\",\n kMv6JI: \"xpo2rfv\",\n kGuDYH: \"x193rfdd\",\n k63SB2: \"x1hews6w\",\n kOIVth: \"xxj4525\",\n kb6lSQ: \"xn43zvd\",\n kLWn49: \"xv61bfh\",\n kORKVm: \"x1odjw0f\",\n kGO01o: \"x1az23kl x18d9i69\",\n kLKAdn: \"x886u18 xexx8yu x3reb9c\",\n kg3NbH: \"xg0ps1x\",\n $$css: true\n },\n centre: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1apw6a7 xd76zvj\",\n $$css: true\n }\n};\n\n// The basic dialog at every width, for an alert dialog. Each entry is the\n// above-breakpoint value of every property its namesake in `styles` changes\n// below the breakpoint, laid over that namesake, so a property it leaves out\n// is the same in both presentations already. A value changed above the\n// breakpoint there has to change here too, which `index.test.tsx` checks by\n// comparing an alert dialog on a phone with any dialog on a desktop.\nconst basic = {\n body: {\n kLKAdn: \"x886u18 xexx8yu\",\n $$css: true\n },\n centre: {\n kmVPX3: \"x1apw6a7\",\n $$css: true\n }\n};\n\n// Whether this dialog is the basic one at every width. Content decides it from\n// the role and the parts read it, since each part carries its own share of\n// the full-screen presentation.\nconst BasicContext = createContext(false);\ntype DialogProps = Omit<DialogTriggerProps, 'children'> & {\n children?: ReactNode;\n};\n\n/**\n * A modal dialog centred over the page, and the same dialog filling the\n * window below the medium breakpoint — the dialogs page's basic and\n * full-screen dialogs, paired by window size as the page pairs them. An\n * alert dialog stays the basic one at every width. Open state is React\n * Aria's: pass `isOpen` with `onOpenChange` to control it, or\n * `defaultOpen` to let it keep its own.\n *\n * Composed rather than configured by props, as `Sheet` is, since a dialog's\n * header, body and actions all take arbitrary content — the parts are\n * `Dialog.Content`, `Dialog.Header`, `Dialog.Title`, `Dialog.Body` and\n * `Dialog.Footer`. A `Button` or `IconButton` placed directly inside\n * `Dialog` opens it, and one given `slot=\"close\"` anywhere inside the\n * content closes it; neither needs a part of its own.\n *\n * `Dialog` is the trigger's half, so a dialog nothing on the page opens — one\n * a route shows, or a menu item raises — leaves it out and passes `isOpen`\n * and `onOpenChange` to `Dialog.Content` instead. Wrapped in `Dialog` with no\n * button inside it, React Aria warns that its press responder found nothing\n * to press.\n */\nfunction Dialog({\n children,\n ...props\n}: DialogProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\nfunction DialogBody({\n ref: callerRef,\n ...props\n}: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n const ref = useRef<HTMLDivElement>(null);\n // A body its content runs past is a tab stop, so a keyboard can scroll it\n // when nothing inside it takes focus; a call site's own tabIndex still\n // wins. See useScrollable.\n const scrollable = useScrollable(ref);\n // The body measures itself through its own ref, and the call site's lands\n // on the same element.\n const merged = useMemo(() => mergeRefs(ref, callerRef ?? undefined), [callerRef]);\n return <div\n // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- a scroll container with nothing focusable inside is otherwise out of a keyboard's reach, which axe's scrollable-region-focusable reports\n tabIndex={scrollable ? 0 : undefined} {...props} ref={merged} {...mergeStyles(stylex.props(styles.body, isBasic && basic.body, overlay.modalBodyRing), props)} />;\n}\n\n/**\n * The dialog itself, and the scrim behind it. Everything the dialog shows\n * goes in here; the trigger stays outside it, since the trigger lives in the\n * page while this is portalled out to the end of the body.\n *\n * `role=\"alertdialog\"` is React Aria's, for a dialog interrupting with\n * something that has to be answered before the page carries on — a screen\n * reader announces it rather than waiting to be asked. It also keeps the\n * dialog the basic one below the medium breakpoint, centred and sized to its\n * content, where a dialog of the default role fills the window.\n *\n * A press on the scrim closes the dialog unless `isDismissable` says\n * otherwise, which is the same default `Sheet` takes and the reverse of\n * React Aria's own. Escape is a separate prop, `isKeyboardDismissDisabled`,\n * and `isDismissable` says nothing about it — so a dialog that has to be\n * answered from one of its actions, as an alert dialog usually does, turns\n * off both.\n *\n * Inside `Dialog`, the open state is the trigger's. On its own, with no\n * trigger, it is this part's: `isOpen` with `onOpenChange` controls it, and\n * a `slot=\"close\"` button, Escape and the scrim all report through\n * `onOpenChange`, as they would to `Dialog`.\n *\n * The scrim draws at `z-index: 900`, over any page content layered below\n * that, such as a sticky header, and the panel draws inside it. A\n * `Snackbar` draws at 1000, so a toast raised from inside the dialog is read\n * over it, and React Aria's popovers and menus draw above both.\n */\nfunction DialogContent({\n children,\n className,\n container,\n defaultOpen,\n isDismissable = true,\n isKeyboardDismissDisabled,\n isOpen,\n onOpenChange,\n ref,\n style,\n ...props\n}: DialogContentProps & RefAttributes<HTMLDivElement>) {\n const isBasic = props.role === 'alertdialog';\n return <BasicContext value={isBasic}>\n <ModalOverlay defaultOpen={defaultOpen} isDismissable={isDismissable} isKeyboardDismissDisabled={isKeyboardDismissDisabled} isOpen={isOpen} onOpenChange={onOpenChange}\n // oxlint-disable-next-line typescript/no-deprecated -- its replacement, UNSAFE_PortalProvider, is not exported by react-aria-components\n UNSTABLE_portalContainer={container} {...stylex.props(overlay.scrim, styles.centre, isBasic && basic.centre)}>\n <Modal\n // The panel, where the call site's class and style land, rather\n // than the dialog inside it, which takes the rest of the props.\n ref={ref} {...mergeStatefulStyles({\n 0: {\n className: \"x1n1nwrg x1u6grsq xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x1w1tqly x19pkqky x1f120ba xx61lck x1gb867b x13rsnn2 x1udv5rz x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r x27kpxv x6iovhr x1u2d2a2 xxzqys8 xb3r6kr x9xqwrn xg8iv3o x19b5e0v xsds98l\"\n },\n 1: {\n className: \"x1n1nwrg x1u6grsq x16dv9tl xvkjz1l x1w1tqly x13rsnn2 x1udv5rz x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r xb3r6kr xbhiib0 xt7dq6l x19pkqky xx61lck x27kpxv x1u2d2a2\"\n }\n }[!!isBasic << 0], {\n className,\n style\n })}>\n <RACDialog {...props} {...stylex.props(overlay.modalDialog)}>\n {children}\n </RACDialog>\n </Modal>\n </ModalOverlay>\n </BasicContext>;\n}\n\n/**\n * The dialog's actions. Full screen they are the action bar on the window's\n * bottom edge, which a toast rises clear of while the dialog is open, so a\n * tap meant for one of them never lands on the toast's own action instead.\n */\nfunction DialogFooter({\n ref: callerRef,\n ...props\n}: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n const ref = useRef<HTMLDivElement>(null);\n useHoldBottomEdge(ref, useFullScreen() && !isBasic);\n // The footer measures itself through its own ref, and the call site's\n // lands on the same element.\n const merged = useMemo(() => mergeRefs(ref, callerRef ?? undefined), [callerRef]);\n return <div {...props} ref={merged} {...mergeStyles({\n 0: {\n className: \"x6s0dn4 x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x1a02dak x126z3so x13a6bvl xnvi70j x8i8c5o x1pr6p50 x13h71tw xs3zajk xg0ps1x\"\n },\n 1: {\n className: \"x6s0dn4 x12smttz x178xt8z x9f619 x78zum5 x2lah0s x1a02dak x126z3so x13a6bvl xg0ps1x x1ejq31n x8i8c5o x13h71tw\"\n }\n }[!!isBasic << 0], props)} />;\n}\nfunction DialogHeader(props: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>) {\n const isBasic = useContext(BasicContext);\n return <div {...props} {...mergeStyles({\n 0: {\n className: \"x6s0dn4 x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xnvi70j xzfxn0k x1pr6p50 x13h71tw xs3zajk xg0ps1x\"\n },\n 1: {\n className: \"x6s0dn4 x1j6faob xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xg0ps1x x1sy0etr xzfxn0k x13h71tw\"\n }\n }[!!isBasic << 0], props)} />;\n}\n\n/**\n * Names the dialog. Rendered through React Aria's title slot, which is what\n * points the dialog's `aria-labelledby` at it — a dialog without one\n * announces itself unnamed.\n */\nfunction DialogTitle(props: DialogTitleProps & RefAttributes<HTMLHeadingElement>) {\n const isBasic = useContext(BasicContext);\n return <Heading slot=\"title\" {...props} {...mergeStyles({\n 0: {\n className: \"x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp xeuugli xj0a0fe\"\n },\n 1: {\n className: \"x9f619 x139gbkf x1ghz6dp xeuugli xj0a0fe x1fz0g89 xkb6epg x76yrz5 x1s1qhaa x1voeury\"\n }\n }[!!isBasic << 0], props)} />;\n}\n\n// Whether the window is at the size the full-screen dialog is drawn at, kept\n// current as it resizes. False on the server, where there is no window and\n// nothing is open.\nfunction isFullScreen() {\n return window.matchMedia(FULL_SCREEN).matches;\n}\nfunction isFullScreenOnServer() {\n return false;\n}\nfunction subscribeToFullScreen(listener: () => void) {\n const query = window.matchMedia(FULL_SCREEN);\n query.addEventListener('change', listener);\n return () => {\n query.removeEventListener('change', listener);\n };\n}\nfunction useFullScreen() {\n return useSyncExternalStore(subscribeToFullScreen, isFullScreen, isFullScreenOnServer);\n}\nDialog.Body = DialogBody;\nDialog.Content = DialogContent;\nDialog.Footer = DialogFooter;\nDialog.Header = DialogHeader;\nDialog.Title = DialogTitle;\n\n// The dialog's own props, plus the scrim's open state and dismissal settings\n// and the container's styling. A call site has no reason to know there are\n// three elements: `className` and `style` reach the container, which is the\n// one worth restyling, the open state and the dismissal settings reach the\n// scrim, and everything else lands on the dialog.\n//\n// `isDismissable` is declared here rather than picked with its siblings,\n// since the picked one carries React Aria's documentation, whose default is\n// the reverse of this component's.\ntype DialogContentProps = {\n /** A function may compute the class from the container's render state. */\n className?: ClassNameOrFunction<ModalRenderProps>;\n /**\n * Where to portal the dialog and scrim. Defaults to the container of the\n * `ThemeScope` around it, which keeps the dialog on that scope's tokens, or\n * to the end of `<body>` where there is none. A subtree themed through the\n * `themeScope` class has no container of its own, so point this inside it, or\n * the dialog renders outside and keeps the page's tokens.\n */\n container?: Element;\n /**\n * Whether a press on the scrim, outside the container, closes the\n * dialog. `true` here where React Aria's own default is `false`, the\n * same default `Sheet` takes. Escape is `isKeyboardDismissDisabled`'s,\n * and this says nothing about it — an alert dialog, which has to be\n * answered from one of its actions, turns off both.\n * @default true\n */\n isDismissable?: boolean;\n /** A function may compute the style from the container's render state. */\n style?: StyleOrFunction<ModalRenderProps>;\n} & Omit<RACDialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'defaultOpen' | 'isKeyboardDismissDisabled' | 'isOpen' | 'onOpenChange'>;\ntype DialogTitleProps = HeadingProps;\nexport type { DialogContentProps, DialogProps, DialogTitleProps };\nexport { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle };\nexport default Dialog;"],"mappings":";;;;;;;;;;;;AAyBA,MAAMuC,cAAc;AAsCpB,MAAMG,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,QAAQ;EACNC,QAAQ;EACRf,QAAQ;EACRgB,QAAQ;EACRC,QAAQ;EACRJ,OAAO;CACT;AACF;AAQA,MAAMK,QAAQ;CACZrB,MAAM;EACJc,QAAQ;EACRE,OAAO;CACT;CACAC,QAAQ;EACNG,QAAQ;EACRJ,OAAO;CACT;AACF;AAKA,MAAMM,eAAenD,cAAc,KAAK;;;;;;;;;;;;;;;;;;;;;;AA0BxC,SAAAS,SAAA6C,IAAA;CAAA,MAAAC,IAAApE,EAAA,CAAA;CAAA,IAAAkE;CAAA,IAAAG;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAgB,CAAA,CAAAD,UAAA,GAAAG,SAAAF;EAGFC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAC;CAAA,OAAA;EAAAH,WAAAE,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAF,YAAAE,EAAA,OAAAC,OAAA;EACLC,KAAA,oBAAC,eAAD;GAAc,GAAKD;GAAQH;EAAb,CAAA;EAAsCE,EAAA,KAAAF;EAAAE,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAApDE;AAAoD;AAE7D,SAAAC,WAAAJ,IAAA;CAAA,MAAAC,IAAApE,EAAA,CAAA;CAAoB,MAAA,EAAAwE,KAAAC,WAAA,GAAAJ,YAAAF;CAIlB,MAAAO,UAAgB5D,WAAWkD,YAAY;CACvC,MAAAQ,MAAYxD,OAAuB,IAAI;CAIvC,MAAA2D,aAAmBlD,cAAc+C,GAAG;CAGQ,MAAAF,KAAAG,aAAAG,KAAAA;CAAsB,IAAAC;CAAA,IAAAT,EAAA,OAAAE,IAAA;EAArCO,KAAAnD,UAAU8C,KAAKF,EAAsB;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAnE,MAAAU,SAA6BD;CAGnB,MAAAE,KAAAJ,aAAA,IAAAC,KAAAA;CAAwD,MAAAI,KAAApD,YAAYhB,MAAa6B,OAAMC,MAAOgC,WAAWX,MAAKrB,MAAOb,QAAOoD,aAAc,GAAGZ,OAAK;CAAC,IAAAa;CAAA,IAAAd,EAAA,OAAAU,UAAAV,EAAA,OAAAC,WAAAD,EAAA,OAAAW,MAAAX,EAAA,OAAAY,IAAA;EAFtJE,KAAA,oBAAA,OAAA;GAEG,UAAAH;GAA0B,GAAMV;GAAYS,KAAAA;GAAM,GAAME;EAA2F,CAAA;EAAIZ,EAAA,KAAAU;EAAAV,EAAA,KAAAC;EAAAD,EAAA,KAAAW;EAAAX,EAAA,KAAAY;EAAAZ,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAF1Jc;AAE0J;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BnK,SAAAC,cAAAhB,IAAA;CAAA,MAAAC,IAAApE,EAAA,EAAA;CAAA,IAAAkE;CAAA,IAAAkB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAApB;CAAA,IAAAG;CAAA,IAAAkB;CAAA,IAAApB;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAuB,CAAA,CAAAD,UAAAkB,WAAAC,WAAAC,aAAAK,eAAArB,IAAAiB,2BAAAC,QAAAC,cAAAjB,KAAAkB,OAAA,GAAArB,WAAAF;EAY8BC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAgB;EAAAhB,EAAA,KAAAiB;EAAAjB,EAAA,KAAAkB;EAAAlB,EAAA,KAAAmB;EAAAnB,EAAA,KAAAoB;EAAApB,EAAA,KAAAqB;EAAArB,EAAA,KAAAC;EAAAD,EAAA,KAAAI;EAAAJ,EAAA,MAAAsB;EAAAtB,EAAA,MAAAE;CAAA,OAAA;EAAAJ,WAAAE,EAAA;EAAAgB,YAAAhB,EAAA;EAAAiB,YAAAjB,EAAA;EAAAkB,cAAAlB,EAAA;EAAAmB,4BAAAnB,EAAA;EAAAoB,SAAApB,EAAA;EAAAqB,eAAArB,EAAA;EAAAC,UAAAD,EAAA;EAAAI,MAAAJ,EAAA;EAAAsB,QAAAtB,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAPnD,MAAAuB,gBAAArB,OAAAM,KAAAA,IAAA,OAAAN;CAQA,MAAAI,UAAgBL,QAAKuB,SAAU;CAAc,IAAAf;CAAA,IAAAT,EAAA,QAAAM,SAAA;EAIFG,KAAAjE,MAAaiB,QAAOgE,OAAQpD,OAAMkB,QAASe,WAAWX,MAAKJ,MAAO;EAACS,EAAA,MAAAM;EAAAN,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAW;CAAA,IAAAX,EAAA,QAAAgB,aAAAhB,EAAA,QAAAM,WAAAN,EAAA,QAAAsB,OAAA;EAI5FX,KAAApD,oBAAoB;GAAAmE,GAC7B,EAAAV,WACU,+PACb;GAACW,GACE,EAAAX,WACU,0KACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAI;GAAAU;GAAAM;EAGnB,CAAC;EAACtB,EAAA,MAAAgB;EAAAhB,EAAA,MAAAM;EAAAN,EAAA,MAAAsB;EAAAtB,EAAA,MAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,QAAA4B,OAAAC,IAAA,2BAAA,GAAA;EAC4BjB,KAAApE,MAAaiB,QAAOqE,WAAY;EAAC9B,EAAA,MAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,IAAAc;CAAA,IAAAd,EAAA,QAAAF,YAAAE,EAAA,QAAAC,SAAA;EAA3Da,KAAA,oBAAC+C,QAAD;GAAU,GAAK5D;GAAK,GAAMW;GACvBd;EADO,CAAA;EAEEE,EAAA,MAAAF;EAAAE,EAAA,MAAAC;EAAAD,EAAA,MAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,IAAA+B;CAAA,IAAA/B,EAAA,QAAAI,OAAAJ,EAAA,QAAAW,MAAAX,EAAA,QAAAc,IAAA;EAhBdiB,KAAA,oBAAC,OAAD;GAGG3B;GAAG,GAAMO;GAWVG,UAAAA;EAdI,CAAA;EAiBEd,EAAA,MAAAI;EAAAJ,EAAA,MAAAW;EAAAX,EAAA,MAAAc;EAAAd,EAAA,MAAA+B;CAAA,OAAAA,KAAA/B,EAAA;CAAA,IAAAgC;CAAA,IAAAhC,EAAA,QAAAiB,aAAAjB,EAAA,QAAAkB,eAAAlB,EAAA,QAAAuB,iBAAAvB,EAAA,QAAAmB,6BAAAnB,EAAA,QAAAoB,UAAApB,EAAA,QAAAqB,gBAAArB,EAAA,QAAAS,MAAAT,EAAA,QAAA+B,IAAA;EApBVC,KAAA,oBAAC,cAAD;GAA2Bd;GAA4BK;GAA0CJ;GAAmCC;GAAsBC;GAElIJ,0BAAAA;GAAS,GAAMR;GACrCsB,UAAAA;EAHW,CAAA;EAqBE/B,EAAA,MAAAiB;EAAAjB,EAAA,MAAAkB;EAAAlB,EAAA,MAAAuB;EAAAvB,EAAA,MAAAmB;EAAAnB,EAAA,MAAAoB;EAAApB,EAAA,MAAAqB;EAAArB,EAAA,MAAAS;EAAAT,EAAA,MAAA+B;EAAA/B,EAAA,MAAAgC;CAAA,OAAAA,KAAAhC,EAAA;CAAA,IAAAiC;CAAA,IAAAjC,EAAA,QAAAM,WAAAN,EAAA,QAAAgC,IAAA;EAtBZC,KAAA,oBAAC,cAAD;GAAqB3B,OAAAA;GACxB0B,UAAAA;EADgB,CAAA;EAuBHhC,EAAA,MAAAM;EAAAN,EAAA,MAAAgC;EAAAhC,EAAA,MAAAiC;CAAA,OAAAA,KAAAjC,EAAA;CAAA,OAvBViC;AAuBU;;;;;;AAQnB,SAAAC,aAAAnC,IAAA;CAAA,MAAAC,IAAApE,EAAA,CAAA;CAAsB,MAAA,EAAAwE,KAAAC,WAAA,GAAAJ,UAAAF;CAIpB,MAAAO,UAAgB5D,WAAWkD,YAAY;CACvC,MAAAQ,MAAYxD,OAAuB,IAAI;CACvCQ,kBAAkBgD,KAAK+B,cAA0B,KAA1B,CAAoB7B,OAAO;CAGN,MAAAJ,KAAAG,aAAAG,KAAAA;CAAsB,IAAAC;CAAA,IAAAT,EAAA,OAAAE,IAAA;EAArCO,KAAAnD,UAAU8C,KAAKF,EAAsB;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAnE,MAAAU,SAA6BD;CACW,MAAAE,KAAAnD,YAAY;EAAAkE,GAC/C,EAAAV,WACU,kJACb;EAACW,GACE,EAAAX,WACU,gHACb;CACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;CAAC,IAAAW;CAAA,IAAAZ,EAAA,OAAAU,UAAAV,EAAA,OAAAC,SAAAD,EAAA,OAAAW,IAAA;EAPlBC,KAAA,oBAAA,OAAA;GAOsB,GAPbX;GAAYS,KAAAA;GAAM,GAAMC;EAOf,CAAA;EAAIX,EAAA,KAAAU;EAAAV,EAAA,KAAAC;EAAAD,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,OAPtBY;AAOsB;AAE/B,SAAAwB,aAAAnC,OAAA;CAAA,MAAAD,IAAApE,EAAA,CAAA;CACE,MAAA0E,UAAgB5D,WAAWkD,YAAY;CAAE,IAAAG;CAAA,IAAAC,EAAA,OAAAM,WAAAN,EAAA,OAAAC,OAAA;EACdF,KAAAvC,YAAY;GAAAkE,GAClC,EAAAV,WACU,uIACb;GAACW,GACE,EAAAX,WACU,sGACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;EAACD,EAAA,KAAAM;EAAAN,EAAA,KAAAC;EAAAD,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAC,SAAAD,EAAA,OAAAD,IAAA;EAPlBG,KAAA,oBAAA,OAAA;GAOsB,GAPbD;GAAK,GAAMF;EAOF,CAAA;EAAIC,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAPtBE;AAOsB;;;;;;AAQ/B,SAAAmC,YAAApC,OAAA;CAAA,MAAAD,IAAApE,EAAA,CAAA;CACE,MAAA0E,UAAgB5D,WAAWkD,YAAY;CAAE,IAAAG;CAAA,IAAAC,EAAA,OAAAM,WAAAN,EAAA,OAAAC,OAAA;EACGF,KAAAvC,YAAY;GAAAkE,GACnD,EAAAV,WACU,+HACb;GAACW,GACE,EAAAX,WACU,sFACb;EACF,EAAE,CAAC,CAACV,WAAW,IAAIL,KAAK;EAACD,EAAA,KAAAM;EAAAN,EAAA,KAAAC;EAAAD,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAC,SAAAD,EAAA,OAAAD,IAAA;EAPlBG,KAAA,oBAAC,SAAD;GAAc,MAAA;GAAO,GAAKD;GAAK,GAAMF;EAOnB,CAAA;EAAIC,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAPtBE;AAOsB;AAM/B,SAASoC,eAAe;CACtB,OAAOC,OAAOC,WAAWtE,WAAW,CAAC,CAACuE;AACxC;AACA,SAASC,uBAAuB;CAC9B,OAAO;AACT;AACA,SAASC,sBAAsBC,UAAsB;CACnD,MAAMC,QAAQN,OAAOC,WAAWtE,WAAW;CAC3C2E,MAAMC,iBAAiB,UAAUF,QAAQ;CACzC,aAAa;EACXC,MAAME,oBAAoB,UAAUH,QAAQ;CAC9C;AACF;AACA,SAAAT,gBAAA;CAAA,OACStF,qBAAqB8F,uBAAuBL,cAAcI,oBAAoB;AAAC;AAExFxF,SAAO8F,OAAO7C;AACdjD,SAAO+F,UAAUlC;AACjB7D,SAAOgG,SAAShB;AAChBhF,SAAOiG,SAASf;AAChBlF,SAAOkG,QAAQf"}
@@ -13,10 +13,11 @@ type FormProps$1 = {
13
13
  *
14
14
  * Under `aria`, moving focus after a server answers is the call site's.
15
15
  * The errors are associated — `aria-invalid` on each control, the message
16
- * in its `aria-describedby` — but nothing moves and nothing is read out,
17
- * because no part of the form knows a round trip happened. `validationErrors`
18
- * is a prop rather than an event, so a form cannot tell a submission coming
19
- * back from a first render that was given errors to begin with.
16
+ * in its `aria-describedby` — and each is read out politely as it appears
17
+ * under its field, but nothing moves, because no part of the form knows a
18
+ * round trip happened. `validationErrors` is a prop rather than an event,
19
+ * so a form cannot tell a submission coming back from a first render that
20
+ * was given errors to begin with. The Async submit story shows the move.
20
21
  * @default 'aria'
21
22
  */
22
23
  validationBehavior?: 'aria' | 'native';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","CSSProperties","RefAttributes","FormProps","RACFormProps","stylex","Form","RACForm","FIELD_VALIDATION_BEHAVIOR","mergeStyles","className","style","validationBehavior","Omit","t0","$","T0","t1","t2","t3","t4","props","undefined","Form","_c","RACForm"],"sources":["../../../src/components/form/index.tsx"],"sourcesContent":["'use client';\n\nimport type { CSSProperties, RefAttributes } from 'react';\nimport type { FormProps as RACFormProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Form as RACForm } from 'react-aria-components';\nimport { FIELD_VALIDATION_BEHAVIOR } from '../../field/root';\nimport { mergeStyles } from '../../styles/merge';\n\n// No page of its own: a form is the fields inside it, and the text fields\n// page is what each of them draws — the error a form reports lands in the\n// field's supporting text, in the error role, under the box. The form\n// draws nothing, and lays nothing out either; a Stack inside it is what\n// spaces the fields.\n//\n// React Aria's `Form` is the element. It hands two things to the fields\n// inside it through context: `validationErrors`, keyed by each field's\n// `name`, which is how a server's answer reaches the fields without any of\n// them changing, and `validationBehavior`, which every field reads in place\n// of its own default. React Aria's own default for that is `native`; the\n// library's is `aria`, set here so a form and a field agree, with `native`\n// the opt-in.\n\ntype FormProps = {\n className?: string;\n style?: CSSProperties;\n /**\n * How the fields inside validate. `aria` marks a field invalid and shows\n * its message as soon as the field says so, and lets the form submit\n * regardless. `native` hands validation to the browser: a required or\n * malformed field blocks submission, and its message is the browser's\n * own, shown once submission is tried.\n *\n * Under `aria`, moving focus after a server answers is the call site's.\n * The errors are associated — `aria-invalid` on each control, the message\n * in its `aria-describedby` — but nothing moves and nothing is read out,\n * because no part of the form knows a round trip happened. `validationErrors`\n * is a prop rather than an event, so a form cannot tell a submission coming\n * back from a first render that was given errors to begin with.\n * @default 'aria'\n */\n validationBehavior?: 'aria' | 'native';\n} & Omit<RACFormProps, 'className' | 'style'>;\n\n/**\n * A form: the fields inside it and what they are told about validation. Pass\n * `validationErrors`, an object keyed by field `name`, to show what a server\n * sent back under each field, and `validationBehavior=\"native\"` to let the\n * browser's own constraint validation block submission. `onSubmit` is handed\n * the submit event; call `preventDefault` on it to handle the submission\n * yourself, and read the values from `new FormData(event.currentTarget)`.\n *\n * Handing `validationErrors` back from a submission is where a reader has to\n * be told something arrived: see `validationBehavior` for what the form does\n * and what it leaves to the call site.\n *\n * A form also reserves each field's message line. A field on its own draws\n * that line only once it has something to say, so an error arriving after a\n * submit or an async check makes the field taller and moves everything below\n * it down the page. Inside a form the line is there from the start, empty,\n * and nothing moves when it fills — which is the whole reason a form is where\n * a message arrives after the fact.\n *\n * The call site's `className` and `style` land on the form element, which is\n * the element a layout positions.\n */\nfunction Form({\n validationBehavior = FIELD_VALIDATION_BEHAVIOR,\n ...props\n}: FormProps & RefAttributes<HTMLFormElement>) {\n return <RACForm validationBehavior={validationBehavior} {...props} {...mergeStyles({\n className: \"x9f619\"\n }, props)} />;\n}\nexport type { FormProps };\nexport default Form;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,SAAAO,OAAAQ,IAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAgB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,IAAA;EAAc,MAAA,EAAAF,oBAAAQ,IAAA,GAAAC,UAAAP;EACZ,MAAAF,qBAAAQ,OAAAE,KAAAA,IAAAd,4BAAAY;EAGQJ,KAAAT;EAA4BK,KAAAA;EAAwBS,KAAAA;EAAWF,KAAAV,YAAY,EAAAC,WACtE,SACb,GAAGW,KAAK;EAACN,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAH,KAAAD,EAAA;EAAAE,KAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;CAAA;CAAA,IAAAK;CAAA,IAAAL,EAAA,OAAAC,MAAAD,EAAA,OAAAE,MAAAF,EAAA,OAAAG,MAAAH,EAAA,OAAAI,IAAA;EAFFC,KAAA,oBAAC,IAAD;GAA6BR,oBAAAA;GAAkB,GAAMS;GAAK,GAAMF;EAE9D,CAAA;EAAIJ,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OAFNK;AAEM"}
1
+ {"version":3,"file":"index.js","names":["c","_c","CSSProperties","RefAttributes","FormProps","RACFormProps","stylex","Form","RACForm","FIELD_VALIDATION_BEHAVIOR","mergeStyles","className","style","validationBehavior","Omit","t0","$","T0","t1","t2","t3","t4","props","undefined","Form","_c","RACForm"],"sources":["../../../src/components/form/index.tsx"],"sourcesContent":["'use client';\n\nimport type { CSSProperties, RefAttributes } from 'react';\nimport type { FormProps as RACFormProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Form as RACForm } from 'react-aria-components';\nimport { FIELD_VALIDATION_BEHAVIOR } from '../../field/root';\nimport { mergeStyles } from '../../styles/merge';\n\n// No page of its own: a form is the fields inside it, and the text fields\n// page is what each of them draws — the error a form reports lands in the\n// field's supporting text, in the error role, under the box. The form\n// draws nothing, and lays nothing out either; a Stack inside it is what\n// spaces the fields.\n//\n// React Aria's `Form` is the element. It hands two things to the fields\n// inside it through context: `validationErrors`, keyed by each field's\n// `name`, which is how a server's answer reaches the fields without any of\n// them changing, and `validationBehavior`, which every field reads in place\n// of its own default. React Aria's own default for that is `native`; the\n// library's is `aria`, set here so a form and a field agree, with `native`\n// the opt-in.\n\ntype FormProps = {\n className?: string;\n style?: CSSProperties;\n /**\n * How the fields inside validate. `aria` marks a field invalid and shows\n * its message as soon as the field says so, and lets the form submit\n * regardless. `native` hands validation to the browser: a required or\n * malformed field blocks submission, and its message is the browser's\n * own, shown once submission is tried.\n *\n * Under `aria`, moving focus after a server answers is the call site's.\n * The errors are associated — `aria-invalid` on each control, the message\n * in its `aria-describedby` — and each is read out politely as it appears\n * under its field, but nothing moves, because no part of the form knows a\n * round trip happened. `validationErrors` is a prop rather than an event,\n * so a form cannot tell a submission coming back from a first render that\n * was given errors to begin with. The Async submit story shows the move.\n * @default 'aria'\n */\n validationBehavior?: 'aria' | 'native';\n} & Omit<RACFormProps, 'className' | 'style'>;\n\n/**\n * A form: the fields inside it and what they are told about validation. Pass\n * `validationErrors`, an object keyed by field `name`, to show what a server\n * sent back under each field, and `validationBehavior=\"native\"` to let the\n * browser's own constraint validation block submission. `onSubmit` is handed\n * the submit event; call `preventDefault` on it to handle the submission\n * yourself, and read the values from `new FormData(event.currentTarget)`.\n *\n * Handing `validationErrors` back from a submission is where a reader has to\n * be told something arrived: see `validationBehavior` for what the form does\n * and what it leaves to the call site.\n *\n * A form also reserves each field's message line. A field on its own draws\n * that line only once it has something to say, so an error arriving after a\n * submit or an async check makes the field taller and moves everything below\n * it down the page. Inside a form the line is there from the start, empty,\n * and nothing moves when it fills — which is the whole reason a form is where\n * a message arrives after the fact.\n *\n * The call site's `className` and `style` land on the form element, which is\n * the element a layout positions.\n */\nfunction Form({\n validationBehavior = FIELD_VALIDATION_BEHAVIOR,\n ...props\n}: FormProps & RefAttributes<HTMLFormElement>) {\n return <RACForm validationBehavior={validationBehavior} {...props} {...mergeStyles({\n className: \"x9f619\"\n }, props)} />;\n}\nexport type { FormProps };\nexport default Form;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEA,SAAAO,OAAAQ,IAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAgB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,IAAA;EAAc,MAAA,EAAAF,oBAAAQ,IAAA,GAAAC,UAAAP;EACZ,MAAAF,qBAAAQ,OAAAE,KAAAA,IAAAd,4BAAAY;EAGQJ,KAAAT;EAA4BK,KAAAA;EAAwBS,KAAAA;EAAWF,KAAAV,YAAY,EAAAC,WACtE,SACb,GAAGW,KAAK;EAACN,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAH,KAAAD,EAAA;EAAAE,KAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;CAAA;CAAA,IAAAK;CAAA,IAAAL,EAAA,OAAAC,MAAAD,EAAA,OAAAE,MAAAF,EAAA,OAAAG,MAAAH,EAAA,OAAAI,IAAA;EAFFC,KAAA,oBAAC,IAAD;GAA6BR,oBAAAA;GAAkB,GAAMS;GAAK,GAAMF;EAE9D,CAAA;EAAIJ,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OAFNK;AAEM"}
@@ -30,13 +30,13 @@ const styles = {
30
30
  };
31
31
  const tones = {
32
32
  inherit: {
33
- kMwMTN: "x1aetzt3 x1heor9g",
34
- k1TLXF: "x1rdisx9 x1dbr5dg",
33
+ kMwMTN: "x1heor9g",
34
+ k1TLXF: "x1dbr5dg",
35
35
  $$css: true
36
36
  },
37
37
  primary: {
38
38
  kMwMTN: "x1mxwv8y",
39
- k1TLXF: "x1rdisx9 xfhk6l2",
39
+ k1TLXF: "x1q3xnwu",
40
40
  $$css: true
41
41
  }
42
42
  };
@@ -46,7 +46,7 @@ const underlines = {
46
46
  $$css: true
47
47
  },
48
48
  hover: {
49
- kMnn75: "x1sur9pj xkrqix3",
49
+ kMnn75: "xkrqix3",
50
50
  $$css: true
51
51
  },
52
52
  none: {
@@ -54,6 +54,17 @@ const underlines = {
54
54
  $$css: true
55
55
  }
56
56
  };
57
+ const hovered = {
58
+ tone: {
59
+ kMwMTN: "x1mxwv8y",
60
+ k1TLXF: "xv4vikv",
61
+ $$css: true
62
+ },
63
+ underline: {
64
+ kMnn75: "xujl8zx",
65
+ $$css: true
66
+ }
67
+ };
57
68
  /**
58
69
  * A navigational link. It renders an `<a>` and sets no type of its own, so it
59
70
  * takes the size and face of the text it sits in. Without `href`, or while
@@ -87,7 +98,7 @@ function Link$1(t0) {
87
98
  t2 = props$1;
88
99
  let t6;
89
100
  if ($[5] !== tone || $[6] !== underline) {
90
- t6 = (state) => props(styles.base, focus.ring, tones[tone], underlines[underline], state.isDisabled && styles.disabled);
101
+ t6 = (state) => props(styles.base, focus.ring, tones[tone], underlines[underline], state.isHovered && hovered.tone, state.isHovered && underline === "hover" && hovered.underline, state.isDisabled && styles.disabled);
91
102
  $[5] = tone;
92
103
  $[6] = underline;
93
104
  $[7] = t6;