@kanso-labs/kanso-ui 0.34.3 → 0.34.5

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.
@@ -1,17 +1,39 @@
1
1
  import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles, mergeStyles } from "../../styles/merge.js";
3
3
  import { overlay } from "../../styles/overlay.js";
4
+ import { useScrollable } from "../../hooks/useScrollable.js";
4
5
  import { c } from "react/compiler-runtime";
6
+ import { useRef } from "react";
5
7
  import { jsx } from "react/jsx-runtime";
6
8
  import { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } from "react-aria-components";
7
9
  //#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
- } };
10
+ const styles = {
11
+ body: {
12
+ kB7OPa: "x9f619",
13
+ kMwMTN: "x1w5n3ug",
14
+ k1xSpc: "x78zum5",
15
+ kXwgrk: "xdt5ytf",
16
+ kzQI83: "x1iyjqo2",
17
+ kMv6JI: "xpo2rfv",
18
+ kGuDYH: "x193rfdd",
19
+ k63SB2: "x1hews6w",
20
+ kOIVth: "xxj4525",
21
+ kb6lSQ: "xn43zvd",
22
+ kLWn49: "xv61bfh",
23
+ kORKVm: "x1odjw0f",
24
+ kGO01o: "x1az23kl x18d9i69",
25
+ kLKAdn: "x886u18 xexx8yu",
26
+ kg3NbH: "xg0ps1x",
27
+ $$css: true
28
+ },
29
+ centre: {
30
+ kGNEyG: "x6s0dn4",
31
+ k1xSpc: "x78zum5",
32
+ kjj79g: "xl56j7k",
33
+ kmVPX3: "x1apw6a7 xd76zvj",
34
+ $$css: true
35
+ }
36
+ };
15
37
  /**
16
38
  * A modal dialog centred over the page, and the same dialog filling the
17
39
  * window below the medium breakpoint — the dialogs page's basic and
@@ -51,25 +73,30 @@ function Dialog$1(t0) {
51
73
  } else t1 = $[5];
52
74
  return t1;
53
75
  }
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 x1az23kl x18d9i69 x886u18 xexx8yu xg0ps1x" }, props);
59
- $[0] = props;
60
- $[1] = t0;
61
- } else t0 = $[1];
76
+ function DialogBody(props$2) {
77
+ const $ = c(6);
78
+ const ref = useRef(null);
79
+ const t0 = useScrollable(ref) ? 0 : void 0;
62
80
  let t1;
63
- if ($[2] !== props || $[3] !== t0) {
64
- t1 = /* @__PURE__ */ jsx("div", {
65
- ...props,
66
- ...t0
81
+ if ($[0] !== props$2) {
82
+ t1 = mergeStyles(props(styles.body, overlay.modalBodyRing), props$2);
83
+ $[0] = props$2;
84
+ $[1] = t1;
85
+ } else t1 = $[1];
86
+ let t2;
87
+ if ($[2] !== props$2 || $[3] !== t0 || $[4] !== t1) {
88
+ t2 = /* @__PURE__ */ jsx("div", {
89
+ tabIndex: t0,
90
+ ...props$2,
91
+ ref,
92
+ ...t1
67
93
  });
68
- $[2] = props;
94
+ $[2] = props$2;
69
95
  $[3] = t0;
70
96
  $[4] = t1;
71
- } else t1 = $[4];
72
- return t1;
97
+ $[5] = t2;
98
+ } else t2 = $[5];
99
+ return t2;
73
100
  }
74
101
  /**
75
102
  * The dialog itself, and the scrim behind it. Everything the dialog shows
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["HTMLAttributes","ReactNode","ClassNameOrFunction","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","DialogProps","RACDialogProps","StyleOrFunction","stylex","DialogTrigger","Heading","Modal","ModalOverlay","Dialog","RACDialog","mergeStatefulStyles","mergeStyles","overlay","colors","media","motion","radii","shadows","spacing","typography","FORCED_COLORS","scaleIn","slideInFromBottom","styles","centre","kGNEyG","k1xSpc","kjj79g","kmVPX3","$$css","Omit","children","t0","$","_c","props","t1","DialogBody","className","DialogContent","container","isKeyboardDismissDisabled","style","isDismissable","undefined","t2","Symbol","for","scrim","t3","t4","modalDialog","t5","t6","t7","DialogFooter","DialogHeader","DialogTitle","Body","Content","Footer","Header","Title","DialogContentProps","Element","Pick","DialogTitleProps"],"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// 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 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 x1az23kl x18d9i69 x886u18 xexx8yu 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. 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 */\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 x1u6grsq xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x1w1tqly x19pkqky x1f120ba xx61lck x1gb867b x13rsnn2 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.\n//\n// `isDismissable` is declared here rather than picked with its sibling, since\n// the picked one carries React Aria's documentation, whose default is the\n// 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 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 /**\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, 'isKeyboardDismissDisabled'>;\ntype DialogTitleProps = HeadingProps;\nexport type { DialogContentProps, DialogProps, DialogTitleProps };\nexport default Dialog;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["HTMLAttributes","ReactNode","ClassNameOrFunction","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","DialogProps","RACDialogProps","StyleOrFunction","stylex","useRef","DialogTrigger","Heading","Modal","ModalOverlay","Dialog","RACDialog","useScrollable","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","Omit","children","t0","$","_c","props","t1","DialogBody","ref","scrollable","undefined","modalBodyRing","t2","DialogContent","className","container","isKeyboardDismissDisabled","style","isDismissable","Symbol","for","scrim","t3","t4","modalDialog","t5","t6","t7","DialogFooter","DialogHeader","DialogTitle","Body","Content","Footer","Header","Title","DialogContentProps","Element","Pick","DialogTitleProps"],"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 { useRef } from 'react';\nimport { DialogTrigger, Heading, Modal, ModalOverlay, Dialog as RACDialog } from 'react-aria-components';\nimport { useScrollable } from '../../hooks/useScrollable';\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 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\",\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};\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 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 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={ref} {...mergeStyles(stylex.props(styles.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.\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 */\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 x1u6grsq xbhiib0 x1ebxanj x16dv9tl xvkjz1l xt7dq6l x1ju3lih x1w1tqly x19pkqky x1f120ba xx61lck x1gb867b x13rsnn2 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.\n//\n// `isDismissable` is declared here rather than picked with its sibling, since\n// the picked one carries React Aria's documentation, whose default is the\n// 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 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 /**\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, 'isKeyboardDismissDisabled'>;\ntype DialogTitleProps = HeadingProps;\nexport type { DialogContentProps, DialogProps, DialogTitleProps };\nexport default Dialog;"],"mappings":";;;;;;;;;AA6CA,MAAMgC,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;;;;;;;;;;;;;;;AAmBA,SAAAjC,SAAAwC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAH;CAAA,IAAAI;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAgB,CAAA,CAAAD,UAAA,GAAAI,SAAAH;EAGFC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAE;CAAA,OAAA;EAAAJ,WAAAE,EAAA;EAAAE,QAAAF,EAAA;CAAA;CAAA,IAAAG;CAAA,IAAAH,EAAA,OAAAF,YAAAE,EAAA,OAAAE,OAAA;EACLC,KAAA,oBAAC,eAAD;GAAc,GAAKD;GAAQJ;EAAb,CAAA;EAAsCE,EAAA,KAAAF;EAAAE,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAApDG;AAAoD;AAE7D,SAAAC,WAAAF,SAAA;CAAA,MAAAF,IAAAC,EAAA,CAAA;CACE,MAAAI,MAAYnD,OAAuB,IAAI;CAO7B,MAAA6C,KAHStC,cAAc4C,GAGvBC,IAAA,IAAAC,KAAAA;CAA0B,IAAAJ;CAAA,IAAAH,EAAA,OAAAE,SAAA;EAA2BC,KAAAxC,YAAYV,MAAasB,OAAMC,MAAOZ,QAAO4C,aAAc,GAAGN,OAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAE,WAAAF,EAAA,OAAAD,MAAAC,EAAA,OAAAG,IAAA;EAF5HM,KAAA,oBAAA,OAAA;GAEG,UAAAV;GAA0B,GAAMG;GAAYG;GAAG,GAAMF;EAAoE,CAAA;EAAIH,EAAA,KAAAE;EAAAF,EAAA,KAAAD;EAAAC,EAAA,KAAAG;EAAAH,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAFhIS;AAEgI;;;;;;;;;;;;;;;;;AAmBzI,SAAAC,cAAAX,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAH;CAAA,IAAAa;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAX;CAAA,IAAAY;CAAA,IAAAX;CAAA,IAAAH,EAAA,OAAAD,IAAA;EAAuB,CAAA,CAAAD,UAAAa,WAAAC,WAAAG,eAAAZ,IAAAU,2BAAAC,OAAA,GAAAZ,WAAAH;EAQFC,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAW;EAAAX,EAAA,KAAAY;EAAAZ,EAAA,KAAAa;EAAAb,EAAA,KAAAE;EAAAF,EAAA,KAAAc;EAAAd,EAAA,KAAAG;CAAA,OAAA;EAAAL,WAAAE,EAAA;EAAAW,YAAAX,EAAA;EAAAY,YAAAZ,EAAA;EAAAa,4BAAAb,EAAA;EAAAE,UAAAF,EAAA;EAAAc,QAAAd,EAAA;EAAAG,KAAAH,EAAA;CAAA;CAJnB,MAAAe,gBAAAZ,OAAAI,KAAAA,IAAA,OAAAJ;CAAoB,IAAAM;CAAA,IAAAT,EAAA,OAAAgB,OAAAC,IAAA,2BAAA,GAAA;EAOqBR,KAAAxD,MAAaW,QAAOsD,OAAQ3C,OAAMkB,MAAO;EAACO,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAmB;CAAA,IAAAnB,EAAA,OAAAW,aAAAX,EAAA,QAAAc,OAAA;EACpEK,KAAAzD,oBAAoB,EAAAiD,WACpB,8NACb,GAAG;GAAAA;GAAAG;EAGH,CAAC;EAACd,EAAA,KAAAW;EAAAX,EAAA,MAAAc;EAAAd,EAAA,MAAAmB;CAAA,OAAAA,KAAAnB,EAAA;CAAA,IAAAoB;CAAA,IAAApB,EAAA,QAAAgB,OAAAC,IAAA,2BAAA,GAAA;EAC4BG,KAAAnE,MAAaW,QAAOyD,WAAY;EAACrB,EAAA,MAAAoB;CAAA,OAAAA,KAAApB,EAAA;CAAA,IAAAsB;CAAA,IAAAtB,EAAA,QAAAF,YAAAE,EAAA,QAAAE,SAAA;EAA3DoB,KAAA,oBAAC,QAAD;GAAU,GAAKpB;GAAK,GAAMkB;GACvBtB;EADO,CAAA;EAEEE,EAAA,MAAAF;EAAAE,EAAA,MAAAE;EAAAF,EAAA,MAAAsB;CAAA,OAAAA,KAAAtB,EAAA;CAAA,IAAAuB;CAAA,IAAAvB,EAAA,QAAAmB,MAAAnB,EAAA,QAAAsB,IAAA;EARdC,KAAA,oBAAC,OAAD;GAAM,GAAKJ;GAMTG,UAAAA;EANI,CAAA;EASEtB,EAAA,MAAAmB;EAAAnB,EAAA,MAAAsB;EAAAtB,EAAA,MAAAuB;CAAA,OAAAA,KAAAvB,EAAA;CAAA,IAAAwB;CAAA,IAAAxB,EAAA,QAAAY,aAAAZ,EAAA,QAAAe,iBAAAf,EAAA,QAAAa,6BAAAb,EAAA,QAAAuB,IAAA;EAZLC,KAAA,oBAAC,cAAD;GAA6BT;GAA0CF;GAEpDD,0BAAAA;GAAS,GAAMH;GACrCc,UAAAA;EAHgB,CAAA;EAaHvB,EAAA,MAAAY;EAAAZ,EAAA,MAAAe;EAAAf,EAAA,MAAAa;EAAAb,EAAA,MAAAuB;EAAAvB,EAAA,MAAAwB;CAAA,OAAAA,KAAAxB,EAAA;CAAA,OAbVwB;AAaU;AAEnB,SAAAC,aAAAvB,OAAA;CAAA,MAAAF,IAAAC,EAAA,CAAA;CAAA,IAAAF;CAAA,IAAAC,EAAA,OAAAE,OAAA;EAC6BH,KAAApC,YAAY,EAAAgD,WAC1B,iJACb,GAAGT,KAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAG;CAAA,IAAAH,EAAA,OAAAE,SAAAF,EAAA,OAAAD,IAAA;EAFFI,KAAA,oBAAA,OAAA;GAEM,GAFGD;GAAK,GAAMH;EAElB,CAAA;EAAIC,EAAA,KAAAE;EAAAF,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAFNG;AAEM;AAEf,SAAAuB,aAAAxB,OAAA;CAAA,MAAAF,IAAAC,EAAA,CAAA;CAAA,IAAAF;CAAA,IAAAC,EAAA,OAAAE,OAAA;EAC6BH,KAAApC,YAAY,EAAAgD,WAC1B,+IACb,GAAGT,KAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAG;CAAA,IAAAH,EAAA,OAAAE,SAAAF,EAAA,OAAAD,IAAA;EAFFI,KAAA,oBAAA,OAAA;GAEM,GAFGD;GAAK,GAAMH;EAElB,CAAA;EAAIC,EAAA,KAAAE;EAAAF,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAFNG;AAEM;;;;;;AAQf,SAAAwB,YAAAzB,OAAA;CAAA,MAAAF,IAAAC,EAAA,CAAA;CAAA,IAAAF;CAAA,IAAAC,EAAA,OAAAE,OAAA;EAC8CH,KAAApC,YAAY,EAAAgD,WAC3C,+GACb,GAAGT,KAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAG;CAAA,IAAAH,EAAA,OAAAE,SAAAF,EAAA,OAAAD,IAAA;EAFFI,KAAA,oBAAC,SAAD;GAAc,MAAA;GAAO,GAAKD;GAAK,GAAMH;EAEnC,CAAA;EAAIC,EAAA,KAAAE;EAAAF,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAFNG;AAEM;AAEf5C,SAAOqE,OAAOxB;AACd7C,SAAOsE,UAAUnB;AACjBnD,SAAOuE,SAASL;AAChBlE,SAAOwE,SAASL;AAChBnE,SAAOyE,QAAQL"}
@@ -1,10 +1,23 @@
1
1
  import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
2
  import { mergeStatefulStyles, mergeStyles } from "../../styles/merge.js";
3
3
  import { overlay } from "../../styles/overlay.js";
4
+ import { useScrollable } from "../../hooks/useScrollable.js";
4
5
  import { c } from "react/compiler-runtime";
6
+ import { useRef } from "react";
5
7
  import { jsx } from "react/jsx-runtime";
6
8
  import { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } from "react-aria-components";
7
9
  //#region src/components/sheet/index.tsx
10
+ const styles = { body: {
11
+ kB7OPa: "x9f619",
12
+ k1xSpc: "x78zum5",
13
+ kXwgrk: "xdt5ytf",
14
+ kzQI83: "x1iyjqo2",
15
+ kOIVth: "xxj4525",
16
+ kORKVm: "x1odjw0f",
17
+ k8WAf4: "xp6hjv6",
18
+ kg3NbH: "xg0ps1x",
19
+ $$css: true
20
+ } };
8
21
  /**
9
22
  * A modal panel that arrives from the edge of the screen — a side sheet on a
10
23
  * wide viewport, a bottom sheet on a narrow one. Open state is React Aria's:
@@ -43,25 +56,30 @@ function Sheet(t0) {
43
56
  } else t1 = $[5];
44
57
  return t1;
45
58
  }
46
- function SheetBody(props) {
47
- const $ = c(5);
48
- let t0;
49
- if ($[0] !== props) {
50
- t0 = mergeStyles({ className: "x9f619 x78zum5 xdt5ytf x1iyjqo2 xxj4525 x1odjw0f xp6hjv6 xg0ps1x" }, props);
51
- $[0] = props;
52
- $[1] = t0;
53
- } else t0 = $[1];
59
+ function SheetBody(props$2) {
60
+ const $ = c(6);
61
+ const ref = useRef(null);
62
+ const t0 = useScrollable(ref) ? 0 : void 0;
54
63
  let t1;
55
- if ($[2] !== props || $[3] !== t0) {
56
- t1 = /* @__PURE__ */ jsx("div", {
57
- ...props,
58
- ...t0
64
+ if ($[0] !== props$2) {
65
+ t1 = mergeStyles(props(styles.body, overlay.modalBodyRing), props$2);
66
+ $[0] = props$2;
67
+ $[1] = t1;
68
+ } else t1 = $[1];
69
+ let t2;
70
+ if ($[2] !== props$2 || $[3] !== t0 || $[4] !== t1) {
71
+ t2 = /* @__PURE__ */ jsx("div", {
72
+ tabIndex: t0,
73
+ ...props$2,
74
+ ref,
75
+ ...t1
59
76
  });
60
- $[2] = props;
77
+ $[2] = props$2;
61
78
  $[3] = t0;
62
79
  $[4] = t1;
63
- } else t1 = $[4];
64
- return t1;
80
+ $[5] = t2;
81
+ } else t2 = $[5];
82
+ return t2;
65
83
  }
66
84
  /**
67
85
  * The panel itself, and the scrim behind it. Everything the sheet shows goes
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["HTMLAttributes","ReactNode","ClassNameOrFunction","DialogProps","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","StyleOrFunction","stylex","Dialog","DialogTrigger","Heading","Modal","ModalOverlay","mergeStatefulStyles","mergeStyles","overlay","colors","media","motion","radii","shadows","spacing","typography","FORCED_COLORS","slideInFromEnd","slideInFromStart","slideInFromBottom","SheetProps","Omit","children","Sheet","t0","$","_c","props","t1","SheetBody","className","SheetContent","container","isKeyboardDismissDisabled","style","isDismissable","undefined","t2","Symbol","for","scrim","t3","t4","modalDialog","t5","t6","t7","SheetFooter","SheetHandle","SheetHeader","SheetTitle","Body","Content","Footer","Handle","Header","Title","SheetContentProps","Pick","Element","SheetTitleProps"],"sources":["../../../src/components/sheet/index.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport type { ClassNameOrFunction, DialogProps, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } 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// 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// One component, two presentations. Above the medium breakpoint it is a side\n// sheet pinned to the inline end of the viewport; below it, the same panel\n// becomes a bottom sheet. That is the pairing the Material Design pages draw\n// rather than two components: a sheet that stayed on the right at 375px would\n// be a drawer covering the whole screen.\n//\n// The two differ in five things and no more: which edges they are pinned to,\n// which two corners are rounded, which axis they arrive along, how much of\n// the viewport they may take, and the drag handle, which is the bottom\n// sheets page's element alone. Everything inside the panel — the 24 of start\n// and end padding, the 12 between the header's elements, the actions area —\n// comes from the side sheets page and is drawn the same in both.\n\n// The side sheet arrives along the inline axis, and it takes two keyframes to\n// do that rather than one. Which edge the panel rests against is logical —\n// `insetInlineEnd` puts it on the right under a left-to-right document and on\n// the left under a right-to-left one — but `translateX` is physical and flips\n// with nothing. One keyframe would therefore have the panel arrive from the\n// far side of where it comes to rest under one of the two.\nconst slideInFromEnd = \"x17cjob-B\";\nconst slideInFromStart = \"x18x3npg-B\";\nconst slideInFromBottom = \"x15b941j-B\";\n\n// Entry only, so there is no exit animation to wait for and closing is\n// immediate: React Aria keeps a closing panel mounted only while an animation\n// is running on it, and finds none. See the comment on `SheetContent` for why\n// that is a design call rather than a limit of StyleX.\n//\n// React Aria's overlay is three nested elements — the scrim, the panel, and\n// the dialog inside it — so the styles are split the same way: the overlay\n// module's scrim on the first, `content` on the panel, its modal dialog style\n// on the element that carries the role. The scrim and that dialog style are\n// shared with every modal overlay; the panel is the sheet's own, since which\n// edge it is pinned to is what makes it a sheet.\n\ntype SheetProps = Omit<DialogTriggerProps, 'children'> & {\n children?: ReactNode;\n};\n\n/**\n * A modal panel that arrives from the edge of the screen — a side sheet on a\n * wide viewport, a bottom sheet on a narrow one. Open state is React Aria's:\n * pass `isOpen` with `onOpenChange` to control it, or `defaultOpen` to let it\n * keep its own.\n *\n * Composed rather than configured by props, because a sheet's header, body,\n * and footer all take arbitrary content — the parts are `Sheet.Content`,\n * `Sheet.Header`, `Sheet.Title`, `Sheet.Body`, and `Sheet.Footer`. A\n * `Button` or `IconButton` placed directly inside `Sheet` opens it, and one\n * given `slot=\"close\"` anywhere inside the content closes it; neither needs\n * a part of its own.\n */\nfunction Sheet({\n children,\n ...props\n}: SheetProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\nfunction SheetBody(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x9f619 x78zum5 xdt5ytf x1iyjqo2 xxj4525 x1odjw0f xp6hjv6 xg0ps1x\"\n }, props)} />;\n}\n\n/**\n * The panel itself, and the scrim behind it. Everything the sheet shows goes\n * in here; the trigger stays outside it, since the trigger lives in the page\n * while this is portalled out to the end of the body.\n *\n * A press on the scrim closes the sheet unless `isDismissable` says\n * otherwise — React Aria's own default is the reverse, and a sheet that\n * ignores a tap outside it reads as stuck.\n */\nfunction SheetContent({\n children,\n className,\n container,\n isDismissable = true,\n isKeyboardDismissDisabled,\n style,\n ...props\n}: SheetContentProps) {\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)}>\n <Modal {...mergeStatefulStyles({\n className: \"x1n1nwrg x1u6grsq x1ioi8j8 xu2fq7p x18ihq2d x16dv9tl x1vnz5z6 x19dwuzr xuz63mn x1lym3mf xkducg2 xrzall9 xb0nsol xjslfuv x1gbqego x1cfajip xjg5lhu x1a37zkv xys6ro8 x6xk272 x9t1vth x19efjv6 x9f619 x139gbkf x78zum5 xdt5ytf x1l2rt3b xwvxfow x1ey2m1c x13vifvy xmpip4z xtijo5x xhi6v0a x1upgybz x7ab17h x11ijow0 xb3r6kr xixxii4\"\n }, {\n className,\n style\n })}>\n <Dialog {...props} {...stylex.props(overlay.modalDialog)}>\n {children}\n </Dialog>\n </Modal>\n </ModalOverlay>;\n}\nfunction SheetFooter(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x12smttz x13fuv20 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x1nhvcw1 x1qafhyn x8i8c5o x1clyivc xg0ps1x\"\n }, props)} />;\n}\n\n/**\n * The bottom sheets page's drag handle: a short bar above the sheet's\n * content, saying the panel is a bottom sheet. Place it first inside\n * `Sheet.Content`; above the medium breakpoint the panel is a side sheet and\n * this draws nothing.\n *\n * It is decoration rather than a control, and hidden from assistive\n * technology. Material's own handle drags a sheet between a collapsed and an\n * expanded height and dismisses it from the collapsed one; this panel has\n * one height and cannot be dragged, so a control that only looked draggable\n * would promise what it cannot do. Closing is already the scrim, Escape, and\n * any button given `slot=\"close\"`.\n */\nfunction SheetHandle(props: HTMLAttributes<HTMLDivElement>) {\n return <div aria-hidden=\"true\" {...props} {...mergeStyles({\n className: \"x6s0dn4 x9f619 x1s85apg x37i4ze x2lah0s xl56j7k x1xg6qyv\"\n }, props)}>\n <span className=\"x1ccu2yh xqu0tyb x1dkaolv x9f619 x1td3qas\" />\n </div>;\n}\nfunction SheetHeader(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x6s0dn4 x1j6faob x1q0q8m5 xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib x1cmllll xg0ps1x\"\n }, props)} />;\n}\n\n/**\n * Names the sheet. Rendered through React Aria's title slot, which is what\n * points the dialog's `aria-labelledby` at it — a sheet without one announces\n * itself as an unnamed dialog.\n */\nfunction SheetTitle(props: SheetTitleProps) {\n return <Heading slot=\"title\" {...props} {...mergeStyles({\n className: \"x9f619 x1w5n3ug xdy5w5q xete2z3 x14ijtet xug9e1u x2divse x1ghz6dp\"\n }, props)} />;\n}\nSheet.Body = SheetBody;\nSheet.Content = SheetContent;\nSheet.Footer = SheetFooter;\nSheet.Handle = SheetHandle;\nSheet.Header = SheetHeader;\nSheet.Title = SheetTitle;\n\n// The dialog's own props, plus the scrim's dismissal settings and the panel's\n// styling. A call site has no reason to know there are three elements:\n// `className` and `style` reach the panel, which is the one worth restyling\n// and positioning, and everything else lands on the dialog.\n//\n// `isDismissable` is declared here rather than picked with its sibling, since\n// the picked one carries React Aria's documentation, whose default is the\n// reverse of this component's.\ntype SheetContentProps = Omit<DialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'isKeyboardDismissDisabled'> & {\n /** A function may compute the class from the panel's render state. */\n className?: ClassNameOrFunction<ModalRenderProps>;\n /**\n * Where to portal the panel 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 inside\n * it, or the sheet renders outside the theme and falls back to the tokens'\n * `prefers-color-scheme` default.\n */\n container?: Element;\n /**\n * Whether a press on the scrim, outside the panel, closes the sheet.\n * `true` here where React Aria's own default is `false`, since a sheet\n * that ignores a tap outside it reads as stuck. Escape is\n * `isKeyboardDismissDisabled`'s, and this says nothing about it.\n * @default true\n */\n isDismissable?: boolean;\n /** A function may compute the style from the panel's render state. */\n style?: StyleOrFunction<ModalRenderProps>;\n};\ntype SheetTitleProps = HeadingProps;\nexport type { SheetContentProps, SheetProps, SheetTitleProps };\nexport default Sheet;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["HTMLAttributes","ReactNode","ClassNameOrFunction","DialogProps","DialogTriggerProps","HeadingProps","ModalOverlayProps","ModalRenderProps","StyleOrFunction","stylex","useRef","Dialog","DialogTrigger","Heading","Modal","ModalOverlay","useScrollable","mergeStatefulStyles","mergeStyles","overlay","colors","media","motion","radii","shadows","spacing","typography","FORCED_COLORS","slideInFromEnd","slideInFromStart","slideInFromBottom","styles","body","kB7OPa","k1xSpc","kXwgrk","kzQI83","kOIVth","kORKVm","k8WAf4","kg3NbH","$$css","SheetProps","Omit","children","Sheet","t0","$","_c","props","t1","SheetBody","ref","scrollable","undefined","modalBodyRing","t2","SheetContent","className","container","isKeyboardDismissDisabled","style","isDismissable","Symbol","for","scrim","t3","t4","modalDialog","t5","t6","t7","SheetFooter","SheetHandle","SheetHeader","SheetTitle","Body","Content","Footer","Handle","Header","Title","SheetContentProps","Pick","Element","SheetTitleProps"],"sources":["../../../src/components/sheet/index.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport type { ClassNameOrFunction, DialogProps, DialogTriggerProps, HeadingProps, ModalOverlayProps, ModalRenderProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useRef } from 'react';\nimport { Dialog, DialogTrigger, Heading, Modal, ModalOverlay } from 'react-aria-components';\nimport { useScrollable } from '../../hooks/useScrollable';\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// One component, two presentations. Above the medium breakpoint it is a side\n// sheet pinned to the inline end of the viewport; below it, the same panel\n// becomes a bottom sheet. That is the pairing the Material Design pages draw\n// rather than two components: a sheet that stayed on the right at 375px would\n// be a drawer covering the whole screen.\n//\n// The two differ in five things and no more: which edges they are pinned to,\n// which two corners are rounded, which axis they arrive along, how much of\n// the viewport they may take, and the drag handle, which is the bottom\n// sheets page's element alone. Everything inside the panel — the 24 of start\n// and end padding, the 12 between the header's elements, the actions area —\n// comes from the side sheets page and is drawn the same in both.\n\n// The side sheet arrives along the inline axis, and it takes two keyframes to\n// do that rather than one. Which edge the panel rests against is logical —\n// `insetInlineEnd` puts it on the right under a left-to-right document and on\n// the left under a right-to-left one — but `translateX` is physical and flips\n// with nothing. One keyframe would therefore have the panel arrive from the\n// far side of where it comes to rest under one of the two.\nconst slideInFromEnd = \"x17cjob-B\";\nconst slideInFromStart = \"x18x3npg-B\";\nconst slideInFromBottom = \"x15b941j-B\";\n\n// Entry only, so there is no exit animation to wait for and closing is\n// immediate: React Aria keeps a closing panel mounted only while an animation\n// is running on it, and finds none. See the comment on `SheetContent` for why\n// that is a design call rather than a limit of StyleX.\n//\n// React Aria's overlay is three nested elements — the scrim, the panel, and\n// the dialog inside it — so the styles are split the same way: the overlay\n// module's scrim on the first, `content` on the panel, its modal dialog style\n// on the element that carries the role. The scrim and that dialog style are\n// shared with every modal overlay; the panel is the sheet's own, since which\n// edge it is pinned to is what makes it a sheet.\nconst styles = {\n body: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kzQI83: \"x1iyjqo2\",\n kOIVth: \"xxj4525\",\n kORKVm: \"x1odjw0f\",\n k8WAf4: \"xp6hjv6\",\n kg3NbH: \"xg0ps1x\",\n $$css: true\n }\n};\ntype SheetProps = Omit<DialogTriggerProps, 'children'> & {\n children?: ReactNode;\n};\n\n/**\n * A modal panel that arrives from the edge of the screen — a side sheet on a\n * wide viewport, a bottom sheet on a narrow one. Open state is React Aria's:\n * pass `isOpen` with `onOpenChange` to control it, or `defaultOpen` to let it\n * keep its own.\n *\n * Composed rather than configured by props, because a sheet's header, body,\n * and footer all take arbitrary content — the parts are `Sheet.Content`,\n * `Sheet.Header`, `Sheet.Title`, `Sheet.Body`, and `Sheet.Footer`. A\n * `Button` or `IconButton` placed directly inside `Sheet` opens it, and one\n * given `slot=\"close\"` anywhere inside the content closes it; neither needs\n * a part of its own.\n */\nfunction Sheet({\n children,\n ...props\n}: SheetProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\nfunction SheetBody(props: HTMLAttributes<HTMLDivElement>) {\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 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={ref} {...mergeStyles(stylex.props(styles.body, overlay.modalBodyRing), props)} />;\n}\n\n/**\n * The panel itself, and the scrim behind it. Everything the sheet shows goes\n * in here; the trigger stays outside it, since the trigger lives in the page\n * while this is portalled out to the end of the body.\n *\n * A press on the scrim closes the sheet unless `isDismissable` says\n * otherwise — React Aria's own default is the reverse, and a sheet that\n * ignores a tap outside it reads as stuck.\n */\nfunction SheetContent({\n children,\n className,\n container,\n isDismissable = true,\n isKeyboardDismissDisabled,\n style,\n ...props\n}: SheetContentProps) {\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)}>\n <Modal {...mergeStatefulStyles({\n className: \"x1n1nwrg x1u6grsq x1ioi8j8 xu2fq7p x18ihq2d x16dv9tl x1vnz5z6 x19dwuzr xuz63mn x1lym3mf xkducg2 xrzall9 xb0nsol xjslfuv x1gbqego x1cfajip xjg5lhu x1a37zkv xys6ro8 x6xk272 x9t1vth x19efjv6 x9f619 x139gbkf x78zum5 xdt5ytf x1l2rt3b xwvxfow x1ey2m1c x13vifvy xmpip4z xtijo5x xhi6v0a x1upgybz x7ab17h x11ijow0 xb3r6kr xixxii4\"\n }, {\n className,\n style\n })}>\n <Dialog {...props} {...stylex.props(overlay.modalDialog)}>\n {children}\n </Dialog>\n </Modal>\n </ModalOverlay>;\n}\nfunction SheetFooter(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x12smttz x13fuv20 x178xt8z x9f619 x78zum5 x2lah0s x126z3so x1nhvcw1 x1qafhyn x8i8c5o x1clyivc xg0ps1x\"\n }, props)} />;\n}\n\n/**\n * The bottom sheets page's drag handle: a short bar above the sheet's\n * content, saying the panel is a bottom sheet. Place it first inside\n * `Sheet.Content`; above the medium breakpoint the panel is a side sheet and\n * this draws nothing.\n *\n * It is decoration rather than a control, and hidden from assistive\n * technology. Material's own handle drags a sheet between a collapsed and an\n * expanded height and dismisses it from the collapsed one; this panel has\n * one height and cannot be dragged, so a control that only looked draggable\n * would promise what it cannot do. Closing is already the scrim, Escape, and\n * any button given `slot=\"close\"`.\n */\nfunction SheetHandle(props: HTMLAttributes<HTMLDivElement>) {\n return <div aria-hidden=\"true\" {...props} {...mergeStyles({\n className: \"x6s0dn4 x9f619 x1s85apg x37i4ze x2lah0s xl56j7k x1xg6qyv\"\n }, props)}>\n <span className=\"x1ccu2yh xqu0tyb x1dkaolv x9f619 x1td3qas\" />\n </div>;\n}\nfunction SheetHeader(props: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} {...mergeStyles({\n className: \"x6s0dn4 x1j6faob x1q0q8m5 xso031l x9f619 x78zum5 x2lah0s x1gka490 x1qughib x1cmllll xg0ps1x\"\n }, props)} />;\n}\n\n/**\n * Names the sheet. Rendered through React Aria's title slot, which is what\n * points the dialog's `aria-labelledby` at it — a sheet without one announces\n * itself as an unnamed dialog.\n */\nfunction SheetTitle(props: SheetTitleProps) {\n return <Heading slot=\"title\" {...props} {...mergeStyles({\n className: \"x9f619 x1w5n3ug xdy5w5q xete2z3 x14ijtet xug9e1u x2divse x1ghz6dp\"\n }, props)} />;\n}\nSheet.Body = SheetBody;\nSheet.Content = SheetContent;\nSheet.Footer = SheetFooter;\nSheet.Handle = SheetHandle;\nSheet.Header = SheetHeader;\nSheet.Title = SheetTitle;\n\n// The dialog's own props, plus the scrim's dismissal settings and the panel's\n// styling. A call site has no reason to know there are three elements:\n// `className` and `style` reach the panel, which is the one worth restyling\n// and positioning, and everything else lands on the dialog.\n//\n// `isDismissable` is declared here rather than picked with its sibling, since\n// the picked one carries React Aria's documentation, whose default is the\n// reverse of this component's.\ntype SheetContentProps = Omit<DialogProps, 'className' | 'style'> & Pick<ModalOverlayProps, 'isKeyboardDismissDisabled'> & {\n /** A function may compute the class from the panel's render state. */\n className?: ClassNameOrFunction<ModalRenderProps>;\n /**\n * Where to portal the panel 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 inside\n * it, or the sheet renders outside the theme and falls back to the tokens'\n * `prefers-color-scheme` default.\n */\n container?: Element;\n /**\n * Whether a press on the scrim, outside the panel, closes the sheet.\n * `true` here where React Aria's own default is `false`, since a sheet\n * that ignores a tap outside it reads as stuck. Escape is\n * `isKeyboardDismissDisabled`'s, and this says nothing about it.\n * @default true\n */\n isDismissable?: boolean;\n /** A function may compute the style from the panel's render state. */\n style?: StyleOrFunction<ModalRenderProps>;\n};\ntype SheetTitleProps = HeadingProps;\nexport type { SheetContentProps, SheetProps, SheetTitleProps };\nexport default Sheet;"],"mappings":"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"}
@@ -18,12 +18,15 @@ import { FormContext, useSlottedContext } from "react-aria-components";
18
18
  */
19
19
  const FIELD_VALIDATION_BEHAVIOR = "aria";
20
20
  /**
21
- * What a field passes React Aria for `isInvalid`, from its `error` prop. Any
22
- * value there, `false` included, makes the field's validation controlled: it
23
- * is exactly as invalid as the prop says, and what a `Form` reports for it —
24
- * a server's errors, or the browser's own — is never shown. So the prop is
25
- * left unset while the field has no error of its own, which is what lets
26
- * the form's reach it.
21
+ * What a field passes React Aria for `isInvalid`, from its `error` prop:
22
+ * `true` while there is a message, and nothing at all while there is not.
23
+ *
24
+ * Nothing rather than `false`, because React Aria reads any `isInvalid` it is
25
+ * given — `false` as much as `true` — as the field taking its validation into
26
+ * its own hands. The field is then exactly as invalid as the prop says, and
27
+ * what a `Form` reports for it, a server's errors or the browser's own, is
28
+ * never shown. Leaving the prop unset while the field has no error of its own
29
+ * is what lets the form's reach it.
27
30
  */
28
31
  function invalidFrom(error) {
29
32
  return error === void 0 ? void 0 : true;
@@ -1 +1 @@
1
- {"version":3,"file":"root.js","names":["stylex","FormContext","useSlottedContext","FIELD_VALIDATION_BEHAVIOR","invalidFrom","error","undefined","useFieldValidationBehavior","form","validationBehavior","useInsideForm","fieldStyles","root","kB7OPa","k1xSpc","kXwgrk","$$css"],"sources":["../../src/field/root.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport { FormContext, useSlottedContext } from 'react-aria-components';\n\n// What a field applies to its own root, which is React Aria's field element\n// rather than a part of the chrome. Apart from the parts in ./index.tsx so\n// that file exports components alone, which is what keeps fast refresh working\n// for it.\n\n/**\n * What a field passes React Aria for `validationBehavior` outside a `Form`.\n * The message under a field is the library's to show, so validation only\n * marks the control rather than surfacing the browser's own constraint UI.\n * One constant rather than a literal in each field, so the decision has one\n * place to be changed.\n *\n * **It leaves announcing and focusing to the app**, and that is the half of\n * the browser's behaviour this gives up. An error under `aria` is associated\n * the way it should be — `aria-invalid` on the control, the message in its\n * `aria-describedby` — so a reader who moves to the field is told. What does\n * not happen is the move: after a server answers, focus is still wherever\n * the submit left it and nothing has been read out. Nothing here knows a\n * round trip happened, so the call site that made it is what moves focus to\n * the first field that came back invalid.\n */\nconst FIELD_VALIDATION_BEHAVIOR = 'aria';\n\n/**\n * What a field passes React Aria for `isInvalid`, from its `error` prop. Any\n * value there, `false` included, makes the field's validation controlled: it\n * is exactly as invalid as the prop says, and what a `Form` reports for it —\n * a server's errors, or the browser's own — is never shown. So the prop is\n * left unset while the field has no error of its own, which is what lets\n * the form's reach it.\n */\nfunction invalidFrom(error: string | undefined): true | undefined {\n return error === undefined ? undefined : true;\n}\n\n/**\n * The validation behaviour a field passes React Aria: its `Form`'s, where it\n * is inside one, and {@link FIELD_VALIDATION_BEHAVIOR} otherwise. React Aria\n * takes a field's own prop over its form's, so a field that passed the\n * constant could never be opted into the native behaviour by the form around\n * it; reading the form here is what lets `Form` decide for every field at\n * once.\n */\nfunction useFieldValidationBehavior(): 'aria' | 'native' {\n const form = useSlottedContext(FormContext);\n return form?.validationBehavior ?? FIELD_VALIDATION_BEHAVIOR;\n}\n\n/**\n * Whether this field is inside a `Form`. A form is where a message arrives\n * after the fact — a server's answer, or the browser's own on submit — so it\n * is where the line under a field is kept clear whether or not there is\n * anything to say, and the fields below it stay where they are.\n */\nfunction useInsideForm() {\n return useSlottedContext(FormContext) !== null;\n}\nconst fieldStyles = {\n root: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n $$css: true\n }\n};\nexport { FIELD_VALIDATION_BEHAVIOR, fieldStyles, invalidFrom, useFieldValidationBehavior, useInsideForm };"],"mappings":";;;;;;;;;;;;;;;;;;AAwBA,MAAMG,4BAA4B;;;;;;;;;AAUlC,SAASC,YAAYC,OAA6C;CAChE,OAAOA,UAAUC,KAAAA,IAAYA,KAAAA,IAAY;AAC3C;;;;;;;;;AAUA,SAAAC,6BAAA;CAC8C,OAA/BL,kBAAkBD,WACxBO,CAAI,EAAAC,sBAAAA;AAAiD;;;;;;;AAS9D,SAAAC,gBAAA;CAAA,OACSR,kBAAkBD,WAAW,MAAM;AAAI;AAEhD,MAAMU,cAAc,EAClBC,MAAM;CACJC,QAAQ;CACRC,QAAQ;CACRC,QAAQ;CACRC,OAAO;AACT,EACF"}
1
+ {"version":3,"file":"root.js","names":["stylex","FormContext","useSlottedContext","FIELD_VALIDATION_BEHAVIOR","invalidFrom","error","undefined","useFieldValidationBehavior","form","validationBehavior","useInsideForm","fieldStyles","root","kB7OPa","k1xSpc","kXwgrk","$$css"],"sources":["../../src/field/root.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport { FormContext, useSlottedContext } from 'react-aria-components';\n\n// What a field applies to its own root, which is React Aria's field element\n// rather than a part of the chrome. Apart from the parts in ./index.tsx so\n// that file exports components alone, which is what keeps fast refresh working\n// for it.\n\n/**\n * What a field passes React Aria for `validationBehavior` outside a `Form`.\n * The message under a field is the library's to show, so validation only\n * marks the control rather than surfacing the browser's own constraint UI.\n * One constant rather than a literal in each field, so the decision has one\n * place to be changed.\n *\n * **It leaves announcing and focusing to the app**, and that is the half of\n * the browser's behaviour this gives up. An error under `aria` is associated\n * the way it should be — `aria-invalid` on the control, the message in its\n * `aria-describedby` — so a reader who moves to the field is told. What does\n * not happen is the move: after a server answers, focus is still wherever\n * the submit left it and nothing has been read out. Nothing here knows a\n * round trip happened, so the call site that made it is what moves focus to\n * the first field that came back invalid.\n */\nconst FIELD_VALIDATION_BEHAVIOR = 'aria';\n\n/**\n * What a field passes React Aria for `isInvalid`, from its `error` prop:\n * `true` while there is a message, and nothing at all while there is not.\n *\n * Nothing rather than `false`, because React Aria reads any `isInvalid` it is\n * given — `false` as much as `true` — as the field taking its validation into\n * its own hands. The field is then exactly as invalid as the prop says, and\n * what a `Form` reports for it, a server's errors or the browser's own, is\n * never shown. Leaving the prop unset while the field has no error of its own\n * is what lets the form's reach it.\n */\nfunction invalidFrom(error: string | undefined): true | undefined {\n return error === undefined ? undefined : true;\n}\n\n/**\n * The validation behaviour a field passes React Aria: its `Form`'s, where it\n * is inside one, and {@link FIELD_VALIDATION_BEHAVIOR} otherwise. React Aria\n * takes a field's own prop over its form's, so a field that passed the\n * constant could never be opted into the native behaviour by the form around\n * it; reading the form here is what lets `Form` decide for every field at\n * once.\n */\nfunction useFieldValidationBehavior(): 'aria' | 'native' {\n const form = useSlottedContext(FormContext);\n return form?.validationBehavior ?? FIELD_VALIDATION_BEHAVIOR;\n}\n\n/**\n * Whether this field is inside a `Form`. A form is where a message arrives\n * after the fact — a server's answer, or the browser's own on submit — so it\n * is where the line under a field is kept clear whether or not there is\n * anything to say, and the fields below it stay where they are.\n */\nfunction useInsideForm() {\n return useSlottedContext(FormContext) !== null;\n}\nconst fieldStyles = {\n root: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n $$css: true\n }\n};\nexport { FIELD_VALIDATION_BEHAVIOR, fieldStyles, invalidFrom, useFieldValidationBehavior, useInsideForm };"],"mappings":";;;;;;;;;;;;;;;;;;AAwBA,MAAMG,4BAA4B;;;;;;;;;;;;AAalC,SAASC,YAAYC,OAA6C;CAChE,OAAOA,UAAUC,KAAAA,IAAYA,KAAAA,IAAY;AAC3C;;;;;;;;;AAUA,SAAAC,6BAAA;CAC8C,OAA/BL,kBAAkBD,WACxBO,CAAI,EAAAC,sBAAAA;AAAiD;;;;;;;AAS9D,SAAAC,gBAAA;CAAA,OACSR,kBAAkBD,WAAW,MAAM;AAAI;AAEhD,MAAMU,cAAc,EAClBC,MAAM;CACJC,QAAQ;CACRC,QAAQ;CACRC,QAAQ;CACRC,OAAO;AACT,EACF"}
@@ -0,0 +1,69 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import { useLayoutEffect, useState } from "react";
3
+ //#region src/hooks/useScrollable.ts
4
+ /**
5
+ * Whether the element in `ref` is scrolling its content: whether the content
6
+ * runs past the element's own block size. Kept current as the element
7
+ * resizes and as its content changes.
8
+ *
9
+ * What it is for is keyboard access. A scroll container with nothing
10
+ * focusable inside it cannot be reached from the keyboard in every browser,
11
+ * so a component makes it a tab stop while this is true, and only then — a
12
+ * body short enough to show whole is no stop at all.
13
+ *
14
+ * The element is watched for its own size, and each child for its size, since
15
+ * a child growing is how content outgrows a container whose size is capped.
16
+ * The children are re-observed whenever the content changes, and a change of
17
+ * text alone is caught by the same mutation observer. Measured in a layout
18
+ * effect, so the first paint already has the answer rather than a frame
19
+ * later.
20
+ */
21
+ function useScrollable(ref) {
22
+ const $ = c(3);
23
+ const [scrollable, setScrollable] = useState(false);
24
+ let t0;
25
+ let t1;
26
+ if ($[0] !== ref) {
27
+ t0 = () => {
28
+ const element = ref.current;
29
+ if (element === null) return;
30
+ const measure = () => {
31
+ setScrollable(element.scrollHeight > element.clientHeight);
32
+ };
33
+ const resize = new ResizeObserver(measure);
34
+ const observe = () => {
35
+ resize.disconnect();
36
+ resize.observe(element);
37
+ for (const child of element.children) resize.observe(child);
38
+ };
39
+ const mutation = new MutationObserver(() => {
40
+ observe();
41
+ measure();
42
+ });
43
+ observe();
44
+ mutation.observe(element, {
45
+ characterData: true,
46
+ childList: true,
47
+ subtree: true
48
+ });
49
+ measure();
50
+ return () => {
51
+ resize.disconnect();
52
+ mutation.disconnect();
53
+ };
54
+ };
55
+ t1 = [ref];
56
+ $[0] = ref;
57
+ $[1] = t0;
58
+ $[2] = t1;
59
+ } else {
60
+ t0 = $[1];
61
+ t1 = $[2];
62
+ }
63
+ useLayoutEffect(t0, t1);
64
+ return scrollable;
65
+ }
66
+ //#endregion
67
+ export { useScrollable };
68
+
69
+ //# sourceMappingURL=useScrollable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScrollable.js","names":["RefObject","useLayoutEffect","useState","useScrollable","ref","$","_c","scrollable","setScrollable","t0","t1","element","current","measure","scrollHeight","clientHeight","resize","ResizeObserver","observe","disconnect","child","children","mutation","MutationObserver","characterData","childList","subtree"],"sources":["../../src/hooks/useScrollable.ts"],"sourcesContent":["import type { RefObject } from 'react'\n\nimport { useLayoutEffect, useState } from 'react'\n\n/**\n * Whether the element in `ref` is scrolling its content: whether the content\n * runs past the element's own block size. Kept current as the element\n * resizes and as its content changes.\n *\n * What it is for is keyboard access. A scroll container with nothing\n * focusable inside it cannot be reached from the keyboard in every browser,\n * so a component makes it a tab stop while this is true, and only then — a\n * body short enough to show whole is no stop at all.\n *\n * The element is watched for its own size, and each child for its size, since\n * a child growing is how content outgrows a container whose size is capped.\n * The children are re-observed whenever the content changes, and a change of\n * text alone is caught by the same mutation observer. Measured in a layout\n * effect, so the first paint already has the answer rather than a frame\n * later.\n */\nfunction useScrollable(ref: RefObject<HTMLElement | null>): boolean {\n const [scrollable, setScrollable] = useState(false)\n\n useLayoutEffect(() => {\n const element = ref.current\n if (element === null) {\n return undefined\n }\n\n const measure = () => {\n setScrollable(element.scrollHeight > element.clientHeight)\n }\n const resize = new ResizeObserver(measure)\n const observe = () => {\n resize.disconnect()\n resize.observe(element)\n for (const child of element.children) {\n resize.observe(child)\n }\n }\n const mutation = new MutationObserver(() => {\n observe()\n measure()\n })\n\n observe()\n mutation.observe(element, {\n characterData: true,\n childList: true,\n subtree: true,\n })\n measure()\n\n return () => {\n resize.disconnect()\n mutation.disconnect()\n }\n }, [ref])\n\n return scrollable\n}\n\nexport { useScrollable }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,SAAAG,cAAAC,KAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CACE,MAAA,CAAAC,YAAAC,iBAAoCN,SAAS,KAAK;CAAC,IAAAO;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAD,KAAA;EAEnCK,WAAA;GACd,MAAAE,UAAgBP,IAAGQ;GACnB,IAAID,YAAY,MAAI;GAIpB,MAAAE,gBAAgB;IACdL,cAAcG,QAAOG,eAAgBH,QAAOI,YAAa;GAAC;GAE5D,MAAAC,SAAe,IAAIC,eAAeJ,OAAO;GACzC,MAAAK,gBAAgB;IACdF,OAAMG,WAAY;IAClBH,OAAME,QAASP,OAAO;IACtB,KAAK,MAAAS,SAAeT,QAAOU,UACzBL,OAAME,QAASE,KAAK;GACrB;GAEH,MAAAE,WAAiB,IAAIC,uBAAiB;IACpCL,QAAQ;IACRL,QAAQ;GAAC,CACV;GAEDK,QAAQ;GACRI,SAAQJ,QAASP,SAAS;IAAAa,eACT;IAAIC,WACR;IAAIC,SACN;GACX,CAAC;GACDb,QAAQ;GAAC,aAEF;IACLG,OAAMG,WAAY;IAClBG,SAAQH,WAAY;GAAC;EACtB;EACAT,KAAA,CAACN,GAAG;EAACC,EAAA,KAAAD;EAAAC,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAlCRJ,gBAAgBQ,IAkCbC,EAAK;CAAC,OAEFH;AAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"focus.js","names":["stylex","colors","focus","ring","kjBf7l","kInvED","k3XXqK","kMeerF","$$css","ringVisible"],"sources":["../../src/styles/focus.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors } from '../tokens/design.tokens.stylex';\n\n// The focus ring, drawn once. Eighteen components spelled the same four\n// declarations out, which made a change to the ring eighteen edits with\n// nothing failing if one were missed.\n//\n// Only these two forms are shared, and the difference is who decides the\n// element has focus. `ring` lets the browser decide, through\n// `:focus-visible`, which is what a natively focusable element wants.\n// `ringVisible` is always solid, for a component that computes focus from\n// React Aria's render state and applies this style only when that state says\n// so — a checkbox, radio or switch, where the ring belongs on the drawn\n// control rather than on the input that actually holds focus.\n//\n// What deliberately stays with its component is every ring that differs, and\n// each of those already carries a comment saying why:\n//\n// - A different colour, because the surface underneath is not the default\n// one: Snackbar's action and close, and Chip's remove.\n// - A negative offset, drawing the ring inside the element rather than\n// around it: DropZone, NumberField, Table, a Tab, and the shared row.\n// - An offset of its own, sized to what the ring surrounds: the colour\n// thumb at 4px, the swatch at 6px, Chip's remove at 1px.\n// - A base of `outlineStyle: 'none'` that a separate style turns solid,\n// which is a different mechanism rather than a different value: the slider\n// thumb, the colour swatch picker, and the shared colour styles.\nconst focus = {\n ring: {\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n $$css: true\n },\n ringVisible: {\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"xaatb59\",\n kMeerF: \"x1de99jn\",\n $$css: true\n }\n};\nexport { focus };"],"mappings":";AA4BA,MAAME,QAAQ;CACZC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,aAAa;EACXL,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"focus.js","names":["stylex","colors","focus","ring","kjBf7l","kInvED","k3XXqK","kMeerF","$$css","ringVisible"],"sources":["../../src/styles/focus.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors } from '../tokens/design.tokens.stylex';\n\n// The focus ring, drawn once. Eighteen components spelled the same four\n// declarations out, which made a change to the ring eighteen edits with\n// nothing failing if one were missed.\n//\n// Only these two forms are shared, and the difference is who decides the\n// element has focus. `ring` lets the browser decide, through\n// `:focus-visible`, which is what a natively focusable element wants.\n// `ringVisible` is always solid, for a component that computes focus from\n// React Aria's render state and applies this style only when that state says\n// so — a checkbox, radio or switch, where the ring belongs on the drawn\n// control rather than on the input that actually holds focus.\n//\n// What deliberately stays with its component is every ring that differs, and\n// each of those already carries a comment saying why:\n//\n// - A different colour, because the surface underneath is not the default\n// one: Snackbar's action and close, and Chip's remove.\n// - A negative offset, drawing the ring inside the element rather than\n// around it: DropZone, NumberField, Table, a Tab, the shared row, and the\n// body of a Dialog or a Sheet while it scrolls.\n// - An offset of its own, sized to what the ring surrounds: the colour\n// thumb at 4px, the swatch at 6px, Chip's remove at 1px.\n// - A base of `outlineStyle: 'none'` that a separate style turns solid,\n// which is a different mechanism rather than a different value: the slider\n// thumb, the colour swatch picker, and the shared colour styles.\nconst focus = {\n ring: {\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n $$css: true\n },\n ringVisible: {\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"xaatb59\",\n kMeerF: \"x1de99jn\",\n $$css: true\n }\n};\nexport { focus };"],"mappings":";AA6BA,MAAME,QAAQ;CACZC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;CACAC,aAAa;EACXL,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;CACT;AACF"}
@@ -16,11 +16,19 @@ const overlay = {
16
16
  k3nNDw: "x1dp6rp6",
17
17
  $$css: true
18
18
  },
19
+ modalBodyRing: {
20
+ kjBf7l: "xrgy624",
21
+ kInvED: "x2ssjo2",
22
+ k3XXqK: "x9v5kkp x1t137rt",
23
+ kMeerF: "x1de99jn",
24
+ $$css: true
25
+ },
19
26
  modalDialog: {
20
27
  kZKoxP: "x5yr21d",
21
28
  kB7OPa: "x9f619",
22
29
  k1xSpc: "x78zum5",
23
30
  kXwgrk: "xdt5ytf",
31
+ kAzted: "x2lwn1j",
24
32
  k3XXqK: "x1t137rt",
25
33
  $$css: true
26
34
  },
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.js","names":["PopoverRenderProps","stylex","colors","motion","radii","shadows","spacing","FORCED_COLORS","fadeIn","scaleIn","overlay","fromBottom","k3nNDw","$$css","fromLeft","fromRight","fromTop","modalDialog","kZKoxP","kB7OPa","k1xSpc","kXwgrk","k3XXqK","popup","k44tkh","kKVMdj","kyAemX","kWkggS","kVAM5u","kaIpWk","ksu8eU","kMzoRj","kGVxlE","kMwMTN","kORKVm","popupDialog","kOIVth","scrim","kpwlN0","kVAEAm","origins","bottom","center","left","right","top","OverlayAlign","OverlaySide","placementOf","side","align","const","popupOrigin","placement"],"sources":["../../src/styles/overlay.ts"],"sourcesContent":["import type { PopoverRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, spacing } 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// What every overlay shares, drawn once. Popover's anchored surface and its\n// entry, Sheet's scrim, and the element that carries the dialog role inside\n// each of them; the coverage plan brings a dozen more overlays — Menu, Select,\n// ComboBox, Tooltip, the date pickers, Dialog — and each would otherwise have\n// written the same surface and the same scrim a second time. Geometry stays\n// with the component: how wide a popover is, which edge a sheet is pinned to,\n// where a dialog sits, are each overlay's own decision.\n//\n// Every one of these is portalled to the end of the body, which is why each\n// component takes a `container` prop and documents the same caveat: an app\n// that scopes its StyleX theme to a subtree has to point the portal inside it,\n// or the surface renders outside the theme and falls back to the tokens'\n// `prefers-color-scheme` default.\n//\n// Entry only, and no exit animation, for the same reason in every overlay:\n// React Aria keeps a closing surface mounted only while an animation is\n// running on it, and a popover in particular is dismissed far more often than\n// it is closed deliberately — usually by pressing something else, where a\n// lingering surface is in the way of whatever the press was for.\n\n// The scrim settles before the panel it sits behind arrives: shorter than\n// any panel's entry, so the two do not finish together.\nconst fadeIn = \"x18re5ia-B\";\n\n// An anchored surface grows from the edge it is anchored by rather than from\n// its own centre, which is what makes it read as coming out of the trigger.\n// The origin is a separate style, chosen from the placement React Aria\n// reports, so the same keyframes serve all four sides.\nconst scaleIn = \"x1k48ry3-B\";\nconst overlay = {\n fromBottom: {\n k3nNDw: \"x18ouj0k\",\n $$css: true\n },\n fromLeft: {\n k3nNDw: \"x1nf803f\",\n $$css: true\n },\n fromRight: {\n k3nNDw: \"xyibjs4\",\n $$css: true\n },\n fromTop: {\n k3nNDw: \"x1dp6rp6\",\n $$css: true\n },\n modalDialog: {\n kZKoxP: \"x5yr21d\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n k3XXqK: \"x1t137rt\",\n $$css: true\n },\n popup: {\n k44tkh: \"xvhm28k x1u6grsq\",\n kKVMdj: \"x97zbip\",\n kyAemX: \"x16dv9tl\",\n kWkggS: \"x1mjdul6\",\n kVAM5u: \"x1w1tqly\",\n kaIpWk: \"x62ce2h\",\n ksu8eU: \"xx61lck\",\n kMzoRj: \"x13rsnn2\",\n kGVxlE: \"x1os83gw\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x139gbkf\",\n kORKVm: \"x1odjw0f\",\n $$css: true\n },\n popupDialog: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kOIVth: \"x126z3so\",\n $$css: true\n },\n scrim: {\n k44tkh: \"x1vhuh8u\",\n kKVMdj: \"xqcmdr3\",\n kyAemX: \"x1yujl0p\",\n kWkggS: \"x1iqbvzf\",\n kB7OPa: \"x9f619\",\n kpwlN0: \"x10a8y8t\",\n kVAEAm: \"xixxii4\",\n $$css: true\n }\n};\n\n// Which side the surface opened on, and the origin its entry grows from.\n// Keyed on the placement React Aria reports rather than the one asked for,\n// since the surface flips to the opposite side when there is no room on its\n// own; `center` is the placement React Aria reports for an anchor it could\n// not place beside, and grows from the top like the default.\nconst origins = {\n bottom: overlay.fromTop,\n center: overlay.fromTop,\n left: overlay.fromRight,\n right: overlay.fromLeft,\n top: overlay.fromBottom\n};\n\n/** Where along that side it lines up with the anchor. */\ntype OverlayAlign = 'center' | 'end' | 'start';\n\n/** Which side of the anchor a surface opens on. */\ntype OverlaySide = 'bottom' | 'left' | 'right' | 'top';\n\n/**\n * React Aria's placement, from the side and the alignment a call site names.\n * Its own vocabulary pairs a side with `top`/`bottom` on the inline sides and\n * `start`/`end` on the block ones; a call site should not have to know which\n * of the two it is asking for, so this maps one onto the other.\n *\n * Shared by every anchored overlay rather than kept in one, since which side\n * a surface opens on is the same question for a popover, a menu and a\n * tooltip.\n */\nfunction placementOf(side: OverlaySide, align: OverlayAlign) {\n if (align === 'center') {\n return side;\n }\n if (side === 'top' || side === 'bottom') {\n return `${side} ${align}` as const;\n }\n return `${side} ${align === 'start' ? 'top' : 'bottom'}` as const;\n}\n\n/**\n * The origin an anchored surface grows from, for the placement React Aria\n * reports through its render state. `null`, before the surface has been\n * placed, grows from the top as `bottom` does.\n */\nfunction popupOrigin(placement: PopoverRenderProps['placement']) {\n return origins[placement ?? 'bottom'];\n}\nexport type { OverlayAlign, OverlaySide };\nexport { overlay, placementOf, popupOrigin };"],"mappings":";AAwCA,MAAMU,UAAU;CACdC,YAAY;EACVC,QAAQ;EACRC,OAAO;CACT;CACAC,UAAU;EACRF,QAAQ;EACRC,OAAO;CACT;CACAE,WAAW;EACTH,QAAQ;EACRC,OAAO;CACT;CACAG,SAAS;EACPJ,QAAQ;EACRC,OAAO;CACT;CACAI,aAAa;EACXC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRT,OAAO;CACT;CACAU,OAAO;EACLC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRb,QAAQ;EACRc,QAAQ;EACRC,QAAQ;EACRrB,OAAO;CACT;CACAsB,aAAa;EACXhB,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRe,QAAQ;EACRvB,OAAO;CACT;CACAwB,OAAO;EACLb,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRR,QAAQ;EACRmB,QAAQ;EACRC,QAAQ;EACR1B,OAAO;CACT;AACF;AAOA,MAAM2B,UAAU;CACdC,QAAQ/B,QAAQM;CAChB0B,QAAQhC,QAAQM;CAChB2B,MAAMjC,QAAQK;CACd6B,OAAOlC,QAAQI;CACf+B,KAAKnC,QAAQC;AACf;;;;;;;;;;;AAkBA,SAASqC,YAAYC,MAAmBC,OAAqB;CAC3D,IAAIA,UAAU,UACZ,OAAOD;CAET,IAAIA,SAAS,SAASA,SAAS,UAC7B,OAAO,GAAGA,KAAI,GAAIC;CAEpB,OAAO,GAAGD,KAAI,GAAIC,UAAU,UAAU,QAAQ;AAChD;;;;;;AAOA,SAASE,YAAYC,WAA4C;CAC/D,OAAOb,QAAQa,aAAa;AAC9B"}
1
+ {"version":3,"file":"overlay.js","names":["PopoverRenderProps","stylex","colors","motion","radii","shadows","spacing","FORCED_COLORS","fadeIn","scaleIn","overlay","fromBottom","k3nNDw","$$css","fromLeft","fromRight","fromTop","modalBodyRing","kjBf7l","kInvED","k3XXqK","kMeerF","modalDialog","kZKoxP","kB7OPa","k1xSpc","kXwgrk","kAzted","popup","k44tkh","kKVMdj","kyAemX","kWkggS","kVAM5u","kaIpWk","ksu8eU","kMzoRj","kGVxlE","kMwMTN","kORKVm","popupDialog","kOIVth","scrim","kpwlN0","kVAEAm","origins","bottom","center","left","right","top","OverlayAlign","OverlaySide","placementOf","side","align","const","popupOrigin","placement"],"sources":["../../src/styles/overlay.ts"],"sourcesContent":["import type { PopoverRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, spacing } 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// What every overlay shares, drawn once. Popover's anchored surface and its\n// entry, Sheet's scrim, and the element that carries the dialog role inside\n// each of them; the coverage plan brings a dozen more overlays — Menu, Select,\n// ComboBox, Tooltip, the date pickers, Dialog — and each would otherwise have\n// written the same surface and the same scrim a second time. Geometry stays\n// with the component: how wide a popover is, which edge a sheet is pinned to,\n// where a dialog sits, are each overlay's own decision.\n//\n// Every one of these is portalled to the end of the body, which is why each\n// component takes a `container` prop and documents the same caveat: an app\n// that scopes its StyleX theme to a subtree has to point the portal inside it,\n// or the surface renders outside the theme and falls back to the tokens'\n// `prefers-color-scheme` default.\n//\n// Entry only, and no exit animation, for the same reason in every overlay:\n// React Aria keeps a closing surface mounted only while an animation is\n// running on it, and a popover in particular is dismissed far more often than\n// it is closed deliberately — usually by pressing something else, where a\n// lingering surface is in the way of whatever the press was for.\n\n// The scrim settles before the panel it sits behind arrives: shorter than\n// any panel's entry, so the two do not finish together.\nconst fadeIn = \"x18re5ia-B\";\n\n// An anchored surface grows from the edge it is anchored by rather than from\n// its own centre, which is what makes it read as coming out of the trigger.\n// The origin is a separate style, chosen from the placement React Aria\n// reports, so the same keyframes serve all four sides.\nconst scaleIn = \"x1k48ry3-B\";\nconst overlay = {\n fromBottom: {\n k3nNDw: \"x18ouj0k\",\n $$css: true\n },\n fromLeft: {\n k3nNDw: \"x1nf803f\",\n $$css: true\n },\n fromRight: {\n k3nNDw: \"xyibjs4\",\n $$css: true\n },\n fromTop: {\n k3nNDw: \"x1dp6rp6\",\n $$css: true\n },\n modalBodyRing: {\n kjBf7l: \"xrgy624\",\n kInvED: \"x2ssjo2\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n $$css: true\n },\n modalDialog: {\n kZKoxP: \"x5yr21d\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kAzted: \"x2lwn1j\",\n k3XXqK: \"x1t137rt\",\n $$css: true\n },\n popup: {\n k44tkh: \"xvhm28k x1u6grsq\",\n kKVMdj: \"x97zbip\",\n kyAemX: \"x16dv9tl\",\n kWkggS: \"x1mjdul6\",\n kVAM5u: \"x1w1tqly\",\n kaIpWk: \"x62ce2h\",\n ksu8eU: \"xx61lck\",\n kMzoRj: \"x13rsnn2\",\n kGVxlE: \"x1os83gw\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x139gbkf\",\n kORKVm: \"x1odjw0f\",\n $$css: true\n },\n popupDialog: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kOIVth: \"x126z3so\",\n $$css: true\n },\n scrim: {\n k44tkh: \"x1vhuh8u\",\n kKVMdj: \"xqcmdr3\",\n kyAemX: \"x1yujl0p\",\n kWkggS: \"x1iqbvzf\",\n kB7OPa: \"x9f619\",\n kpwlN0: \"x10a8y8t\",\n kVAEAm: \"xixxii4\",\n $$css: true\n }\n};\n\n// Which side the surface opened on, and the origin its entry grows from.\n// Keyed on the placement React Aria reports rather than the one asked for,\n// since the surface flips to the opposite side when there is no room on its\n// own; `center` is the placement React Aria reports for an anchor it could\n// not place beside, and grows from the top like the default.\nconst origins = {\n bottom: overlay.fromTop,\n center: overlay.fromTop,\n left: overlay.fromRight,\n right: overlay.fromLeft,\n top: overlay.fromBottom\n};\n\n/** Where along that side it lines up with the anchor. */\ntype OverlayAlign = 'center' | 'end' | 'start';\n\n/** Which side of the anchor a surface opens on. */\ntype OverlaySide = 'bottom' | 'left' | 'right' | 'top';\n\n/**\n * React Aria's placement, from the side and the alignment a call site names.\n * Its own vocabulary pairs a side with `top`/`bottom` on the inline sides and\n * `start`/`end` on the block ones; a call site should not have to know which\n * of the two it is asking for, so this maps one onto the other.\n *\n * Shared by every anchored overlay rather than kept in one, since which side\n * a surface opens on is the same question for a popover, a menu and a\n * tooltip.\n */\nfunction placementOf(side: OverlaySide, align: OverlayAlign) {\n if (align === 'center') {\n return side;\n }\n if (side === 'top' || side === 'bottom') {\n return `${side} ${align}` as const;\n }\n return `${side} ${align === 'start' ? 'top' : 'bottom'}` as const;\n}\n\n/**\n * The origin an anchored surface grows from, for the placement React Aria\n * reports through its render state. `null`, before the surface has been\n * placed, grows from the top as `bottom` does.\n */\nfunction popupOrigin(placement: PopoverRenderProps['placement']) {\n return origins[placement ?? 'bottom'];\n}\nexport type { OverlayAlign, OverlaySide };\nexport { overlay, placementOf, popupOrigin };"],"mappings":";AAwCA,MAAMU,UAAU;CACdC,YAAY;EACVC,QAAQ;EACRC,OAAO;CACT;CACAC,UAAU;EACRF,QAAQ;EACRC,OAAO;CACT;CACAE,WAAW;EACTH,QAAQ;EACRC,OAAO;CACT;CACAG,SAAS;EACPJ,QAAQ;EACRC,OAAO;CACT;CACAI,eAAe;EACbC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRR,OAAO;CACT;CACAS,aAAa;EACXC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRP,QAAQ;EACRP,OAAO;CACT;CACAe,OAAO;EACLC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRb,QAAQ;EACRc,QAAQ;EACRC,QAAQ;EACR1B,OAAO;CACT;CACA2B,aAAa;EACXhB,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRe,QAAQ;EACR5B,OAAO;CACT;CACA6B,OAAO;EACLb,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRR,QAAQ;EACRmB,QAAQ;EACRC,QAAQ;EACR/B,OAAO;CACT;AACF;AAOA,MAAMgC,UAAU;CACdC,QAAQpC,QAAQM;CAChB+B,QAAQrC,QAAQM;CAChBgC,MAAMtC,QAAQK;CACdkC,OAAOvC,QAAQI;CACfoC,KAAKxC,QAAQC;AACf;;;;;;;;;;;AAkBA,SAAS0C,YAAYC,MAAmBC,OAAqB;CAC3D,IAAIA,UAAU,UACZ,OAAOD;CAET,IAAIA,SAAS,SAASA,SAAS,UAC7B,OAAO,GAAGA,KAAI,GAAIC;CAEpB,OAAO,GAAGD,KAAI,GAAIC,UAAU,UAAU,QAAQ;AAChD;;;;;;AAOA,SAASE,YAAYC,WAA4C;CAC/D,OAAOb,QAAQa,aAAa;AAC9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanso-labs/kanso-ui",
3
- "version": "0.34.3",
3
+ "version": "0.34.5",
4
4
  "description": "A React component library built on React Aria Components primitives and styled with StyleX, with design tokens sourced from a single W3C DTCG file and compiled via Style Dictionary",
5
5
  "keywords": [
6
6
  "react",
@@ -74,7 +74,7 @@
74
74
  "@commitlint/cli": "21.2.3",
75
75
  "@commitlint/config-conventional": "21.2.3",
76
76
  "@eslint/js": "10.0.1",
77
- "@kanso-labs/unplugin-style-dictionary": "0.10.6",
77
+ "@kanso-labs/unplugin-style-dictionary": "0.10.7",
78
78
  "@rolldown/plugin-babel": "0.2.4",
79
79
  "@storybook/addon-a11y": "10.6.0",
80
80
  "@storybook/addon-docs": "10.6.0",
@@ -104,7 +104,7 @@
104
104
  "oxc-transform-react": "0.145.0",
105
105
  "oxfmt": "0.70.0",
106
106
  "oxlint": "1.85.0",
107
- "oxlint-tsgolint": "7.0.2002",
107
+ "oxlint-tsgolint": "7.0.2003",
108
108
  "playwright": "1.63.0",
109
109
  "publint": "0.3.24",
110
110
  "react": "19.3.0",
@@ -115,7 +115,7 @@
115
115
  "tsdown": "0.23.0",
116
116
  "typescript": "6.0.3",
117
117
  "typescript-eslint": "8.70.1",
118
- "vite": "8.3.0",
118
+ "vite": "8.3.1",
119
119
  "vitest": "4.1.11"
120
120
  },
121
121
  "peerDependencies": {