@kanso-labs/kanso-ui 0.44.1 → 0.45.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.
- package/README.md +59 -7
- package/dist/chip/index.js +24 -4
- package/dist/chip/index.js.map +1 -1
- package/dist/chip/styles.js +13 -5
- package/dist/chip/styles.js.map +1 -1
- package/dist/components/app-bar/index.d.ts +14 -2
- package/dist/components/app-bar/index.js +36 -7
- package/dist/components/app-bar/index.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +44 -0
- package/dist/components/autocomplete/index.js +44 -0
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/button/index.d.ts +3 -2
- package/dist/components/button/index.js +53 -59
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/card/index.d.ts +11 -3
- package/dist/components/card/index.js +23 -1
- package/dist/components/card/index.js.map +1 -1
- package/dist/components/checkbox/index.js +65 -58
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/chip/index.d.ts +46 -30
- package/dist/components/chip/index.js +38 -17
- package/dist/components/chip/index.js.map +1 -1
- package/dist/components/chip-group/index.d.ts +5 -2
- package/dist/components/chip-group/index.js +8 -2
- package/dist/components/chip-group/index.js.map +1 -1
- package/dist/components/dialog/index.d.ts +27 -0
- package/dist/components/dialog/index.js +81 -37
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/fab/index.d.ts +1 -1
- package/dist/components/fab/index.js.map +1 -1
- package/dist/components/form/index.d.ts +14 -4
- package/dist/components/form/index.js +6 -3
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +15 -1
- package/dist/components/icon-button/index.js +15 -1
- package/dist/components/icon-button/index.js.map +1 -1
- package/dist/components/link/index.d.ts +4 -0
- package/dist/components/link/index.js +4 -0
- package/dist/components/link/index.js.map +1 -1
- package/dist/components/list/index.d.ts +34 -0
- package/dist/components/list/index.js +47 -13
- package/dist/components/list/index.js.map +1 -1
- package/dist/components/list-detail/index.d.ts +34 -1
- package/dist/components/list-detail/index.js +34 -1
- package/dist/components/list-detail/index.js.map +1 -1
- package/dist/components/list-item/index.d.ts +21 -2
- package/dist/components/list-item/index.js +6 -0
- package/dist/components/list-item/index.js.map +1 -1
- package/dist/components/menu/index.d.ts +6 -3
- package/dist/components/menu/index.js +3 -1
- package/dist/components/menu/index.js.map +1 -1
- package/dist/components/meter/index.d.ts +4 -0
- package/dist/components/meter/index.js +4 -0
- package/dist/components/meter/index.js.map +1 -1
- package/dist/components/navigation-bar/index.d.ts +14 -2
- package/dist/components/navigation-bar/index.js +14 -2
- package/dist/components/navigation-bar/index.js.map +1 -1
- package/dist/components/navigation-tree/index.js +2 -9
- package/dist/components/navigation-tree/index.js.map +1 -1
- package/dist/components/number-field/index.d.ts +7 -1
- package/dist/components/number-field/index.js +7 -1
- package/dist/components/number-field/index.js.map +1 -1
- package/dist/components/popover/index.d.ts +15 -1
- package/dist/components/popover/index.js +15 -1
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/product-icon/index.d.ts +8 -1
- package/dist/components/product-icon/index.js +8 -1
- package/dist/components/product-icon/index.js.map +1 -1
- package/dist/components/progress-indicator/index.d.ts +12 -6
- package/dist/components/progress-indicator/index.js +57 -46
- package/dist/components/progress-indicator/index.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +7 -0
- package/dist/components/radio-group/index.js +23 -14
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/search-field/index.d.ts +13 -4
- package/dist/components/search-field/index.js +10 -4
- package/dist/components/search-field/index.js.map +1 -1
- package/dist/components/search-view/index.d.ts +2 -0
- package/dist/components/search-view/index.js.map +1 -1
- package/dist/components/segmented-button/index.d.ts +1 -1
- package/dist/components/segmented-button/index.js.map +1 -1
- package/dist/components/separator/index.d.ts +31 -6
- package/dist/components/separator/index.js +30 -6
- package/dist/components/separator/index.js.map +1 -1
- package/dist/components/sheet/index.d.ts +96 -37
- package/dist/components/sheet/index.js +420 -136
- package/dist/components/sheet/index.js.map +1 -1
- package/dist/components/snackbar/index.d.ts +8 -1
- package/dist/components/snackbar/index.js +7 -0
- package/dist/components/snackbar/index.js.map +1 -1
- package/dist/components/stack/index.d.ts +21 -5
- package/dist/components/stack/index.js +10 -0
- package/dist/components/stack/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +12 -0
- package/dist/components/switch/index.js +12 -0
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/text-field/index.d.ts +39 -9
- package/dist/components/text-field/index.js +29 -7
- package/dist/components/text-field/index.js.map +1 -1
- package/dist/components/tree/index.js +11 -15
- package/dist/components/tree/index.js.map +1 -1
- package/dist/hooks/useBottomEdge.js +6 -3
- package/dist/hooks/useBottomEdge.js.map +1 -1
- package/dist/hooks/useRipple.js +216 -192
- package/dist/hooks/useRipple.js.map +1 -1
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/messages.js +34 -0
- package/dist/i18n/messages.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/indicator/styles.js +7 -4
- package/dist/indicator/styles.js.map +1 -1
- package/dist/mark/styles.js +11 -5
- package/dist/mark/styles.js.map +1 -1
- package/dist/react-aria.d.ts +2 -2
- package/dist/row/index.js +90 -62
- package/dist/row/index.js.map +1 -1
- package/dist/row/styles.js +6 -1
- package/dist/row/styles.js.map +1 -1
- package/dist/styles/focus.js.map +1 -1
- package/dist/styles/overlay.js +8 -0
- package/dist/styles/overlay.js.map +1 -1
- package/dist/styles.css +135 -114
- package/dist/theme-scope.d.ts +14 -2
- package/dist/theme-scope.js +12 -0
- package/dist/theme-scope.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["c","_c","Ref","RefAttributes","SearchFieldProps","RACSearchFieldProps","SearchFieldRenderProps","stylex","FieldInputContext","Label","SearchField","RACSearchField","useSlottedContext","VisuallyHidden","FieldInput","FieldMessage","focusesControl","fieldStyles","invalidFrom","useFieldValidationBehavior","CloseGlyph","SearchGlyph","mergeStatefulStyles","colors","motion","radii","sizing","spacing","stateLayerOpacity","IconButton","FORCED_COLORS","HOVER_CAPABLE","clearLabel","description","enterKeyHint","error","inputRef","HTMLInputElement","label","placeholder","Omit","fieldContent","state","undefined","className","isInvalid","isDisabled","isEmpty","t0","$","t1","props","validationBehavior","inherited","T0","t2","t3","t4","root","t5","t6","SearchField","_c","props","RACSearchField","stylex.props"],"sources":["../../../src/components/search-field/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport type { SearchFieldProps as RACSearchFieldProps, SearchFieldRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { FieldInputContext, Label, SearchField as RACSearchField, useSlottedContext, VisuallyHidden } from 'react-aria-components';\nimport { FieldInput, FieldMessage } from '../../field';\nimport { focusesControl } from '../../field/press';\nimport { fieldStyles, invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CloseGlyph, SearchGlyph } from '../../glyphs';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, spacing, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\nimport IconButton from '../icon-button';\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// A pointer that can hover: a mouse or a trackpad, not a finger. The bar is a\n// plain element around the input rather than a part React Aria hosts, so its\n// hover layer is a pseudo-class, and Chromium leaves `:hover` on whatever a\n// touch last tapped. Inside this query a touch screen draws no hover at all;\n// a touchscreen laptop still matches it for its trackpad.\nconst HOVER_CAPABLE = '@media (hover: hover)';\n\n// The search page's search bar, on its own: a 56dp container with a full\n// corner on surface container high, a 24dp magnifier in on surface variant\n// at the start, the supporting text in on surface variant and the input\n// text in on surface, both body-large, and a trailing icon button in on\n// surface variant that clears the field while it holds anything. The page's\n// 16dp of padding is to a 48dp tap target, and the icon sits 12dp inside\n// that, so the magnifier starts 28dp in and the text 4dp past the target,\n// at 68dp; the clear button is the medium icon button, 40dp around a 24dp\n// icon, set 4dp in from the padding so its icon ends 28dp from the end. The\n// container follows its own width up to the page's 720dp; the page's 360dp\n// floor is left to the call site, since a phone's width less its margins is\n// under it. The list of suggestions the page draws under the bar is\n// Autocomplete's, and nothing here.\n//\n// The page's hovered and pressed states are on surface state layers over\n// the container, at the opacities the tokens hold. It names a focused state\n// and draws nothing for it, so the bar takes the 2dp primary ring the text\n// fields page gives a focused field, drawn inside the pill as a shadow for\n// the reason the chrome's box draws its underline that way: a shadow\n// changes nothing about the bar's size, and clipped to the corner it stays\n// inside the pill. It shows on any focus, as the underline does; a text\n// control matches `:focus-visible` on every focus anyway. Disabled takes\n// the chrome's dimmed container and content, since the page has no disabled\n// state and the sibling fields already agree on one.\n//\n// React Aria's `SearchField` is the root, a div holding the label,\n// description and error slots and the clear button's context; the bar is\n// its own element around the field chrome's input, and the label is\n// visually hidden, since the bar carries no label of its own and the\n// supporting text is what a person reads.\n\ntype SearchFieldProps = {\n /**\n * The name of the button that clears the field, for a screen reader.\n * Left out, React Aria names it in the reader's locale — \"Clear search\" in\n * English.\n */\n clearLabel?: string;\n /**\n * A hint shown under the bar. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The action an on-screen keyboard labels its Enter key with. A search\n * field asks for Search, which iOS otherwise shows only for a search input\n * inside a form with an action, so a field submitted through `onSubmit`\n * alone gets it too. Inside an `Autocomplete` the field takes the Go key\n * React Aria gives it there, for the option Enter picks.\n *\n * @default 'search'\n */\n enterKeyHint?: RACSearchFieldProps['enterKeyHint'];\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * A ref to the field's own `<input>`, which is the element a call site moves\n * focus to — after a server's error, say. `ref` is the field as a whole.\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * What the field searches, for a screen reader. The bar draws no label,\n * so this is read and never shown; `placeholder` is what is seen.\n */\n label: string;\n /** The supporting text in the empty bar, which is what a person reads. */\n placeholder?: string;\n} & Omit<RACSearchFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n// What the bar draws, from the field's render state: the clear button only\n// while the field holds something, and the error ring while it is invalid. Built by a call rather than written\n// inline at the prop, which is what react-perf's no-new-function-as-prop is\n// after; the React Compiler memoises the result on its inputs.\n//\n// A press anywhere on the bar focuses the input, as a press anywhere on the\n// box of every other field does. The bar is 56dp and the input's line 24dp\n// of it, so the magnifier, the padding at either end and the strips above\n// and below the text took a press, darkened the bar for it, and focused\n// nothing. A press on the input itself or on the clear button is left to\n// them, and a disabled field takes none.\nfunction fieldContent(label: string, placeholder: string | undefined, clearLabel: string | undefined, description: string | undefined, error: string | undefined, inputRef: Ref<HTMLInputElement> | undefined) {\n return (state: SearchFieldRenderProps) => <>\n <VisuallyHidden>\n <Label>{label}</Label>\n </VisuallyHidden>\n <div onPointerDown={focusesControl(undefined)} {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 x5u4zhu x17m4uoy xuwmtp3 xmaqtb8 x9qvdww x42wrt3 xvkjz1l xs1ryiz x1ylmb6m x1dkaolv xx61lck x13rsnn2 x19i8hm1 x1gnnqk1 x9f619 x1w5n3ug x1ed109x x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7\"\n },\n 2: {\n className: \"x12w9bfk x6s0dn4 x5u4zhu x17m4uoy xuwmtp3 xmaqtb8 x9qvdww x42wrt3 xvkjz1l xs1ryiz x1ylmb6m x1dkaolv xx61lck x13rsnn2 x9f619 x1w5n3ug x1ed109x x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 x1bll8u6 x19irva8\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 xs1ryiz x1dkaolv xx61lck x13rsnn2 x9f619 x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 xepofeg xmnqt3w x1gnnqk1 x1xj74d8 x1bhcspo x1h6gzvc\"\n },\n 3: {\n className: \"x12w9bfk x6s0dn4 xs1ryiz x1dkaolv xx61lck x13rsnn2 x9f619 x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 xepofeg xmnqt3w x1gnnqk1 x1xj74d8 x1bhcspo x1h6gzvc\"\n }\n }[!!state.isInvalid << 1 | !!state.isDisabled << 0]}>\n <SearchGlyph className=\"xxk0z11 x1lliihq x2lah0s xvy4d1p\" />\n <FieldInput placeholder={placeholder} ref={inputRef} className=\"x1hcrkkg xzwh6sb xjyslct xmper1u x1iyjqo2 xeuugli\" />\n {state.isEmpty ? null : <IconButton aria-label={clearLabel} className=\"x15ir4sr\">\n <CloseGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>}\n </div>\n <FieldMessage description={description} error={error} />\n </>;\n}\n\n/**\n * A search bar: a keyword typed into a pill, submitted with Enter and\n * cleared with Escape or its button. Its value is React Aria's: pass\n * `value` with `onChange` to control it, or `defaultValue` to let it keep\n * its own; `onSubmit` is handed the value on Enter and `onClear` is called\n * when it is emptied.\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions. The input and the message are\n * the field chrome in `src/field`, shared with every other field; the bar\n * around them is the search page's rather than the box the other fields\n * share.\n */\nfunction SearchField({\n clearLabel,\n description,\n enterKeyHint,\n error,\n inputRef,\n isDisabled = false,\n label,\n placeholder,\n ...props\n}: RefAttributes<HTMLDivElement> & SearchFieldProps) {\n const validationBehavior = useFieldValidationBehavior();\n // An Autocomplete hands its input `go` through this context, and a prop\n // written here would replace it, so the default steps aside for it; an\n // undefined prop leaves the context's value standing.\n const inherited = useSlottedContext(FieldInputContext)?.enterKeyHint;\n return <RACSearchField enterKeyHint={enterKeyHint ?? (inherited === undefined ? 'search' : undefined)} isDisabled={isDisabled} isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(fieldStyles.root), props)}>\n {fieldContent(label, placeholder, clearLabel, description, error, inputRef)}\n </RACSearchField>;\n}\nexport type { SearchFieldProps };\nexport default SearchField;"],"mappings":";;;;;;;;;;;;AAoHA,SAASyC,aAAaH,OAAeC,aAAiCP,YAAgCC,aAAiCE,OAA2BC,UAA6C;CAC7M,QAAQM,UAAkC,qBAAA,UAAA,EAAA,UAAA;EACtC,oBAAC,gBAAD,EAAA,UACE,oBAAC,OAAD,EAAA,UAAQJ,MAAa,CAAA,EACP,CAAA;EAChB,qBAAC,OAAD;GAAK,eAAetB,eAAe2B,KAAAA,CAAS;GAAG,GAAI;IACnD,GAAG,EACDC,WAAW,gRACb;IACA,GAAG,EACDA,WAAW,gRACb;IACA,GAAG,EACDA,WAAW,8NACb;IACA,GAAG,EACDA,WAAW,8NACb;GACF,EAAE,CAAC,CAACF,MAAMG,aAAa,IAAI,CAAC,CAACH,MAAMI,cAAc;GAb/C,UAAA;IAcE,oBAAC,aAAD,EAAa,WAAU,mCAAkC,CAAA;IACzD,oBAAC,YAAD;KAAyBP;KAAa,KAAKH;KAAU,WAAU;IAAmD,CAAA;IACjHM,MAAMK,UAAU,OAAO,oBAAC,YAAD;KAAY,cAAYf;KAAY,WAAU;KAClE,UAAA,oBAAC,YAAD,EAAY,WAAU,4BAA2B,CAAA;IACvC,CAAA;GACX;;EACL,oBAAC,cAAD;GAA2BC;GAAoBE;EAAM,CAAA;CACvD,EAAA,CAAA;AACJ;;;;;;;;;;;;;;AAeA,SAAAzB,cAAAsC,IAAA;CAAA,MAAAC,IAAAhD,EAAA,EAAA;CAAqB,MAAA,EAAA+B,YAAAC,aAAAC,cAAAC,OAAAC,UAAAU,YAAAI,IAAAZ,OAAAC,aAAA,GAAAY,YAAAH;CAMnB,MAAAF,aAAAI,OAAAP,KAAAA,IAAA,QAAAO;CAKA,MAAAE,qBAA2BjC,2BAA2B;CAItD,MAAAkC,YAAkBzC,kBAAkBJ,iBAA+B,CAAC,EAAA0B;CAC5D,MAAAoB,KAAA3C;CAA6B,MAAA4C,KAAArB,iBAAiBmB,cAAcV,KAAAA,IAAd,WAAAA,KAAAA;CAA+C,IAAAa;CAAA,IAAAP,EAAA,OAAAd,OAAA;EAAqCqB,KAAAtC,YAAYiB,KAAK;EAACc,EAAA,KAAAd;EAAAc,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAyD,MAAAQ,KAAAnC,oBAAoBf,MAAaU,YAAWyC,IAAK,GAAGP,OAAK;CAAC,IAAAQ;CAAA,IAAAV,EAAA,OAAAjB,cAAAiB,EAAA,OAAAhB,eAAAgB,EAAA,OAAAd,SAAAc,EAAA,OAAAb,YAAAa,EAAA,OAAAX,SAAAW,EAAA,OAAAV,aAAA;EAC1QoB,KAAAlB,aAAaH,OAAOC,aAAaP,YAAYC,aAAaE,OAAOC,QAAQ;EAACa,EAAA,KAAAjB;EAAAiB,EAAA,KAAAhB;EAAAgB,EAAA,KAAAd;EAAAc,EAAA,KAAAb;EAAAa,EAAA,KAAAX;EAAAW,EAAA,KAAAV;EAAAU,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,IAAAW;CAAA,IAAAX,EAAA,OAAAK,MAAAL,EAAA,QAAAH,cAAAG,EAAA,QAAAE,WAAAF,EAAA,QAAAM,MAAAN,EAAA,QAAAO,MAAAP,EAAA,QAAAQ,MAAAR,EAAA,QAAAU,MAAAV,EAAA,QAAAG,oBAAA;EADxEQ,KAAA,oBAAC,IAAD;GAA8B,cAAAL;GAA8ET;GAAuB,WAAAU;GAAwCJ;GAAkB,GAAMD;GAAK,GAAMM;GAChNE,UAAAA;EADiB,CAAA;EAEHV,EAAA,KAAAK;EAAAL,EAAA,MAAAH;EAAAG,EAAA,MAAAE;EAAAF,EAAA,MAAAM;EAAAN,EAAA,MAAAO;EAAAP,EAAA,MAAAQ;EAAAR,EAAA,MAAAU;EAAAV,EAAA,MAAAG;EAAAH,EAAA,MAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,OAFZW;AAEY"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["c","_c","Ref","RefAttributes","SearchFieldProps","RACSearchFieldProps","SearchFieldRenderProps","stylex","FieldInputContext","Label","SearchField","RACSearchField","useSlottedContext","VisuallyHidden","FieldInput","FieldMessage","focusesControl","fieldStyles","invalidFrom","useFieldValidationBehavior","CloseGlyph","SearchGlyph","mergeStatefulStyles","colors","motion","radii","sizing","spacing","stateLayerOpacity","IconButton","FORCED_COLORS","HOVER_CAPABLE","clearLabel","description","enterKeyHint","error","inputRef","HTMLInputElement","label","placeholder","Omit","fieldContent","state","undefined","className","isInvalid","isDisabled","isEmpty","t0","$","t1","props","validationBehavior","inherited","T0","t2","t3","t4","root","t5","t6","SearchField","_c","props","RACSearchField","stylex.props"],"sources":["../../../src/components/search-field/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport type { SearchFieldProps as RACSearchFieldProps, SearchFieldRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { FieldInputContext, Label, SearchField as RACSearchField, useSlottedContext, VisuallyHidden } from 'react-aria-components';\nimport { FieldInput, FieldMessage } from '../../field';\nimport { focusesControl } from '../../field/press';\nimport { fieldStyles, invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CloseGlyph, SearchGlyph } from '../../glyphs';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, spacing, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\nimport IconButton from '../icon-button';\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// A pointer that can hover: a mouse or a trackpad, not a finger. The bar is a\n// plain element around the input rather than a part React Aria hosts, so its\n// hover layer is a pseudo-class, and Chromium leaves `:hover` on whatever a\n// touch last tapped. Inside this query a touch screen draws no hover at all;\n// a touchscreen laptop still matches it for its trackpad.\nconst HOVER_CAPABLE = '@media (hover: hover)';\n\n// The search page's search bar, on its own: a 56dp container with a full\n// corner on surface container high, a 24dp magnifier in on surface at the\n// start, the supporting text in on surface variant and the input text in on\n// surface, both body-large, and a trailing icon button in on surface\n// variant that clears the field while it holds anything. The page's\n// 16dp of padding is to a 48dp tap target, and the icon sits 12dp inside\n// that, so the magnifier starts 28dp in and the text 4dp past the target,\n// at 68dp; the clear button is the medium icon button, 40dp around a 24dp\n// icon, set 4dp in from the padding so its icon ends 28dp from the end. The\n// container follows its own width up to the page's 720dp; the page's 360dp\n// floor is left to the call site, since a phone's width less its margins is\n// under it. The list of suggestions the page draws under the bar is\n// Autocomplete's, and nothing here.\n//\n// The page gives the container level 3 elevation, and the bar casts no\n// shadow for it. Surface container high is the tone that level stands for,\n// and Google's own search bars draw it so: Compose's defaults give the bar\n// a shadow elevation of level 0, and the Android library keeps its 6dp but\n// makes the shadow transparent. The docked SearchView, which floats over\n// the page, is what casts level 3.\n//\n// The page's hovered and pressed states are on surface state layers over\n// the container, at the opacities the tokens hold. It names a focused state\n// and draws nothing for it, so the bar takes the 2dp primary ring the text\n// fields page gives a focused field, drawn inside the pill as a shadow for\n// the reason the chrome's box draws its underline that way: a shadow\n// changes nothing about the bar's size, and clipped to the corner it stays\n// inside the pill. It shows on any focus, as the underline does; a text\n// control matches `:focus-visible` on every focus anyway. Disabled takes\n// the chrome's dimmed container and content, since the page has no disabled\n// state and the sibling fields already agree on one.\n//\n// React Aria's `SearchField` is the root, a div holding the label,\n// description and error slots and the clear button's context; the bar is\n// its own element around the field chrome's input, and the label is\n// visually hidden, since the bar carries no label of its own and the\n// supporting text is what a person reads.\n\ntype SearchFieldProps = {\n /**\n * The name of the button that clears the field, for a screen reader.\n * Left out, React Aria names it in the reader's locale — \"Clear search\" in\n * English.\n */\n clearLabel?: string;\n /**\n * A hint shown under the bar. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The action an on-screen keyboard labels its Enter key with. A search\n * field asks for Search, which iOS otherwise shows only for a search input\n * inside a form with an action, so a field submitted through `onSubmit`\n * alone gets it too. Inside an `Autocomplete` the field takes the Go key\n * React Aria gives it there, for the option Enter picks.\n *\n * @default 'search'\n */\n enterKeyHint?: RACSearchFieldProps['enterKeyHint'];\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * A ref to the field's own `<input>`, which is the element a call site moves\n * focus to — after a server's error, say. `ref` is the field as a whole.\n */\n inputRef?: Ref<HTMLInputElement>;\n /**\n * What the field searches, for a screen reader. The bar draws no label,\n * so this is read and never shown; `placeholder` is what is seen.\n *\n * Write it so it contains the placeholder's words — `Search` beside a\n * `Search` placeholder, or `Search people`. The placeholder is the only\n * text a sighted reader has to call the field by, so it is what someone\n * driving the page by voice says, and a name that does not contain it\n * leaves them nothing to say.\n */\n label: string;\n /** The supporting text in the empty bar, which is what a person reads. */\n placeholder?: string;\n} & Omit<RACSearchFieldProps, 'children' | 'enterKeyHint' | 'isInvalid' | 'validationBehavior'>;\n\n// What the bar draws, from the field's render state: the clear button only\n// while the field holds something, and the error ring while it is invalid. Built by a call rather than written\n// inline at the prop, which is what react-perf's no-new-function-as-prop is\n// after; the React Compiler memoises the result on its inputs.\n//\n// A press anywhere on the bar focuses the input, as a press anywhere on the\n// box of every other field does. The bar is 56dp and the input's line 24dp\n// of it, so the magnifier, the padding at either end and the strips above\n// and below the text took a press, darkened the bar for it, and focused\n// nothing. A press on the input itself or on the clear button is left to\n// them, and a disabled field takes none.\nfunction fieldContent(label: string, placeholder: string | undefined, clearLabel: string | undefined, description: string | undefined, error: string | undefined, inputRef: Ref<HTMLInputElement> | undefined) {\n return (state: SearchFieldRenderProps) => <>\n <VisuallyHidden>\n <Label>{label}</Label>\n </VisuallyHidden>\n <div onPointerDown={focusesControl(undefined)} {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 x5u4zhu x17m4uoy xuwmtp3 xmaqtb8 x9qvdww x42wrt3 xvkjz1l xs1ryiz x1ylmb6m x1dkaolv xx61lck x13rsnn2 x19i8hm1 x1gnnqk1 x9f619 x1w5n3ug x1ed109x x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7\"\n },\n 2: {\n className: \"x12w9bfk x6s0dn4 x5u4zhu x17m4uoy xuwmtp3 xmaqtb8 x9qvdww x42wrt3 xvkjz1l xs1ryiz x1ylmb6m x1dkaolv xx61lck x13rsnn2 x9f619 x1w5n3ug x1ed109x x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 x1bll8u6 x19irva8\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 xs1ryiz x1dkaolv xx61lck x13rsnn2 x9f619 x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 xepofeg xmnqt3w x1gnnqk1 x1xj74d8 x1bhcspo x1h6gzvc\"\n },\n 3: {\n className: \"x12w9bfk x6s0dn4 xs1ryiz x1dkaolv xx61lck x13rsnn2 x9f619 x78zum5 xxj4525 xh8yej3 xwnkcuf x1x84bn5 x12iqurn xi9ts3s x1jrff4x x1glmgrm xtrd051 x1qno0dh x106061f xpc4ca7 xepofeg xmnqt3w x1gnnqk1 x1xj74d8 x1bhcspo x1h6gzvc\"\n }\n }[!!state.isInvalid << 1 | !!state.isDisabled << 0]}>\n <SearchGlyph {...{\n 0: {\n className: \"xxk0z11 x139gbkf x1lliihq x2lah0s xvy4d1p\"\n },\n 1: {\n className: \"xxk0z11 x1lliihq x2lah0s xvy4d1p x1heor9g\"\n }\n }[!!state.isDisabled << 0]} />\n <FieldInput placeholder={placeholder} ref={inputRef} className=\"x1hcrkkg xzwh6sb xjyslct xmper1u x1iyjqo2 xeuugli\" />\n {state.isEmpty ? null : <IconButton aria-label={clearLabel} className=\"x15ir4sr\">\n <CloseGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>}\n </div>\n <FieldMessage description={description} error={error} />\n </>;\n}\n\n/**\n * A search bar: a keyword typed into a pill, submitted with Enter and\n * cleared with Escape or its button. Its value is React Aria's: pass\n * `value` with `onChange` to control it, or `defaultValue` to let it keep\n * its own; `onSubmit` is handed the value on Enter and `onClear` is called\n * when it is emptied.\n *\n * ```tsx\n * <SearchField label=\"Search\" onSubmit={search} placeholder=\"Search\" />\n * ```\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions. The input and the message are\n * drawn as every field in the library draws them; the pill around them is\n * Material Design's search bar rather than the box of its text fields.\n */\nfunction SearchField({\n clearLabel,\n description,\n enterKeyHint,\n error,\n inputRef,\n isDisabled = false,\n label,\n placeholder,\n ...props\n}: RefAttributes<HTMLDivElement> & SearchFieldProps) {\n const validationBehavior = useFieldValidationBehavior();\n // An Autocomplete hands its input `go` through this context, and a prop\n // written here would replace it, so the default steps aside for it; an\n // undefined prop leaves the context's value standing.\n const inherited = useSlottedContext(FieldInputContext)?.enterKeyHint;\n return <RACSearchField enterKeyHint={enterKeyHint ?? (inherited === undefined ? 'search' : undefined)} isDisabled={isDisabled} isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(fieldStyles.root), props)}>\n {fieldContent(label, placeholder, clearLabel, description, error, inputRef)}\n </RACSearchField>;\n}\nexport type { SearchFieldProps };\nexport default SearchField;"],"mappings":"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"}
|
|
@@ -28,6 +28,8 @@ type SearchViewContentProps<T extends object = object> = {
|
|
|
28
28
|
/**
|
|
29
29
|
* What is searched, for a screen reader. It names both the view and its
|
|
30
30
|
* input, and is read rather than shown; `placeholder` is what is seen.
|
|
31
|
+
* Write it so it contains the placeholder's words, as SearchField's
|
|
32
|
+
* `label` explains.
|
|
31
33
|
*/
|
|
32
34
|
label: string;
|
|
33
35
|
/** The supporting text in the empty input, which is what a person reads. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","ClassNameOrFunction","DialogTriggerProps","PopoverRenderProps","SearchFieldRenderProps","StyleOrFunction","stylex","Dialog","DialogTrigger","Label","Popover","RACPopover","SearchField","RACSearchField","VisuallyHidden","AutocompleteProps","FieldInput","ArrowBackGlyph","CloseGlyph","useMessages","mergeStatefulStyles","overlay","colors","media","radii","shadows","sizing","spacing","Autocomplete","IconButton","SIDE_OFFSET","styles","view","kWkggS","kZKoxP","kaIpWk","kGVxlE","k1xSpc","kXwgrk","kzqmXN","krVfgx","k87sOh","kt4wiu","kLqNvP","kskxy","ks0D6T","kVQacm","kVAEAm","$$css","SearchViewContentProps","backLabel","children","className","clearLabel","container","Element","label","placeholder","style","Omit","T","SearchViewProps","fieldContent","state","isEmpty","SearchView","t0","$","props","t1","SearchViewContent","ref","messages","popup","t2","back","t3","Symbol","for","t4","t5","t6","t7","t8","t9","t10","t11","t12","Content","_c","props","stylex.props","RACSearchField","Autocomplete","RACPopover"],"sources":["../../../src/components/search-view/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { ClassNameOrFunction, DialogTriggerProps, PopoverRenderProps, SearchFieldRenderProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Dialog, DialogTrigger, Label, Popover as RACPopover, SearchField as RACSearchField, VisuallyHidden } from 'react-aria-components';\nimport type { AutocompleteProps } from '../autocomplete';\nimport { FieldInput } from '../../field';\nimport { ArrowBackGlyph, CloseGlyph } from '../../glyphs';\nimport { useMessages } from '../../i18n';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport { overlay } from '../../styles/overlay';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, media, radii, shadows, sizing, spacing } from '../../tokens/design.tokens.stylex';\nimport Autocomplete from '../autocomplete';\nimport IconButton from '../icon-button';\n\n// The search page's search view: what a search opens into. A header holds a\n// back button, the input and a clear button, over a 1dp divider in the\n// outline role, and the results run under it. Both of the page's forms are\n// surface container high, with the input in body-large on surface over a\n// supporting text in on surface variant, the back icon in on surface and the\n// clear icon in on surface variant.\n//\n// **Which form is the window's.** Below the medium breakpoint it is the\n// page's full-screen view: the whole window, square, with a 72dp header.\n// Above it, the docked view: dropped under what opened it, as wide as that\n// and held between the page's 360dp and 720dp, with a 28dp corner, a 56dp\n// header, results at least 240dp tall and the whole view no taller than two\n// thirds of the window, at elevation 3 — Compose's measurements for its\n// docked search bar, which the page draws without numbers. The swap is the\n// date pickers' — see `src/styles/picker.ts`: React Aria places the surface\n// with inline styles, which a class outranks only with `!important`, so the\n// full-screen form takes it on the edges, the position and the size, and\n// above the breakpoint this says nothing about any of them.\n//\n// **It is Autocomplete in an overlay.** The header's input and the results\n// are Autocomplete's two halves, so typing narrows the results as it does\n// anywhere else, and the results are the call site's ListBox or Menu.\n// Autocomplete still renders nothing of its own; this is the element around\n// it.\n//\n// **The header lines up with the search bar's.** The back button sits where\n// the bar's magnifier does, its icon 28dp in, and the text starts at 68dp,\n// as the bar's does; the clear button's icon ends 28dp from the end. So a\n// view opened from a bar puts its input where the bar's was.\n//\n// Composed as Popover is: `SearchView` holds the open state, a Button or\n// IconButton placed directly inside it opens the view, and\n// `SearchView.Content` is the view. The back button closes it, as Escape and\n// a press outside the docked view do.\n\n// The gap between what opened the view and the docked view, Popover's.\nconst SIDE_OFFSET = 8;\nconst styles = {\n view: {\n kWkggS: \"xvkjz1l\",\n kZKoxP: \"x16m7gpl\",\n kaIpWk: \"x19pkqky xxl0i3l\",\n kGVxlE: \"x1udv5rz xzvmenf\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kzqmXN: \"xd4ksm1 x14gilbs\",\n krVfgx: \"xudx362\",\n k87sOh: \"xbvrusa\",\n kt4wiu: \"x1v0tev1\",\n kLqNvP: \"x12sfaok\",\n kskxy: \"x10iheve\",\n ks0D6T: \"x16xn7b0 x6iovhr\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1mesnot\",\n $$css: true\n }\n};\ntype SearchViewContentProps<T extends object = object> = {\n /**\n * What the back button is called, for a screen reader. Left out, the\n * library names it in the reader's locale — \"Back\" in English.\n */\n backLabel?: string;\n /** The results: a ListBox or a Menu, which typing narrows. */\n children?: ReactNode;\n /** A function may compute the class from the view's render state. */\n className?: ClassNameOrFunction<PopoverRenderProps>;\n /**\n * What the clear button is called, for a screen reader. Left out, React\n * Aria names it in the reader's locale — \"Clear search\" in English.\n */\n clearLabel?: string;\n /**\n * Where to portal the view. Defaults to the container of the `ThemeScope`\n * around it, which keeps the view on that scope's tokens, or to the end of\n * `<body>` where there is none. A subtree themed through the `themeScope`\n * class has no container of its own, so point this inside it, or the view\n * renders outside and keeps the page's tokens.\n */\n container?: Element;\n /**\n * What is searched, for a screen reader. It names both the view and its\n * input, and is read rather than shown; `placeholder` is what is seen.\n */\n label: string;\n /** The supporting text in the empty input, which is what a person reads. */\n placeholder?: string;\n /** A function may compute the style from the view's render state. */\n style?: StyleOrFunction<PopoverRenderProps>;\n} & Omit<AutocompleteProps<T>, 'children'>;\ntype SearchViewProps = Omit<DialogTriggerProps, 'children'> & {\n /**\n * The Button or IconButton that opens the view, and `SearchView.Content`.\n */\n children?: ReactNode;\n};\n\n// What the field draws, from its render state: the clear button only while\n// it holds something. Built by a call rather than written inline at the\n// prop, which is what react-perf's no-new-function-as-prop is after.\nfunction fieldContent(label: string, placeholder: string | undefined, clearLabel: string | undefined) {\n return (state: SearchFieldRenderProps) => <>\n <VisuallyHidden>\n <Label>{label}</Label>\n </VisuallyHidden>\n <FieldInput\n // oxlint-disable-next-line jsx-a11y/no-autofocus -- a search view opens to be typed into, so the input takes focus rather than the back button the dialog would otherwise start on\n autoFocus placeholder={placeholder} className=\"x1hcrkkg xzwh6sb xjyslct x1iyjqo2 xeuugli\" />\n {state.isEmpty ? null : <IconButton aria-label={clearLabel} className=\"x15ir4sr\">\n <CloseGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>}\n </>;\n}\n\n/**\n * The view a search opens into: full screen on a compact window, docked\n * under what opened it on a wider one. Open state is React Aria's: pass\n * `isOpen` with `onOpenChange` to control it, or `defaultOpen` to let it keep\n * its own.\n *\n * ```tsx\n * <SearchView>\n * <IconButton aria-label=\"Search\"><SearchIcon /></IconButton>\n * <SearchView.Content label=\"Search\" placeholder=\"Search\">\n * <ListBox aria-label=\"Results\">…</ListBox>\n * </SearchView.Content>\n * </SearchView>\n * ```\n *\n * A Button or IconButton placed directly inside opens the view;\n * `SearchView.Content` is the view itself.\n */\nfunction SearchView({\n children,\n ...props\n}: SearchViewProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\n\n/**\n * The view: the header with its back button, input and clear button, and\n * the results under it, inside React Aria's Autocomplete, so typing narrows\n * them. Its value is Autocomplete's: pass `inputValue` with `onInputChange`\n * to control what has been typed, or `defaultInputValue` to let it keep its\n * own.\n *\n * The call site's `className` and `style` land on the view's surface, and\n * its `ref` too.\n */\nfunction SearchViewContent<T extends object = object>({\n backLabel,\n children,\n className,\n clearLabel,\n container,\n label,\n placeholder,\n ref,\n style,\n ...props\n}: RefAttributes<HTMLElement> & SearchViewContentProps<T>) {\n const messages = useMessages();\n return <RACPopover offset={SIDE_OFFSET} placement=\"bottom start\" ref={ref}\n // oxlint-disable-next-line typescript/no-deprecated -- its replacement, UNSAFE_PortalProvider, is not exported by react-aria-components\n UNSTABLE_portalContainer={container} {...mergeStatefulStyles(stylex.props(overlay.popup, styles.view), {\n className,\n style\n })}>\n <Dialog aria-label={label} className=\"x9f619 x78zum5 xdt5ytf x1iyjqo2 x2lwn1j x1t137rt\">\n <Autocomplete<T> {...props}>\n <div className=\"x6s0dn4 xs1ryiz xzcdm5u x9f619 x78zum5 x2lah0s x126z3so x790zyz\">\n <IconButton aria-label={backLabel ?? messages.back} slot=\"close\" className=\"x6aqprb\">\n <ArrowBackGlyph className=\"xlzyvqe x139gbkf x1lliihq x15vhz18 x19axjrm x1c071of\" />\n </IconButton>\n <RACSearchField className=\"x6s0dn4 x9f619 x78zum5 x1iyjqo2 x126z3so xeuugli\">\n {fieldContent(label, placeholder, clearLabel)}\n </RACSearchField>\n </div>\n <hr className=\"xp2scj5 xjm9jq1 xc342km x9f619 x2lah0s x1ghz6dp\" />\n <div className=\"x9f619 x1iyjqo2 xfwfbzp xrsa6q8 x1ficeh5 x1iob9gu x1odjw0f xish69e\">{children}</div>\n </Autocomplete>\n </Dialog>\n </RACPopover>;\n}\nSearchView.Content = SearchViewContent;\nexport type { SearchViewContentProps, SearchViewProps };\nexport { SearchViewContent };\nexport default SearchView;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["c","_c","ReactNode","RefAttributes","ClassNameOrFunction","DialogTriggerProps","PopoverRenderProps","SearchFieldRenderProps","StyleOrFunction","stylex","Dialog","DialogTrigger","Label","Popover","RACPopover","SearchField","RACSearchField","VisuallyHidden","AutocompleteProps","FieldInput","ArrowBackGlyph","CloseGlyph","useMessages","mergeStatefulStyles","overlay","colors","media","radii","shadows","sizing","spacing","Autocomplete","IconButton","SIDE_OFFSET","styles","view","kWkggS","kZKoxP","kaIpWk","kGVxlE","k1xSpc","kXwgrk","kzqmXN","krVfgx","k87sOh","kt4wiu","kLqNvP","kskxy","ks0D6T","kVQacm","kVAEAm","$$css","SearchViewContentProps","backLabel","children","className","clearLabel","container","Element","label","placeholder","style","Omit","T","SearchViewProps","fieldContent","state","isEmpty","SearchView","t0","$","props","t1","SearchViewContent","ref","messages","popup","t2","back","t3","Symbol","for","t4","t5","t6","t7","t8","t9","t10","t11","t12","Content","_c","props","stylex.props","RACSearchField","Autocomplete","RACPopover"],"sources":["../../../src/components/search-view/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode, RefAttributes } from 'react';\nimport type { ClassNameOrFunction, DialogTriggerProps, PopoverRenderProps, SearchFieldRenderProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Dialog, DialogTrigger, Label, Popover as RACPopover, SearchField as RACSearchField, VisuallyHidden } from 'react-aria-components';\nimport type { AutocompleteProps } from '../autocomplete';\nimport { FieldInput } from '../../field';\nimport { ArrowBackGlyph, CloseGlyph } from '../../glyphs';\nimport { useMessages } from '../../i18n';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport { overlay } from '../../styles/overlay';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, media, radii, shadows, sizing, spacing } from '../../tokens/design.tokens.stylex';\nimport Autocomplete from '../autocomplete';\nimport IconButton from '../icon-button';\n\n// The search page's search view: what a search opens into. A header holds a\n// back button, the input and a clear button, over a 1dp divider in the\n// outline role, and the results run under it. Both of the page's forms are\n// surface container high, with the input in body-large on surface over a\n// supporting text in on surface variant, the back icon in on surface and the\n// clear icon in on surface variant.\n//\n// **Which form is the window's.** Below the medium breakpoint it is the\n// page's full-screen view: the whole window, square, with a 72dp header.\n// Above it, the docked view: dropped under what opened it, as wide as that\n// and held between the page's 360dp and 720dp, with a 28dp corner, a 56dp\n// header, results at least 240dp tall and the whole view no taller than two\n// thirds of the window, at elevation 3 — Compose's measurements for its\n// docked search bar, which the page draws without numbers. The swap is the\n// date pickers' — see `src/styles/picker.ts`: React Aria places the surface\n// with inline styles, which a class outranks only with `!important`, so the\n// full-screen form takes it on the edges, the position and the size, and\n// above the breakpoint this says nothing about any of them.\n//\n// **It is Autocomplete in an overlay.** The header's input and the results\n// are Autocomplete's two halves, so typing narrows the results as it does\n// anywhere else, and the results are the call site's ListBox or Menu.\n// Autocomplete still renders nothing of its own; this is the element around\n// it.\n//\n// **The header lines up with the search bar's.** The back button sits where\n// the bar's magnifier does, its icon 28dp in, and the text starts at 68dp,\n// as the bar's does; the clear button's icon ends 28dp from the end. So a\n// view opened from a bar puts its input where the bar's was.\n//\n// Composed as Popover is: `SearchView` holds the open state, a Button or\n// IconButton placed directly inside it opens the view, and\n// `SearchView.Content` is the view. The back button closes it, as Escape and\n// a press outside the docked view do.\n\n// The gap between what opened the view and the docked view, Popover's.\nconst SIDE_OFFSET = 8;\nconst styles = {\n view: {\n kWkggS: \"xvkjz1l\",\n kZKoxP: \"x16m7gpl\",\n kaIpWk: \"x19pkqky xxl0i3l\",\n kGVxlE: \"x1udv5rz xzvmenf\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kzqmXN: \"xd4ksm1 x14gilbs\",\n krVfgx: \"xudx362\",\n k87sOh: \"xbvrusa\",\n kt4wiu: \"x1v0tev1\",\n kLqNvP: \"x12sfaok\",\n kskxy: \"x10iheve\",\n ks0D6T: \"x16xn7b0 x6iovhr\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1mesnot\",\n $$css: true\n }\n};\ntype SearchViewContentProps<T extends object = object> = {\n /**\n * What the back button is called, for a screen reader. Left out, the\n * library names it in the reader's locale — \"Back\" in English.\n */\n backLabel?: string;\n /** The results: a ListBox or a Menu, which typing narrows. */\n children?: ReactNode;\n /** A function may compute the class from the view's render state. */\n className?: ClassNameOrFunction<PopoverRenderProps>;\n /**\n * What the clear button is called, for a screen reader. Left out, React\n * Aria names it in the reader's locale — \"Clear search\" in English.\n */\n clearLabel?: string;\n /**\n * Where to portal the view. Defaults to the container of the `ThemeScope`\n * around it, which keeps the view on that scope's tokens, or to the end of\n * `<body>` where there is none. A subtree themed through the `themeScope`\n * class has no container of its own, so point this inside it, or the view\n * renders outside and keeps the page's tokens.\n */\n container?: Element;\n /**\n * What is searched, for a screen reader. It names both the view and its\n * input, and is read rather than shown; `placeholder` is what is seen.\n * Write it so it contains the placeholder's words, as SearchField's\n * `label` explains.\n */\n label: string;\n /** The supporting text in the empty input, which is what a person reads. */\n placeholder?: string;\n /** A function may compute the style from the view's render state. */\n style?: StyleOrFunction<PopoverRenderProps>;\n} & Omit<AutocompleteProps<T>, 'children'>;\ntype SearchViewProps = Omit<DialogTriggerProps, 'children'> & {\n /**\n * The Button or IconButton that opens the view, and `SearchView.Content`.\n */\n children?: ReactNode;\n};\n\n// What the field draws, from its render state: the clear button only while\n// it holds something. Built by a call rather than written inline at the\n// prop, which is what react-perf's no-new-function-as-prop is after.\nfunction fieldContent(label: string, placeholder: string | undefined, clearLabel: string | undefined) {\n return (state: SearchFieldRenderProps) => <>\n <VisuallyHidden>\n <Label>{label}</Label>\n </VisuallyHidden>\n <FieldInput\n // oxlint-disable-next-line jsx-a11y/no-autofocus -- a search view opens to be typed into, so the input takes focus rather than the back button the dialog would otherwise start on\n autoFocus placeholder={placeholder} className=\"x1hcrkkg xzwh6sb xjyslct x1iyjqo2 xeuugli\" />\n {state.isEmpty ? null : <IconButton aria-label={clearLabel} className=\"x15ir4sr\">\n <CloseGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>}\n </>;\n}\n\n/**\n * The view a search opens into: full screen on a compact window, docked\n * under what opened it on a wider one. Open state is React Aria's: pass\n * `isOpen` with `onOpenChange` to control it, or `defaultOpen` to let it keep\n * its own.\n *\n * ```tsx\n * <SearchView>\n * <IconButton aria-label=\"Search\"><SearchIcon /></IconButton>\n * <SearchView.Content label=\"Search\" placeholder=\"Search\">\n * <ListBox aria-label=\"Results\">…</ListBox>\n * </SearchView.Content>\n * </SearchView>\n * ```\n *\n * A Button or IconButton placed directly inside opens the view;\n * `SearchView.Content` is the view itself.\n */\nfunction SearchView({\n children,\n ...props\n}: SearchViewProps) {\n return <DialogTrigger {...props}>{children}</DialogTrigger>;\n}\n\n/**\n * The view: the header with its back button, input and clear button, and\n * the results under it, inside React Aria's Autocomplete, so typing narrows\n * them. Its value is Autocomplete's: pass `inputValue` with `onInputChange`\n * to control what has been typed, or `defaultInputValue` to let it keep its\n * own.\n *\n * The call site's `className` and `style` land on the view's surface, and\n * its `ref` too.\n */\nfunction SearchViewContent<T extends object = object>({\n backLabel,\n children,\n className,\n clearLabel,\n container,\n label,\n placeholder,\n ref,\n style,\n ...props\n}: RefAttributes<HTMLElement> & SearchViewContentProps<T>) {\n const messages = useMessages();\n return <RACPopover offset={SIDE_OFFSET} placement=\"bottom start\" ref={ref}\n // oxlint-disable-next-line typescript/no-deprecated -- its replacement, UNSAFE_PortalProvider, is not exported by react-aria-components\n UNSTABLE_portalContainer={container} {...mergeStatefulStyles(stylex.props(overlay.popup, styles.view), {\n className,\n style\n })}>\n <Dialog aria-label={label} className=\"x9f619 x78zum5 xdt5ytf x1iyjqo2 x2lwn1j x1t137rt\">\n <Autocomplete<T> {...props}>\n <div className=\"x6s0dn4 xs1ryiz xzcdm5u x9f619 x78zum5 x2lah0s x126z3so x790zyz\">\n <IconButton aria-label={backLabel ?? messages.back} slot=\"close\" className=\"x6aqprb\">\n <ArrowBackGlyph className=\"xlzyvqe x139gbkf x1lliihq x15vhz18 x19axjrm x1c071of\" />\n </IconButton>\n <RACSearchField className=\"x6s0dn4 x9f619 x78zum5 x1iyjqo2 x126z3so xeuugli\">\n {fieldContent(label, placeholder, clearLabel)}\n </RACSearchField>\n </div>\n <hr className=\"xp2scj5 xjm9jq1 xc342km x9f619 x2lah0s x1ghz6dp\" />\n <div className=\"x9f619 x1iyjqo2 xfwfbzp xrsa6q8 x1ficeh5 x1iob9gu x1odjw0f xish69e\">{children}</div>\n </Autocomplete>\n </Dialog>\n </RACPopover>;\n}\nSearchView.Content = SearchViewContent;\nexport type { SearchViewContentProps, SearchViewProps };\nexport { SearchViewContent };\nexport default SearchView;"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { LabelledByAttribute } from "../../render/name.js";
|
|
|
2
2
|
import { ReactNode, RefAttributes } from "react";
|
|
3
3
|
import { Key, ToggleButtonGroupProps, ToggleButtonProps } from "react-aria-components";
|
|
4
4
|
//#region src/components/segmented-button/index.d.ts
|
|
5
|
-
type SegmentedButtonProps = LabelledByAttribute & Omit<ToggleButtonGroupProps, 'className' | 'orientation' | 'style'> & {
|
|
5
|
+
type SegmentedButtonProps = LabelledByAttribute & Omit<ToggleButtonGroupProps, 'className' | 'disallowEmptySelection' | 'orientation' | 'style'> & {
|
|
6
6
|
/** A function may compute the class from the set's render state. */
|
|
7
7
|
className?: ToggleButtonGroupProps['className'];
|
|
8
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["c","_c","KeyboardEventHandler","ReactNode","RefAttributes","FocusableElement","Key","ToggleButtonGroupProps","RACToggleButtonGroupProps","ToggleButtonProps","RACToggleButtonProps","SharedElementRenderProps","ToggleButtonRenderProps","ToggleGroupState","stylex","createContext","createElement","useContext","useLayoutEffect","useState","SelectionIndicator","RACSelectionIndicator","ToggleButton","RACToggleButton","ToggleButtonGroup","RACToggleButtonGroup","LabelledByAttribute","CheckGlyph","useRipple","useToggleGroupDisabled","ariaAttributesOf","toggleButtonRenderer","focus","mergeStatefulStyles","colors","motion","radii","sizing","spacing","stateLayerOpacity","typography","ShowSelectedIconContext","SelectionModeContext","SelectionMode","GroupRender","Ripple","ReturnType","NonNullable","keyOf","segment","HTMLElement","written","dataset","key","undefined","JSON","parse","radioGroupRenderer","render","domProps","renderProps","merged","onKeyDownCapture","radioKeys","state","toolbar","HTMLDivElement","event","group","currentTarget","segments","querySelectorAll","filter","closest","from","findIndex","target","step","altKey","ctrlKey","metaKey","stepOf","getComputedStyle","direction","preventDefault","stopPropagation","to","length","setSelected","rtl","GLYPH_SIZE","GLYPH_RESERVE","sm","GLYPH_RESERVE_HALF","PADDING_GIVE","md","FORCED_COLORS","styles","kgeoSG","kGOzcv","kpsdNU","kEoFBp","k6CgDc","kGNEyG","kWkggS","kZKoxP","kVAM5u","kT0f0o","kVL7Gh","k2ei4v","kfmiAY","krdFHd","ksu8eU","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kMv6JI","kGuDYH","k63SB2","kjj79g","kb6lSQ","kLWn49","k7Eaqz","k8WAf4","kg3NbH","kVAEAm","kIyJzY","k1ekBW","kAMwcw","$$css","segmentDisabled","kMwMTN","segmentSelected","segmentSelectedUnmarked","segmentUnselected","spacer","kmuXW","kzqmXN","spacerHalf","spacerHolding","spacerIcon","SegmentedButtonProps","Omit","className","disallowEmptySelection","showSelectedIcon","style","SegmentedButtonSegmentProps","children","disableRipple","icon","id","glyphFor","marked","isSelected","hasLabel","indicatorClassName","isDisabled","selectionMode","isEntering","isExiting","segmentContent","ripple","labelRef","element","HTMLSpanElement","labelTitle","labelled","reserves","glyph","drawn","isHovered","isFocusVisible","isPressed","props","surface","SegmentedButton","t0","$","T0","T1","T2","t1","t2","t3","t4","t5","t6","t7","t8","t9","single","t10","SegmentedButtonSegment","onClick","onContextMenu","onKeyDown","onKeyUp","onPointerCancel","onPointerDown","onPointerLeave","onPointerUp","label","setLabel","useTruncatedText","aria","disabledByGroup","stringify","handlers","segmentStyles","ring","text","setText","measure","cut","scrollWidth","clientWidth","textContent","resize","ResizeObserver","observe","relabel","MutationObserver","characterData","childList","subtree","disconnect","Segment","RACSelectionIndicator","stylex.props","_c","RACToggleButtonGroup","RACToggleButton"],"sources":["../../../src/components/segmented-button/index.tsx"],"sourcesContent":["'use client';\n\nimport type { KeyboardEventHandler, ReactNode, RefAttributes } from 'react';\nimport type { FocusableElement, Key, ToggleButtonGroupProps as RACToggleButtonGroupProps, ToggleButtonProps as RACToggleButtonProps, SharedElementRenderProps, ToggleButtonRenderProps, ToggleGroupState } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, createElement, useContext, useLayoutEffect, useState } from 'react';\nimport { SelectionIndicator as RACSelectionIndicator, ToggleButton as RACToggleButton, ToggleButtonGroup as RACToggleButtonGroup } from 'react-aria-components';\nimport type { LabelledByAttribute } from '../../render/name';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { useToggleGroupDisabled } from '../../hooks/useToggleGroupDisabled';\nimport { ariaAttributesOf, toggleButtonRenderer } from '../../render/aria';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The segmented buttons page's outlined segmented button: two to five\n// segments joined into one outlined track, of which one or several are\n// chosen. A segment is Button's default size and type role — a 40dp\n// container with a label-large label — which is what that page gives too.\n//\n// What a screen reader hears follows the selection mode, and React Aria\n// decides it rather than this component. Choosing one of the segments is a\n// radio group, so the track is a `radiogroup` and each segment a `radio`\n// reporting `aria-checked`; choosing several is a `toolbar` of buttons each\n// reporting `aria-pressed`. That is the right mapping for both, and it is\n// why the mode is a word on the group rather than two components.\n//\n// React Aria stops at the name, though: its single mode is announced as a\n// radio group and behaves as a toolbar. So that mode takes the rest of the\n// radio group pattern from the ARIA Authoring Practices, a deliberate\n// departure from React Aria's `ToggleButtonGroup`, in two parts. The chosen\n// segment cannot be pressed off, since a radio group always holds a choice\n// and the page's single-select set always keeps one segment chosen;\n// `disallowEmptySelection={false}` gives React Aria's default back. And the\n// arrow keys choose as they move, wrapping at either end, with Home and End\n// choosing the first and last segment. Under React Aria the arrows moved\n// focus alone and stopped at the ends, so a screen reader reached each radio\n// without it being checked, and choosing one took a separate Space. Choosing\n// several keeps React Aria's toolbar keys, where the arrows only move between\n// buttons and Space toggles one.\n//\n// Six things are this component's own.\n//\n// **The segments are one track, not a row of buttons.** Every segment\n// carries the page's 1dp outline, and each one after the first drops its\n// leading edge so neighbours share a single rule rather than drawing two\n// against each other. The outer ends are the page's fully rounded shape and\n// the inner joins are square.\n//\n// **Every segment is the same width.** The page gives the segment width as\n// the container's divided by their number, so the track is a grid of equal\n// columns; the container itself is still as wide as its widest label asks,\n// plus the room described next.\n//\n// **A chosen segment says so with a check.** The page draws it in the icon\n// slot, so a segment given an `icon` shows the icon while unselected and the\n// check once chosen. `showSelectedIcon` turns it off for a set whose labels\n// already read as chosen or not.\n//\n// Without the check, the page's chosen container is the only cue, and it is\n// about 1.2:1 against the page in the light theme, with the same label\n// colour either way — under WCAG's 3:1 for a state. So a set with the check\n// off draws its chosen segment on the secondary role instead, with the label\n// on it, which clears that comfortably. A departure from the page, taken\n// only where the page's own cue has been turned off; with the check drawn,\n// the chosen segment is the page's.\n//\n// A segment with an `icon` and no label is drawn that way whatever the set\n// says. It keeps its icon when chosen, since the icon is all that tells it\n// from its neighbours, and a check in its place would hide which of them is\n// the chosen one.\n//\n// Under forced colours a fill is painted in the page's own `Canvas`, so the\n// chosen container is `Highlight` with its label in `HighlightText` — the\n// pair the mode gives whatever is chosen — and a disabled chosen one keeps\n// a `GrayText` ring rather than a fill, which leaves its `GrayText` label\n// readable.\n//\n// Every segment that could ever draw that slot keeps room for it whether\n// or not it is drawing one. Sized by what it drew, the slot made the widest\n// segment whichever one was chosen, and the whole track changed width with\n// the choice — moving every label, and moving the ground under the chosen\n// container while it was sliding across it. The mechanism is Angular\n// Material's button toggle: the slot opens from 0 to 18dp and the space it\n// lands in opens beside it, both over `durationShort2`. Here that space is\n// two spacers either side of the label, which trade it between them: half\n// on each side while nothing is drawn, so a bare label stays centred, and\n// all of it on the leading side, where the slot sits, once something is.\n// Their total never changes, so neither does the segment's width. Angular\n// Material has no case of the first kind, since its toggles are sized by\n// their own content rather than by the widest of them.\n//\n// That room gives way before the label does. A track with room to spare is\n// the widest label plus 26dp per segment, which is what the widest column\n// already measured while its own segment was the chosen one. A track\n// squeezed below that — long labels on a phone — gives the reserve back\n// first, then the 4dp of the page's 12dp padding beyond the 8dp a segment\n// always keeps, and only then cuts a label short, with an ellipsis and a\n// `title` that shows it whole. A segment drawing a glyph keeps the glyph and\n// its 8dp gap, so the chosen label is the first to be cut. A label shows\n// whole in a segment 16dp wider than it, or 42dp while a glyph is drawn\n// beside it, plus the segment's rule. The track's width still never depends\n// on the choice: squeezed, its columns are the container's, shared equally.\n//\n// Angular Material delays the check's own transition by 45ms so the space\n// opens before the glyph arrives. That is dropped rather than carried as a\n// literal: there is no motion token for it, and the slot here opens from its\n// centre rather than its leading edge, so the check and the label never\n// cross even when the two run together.\n//\n// **The chosen container is an element of its own, and it moves.** It is\n// React Aria's `SelectionIndicator`, a shared element rendered inside every\n// segment and drawn in the chosen one: on a change it keeps the old one\n// until it has finished moving, so two exist while it slides. No\n// `SharedElementTransition` is rendered here, because `ToggleButtonGroup`\n// wraps its children in one already — worth saying, since the primitive\n// throws outside a scope wherever else it is used.\n//\n// It is the page's chosen container rather than a smaller pill: it covers\n// the segment, which is the box a background painted, so the fill is all\n// that travels. Three things follow. It is drawn behind the segments rather\n// than inside one, or a container crossing a neighbour would pass over that\n// neighbour's label and the rule beside it. Its corners have to match\n// whichever segment it is in, which the segment hands down as a custom\n// property, because a child cannot read its own parent's place in the track.\n// And the state layers move onto a layer of their own above it, since a\n// container that slides away would otherwise take the hover with it and off\n// the segment under the pointer.\n//\n// **Choosing several animates differently, rather than the same way twice.**\n// A shared element is one element: it can move between segments, but with\n// several chosen there is no single segment for it to be at. So\n// `selectionMode=\"multiple\"` names only `opacity` in the transition, nothing\n// positional is snapshotted, and each container fades in and out where it\n// is; `single` names `translate` and `border-radius` as well, and the one\n// container travels between segments.\n//\n// **Two of the page's values are the library's instead**, both for\n// consistency with the controls beside them: the focus ring, which is\n// primary at 2dp offset 2dp everywhere here rather than the page's secondary\n// at 3dp, and the press, which is the library's ripple rather than a flat\n// state layer. The page names a ripple as the pressed state, so the second\n// is a departure only in how it is drawn.\n//\n// **The density steps are not drawn.** The page removes 4dp of height per\n// step down, for denser interfaces; nothing else in the library takes a\n// density, and one component that did would be the odd one out. A shorter\n// track is a `className` away.\n//\n// Vertical is React Aria's and is not passed through, since the page draws\n// one row and a column of joined segments is a different shape — the outer\n// corners, the shared rule and the equal columns would all have to mean\n// something else.\n\n// Whether a chosen segment draws the check. A context rather than a prop on\n// each segment, since it is the set's decision and repeating it on every\n// segment is how the two drift.\nconst ShowSelectedIconContext = createContext(true);\n\n// Which of the two animations the chosen container plays. Read from a\n// context for the same reason, and because React Aria's own state context\n// holds the mode in a shape this would have to narrow before using.\nconst SelectionModeContext = createContext<SelectionMode>('single');\ntype GroupRender = RACToggleButtonGroupProps['render'];\ntype Ripple = ReturnType<typeof useRipple<FocusableElement>>;\ntype SelectionMode = NonNullable<RACToggleButtonGroupProps['selectionMode']>;\n\n// A segment's key, back from the attribute `SegmentedButtonSegment` writes\n// it into. JSON rather than the key as written, so a numeric key comes back\n// a number and matches the one React Aria's selection holds.\nfunction keyOf(segment: HTMLElement): Key | null {\n const written = segment.dataset.key;\n if (written === undefined) {\n return null;\n }\n const key: unknown = JSON.parse(written);\n return typeof key === 'string' || typeof key === 'number' ? key : null;\n}\n\n// The group's element, with `radioKeys` in place of React Aria's keyboard\n// handler, then handed to the call site's own `render` if it passed one.\nfunction radioGroupRenderer(render: GroupRender): NonNullable<GroupRender> {\n return (domProps, renderProps) => {\n const merged = {\n ...domProps,\n onKeyDownCapture: radioKeys(renderProps.state, domProps.onKeyDownCapture)\n };\n return render === undefined ? createElement('div', merged) : render(merged, renderProps);\n };\n}\n\n// The radio group's keys, taken ahead of React Aria's toolbar ones on the\n// same capture listener: the arrows, Home and End move focus to a segment\n// and choose it, wrapping at the ends and passing over a disabled segment,\n// which is what the toolbar's own handler would otherwise do with focus\n// alone. Everything else — Tab, and an arrow held with a modifier the\n// browser may want — is handed to the toolbar as before.\nfunction radioKeys(state: ToggleGroupState, toolbar: KeyboardEventHandler<HTMLDivElement> | undefined): KeyboardEventHandler<HTMLDivElement> {\n return event => {\n const group = event.currentTarget;\n const segments = [...group.querySelectorAll<HTMLElement>('[data-key]:not([data-disabled])')].filter(segment => segment.closest('[role=\"radiogroup\"]') === group);\n const from = segments.findIndex(segment => segment === event.target);\n const step = event.altKey || event.ctrlKey || event.metaKey ? null : stepOf(event.key, getComputedStyle(group).direction === 'rtl');\n if (from === -1 || step === null) {\n toolbar?.(event);\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const to = step === 'first' ? 0 : step === 'last' ? segments.length - 1 : (from + step + segments.length) % segments.length;\n const segment = segments[to];\n const key = keyOf(segment);\n if (key === null) {\n return;\n }\n segment.focus();\n state.setSelected(key, true);\n };\n}\n\n// Where a key moves the choice in a radio group: one segment on, one back,\n// or to either end. Right and left follow the direction the track is drawn\n// in, read off the track itself rather than the locale, so a `dir` on a\n// wrapper turns them over as it turns the track over; up and down, and Home\n// and End, follow the document order whatever the direction.\nfunction stepOf(key: string, rtl: boolean): -1 | 1 | 'first' | 'last' | null {\n switch (key) {\n case 'ArrowDown':\n {\n return 1;\n }\n case 'ArrowLeft':\n {\n return rtl ? 1 : -1;\n }\n case 'ArrowRight':\n {\n return rtl ? -1 : 1;\n }\n case 'ArrowUp':\n {\n return -1;\n }\n case 'End':\n {\n return 'last';\n }\n case 'Home':\n {\n return 'first';\n }\n default:\n {\n return null;\n }\n }\n}\n\n// The page's 18dp icon slot, and the room a segment keeps for it: the slot\n// plus the gap between it and the label. Half of that room sits on each side\n// of the label while nothing is drawn, which is what keeps a bare label\n// centred; see `labelReserved`.\nconst GLYPH_SIZE = '18px';\nconst GLYPH_RESERVE = `calc(${GLYPH_SIZE} + ${spacing.sm})`;\nconst GLYPH_RESERVE_HALF = `calc((${GLYPH_SIZE} + ${spacing.sm}) / 2)`;\n\n// The part of the page's 12dp padding a segment gives back on a narrow\n// track: the padding is 8dp, and the rest sits in the spacers, which shrink.\nconst PADDING_GIVE = `calc(${spacing.md} - ${spacing.sm})`;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n segment: {\n \"--segment-indicator-radius-end\": \"x32u3vw x111hk5a\",\n \"--segment-indicator-radius-start\": \"xatjrgw x1syycwj\",\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"x17kqlg\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1rv7mn0\",\n kVAM5u: \"x1fwvt7v\",\n kT0f0o: \"x1fougng xkducg2\",\n kVL7Gh: \"x1prwiuu x1uwupfv\",\n k2ei4v: \"x120dh57 x14e42zd\",\n kfmiAY: \"x17hb1p4 x1a37zkv\",\n krdFHd: \"xwfph4i xb01x1j\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xmkeg23\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kjj79g: \"xl56j7k\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n k7Eaqz: \"xeuugli\",\n k8WAf4: \"xt970qd\",\n kg3NbH: \"xn60lsn\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xt3l3uh\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n segmentDisabled: {\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8 x1bhcspo\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n segmentSelected: {\n kMwMTN: \"x1sawysd x1k5gbb1\",\n $$css: true\n },\n segmentSelectedUnmarked: {\n kMwMTN: \"x1lba3jz x1k5gbb1\",\n $$css: true\n },\n segmentUnselected: {\n kMwMTN: \"x139gbkf\",\n $$css: true\n },\n spacer: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"xs83m0k\",\n kzqmXN: \"xbraz1g\",\n kjj79g: \"x13a6bvl\",\n k7Eaqz: \"xeuugli\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x1pha8k4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n spacerHalf: {\n kzqmXN: \"x154zo0h\",\n $$css: true\n },\n spacerHolding: {\n kzqmXN: \"x1n85vuq\",\n k7Eaqz: \"x36sgg7\",\n $$css: true\n },\n spacerIcon: {\n kzqmXN: \"x1iuy3mw\",\n k7Eaqz: \"x16xo4sp\",\n $$css: true\n }\n};\ntype SegmentedButtonProps = LabelledByAttribute & Omit<RACToggleButtonGroupProps, 'className' | 'orientation' | 'style'> & {\n /** A function may compute the class from the set's render state. */\n className?: RACToggleButtonGroupProps['className'];\n /**\n * Whether the chosen segment stays chosen when it is pressed again. On\n * by default while one is chosen, since a radio group always holds a\n * choice; `false` lets a press clear it, as React Aria's own default\n * does. Off by default while several may be, where any of them can be\n * turned off.\n * @default true while one is chosen, false while several may be\n */\n disallowEmptySelection?: boolean;\n /**\n * Whether a chosen segment draws a check before its label, as the page\n * has it. `false` leaves the segment's own icon in place while selected,\n * and draws the chosen segment on the stronger secondary container, since\n * the page's own is too faint to say which is chosen by itself.\n * @default true\n */\n showSelectedIcon?: boolean;\n /** A function may compute the style from the set's render state. */\n style?: RACToggleButtonGroupProps['style'];\n};\ntype SegmentedButtonSegmentProps = Omit<RACToggleButtonProps, 'children' | 'className' | 'id' | 'style'> & {\n /** The segment's label. */\n children?: ReactNode;\n /** A function may compute the class from the segment's render state. */\n className?: RACToggleButtonProps['className'];\n /**\n * Disables the press ripple. The hover and pressed state layers are\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * An icon before the label, in the page's 18dp size. Replaced by the check\n * while the segment is chosen, unless the set turns that off. An icon drawn\n * in `em` takes that size from the slot.\n *\n * Given with no label, the icon is the segment, centred in it and kept\n * while chosen; name the segment with `aria-label` then.\n */\n icon?: ReactNode;\n /**\n * The key selection is reported by. Required, because React Aria joins a\n * toggle to its group's selection by this key alone: a segment without one\n * keeps a pressed state of its own, so a set where one is chosen could hold\n * two, and it is announced as a pressed button rather than a radio.\n */\n id: Key;\n /** A function may compute the style from the segment's render state. */\n style?: RACToggleButtonProps['style'];\n};\n\n/**\n * What the glyph slot draws: the check on a chosen segment, or the segment's\n * own icon. `null` for a segment with neither, which leaves the slot empty\n * and closed rather than unrendered. Returns a node rather than letting the\n * type be inferred, since `ReactNode` is a union that includes a promise and\n * an inferred one has to be `async`.\n */\nfunction glyphFor(state: ToggleButtonRenderProps, icon: ReactNode, marked: boolean): ReactNode {\n if (state.isSelected && marked) {\n return <CheckGlyph className=\"x5yr21d x2lah0s x1xp8n7a\" />;\n }\n return icon ?? null;\n}\n\n// Whether a segment has a label, rather than an icon alone. An empty string\n// and a `false` from a condition at the call site are no label either.\nfunction hasLabel(children: ReactNode) {\n return children !== undefined && children !== null && children !== false && children !== '';\n}\n\n// The chosen container's class, from the segment's own state and the shared\n// element's. A function, because React Aria hands the indicator the entering\n// and leaving states the fade is drawn from, and those are the only two the\n// element knows about itself.\nfunction indicatorClassName(isDisabled: boolean, selectionMode: SelectionMode, marked: boolean): (state: SharedElementRenderProps) => string {\n return state => ({\n 0: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd\"\n },\n 8: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7\"\n },\n 4: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd x167r6xl x1jzqe4\"\n },\n 12: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 x167r6xl x1jzqe4\"\n },\n 2: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 10: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 6: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 14: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 1: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xg01cxk\"\n },\n 9: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xg01cxk\"\n },\n 5: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd x167r6xl x1jzqe4 xg01cxk\"\n },\n 13: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 x167r6xl x1jzqe4 xg01cxk\"\n },\n 3: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 11: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 7: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 15: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n }\n })[!!(selectionMode === 'multiple') << 3 | !!!marked << 2 | !!isDisabled << 1 | !!(state.isEntering || state.isExiting) << 0].className ?? '';\n}\n\n// What a segment draws, from React Aria's render state. Built by a call\n// rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result\n// on its inputs.\nfunction segmentContent(children: ReactNode, icon: ReactNode, ripple: Ripple, selectionMode: SelectionMode, marked: boolean, labelRef: (element: HTMLSpanElement | null) => void, labelTitle: string | undefined) {\n const labelled = hasLabel(children);\n // Whether this segment can ever draw a glyph, and so whether it keeps room\n // for one. A set that draws no check and a segment with no icon of its own\n // never needs the slot, and reserving it there would be dead space in\n // every segment of the track.\n const reserves = marked || icon !== undefined;\n return (state: ToggleButtonRenderProps) => {\n const glyph = glyphFor(state, icon, marked);\n const drawn = glyph !== null;\n return <>\n <RACSelectionIndicator className={indicatorClassName(state.isDisabled, selectionMode, marked)} />\n <span {...{\n 0: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi xg01cxk x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4\"\n },\n 4: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xe2qvxb\"\n },\n 2: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xcl2av\"\n },\n 6: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xcl2av\"\n },\n 1: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 5: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 3: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 7: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n }\n }[!!state.isHovered << 2 | !!state.isFocusVisible << 1 | !!state.isPressed << 0]} />\n <span {...stylex.props(styles.spacer, reserves && (drawn ? labelled ? styles.spacerHolding : styles.spacerIcon : styles.spacerHalf))}>\n {reserves && <span {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7\"\n },\n 2: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1nsf9p3\"\n },\n 3: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a x1nsf9p3\"\n }\n }[!!drawn << 1 | !!(drawn && labelled) << 0]}>\n {glyph}\n </span>}\n </span>\n {labelled && <span ref={labelRef} title={labelTitle} {...{\n 0: {\n className: \"x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft\"\n },\n 2: {\n className: \"x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8\"\n },\n 1: {\n className: \"x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1g12otp\"\n },\n 3: {\n className: \"x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8 x1g12otp\"\n }\n }[!!drawn << 1 | !!(state.isSelected && !state.isDisabled) << 0]}>\n {children}\n </span>}\n <span {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k xbraz1g x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7 x154zo0h\"\n }\n }[!!(reserves && !drawn) << 0]} />\n {ripple.surface}\n </>;\n };\n}\n\n/**\n * A row of two to five joined segments, of which one — or with\n * `selectionMode=\"multiple\"`, several — is chosen. Selection is React Aria's:\n * pass `selectedKeys` with `onSelectionChange` to control it, or\n * `defaultSelectedKeys` to let it keep its own. Give every segment an `id`,\n * which is the key selection is reported by.\n *\n * ```tsx\n * <SegmentedButton aria-label=\"Label\" defaultSelectedKeys={['first']}>\n * <SegmentedButton.Segment id=\"first\">First item</SegmentedButton.Segment>\n * <SegmentedButton.Segment id=\"second\">Second item</SegmentedButton.Segment>\n * </SegmentedButton>\n * ```\n *\n * Name the set with `aria-label` or `aria-labelledby`, one of which the\n * props require — nothing here labels it for you, and a set with no name is\n * a group a screen reader cannot announce. What it is announced as follows the selection mode: choosing one\n * is a radio group, choosing several a toolbar of two-state buttons. So does\n * how the chosen container moves: it slides between segments while one is\n * chosen, and fades in place while several may be.\n *\n * Choosing one behaves as a radio group too, which React Aria's\n * `ToggleButtonGroup` does not. The chosen segment stays chosen when it is\n * pressed again, unless `disallowEmptySelection` is `false`. The arrow keys\n * move to a segment and choose it, wrapping at either end, and Home and End\n * choose the first and last. Choosing several keeps React Aria's keys: the\n * arrows move between segments, and Space or Enter toggles the focused one.\n *\n * The call site's `className` and `style` land on the track, which is the\n * element a layout positions.\n */\nfunction SegmentedButton({\n disallowEmptySelection,\n render,\n selectionMode = 'single',\n showSelectedIcon = true,\n ...props\n}: RefAttributes<HTMLDivElement> & SegmentedButtonProps) {\n const single = selectionMode === 'single';\n return <ShowSelectedIconContext value={showSelectedIcon}>\n <SelectionModeContext value={selectionMode}>\n <RACToggleButtonGroup {...props} disallowEmptySelection={disallowEmptySelection ?? single} render={single ? radioGroupRenderer(render) : render} selectionMode={selectionMode} {...mergeStatefulStyles({\n className: \"x9f619 xwz0xwf xu6a5m6 x1mt1orb xc8icb0\"\n }, props)} />\n </SelectionModeContext>\n </ShowSelectedIconContext>;\n}\n\n/**\n * One segment. Its `id` is what selection is reported by, and its label is\n * what names it. A chosen segment draws a check before the label; an\n * unchosen one draws whatever `icon` holds, if anything.\n */\nfunction SegmentedButtonSegment({\n children,\n disableRipple = false,\n icon,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n render,\n ...props\n}: RefAttributes<HTMLButtonElement> & SegmentedButtonSegmentProps) {\n const selectionMode = useContext(SelectionModeContext);\n // Whether this segment draws the check when chosen: the set's choice,\n // unless the segment has no label — see the header.\n const marked = useContext(ShowSelectedIconContext) && hasLabel(children);\n const [label, setLabel] = useState<HTMLSpanElement | null>(null);\n const labelTitle = useTruncatedText(label);\n // The `aria-*` props React Aria would drop and the keyboard handlers it\n // would wrap go on the element itself, as they do on Chip, Button and\n // IconButton; see src/render/aria.tsx.\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n // Off while disabled, as in Button: a control that cannot be pressed\n // should not answer a press with an animation. A disabled set disables\n // its segments through React Aria's group state rather than their props,\n // so the group is read as well.\n const disabledByGroup = useToggleGroupDisabled(props.id);\n // The call site's pointer handlers go through the ripple, which calls\n // them after its own. Spread beside the ripple's, one of the two sets\n // would write over the other.\n const ripple = useRipple<FocusableElement>(!disableRipple && props.isDisabled !== true && !disabledByGroup, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n return <RACToggleButton\n // The key the radio group's arrow keys choose this segment by; see\n // `radioKeys`. React Aria keeps a segment's key off its element.\n data-key={selectionMode === 'single' ? JSON.stringify(props.id) : undefined} render={toggleButtonRenderer(element, render)} {...ripple.handlers} {...props} {...mergeStatefulStyles(segmentStyles(marked), props)}>\n {segmentContent(children, icon, ripple, selectionMode, marked, setLabel, labelTitle)}\n </RACToggleButton>;\n}\n\n// StyleX cannot target `[data-selected]` on the element it is styling, so a\n// segment's state comes from the render state React Aria hands its\n// className. `disabled` is applied last so its label colour wins over both\n// of the others. Built by a call, since a set that draws no check labels its\n// chosen segment for the container it draws instead.\nfunction segmentStyles(marked: boolean) {\n return (state: ToggleButtonRenderProps) => stylex.props(styles.segment, focus.ring, state.isSelected ? styles.segmentSelected : styles.segmentUnselected, state.isSelected && !marked && styles.segmentSelectedUnmarked, state.isDisabled && styles.segmentDisabled);\n}\n\n// The text of a label its segment is cutting short, for a `title` that shows\n// it whole; undefined while it fits. Measured again whenever the label's box\n// or its text changes, which is when it can start or stop being cut.\nfunction useTruncatedText(label: HTMLElement | null): string | undefined {\n const [text, setText] = useState<string | undefined>(undefined);\n useLayoutEffect(() => {\n if (label === null) {\n return undefined;\n }\n const measure = () => {\n const cut = label.scrollWidth > label.clientWidth;\n setText(cut && label.textContent !== '' ? label.textContent : undefined);\n };\n measure();\n const resize = new ResizeObserver(measure);\n resize.observe(label);\n const relabel = new MutationObserver(measure);\n relabel.observe(label, {\n characterData: true,\n childList: true,\n subtree: true\n });\n return () => {\n resize.disconnect();\n relabel.disconnect();\n };\n }, [label]);\n return text;\n}\nSegmentedButton.Segment = SegmentedButtonSegment;\nexport type { SegmentedButtonProps, SegmentedButtonSegmentProps };\nexport { SegmentedButtonSegment };\nexport default SegmentedButton;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["c","_c","KeyboardEventHandler","ReactNode","RefAttributes","FocusableElement","Key","ToggleButtonGroupProps","RACToggleButtonGroupProps","ToggleButtonProps","RACToggleButtonProps","SharedElementRenderProps","ToggleButtonRenderProps","ToggleGroupState","stylex","createContext","createElement","useContext","useLayoutEffect","useState","SelectionIndicator","RACSelectionIndicator","ToggleButton","RACToggleButton","ToggleButtonGroup","RACToggleButtonGroup","LabelledByAttribute","CheckGlyph","useRipple","useToggleGroupDisabled","ariaAttributesOf","toggleButtonRenderer","focus","mergeStatefulStyles","colors","motion","radii","sizing","spacing","stateLayerOpacity","typography","ShowSelectedIconContext","SelectionModeContext","SelectionMode","GroupRender","Ripple","ReturnType","NonNullable","keyOf","segment","HTMLElement","written","dataset","key","undefined","JSON","parse","radioGroupRenderer","render","domProps","renderProps","merged","onKeyDownCapture","radioKeys","state","toolbar","HTMLDivElement","event","group","currentTarget","segments","querySelectorAll","filter","closest","from","findIndex","target","step","altKey","ctrlKey","metaKey","stepOf","getComputedStyle","direction","preventDefault","stopPropagation","to","length","setSelected","rtl","GLYPH_SIZE","GLYPH_RESERVE","sm","GLYPH_RESERVE_HALF","PADDING_GIVE","md","FORCED_COLORS","styles","kgeoSG","kGOzcv","kpsdNU","kEoFBp","k6CgDc","kGNEyG","kWkggS","kZKoxP","kVAM5u","kT0f0o","kVL7Gh","k2ei4v","kfmiAY","krdFHd","ksu8eU","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kMv6JI","kGuDYH","k63SB2","kjj79g","kb6lSQ","kLWn49","k7Eaqz","k8WAf4","kg3NbH","kVAEAm","kIyJzY","k1ekBW","kAMwcw","$$css","segmentDisabled","kMwMTN","segmentSelected","segmentSelectedUnmarked","segmentUnselected","spacer","kmuXW","kzqmXN","spacerHalf","spacerHolding","spacerIcon","SegmentedButtonProps","Omit","className","disallowEmptySelection","showSelectedIcon","style","SegmentedButtonSegmentProps","children","disableRipple","icon","id","glyphFor","marked","isSelected","hasLabel","indicatorClassName","isDisabled","selectionMode","isEntering","isExiting","segmentContent","ripple","labelRef","element","HTMLSpanElement","labelTitle","labelled","reserves","glyph","drawn","isHovered","isFocusVisible","isPressed","props","surface","SegmentedButton","t0","$","T0","T1","T2","t1","t2","t3","t4","t5","t6","t7","t8","t9","single","t10","SegmentedButtonSegment","onClick","onContextMenu","onKeyDown","onKeyUp","onPointerCancel","onPointerDown","onPointerLeave","onPointerUp","label","setLabel","useTruncatedText","aria","disabledByGroup","stringify","handlers","segmentStyles","ring","text","setText","measure","cut","scrollWidth","clientWidth","textContent","resize","ResizeObserver","observe","relabel","MutationObserver","characterData","childList","subtree","disconnect","Segment","RACSelectionIndicator","stylex.props","_c","RACToggleButtonGroup","RACToggleButton"],"sources":["../../../src/components/segmented-button/index.tsx"],"sourcesContent":["'use client';\n\nimport type { KeyboardEventHandler, ReactNode, RefAttributes } from 'react';\nimport type { FocusableElement, Key, ToggleButtonGroupProps as RACToggleButtonGroupProps, ToggleButtonProps as RACToggleButtonProps, SharedElementRenderProps, ToggleButtonRenderProps, ToggleGroupState } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createContext, createElement, useContext, useLayoutEffect, useState } from 'react';\nimport { SelectionIndicator as RACSelectionIndicator, ToggleButton as RACToggleButton, ToggleButtonGroup as RACToggleButtonGroup } from 'react-aria-components';\nimport type { LabelledByAttribute } from '../../render/name';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { useToggleGroupDisabled } from '../../hooks/useToggleGroupDisabled';\nimport { ariaAttributesOf, toggleButtonRenderer } from '../../render/aria';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The segmented buttons page's outlined segmented button: two to five\n// segments joined into one outlined track, of which one or several are\n// chosen. A segment is Button's default size and type role — a 40dp\n// container with a label-large label — which is what that page gives too.\n//\n// What a screen reader hears follows the selection mode, and React Aria\n// decides it rather than this component. Choosing one of the segments is a\n// radio group, so the track is a `radiogroup` and each segment a `radio`\n// reporting `aria-checked`; choosing several is a `toolbar` of buttons each\n// reporting `aria-pressed`. That is the right mapping for both, and it is\n// why the mode is a word on the group rather than two components.\n//\n// React Aria stops at the name, though: its single mode is announced as a\n// radio group and behaves as a toolbar. So that mode takes the rest of the\n// radio group pattern from the ARIA Authoring Practices, a deliberate\n// departure from React Aria's `ToggleButtonGroup`, in two parts. The chosen\n// segment cannot be pressed off, since a radio group always holds a choice\n// and the page's single-select set always keeps one segment chosen;\n// `disallowEmptySelection={false}` gives React Aria's default back. And the\n// arrow keys choose as they move, wrapping at either end, with Home and End\n// choosing the first and last segment. Under React Aria the arrows moved\n// focus alone and stopped at the ends, so a screen reader reached each radio\n// without it being checked, and choosing one took a separate Space. Choosing\n// several keeps React Aria's toolbar keys, where the arrows only move between\n// buttons and Space toggles one.\n//\n// Six things are this component's own.\n//\n// **The segments are one track, not a row of buttons.** Every segment\n// carries the page's 1dp outline, and each one after the first drops its\n// leading edge so neighbours share a single rule rather than drawing two\n// against each other. The outer ends are the page's fully rounded shape and\n// the inner joins are square.\n//\n// **Every segment is the same width.** The page gives the segment width as\n// the container's divided by their number, so the track is a grid of equal\n// columns; the container itself is still as wide as its widest label asks,\n// plus the room described next.\n//\n// **A chosen segment says so with a check.** The page draws it in the icon\n// slot, so a segment given an `icon` shows the icon while unselected and the\n// check once chosen. `showSelectedIcon` turns it off for a set whose labels\n// already read as chosen or not.\n//\n// Without the check, the page's chosen container is the only cue, and it is\n// about 1.2:1 against the page in the light theme, with the same label\n// colour either way — under WCAG's 3:1 for a state. So a set with the check\n// off draws its chosen segment on the secondary role instead, with the label\n// on it, which clears that comfortably. A departure from the page, taken\n// only where the page's own cue has been turned off; with the check drawn,\n// the chosen segment is the page's.\n//\n// A segment with an `icon` and no label is drawn that way whatever the set\n// says. It keeps its icon when chosen, since the icon is all that tells it\n// from its neighbours, and a check in its place would hide which of them is\n// the chosen one.\n//\n// Under forced colours a fill is painted in the page's own `Canvas`, so the\n// chosen container is `Highlight` with its label in `HighlightText` — the\n// pair the mode gives whatever is chosen — and a disabled chosen one keeps\n// a `GrayText` ring rather than a fill, which leaves its `GrayText` label\n// readable.\n//\n// Every segment that could ever draw that slot keeps room for it whether\n// or not it is drawing one. Sized by what it drew, the slot made the widest\n// segment whichever one was chosen, and the whole track changed width with\n// the choice — moving every label, and moving the ground under the chosen\n// container while it was sliding across it. The mechanism is Angular\n// Material's button toggle: the slot opens from 0 to 18dp and the space it\n// lands in opens beside it, both over `durationShort2`. Here that space is\n// two spacers either side of the label, which trade it between them: half\n// on each side while nothing is drawn, so a bare label stays centred, and\n// all of it on the leading side, where the slot sits, once something is.\n// Their total never changes, so neither does the segment's width. Angular\n// Material has no case of the first kind, since its toggles are sized by\n// their own content rather than by the widest of them.\n//\n// That room gives way before the label does. A track with room to spare is\n// the widest label plus 26dp per segment, which is what the widest column\n// already measured while its own segment was the chosen one. A track\n// squeezed below that — long labels on a phone — gives the reserve back\n// first, then the 4dp of the page's 12dp padding beyond the 8dp a segment\n// always keeps, and only then cuts a label short, with an ellipsis and a\n// `title` that shows it whole. A segment drawing a glyph keeps the glyph and\n// its 8dp gap, so the chosen label is the first to be cut. A label shows\n// whole in a segment 16dp wider than it, or 42dp while a glyph is drawn\n// beside it, plus the segment's rule. The track's width still never depends\n// on the choice: squeezed, its columns are the container's, shared equally.\n//\n// Angular Material delays the check's own transition by 45ms so the space\n// opens before the glyph arrives. That is dropped rather than carried as a\n// literal: there is no motion token for it, and the slot here opens from its\n// centre rather than its leading edge, so the check and the label never\n// cross even when the two run together.\n//\n// **The chosen container is an element of its own, and it moves.** It is\n// React Aria's `SelectionIndicator`, a shared element rendered inside every\n// segment and drawn in the chosen one: on a change it keeps the old one\n// until it has finished moving, so two exist while it slides. No\n// `SharedElementTransition` is rendered here, because `ToggleButtonGroup`\n// wraps its children in one already — worth saying, since the primitive\n// throws outside a scope wherever else it is used.\n//\n// It is the page's chosen container rather than a smaller pill: it covers\n// the segment, which is the box a background painted, so the fill is all\n// that travels. Three things follow. It is drawn behind the segments rather\n// than inside one, or a container crossing a neighbour would pass over that\n// neighbour's label and the rule beside it. Its corners have to match\n// whichever segment it is in, which the segment hands down as a custom\n// property, because a child cannot read its own parent's place in the track.\n// And the state layers move onto a layer of their own above it, since a\n// container that slides away would otherwise take the hover with it and off\n// the segment under the pointer.\n//\n// **Choosing several animates differently, rather than the same way twice.**\n// A shared element is one element: it can move between segments, but with\n// several chosen there is no single segment for it to be at. So\n// `selectionMode=\"multiple\"` names only `opacity` in the transition, nothing\n// positional is snapshotted, and each container fades in and out where it\n// is; `single` names `translate` and `border-radius` as well, and the one\n// container travels between segments.\n//\n// **Two of the page's values are the library's instead**, both for\n// consistency with the controls beside them: the focus ring, which is\n// primary at 2dp offset 2dp everywhere here rather than the page's secondary\n// at 3dp, and the press, which is the library's ripple rather than a flat\n// state layer. The page names a ripple as the pressed state, so the second\n// is a departure only in how it is drawn.\n//\n// **The density steps are not drawn.** The page removes 4dp of height per\n// step down, for denser interfaces; nothing else in the library takes a\n// density, and one component that did would be the odd one out. A shorter\n// track is a `className` away.\n//\n// Vertical is React Aria's and is not passed through, since the page draws\n// one row and a column of joined segments is a different shape — the outer\n// corners, the shared rule and the equal columns would all have to mean\n// something else.\n\n// Whether a chosen segment draws the check. A context rather than a prop on\n// each segment, since it is the set's decision and repeating it on every\n// segment is how the two drift.\nconst ShowSelectedIconContext = createContext(true);\n\n// Which of the two animations the chosen container plays. Read from a\n// context for the same reason, and because React Aria's own state context\n// holds the mode in a shape this would have to narrow before using.\nconst SelectionModeContext = createContext<SelectionMode>('single');\ntype GroupRender = RACToggleButtonGroupProps['render'];\ntype Ripple = ReturnType<typeof useRipple<FocusableElement>>;\ntype SelectionMode = NonNullable<RACToggleButtonGroupProps['selectionMode']>;\n\n// A segment's key, back from the attribute `SegmentedButtonSegment` writes\n// it into. JSON rather than the key as written, so a numeric key comes back\n// a number and matches the one React Aria's selection holds.\nfunction keyOf(segment: HTMLElement): Key | null {\n const written = segment.dataset.key;\n if (written === undefined) {\n return null;\n }\n const key: unknown = JSON.parse(written);\n return typeof key === 'string' || typeof key === 'number' ? key : null;\n}\n\n// The group's element, with `radioKeys` in place of React Aria's keyboard\n// handler, then handed to the call site's own `render` if it passed one.\nfunction radioGroupRenderer(render: GroupRender): NonNullable<GroupRender> {\n return (domProps, renderProps) => {\n const merged = {\n ...domProps,\n onKeyDownCapture: radioKeys(renderProps.state, domProps.onKeyDownCapture)\n };\n return render === undefined ? createElement('div', merged) : render(merged, renderProps);\n };\n}\n\n// The radio group's keys, taken ahead of React Aria's toolbar ones on the\n// same capture listener: the arrows, Home and End move focus to a segment\n// and choose it, wrapping at the ends and passing over a disabled segment,\n// which is what the toolbar's own handler would otherwise do with focus\n// alone. Everything else — Tab, and an arrow held with a modifier the\n// browser may want — is handed to the toolbar as before.\nfunction radioKeys(state: ToggleGroupState, toolbar: KeyboardEventHandler<HTMLDivElement> | undefined): KeyboardEventHandler<HTMLDivElement> {\n return event => {\n const group = event.currentTarget;\n const segments = [...group.querySelectorAll<HTMLElement>('[data-key]:not([data-disabled])')].filter(segment => segment.closest('[role=\"radiogroup\"]') === group);\n const from = segments.findIndex(segment => segment === event.target);\n const step = event.altKey || event.ctrlKey || event.metaKey ? null : stepOf(event.key, getComputedStyle(group).direction === 'rtl');\n if (from === -1 || step === null) {\n toolbar?.(event);\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const to = step === 'first' ? 0 : step === 'last' ? segments.length - 1 : (from + step + segments.length) % segments.length;\n const segment = segments[to];\n const key = keyOf(segment);\n if (key === null) {\n return;\n }\n segment.focus();\n state.setSelected(key, true);\n };\n}\n\n// Where a key moves the choice in a radio group: one segment on, one back,\n// or to either end. Right and left follow the direction the track is drawn\n// in, read off the track itself rather than the locale, so a `dir` on a\n// wrapper turns them over as it turns the track over; up and down, and Home\n// and End, follow the document order whatever the direction.\nfunction stepOf(key: string, rtl: boolean): -1 | 1 | 'first' | 'last' | null {\n switch (key) {\n case 'ArrowDown':\n {\n return 1;\n }\n case 'ArrowLeft':\n {\n return rtl ? 1 : -1;\n }\n case 'ArrowRight':\n {\n return rtl ? -1 : 1;\n }\n case 'ArrowUp':\n {\n return -1;\n }\n case 'End':\n {\n return 'last';\n }\n case 'Home':\n {\n return 'first';\n }\n default:\n {\n return null;\n }\n }\n}\n\n// The page's 18dp icon slot, and the room a segment keeps for it: the slot\n// plus the gap between it and the label. Half of that room sits on each side\n// of the label while nothing is drawn, which is what keeps a bare label\n// centred; see `labelReserved`.\nconst GLYPH_SIZE = '18px';\nconst GLYPH_RESERVE = `calc(${GLYPH_SIZE} + ${spacing.sm})`;\nconst GLYPH_RESERVE_HALF = `calc((${GLYPH_SIZE} + ${spacing.sm}) / 2)`;\n\n// The part of the page's 12dp padding a segment gives back on a narrow\n// track: the padding is 8dp, and the rest sits in the spacers, which shrink.\nconst PADDING_GIVE = `calc(${spacing.md} - ${spacing.sm})`;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n segment: {\n \"--segment-indicator-radius-end\": \"x32u3vw x111hk5a\",\n \"--segment-indicator-radius-start\": \"xatjrgw x1syycwj\",\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"x17kqlg\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1rv7mn0\",\n kVAM5u: \"x1fwvt7v\",\n kT0f0o: \"x1fougng xkducg2\",\n kVL7Gh: \"x1prwiuu x1uwupfv\",\n k2ei4v: \"x120dh57 x14e42zd\",\n kfmiAY: \"x17hb1p4 x1a37zkv\",\n krdFHd: \"xwfph4i xb01x1j\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xmkeg23\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kjj79g: \"xl56j7k\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n k7Eaqz: \"xeuugli\",\n k8WAf4: \"xt970qd\",\n kg3NbH: \"xn60lsn\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xt3l3uh\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n segmentDisabled: {\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8 x1bhcspo\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n segmentSelected: {\n kMwMTN: \"x1sawysd x1k5gbb1\",\n $$css: true\n },\n segmentSelectedUnmarked: {\n kMwMTN: \"x1lba3jz x1k5gbb1\",\n $$css: true\n },\n segmentUnselected: {\n kMwMTN: \"x139gbkf\",\n $$css: true\n },\n spacer: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"xs83m0k\",\n kzqmXN: \"xbraz1g\",\n kjj79g: \"x13a6bvl\",\n k7Eaqz: \"xeuugli\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x1pha8k4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n spacerHalf: {\n kzqmXN: \"x154zo0h\",\n $$css: true\n },\n spacerHolding: {\n kzqmXN: \"x1n85vuq\",\n k7Eaqz: \"x36sgg7\",\n $$css: true\n },\n spacerIcon: {\n kzqmXN: \"x1iuy3mw\",\n k7Eaqz: \"x16xo4sp\",\n $$css: true\n }\n};\ntype SegmentedButtonProps = LabelledByAttribute & Omit<RACToggleButtonGroupProps, 'className' | 'disallowEmptySelection' | 'orientation' | 'style'> & {\n /** A function may compute the class from the set's render state. */\n className?: RACToggleButtonGroupProps['className'];\n /**\n * Whether the chosen segment stays chosen when it is pressed again. On\n * by default while one is chosen, since a radio group always holds a\n * choice; `false` lets a press clear it, as React Aria's own default\n * does. Off by default while several may be, where any of them can be\n * turned off.\n * @default true while one is chosen, false while several may be\n */\n disallowEmptySelection?: boolean;\n /**\n * Whether a chosen segment draws a check before its label, as the page\n * has it. `false` leaves the segment's own icon in place while selected,\n * and draws the chosen segment on the stronger secondary container, since\n * the page's own is too faint to say which is chosen by itself.\n * @default true\n */\n showSelectedIcon?: boolean;\n /** A function may compute the style from the set's render state. */\n style?: RACToggleButtonGroupProps['style'];\n};\ntype SegmentedButtonSegmentProps = Omit<RACToggleButtonProps, 'children' | 'className' | 'id' | 'style'> & {\n /** The segment's label. */\n children?: ReactNode;\n /** A function may compute the class from the segment's render state. */\n className?: RACToggleButtonProps['className'];\n /**\n * Disables the press ripple. The hover and pressed state layers are\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * An icon before the label, in the page's 18dp size. Replaced by the check\n * while the segment is chosen, unless the set turns that off. An icon drawn\n * in `em` takes that size from the slot.\n *\n * Given with no label, the icon is the segment, centred in it and kept\n * while chosen; name the segment with `aria-label` then.\n */\n icon?: ReactNode;\n /**\n * The key selection is reported by. Required, because React Aria joins a\n * toggle to its group's selection by this key alone: a segment without one\n * keeps a pressed state of its own, so a set where one is chosen could hold\n * two, and it is announced as a pressed button rather than a radio.\n */\n id: Key;\n /** A function may compute the style from the segment's render state. */\n style?: RACToggleButtonProps['style'];\n};\n\n/**\n * What the glyph slot draws: the check on a chosen segment, or the segment's\n * own icon. `null` for a segment with neither, which leaves the slot empty\n * and closed rather than unrendered. Returns a node rather than letting the\n * type be inferred, since `ReactNode` is a union that includes a promise and\n * an inferred one has to be `async`.\n */\nfunction glyphFor(state: ToggleButtonRenderProps, icon: ReactNode, marked: boolean): ReactNode {\n if (state.isSelected && marked) {\n return <CheckGlyph className=\"x5yr21d x2lah0s x1xp8n7a\" />;\n }\n return icon ?? null;\n}\n\n// Whether a segment has a label, rather than an icon alone. An empty string\n// and a `false` from a condition at the call site are no label either.\nfunction hasLabel(children: ReactNode) {\n return children !== undefined && children !== null && children !== false && children !== '';\n}\n\n// The chosen container's class, from the segment's own state and the shared\n// element's. A function, because React Aria hands the indicator the entering\n// and leaving states the fade is drawn from, and those are the only two the\n// element knows about itself.\nfunction indicatorClassName(isDisabled: boolean, selectionMode: SelectionMode, marked: boolean): (state: SharedElementRenderProps) => string {\n return state => ({\n 0: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd\"\n },\n 8: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7\"\n },\n 4: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd x167r6xl x1jzqe4\"\n },\n 12: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 x167r6xl x1jzqe4\"\n },\n 2: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 10: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 6: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 14: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1\"\n },\n 1: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xg01cxk\"\n },\n 9: {\n className: \"x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xg01cxk\"\n },\n 5: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd x167r6xl x1jzqe4 xg01cxk\"\n },\n 13: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 x167r6xl x1jzqe4 xg01cxk\"\n },\n 3: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 11: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 7: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n },\n 15: {\n className: \"xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk\"\n }\n })[!!(selectionMode === 'multiple') << 3 | !!!marked << 2 | !!isDisabled << 1 | !!(state.isEntering || state.isExiting) << 0].className ?? '';\n}\n\n// What a segment draws, from React Aria's render state. Built by a call\n// rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result\n// on its inputs.\nfunction segmentContent(children: ReactNode, icon: ReactNode, ripple: Ripple, selectionMode: SelectionMode, marked: boolean, labelRef: (element: HTMLSpanElement | null) => void, labelTitle: string | undefined) {\n const labelled = hasLabel(children);\n // Whether this segment can ever draw a glyph, and so whether it keeps room\n // for one. A set that draws no check and a segment with no icon of its own\n // never needs the slot, and reserving it there would be dead space in\n // every segment of the track.\n const reserves = marked || icon !== undefined;\n return (state: ToggleButtonRenderProps) => {\n const glyph = glyphFor(state, icon, marked);\n const drawn = glyph !== null;\n return <>\n <RACSelectionIndicator className={indicatorClassName(state.isDisabled, selectionMode, marked)} />\n <span {...{\n 0: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi xg01cxk x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4\"\n },\n 4: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xe2qvxb\"\n },\n 2: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xcl2av\"\n },\n 6: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xcl2av\"\n },\n 1: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 5: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 3: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n },\n 7: {\n className: \"x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g\"\n }\n }[!!state.isHovered << 2 | !!state.isFocusVisible << 1 | !!state.isPressed << 0]} />\n <span {...stylex.props(styles.spacer, reserves && (drawn ? labelled ? styles.spacerHolding : styles.spacerIcon : styles.spacerHalf))}>\n {reserves && <span {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7\"\n },\n 2: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1nsf9p3\"\n },\n 3: {\n className: \"x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a x1nsf9p3\"\n }\n }[!!drawn << 1 | !!(drawn && labelled) << 0]}>\n {glyph}\n </span>}\n </span>\n {labelled && <span ref={labelRef} title={labelTitle} {...{\n 0: {\n className: \"x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft\"\n },\n 2: {\n className: \"x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8\"\n },\n 1: {\n className: \"x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1g12otp\"\n },\n 3: {\n className: \"x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8 x1g12otp\"\n }\n }[!!drawn << 1 | !!(state.isSelected && !state.isDisabled) << 0]}>\n {children}\n </span>}\n <span {...{\n 0: {\n className: \"x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k xbraz1g x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7\"\n },\n 1: {\n className: \"x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7 x154zo0h\"\n }\n }[!!(reserves && !drawn) << 0]} />\n {ripple.surface}\n </>;\n };\n}\n\n/**\n * A row of two to five joined segments, of which one — or with\n * `selectionMode=\"multiple\"`, several — is chosen. Selection is React Aria's:\n * pass `selectedKeys` with `onSelectionChange` to control it, or\n * `defaultSelectedKeys` to let it keep its own. Give every segment an `id`,\n * which is the key selection is reported by.\n *\n * ```tsx\n * <SegmentedButton aria-label=\"Label\" defaultSelectedKeys={['first']}>\n * <SegmentedButton.Segment id=\"first\">First item</SegmentedButton.Segment>\n * <SegmentedButton.Segment id=\"second\">Second item</SegmentedButton.Segment>\n * </SegmentedButton>\n * ```\n *\n * Name the set with `aria-label` or `aria-labelledby`, one of which the\n * props require — nothing here labels it for you, and a set with no name is\n * a group a screen reader cannot announce. What it is announced as follows the selection mode: choosing one\n * is a radio group, choosing several a toolbar of two-state buttons. So does\n * how the chosen container moves: it slides between segments while one is\n * chosen, and fades in place while several may be.\n *\n * Choosing one behaves as a radio group too, which React Aria's\n * `ToggleButtonGroup` does not. The chosen segment stays chosen when it is\n * pressed again, unless `disallowEmptySelection` is `false`. The arrow keys\n * move to a segment and choose it, wrapping at either end, and Home and End\n * choose the first and last. Choosing several keeps React Aria's keys: the\n * arrows move between segments, and Space or Enter toggles the focused one.\n *\n * The call site's `className` and `style` land on the track, which is the\n * element a layout positions.\n */\nfunction SegmentedButton({\n disallowEmptySelection,\n render,\n selectionMode = 'single',\n showSelectedIcon = true,\n ...props\n}: RefAttributes<HTMLDivElement> & SegmentedButtonProps) {\n const single = selectionMode === 'single';\n return <ShowSelectedIconContext value={showSelectedIcon}>\n <SelectionModeContext value={selectionMode}>\n <RACToggleButtonGroup {...props} disallowEmptySelection={disallowEmptySelection ?? single} render={single ? radioGroupRenderer(render) : render} selectionMode={selectionMode} {...mergeStatefulStyles({\n className: \"x9f619 xwz0xwf xu6a5m6 x1mt1orb xc8icb0\"\n }, props)} />\n </SelectionModeContext>\n </ShowSelectedIconContext>;\n}\n\n/**\n * One segment. Its `id` is what selection is reported by, and its label is\n * what names it. A chosen segment draws a check before the label; an\n * unchosen one draws whatever `icon` holds, if anything.\n */\nfunction SegmentedButtonSegment({\n children,\n disableRipple = false,\n icon,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n render,\n ...props\n}: RefAttributes<HTMLButtonElement> & SegmentedButtonSegmentProps) {\n const selectionMode = useContext(SelectionModeContext);\n // Whether this segment draws the check when chosen: the set's choice,\n // unless the segment has no label — see the header.\n const marked = useContext(ShowSelectedIconContext) && hasLabel(children);\n const [label, setLabel] = useState<HTMLSpanElement | null>(null);\n const labelTitle = useTruncatedText(label);\n // The `aria-*` props React Aria would drop and the keyboard handlers it\n // would wrap go on the element itself, as they do on Chip, Button and\n // IconButton; see src/render/aria.tsx.\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n // Off while disabled, as in Button: a control that cannot be pressed\n // should not answer a press with an animation. A disabled set disables\n // its segments through React Aria's group state rather than their props,\n // so the group is read as well.\n const disabledByGroup = useToggleGroupDisabled(props.id);\n // The call site's pointer handlers go through the ripple, which calls\n // them after its own. Spread beside the ripple's, one of the two sets\n // would write over the other.\n const ripple = useRipple<FocusableElement>(!disableRipple && props.isDisabled !== true && !disabledByGroup, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n return <RACToggleButton\n // The key the radio group's arrow keys choose this segment by; see\n // `radioKeys`. React Aria keeps a segment's key off its element.\n data-key={selectionMode === 'single' ? JSON.stringify(props.id) : undefined} render={toggleButtonRenderer(element, render)} {...ripple.handlers} {...props} {...mergeStatefulStyles(segmentStyles(marked), props)}>\n {segmentContent(children, icon, ripple, selectionMode, marked, setLabel, labelTitle)}\n </RACToggleButton>;\n}\n\n// StyleX cannot target `[data-selected]` on the element it is styling, so a\n// segment's state comes from the render state React Aria hands its\n// className. `disabled` is applied last so its label colour wins over both\n// of the others. Built by a call, since a set that draws no check labels its\n// chosen segment for the container it draws instead.\nfunction segmentStyles(marked: boolean) {\n return (state: ToggleButtonRenderProps) => stylex.props(styles.segment, focus.ring, state.isSelected ? styles.segmentSelected : styles.segmentUnselected, state.isSelected && !marked && styles.segmentSelectedUnmarked, state.isDisabled && styles.segmentDisabled);\n}\n\n// The text of a label its segment is cutting short, for a `title` that shows\n// it whole; undefined while it fits. Measured again whenever the label's box\n// or its text changes, which is when it can start or stop being cut.\nfunction useTruncatedText(label: HTMLElement | null): string | undefined {\n const [text, setText] = useState<string | undefined>(undefined);\n useLayoutEffect(() => {\n if (label === null) {\n return undefined;\n }\n const measure = () => {\n const cut = label.scrollWidth > label.clientWidth;\n setText(cut && label.textContent !== '' ? label.textContent : undefined);\n };\n measure();\n const resize = new ResizeObserver(measure);\n resize.observe(label);\n const relabel = new MutationObserver(measure);\n relabel.observe(label, {\n characterData: true,\n childList: true,\n subtree: true\n });\n return () => {\n resize.disconnect();\n relabel.disconnect();\n };\n }, [label]);\n return text;\n}\nSegmentedButton.Segment = SegmentedButtonSegment;\nexport type { SegmentedButtonProps, SegmentedButtonSegmentProps };\nexport { SegmentedButtonSegment };\nexport default SegmentedButton;"],"mappings":"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"}
|
|
@@ -26,16 +26,41 @@ type SeparatorProps$1 = {
|
|
|
26
26
|
* any other. Defaults to whatever the container asks for — a `Toolbar`
|
|
27
27
|
* asks for the rule across its own direction — and to horizontal outside
|
|
28
28
|
* one.
|
|
29
|
+
* @default 'horizontal'
|
|
29
30
|
*/
|
|
30
31
|
orientation?: 'horizontal' | 'vertical';
|
|
31
32
|
} & Omit<SeparatorProps, 'orientation'>;
|
|
32
33
|
/**
|
|
33
|
-
* A 1px rule between items
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
34
|
+
* A 1px rule between items: inset between list rows, across a toolbar's
|
|
35
|
+
* direction among its controls, and as `Menu.Separator` between groups of a
|
|
36
|
+
* menu's items.
|
|
37
|
+
*
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <Card padding="none" variant="outlined">
|
|
40
|
+
* <ListItem>First item</ListItem>
|
|
41
|
+
* <Separator inset="start" />
|
|
42
|
+
* <ListItem>Second item</ListItem>
|
|
43
|
+
* </Card>
|
|
44
|
+
*
|
|
45
|
+
* <Toolbar aria-label="Label">
|
|
46
|
+
* <Button variant="text">First</Button>
|
|
47
|
+
* <Separator />
|
|
48
|
+
* <Button variant="text">Second</Button>
|
|
49
|
+
* </Toolbar>
|
|
50
|
+
*
|
|
51
|
+
* <Menu.Content>
|
|
52
|
+
* <Menu.Item id="first">First item</Menu.Item>
|
|
53
|
+
* <Menu.Separator />
|
|
54
|
+
* <Menu.Item id="second">Second item</Menu.Item>
|
|
55
|
+
* </Menu.Content>
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* The orientation drives the accessibility tree as well as which side the
|
|
59
|
+
* rule is drawn on: horizontal renders an `<hr>` and vertical a `<div>`, each
|
|
60
|
+
* given the separator role, and the vertical one `aria-orientation="vertical"`
|
|
61
|
+
* besides. `decorative` takes the rule out of that tree altogether, for one
|
|
62
|
+
* that only draws a line between items that already carry their own
|
|
63
|
+
* structure.
|
|
39
64
|
*
|
|
40
65
|
* `inset` holds the rule off the ends it runs between — `start` off the
|
|
41
66
|
* leading one, `both` off each — which is what a rule between list rows
|
|
@@ -75,12 +75,36 @@ function decorativeRenderer(element, render) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* A 1px rule between items
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
78
|
+
* A 1px rule between items: inset between list rows, across a toolbar's
|
|
79
|
+
* direction among its controls, and as `Menu.Separator` between groups of a
|
|
80
|
+
* menu's items.
|
|
81
|
+
*
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <Card padding="none" variant="outlined">
|
|
84
|
+
* <ListItem>First item</ListItem>
|
|
85
|
+
* <Separator inset="start" />
|
|
86
|
+
* <ListItem>Second item</ListItem>
|
|
87
|
+
* </Card>
|
|
88
|
+
*
|
|
89
|
+
* <Toolbar aria-label="Label">
|
|
90
|
+
* <Button variant="text">First</Button>
|
|
91
|
+
* <Separator />
|
|
92
|
+
* <Button variant="text">Second</Button>
|
|
93
|
+
* </Toolbar>
|
|
94
|
+
*
|
|
95
|
+
* <Menu.Content>
|
|
96
|
+
* <Menu.Item id="first">First item</Menu.Item>
|
|
97
|
+
* <Menu.Separator />
|
|
98
|
+
* <Menu.Item id="second">Second item</Menu.Item>
|
|
99
|
+
* </Menu.Content>
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* The orientation drives the accessibility tree as well as which side the
|
|
103
|
+
* rule is drawn on: horizontal renders an `<hr>` and vertical a `<div>`, each
|
|
104
|
+
* given the separator role, and the vertical one `aria-orientation="vertical"`
|
|
105
|
+
* besides. `decorative` takes the rule out of that tree altogether, for one
|
|
106
|
+
* that only draws a line between items that already carry their own
|
|
107
|
+
* structure.
|
|
84
108
|
*
|
|
85
109
|
* `inset` holds the rule off the ends it runs between — `start` off the
|
|
86
110
|
* leading one, `both` off each — which is what a rule between list rows
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["c","_c","RefAttributes","SeparatorProps","RACSeparatorProps","stylex","createElement","Separator","RACSeparator","SeparatorContext","useSlottedContext","mergeStyles","colors","spacing","FORCED_COLORS","styles","base","kWkggS","kMzoRj","kB7OPa","kmuXW","kogj98","$$css","horizontal","kZKoxP","kLZC3w","kPef9Z","kEafiO","kzqmXN","vertical","kSGwAc","kGJrpR","kVhnKS","k2ei4v","k1xSpc","kAzted","kXLuUW","horizontalInsets","both","k71WvV","keTefX","none","start","verticalInsets","k1K539","keoZOQ","insets","SeparatorInset","decorative","inset","orientation","Omit","decorativeRenderer","element","render","NonNullable","domProps","renderProps","hidden","undefined","role","t0","$","t1","t2","props","context","slot","resolved","requested","elementType","T0","t3","t4","t5","Separator","_c","props","RACSeparator","stylex.props"],"sources":["../../../src/components/separator/index.tsx"],"sourcesContent":["'use client';\n\nimport type { RefAttributes } from 'react';\nimport type { SeparatorProps as RACSeparatorProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement } from 'react';\nimport { Separator as RACSeparator, SeparatorContext, useSlottedContext } from 'react-aria-components';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, 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// A divider is the same colour as a border, so it draws from outlineVariant\n// rather than a role of its own — the design system treats the two as one\n// decision, and a separator that drifted from the borders around it would\n// read as a mistake.\n//\n// Drawn as a background on a 1px box rather than as a border, so the rule is\n// the element itself. A border would leave the element's own box at zero\n// size, which makes it invisible to flex `gap` and to anything measuring it.\n// The horizontal element is an <hr>, which arrives with a border and a\n// margin of its own; both are zeroed here so it is the same 1px box a <div>\n// would be.\n//\n// Vertical takes its length from the flex or grid parent through\n// `alignSelf: stretch`, since a divider between two columns should match\n// whatever they turn out to be rather than being told a height at the call\n// site. Anywhere else there is nothing to stretch to, so it falls back to\n// `1em`, one line of the text around it, and sits in that line as an inline\n// block rather than breaking it: between two words in a paragraph it is a\n// short upright bar, rather than a 1px box with no height that draws\n// nothing. The divider page gives no length for a vertical rule standing on\n// its own, so the `1em` is this library's choice. Inside a flex or grid\n// parent the inline display is blockified and the floor sits below any\n// length the parent stretches it to, so neither changes the rule there.\n//\n// The divider page gives three forms and this draws all three: full width,\n// inset by 16dp at the leading end, and middle-inset by 16dp at both. The\n// page names them \"inset\" and \"middle-inset\"; the prop says `start` and\n// `both` instead, since `inset=\"inset\"` reads as nothing at all and the two\n// words say which ends move.\n//\n// The inset is drawn as a margin on the logical axis the rule runs along, so\n// it follows the writing mode and works for a vertical rule as well — the\n// page only draws horizontal ones, but a shortened vertical rule between two\n// columns is the same idea and would otherwise have to be written at the\n// call site. An inset rule's length is `100%` less its margins: a margin\n// sits outside the box, so a full-width rule with one would overflow its\n// parent by exactly the inset, and `auto` in its place gives an empty `<hr>`\n// a width only where the parent stretches it — in a flex row, or a parent\n// centring its children, the rule came out 0 wide and vanished.\n//\n// The orientation is resolved rather than defaulted eagerly, so a container\n// that sets one through React Aria's separator context reaches it. Toolbar\n// is what needs that: a rule between two controls in a row is vertical, and\n// a `Separator` written inside one should not have to say so. React Aria's\n// own `Toolbar` sets no such context — it puts the orientation on itself and\n// nothing else — so ours provides it, and this is the half that reads it.\nconst styles = {\n base: {\n kWkggS: \"x1l12bh\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kogj98: \"x1ghz6dp\",\n $$css: true\n },\n horizontal: {\n kZKoxP: \"xjm9jq1\",\n kLZC3w: \"x19dwuzr\",\n kPef9Z: \"x4z998w\",\n kEafiO: \"x1lym3mf\",\n kzqmXN: \"xh8yej3\",\n $$css: true\n },\n vertical: {\n kSGwAc: \"xkh2ocl\",\n kGJrpR: \"xjslfuv\",\n kVhnKS: \"x1gbqego\",\n k2ei4v: \"xjg5lhu\",\n k1xSpc: \"x1rg5ohu\",\n kzqmXN: \"x1i1rx1s\",\n kAzted: \"x1xaadd7\",\n kXLuUW: \"xxymvpz\",\n $$css: true\n }\n};\n\n// The page's 16dp, on whichever axis the rule runs along. The length is the\n// full-width rule's `100%` less the margins, which keeps the rule inside its\n// parent — a margin outside a 100% box overflows by the inset — and still\n// gives it a width in every layout, where `auto` gives an `<hr>` with no\n// content one only in a parent that stretches it.\nconst horizontalInsets = {\n both: {\n kzqmXN: \"x1n0idw\",\n k71WvV: \"xdf1gh2\",\n keTefX: \"x1m7rnnc\",\n $$css: true\n },\n none: {\n $$css: true\n },\n start: {\n kzqmXN: \"x1u7osep\",\n keTefX: \"x1m7rnnc\",\n $$css: true\n }\n};\n\n// A vertical rule takes its length from the parent through `alignSelf`, so\n// the margin shortens it from the end it is on rather than moving it. The\n// `1em` floor is the rule's own length and the margins sit outside it: a\n// stretched rule is shortened down to the floor and no further, and one with\n// no parent to stretch to keeps its `1em` and takes the inset as space above\n// and below, since there is no length of the parent's for it to hold off.\nconst verticalInsets = {\n both: {\n k1K539: \"xxkrg4w\",\n keoZOQ: \"xwf6w2j\",\n $$css: true\n },\n none: {\n $$css: true\n },\n start: {\n keoZOQ: \"xwf6w2j\",\n $$css: true\n }\n};\nconst insets = {\n horizontal: horizontalInsets,\n vertical: verticalInsets\n};\ntype SeparatorInset = 'both' | 'none' | 'start';\ntype SeparatorProps = {\n /**\n * Takes the rule out of the accessibility tree, for a divider that only\n * draws a line between things that already say where each starts — the\n * sections of a `DisclosureGroup`, or rows that are each a control. A\n * reader then hears nothing between them rather than \"separator\" at every\n * one. The rule draws the same either way.\n * @default false\n */\n decorative?: boolean;\n /**\n * How far the rule is held off the edges it runs between. `start` holds it\n * 16dp off the leading end, which is the page's inset divider; `both`\n * holds it off each end, which is its middle-inset one. The inset follows\n * the writing mode rather than a fixed side.\n * @default 'none'\n */\n inset?: SeparatorInset;\n /**\n * Which way the rule runs. A vertical separator takes its length from a\n * flex or grid parent, and is one line of the text around it, `1em`, in\n * any other. Defaults to whatever the container asks for — a `Toolbar`\n * asks for the rule across its own direction — and to horizontal outside\n * one.\n */\n orientation?: 'horizontal' | 'vertical';\n} & Omit<RACSeparatorProps, 'orientation'>;\n\n// A rule taken out of the accessibility tree. React Aria passes on neither\n// `aria-hidden` nor `role` from a separator's props, and sets the separator\n// role itself, so the element is rewritten in its render function, after\n// both: hidden, with the role and orientation it would be announced by\n// dropped. A render function from the call site still gets the last word.\nfunction decorativeRenderer(element: string, render: RACSeparatorProps['render']): NonNullable<RACSeparatorProps['render']> {\n return (domProps, renderProps) => {\n const hidden = {\n ...domProps,\n 'aria-hidden': true,\n 'aria-orientation': undefined,\n role: undefined\n };\n return render === undefined ? createElement(element, hidden) : render(hidden, renderProps);\n };\n}\n\n/**\n * A 1px rule between items. The orientation drives the accessibility tree as\n * well as which side the rule is drawn on: horizontal renders an `<hr>`,\n * whose role and orientation are implicit, and vertical a `<div>` given the\n * separator role and `aria-orientation=\"vertical\"`. `decorative` takes the\n * rule out of that tree altogether, for one that only draws a line between\n * items that already carry their own structure.\n *\n * `inset` holds the rule off the ends it runs between — `start` off the\n * leading one, `both` off each — which is what a rule between list rows\n * takes so it lines up with their text rather than the container's edge.\n *\n * React Aria's rather than a styled element of the library's own, so a\n * `Menu` or `Toolbar` around it reaches it through context — a separator\n * between menu items is part of the collection, and one in a toolbar takes\n * the rule across the toolbar's own direction. `elementType` picks a\n * different element, and `render` is React Aria's function form.\n */\nfunction Separator({\n decorative = false,\n inset = 'none',\n orientation,\n render,\n ...props\n}: RefAttributes<HTMLElement> & SeparatorProps) {\n const context = useSlottedContext(SeparatorContext, props.slot);\n const resolved = orientation ?? context?.orientation ?? 'horizontal';\n // The element React Aria renders, which its render function is held to:\n // an <hr> unless the call site or a container asks for another, and a\n // <div> in place of a vertical <hr>.\n const requested = props.elementType ?? context?.elementType ?? 'hr';\n const element = requested === 'hr' && resolved === 'vertical' ? 'div' : requested;\n return <RACSeparator orientation={resolved} render={decorative ? decorativeRenderer(element, render) : render} {...props} {...mergeStyles(stylex.props(styles.base, styles[resolved], insets[resolved][inset]), props)} />;\n}\nexport type { SeparatorInset, SeparatorProps };\nexport default Separator;"],"mappings":";;;;;;;;AA+DA,MAAMe,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,OAAO;CACT;CACAC,YAAY;EACVC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRN,OAAO;CACT;CACAO,UAAU;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRN,QAAQ;EACRO,QAAQ;EACRC,QAAQ;EACRd,OAAO;CACT;AACF;AA4CA,MAAMwB,SAAS;CACbvB,YAAYc;EArCZC,MAAM;GACJV,QAAQ;GACRW,QAAQ;GACRC,QAAQ;GACRlB,OAAO;EACT;EACAmB,MAAM,EACJnB,OAAO,KACT;EACAoB,OAAO;GACLd,QAAQ;GACRY,QAAQ;GACRlB,OAAO;EACT;CAwBYe;CACZR,UAAUc;EAfVL,MAAM;GACJM,QAAQ;GACRC,QAAQ;GACRvB,OAAO;EACT;EACAmB,MAAM,EACJnB,OAAO,KACT;EACAoB,OAAO;GACLG,QAAQ;GACRvB,OAAO;EACT;CAIUqB;AACZ;AAmCA,SAASS,mBAAmBC,SAAiBC,QAA+E;CAC1H,QAAQE,UAAUC,gBAAgB;EAChC,MAAMC,SAAS;GACb,GAAGF;GACH,eAAe;GACf,oBAAoBG,KAAAA;GACpBC,MAAMD,KAAAA;EACR;EACA,OAAOL,WAAWK,KAAAA,IAAYrD,cAAc+C,SAASK,MAAM,IAAIJ,OAAOI,QAAQD,WAAW;CAC3F;AACF;;;;;;;;;;;;;;;;;;;AAoBA,SAAAlD,YAAAsD,IAAA;CAAA,MAAAC,IAAA7D,EAAA,CAAA;CAAmB,MAAA,EAAA+C,YAAAe,IAAAd,OAAAe,IAAAd,aAAAI,QAAA,GAAAW,YAAAJ;CACjB,MAAAb,aAAAe,OAAAJ,KAAAA,IAAA,QAAAI;CACA,MAAAd,QAAAe,OAAAL,KAAAA,IAAA,SAAAK;CAKA,MAAAE,UAAgBxD,kBAAkBD,kBAAkBwD,QAAKE,IAAK;CAC9D,MAAAC,WAAiBlB,eAAegB,SAAOhB,eAAtB;CAIjB,MAAAmB,YAAkBJ,QAAKK,eAAgBJ,SAAOI,eAA5B;CAClB,MAAAjB,UAAgBgB,cAAc,QAAQD,aAAa,aAAnC,QAAAC;CACR,MAAAE,KAAA/D;CAA4C,MAAAgE,KAAAxB,aAAaI,mBAAmBC,SAASC,MAAe,IAAxDA;CAA0E,MAAAmB,KAAA9D,YAAYN,MAAaU,OAAMC,MAAOD,OAAOqD,WAAWtB,OAAOsB,SAAS,CAACnB,MAAM,GAAGgB,OAAK;CAAC,IAAAS;CAAA,IAAAZ,EAAA,OAAAS,MAAAT,EAAA,OAAAG,WAAAH,EAAA,OAAAM,YAAAN,EAAA,OAAAU,MAAAV,EAAA,OAAAW,IAAA;EAA/MC,KAAA,oBAAC,IAAD;GAA2BN,aAAAA;GAAkB,QAAAI;GAAyD,GAAMP;GAAK,GAAMQ;EAAwF,CAAA;EAAIX,EAAA,KAAAS;EAAAT,EAAA,KAAAG;EAAAH,EAAA,KAAAM;EAAAN,EAAA,KAAAU;EAAAV,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,OAAnNY;AAAmN"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["c","_c","RefAttributes","SeparatorProps","RACSeparatorProps","stylex","createElement","Separator","RACSeparator","SeparatorContext","useSlottedContext","mergeStyles","colors","spacing","FORCED_COLORS","styles","base","kWkggS","kMzoRj","kB7OPa","kmuXW","kogj98","$$css","horizontal","kZKoxP","kLZC3w","kPef9Z","kEafiO","kzqmXN","vertical","kSGwAc","kGJrpR","kVhnKS","k2ei4v","k1xSpc","kAzted","kXLuUW","horizontalInsets","both","k71WvV","keTefX","none","start","verticalInsets","k1K539","keoZOQ","insets","SeparatorInset","decorative","inset","orientation","Omit","decorativeRenderer","element","render","NonNullable","domProps","renderProps","hidden","undefined","role","t0","$","t1","t2","props","context","slot","resolved","requested","elementType","T0","t3","t4","t5","Separator","_c","props","RACSeparator","stylex.props"],"sources":["../../../src/components/separator/index.tsx"],"sourcesContent":["'use client';\n\nimport type { RefAttributes } from 'react';\nimport type { SeparatorProps as RACSeparatorProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement } from 'react';\nimport { Separator as RACSeparator, SeparatorContext, useSlottedContext } from 'react-aria-components';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, 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// A divider is the same colour as a border, so it draws from outlineVariant\n// rather than a role of its own — the design system treats the two as one\n// decision, and a separator that drifted from the borders around it would\n// read as a mistake.\n//\n// Drawn as a background on a 1px box rather than as a border, so the rule is\n// the element itself. A border would leave the element's own box at zero\n// size, which makes it invisible to flex `gap` and to anything measuring it.\n// The horizontal element is an <hr>, which arrives with a border and a\n// margin of its own; both are zeroed here so it is the same 1px box a <div>\n// would be.\n//\n// Vertical takes its length from the flex or grid parent through\n// `alignSelf: stretch`, since a divider between two columns should match\n// whatever they turn out to be rather than being told a height at the call\n// site. Anywhere else there is nothing to stretch to, so it falls back to\n// `1em`, one line of the text around it, and sits in that line as an inline\n// block rather than breaking it: between two words in a paragraph it is a\n// short upright bar, rather than a 1px box with no height that draws\n// nothing. The divider page gives no length for a vertical rule standing on\n// its own, so the `1em` is this library's choice. Inside a flex or grid\n// parent the inline display is blockified and the floor sits below any\n// length the parent stretches it to, so neither changes the rule there.\n//\n// The divider page gives three forms and this draws all three: full width,\n// inset by 16dp at the leading end, and middle-inset by 16dp at both. The\n// page names them \"inset\" and \"middle-inset\"; the prop says `start` and\n// `both` instead, since `inset=\"inset\"` reads as nothing at all and the two\n// words say which ends move.\n//\n// The inset is drawn as a margin on the logical axis the rule runs along, so\n// it follows the writing mode and works for a vertical rule as well — the\n// page only draws horizontal ones, but a shortened vertical rule between two\n// columns is the same idea and would otherwise have to be written at the\n// call site. An inset rule's length is `100%` less its margins: a margin\n// sits outside the box, so a full-width rule with one would overflow its\n// parent by exactly the inset, and `auto` in its place gives an empty `<hr>`\n// a width only where the parent stretches it — in a flex row, or a parent\n// centring its children, the rule came out 0 wide and vanished.\n//\n// The orientation is resolved rather than defaulted eagerly, so a container\n// that sets one through React Aria's separator context reaches it. Toolbar\n// is what needs that: a rule between two controls in a row is vertical, and\n// a `Separator` written inside one should not have to say so. React Aria's\n// own `Toolbar` sets no such context — it puts the orientation on itself and\n// nothing else — so ours provides it, and this is the half that reads it.\nconst styles = {\n base: {\n kWkggS: \"x1l12bh\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kogj98: \"x1ghz6dp\",\n $$css: true\n },\n horizontal: {\n kZKoxP: \"xjm9jq1\",\n kLZC3w: \"x19dwuzr\",\n kPef9Z: \"x4z998w\",\n kEafiO: \"x1lym3mf\",\n kzqmXN: \"xh8yej3\",\n $$css: true\n },\n vertical: {\n kSGwAc: \"xkh2ocl\",\n kGJrpR: \"xjslfuv\",\n kVhnKS: \"x1gbqego\",\n k2ei4v: \"xjg5lhu\",\n k1xSpc: \"x1rg5ohu\",\n kzqmXN: \"x1i1rx1s\",\n kAzted: \"x1xaadd7\",\n kXLuUW: \"xxymvpz\",\n $$css: true\n }\n};\n\n// The page's 16dp, on whichever axis the rule runs along. The length is the\n// full-width rule's `100%` less the margins, which keeps the rule inside its\n// parent — a margin outside a 100% box overflows by the inset — and still\n// gives it a width in every layout, where `auto` gives an `<hr>` with no\n// content one only in a parent that stretches it.\nconst horizontalInsets = {\n both: {\n kzqmXN: \"x1n0idw\",\n k71WvV: \"xdf1gh2\",\n keTefX: \"x1m7rnnc\",\n $$css: true\n },\n none: {\n $$css: true\n },\n start: {\n kzqmXN: \"x1u7osep\",\n keTefX: \"x1m7rnnc\",\n $$css: true\n }\n};\n\n// A vertical rule takes its length from the parent through `alignSelf`, so\n// the margin shortens it from the end it is on rather than moving it. The\n// `1em` floor is the rule's own length and the margins sit outside it: a\n// stretched rule is shortened down to the floor and no further, and one with\n// no parent to stretch to keeps its `1em` and takes the inset as space above\n// and below, since there is no length of the parent's for it to hold off.\nconst verticalInsets = {\n both: {\n k1K539: \"xxkrg4w\",\n keoZOQ: \"xwf6w2j\",\n $$css: true\n },\n none: {\n $$css: true\n },\n start: {\n keoZOQ: \"xwf6w2j\",\n $$css: true\n }\n};\nconst insets = {\n horizontal: horizontalInsets,\n vertical: verticalInsets\n};\ntype SeparatorInset = 'both' | 'none' | 'start';\ntype SeparatorProps = {\n /**\n * Takes the rule out of the accessibility tree, for a divider that only\n * draws a line between things that already say where each starts — the\n * sections of a `DisclosureGroup`, or rows that are each a control. A\n * reader then hears nothing between them rather than \"separator\" at every\n * one. The rule draws the same either way.\n * @default false\n */\n decorative?: boolean;\n /**\n * How far the rule is held off the edges it runs between. `start` holds it\n * 16dp off the leading end, which is the page's inset divider; `both`\n * holds it off each end, which is its middle-inset one. The inset follows\n * the writing mode rather than a fixed side.\n * @default 'none'\n */\n inset?: SeparatorInset;\n /**\n * Which way the rule runs. A vertical separator takes its length from a\n * flex or grid parent, and is one line of the text around it, `1em`, in\n * any other. Defaults to whatever the container asks for — a `Toolbar`\n * asks for the rule across its own direction — and to horizontal outside\n * one.\n * @default 'horizontal'\n */\n orientation?: 'horizontal' | 'vertical';\n} & Omit<RACSeparatorProps, 'orientation'>;\n\n// A rule taken out of the accessibility tree. React Aria passes on neither\n// `aria-hidden` nor `role` from a separator's props, and sets the separator\n// role itself, so the element is rewritten in its render function, after\n// both: hidden, with the role and orientation it would be announced by\n// dropped. A render function from the call site still gets the last word.\nfunction decorativeRenderer(element: string, render: RACSeparatorProps['render']): NonNullable<RACSeparatorProps['render']> {\n return (domProps, renderProps) => {\n const hidden = {\n ...domProps,\n 'aria-hidden': true,\n 'aria-orientation': undefined,\n role: undefined\n };\n return render === undefined ? createElement(element, hidden) : render(hidden, renderProps);\n };\n}\n\n/**\n * A 1px rule between items: inset between list rows, across a toolbar's\n * direction among its controls, and as `Menu.Separator` between groups of a\n * menu's items.\n *\n * ```tsx\n * <Card padding=\"none\" variant=\"outlined\">\n * <ListItem>First item</ListItem>\n * <Separator inset=\"start\" />\n * <ListItem>Second item</ListItem>\n * </Card>\n *\n * <Toolbar aria-label=\"Label\">\n * <Button variant=\"text\">First</Button>\n * <Separator />\n * <Button variant=\"text\">Second</Button>\n * </Toolbar>\n *\n * <Menu.Content>\n * <Menu.Item id=\"first\">First item</Menu.Item>\n * <Menu.Separator />\n * <Menu.Item id=\"second\">Second item</Menu.Item>\n * </Menu.Content>\n * ```\n *\n * The orientation drives the accessibility tree as well as which side the\n * rule is drawn on: horizontal renders an `<hr>` and vertical a `<div>`, each\n * given the separator role, and the vertical one `aria-orientation=\"vertical\"`\n * besides. `decorative` takes the rule out of that tree altogether, for one\n * that only draws a line between items that already carry their own\n * structure.\n *\n * `inset` holds the rule off the ends it runs between — `start` off the\n * leading one, `both` off each — which is what a rule between list rows\n * takes so it lines up with their text rather than the container's edge.\n *\n * React Aria's rather than a styled element of the library's own, so a\n * `Menu` or `Toolbar` around it reaches it through context — a separator\n * between menu items is part of the collection, and one in a toolbar takes\n * the rule across the toolbar's own direction. `elementType` picks a\n * different element, and `render` is React Aria's function form.\n */\nfunction Separator({\n decorative = false,\n inset = 'none',\n orientation,\n render,\n ...props\n}: RefAttributes<HTMLElement> & SeparatorProps) {\n const context = useSlottedContext(SeparatorContext, props.slot);\n const resolved = orientation ?? context?.orientation ?? 'horizontal';\n // The element React Aria renders, which its render function is held to:\n // an <hr> unless the call site or a container asks for another, and a\n // <div> in place of a vertical <hr>.\n const requested = props.elementType ?? context?.elementType ?? 'hr';\n const element = requested === 'hr' && resolved === 'vertical' ? 'div' : requested;\n return <RACSeparator orientation={resolved} render={decorative ? decorativeRenderer(element, render) : render} {...props} {...mergeStyles(stylex.props(styles.base, styles[resolved], insets[resolved][inset]), props)} />;\n}\nexport type { SeparatorInset, SeparatorProps };\nexport default Separator;"],"mappings":";;;;;;;;AA+DA,MAAMe,SAAS;CACbC,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,OAAO;CACT;CACAC,YAAY;EACVC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRN,OAAO;CACT;CACAO,UAAU;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRN,QAAQ;EACRO,QAAQ;EACRC,QAAQ;EACRd,OAAO;CACT;AACF;AA4CA,MAAMwB,SAAS;CACbvB,YAAYc;EArCZC,MAAM;GACJV,QAAQ;GACRW,QAAQ;GACRC,QAAQ;GACRlB,OAAO;EACT;EACAmB,MAAM,EACJnB,OAAO,KACT;EACAoB,OAAO;GACLd,QAAQ;GACRY,QAAQ;GACRlB,OAAO;EACT;CAwBYe;CACZR,UAAUc;EAfVL,MAAM;GACJM,QAAQ;GACRC,QAAQ;GACRvB,OAAO;EACT;EACAmB,MAAM,EACJnB,OAAO,KACT;EACAoB,OAAO;GACLG,QAAQ;GACRvB,OAAO;EACT;CAIUqB;AACZ;AAoCA,SAASS,mBAAmBC,SAAiBC,QAA+E;CAC1H,QAAQE,UAAUC,gBAAgB;EAChC,MAAMC,SAAS;GACb,GAAGF;GACH,eAAe;GACf,oBAAoBG,KAAAA;GACpBC,MAAMD,KAAAA;EACR;EACA,OAAOL,WAAWK,KAAAA,IAAYrD,cAAc+C,SAASK,MAAM,IAAIJ,OAAOI,QAAQD,WAAW;CAC3F;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAAlD,YAAAsD,IAAA;CAAA,MAAAC,IAAA7D,EAAA,CAAA;CAAmB,MAAA,EAAA+C,YAAAe,IAAAd,OAAAe,IAAAd,aAAAI,QAAA,GAAAW,YAAAJ;CACjB,MAAAb,aAAAe,OAAAJ,KAAAA,IAAA,QAAAI;CACA,MAAAd,QAAAe,OAAAL,KAAAA,IAAA,SAAAK;CAKA,MAAAE,UAAgBxD,kBAAkBD,kBAAkBwD,QAAKE,IAAK;CAC9D,MAAAC,WAAiBlB,eAAegB,SAAOhB,eAAtB;CAIjB,MAAAmB,YAAkBJ,QAAKK,eAAgBJ,SAAOI,eAA5B;CAClB,MAAAjB,UAAgBgB,cAAc,QAAQD,aAAa,aAAnC,QAAAC;CACR,MAAAE,KAAA/D;CAA4C,MAAAgE,KAAAxB,aAAaI,mBAAmBC,SAASC,MAAe,IAAxDA;CAA0E,MAAAmB,KAAA9D,YAAYN,MAAaU,OAAMC,MAAOD,OAAOqD,WAAWtB,OAAOsB,SAAS,CAACnB,MAAM,GAAGgB,OAAK;CAAC,IAAAS;CAAA,IAAAZ,EAAA,OAAAS,MAAAT,EAAA,OAAAG,WAAAH,EAAA,OAAAM,YAAAN,EAAA,OAAAU,MAAAV,EAAA,OAAAW,IAAA;EAA/MC,KAAA,oBAAC,IAAD;GAA2BN,aAAAA;GAAkB,QAAAI;GAAyD,GAAMP;GAAK,GAAMQ;EAAwF,CAAA;EAAIX,EAAA,KAAAS;EAAAT,EAAA,KAAAG;EAAAH,EAAA,KAAAM;EAAAN,EAAA,KAAAU;EAAAV,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,OAAnNY;AAAmN"}
|