@kanso-labs/kanso-ui 0.17.0 → 0.18.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 (49) hide show
  1. package/dist/components/button/index.d.ts +7 -1
  2. package/dist/components/button/index.js +43 -4
  3. package/dist/components/button/index.js.map +1 -1
  4. package/dist/components/checkbox/index.js +1 -1
  5. package/dist/components/checkbox-group/index.js +1 -1
  6. package/dist/components/dialog/index.d.ts +69 -0
  7. package/dist/components/dialog/index.js +180 -0
  8. package/dist/components/dialog/index.js.map +1 -0
  9. package/dist/components/icon-button/index.d.ts +7 -1
  10. package/dist/components/icon-button/index.js +43 -4
  11. package/dist/components/icon-button/index.js.map +1 -1
  12. package/dist/components/index.d.ts +6 -1
  13. package/dist/components/meter/index.d.ts +44 -0
  14. package/dist/components/meter/index.js +39 -0
  15. package/dist/components/meter/index.js.map +1 -0
  16. package/dist/components/number-field/index.js +1 -1
  17. package/dist/components/popover/index.d.ts +23 -2
  18. package/dist/components/popover/index.js +17 -6
  19. package/dist/components/popover/index.js.map +1 -1
  20. package/dist/components/progress-indicator/index.d.ts +66 -0
  21. package/dist/components/progress-indicator/index.js +334 -0
  22. package/dist/components/progress-indicator/index.js.map +1 -0
  23. package/dist/components/radio-group/index.js +1 -1
  24. package/dist/components/search-field/index.js +1 -1
  25. package/dist/components/sheet/index.d.ts +15 -0
  26. package/dist/components/sheet/index.js +41 -0
  27. package/dist/components/sheet/index.js.map +1 -1
  28. package/dist/components/snackbar/index.d.ts +108 -0
  29. package/dist/components/snackbar/index.js +308 -0
  30. package/dist/components/snackbar/index.js.map +1 -0
  31. package/dist/components/switch/index.js +1 -1
  32. package/dist/components/text-area/index.js +1 -1
  33. package/dist/components/text-field/index.js +1 -1
  34. package/dist/components/tooltip/index.d.ts +61 -0
  35. package/dist/components/tooltip/index.js +62 -0
  36. package/dist/components/tooltip/index.js.map +1 -0
  37. package/dist/field/index.js +5 -3
  38. package/dist/field/index.js.map +1 -1
  39. package/dist/field/root.js +10 -1
  40. package/dist/field/root.js.map +1 -1
  41. package/dist/index.d.ts +6 -1
  42. package/dist/index.js +6 -1
  43. package/dist/indicator/index.js +136 -0
  44. package/dist/indicator/index.js.map +1 -0
  45. package/dist/indicator/styles.d.ts +4 -0
  46. package/dist/indicator/styles.js +99 -0
  47. package/dist/indicator/styles.js.map +1 -0
  48. package/dist/styles.css +535 -3
  49. package/package.json +3 -3
@@ -19,6 +19,12 @@ type ButtonProps$1 = {
19
19
  * form only.
20
20
  */
21
21
  href?: string;
22
+ /**
23
+ * The name of the ring shown while the button is pending, for a screen
24
+ * reader. The label it replaces is hidden while it shows.
25
+ * @default 'Loading'
26
+ */
27
+ pendingLabel?: string;
22
28
  /** The link's `rel`, when `href` is set. */
23
29
  rel?: string;
24
30
  /**
@@ -45,7 +51,7 @@ type GlobalEventKey = Exclude<keyof DOMAttributes<HTMLElement> & keyof ButtonPro
45
51
  * forwarded to the element; React Aria alone would keep only the labelling
46
52
  * ones.
47
53
  */
48
- declare function Button$1({ children, disableRipple, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, rel, render, size, target, variant, ...props }: ButtonProps$1): import("react").JSX.Element;
54
+ declare function Button$1({ children, disableRipple, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, pendingLabel, rel, render, size, target, variant, ...props }: ButtonProps$1): import("react").JSX.Element;
49
55
  //#endregion
50
56
  export { type ButtonDOMProps, type ButtonProps$1 as ButtonProps, type ButtonSize, type ButtonState, type ButtonVariant, Button$1 as default };
51
57
  //# sourceMappingURL=index.d.ts.map
@@ -2,7 +2,8 @@ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles } from "../../styles/merge.js";
3
3
  import { useRipple } from "../../hooks/useRipple.js";
4
4
  import { ariaAttributesOf, buttonRenderer, linkRenderer } from "../../render/aria.js";
5
- import { jsxs } from "react/jsx-runtime";
5
+ import ProgressIndicator from "../progress-indicator/index.js";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Button, Link } from "react-aria-components";
7
8
  //#region src/components/button/index.tsx
8
9
  const styles = {
@@ -43,6 +44,14 @@ const styles = {
43
44
  kMwMTN: "x1xj74d8",
44
45
  $$css: true
45
46
  },
47
+ label: {
48
+ k1xSpc: "xjp7ctv",
49
+ $$css: true
50
+ },
51
+ labelPending: {
52
+ k33iCy: "xlshs6z",
53
+ $$css: true
54
+ },
46
55
  lg: {
47
56
  kZKoxP: "xnnlda6",
48
57
  kMv6JI: "x46eyla",
@@ -72,6 +81,14 @@ const styles = {
72
81
  kMwMTN: "x1xj74d8",
73
82
  $$css: true
74
83
  },
84
+ pending: {
85
+ kGNEyG: "x6s0dn4",
86
+ k1xSpc: "x78zum5",
87
+ kpwlN0: "x10a8y8t",
88
+ kjj79g: "xl56j7k",
89
+ kVAEAm: "x10l6tqk",
90
+ $$css: true
91
+ },
75
92
  text: {
76
93
  kWkggS: "x12vej0r x598nmq x14dcer4 xjbqb8w",
77
94
  kMwMTN: "x1mxwv8y",
@@ -156,7 +173,7 @@ const disabledStyles = {
156
173
  * forwarded to the element; React Aria alone would keep only the labelling
157
174
  * ones.
158
175
  */
159
- function Button$1({ children, disableRipple = false, href, isDisabled = false, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, rel, render, size = "md", target, variant = "filled", ...props$1 }) {
176
+ function Button$1({ children, disableRipple = false, href, isDisabled = false, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, pendingLabel = "Loading", rel, render, size = "md", target, variant = "filled", ...props$1 }) {
160
177
  const ripple = useRipple(!disableRipple && !isDisabled, {
161
178
  onClick,
162
179
  onContextMenu,
@@ -182,15 +199,37 @@ function Button$1({ children, disableRipple = false, href, isDisabled = false, o
182
199
  ...styleProps,
183
200
  children: [children, ripple.surface]
184
201
  });
185
- return /* @__PURE__ */ jsxs(Button, {
202
+ return /* @__PURE__ */ jsx(Button, {
186
203
  isDisabled,
187
204
  render: buttonRenderer(element, render),
188
205
  ...ripple.handlers,
189
206
  ...props$1,
190
207
  ...styleProps,
191
- children: [children, ripple.surface]
208
+ children: buttonContent(children, pendingLabel, ripple)
192
209
  });
193
210
  }
211
+ function buttonContent(children, pendingLabel, ripple) {
212
+ return (state) => /* @__PURE__ */ jsxs(Fragment, { children: [
213
+ /* @__PURE__ */ jsx("span", {
214
+ ...{
215
+ 0: { className: "xjp7ctv" },
216
+ 1: { className: "xjp7ctv xlshs6z" }
217
+ }[!!state.isPending << 0],
218
+ children
219
+ }),
220
+ state.isPending ? /* @__PURE__ */ jsx("span", {
221
+ className: "x6s0dn4 x78zum5 x10a8y8t xl56j7k x10l6tqk",
222
+ children: /* @__PURE__ */ jsx(ProgressIndicator, {
223
+ "aria-label": pendingLabel,
224
+ isIndeterminate: true,
225
+ size: "1em",
226
+ tone: "inherit",
227
+ variant: "circular"
228
+ })
229
+ }) : null,
230
+ ripple.surface
231
+ ] });
232
+ }
194
233
  //#endregion
195
234
  export { Button$1 as default };
196
235
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.tsx"],"sourcesContent":["import type { DOMAttributes, ReactNode } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, FocusableElement, ButtonProps as RACButtonProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, Link as RACLink } from 'react-aria-components';\nimport { useRipple } from '../../hooks/useRipple';\nimport { ariaAttributesOf, buttonRenderer, linkRenderer } from '../../render/aria';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, shadows, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// Each variant composites its label colour over its container at the\n// interaction state's opacity, rather than swapping in a separate\n// hover/pressed color: filled and tonal paint the 'on-color' over the\n// container, outlined and text paint the label colour over a transparent\n// one. The pairs are the buttons spec page's newer values: tonal on\n// secondary container, outlined with an outline variant border and an\n// on-surface-variant label, text on primary.\n// calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes. Inlined rather than factored into a helper:\n// @stylexjs/babel-plugin only statically recognizes expressions written\n// directly as property values, and a call to an externally-defined function\n// isn't one of them.\n//\n// Disabled is a style of its own per variant rather than a `:disabled`\n// branch inside each property: a button given `href` renders as a link,\n// which React Aria turns into a <span> while disabled, and neither matches\n// the pseudo-class. The disabled styles are applied last from the render\n// state's `isDisabled`, and StyleX replaces a property whole, so they also\n// take the hover and pressed branches with them — which is what keeps a\n// hovered disabled button from lighting up.\n//\n// Two independent axes, applied base -> variant -> size. The order is what\n// lets `text` keep its tighter inline padding at the default size while the\n// other sizes still set their own: `md` deliberately declares no\n// paddingInline, so a medium button falls through to whatever its variant\n// asked for, and every other size overrides it. That mirrors the source\n// design's own cascade, where the size classes are declared after the\n// variant ones and win on padding for exactly the same reason.\nconst styles = {\n base: {\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x3y1ksm\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kOIVth: \"x126z3so\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVAEAm: \"x1n2onr6\",\n kybGjl: \"x1hl2dhg\",\n $$css: true\n },\n disabled: {\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n filled: {\n kWkggS: \"xpky1to x16z974x xyf7a0q xnety89\",\n kGVxlE: \"xpk4wdd x1955hzl x1gnnqk1\",\n kMwMTN: \"xwjo7ld\",\n $$css: true\n },\n filledDisabled: {\n kWkggS: \"xepofeg\",\n kGVxlE: \"x1gnnqk1\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n lg: {\n kZKoxP: \"xnnlda6\",\n kMv6JI: \"x46eyla\",\n kGuDYH: \"x5ehqhr\",\n k63SB2: \"xrf6cl6\",\n kb6lSQ: \"x1g135zh\",\n kLWn49: \"x1ggk5va\",\n kg3NbH: \"xg0ps1x\",\n $$css: true\n },\n md: {\n kZKoxP: \"x1vqgdyp\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x1dg9itu x1yu1589 x1728qcm xjbqb8w\",\n kVAM5u: \"x133yhug\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xmkeg23\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n outlinedDisabled: {\n kWkggS: \"xjbqb8w\",\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n text: {\n kWkggS: \"x12vej0r x598nmq x14dcer4 xjbqb8w\",\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n },\n textDisabled: {\n kWkggS: \"xjbqb8w\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n tonal: {\n kWkggS: \"xnqsvhv xc87fxa xlizrex x15dekr4\",\n kGVxlE: \"xpk4wdd x1955hzl x1gnnqk1\",\n kMwMTN: \"x1sawysd\",\n $$css: true\n },\n tonalDisabled: {\n kWkggS: \"xepofeg\",\n kGVxlE: \"x1gnnqk1\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n xl: {\n kZKoxP: \"xjp8j0k\",\n kMv6JI: \"x1fz0g89\",\n kGuDYH: \"xkb6epg\",\n k63SB2: \"x76yrz5\",\n kOIVth: \"x1gka490\",\n kb6lSQ: \"x1s1qhaa\",\n kLWn49: \"x1voeury\",\n kg3NbH: \"x1sdxjpb\",\n $$css: true\n },\n xs: {\n kZKoxP: \"x10w6t97\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n xxl: {\n kZKoxP: \"xn866dk\",\n kMv6JI: \"x1vsmgmf\",\n kGuDYH: \"xh9c4x\",\n k63SB2: \"x1y15vu6\",\n kOIVth: \"xxj4525\",\n kb6lSQ: \"xoqu3bc\",\n kLWn49: \"x10x9d6x\",\n kg3NbH: \"x1dao9b2\",\n $$css: true\n }\n};\n\n// The outlined button's border thickens with the size, as the page's size\n// tokens have it: 1dp up to M, 2dp at L, 3dp at XL. A style per size rather\n// than a value in the size style, since a border on a filled button would\n// draw in the label colour.\nconst outlineWidths = {\n lg: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n md: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xl: {\n kMzoRj: \"xdh2fpr\",\n $$css: true\n },\n xs: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xxl: {\n kMzoRj: \"x9r2w2z\",\n $$css: true\n }\n};\nconst disabledStyles = {\n filled: styles.filledDisabled,\n outlined: styles.outlinedDisabled,\n text: styles.textDisabled,\n tonal: styles.tonalDisabled\n};\ntype ButtonDOMProps = Omit<RACButtonProps, 'children' | 'className' | 'style' | GlobalEventKey> & Pick<DOMAttributes<HTMLElement>, GlobalEventKey>;\ntype ButtonProps = {\n children?: ReactNode;\n /** A function may compute the class from the button's render state. */\n className?: ClassNameOrFunction<ButtonState>;\n /**\n * Disables the press ripple. The hover/pressed background state layer is\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * Where the button leads. Given one, the button is rendered as a link —\n * an `<a>`, announced as the link it is — with the same styles and ripple.\n * `render`, `type`, and the form and pending props apply to the button\n * form only.\n */\n href?: string;\n /** The link's `rel`, when `href` is set. */\n rel?: string;\n /**\n * Control height: `xs` 32px, `md` 40px, `lg` 56px, `xl` 96px, `xxl` 136px —\n * the buttons spec page's XS, S, M, L and XL, each with its own inline\n * padding and type role. `md` is the page's default.\n * @default 'md'\n */\n size?: ButtonSize;\n /** A function may compute the style from the button's render state. */\n style?: StyleOrFunction<ButtonState>;\n /** The link's `target`, when `href` is set. */\n target?: string;\n /** @default 'filled' */\n variant?: ButtonVariant;\n} & ButtonDOMProps;\ntype ButtonSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl';\n\n// The render state both of React Aria's elements share. A className or\n// style function written against it serves the button and the link alike;\n// `isPending` belongs to the button alone, and `isCurrent` to the link.\ntype ButtonState = Pick<ButtonRenderProps, 'isDisabled' | 'isFocused' | 'isFocusVisible' | 'isHovered' | 'isPressed'>;\ntype ButtonVariant = 'filled' | 'outlined' | 'text' | 'tonal';\n\n// React Aria types the global DOM events — pointer, mouse, touch, wheel and\n// the rest — against the element each component renders, and a handler\n// written for a <button> does not type-check against an <a>. The keys are\n// retyped against HTMLElement here so one set of props serves both forms;\n// the events React Aria defines itself (press, focus, keyboard) keep its\n// types, since it hands those its own event objects.\ntype GlobalEventKey = Exclude<keyof DOMAttributes<HTMLElement> & keyof RACButtonProps, 'onBlur' | 'onClick' | 'onFocus'>;\n\n/**\n * The design's button, at four emphasis levels and five control heights.\n * Given `href` it is a link with the same appearance. Every `aria-*` prop is\n * forwarded to the element; React Aria alone would keep only the labelling\n * ones.\n */\nfunction Button({\n children,\n disableRipple = false,\n href,\n isDisabled = false,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n rel,\n render,\n size = 'md',\n target,\n variant = 'filled',\n ...props\n}: ButtonProps) {\n // `props` (className/style, etc.) is spread separately: `className` and\n // `style` there may be functions of render state, which ripple's own\n // handler-only merge doesn't need to know about. It is also why the styles\n // below merge through mergeStatefulStyles rather than the plain\n // mergeStyles. The ripple is off while disabled: React Aria still forwards\n // pointer events to a disabled element, and a press that changes nothing\n // should not look like one.\n const ripple = useRipple<FocusableElement>(!disableRipple && !isDisabled, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n const styleProps = mergeStatefulStyles((state: ButtonState) => stylex.props(styles.base, styles[variant], styles[size], variant === 'outlined' && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]), props);\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={isDisabled} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={isDisabled} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACButton>;\n}\nexport type { ButtonDOMProps, ButtonProps, ButtonSize, ButtonState, ButtonVariant };\nexport default Button;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.tsx"],"sourcesContent":["import type { DOMAttributes, ReactNode } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, FocusableElement, ButtonProps as RACButtonProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, Link as RACLink } from 'react-aria-components';\nimport { useRipple } from '../../hooks/useRipple';\nimport { ariaAttributesOf, buttonRenderer, linkRenderer } from '../../render/aria';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, shadows, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\nimport ProgressIndicator from '../progress-indicator';\n\n// Each variant composites its label colour over its container at the\n// interaction state's opacity, rather than swapping in a separate\n// hover/pressed color: filled and tonal paint the 'on-color' over the\n// container, outlined and text paint the label colour over a transparent\n// one. The pairs are the buttons spec page's newer values: tonal on\n// secondary container, outlined with an outline variant border and an\n// on-surface-variant label, text on primary.\n// calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes. Inlined rather than factored into a helper:\n// @stylexjs/babel-plugin only statically recognizes expressions written\n// directly as property values, and a call to an externally-defined function\n// isn't one of them.\n//\n// Disabled is a style of its own per variant rather than a `:disabled`\n// branch inside each property: a button given `href` renders as a link,\n// which React Aria turns into a <span> while disabled, and neither matches\n// the pseudo-class. The disabled styles are applied last from the render\n// state's `isDisabled`, and StyleX replaces a property whole, so they also\n// take the hover and pressed branches with them — which is what keeps a\n// hovered disabled button from lighting up.\n//\n// Two independent axes, applied base -> variant -> size. The order is what\n// lets `text` keep its tighter inline padding at the default size while the\n// other sizes still set their own: `md` deliberately declares no\n// paddingInline, so a medium button falls through to whatever its variant\n// asked for, and every other size overrides it. That mirrors the source\n// design's own cascade, where the size classes are declared after the\n// variant ones and win on padding for exactly the same reason.\ntype Ripple = ReturnType<typeof useRipple<FocusableElement>>;\nconst styles = {\n base: {\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x3y1ksm\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kOIVth: \"x126z3so\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVAEAm: \"x1n2onr6\",\n kybGjl: \"x1hl2dhg\",\n $$css: true\n },\n disabled: {\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n filled: {\n kWkggS: \"xpky1to x16z974x xyf7a0q xnety89\",\n kGVxlE: \"xpk4wdd x1955hzl x1gnnqk1\",\n kMwMTN: \"xwjo7ld\",\n $$css: true\n },\n filledDisabled: {\n kWkggS: \"xepofeg\",\n kGVxlE: \"x1gnnqk1\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n label: {\n k1xSpc: \"xjp7ctv\",\n $$css: true\n },\n labelPending: {\n k33iCy: \"xlshs6z\",\n $$css: true\n },\n lg: {\n kZKoxP: \"xnnlda6\",\n kMv6JI: \"x46eyla\",\n kGuDYH: \"x5ehqhr\",\n k63SB2: \"xrf6cl6\",\n kb6lSQ: \"x1g135zh\",\n kLWn49: \"x1ggk5va\",\n kg3NbH: \"xg0ps1x\",\n $$css: true\n },\n md: {\n kZKoxP: \"x1vqgdyp\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x1dg9itu x1yu1589 x1728qcm xjbqb8w\",\n kVAM5u: \"x133yhug\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xmkeg23\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n outlinedDisabled: {\n kWkggS: \"xjbqb8w\",\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n pending: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kpwlN0: \"x10a8y8t\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n $$css: true\n },\n text: {\n kWkggS: \"x12vej0r x598nmq x14dcer4 xjbqb8w\",\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n },\n textDisabled: {\n kWkggS: \"xjbqb8w\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n tonal: {\n kWkggS: \"xnqsvhv xc87fxa xlizrex x15dekr4\",\n kGVxlE: \"xpk4wdd x1955hzl x1gnnqk1\",\n kMwMTN: \"x1sawysd\",\n $$css: true\n },\n tonalDisabled: {\n kWkggS: \"xepofeg\",\n kGVxlE: \"x1gnnqk1\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n xl: {\n kZKoxP: \"xjp8j0k\",\n kMv6JI: \"x1fz0g89\",\n kGuDYH: \"xkb6epg\",\n k63SB2: \"x76yrz5\",\n kOIVth: \"x1gka490\",\n kb6lSQ: \"x1s1qhaa\",\n kLWn49: \"x1voeury\",\n kg3NbH: \"x1sdxjpb\",\n $$css: true\n },\n xs: {\n kZKoxP: \"x10w6t97\",\n kg3NbH: \"x790zyz\",\n $$css: true\n },\n xxl: {\n kZKoxP: \"xn866dk\",\n kMv6JI: \"x1vsmgmf\",\n kGuDYH: \"xh9c4x\",\n k63SB2: \"x1y15vu6\",\n kOIVth: \"xxj4525\",\n kb6lSQ: \"xoqu3bc\",\n kLWn49: \"x10x9d6x\",\n kg3NbH: \"x1dao9b2\",\n $$css: true\n }\n};\n\n// The outlined button's border thickens with the size, as the page's size\n// tokens have it: 1dp up to M, 2dp at L, 3dp at XL. A style per size rather\n// than a value in the size style, since a border on a filled button would\n// draw in the label colour.\nconst outlineWidths = {\n lg: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n md: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xl: {\n kMzoRj: \"xdh2fpr\",\n $$css: true\n },\n xs: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xxl: {\n kMzoRj: \"x9r2w2z\",\n $$css: true\n }\n};\nconst disabledStyles = {\n filled: styles.filledDisabled,\n outlined: styles.outlinedDisabled,\n text: styles.textDisabled,\n tonal: styles.tonalDisabled\n};\ntype ButtonDOMProps = Omit<RACButtonProps, 'children' | 'className' | 'style' | GlobalEventKey> & Pick<DOMAttributes<HTMLElement>, GlobalEventKey>;\ntype ButtonProps = {\n children?: ReactNode;\n /** A function may compute the class from the button's render state. */\n className?: ClassNameOrFunction<ButtonState>;\n /**\n * Disables the press ripple. The hover/pressed background state layer is\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * Where the button leads. Given one, the button is rendered as a link —\n * an `<a>`, announced as the link it is — with the same styles and ripple.\n * `render`, `type`, and the form and pending props apply to the button\n * form only.\n */\n href?: string;\n /**\n * The name of the ring shown while the button is pending, for a screen\n * reader. The label it replaces is hidden while it shows.\n * @default 'Loading'\n */\n pendingLabel?: string;\n /** The link's `rel`, when `href` is set. */\n rel?: string;\n /**\n * Control height: `xs` 32px, `md` 40px, `lg` 56px, `xl` 96px, `xxl` 136px —\n * the buttons spec page's XS, S, M, L and XL, each with its own inline\n * padding and type role. `md` is the page's default.\n * @default 'md'\n */\n size?: ButtonSize;\n /** A function may compute the style from the button's render state. */\n style?: StyleOrFunction<ButtonState>;\n /** The link's `target`, when `href` is set. */\n target?: string;\n /** @default 'filled' */\n variant?: ButtonVariant;\n} & ButtonDOMProps;\ntype ButtonSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl';\n\n// The render state both of React Aria's elements share. A className or\n// style function written against it serves the button and the link alike;\n// `isPending` belongs to the button alone, and `isCurrent` to the link, so\n// neither is here: a `className` written against this state serves both\n// elements. What the button draws while pending is decided in\n// `buttonContent`, which sees React Aria's own state rather than this one.\ntype ButtonState = Pick<ButtonRenderProps, 'isDisabled' | 'isFocused' | 'isFocusVisible' | 'isHovered' | 'isPressed'>;\ntype ButtonVariant = 'filled' | 'outlined' | 'text' | 'tonal';\n\n// React Aria types the global DOM events — pointer, mouse, touch, wheel and\n// the rest — against the element each component renders, and a handler\n// written for a <button> does not type-check against an <a>. The keys are\n// retyped against HTMLElement here so one set of props serves both forms;\n// the events React Aria defines itself (press, focus, keyboard) keep its\n// types, since it hands those its own event objects.\ntype GlobalEventKey = Exclude<keyof DOMAttributes<HTMLElement> & keyof RACButtonProps, 'onBlur' | 'onClick' | 'onFocus'>;\n\n/**\n * The design's button, at four emphasis levels and five control heights.\n * Given `href` it is a link with the same appearance. Every `aria-*` prop is\n * forwarded to the element; React Aria alone would keep only the labelling\n * ones.\n */\nfunction Button({\n children,\n disableRipple = false,\n href,\n isDisabled = false,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n pendingLabel = 'Loading',\n rel,\n render,\n size = 'md',\n target,\n variant = 'filled',\n ...props\n}: ButtonProps) {\n // `props` (className/style, etc.) is spread separately: `className` and\n // `style` there may be functions of render state, which ripple's own\n // handler-only merge doesn't need to know about. It is also why the styles\n // below merge through mergeStatefulStyles rather than the plain\n // mergeStyles. The ripple is off while disabled: React Aria still forwards\n // pointer events to a disabled element, and a press that changes nothing\n // should not look like one.\n const ripple = useRipple<FocusableElement>(!disableRipple && !isDisabled, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n const styleProps = mergeStatefulStyles((state: ButtonState) => stylex.props(styles.base, styles[variant], styles[size], variant === 'outlined' && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]), props);\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={isDisabled} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={isDisabled} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {buttonContent(children, pendingLabel, ripple)}\n </RACButton>;\n}\n// What the button draws: its label, hidden while the button is pending, with\n// the ring over it. The ring takes the button's own content colour rather\n// than the progress page's primary, which on a filled button is the fill\n// itself and so invisible. The label stays in the flow so the button keeps its\n// width, which is what stops a form jumping the moment it is submitted.\n// React Aria wants the progress bar in the accessibility tree as soon as the\n// button goes pending, so it is rendered from the render state rather than\n// after a delay.\n//\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\n// memoises the result on its inputs.\nfunction buttonContent(children: ReactNode, pendingLabel: string, ripple: Ripple) {\n return (state: ButtonRenderProps) => <>\n <span {...{\n 0: {\n className: \"xjp7ctv\"\n },\n 1: {\n className: \"xjp7ctv xlshs6z\"\n }\n }[!!state.isPending << 0]}>\n {children}\n </span>\n {state.isPending ? <span className=\"x6s0dn4 x78zum5 x10a8y8t xl56j7k x10l6tqk\">\n <ProgressIndicator aria-label={pendingLabel} isIndeterminate size=\"1em\" tone=\"inherit\" variant=\"circular\" />\n </span> : null}\n {ripple.surface}\n </>;\n}\nexport type { ButtonDOMProps, ButtonProps, ButtonSize, ButtonState, ButtonVariant };\nexport default Button;"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles } from "../../styles/merge.js";
3
3
  import { useRipple } from "../../hooks/useRipple.js";
4
- import { FieldMessage } from "../../field/index.js";
5
4
  import { invalidFrom, useFieldValidationBehavior } from "../../field/root.js";
5
+ import { FieldMessage } from "../../field/index.js";
6
6
  import { CheckGlyph, IndeterminateGlyph } from "../../glyphs/index.js";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { c } from "react/compiler-runtime";
@@ -1,6 +1,6 @@
1
1
  import { mergeStatefulStyles } from "../../styles/merge.js";
2
- import { FieldLabel, FieldMessage } from "../../field/index.js";
3
2
  import { invalidFrom, useFieldValidationBehavior } from "../../field/root.js";
3
+ import { FieldLabel, FieldMessage } from "../../field/index.js";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { c } from "react/compiler-runtime";
6
6
  import { CheckboxGroup } from "react-aria-components";
@@ -0,0 +1,69 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ import { ClassNameOrFunction, DialogProps, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, StyleOrFunction } from "react-aria-components";
3
+ //#region src/components/dialog/index.d.ts
4
+ type DialogProps$1 = Omit<DialogTriggerProps, 'children'> & {
5
+ children?: ReactNode;
6
+ };
7
+ /**
8
+ * A modal dialog centred over the page, and the same dialog filling the
9
+ * window below the medium breakpoint — the dialogs page's basic and
10
+ * full-screen dialogs, paired by window size as the page pairs them. Open
11
+ * state is React Aria's: pass `isOpen` with `onOpenChange` to control it, or
12
+ * `defaultOpen` to let it keep its own.
13
+ *
14
+ * Composed rather than configured by props, as `Sheet` is, since a dialog's
15
+ * header, body and actions all take arbitrary content — the parts are
16
+ * `Dialog.Content`, `Dialog.Header`, `Dialog.Title`, `Dialog.Body` and
17
+ * `Dialog.Footer`. A `Button` or `IconButton` placed directly inside
18
+ * `Dialog` opens it, and one given `slot="close"` anywhere inside the
19
+ * content closes it; neither needs a part of its own.
20
+ */
21
+ declare function Dialog$1({ children, ...props }: DialogProps$1): import("react").JSX.Element;
22
+ declare namespace Dialog$1 {
23
+ var Body: typeof DialogBody;
24
+ var Content: typeof DialogContent;
25
+ var Footer: typeof DialogFooter;
26
+ var Header: typeof DialogHeader;
27
+ var Title: typeof DialogTitle;
28
+ }
29
+ declare function DialogBody(props: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
30
+ /**
31
+ * The dialog itself, and the scrim behind it. Everything the dialog shows
32
+ * goes in here; the trigger stays outside it, since the trigger lives in the
33
+ * page while this is portalled out to the end of the body.
34
+ *
35
+ * `role="alertdialog"` is React Aria's, for a dialog interrupting with
36
+ * something that has to be answered before the page carries on — a screen
37
+ * reader announces it rather than waiting to be asked.
38
+ *
39
+ * A press on the scrim closes the dialog unless `isDismissable` says
40
+ * otherwise, which is the same default `Sheet` takes and the reverse of
41
+ * React Aria's own.
42
+ */
43
+ declare function DialogContent({ children, className, container, isDismissable, isKeyboardDismissDisabled, style, ...props }: DialogContentProps): import("react").JSX.Element;
44
+ declare function DialogFooter(props: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
45
+ declare function DialogHeader(props: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
46
+ /**
47
+ * Names the dialog. Rendered through React Aria's title slot, which is what
48
+ * points the dialog's `aria-labelledby` at it — a dialog without one
49
+ * announces itself unnamed.
50
+ */
51
+ declare function DialogTitle(props: DialogTitleProps): import("react").JSX.Element;
52
+ type DialogContentProps = Omit<DialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'isDismissable' | 'isKeyboardDismissDisabled'> & {
53
+ /** A function may compute the class from the container's render state. */
54
+ className?: ClassNameOrFunction<ModalRenderProps>;
55
+ /**
56
+ * Where to portal the dialog and scrim. Defaults to the end of `<body>`,
57
+ * which is right for an app that sets its StyleX theme on `:root`. An app
58
+ * that scopes the theme to a subtree has to point this at an element
59
+ * inside it, or the dialog renders outside the theme and falls back to
60
+ * the tokens' `prefers-color-scheme` default.
61
+ */
62
+ container?: Element;
63
+ /** A function may compute the style from the container's render state. */
64
+ style?: StyleOrFunction<ModalRenderProps>;
65
+ };
66
+ type DialogTitleProps = HeadingProps;
67
+ //#endregion
68
+ export { type DialogContentProps, type DialogProps$1 as DialogProps, type DialogTitleProps, Dialog$1 as default };
69
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,180 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { mergeStatefulStyles, mergeStyles } from "../../styles/merge.js";
3
+ import { overlay } from "../../styles/overlay.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { c } from "react/compiler-runtime";
6
+ import { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } from "react-aria-components";
7
+ //#region src/components/dialog/index.tsx
8
+ const styles = { centre: {
9
+ kGNEyG: "x6s0dn4",
10
+ k1xSpc: "x78zum5",
11
+ kjj79g: "xl56j7k",
12
+ kmVPX3: "x1apw6a7 xd76zvj",
13
+ $$css: true
14
+ } };
15
+ /**
16
+ * A modal dialog centred over the page, and the same dialog filling the
17
+ * window below the medium breakpoint — the dialogs page's basic and
18
+ * full-screen dialogs, paired by window size as the page pairs them. Open
19
+ * state is React Aria's: pass `isOpen` with `onOpenChange` to control it, or
20
+ * `defaultOpen` to let it keep its own.
21
+ *
22
+ * Composed rather than configured by props, as `Sheet` is, since a dialog's
23
+ * header, body and actions all take arbitrary content — the parts are
24
+ * `Dialog.Content`, `Dialog.Header`, `Dialog.Title`, `Dialog.Body` and
25
+ * `Dialog.Footer`. A `Button` or `IconButton` placed directly inside
26
+ * `Dialog` opens it, and one given `slot="close"` anywhere inside the
27
+ * content closes it; neither needs a part of its own.
28
+ */
29
+ function Dialog$1(t0) {
30
+ const $ = c(6);
31
+ let children;
32
+ let props;
33
+ if ($[0] !== t0) {
34
+ ({children, ...props} = t0);
35
+ $[0] = t0;
36
+ $[1] = children;
37
+ $[2] = props;
38
+ } else {
39
+ children = $[1];
40
+ props = $[2];
41
+ }
42
+ let t1;
43
+ if ($[3] !== children || $[4] !== props) {
44
+ t1 = /* @__PURE__ */ jsx(DialogTrigger, {
45
+ ...props,
46
+ children
47
+ });
48
+ $[3] = children;
49
+ $[4] = props;
50
+ $[5] = t1;
51
+ } else t1 = $[5];
52
+ return t1;
53
+ }
54
+ function DialogBody(props) {
55
+ const $ = c(5);
56
+ let t0;
57
+ if ($[0] !== props) {
58
+ t0 = mergeStyles({ className: "x9f619 x1w5n3ug x78zum5 xdt5ytf x1iyjqo2 xpo2rfv x193rfdd x1hews6w xxj4525 xn43zvd xv61bfh x1odjw0f xg0ps1x" }, props);
59
+ $[0] = props;
60
+ $[1] = t0;
61
+ } else t0 = $[1];
62
+ let t1;
63
+ if ($[2] !== props || $[3] !== t0) {
64
+ t1 = /* @__PURE__ */ jsx("div", {
65
+ ...props,
66
+ ...t0
67
+ });
68
+ $[2] = props;
69
+ $[3] = t0;
70
+ $[4] = t1;
71
+ } else t1 = $[4];
72
+ return t1;
73
+ }
74
+ /**
75
+ * The dialog itself, and the scrim behind it. Everything the dialog shows
76
+ * goes in here; the trigger stays outside it, since the trigger lives in the
77
+ * page while this is portalled out to the end of the body.
78
+ *
79
+ * `role="alertdialog"` is React Aria's, for a dialog interrupting with
80
+ * something that has to be answered before the page carries on — a screen
81
+ * reader announces it rather than waiting to be asked.
82
+ *
83
+ * A press on the scrim closes the dialog unless `isDismissable` says
84
+ * otherwise, which is the same default `Sheet` takes and the reverse of
85
+ * React Aria's own.
86
+ */
87
+ function DialogContent({ children, className, container, isDismissable = true, isKeyboardDismissDisabled, style, ...props$1 }) {
88
+ return /* @__PURE__ */ jsx(ModalOverlay, {
89
+ isDismissable,
90
+ isKeyboardDismissDisabled,
91
+ UNSTABLE_portalContainer: container,
92
+ ...props(overlay.scrim, styles.centre),
93
+ children: /* @__PURE__ */ jsx(Modal, {
94
+ ...mergeStatefulStyles({ className: "x1n1nwrg xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x19pkqky x1f120ba x19efjv6 x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r x27kpxv x6iovhr x1u2d2a2 xxzqys8 xb3r6kr" }, {
95
+ className,
96
+ style
97
+ }),
98
+ children: /* @__PURE__ */ jsx(Dialog, {
99
+ ...props$1,
100
+ ...props(overlay.modalDialog),
101
+ children
102
+ })
103
+ })
104
+ });
105
+ }
106
+ function DialogFooter(props) {
107
+ const $ = c(5);
108
+ let t0;
109
+ if ($[0] !== props) {
110
+ t0 = mergeStyles({ className: "x6s0dn4 xt7dq6l xxcmccx x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl x8i8c5o x11d16zi x13h71tw x5ubeis xg0ps1x" }, props);
111
+ $[0] = props;
112
+ $[1] = t0;
113
+ } else t0 = $[1];
114
+ let t1;
115
+ if ($[2] !== props || $[3] !== t0) {
116
+ t1 = /* @__PURE__ */ jsx("div", {
117
+ ...props,
118
+ ...t0
119
+ });
120
+ $[2] = props;
121
+ $[3] = t0;
122
+ $[4] = t1;
123
+ } else t1 = $[4];
124
+ return t1;
125
+ }
126
+ function DialogHeader(props) {
127
+ const $ = c(5);
128
+ let t0;
129
+ if ($[0] !== props) {
130
+ t0 = mergeStyles({ className: "x6s0dn4 xt7dq6l xxcmccx x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xzfxn0k x11d16zi x13h71tw x5ubeis xg0ps1x" }, props);
131
+ $[0] = props;
132
+ $[1] = t0;
133
+ } else t0 = $[1];
134
+ let t1;
135
+ if ($[2] !== props || $[3] !== t0) {
136
+ t1 = /* @__PURE__ */ jsx("div", {
137
+ ...props,
138
+ ...t0
139
+ });
140
+ $[2] = props;
141
+ $[3] = t0;
142
+ $[4] = t1;
143
+ } else t1 = $[4];
144
+ return t1;
145
+ }
146
+ /**
147
+ * Names the dialog. Rendered through React Aria's title slot, which is what
148
+ * points the dialog's `aria-labelledby` at it — a dialog without one
149
+ * announces itself unnamed.
150
+ */
151
+ function DialogTitle(props) {
152
+ const $ = c(5);
153
+ let t0;
154
+ if ($[0] !== props) {
155
+ t0 = mergeStyles({ className: "x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp" }, props);
156
+ $[0] = props;
157
+ $[1] = t0;
158
+ } else t0 = $[1];
159
+ let t1;
160
+ if ($[2] !== props || $[3] !== t0) {
161
+ t1 = /* @__PURE__ */ jsx(Heading, {
162
+ slot: "title",
163
+ ...props,
164
+ ...t0
165
+ });
166
+ $[2] = props;
167
+ $[3] = t0;
168
+ $[4] = t1;
169
+ } else t1 = $[4];
170
+ return t1;
171
+ }
172
+ Dialog$1.Body = DialogBody;
173
+ Dialog$1.Content = DialogContent;
174
+ Dialog$1.Footer = DialogFooter;
175
+ Dialog$1.Header = DialogHeader;
176
+ Dialog$1.Title = DialogTitle;
177
+ //#endregion
178
+ export { Dialog$1 as default };
179
+
180
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["children"],"sources":["../../../src/components/dialog/index.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport type { ClassNameOrFunction, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, DialogProps as RACDialogProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { DialogTrigger, Heading, Modal, ModalOverlay, Dialog as RACDialog } from 'react-aria-components';\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// 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 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 centre: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1apw6a7 xd76zvj\",\n $$css: true\n }\n};\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. Open\n * state is React 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 */\nfunction Dialog({\n children,\n ...props\n}: DialogProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\nfunction DialogBody(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x9f619 x1w5n3ug x78zum5 xdt5ytf x1iyjqo2 xpo2rfv x193rfdd x1hews6w xxj4525 xn43zvd xv61bfh x1odjw0f xg0ps1x\"\n }, 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.\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.\n */\nfunction DialogContent({\n children,\n className,\n container,\n isDismissable = true,\n isKeyboardDismissDisabled,\n style,\n ...props\n}: DialogContentProps) {\n return <ModalOverlay isDismissable={isDismissable} isKeyboardDismissDisabled={isKeyboardDismissDisabled}\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)}>\n <Modal {...mergeStatefulStyles({\n className: \"x1n1nwrg xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x19pkqky x1f120ba x19efjv6 x9f619 x139gbkf x78zum5 xdt5ytf xh8yej3 xmz0i5r x27kpxv x6iovhr x1u2d2a2 xxzqys8 xb3r6kr\"\n }, {\n className,\n style\n })}>\n <RACDialog {...props} {...stylex.props(overlay.modalDialog)}>\n {children}\n </RACDialog>\n </Modal>\n </ModalOverlay>;\n}\nfunction DialogFooter(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x6s0dn4 xt7dq6l xxcmccx x12smttz x1ejq31n x1vv4zg8 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x13a6bvl x8i8c5o x11d16zi x13h71tw x5ubeis xg0ps1x\"\n }, props)} />;\n}\nfunction DialogHeader(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x6s0dn4 xt7dq6l xxcmccx x1j6faob x1sy0etr xf6te7g xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib xzfxn0k x11d16zi x13h71tw x5ubeis xg0ps1x\"\n }, 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) {\n return <Heading slot=\"title\" {...props} {...mergeStyles({\n className: \"x9f619 x139gbkf x1fz0g89 xl849ld xkb6epg xcji80f x76yrz5 x6ksu6j x1s1qhaa x1khanjg x1voeury xrr2tf9 x1ghz6dp\"\n }, 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 dismissal settings and the\n// container's styling. A call site has no reason to know there are three\n// elements: `className` and `style` reach the container, which is the one\n// worth restyling, and everything else lands on the dialog.\ntype DialogContentProps = Omit<RACDialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'isDismissable' | 'isKeyboardDismissDisabled'> & {\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 end of `<body>`,\n * which is right for an app that sets its StyleX theme on `:root`. An app\n * that scopes the theme to a subtree has to point this at an element\n * inside it, or the dialog renders outside the theme and falls back to\n * the tokens' `prefers-color-scheme` default.\n */\n container?: Element;\n /** A function may compute the style from the container's render state. */\n style?: StyleOrFunction<ModalRenderProps>;\n};\ntype DialogTitleProps = HeadingProps;\nexport type { DialogContentProps, DialogProps, DialogTitleProps };\nexport default Dialog;"],"mappings":"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"}
@@ -25,6 +25,12 @@ type IconButtonProps = {
25
25
  * form only.
26
26
  */
27
27
  href?: string;
28
+ /**
29
+ * The name of the ring shown while the button is pending, for a screen
30
+ * reader. The label it replaces is hidden while it shows.
31
+ * @default 'Loading'
32
+ */
33
+ pendingLabel?: string;
28
34
  /** The link's `rel`, when `href` is set. */
29
35
  rel?: string;
30
36
  /**
@@ -51,7 +57,7 @@ type IconButtonProps = {
51
57
  * link with the same appearance. Every `aria-*` prop is forwarded to the
52
58
  * element; React Aria alone would keep only the labelling ones.
53
59
  */
54
- declare function IconButton({ children, disableRipple, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, rel, render, size, target, variant, ...props }: IconButtonProps): import("react").JSX.Element;
60
+ declare function IconButton({ children, disableRipple, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, pendingLabel, rel, render, size, target, variant, ...props }: IconButtonProps): import("react").JSX.Element;
55
61
  //#endregion
56
62
  export { type IconButtonProps, IconButton as default };
57
63
  //# sourceMappingURL=index.d.ts.map
@@ -2,7 +2,8 @@ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles } from "../../styles/merge.js";
3
3
  import { useRipple } from "../../hooks/useRipple.js";
4
4
  import { ariaAttributesOf, buttonRenderer, linkRenderer } from "../../render/aria.js";
5
- import { jsxs } from "react/jsx-runtime";
5
+ import ProgressIndicator from "../progress-indicator/index.js";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Button, ButtonContext, Link, useSlottedContext } from "react-aria-components";
7
8
  //#region src/components/icon-button/index.tsx
8
9
  const styles = {
@@ -42,6 +43,14 @@ const styles = {
42
43
  kMwMTN: "x1xj74d8",
43
44
  $$css: true
44
45
  },
46
+ label: {
47
+ k1xSpc: "xjp7ctv",
48
+ $$css: true
49
+ },
50
+ labelPending: {
51
+ k33iCy: "xlshs6z",
52
+ $$css: true
53
+ },
45
54
  lg: {
46
55
  kZKoxP: "xnnlda6",
47
56
  kaIpWk: "xtt5grq x3y1ksm",
@@ -56,6 +65,14 @@ const styles = {
56
65
  kzqmXN: "x100vrsf",
57
66
  $$css: true
58
67
  },
68
+ pending: {
69
+ kGNEyG: "x6s0dn4",
70
+ k1xSpc: "x78zum5",
71
+ kpwlN0: "x10a8y8t",
72
+ kjj79g: "xl56j7k",
73
+ kVAEAm: "x10l6tqk",
74
+ $$css: true
75
+ },
59
76
  standard: {
60
77
  kWkggS: "x83qkoq x1p2om7n xjbqb8w",
61
78
  kMwMTN: "x1w5n3ug",
@@ -103,12 +120,34 @@ const disabledStyles = {
103
120
  standard: styles.standardDisabled,
104
121
  tonal: styles.tonalDisabled
105
122
  };
123
+ function buttonContent(children, pendingLabel, ripple) {
124
+ return (state) => /* @__PURE__ */ jsxs(Fragment, { children: [
125
+ /* @__PURE__ */ jsx("span", {
126
+ ...{
127
+ 0: { className: "xjp7ctv" },
128
+ 1: { className: "xjp7ctv xlshs6z" }
129
+ }[!!state.isPending << 0],
130
+ children
131
+ }),
132
+ state.isPending ? /* @__PURE__ */ jsx("span", {
133
+ className: "x6s0dn4 x78zum5 x10a8y8t xl56j7k x10l6tqk",
134
+ children: /* @__PURE__ */ jsx(ProgressIndicator, {
135
+ "aria-label": pendingLabel,
136
+ isIndeterminate: true,
137
+ size: "1em",
138
+ tone: "inherit",
139
+ variant: "circular"
140
+ })
141
+ }) : null,
142
+ ripple.surface
143
+ ] });
144
+ }
106
145
  /**
107
146
  * A button that is an icon, at five control heights. Given `href` it is a
108
147
  * link with the same appearance. Every `aria-*` prop is forwarded to the
109
148
  * element; React Aria alone would keep only the labelling ones.
110
149
  */
111
- function IconButton({ children, disableRipple = false, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, rel, render, size = "md", target, variant = "standard", ...props$1 }) {
150
+ function IconButton({ children, disableRipple = false, href, isDisabled, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, pendingLabel = "Loading", rel, render, size = "md", target, variant = "standard", ...props$1 }) {
112
151
  const context = useSlottedContext(ButtonContext, props$1.slot);
113
152
  const disabled = isDisabled ?? context?.isDisabled ?? false;
114
153
  const ripple = useRipple(!disableRipple && !disabled, {
@@ -136,13 +175,13 @@ function IconButton({ children, disableRipple = false, href, isDisabled, onClick
136
175
  ...styleProps,
137
176
  children: [children, ripple.surface]
138
177
  });
139
- return /* @__PURE__ */ jsxs(Button, {
178
+ return /* @__PURE__ */ jsx(Button, {
140
179
  isDisabled: disabled,
141
180
  render: buttonRenderer(element, render),
142
181
  ...ripple.handlers,
143
182
  ...props$1,
144
183
  ...styleProps,
145
- children: [children, ripple.surface]
184
+ children: buttonContent(children, pendingLabel, ripple)
146
185
  });
147
186
  }
148
187
  //#endregion