@kanso-labs/kanso-ui 0.31.0 → 0.31.1
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/dist/components/icon-button/index.js +6 -0
- package/dist/components/icon-button/index.js.map +1 -1
- package/dist/components/number-field/index.js +2 -2
- package/dist/components/number-field/index.js.map +1 -1
- package/dist/components/snackbar/index.d.ts +7 -4
- package/dist/components/snackbar/index.js.map +1 -1
- package/dist/components/switch/index.js +5 -0
- package/dist/components/switch/index.js.map +1 -1
- package/dist/control/styles.js +3 -0
- package/dist/control/styles.js.map +1 -1
- package/dist/styles.css +16 -0
- package/package.json +2 -2
|
@@ -63,6 +63,9 @@ const styles = {
|
|
|
63
63
|
$$css: true
|
|
64
64
|
},
|
|
65
65
|
md: {
|
|
66
|
+
kgeoSG: "x1cpjm7i",
|
|
67
|
+
kFcpXp: "x1q69gdh",
|
|
68
|
+
kEoFBp: "x1hmns74",
|
|
66
69
|
kZKoxP: "x1rv7mn0",
|
|
67
70
|
kaIpWk: "x1r81nxe x1dkaolv",
|
|
68
71
|
kGuDYH: "x1pvqxga",
|
|
@@ -134,6 +137,9 @@ const styles = {
|
|
|
134
137
|
$$css: true
|
|
135
138
|
},
|
|
136
139
|
xs: {
|
|
140
|
+
kgeoSG: "x1cpjm7i",
|
|
141
|
+
kFcpXp: "x1n6cgzf",
|
|
142
|
+
kEoFBp: "x1hmns74",
|
|
137
143
|
kZKoxP: "xig8zya",
|
|
138
144
|
kaIpWk: "x1r81nxe x1dkaolv",
|
|
139
145
|
kGuDYH: "xwsyq91",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["ReactNode","ButtonRenderProps","ClassNameOrFunction","DOMRenderFunction","FocusableElement","StyleOrFunction","stylex","ButtonContext","Button","RACButton","Link","RACLink","ToggleButton","RACToggleButton","useSlottedContext","ButtonDOMProps","ButtonState","useRipple","ariaAttributesOf","buttonRenderer","linkRenderer","toggleButtonRenderer","focus","mergeStatefulStyles","colors","motion","radii","sizing","stateLayerOpacity","ProgressIndicator","Ripple","ReturnType","styles","base","k6CgDc","kGNEyG","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kmVPX3","kVAEAm","kybGjl","kIyJzY","k1ekBW","kAMwcw","$$css","disabled","filled","kWkggS","kMwMTN","filledDisabled","filledToggle","label","labelPending","k33iCy","lg","kZKoxP","kGuDYH","kzqmXN","md","outlined","kVAM5u","ksu8eU","outlinedDisabled","outlinedToggleSelected","pending","kpwlN0","standard","standardDisabled","standardToggleSelected","tonal","tonalDisabled","tonalToggleSelected","xl","xs","xxl","outlineWidths","selectedShapes","toggleStyles","selected","unselected","disabledStyles","IconButtonProps","children","className","IconButtonState","defaultSelected","disableRipple","href","isSelected","onChange","pendingLabel","rel","render","size","IconButtonSize","style","target","variant","IconButtonVariant","Omit","buttonContent","ripple","state","isPending","surface","IconButton","t0","$","_c","t1","isDisabled","t2","onClick","onContextMenu","onKeyDown","onKeyUp","onPointerCancel","onPointerDown","onPointerLeave","onPointerUp","t3","t4","t5","props","undefined","context","slot","t6","element","aria","t7","t8","handlers","t9","toggleStyleProps","t10","toggleContent","ring","styleProps","T0","t11"],"sources":["../../../src/components/icon-button/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, DOMRenderFunction, FocusableElement, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { ButtonContext, Button as RACButton, Link as RACLink, ToggleButton as RACToggleButton, useSlottedContext } from 'react-aria-components';\nimport type { ButtonDOMProps, ButtonState } from '../button';\nimport { useRipple } from '../../hooks/useRipple';\nimport { ariaAttributesOf, buttonRenderer, linkRenderer, toggleButtonRenderer } from '../../render/aria';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\nimport ProgressIndicator from '../progress-indicator';\n\n// Each variant composites an 'on-color' over its own container at the\n// interaction state's opacity, rather than swapping in a separate hover\n// color. The pairs are the icon buttons spec page's: filled on primary,\n// tonal on secondary container, outlined with an outline variant border and\n// an on-surface-variant icon, standard on surface variant over nothing. calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes. Inlined at each property rather than factored\n// into a helper: @stylexjs/babel-plugin only statically recognizes\n// expressions written directly as property values.\n//\n// Disabled is a style of its own per variant rather than a `:disabled`\n// branch inside each property, for the reason Button's comment gives: given\n// `href` this renders as a link, which React Aria turns into a <span> while\n// disabled, and neither matches the pseudo-class. Applied last from the\n// render state, the disabled styles replace each property whole, hover and\n// pressed branches included.\n//\n// **The outlined border thickens with the size, and the widths are Button's\n// rather than this page's.** The icon buttons page keeps them in a size token\n// set its widget will not open to a script, and the two components already\n// share their five heights on purpose — a 96dp icon button beside a 96dp\n// outlined button with a different border weight would read as a mistake.\n//\n// **A toggle is the same button reporting a state.** Given `isSelected`,\n// `defaultSelected` or `onChange` it is React Aria's `ToggleButton` instead\n// of its `Button`, which announces the state through `aria-pressed` rather\n// than a role of its own — every variant and size still applies. The page\n// gives each style a second pair of colour roles for it, and they are not\n// the plain button's: a filled toggle rests on surface container with an\n// on-surface-variant icon and takes primary once chosen, a tonal one rests\n// on secondary container and takes secondary, and a standard one is\n// transparent throughout with the icon going from on-surface-variant to\n// primary, and an outlined one swaps its border for the inverse surface\n// pair. So a chosen filled toggle looks like a plain filled button, and an\n// unchosen one does not.\n//\n// A toggle is never a link and never pending. React Aria's `ToggleButton`\n// takes neither, and neither means anything for a control whose whole job is\n// to report which of two states it is in.\n//\n// The corner softens from a circle to a rounded square while pressed, which\n// is the shape morph the icon buttons spec page gives this control, at the\n// pressed corner its size token set names: 8 for the two small sizes, 12 at\n// medium, 16 at the two large. Each size carries its own pressed radius, since\n// StyleX replaces the property whole. The two transitioned properties take\n// different curves — the colour change is linear-ish and the shape change is\n// emphasized — so the timing functions are a matching comma list rather than\n// one value.\n//\n// A chosen toggle rests at that same pressed corner, which is the page's\n// shape morph: a toggle icon button moves from round while unchosen to\n// square once chosen. The square shape's own corner sits in a token set the\n// page keeps behind its size menu, but the page also says both shapes press\n// to the same radius — so the size's pressed corner is the value it already\n// assigns to that size, used here at rest rather than invented.\ntype Ripple = ReturnType<typeof useRipple<FocusableElement>>;\nconst styles = {\n base: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1717udv\",\n kVAEAm: \"x1n2onr6\",\n kybGjl: \"x1hl2dhg\",\n kIyJzY: \"x1iuyhda\",\n k1ekBW: \"xb5u718\",\n kAMwcw: \"x15l9jch\",\n $$css: true\n },\n disabled: {\n kaIpWk: \"x1dkaolv\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n filled: {\n kWkggS: \"xpky1to xyf7a0q xnety89\",\n kMwMTN: \"xwjo7ld\",\n $$css: true\n },\n filledDisabled: {\n kWkggS: \"xepofeg\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n filledToggle: {\n kWkggS: \"xbck2fw x1h1ujn1 x1mjdul6\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n label: {\n k1xSpc: \"xjp7ctv\",\n $$css: true\n },\n labelPending: {\n k33iCy: \"xlshs6z\",\n $$css: true\n },\n lg: {\n kZKoxP: \"xs1ryiz\",\n kaIpWk: \"xtt5grq x1dkaolv\",\n kGuDYH: \"x1pvqxga\",\n kzqmXN: \"x1fh0d6s\",\n $$css: true\n },\n md: {\n kZKoxP: \"x1rv7mn0\",\n kaIpWk: \"x1r81nxe x1dkaolv\",\n kGuDYH: \"x1pvqxga\",\n kzqmXN: \"x1eujcsb\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x1dg9itu x1728qcm xjbqb8w\",\n kVAM5u: \"x133yhug\",\n ksu8eU: \"x1y0btm7\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n outlinedDisabled: {\n kWkggS: \"xjbqb8w\",\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n outlinedToggleSelected: {\n kWkggS: \"x1q27o6y x1v1ylhe x1c5gpgi\",\n kVAM5u: \"x9r1u3d\",\n kMwMTN: \"x1girmi0\",\n $$css: true\n },\n pending: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kpwlN0: \"x10a8y8t\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n $$css: true\n },\n standard: {\n kWkggS: \"x83qkoq x1p2om7n xjbqb8w\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n standardDisabled: {\n kWkggS: \"xjbqb8w\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n standardToggleSelected: {\n kWkggS: \"x12vej0r x14dcer4 xjbqb8w\",\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n },\n tonal: {\n kWkggS: \"xnqsvhv xlizrex x15dekr4\",\n kMwMTN: \"x1sawysd\",\n $$css: true\n },\n tonalDisabled: {\n kWkggS: \"xepofeg\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n tonalToggleSelected: {\n kWkggS: \"x1q841l6 x1ofvui0 x167r6xl\",\n kMwMTN: \"x1lba3jz\",\n $$css: true\n },\n xl: {\n kZKoxP: \"x1xaimp3\",\n kaIpWk: \"x11f6t2b x1dkaolv\",\n kGuDYH: \"x1s3cmhv\",\n kzqmXN: \"xszbqgh\",\n $$css: true\n },\n xs: {\n kZKoxP: \"xig8zya\",\n kaIpWk: \"x1r81nxe x1dkaolv\",\n kGuDYH: \"xwsyq91\",\n kzqmXN: \"x11ts1a5\",\n $$css: true\n },\n xxl: {\n kZKoxP: \"x173yhrv\",\n kaIpWk: \"x11f6t2b x1dkaolv\",\n kGuDYH: \"x1tgwohi\",\n kzqmXN: \"xz1kjiq\",\n $$css: true\n }\n};\n\n// The outlined border thickens with the size, as Button's does: 1dp up to M,\n// 2dp at XL, 3dp at XXL. A style per size rather than a value in the size\n// style, since a border on a filled button would draw in the icon's colour.\nconst outlineWidths = {\n lg: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n md: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xl: {\n kMzoRj: \"xdh2fpr\",\n $$css: true\n },\n xs: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xxl: {\n kMzoRj: \"x9r2w2z\",\n $$css: true\n }\n};\n\n// A chosen toggle rests at the corner its size presses to, which is the\n// page's round-to-square morph. A style per size rather than a value inside\n// each size style, since StyleX replaces the property whole and this one has\n// to beat both the size's `:active` branch and the disabled style's circle.\nconst selectedShapes = {\n lg: {\n kaIpWk: \"x62ce2h\",\n $$css: true\n },\n md: {\n kaIpWk: \"x1xdvaa9\",\n $$css: true\n },\n xl: {\n kaIpWk: \"xhpdng0\",\n $$css: true\n },\n xs: {\n kaIpWk: \"x1xdvaa9\",\n $$css: true\n },\n xxl: {\n kaIpWk: \"xhpdng0\",\n $$css: true\n }\n};\n\n// Which container a toggle draws, chosen and not. Three of the six are the\n// plain button's own styles: a chosen filled toggle is the filled button, and\n// an unchosen tonal or standard one is the tonal or standard button.\nconst toggleStyles = {\n filled: {\n selected: styles.filled,\n unselected: styles.filledToggle\n },\n outlined: {\n selected: styles.outlinedToggleSelected,\n unselected: styles.outlined\n },\n standard: {\n selected: styles.standardToggleSelected,\n unselected: styles.standard\n },\n tonal: {\n selected: styles.tonalToggleSelected,\n unselected: styles.tonal\n }\n};\nconst disabledStyles = {\n filled: styles.filledDisabled,\n outlined: styles.outlinedDisabled,\n standard: styles.standardDisabled,\n tonal: styles.tonalDisabled\n};\ntype IconButtonProps = {\n /**\n * What the button does, in words. Required rather than optional: an icon\n * on its own has no accessible name, so without this the control announces\n * nothing at all.\n */\n 'aria-label': string;\n children?: ReactNode;\n /** A function may compute the class from the button's render state. */\n className?: ClassNameOrFunction<IconButtonState>;\n /**\n * Whether a toggle starts chosen, when it keeps its own state. Passing\n * this, `isSelected` or `onChange` is what makes the button a toggle.\n */\n defaultSelected?: boolean;\n /**\n * Disables the press ripple. The hover and pressed state layers are\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * Where the button leads. Given one, the button is rendered as a link —\n * an `<a>`, announced as the link it is — with the same styles and ripple.\n * `render`, `type`, and the form and pending props apply to the button\n * form only, and a toggle is never a link.\n */\n href?: string;\n /**\n * Whether a toggle is chosen, when the call site holds the state. Pass it\n * with `onChange`; passing this, `defaultSelected` or `onChange` is what\n * makes the button a toggle.\n */\n isSelected?: boolean;\n /**\n * Called with the new state when a toggle is pressed. Passing this,\n * `isSelected` or `defaultSelected` is what makes the button a toggle.\n */\n onChange?: (isSelected: boolean) => void;\n /**\n * The name of the ring shown while the button is pending, for a screen\n * reader. The label it replaces is hidden while it shows.\n * @default 'Loading'\n */\n pendingLabel?: string;\n /** The link's `rel`, when `href` is set. */\n rel?: string;\n /**\n * The element to render, given the props it would have carried. React\n * Aria's own form: it has to return the element the component would have\n * rendered itself.\n */\n render?: DOMRenderFunction<'button', IconButtonState>;\n /**\n * Control size: `xs` 32px, `md` 40px, `lg` 56px, `xl` 96px, `xxl` 136px —\n * the icon buttons spec page's XS to XL, and the same heights `Button`\n * uses, so the two line up beside each other in a row. The icon is 20px,\n * 24px, 24px, 32px and 40px in turn.\n * @default 'md'\n */\n size?: IconButtonSize;\n /** A function may compute the style from the button's render state. */\n style?: StyleOrFunction<IconButtonState>;\n /** The link's `target`, when `href` is set. */\n target?: string;\n /**\n * `standard` is transparent and tints what it sits on; `outlined` is\n * transparent with a rule around it; `filled` and `tonal` carry a container\n * of their own.\n * @default 'standard'\n */\n variant?: IconButtonVariant;\n} & Omit<ButtonDOMProps, 'render'>;\ntype IconButtonSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl';\n\n// The render state a call site's `className`, `style` or `render` function is\n// handed. `isSelected` is optional because only the toggle form has one, and\n// one function has to be accepted by both: React Aria hands the plain button\n// a state without it and the toggle a state with it, and a parameter type\n// this wide accepts either.\ntype IconButtonState = ButtonState & {\n isSelected?: boolean;\n};\ntype IconButtonVariant = 'filled' | 'outlined' | 'standard' | 'tonal';\n\n// What the button draws: its label, hidden while the button is pending, with\n// the ring over it. The ring takes the button's own content colour rather\n// than the progress page's primary, which on a filled button is the fill\n// itself and so invisible. The label stays in the flow so the button keeps its\n// width, which is what stops a form jumping the moment it is submitted.\n// React Aria wants the progress bar in the accessibility tree as soon as the\n// button goes pending, so it is rendered from the render state rather than\n// after a delay.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction buttonContent(children: ReactNode, pendingLabel: string, ripple: Ripple) {\n return (state: ButtonRenderProps) => <>\n <span {...{\n 0: {\n className: \"xjp7ctv\"\n },\n 1: {\n className: \"xjp7ctv xlshs6z\"\n }\n }[!!state.isPending << 0]}>\n {children}\n </span>\n {state.isPending ? <span className=\"x6s0dn4 x78zum5 x10a8y8t xl56j7k x10l6tqk\">\n <ProgressIndicator aria-label={pendingLabel} isIndeterminate size=\"1em\" tone=\"inherit\" variant=\"circular\" />\n </span> : null}\n {ripple.surface}\n </>;\n}\n/**\n * A button that is an icon, at five control heights. Given `href` it is a\n * link with the same appearance. Every `aria-*` prop is forwarded to the\n * element; React Aria alone would keep only the labelling ones.\n *\n * Given `isSelected`, `defaultSelected` or `onChange` it is a toggle, which\n * reports its state through `aria-pressed` and draws the page's second pair\n * of colour roles for its variant. A toggle takes neither `href` nor the\n * pending props.\n *\n * ```tsx\n * <IconButton aria-label=\"Label\" defaultSelected variant=\"tonal\">\n * <StarIcon />\n * </IconButton>\n * ```\n */\nfunction IconButton({\n children,\n defaultSelected,\n disableRipple = false,\n href,\n isDisabled,\n isPending = false,\n isSelected,\n onChange,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n pendingLabel = 'Loading',\n rel,\n render,\n size = 'md',\n target,\n variant = 'standard',\n ...props\n}: IconButtonProps) {\n // A field's context may disable the button — a number field's stepper at\n // the end of its range, a search field's clear button with the field — and\n // React Aria takes a prop over its context, so a default of `false` here\n // would keep every one of them enabled. The call site's own prop still\n // wins where it is given; the context is read for the ripple, which has\n // to know before the render state does.\n const context = useSlottedContext(ButtonContext, props.slot);\n const disabled = isDisabled ?? context?.isDisabled ?? false;\n\n // `props` (className/style, etc.) is spread separately: `className` and\n // `style` there may be functions of render state, which ripple's own\n // handler-only merge doesn't need to know about. It is also why the styles\n // below merge through mergeStatefulStyles rather than the plain\n // mergeStyles. The ripple is off while disabled, and while pending, as in\n // Button — and pending for the same second reason given there: React Aria\n // suppresses the click that would end a press but not the pointer events\n // that start one, so a ripple begun while pending was never ended.\n const ripple = useRipple<FocusableElement>(!disableRipple && !disabled && !isPending, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n\n // The three props that make this a toggle. Read together rather than behind\n // a `toggle` word of its own, the way `href` already turns the button into\n // a link: a button given none of them has no state to report, and one given\n // any of them has nothing else it could mean.\n if (defaultSelected !== undefined || isSelected !== undefined || onChange !== undefined) {\n return <RACToggleButton defaultSelected={defaultSelected} isDisabled={disabled} isSelected={isSelected} onChange={onChange} render={toggleButtonRenderer(element, render)} {...ripple.handlers} {...props} {...mergeStatefulStyles(toggleStyleProps(size, variant), props)}>\n {toggleContent(children, ripple)}\n </RACToggleButton>;\n }\n const styleProps = mergeStatefulStyles((state: ButtonState) => stylex.props(styles.base, focus.ring, styles[variant], styles[size], variant === 'outlined' && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]), props);\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={disabled} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={disabled} isPending={isPending} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {buttonContent(children, pendingLabel, ripple)}\n </RACButton>;\n}\n\n// What a toggle draws: its icon and the ripple. No pending ring — React\n// Aria's toggle button has no pending state, and a control reporting which of\n// two states it is in has nothing to be pending about.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler memoises\n// the result on its inputs.\nfunction toggleContent(children: ReactNode, ripple: Ripple) {\n return () => <>\n {children}\n {ripple.surface}\n </>;\n}\n\n// A toggle's styles, from React Aria's render state. The chosen shape is\n// applied after the disabled styles so it survives them: which of the two\n// states a disabled toggle is in should still be readable, and the disabled\n// style otherwise forces the circle back.\nfunction toggleStyleProps(size: IconButtonSize, variant: IconButtonVariant) {\n return (state: IconButtonState) => stylex.props(styles.base, focus.ring, state.isSelected === true ? toggleStyles[variant].selected : toggleStyles[variant].unselected, styles[size],\n // A chosen outlined toggle has a container rather than a rule, so the\n // width goes on only while it is unchosen.\n variant === 'outlined' && state.isSelected !== true && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant], state.isSelected === true && selectedShapes[size]);\n}\nexport type { IconButtonProps, IconButtonSize, IconButtonState, IconButtonVariant };\nexport default IconButton;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["ReactNode","ButtonRenderProps","ClassNameOrFunction","DOMRenderFunction","FocusableElement","StyleOrFunction","stylex","ButtonContext","Button","RACButton","Link","RACLink","ToggleButton","RACToggleButton","useSlottedContext","ButtonDOMProps","ButtonState","useRipple","ariaAttributesOf","buttonRenderer","linkRenderer","toggleButtonRenderer","focus","mergeStatefulStyles","colors","motion","radii","sizing","stateLayerOpacity","ProgressIndicator","Ripple","ReturnType","TARGET_SIZE","styles","base","k6CgDc","kGNEyG","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kmVPX3","kVAEAm","kybGjl","kIyJzY","k1ekBW","kAMwcw","$$css","disabled","filled","kWkggS","kMwMTN","filledDisabled","filledToggle","label","labelPending","k33iCy","lg","kZKoxP","kGuDYH","kzqmXN","md","kgeoSG","kFcpXp","kEoFBp","outlined","kVAM5u","ksu8eU","outlinedDisabled","outlinedToggleSelected","pending","kpwlN0","standard","standardDisabled","standardToggleSelected","tonal","tonalDisabled","tonalToggleSelected","xl","xs","xxl","outlineWidths","selectedShapes","toggleStyles","selected","unselected","disabledStyles","IconButtonProps","children","className","IconButtonState","defaultSelected","disableRipple","href","isSelected","onChange","pendingLabel","rel","render","size","IconButtonSize","style","target","variant","IconButtonVariant","Omit","buttonContent","ripple","state","isPending","surface","IconButton","t0","$","_c","t1","isDisabled","t2","onClick","onContextMenu","onKeyDown","onKeyUp","onPointerCancel","onPointerDown","onPointerLeave","onPointerUp","t3","t4","t5","props","undefined","context","slot","t6","element","aria","t7","t8","handlers","t9","toggleStyleProps","t10","toggleContent","ring","styleProps","T0","t11"],"sources":["../../../src/components/icon-button/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, DOMRenderFunction, FocusableElement, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { ButtonContext, Button as RACButton, Link as RACLink, ToggleButton as RACToggleButton, useSlottedContext } from 'react-aria-components';\nimport type { ButtonDOMProps, ButtonState } from '../button';\nimport { useRipple } from '../../hooks/useRipple';\nimport { ariaAttributesOf, buttonRenderer, linkRenderer, toggleButtonRenderer } from '../../render/aria';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, sizing, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\nimport ProgressIndicator from '../progress-indicator';\n\n// Each variant composites an 'on-color' over its own container at the\n// interaction state's opacity, rather than swapping in a separate hover\n// color. The pairs are the icon buttons spec page's: filled on primary,\n// tonal on secondary container, outlined with an outline variant border and\n// an on-surface-variant icon, standard on surface variant over nothing. calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes. Inlined at each property rather than factored\n// into a helper: @stylexjs/babel-plugin only statically recognizes\n// expressions written directly as property values.\n//\n// Disabled is a style of its own per variant rather than a `:disabled`\n// branch inside each property, for the reason Button's comment gives: given\n// `href` this renders as a link, which React Aria turns into a <span> while\n// disabled, and neither matches the pseudo-class. Applied last from the\n// render state, the disabled styles replace each property whole, hover and\n// pressed branches included.\n//\n// **The outlined border thickens with the size, and the widths are Button's\n// rather than this page's.** The icon buttons page keeps them in a size token\n// set its widget will not open to a script, and the two components already\n// share their five heights on purpose — a 96dp icon button beside a 96dp\n// outlined button with a different border weight would read as a mistake.\n//\n// **A toggle is the same button reporting a state.** Given `isSelected`,\n// `defaultSelected` or `onChange` it is React Aria's `ToggleButton` instead\n// of its `Button`, which announces the state through `aria-pressed` rather\n// than a role of its own — every variant and size still applies. The page\n// gives each style a second pair of colour roles for it, and they are not\n// the plain button's: a filled toggle rests on surface container with an\n// on-surface-variant icon and takes primary once chosen, a tonal one rests\n// on secondary container and takes secondary, and a standard one is\n// transparent throughout with the icon going from on-surface-variant to\n// primary, and an outlined one swaps its border for the inverse surface\n// pair. So a chosen filled toggle looks like a plain filled button, and an\n// unchosen one does not.\n//\n// A toggle is never a link and never pending. React Aria's `ToggleButton`\n// takes neither, and neither means anything for a control whose whole job is\n// to report which of two states it is in.\n//\n// The corner softens from a circle to a rounded square while pressed, which\n// is the shape morph the icon buttons spec page gives this control, at the\n// pressed corner its size token set names: 8 for the two small sizes, 12 at\n// medium, 16 at the two large. Each size carries its own pressed radius, since\n// StyleX replaces the property whole. The two transitioned properties take\n// different curves — the colour change is linear-ish and the shape change is\n// emphasized — so the timing functions are a matching comma list rather than\n// one value.\n//\n// A chosen toggle rests at that same pressed corner, which is the page's\n// shape morph: a toggle icon button moves from round while unchosen to\n// square once chosen. The square shape's own corner sits in a token set the\n// page keeps behind its size menu, but the page also says both shapes press\n// to the same radius — so the size's pressed corner is the value it already\n// assigns to that size, used here at rest rather than invented.\ntype Ripple = ReturnType<typeof useRipple<FocusableElement>>;\n\n/**\n * The press area the page requires of its two smallest sizes. A literal\n * rather than `sizing.controlMd`, which holds the same number: that is a step\n * of the control scale, and a consumer resizing their medium controls should\n * not shrink a target the page states as a floor.\n */\nconst TARGET_SIZE = '48px';\nconst styles = {\n base: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kmVPX3: \"x1717udv\",\n kVAEAm: \"x1n2onr6\",\n kybGjl: \"x1hl2dhg\",\n kIyJzY: \"x1iuyhda\",\n k1ekBW: \"xb5u718\",\n kAMwcw: \"x15l9jch\",\n $$css: true\n },\n disabled: {\n kaIpWk: \"x1dkaolv\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n filled: {\n kWkggS: \"xpky1to xyf7a0q xnety89\",\n kMwMTN: \"xwjo7ld\",\n $$css: true\n },\n filledDisabled: {\n kWkggS: \"xepofeg\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n filledToggle: {\n kWkggS: \"xbck2fw x1h1ujn1 x1mjdul6\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n label: {\n k1xSpc: \"xjp7ctv\",\n $$css: true\n },\n labelPending: {\n k33iCy: \"xlshs6z\",\n $$css: true\n },\n lg: {\n kZKoxP: \"xs1ryiz\",\n kaIpWk: \"xtt5grq x1dkaolv\",\n kGuDYH: \"x1pvqxga\",\n kzqmXN: \"x1fh0d6s\",\n $$css: true\n },\n md: {\n kgeoSG: \"x1cpjm7i\",\n kFcpXp: \"x1q69gdh\",\n kEoFBp: \"x1hmns74\",\n kZKoxP: \"x1rv7mn0\",\n kaIpWk: \"x1r81nxe x1dkaolv\",\n kGuDYH: \"x1pvqxga\",\n kzqmXN: \"x1eujcsb\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x1dg9itu x1728qcm xjbqb8w\",\n kVAM5u: \"x133yhug\",\n ksu8eU: \"x1y0btm7\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n outlinedDisabled: {\n kWkggS: \"xjbqb8w\",\n kVAM5u: \"xrh88j3\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n outlinedToggleSelected: {\n kWkggS: \"x1q27o6y x1v1ylhe x1c5gpgi\",\n kVAM5u: \"x9r1u3d\",\n kMwMTN: \"x1girmi0\",\n $$css: true\n },\n pending: {\n kGNEyG: \"x6s0dn4\",\n k1xSpc: \"x78zum5\",\n kpwlN0: \"x10a8y8t\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n $$css: true\n },\n standard: {\n kWkggS: \"x83qkoq x1p2om7n xjbqb8w\",\n kMwMTN: \"x1w5n3ug\",\n $$css: true\n },\n standardDisabled: {\n kWkggS: \"xjbqb8w\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n standardToggleSelected: {\n kWkggS: \"x12vej0r x14dcer4 xjbqb8w\",\n kMwMTN: \"x1mxwv8y\",\n $$css: true\n },\n tonal: {\n kWkggS: \"xnqsvhv xlizrex x15dekr4\",\n kMwMTN: \"x1sawysd\",\n $$css: true\n },\n tonalDisabled: {\n kWkggS: \"xepofeg\",\n kMwMTN: \"x1xj74d8\",\n $$css: true\n },\n tonalToggleSelected: {\n kWkggS: \"x1q841l6 x1ofvui0 x167r6xl\",\n kMwMTN: \"x1lba3jz\",\n $$css: true\n },\n xl: {\n kZKoxP: \"x1xaimp3\",\n kaIpWk: \"x11f6t2b x1dkaolv\",\n kGuDYH: \"x1s3cmhv\",\n kzqmXN: \"xszbqgh\",\n $$css: true\n },\n xs: {\n kgeoSG: \"x1cpjm7i\",\n kFcpXp: \"x1n6cgzf\",\n kEoFBp: \"x1hmns74\",\n kZKoxP: \"xig8zya\",\n kaIpWk: \"x1r81nxe x1dkaolv\",\n kGuDYH: \"xwsyq91\",\n kzqmXN: \"x11ts1a5\",\n $$css: true\n },\n xxl: {\n kZKoxP: \"x173yhrv\",\n kaIpWk: \"x11f6t2b x1dkaolv\",\n kGuDYH: \"x1tgwohi\",\n kzqmXN: \"xz1kjiq\",\n $$css: true\n }\n};\n\n// The outlined border thickens with the size, as Button's does: 1dp up to M,\n// 2dp at XL, 3dp at XXL. A style per size rather than a value in the size\n// style, since a border on a filled button would draw in the icon's colour.\nconst outlineWidths = {\n lg: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n md: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xl: {\n kMzoRj: \"xdh2fpr\",\n $$css: true\n },\n xs: {\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n xxl: {\n kMzoRj: \"x9r2w2z\",\n $$css: true\n }\n};\n\n// A chosen toggle rests at the corner its size presses to, which is the\n// page's round-to-square morph. A style per size rather than a value inside\n// each size style, since StyleX replaces the property whole and this one has\n// to beat both the size's `:active` branch and the disabled style's circle.\nconst selectedShapes = {\n lg: {\n kaIpWk: \"x62ce2h\",\n $$css: true\n },\n md: {\n kaIpWk: \"x1xdvaa9\",\n $$css: true\n },\n xl: {\n kaIpWk: \"xhpdng0\",\n $$css: true\n },\n xs: {\n kaIpWk: \"x1xdvaa9\",\n $$css: true\n },\n xxl: {\n kaIpWk: \"xhpdng0\",\n $$css: true\n }\n};\n\n// Which container a toggle draws, chosen and not. Three of the six are the\n// plain button's own styles: a chosen filled toggle is the filled button, and\n// an unchosen tonal or standard one is the tonal or standard button.\nconst toggleStyles = {\n filled: {\n selected: styles.filled,\n unselected: styles.filledToggle\n },\n outlined: {\n selected: styles.outlinedToggleSelected,\n unselected: styles.outlined\n },\n standard: {\n selected: styles.standardToggleSelected,\n unselected: styles.standard\n },\n tonal: {\n selected: styles.tonalToggleSelected,\n unselected: styles.tonal\n }\n};\nconst disabledStyles = {\n filled: styles.filledDisabled,\n outlined: styles.outlinedDisabled,\n standard: styles.standardDisabled,\n tonal: styles.tonalDisabled\n};\ntype IconButtonProps = {\n /**\n * What the button does, in words. Required rather than optional: an icon\n * on its own has no accessible name, so without this the control announces\n * nothing at all.\n */\n 'aria-label': string;\n children?: ReactNode;\n /** A function may compute the class from the button's render state. */\n className?: ClassNameOrFunction<IconButtonState>;\n /**\n * Whether a toggle starts chosen, when it keeps its own state. Passing\n * this, `isSelected` or `onChange` is what makes the button a toggle.\n */\n defaultSelected?: boolean;\n /**\n * Disables the press ripple. The hover and pressed state layers are\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * Where the button leads. Given one, the button is rendered as a link —\n * an `<a>`, announced as the link it is — with the same styles and ripple.\n * `render`, `type`, and the form and pending props apply to the button\n * form only, and a toggle is never a link.\n */\n href?: string;\n /**\n * Whether a toggle is chosen, when the call site holds the state. Pass it\n * with `onChange`; passing this, `defaultSelected` or `onChange` is what\n * makes the button a toggle.\n */\n isSelected?: boolean;\n /**\n * Called with the new state when a toggle is pressed. Passing this,\n * `isSelected` or `defaultSelected` is what makes the button a toggle.\n */\n onChange?: (isSelected: boolean) => void;\n /**\n * The name of the ring shown while the button is pending, for a screen\n * reader. The label it replaces is hidden while it shows.\n * @default 'Loading'\n */\n pendingLabel?: string;\n /** The link's `rel`, when `href` is set. */\n rel?: string;\n /**\n * The element to render, given the props it would have carried. React\n * Aria's own form: it has to return the element the component would have\n * rendered itself.\n */\n render?: DOMRenderFunction<'button', IconButtonState>;\n /**\n * Control size: `xs` 32px, `md` 40px, `lg` 56px, `xl` 96px, `xxl` 136px —\n * the icon buttons spec page's XS to XL, and the same heights `Button`\n * uses, so the two line up beside each other in a row. The icon is 20px,\n * 24px, 24px, 32px and 40px in turn.\n * @default 'md'\n */\n size?: IconButtonSize;\n /** A function may compute the style from the button's render state. */\n style?: StyleOrFunction<IconButtonState>;\n /** The link's `target`, when `href` is set. */\n target?: string;\n /**\n * `standard` is transparent and tints what it sits on; `outlined` is\n * transparent with a rule around it; `filled` and `tonal` carry a container\n * of their own.\n * @default 'standard'\n */\n variant?: IconButtonVariant;\n} & Omit<ButtonDOMProps, 'render'>;\ntype IconButtonSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl';\n\n// The render state a call site's `className`, `style` or `render` function is\n// handed. `isSelected` is optional because only the toggle form has one, and\n// one function has to be accepted by both: React Aria hands the plain button\n// a state without it and the toggle a state with it, and a parameter type\n// this wide accepts either.\ntype IconButtonState = ButtonState & {\n isSelected?: boolean;\n};\ntype IconButtonVariant = 'filled' | 'outlined' | 'standard' | 'tonal';\n\n// What the button draws: its label, hidden while the button is pending, with\n// the ring over it. The ring takes the button's own content colour rather\n// than the progress page's primary, which on a filled button is the fill\n// itself and so invisible. The label stays in the flow so the button keeps its\n// width, which is what stops a form jumping the moment it is submitted.\n// React Aria wants the progress bar in the accessibility tree as soon as the\n// button goes pending, so it is rendered from the render state rather than\n// after a delay.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction buttonContent(children: ReactNode, pendingLabel: string, ripple: Ripple) {\n return (state: ButtonRenderProps) => <>\n <span {...{\n 0: {\n className: \"xjp7ctv\"\n },\n 1: {\n className: \"xjp7ctv xlshs6z\"\n }\n }[!!state.isPending << 0]}>\n {children}\n </span>\n {state.isPending ? <span className=\"x6s0dn4 x78zum5 x10a8y8t xl56j7k x10l6tqk\">\n <ProgressIndicator aria-label={pendingLabel} isIndeterminate size=\"1em\" tone=\"inherit\" variant=\"circular\" />\n </span> : null}\n {ripple.surface}\n </>;\n}\n/**\n * A button that is an icon, at five control heights. Given `href` it is a\n * link with the same appearance. Every `aria-*` prop is forwarded to the\n * element; React Aria alone would keep only the labelling ones.\n *\n * Given `isSelected`, `defaultSelected` or `onChange` it is a toggle, which\n * reports its state through `aria-pressed` and draws the page's second pair\n * of colour roles for its variant. A toggle takes neither `href` nor the\n * pending props.\n *\n * ```tsx\n * <IconButton aria-label=\"Label\" defaultSelected variant=\"tonal\">\n * <StarIcon />\n * </IconButton>\n * ```\n */\nfunction IconButton({\n children,\n defaultSelected,\n disableRipple = false,\n href,\n isDisabled,\n isPending = false,\n isSelected,\n onChange,\n onClick,\n onContextMenu,\n onKeyDown,\n onKeyUp,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n pendingLabel = 'Loading',\n rel,\n render,\n size = 'md',\n target,\n variant = 'standard',\n ...props\n}: IconButtonProps) {\n // A field's context may disable the button — a number field's stepper at\n // the end of its range, a search field's clear button with the field — and\n // React Aria takes a prop over its context, so a default of `false` here\n // would keep every one of them enabled. The call site's own prop still\n // wins where it is given; the context is read for the ripple, which has\n // to know before the render state does.\n const context = useSlottedContext(ButtonContext, props.slot);\n const disabled = isDisabled ?? context?.isDisabled ?? false;\n\n // `props` (className/style, etc.) is spread separately: `className` and\n // `style` there may be functions of render state, which ripple's own\n // handler-only merge doesn't need to know about. It is also why the styles\n // below merge through mergeStatefulStyles rather than the plain\n // mergeStyles. The ripple is off while disabled, and while pending, as in\n // Button — and pending for the same second reason given there: React Aria\n // suppresses the click that would end a press but not the pointer events\n // that start one, so a ripple begun while pending was never ended.\n const ripple = useRipple<FocusableElement>(!disableRipple && !disabled && !isPending, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n const element = {\n aria: ariaAttributesOf(props),\n onKeyDown,\n onKeyUp\n };\n\n // The three props that make this a toggle. Read together rather than behind\n // a `toggle` word of its own, the way `href` already turns the button into\n // a link: a button given none of them has no state to report, and one given\n // any of them has nothing else it could mean.\n if (defaultSelected !== undefined || isSelected !== undefined || onChange !== undefined) {\n return <RACToggleButton defaultSelected={defaultSelected} isDisabled={disabled} isSelected={isSelected} onChange={onChange} render={toggleButtonRenderer(element, render)} {...ripple.handlers} {...props} {...mergeStatefulStyles(toggleStyleProps(size, variant), props)}>\n {toggleContent(children, ripple)}\n </RACToggleButton>;\n }\n const styleProps = mergeStatefulStyles((state: ButtonState) => stylex.props(styles.base, focus.ring, styles[variant], styles[size], variant === 'outlined' && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]), props);\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={disabled} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={disabled} isPending={isPending} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {buttonContent(children, pendingLabel, ripple)}\n </RACButton>;\n}\n\n// What a toggle draws: its icon and the ripple. No pending ring — React\n// Aria's toggle button has no pending state, and a control reporting which of\n// two states it is in has nothing to be pending about.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler memoises\n// the result on its inputs.\nfunction toggleContent(children: ReactNode, ripple: Ripple) {\n return () => <>\n {children}\n {ripple.surface}\n </>;\n}\n\n// A toggle's styles, from React Aria's render state. The chosen shape is\n// applied after the disabled styles so it survives them: which of the two\n// states a disabled toggle is in should still be readable, and the disabled\n// style otherwise forces the circle back.\nfunction toggleStyleProps(size: IconButtonSize, variant: IconButtonVariant) {\n return (state: IconButtonState) => stylex.props(styles.base, focus.ring, state.isSelected === true ? toggleStyles[variant].selected : toggleStyles[variant].unselected, styles[size],\n // A chosen outlined toggle has a container rather than a rule, so the\n // width goes on only while it is unchosen.\n variant === 'outlined' && state.isSelected !== true && outlineWidths[size], state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant], state.isSelected === true && selectedShapes[size]);\n}\nexport type { IconButtonProps, IconButtonSize, IconButtonState, IconButtonVariant };\nexport default IconButton;"],"mappings":"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"}
|
|
@@ -116,9 +116,9 @@ function NumberField$1(t0) {
|
|
|
116
116
|
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
117
117
|
t13 = {
|
|
118
118
|
0: { className: "x78zum5 xdt5ytf x2lah0s x1motrhk xk4mfur" },
|
|
119
|
-
2: { className: "x78zum5 x2lah0s x1q0g3np xdj266r x1tn5xpv" },
|
|
119
|
+
2: { className: "x78zum5 x2lah0s x1q0g3np x126z3so xdj266r x1tn5xpv" },
|
|
120
120
|
1: { className: "x78zum5 xdt5ytf x2lah0s xk4mfur x17v9ssf" },
|
|
121
|
-
3: { className: "x78zum5 x2lah0s x1q0g3np x1tn5xpv x17v9ssf" }
|
|
121
|
+
3: { className: "x78zum5 x2lah0s x1q0g3np x126z3so x1tn5xpv x17v9ssf" }
|
|
122
122
|
};
|
|
123
123
|
$[5] = t13;
|
|
124
124
|
} else t13 = $[5];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["ReactNode","ButtonRenderProps","NumberFieldProps","RACNumberFieldProps","stylex","Button","RACButton","NumberField","RACNumberField","FieldVariant","FieldBox","FieldInput","FieldMessage","fieldStyles","invalidFrom","useFieldValidationBehavior","MinusGlyph","PlusGlyph","mergeStatefulStyles","colors","motion","radii","spacing","stateLayerOpacity","typography","IconButton","BOX_HALF","sm","bodySmallLineHeight","bodyLargeLineHeight","BOX_OUTLINED_HALF","lg","styles","stepper","k6CgDc","kGNEyG","kWkggS","kZKoxP","kaIpWk","kMzoRj","kB7OPa","kMwMTN","kkrTdU","k1xSpc","kzqmXN","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kmVPX3","kIyJzY","k1ekBW","kAMwcw","$$css","stepperBottomOutlined","kT0f0o","stepperDisabled","stepperFocused","stepperHovered","stepperOutlined","stepperPressed","stepperTop","kfmiAY","decrementLabel","description","error","floatingLabel","incrementLabel","label","numeric","steppers","variant","Omit","t0","$","_c","t1","t2","t3","isDisabled","t4","t5","t6","t7","props","undefined","inline","validationBehavior","T0","t8","t9","root","t10","Symbol","for","0","className","1","t11","t12","t13","2","3","t14","t15","t16","t17","t18","t19","t20","StackedStepper","children","outlined","slot","stepperStyles","top","state","isHovered","isPressed","isFocusVisible"],"sources":["../../../src/components/number-field/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { ButtonRenderProps, NumberFieldProps as RACNumberFieldProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, NumberField as RACNumberField } from 'react-aria-components';\nimport type { FieldVariant } from '../../field';\nimport { FieldBox, FieldInput, FieldMessage } from '../../field';\nimport { fieldStyles, invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { MinusGlyph, PlusGlyph } from '../../glyphs';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\nimport IconButton from '../icon-button';\n\n// The text fields page's field, holding a number: the same box, floating\n// label, underline and message as TextField, with the value in the mono\n// face and tabular figures by default, since a number is what those are\n// for, and two steppers at the trailing end.\n//\n// The steppers come in two layouts. Stacked, the plus over the minus, they\n// are a column flush with the box's top, end and bottom, each half of the\n// box's 56dp and 32dp wide, drawn here since the smallest icon button is\n// 32dp and two of those do not fit; the glyph is the icon buttons page's\n// 20dp for that size, and the hover, pressed, focus and disabled treatments\n// are the standard icon button's. Side by side, they are extra-small icon\n// buttons, the page's trailing icons in the library's own control, 12dp\n// from the end where the page puts a field's icons — the box's 16dp of\n// padding less the 4dp they pull back.\n//\n// React Aria's `NumberField` is the root and the box is its `Group`, which\n// is what names the box and the two steppers as one control; the steppers\n// are its increment and decrement buttons through context, disabled at the\n// ends of the range and kept out of the tab order, and the formatting is its\n// `formatOptions`.\n// Half the box, spelled from the same tokens the box derives its height\n// from rather than as the 28 that half of 56 comes to. A theme with a longer\n// body line makes the box taller — `Editorial` in src/theming/themes.ts does\n// — and a stated half leaves the pair short of the bottom edge they are\n// flush with.\n//\n// Written here rather than imported from src/field/styles.ts, which spells\n// the same two expressions: the StyleX compiler resolves a constant across\n// files only out of a `.stylex.ts` module, the same reason that file gives\n// for re-declaring the forced-colours query. The two have to move together.\nconst BOX_HALF = `calc((2 * ${spacing.sm} + ${typography.bodySmallLineHeight} + ${typography.bodyLargeLineHeight}) / 2)`;\nconst BOX_OUTLINED_HALF = `calc((2 * ${spacing.lg} + ${typography.bodyLargeLineHeight}) / 2)`;\nconst styles = {\n stepper: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1viytl0\",\n kaIpWk: \"x2u8bby\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1td3qas\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x2ssjo2\",\n k3XXqK: \"x1t137rt\",\n kMeerF: \"x1de99jn\",\n kmVPX3: \"x1717udv\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xs2xxs2\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n stepperBottomOutlined: {\n kT0f0o: \"x4gcak0\",\n $$css: true\n },\n stepperDisabled: {\n kMwMTN: \"x1xj74d8\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n stepperFocused: {\n k3XXqK: \"xaatb59\",\n $$css: true\n },\n stepperHovered: {\n kWkggS: \"x14noynh\",\n $$css: true\n },\n stepperOutlined: {\n kZKoxP: \"x1o675yb\",\n $$css: true\n },\n stepperPressed: {\n kWkggS: \"x123fei2\",\n $$css: true\n },\n stepperTop: {\n kfmiAY: \"xirz1nw\",\n $$css: true\n }\n};\ntype NumberFieldProps = {\n /**\n * The name of the stepper that lowers the value, for a screen reader.\n * @default 'Decrease'\n */\n decrementLabel?: string;\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message, the red underline, and\n * `aria-invalid` all follow 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 * Whether the label sits in the empty box and floats to the top once the\n * field is focused or holds a value, as the text fields page draws it.\n * `false` keeps it small at the top in every state.\n * @default true\n */\n floatingLabel?: boolean;\n /**\n * The name of the stepper that raises the value, for a screen reader.\n * @default 'Increase'\n */\n incrementLabel?: string;\n /**\n * What the field is for. Required rather than optional: a field with no\n * label is a box a screen reader cannot name.\n */\n label: string;\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column. On by default, since a\n * number field holds nothing else.\n * @default true\n */\n numeric?: boolean;\n /**\n * How the two steppers sit at the end of the box: stacked, the plus over\n * the minus, flush with the box's edge, or side by side as extra-small\n * icon buttons.\n * @default 'vertical'\n */\n steppers?: 'horizontal' | 'vertical';\n /**\n * The filled box, or the outlined one: no fill, an outline that thickens\n * and takes the primary role while focused, and the label cutting it once\n * it floats — the text fields page's two fields.\n * @default 'filled'\n */\n variant?: FieldVariant;\n} & Omit<RACNumberFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n/**\n * A labelled number input with steppers. Its value is React Aria's: pass\n * `value` with `onChange` to control it, or `defaultValue` to let it keep\n * its own — and `onChange` is handed the number, `NaN` while the field is\n * empty. `minValue`, `maxValue` and `step` shape it, and `formatOptions`\n * says how it reads, in the locale the page is in: a currency, a percentage,\n * a unit. Arrow keys step the value, and Page Up and Page Down by ten steps.\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 box, label, input and message\n * are the field chrome in `src/field`, shared with every other field.\n */\nfunction NumberField({\n decrementLabel = 'Decrease',\n description,\n error,\n floatingLabel = true,\n incrementLabel = 'Increase',\n isDisabled = false,\n label,\n numeric = true,\n steppers = 'vertical',\n variant = 'filled',\n ...props\n}: NumberFieldProps) {\n const inline = steppers === 'horizontal';\n const validationBehavior = useFieldValidationBehavior();\n return <RACNumberField isDisabled={isDisabled} isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(fieldStyles.root), props)}>\n <FieldBox floatingLabel={floatingLabel} label={label} variant={variant}>\n <div {...{\n 0: {\n className: \"x1cy8zhl x9f619 x78zum5 x126z3so\"\n },\n 1: {\n className: \"x9f619 x78zum5 x126z3so x6s0dn4\"\n }\n }[!!inline << 0]}>\n <FieldInput numeric={numeric} />\n <div {...{\n 0: {\n className: \"x78zum5 xdt5ytf x2lah0s x1motrhk xk4mfur\"\n },\n 2: {\n className: \"x78zum5 x2lah0s x1q0g3np xdj266r x1tn5xpv\"\n },\n 1: {\n className: \"x78zum5 xdt5ytf x2lah0s xk4mfur x17v9ssf\"\n },\n 3: {\n className: \"x78zum5 x2lah0s x1q0g3np x1tn5xpv x17v9ssf\"\n }\n }[!!inline << 1 | !!(!inline && variant === 'outlined') << 0]}>\n {inline ? <>\n <IconButton aria-label={decrementLabel} size=\"xs\" slot=\"decrement\">\n <MinusGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>\n <IconButton aria-label={incrementLabel} size=\"xs\" slot=\"increment\">\n <PlusGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>\n </> : <>\n <StackedStepper label={incrementLabel} outlined={variant === 'outlined'} slot=\"increment\">\n <PlusGlyph className=\"x1qx5ct2 x1lliihq xw4jnvo\" />\n </StackedStepper>\n <StackedStepper label={decrementLabel} outlined={variant === 'outlined'} slot=\"decrement\">\n <MinusGlyph className=\"x1qx5ct2 x1lliihq xw4jnvo\" />\n </StackedStepper>\n </>}\n </div>\n </div>\n </FieldBox>\n <FieldMessage description={description} error={error} />\n </RACNumberField>;\n}\nfunction StackedStepper({\n children,\n label,\n outlined,\n slot\n}: {\n children: ReactNode;\n label: string;\n outlined: boolean;\n slot: 'decrement' | 'increment';\n}) {\n return <RACButton aria-label={label} slot={slot} {...mergeStatefulStyles(stepperStyles(slot === 'increment', outlined), {})}>\n {children}\n </RACButton>;\n}\n\n// A stacked stepper: React Aria's button with the slot the field's context\n// looks for, drawn from its render state. Built by a call rather than\n// written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after.\nfunction stepperStyles(top: boolean, outlined: boolean) {\n return (state: ButtonRenderProps) => stylex.props(styles.stepper, outlined && styles.stepperOutlined, top && styles.stepperTop, !top && outlined && styles.stepperBottomOutlined, state.isHovered && !state.isDisabled && styles.stepperHovered, state.isPressed && !state.isDisabled && styles.stepperPressed, state.isFocusVisible && styles.stepperFocused, state.isDisabled && styles.stepperDisabled);\n}\nexport type { NumberFieldProps };\nexport default NumberField;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["ReactNode","ButtonRenderProps","NumberFieldProps","RACNumberFieldProps","stylex","Button","RACButton","NumberField","RACNumberField","FieldVariant","FieldBox","FieldInput","FieldMessage","fieldStyles","invalidFrom","useFieldValidationBehavior","MinusGlyph","PlusGlyph","mergeStatefulStyles","colors","motion","radii","spacing","stateLayerOpacity","typography","IconButton","BOX_HALF","sm","bodySmallLineHeight","bodyLargeLineHeight","BOX_OUTLINED_HALF","lg","styles","stepper","k6CgDc","kGNEyG","kWkggS","kZKoxP","kaIpWk","kMzoRj","kB7OPa","kMwMTN","kkrTdU","k1xSpc","kzqmXN","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kmVPX3","kIyJzY","k1ekBW","kAMwcw","$$css","stepperBottomOutlined","kT0f0o","stepperDisabled","stepperFocused","stepperHovered","stepperOutlined","stepperPressed","stepperTop","kfmiAY","decrementLabel","description","error","floatingLabel","incrementLabel","label","numeric","steppers","variant","Omit","t0","$","_c","t1","t2","t3","isDisabled","t4","t5","t6","t7","props","undefined","inline","validationBehavior","T0","t8","t9","root","t10","Symbol","for","0","className","1","t11","t12","t13","2","3","t14","t15","t16","t17","t18","t19","t20","StackedStepper","children","outlined","slot","stepperStyles","top","state","isHovered","isPressed","isFocusVisible"],"sources":["../../../src/components/number-field/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { ButtonRenderProps, NumberFieldProps as RACNumberFieldProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, NumberField as RACNumberField } from 'react-aria-components';\nimport type { FieldVariant } from '../../field';\nimport { FieldBox, FieldInput, FieldMessage } from '../../field';\nimport { fieldStyles, invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { MinusGlyph, PlusGlyph } from '../../glyphs';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\nimport IconButton from '../icon-button';\n\n// The text fields page's field, holding a number: the same box, floating\n// label, underline and message as TextField, with the value in the mono\n// face and tabular figures by default, since a number is what those are\n// for, and two steppers at the trailing end.\n//\n// The steppers come in two layouts. Stacked, the plus over the minus, they\n// are a column flush with the box's top, end and bottom, each half of the\n// box's 56dp and 32dp wide, drawn here since the smallest icon button is\n// 32dp and two of those do not fit; the glyph is the icon buttons page's\n// 20dp for that size, and the hover, pressed, focus and disabled treatments\n// are the standard icon button's. Side by side, they are extra-small icon\n// buttons, the page's trailing icons in the library's own control, 12dp\n// from the end where the page puts a field's icons — the box's 16dp of\n// padding less the 4dp they pull back.\n//\n// **The stacked pair is the one control here that does not reach the 48dp\n// target**, and it is the layout rather than an oversight. Every other small\n// control in the library draws that target out of flow, over whatever sits\n// beside it — src/control/styles.ts carries the decision. These two have only\n// each other beside them: the column is 56dp tall in total, so two 48dp\n// targets inside it would overlap across most of their height, and the half\n// of a press that landed in the overlap would go to whichever box was\n// uppermost rather than to the glyph under the finger. Incrementing when a\n// reader meant to decrement is worse than a target that is short, so the\n// stacked layout keeps its 32 by 28 and the reader who needs the larger one\n// has `steppers=\"horizontal\"`, where each is an extra-small icon button and\n// gets the target from there — with the gap that keeps those two targets off\n// each other, which is the room the column has none of.\n//\n// React Aria's `NumberField` is the root and the box is its `Group`, which\n// is what names the box and the two steppers as one control; the steppers\n// are its increment and decrement buttons through context, disabled at the\n// ends of the range and kept out of the tab order, and the formatting is its\n// `formatOptions`.\n// Half the box, spelled from the same tokens the box derives its height\n// from rather than as the 28 that half of 56 comes to. A theme with a longer\n// body line makes the box taller — `Editorial` in src/theming/themes.ts does\n// — and a stated half leaves the pair short of the bottom edge they are\n// flush with.\n//\n// Written here rather than imported from src/field/styles.ts, which spells\n// the same two expressions: the StyleX compiler resolves a constant across\n// files only out of a `.stylex.ts` module, the same reason that file gives\n// for re-declaring the forced-colours query. The two have to move together.\nconst BOX_HALF = `calc((2 * ${spacing.sm} + ${typography.bodySmallLineHeight} + ${typography.bodyLargeLineHeight}) / 2)`;\nconst BOX_OUTLINED_HALF = `calc((2 * ${spacing.lg} + ${typography.bodyLargeLineHeight}) / 2)`;\nconst styles = {\n stepper: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1viytl0\",\n kaIpWk: \"x2u8bby\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"x1w5n3ug\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1td3qas\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x2ssjo2\",\n k3XXqK: \"x1t137rt\",\n kMeerF: \"x1de99jn\",\n kmVPX3: \"x1717udv\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xs2xxs2\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n stepperBottomOutlined: {\n kT0f0o: \"x4gcak0\",\n $$css: true\n },\n stepperDisabled: {\n kMwMTN: \"x1xj74d8\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n stepperFocused: {\n k3XXqK: \"xaatb59\",\n $$css: true\n },\n stepperHovered: {\n kWkggS: \"x14noynh\",\n $$css: true\n },\n stepperOutlined: {\n kZKoxP: \"x1o675yb\",\n $$css: true\n },\n stepperPressed: {\n kWkggS: \"x123fei2\",\n $$css: true\n },\n stepperTop: {\n kfmiAY: \"xirz1nw\",\n $$css: true\n }\n};\ntype NumberFieldProps = {\n /**\n * The name of the stepper that lowers the value, for a screen reader.\n * @default 'Decrease'\n */\n decrementLabel?: string;\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state — the message, the red underline, and\n * `aria-invalid` all follow 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 * Whether the label sits in the empty box and floats to the top once the\n * field is focused or holds a value, as the text fields page draws it.\n * `false` keeps it small at the top in every state.\n * @default true\n */\n floatingLabel?: boolean;\n /**\n * The name of the stepper that raises the value, for a screen reader.\n * @default 'Increase'\n */\n incrementLabel?: string;\n /**\n * What the field is for. Required rather than optional: a field with no\n * label is a box a screen reader cannot name.\n */\n label: string;\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column. On by default, since a\n * number field holds nothing else.\n * @default true\n */\n numeric?: boolean;\n /**\n * How the two steppers sit at the end of the box: stacked, the plus over\n * the minus, flush with the box's edge, or side by side as extra-small\n * icon buttons.\n * @default 'vertical'\n */\n steppers?: 'horizontal' | 'vertical';\n /**\n * The filled box, or the outlined one: no fill, an outline that thickens\n * and takes the primary role while focused, and the label cutting it once\n * it floats — the text fields page's two fields.\n * @default 'filled'\n */\n variant?: FieldVariant;\n} & Omit<RACNumberFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n/**\n * A labelled number input with steppers. Its value is React Aria's: pass\n * `value` with `onChange` to control it, or `defaultValue` to let it keep\n * its own — and `onChange` is handed the number, `NaN` while the field is\n * empty. `minValue`, `maxValue` and `step` shape it, and `formatOptions`\n * says how it reads, in the locale the page is in: a currency, a percentage,\n * a unit. Arrow keys step the value, and Page Up and Page Down by ten steps.\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 box, label, input and message\n * are the field chrome in `src/field`, shared with every other field.\n */\nfunction NumberField({\n decrementLabel = 'Decrease',\n description,\n error,\n floatingLabel = true,\n incrementLabel = 'Increase',\n isDisabled = false,\n label,\n numeric = true,\n steppers = 'vertical',\n variant = 'filled',\n ...props\n}: NumberFieldProps) {\n const inline = steppers === 'horizontal';\n const validationBehavior = useFieldValidationBehavior();\n return <RACNumberField isDisabled={isDisabled} isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(fieldStyles.root), props)}>\n <FieldBox floatingLabel={floatingLabel} label={label} variant={variant}>\n <div {...{\n 0: {\n className: \"x1cy8zhl x9f619 x78zum5 x126z3so\"\n },\n 1: {\n className: \"x9f619 x78zum5 x126z3so x6s0dn4\"\n }\n }[!!inline << 0]}>\n <FieldInput numeric={numeric} />\n <div {...{\n 0: {\n className: \"x78zum5 xdt5ytf x2lah0s x1motrhk xk4mfur\"\n },\n 2: {\n className: \"x78zum5 x2lah0s x1q0g3np x126z3so xdj266r x1tn5xpv\"\n },\n 1: {\n className: \"x78zum5 xdt5ytf x2lah0s xk4mfur x17v9ssf\"\n },\n 3: {\n className: \"x78zum5 x2lah0s x1q0g3np x126z3so x1tn5xpv x17v9ssf\"\n }\n }[!!inline << 1 | !!(!inline && variant === 'outlined') << 0]}>\n {inline ? <>\n <IconButton aria-label={decrementLabel} size=\"xs\" slot=\"decrement\">\n <MinusGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>\n <IconButton aria-label={incrementLabel} size=\"xs\" slot=\"increment\">\n <PlusGlyph className=\"xlzyvqe x1lliihq x15vhz18\" />\n </IconButton>\n </> : <>\n <StackedStepper label={incrementLabel} outlined={variant === 'outlined'} slot=\"increment\">\n <PlusGlyph className=\"x1qx5ct2 x1lliihq xw4jnvo\" />\n </StackedStepper>\n <StackedStepper label={decrementLabel} outlined={variant === 'outlined'} slot=\"decrement\">\n <MinusGlyph className=\"x1qx5ct2 x1lliihq xw4jnvo\" />\n </StackedStepper>\n </>}\n </div>\n </div>\n </FieldBox>\n <FieldMessage description={description} error={error} />\n </RACNumberField>;\n}\nfunction StackedStepper({\n children,\n label,\n outlined,\n slot\n}: {\n children: ReactNode;\n label: string;\n outlined: boolean;\n slot: 'decrement' | 'increment';\n}) {\n return <RACButton aria-label={label} slot={slot} {...mergeStatefulStyles(stepperStyles(slot === 'increment', outlined), {})}>\n {children}\n </RACButton>;\n}\n\n// A stacked stepper: React Aria's button with the slot the field's context\n// looks for, drawn from its render state. Built by a call rather than\n// written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after.\nfunction stepperStyles(top: boolean, outlined: boolean) {\n return (state: ButtonRenderProps) => stylex.props(styles.stepper, outlined && styles.stepperOutlined, top && styles.stepperTop, !top && outlined && styles.stepperBottomOutlined, state.isHovered && !state.isDisabled && styles.stepperHovered, state.isPressed && !state.isDisabled && styles.stepperPressed, state.isFocusVisible && styles.stepperFocused, state.isDisabled && styles.stepperDisabled);\n}\nexport type { NumberFieldProps };\nexport default NumberField;"],"mappings":"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"}
|
|
@@ -39,10 +39,13 @@ type SnackbarOptions = {
|
|
|
39
39
|
*/
|
|
40
40
|
timeout?: number;
|
|
41
41
|
};
|
|
42
|
-
type SnackbarProps =
|
|
42
|
+
type SnackbarProps = {
|
|
43
43
|
/**
|
|
44
|
-
* What a screen reader calls the region holding the snackbar.
|
|
45
|
-
*
|
|
44
|
+
* What a screen reader calls the region holding the snackbar. Left out,
|
|
45
|
+
* React Aria names the region itself: a count of the messages it holds, in
|
|
46
|
+
* the reader's own locale — "1 notification." in English, and one of some
|
|
47
|
+
* thirty languages otherwise. Pass a name only to replace that, and pass a
|
|
48
|
+
* translated one, since whatever is passed is read as written.
|
|
46
49
|
*/
|
|
47
50
|
'aria-label'?: string;
|
|
48
51
|
/** A function may compute the class from the region's render state. */
|
|
@@ -58,7 +61,7 @@ type SnackbarProps = Omit<ToastRegionProps<SnackbarMessage>, 'children' | 'class
|
|
|
58
61
|
queue: SnackbarQueue;
|
|
59
62
|
/** A function may compute the style from the region's render state. */
|
|
60
63
|
style?: ToastRegionProps<SnackbarMessage>['style'];
|
|
61
|
-
}
|
|
64
|
+
} & Omit<ToastRegionProps<SnackbarMessage>, 'children' | 'className' | 'queue' | 'style'>;
|
|
62
65
|
/**
|
|
63
66
|
* The queue a snackbar is shown from. Make one where the app can reach it —
|
|
64
67
|
* a module of its own is the usual place — mount `Snackbar` once with it,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["ReactNode","FocusableElement","ToastRegionProps","RACToastRegionProps","ToastRegionRenderProps","stylex","Button","RACButton","UNSTABLE_Toast","RACToast","UNSTABLE_ToastContent","RACToastContent","UNSTABLE_ToastQueue","RACToastQueue","UNSTABLE_ToastRegion","RACToastRegion","Text","CloseGlyph","useRipple","mergeStatefulStyles","colors","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","SHORT_MS","LONG_MS","WIDE","rise","styles","action","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","k8WAf4","kg3NbH","$$css","close","kZKoxP","kzqmXN","kmVPX3","control","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kVQacm","kVAEAm","SnackbarAction","label","onPress","SnackbarMessage","isDismissable","message","SnackbarOptions","onClose","timeout","SnackbarProps","Omit","className","closeLabel","queue","SnackbarQueue","style","SnackbarToastItem","rac","constructor","maxVisibleToasts","add","options","undefined","clear","key","actionPress","closeToast","Snackbar","t0","$","_c","T0","t1","t2","t3","t4","t5","props","snackbarContent","SnackbarButton","children","ripple","handlers","surface","toast","SnackbarControls","SnackbarToast","content","Queue","SnackbarRegionRenderProps"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { FocusableElement, ToastRegionProps as RACToastRegionProps, ToastRegionRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, UNSTABLE_Toast as RACToast, UNSTABLE_ToastContent as RACToastContent, UNSTABLE_ToastQueue as RACToastQueue, UNSTABLE_ToastRegion as RACToastRegion, Text } from 'react-aria-components';\nimport { CloseGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that. The\n// page's container is the inverse surface at a 4dp corner and elevation 3,\n// its supporting text is body-medium in inverse on surface, its action label\n// is inverse primary, and its close icon takes the supporting text's colour.\n// The measurements are the page's too: 8dp of margin from the edges of the\n// screen, 8dp of padding inside the container with another 8dp either side\n// of the message, 14dp above and below on a single line, and between 320 and\n// 576dp wide above the page's 600dp breakpoint — full width below it.\n//\n// One at a time. The page shows a single snackbar and replaces it rather\n// than stacking, which is `maxVisibleToasts: 1` on the queue.\n//\n// React Aria's toast is the behaviour: the region is a landmark that holds\n// the message, moves focus into it for a keyboard, and pauses every timer\n// while it is hovered or focused, so a message never expires while it is\n// being read or acted on.\n//\n// Three things are decided here rather than taken from React Aria or from\n// the page.\n//\n// **The queue is ours, not React Aria's.** React Aria's toast is still\n// `UNSTABLE_`, and `SnackbarQueue` is what keeps that name out of a\n// consumer's code — an upstream rename is this file rather than every call\n// site. It wraps their queue, defaults it to one visible message, and takes\n// the message and its options as one call.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton.** The page colours them inverse primary and inverse\n// on surface, which no variant of either carries, and a colour pushed in\n// from outside through `className` is the merge hazard AGENTS.md describes:\n// StyleX decides between two atomic classes by their order in the compiled\n// stylesheet, not by the order they are applied. Both are React Aria's\n// `Button` with the same ripple and the same state layers, over\n// `currentColor` so each takes the colour the snackbar gives it.\n//\n// **There is no `container` prop.** Every other overlay here takes one,\n// because React Aria's `Modal` and `Popover` accept a portal container, and\n// `src/components/portal-container.test.tsx` is what keeps that true.\n// Its toast region does not: it reads a portal provider that\n// `react-aria-components` does not export, so the region always lands at the\n// end of `<body>`. An app that scopes its StyleX theme to a subtree has to\n// put the theme on `:root` for the snackbar to be drawn in it.\n\n// The page's two durations, from the same implementation its measurements\n// come from: a message alone is shown for the short one, a message with an\n// action for the long one, since an action has to be read before it can be\n// taken.\nconst SHORT_MS = 1500;\nconst LONG_MS = 2750;\n\n// Below the page's 600dp breakpoint the snackbar runs the width of the\n// screen; above it, it takes between 320 and 576.\nconst WIDE = '@media (min-width: 600px)';\n\n// The page's own is a fade. It rises a little as it arrives too, which is\n// what the page draws and what says the message came from the edge of the\n// screen rather than appearing over it.\nconst rise = \"x15b941j-B\";\nconst styles = {\n action: {\n kMwMTN: \"x16bex6i\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x18fpw6u\",\n $$css: true\n },\n close: {\n kZKoxP: \"xbg5kjn\",\n kMwMTN: \"x1girmi0\",\n kzqmXN: \"xoqf9c6\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n control: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xy3r1oc x1en43ny x15a1ka xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"x14ytart\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n }\n};\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n label: string;\n /** Run when the action is pressed, just before the snackbar closes. */\n onPress: () => void;\n};\n\n/** What a snackbar carries: its message, and what may sit beside it. */\ntype SnackbarMessage = {\n action: SnackbarAction | undefined;\n isDismissable: boolean;\n message: ReactNode;\n};\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n action?: SnackbarAction;\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n * @default false\n */\n isDismissable?: boolean;\n /** Run when the snackbar closes, however it was closed. */\n onClose?: () => void;\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to the page's\n * short duration, or its long one when there is an action to read, and the\n * timer is paused while the region is hovered or focused so a message never\n * expires while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `isDismissable`, or there is no\n * way to be rid of it.\n */\n timeout?: number;\n};\ntype SnackbarProps = Omit<RACToastRegionProps<SnackbarMessage>, 'children' | 'className' | 'queue' | 'style'> & {\n /**\n * What a screen reader calls the region holding the snackbar.\n * @default 'Notifications'\n */\n 'aria-label'?: string;\n /** A function may compute the class from the region's render state. */\n className?: RACToastRegionProps<SnackbarMessage>['className'];\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message, so putting it there would make every `add` call repeat it.\n * @default 'Close'\n */\n closeLabel?: string;\n /** The queue the region shows messages from. */\n queue: SnackbarQueue;\n /** A function may compute the style from the region's render state. */\n style?: RACToastRegionProps<SnackbarMessage>['style'];\n};\n\n// One entry of the queue, as React Aria hands it to the region's render\n// function. Taken from its render state rather than imported from\n// `react-stately`, which this package does not depend on.\ntype SnackbarToastItem = ToastRegionRenderProps<SnackbarMessage>['visibleToasts'][number];\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it —\n * a module of its own is the usual place — mount `Snackbar` once with it,\n * and call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n *\n * It wraps React Aria's toast queue rather than exposing it, which is what\n * keeps that API's `UNSTABLE_` name out of a consumer's code.\n */\nclass SnackbarQueue {\n /**\n * React Aria's queue, which `Snackbar` subscribes to. Not part of the\n * package's API — read it and an upstream release may break the call site.\n */\n readonly rac: RACToastQueue<SnackbarMessage>;\n constructor() {\n // One at a time, which is what the page shows: a second message replaces\n // the first rather than stacking under it.\n this.rac = new RACToastQueue<SnackbarMessage>({\n maxVisibleToasts: 1\n });\n }\n\n /**\n * Shows a message, and returns the key that closes it.\n */\n add(message: ReactNode, options: SnackbarOptions = {}) {\n const {\n action,\n isDismissable = false,\n onClose,\n timeout\n } = options;\n return this.rac.add({\n action,\n isDismissable,\n message\n }, {\n onClose,\n timeout: timeout ?? (action === undefined ? SHORT_MS : LONG_MS)\n });\n }\n\n /** Closes every snackbar, shown or waiting. */\n clear() {\n this.rac.clear();\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n this.rac.close(key);\n }\n}\n\n// The three handlers the snackbar hands to something below it, each built by\n// a call rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result on\n// its inputs.\nfunction actionPress(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress();\n close();\n };\n}\nfunction closeToast(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key);\n };\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action. Mount\n * one of these with a `Snackbar.Queue`, and call the queue's `add` to show a\n * message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * The region is portalled to the end of `<body>` and renders nothing while\n * the queue is empty. It is one region rather than one per message, so mount\n * it once, near the root.\n *\n * The call site's `className` and `style` land on that region, which is the\n * element a layout positions.\n */\nfunction Snackbar({\n closeLabel = 'Close',\n queue,\n ...props\n}: SnackbarProps) {\n return <RACToastRegion<SnackbarMessage> queue={queue.rac} {...props} {...mergeStatefulStyles({\n className: \"x6s0dn4 x9f619 x78zum5 xdt5ytf x126z3so x1ey2m1c x17y0mx6 x1t137rt x1a7rqcl x47corl xixxii4 xfo81ep\"\n }, props)}>\n {snackbarContent(queue, closeLabel)}\n </RACToastRegion>;\n}\n\n/**\n * One of the snackbar's two controls. React Aria's `Button` rather than the\n * library's, for the colour reason in the comment at the top of this file;\n * the ripple and the state layers are the same ones every other control\n * here draws, over `currentColor`.\n */\nfunction SnackbarButton({\n children,\n style,\n ...props\n}: {\n 'aria-label'?: string;\n children: ReactNode;\n onPress?: () => void;\n slot?: string;\n style: stylex.StyleXStyles;\n}) {\n const ripple = useRipple<FocusableElement>();\n return <RACButton {...ripple.handlers} {...props} {...stylex.props(styles.control, style)}>\n {children}\n {ripple.surface}\n </RACButton>;\n}\nfunction snackbarContent(queue: SnackbarQueue, closeLabel: string) {\n return ({\n toast\n }: {\n toast: SnackbarToastItem;\n }) => <SnackbarToast close={closeToast(queue, toast.key)} closeLabel={closeLabel} toast={toast} />;\n}\n\n/** The action, the close button, or nothing, after the message. */\nfunction SnackbarControls({\n action,\n close,\n closeLabel,\n isDismissable\n}: {\n action: SnackbarAction | undefined;\n close: () => void;\n closeLabel: string;\n isDismissable: boolean;\n}) {\n return <>\n {action === undefined ? null : <SnackbarButton onPress={actionPress(action, close)} style={styles.action}>\n {action.label}\n </SnackbarButton>}\n {isDismissable ? <SnackbarButton aria-label={closeLabel} slot=\"close\" style={styles.close}>\n <CloseGlyph className=\"xxk0z11 xvy4d1p\" />\n </SnackbarButton> : null}\n </>;\n}\n\n/** One snackbar: its message, then whatever sits after it. */\nfunction SnackbarToast({\n close,\n closeLabel,\n toast\n}: {\n close: () => void;\n closeLabel: string;\n toast: SnackbarToastItem;\n}) {\n const {\n action,\n isDismissable,\n message\n } = toast.content;\n return <RACToast toast={toast} className=\"x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1tfhd1 x1udv5rz x9f619 x78zum5 xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w\">\n <RACToastContent className=\"x9f619 x1girmi0 x1iyjqo2 xpo2rfv x193rfdd x1hews6w xn43zvd xv61bfh xz158ff xeuugli xxlmvz2\">\n <Text slot=\"title\">{message}</Text>\n </RACToastContent>\n <SnackbarControls action={action} close={close} closeLabel={closeLabel} isDismissable={isDismissable} />\n </RACToast>;\n}\nSnackbar.Queue = SnackbarQueue;\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component: this file would otherwise export something that is not a\n// component, which is what turns fast refresh off for it.\nexport type { SnackbarAction, SnackbarMessage, SnackbarOptions, SnackbarProps, SnackbarQueue, ToastRegionRenderProps as SnackbarRegionRenderProps };\nexport default Snackbar;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["ReactNode","FocusableElement","ToastRegionProps","RACToastRegionProps","ToastRegionRenderProps","stylex","Button","RACButton","UNSTABLE_Toast","RACToast","UNSTABLE_ToastContent","RACToastContent","UNSTABLE_ToastQueue","RACToastQueue","UNSTABLE_ToastRegion","RACToastRegion","Text","CloseGlyph","useRipple","mergeStatefulStyles","colors","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","SHORT_MS","LONG_MS","WIDE","rise","styles","action","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","k8WAf4","kg3NbH","$$css","close","kZKoxP","kzqmXN","kmVPX3","control","kGNEyG","kWkggS","kaIpWk","kMzoRj","kB7OPa","kkrTdU","k1xSpc","kmuXW","kjj79g","kjBf7l","kInvED","k3XXqK","kMeerF","kVQacm","kVAEAm","SnackbarAction","label","onPress","SnackbarMessage","isDismissable","message","SnackbarOptions","onClose","timeout","SnackbarProps","className","closeLabel","queue","SnackbarQueue","style","Omit","SnackbarToastItem","rac","constructor","maxVisibleToasts","add","options","undefined","clear","key","actionPress","closeToast","Snackbar","t0","$","_c","T0","t1","t2","t3","t4","t5","props","snackbarContent","SnackbarButton","children","ripple","handlers","surface","toast","SnackbarControls","SnackbarToast","content","Queue","SnackbarRegionRenderProps"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { FocusableElement, ToastRegionProps as RACToastRegionProps, ToastRegionRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, UNSTABLE_Toast as RACToast, UNSTABLE_ToastContent as RACToastContent, UNSTABLE_ToastQueue as RACToastQueue, UNSTABLE_ToastRegion as RACToastRegion, Text } from 'react-aria-components';\nimport { CloseGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, shadows, sizing, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that. The\n// page's container is the inverse surface at a 4dp corner and elevation 3,\n// its supporting text is body-medium in inverse on surface, its action label\n// is inverse primary, and its close icon takes the supporting text's colour.\n// The measurements are the page's too: 8dp of margin from the edges of the\n// screen, 8dp of padding inside the container with another 8dp either side\n// of the message, 14dp above and below on a single line, and between 320 and\n// 576dp wide above the page's 600dp breakpoint — full width below it.\n//\n// One at a time. The page shows a single snackbar and replaces it rather\n// than stacking, which is `maxVisibleToasts: 1` on the queue.\n//\n// React Aria's toast is the behaviour: the region is a landmark that holds\n// the message, moves focus into it for a keyboard, and pauses every timer\n// while it is hovered or focused, so a message never expires while it is\n// being read or acted on.\n//\n// Three things are decided here rather than taken from React Aria or from\n// the page.\n//\n// **The queue is ours, not React Aria's.** React Aria's toast is still\n// `UNSTABLE_`, and `SnackbarQueue` is what keeps that name out of a\n// consumer's code — an upstream rename is this file rather than every call\n// site. It wraps their queue, defaults it to one visible message, and takes\n// the message and its options as one call.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton.** The page colours them inverse primary and inverse\n// on surface, which no variant of either carries, and a colour pushed in\n// from outside through `className` is the merge hazard AGENTS.md describes:\n// StyleX decides between two atomic classes by their order in the compiled\n// stylesheet, not by the order they are applied. Both are React Aria's\n// `Button` with the same ripple and the same state layers, over\n// `currentColor` so each takes the colour the snackbar gives it.\n//\n// **There is no `container` prop.** Every other overlay here takes one,\n// because React Aria's `Modal` and `Popover` accept a portal container, and\n// `src/components/portal-container.test.tsx` is what keeps that true.\n// Its toast region does not: it reads a portal provider that\n// `react-aria-components` does not export, so the region always lands at the\n// end of `<body>`. An app that scopes its StyleX theme to a subtree has to\n// put the theme on `:root` for the snackbar to be drawn in it.\n\n// The page's two durations, from the same implementation its measurements\n// come from: a message alone is shown for the short one, a message with an\n// action for the long one, since an action has to be read before it can be\n// taken.\nconst SHORT_MS = 1500;\nconst LONG_MS = 2750;\n\n// Below the page's 600dp breakpoint the snackbar runs the width of the\n// screen; above it, it takes between 320 and 576.\nconst WIDE = '@media (min-width: 600px)';\n\n// The page's own is a fade. It rises a little as it arrives too, which is\n// what the page draws and what says the message came from the edge of the\n// screen rather than appearing over it.\nconst rise = \"x15b941j-B\";\nconst styles = {\n action: {\n kMwMTN: \"x16bex6i\",\n kMv6JI: \"xkknnkr\",\n kGuDYH: \"x14zspaw\",\n k63SB2: \"x1v9cpvo\",\n kb6lSQ: \"x155f00i\",\n kLWn49: \"x1lz68p4\",\n k8WAf4: \"x1cmllll\",\n kg3NbH: \"x18fpw6u\",\n $$css: true\n },\n close: {\n kZKoxP: \"xbg5kjn\",\n kMwMTN: \"x1girmi0\",\n kzqmXN: \"xoqf9c6\",\n kmVPX3: \"x1717udv\",\n $$css: true\n },\n control: {\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xy3r1oc x1en43ny x15a1ka xjbqb8w\",\n kaIpWk: \"x1dkaolv\",\n kMzoRj: \"xc342km\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"x14ytart\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n }\n};\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n label: string;\n /** Run when the action is pressed, just before the snackbar closes. */\n onPress: () => void;\n};\n\n/** What a snackbar carries: its message, and what may sit beside it. */\ntype SnackbarMessage = {\n action: SnackbarAction | undefined;\n isDismissable: boolean;\n message: ReactNode;\n};\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n action?: SnackbarAction;\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n * @default false\n */\n isDismissable?: boolean;\n /** Run when the snackbar closes, however it was closed. */\n onClose?: () => void;\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to the page's\n * short duration, or its long one when there is an action to read, and the\n * timer is paused while the region is hovered or focused so a message never\n * expires while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `isDismissable`, or there is no\n * way to be rid of it.\n */\n timeout?: number;\n};\ntype SnackbarProps = {\n /**\n * What a screen reader calls the region holding the snackbar. Left out,\n * React Aria names the region itself: a count of the messages it holds, in\n * the reader's own locale — \"1 notification.\" in English, and one of some\n * thirty languages otherwise. Pass a name only to replace that, and pass a\n * translated one, since whatever is passed is read as written.\n */\n 'aria-label'?: string;\n /** A function may compute the class from the region's render state. */\n className?: RACToastRegionProps<SnackbarMessage>['className'];\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message, so putting it there would make every `add` call repeat it.\n * @default 'Close'\n */\n closeLabel?: string;\n /** The queue the region shows messages from. */\n queue: SnackbarQueue;\n /** A function may compute the style from the region's render state. */\n style?: RACToastRegionProps<SnackbarMessage>['style'];\n} & Omit<RACToastRegionProps<SnackbarMessage>, 'children' | 'className' | 'queue' | 'style'>;\n\n// One entry of the queue, as React Aria hands it to the region's render\n// function. Taken from its render state rather than imported from\n// `react-stately`, which this package does not depend on.\ntype SnackbarToastItem = ToastRegionRenderProps<SnackbarMessage>['visibleToasts'][number];\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it —\n * a module of its own is the usual place — mount `Snackbar` once with it,\n * and call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n *\n * It wraps React Aria's toast queue rather than exposing it, which is what\n * keeps that API's `UNSTABLE_` name out of a consumer's code.\n */\nclass SnackbarQueue {\n /**\n * React Aria's queue, which `Snackbar` subscribes to. Not part of the\n * package's API — read it and an upstream release may break the call site.\n */\n readonly rac: RACToastQueue<SnackbarMessage>;\n constructor() {\n // One at a time, which is what the page shows: a second message replaces\n // the first rather than stacking under it.\n this.rac = new RACToastQueue<SnackbarMessage>({\n maxVisibleToasts: 1\n });\n }\n\n /**\n * Shows a message, and returns the key that closes it.\n */\n add(message: ReactNode, options: SnackbarOptions = {}) {\n const {\n action,\n isDismissable = false,\n onClose,\n timeout\n } = options;\n return this.rac.add({\n action,\n isDismissable,\n message\n }, {\n onClose,\n timeout: timeout ?? (action === undefined ? SHORT_MS : LONG_MS)\n });\n }\n\n /** Closes every snackbar, shown or waiting. */\n clear() {\n this.rac.clear();\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n this.rac.close(key);\n }\n}\n\n// The three handlers the snackbar hands to something below it, each built by\n// a call rather than written inline at the prop, which is what react-perf's\n// no-new-function-as-prop is after; the React Compiler memoises the result on\n// its inputs.\nfunction actionPress(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress();\n close();\n };\n}\nfunction closeToast(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key);\n };\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action. Mount\n * one of these with a `Snackbar.Queue`, and call the queue's `add` to show a\n * message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * The region is portalled to the end of `<body>` and renders nothing while\n * the queue is empty. It is one region rather than one per message, so mount\n * it once, near the root.\n *\n * The call site's `className` and `style` land on that region, which is the\n * element a layout positions.\n */\nfunction Snackbar({\n closeLabel = 'Close',\n queue,\n ...props\n}: SnackbarProps) {\n return <RACToastRegion<SnackbarMessage> queue={queue.rac} {...props} {...mergeStatefulStyles({\n className: \"x6s0dn4 x9f619 x78zum5 xdt5ytf x126z3so x1ey2m1c x17y0mx6 x1t137rt x1a7rqcl x47corl xixxii4 xfo81ep\"\n }, props)}>\n {snackbarContent(queue, closeLabel)}\n </RACToastRegion>;\n}\n\n/**\n * One of the snackbar's two controls. React Aria's `Button` rather than the\n * library's, for the colour reason in the comment at the top of this file;\n * the ripple and the state layers are the same ones every other control\n * here draws, over `currentColor`.\n */\nfunction SnackbarButton({\n children,\n style,\n ...props\n}: {\n 'aria-label'?: string;\n children: ReactNode;\n onPress?: () => void;\n slot?: string;\n style: stylex.StyleXStyles;\n}) {\n const ripple = useRipple<FocusableElement>();\n return <RACButton {...ripple.handlers} {...props} {...stylex.props(styles.control, style)}>\n {children}\n {ripple.surface}\n </RACButton>;\n}\nfunction snackbarContent(queue: SnackbarQueue, closeLabel: string) {\n return ({\n toast\n }: {\n toast: SnackbarToastItem;\n }) => <SnackbarToast close={closeToast(queue, toast.key)} closeLabel={closeLabel} toast={toast} />;\n}\n\n/** The action, the close button, or nothing, after the message. */\nfunction SnackbarControls({\n action,\n close,\n closeLabel,\n isDismissable\n}: {\n action: SnackbarAction | undefined;\n close: () => void;\n closeLabel: string;\n isDismissable: boolean;\n}) {\n return <>\n {action === undefined ? null : <SnackbarButton onPress={actionPress(action, close)} style={styles.action}>\n {action.label}\n </SnackbarButton>}\n {isDismissable ? <SnackbarButton aria-label={closeLabel} slot=\"close\" style={styles.close}>\n <CloseGlyph className=\"xxk0z11 xvy4d1p\" />\n </SnackbarButton> : null}\n </>;\n}\n\n/** One snackbar: its message, then whatever sits after it. */\nfunction SnackbarToast({\n close,\n closeLabel,\n toast\n}: {\n close: () => void;\n closeLabel: string;\n toast: SnackbarToastItem;\n}) {\n const {\n action,\n isDismissable,\n message\n } = toast.content;\n return <RACToast toast={toast} className=\"x6s0dn4 x1n1nwrg x1u6grsq x1dwmuk9 x16dv9tl x1c5gpgi x1tfhd1 x1udv5rz x9f619 x78zum5 xh8yej3 x1x1rfll xlx31pv x1dry9sr xeuugli xuq8xha x1ulcdur x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd xn60lsn x67bb7w\">\n <RACToastContent className=\"x9f619 x1girmi0 x1iyjqo2 xpo2rfv x193rfdd x1hews6w xn43zvd xv61bfh xz158ff xeuugli xxlmvz2\">\n <Text slot=\"title\">{message}</Text>\n </RACToastContent>\n <SnackbarControls action={action} close={close} closeLabel={closeLabel} isDismissable={isDismissable} />\n </RACToast>;\n}\nSnackbar.Queue = SnackbarQueue;\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component: this file would otherwise export something that is not a\n// component, which is what turns fast refresh off for it.\nexport type { SnackbarAction, SnackbarMessage, SnackbarOptions, SnackbarProps, SnackbarQueue, ToastRegionRenderProps as SnackbarRegionRenderProps };\nexport default Snackbar;"],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ const _temp = {
|
|
|
18
18
|
};
|
|
19
19
|
const styles = {
|
|
20
20
|
control: {
|
|
21
|
+
kgeoSG: "x1cpjm7i",
|
|
22
|
+
kGOzcv: "x1fb0czk",
|
|
23
|
+
kpsdNU: "xm4btww",
|
|
24
|
+
kEoFBp: "x1hmns74",
|
|
21
25
|
kGNEyG: "x6s0dn4",
|
|
22
26
|
kZKoxP: "x1vqgdyp",
|
|
23
27
|
kB7OPa: "x9f619",
|
|
@@ -26,6 +30,7 @@ const styles = {
|
|
|
26
30
|
kmuXW: "x2lah0s",
|
|
27
31
|
kzqmXN: "xvni27",
|
|
28
32
|
kjj79g: "xl56j7k",
|
|
33
|
+
kVAEAm: "x1n2onr6",
|
|
29
34
|
$$css: true
|
|
30
35
|
},
|
|
31
36
|
handle: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["MouseEvent","ReactMouseEvent","ReactNode","PointerEvent","ReactPointerEvent","SwitchFieldProps","RACSwitchFieldProps","SwitchButtonRenderProps","stylex","useCallback","useRef","useState","SwitchButton","SwitchField","ControlLabel","controlStyles","FieldMessage","invalidFrom","useFieldValidationBehavior","CheckGlyph","useRipple","focus","mergeStatefulStyles","colors","motion","radii","stateLayerOpacity","_temp","kLqNvP","styles","control","kGNEyG","kZKoxP","kB7OPa","kkrTdU","k1xSpc","kmuXW","kzqmXN","kjj79g","$$css","handle","k6CgDc","kWkggS","kaIpWk","kMwMTN","kIyJzY","k1ekBW","kAMwcw","handleActive","handleDisabled","handleOn","handleOnActive","handleOnDisabled","handlePressed","layer","kpwlN0","kVAEAm","seat","k87sOh","seatAt","offset","val","undefined","seatDragging","seatOn","track","kVAM5u","ksu8eU","kMzoRj","trackDisabled","trackOn","trackOnDisabled","hoverLayers","off","on","pressedLayers","TRAVEL","Drag","ReturnType","useHandleDrag","Ripple","HTMLSpanElement","SwitchProps","children","description","error","icon","Omit","buttonContent","ripple","drag","state","interactive","isDisabled","isReadOnly","isSelected","dragging","active","isHovered","isPressed","isFocusVisible","props","controlReadOnly","controlDisabled","ringVisible","handlers","surface","Switch","t0","$","_c","t1","validationBehavior","T0","t2","t3","field","t4","t5","t6","Symbol","for","messages","t7","t8","setOffset","origin","settled","cancelClick","current","onPointerCancel","event","preventDefault","stopPropagation","onClickCapture","event_0","from","along","rtl","x","clientX","next","Math","min","max","base","onPointerMove","event_1","from_0","stopped","currentTarget","dispatchEvent","bubbles","pointerId","pointerType","input","closest","querySelector","click","onPointerUp","onPointerDown","event_2","button","getComputedStyle","direction","setPointerCapture"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["// React's event types are aliased because `useHandleDrag` also constructs a\n// DOM `PointerEvent`. Imported unaliased, the name shadows that constructor:\n// TypeScript still resolves the call to the global, since a type-only import\n// takes no value name, but a reader and a static analyser alike read it as\n// React's type, which has no runtime value behind it at all.\nimport type { MouseEvent as ReactMouseEvent, ReactNode, PointerEvent as ReactPointerEvent } from 'react';\nimport type { SwitchFieldProps as RACSwitchFieldProps, SwitchButtonRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback, useRef, useState } from 'react';\nimport { SwitchButton, SwitchField } from 'react-aria-components';\nimport { ControlLabel } from '../../control';\nimport { controlStyles } from '../../control/styles';\nimport { FieldMessage } from '../../field';\nimport { invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// The switch page: a 52 by 32dp track with a 2dp outline and a full corner,\n// a handle that is 16dp off, 24dp on and 28dp while pressed, a 16dp icon in\n// the handle when asked for, a 40dp state layer around the handle and a 48dp\n// target. Off, the track is surface container highest inside an outline\n// rule and the handle is outline, turning on surface variant while hovered,\n// pressed or focused; on, the track is primary and the handle on primary,\n// turning primary container in the same states, with the icon in on primary\n// container. Disabled, the track and its rule are on surface at the\n// disabled container opacity and the handle on surface at the disabled\n// content opacity, or surface when on. The state layer is on surface off and\n// primary on.\n//\n// React Aria's `SwitchField` is the root, a div holding the description and\n// error slots; its `SwitchButton` is the label around a visually hidden\n// input, and everything drawn is that label's children, chosen from the\n// render state React Aria hands them. The field is the two-column grid the\n// checkbox uses, with the label `display: contents`, so the description and\n// error line up under the text.\n//\n// The handle travels between the two ends of the track and grows between\n// its three sizes on the same transition, `motion.durationShort2` with the\n// standard easing; the state layer and the ripple sit on a 40dp disc centred\n// on the handle, so they move with it. The adjacent label is body-large on\n// surface, which the page keeps the same whichever way the switch is.\n//\n// The page's pressed handle follows the pointer: it grows, travels with the\n// drag, and the switch flips when it is released past the middle of the\n// track or springs back when it is not. React Aria's `SwitchButton` has no\n// drag of its own, so the travel is this component's — see `useHandleDrag`.\nconst _temp = {\n kLqNvP: \"x1lxsm33\",\n \"$$css\": true\n};\nconst styles = {\n control: {\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1vqgdyp\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kjj79g: \"xl56j7k\",\n $$css: true\n },\n handle: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xp2scj5\",\n kZKoxP: \"xlup9mm\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"xscdzaa\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1kky2od\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x7okvu4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n handleActive: {\n kWkggS: \"x1ccu2yh\",\n $$css: true\n },\n handleDisabled: {\n kWkggS: \"x1crcgwy\",\n $$css: true\n },\n handleOn: {\n kWkggS: \"x1ntwmx2\",\n kZKoxP: \"xxk0z11\",\n kzqmXN: \"xvy4d1p\",\n $$css: true\n },\n handleOnActive: {\n kWkggS: \"xp89om9\",\n $$css: true\n },\n handleOnDisabled: {\n kWkggS: \"x14s9m32\",\n kMwMTN: \"x1gpw424\",\n $$css: true\n },\n handlePressed: {\n kZKoxP: \"x1fgtraw\",\n kzqmXN: \"xgd8bvy\",\n $$css: true\n },\n layer: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1vqgdyp\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kzqmXN: \"x100vrsf\",\n kpwlN0: \"x1qx2jxi\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seat: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1fgtraw\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"xgd8bvy\",\n k87sOh: \"x13vifvy\",\n kLqNvP: \"x1o0tod\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x2hifos\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seatAt: (offset: number) => [_temp, {\n \"--x-insetInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(`${offset}px`)\n }],\n seatDragging: {\n kIyJzY: \"x1mq3mr6\",\n $$css: true\n },\n seatOn: {\n kLqNvP: \"x1n8ud3w\",\n $$css: true\n },\n track: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"x1rrhr5q\",\n kZKoxP: \"x10w6t97\",\n kVAM5u: \"x1fwvt7v\",\n kaIpWk: \"x1dkaolv\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xdh2fpr\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xts7igz\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n trackDisabled: {\n kWkggS: \"x1trd85j\",\n kVAM5u: \"xrh88j3\",\n $$css: true\n },\n trackOn: {\n kWkggS: \"xnety89\",\n kVAM5u: \"x1uajy3w\",\n $$css: true\n },\n trackOnDisabled: {\n kWkggS: \"x19v6zzp\",\n kVAM5u: \"x9r1u3d\",\n $$css: true\n }\n};\n\n// The state layer over the handle: on surface while the switch is off and\n// primary while it is on, at the hover or the pressed opacity.\nconst hoverLayers = {\n off: {\n kWkggS: \"x1b18xnh\",\n $$css: true\n },\n on: {\n kWkggS: \"x659ado\",\n $$css: true\n }\n};\nconst pressedLayers = {\n off: {\n kWkggS: \"xjeeohs\",\n $$css: true\n },\n on: {\n kWkggS: \"x1dvjsmr\",\n $$css: true\n }\n};\n\n// How far the seat travels: the track's 48dp inside its 2dp rule, less the\n// seat's own 28dp.\nconst TRAVEL = 20;\ntype Drag = ReturnType<typeof useHandleDrag>;\ntype Ripple = ReturnType<typeof useRipple<HTMLSpanElement>>;\ntype SwitchProps = {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` instead.\n */\n children?: ReactNode;\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * Draws the check in the handle while the switch is on, the page's\n * \"icon on selected switch\" form.\n * @default false\n */\n icon?: boolean;\n} & Omit<RACSwitchFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n// What the label draws, chosen from the render state React Aria hands it.\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler memoises\n// the result on its inputs. The ripple's handlers and surface go on the\n// state layer while the switch can change, and are left off while it\n// cannot, since a press that changes nothing should not look like one.\nfunction buttonContent(children: ReactNode, icon: boolean, ripple: Ripple, drag: Drag) {\n return (state: SwitchButtonRenderProps) => {\n const interactive = !state.isDisabled && !state.isReadOnly;\n const on = state.isSelected;\n const dragging = interactive && drag.offset !== null;\n const active = interactive && (state.isHovered || state.isPressed || state.isFocusVisible);\n return <>\n <span {...stylex.props(styles.control, state.isReadOnly && controlStyles.controlReadOnly, state.isDisabled && controlStyles.controlDisabled)}>\n <span {...stylex.props(styles.track, on && styles.trackOn, state.isDisabled && (on ? styles.trackOnDisabled : styles.trackDisabled), state.isFocusVisible && focus.ringVisible)}>\n <span {...interactive ? drag.handlers(on) : {}} {...stylex.props(styles.seat, on && styles.seatOn, dragging && styles.seatDragging, dragging && styles.seatAt(drag.offset ?? 0))}>\n <span {...interactive ? ripple.handlers : {}} {...stylex.props(styles.layer, interactive && state.isHovered && hoverLayers[on ? 'on' : 'off'], interactive && state.isPressed && pressedLayers[on ? 'on' : 'off'])}>\n {interactive ? ripple.surface : null}\n </span>\n <span {...stylex.props(styles.handle, on && styles.handleOn, active && (on ? styles.handleOnActive : styles.handleActive), (dragging || interactive && state.isPressed) && styles.handlePressed, state.isDisabled && (on ? styles.handleOnDisabled : styles.handleDisabled))}>\n {icon && on ? <CheckGlyph className=\"xlup9mm x1lliihq x1kky2od\" /> : null}\n </span>\n </span>\n </span>\n </span>\n <ControlLabel state={state}>{children}</ControlLabel>\n </>;\n };\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Aria's: pass\n * `isSelected` with `onChange` to control it, or `defaultSelected` to let it\n * keep its own. A switch takes effect as it is flipped, which is what sets\n * it apart from a checkbox in a form.\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions.\n */\nfunction Switch({\n children,\n description,\n error,\n icon = false,\n ...props\n}: SwitchProps) {\n const ripple = useRipple<HTMLSpanElement>();\n const drag = useHandleDrag();\n const validationBehavior = useFieldValidationBehavior();\n return <SwitchField isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(controlStyles.field), props)}>\n <SwitchButton className=\"xjp7ctv\">\n {buttonContent(children, icon, ripple, drag)}\n </SwitchButton>\n <div {...stylex.props(controlStyles.messages)}>\n <FieldMessage description={description} error={error} inset={false} />\n </div>\n </SwitchField>;\n}\n\n/**\n * The handle following a pointer across the track, as the switch page draws\n * a pressed switch. The seat's inset comes from the drag while one is under\n * way, and the switch settles from where the handle was let go: on past the\n * middle of the track, off before it.\n *\n * What flips the switch on an ordinary tap is React Aria's own press, which\n * ends on the pointer being released and pays no attention to where the\n * handle was dragged to — so a drag has to end that press before releasing,\n * which is what the pointer cancel is for, and settle the switch itself.\n * Settling means clicking the field's own input, the same element a tap\n * reaches in the end: the change goes through React Aria, and a controlled\n * switch stays controlled, since nothing here calls `onChange` or holds any\n * state of the switch's own. The click the pointer's release sends after\n * that is cancelled too, so nothing flips the switch a second time.\n *\n * A press that never moves is left alone entirely, so a tap flips the switch\n * as it did before.\n */\nfunction useHandleDrag() {\n const [offset, setOffset] = useState<null | number>(null);\n const origin = useRef<null | {\n base: number;\n on: boolean;\n rtl: boolean;\n x: number;\n }>(null);\n const settled = useRef<null | number>(null);\n const cancelClick = useRef(false);\n const onPointerCancel = useCallback(() => {\n origin.current = null;\n settled.current = null;\n setOffset(null);\n }, []);\n const onClickCapture = useCallback((event: ReactMouseEvent<HTMLSpanElement>) => {\n if (!cancelClick.current) {\n return;\n }\n cancelClick.current = false;\n // The label's activation is the browser's own, so this is what stops the\n // input being flipped by a drag that settled where it began.\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n if (from === null) {\n return;\n }\n const along = from.rtl ? from.x - event.clientX : event.clientX - from.x;\n const next = Math.min(TRAVEL, Math.max(0, from.base + along));\n settled.current = next;\n setOffset(next);\n }, []);\n const onPointerUp = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n const stopped = settled.current;\n const seat = event.currentTarget;\n origin.current = null;\n settled.current = null;\n setOffset(null);\n // A press that never moved is a tap, which React Aria flips on its own.\n if (from === null || stopped === null) {\n return;\n }\n // React Aria's press is about to flip the switch from wherever it\n // started, so it is cancelled first — a pointer cancel is what ends a\n // press without firing it — and the drag settles the switch instead.\n seat.dispatchEvent(new PointerEvent('pointercancel', {\n bubbles: true,\n pointerId: event.pointerId,\n pointerType: event.pointerType\n }));\n // The pointer's own click follows this, by which time the switch has\n // already settled.\n cancelClick.current = true;\n if (stopped > TRAVEL / 2 === from.on) {\n return;\n }\n const input = seat.closest('label')?.querySelector('input');\n input?.click();\n }, []);\n const handlers = useCallback((on: boolean) => ({\n onClickCapture,\n onPointerCancel,\n onPointerDown: (event: ReactPointerEvent<HTMLSpanElement>) => {\n if (event.pointerType === 'mouse' && event.button !== 0) {\n return;\n }\n origin.current = {\n base: on ? TRAVEL : 0,\n on,\n rtl: getComputedStyle(event.currentTarget).direction === 'rtl',\n x: event.clientX\n };\n settled.current = null;\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // A pointer the browser is not tracking has no capture to take —\n // a synthetic event in a test, where the moves are dispatched on\n // this element anyway.\n }\n },\n onPointerMove,\n onPointerUp\n }), [onClickCapture, onPointerCancel, onPointerMove, onPointerUp]);\n return {\n handlers,\n offset\n };\n}\nexport type { SwitchProps };\nexport default Switch;"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["MouseEvent","ReactMouseEvent","ReactNode","PointerEvent","ReactPointerEvent","SwitchFieldProps","RACSwitchFieldProps","SwitchButtonRenderProps","stylex","useCallback","useRef","useState","SwitchButton","SwitchField","ControlLabel","controlStyles","FieldMessage","invalidFrom","useFieldValidationBehavior","CheckGlyph","useRipple","focus","mergeStatefulStyles","colors","motion","radii","stateLayerOpacity","_temp","kLqNvP","styles","control","kgeoSG","kGOzcv","kpsdNU","kEoFBp","kGNEyG","kZKoxP","kB7OPa","kkrTdU","k1xSpc","kmuXW","kzqmXN","kjj79g","kVAEAm","$$css","handle","k6CgDc","kWkggS","kaIpWk","kMwMTN","kIyJzY","k1ekBW","kAMwcw","handleActive","handleDisabled","handleOn","handleOnActive","handleOnDisabled","handlePressed","layer","kpwlN0","seat","k87sOh","seatAt","offset","val","undefined","seatDragging","seatOn","track","kVAM5u","ksu8eU","kMzoRj","trackDisabled","trackOn","trackOnDisabled","hoverLayers","off","on","pressedLayers","TRAVEL","Drag","ReturnType","useHandleDrag","Ripple","HTMLSpanElement","SwitchProps","children","description","error","icon","Omit","buttonContent","ripple","drag","state","interactive","isDisabled","isReadOnly","isSelected","dragging","active","isHovered","isPressed","isFocusVisible","props","controlReadOnly","controlDisabled","ringVisible","handlers","surface","Switch","t0","$","_c","t1","validationBehavior","T0","t2","t3","field","t4","t5","t6","Symbol","for","messages","t7","t8","setOffset","origin","settled","cancelClick","current","onPointerCancel","event","preventDefault","stopPropagation","onClickCapture","event_0","from","along","rtl","x","clientX","next","Math","min","max","base","onPointerMove","event_1","from_0","stopped","currentTarget","dispatchEvent","bubbles","pointerId","pointerType","input","closest","querySelector","click","onPointerUp","onPointerDown","event_2","button","getComputedStyle","direction","setPointerCapture"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["// React's event types are aliased because `useHandleDrag` also constructs a\n// DOM `PointerEvent`. Imported unaliased, the name shadows that constructor:\n// TypeScript still resolves the call to the global, since a type-only import\n// takes no value name, but a reader and a static analyser alike read it as\n// React's type, which has no runtime value behind it at all.\nimport type { MouseEvent as ReactMouseEvent, ReactNode, PointerEvent as ReactPointerEvent } from 'react';\nimport type { SwitchFieldProps as RACSwitchFieldProps, SwitchButtonRenderProps } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { useCallback, useRef, useState } from 'react';\nimport { SwitchButton, SwitchField } from 'react-aria-components';\nimport { ControlLabel } from '../../control';\nimport { controlStyles } from '../../control/styles';\nimport { FieldMessage } from '../../field';\nimport { invalidFrom, useFieldValidationBehavior } from '../../field/root';\nimport { CheckGlyph } from '../../glyphs';\nimport { useRipple } from '../../hooks/useRipple';\nimport { focus } from '../../styles/focus';\nimport { mergeStatefulStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// The switch page: a 52 by 32dp track with a 2dp outline and a full corner,\n// a handle that is 16dp off, 24dp on and 28dp while pressed, a 16dp icon in\n// the handle when asked for, a 40dp state layer around the handle and a 48dp\n// target. Off, the track is surface container highest inside an outline\n// rule and the handle is outline, turning on surface variant while hovered,\n// pressed or focused; on, the track is primary and the handle on primary,\n// turning primary container in the same states, with the icon in on primary\n// container. Disabled, the track and its rule are on surface at the\n// disabled container opacity and the handle on surface at the disabled\n// content opacity, or surface when on. The state layer is on surface off and\n// primary on.\n//\n// React Aria's `SwitchField` is the root, a div holding the description and\n// error slots; its `SwitchButton` is the label around a visually hidden\n// input, and everything drawn is that label's children, chosen from the\n// render state React Aria hands them. The field is the two-column grid the\n// checkbox uses, with the label `display: contents`, so the description and\n// error line up under the text.\n//\n// The handle travels between the two ends of the track and grows between\n// its three sizes on the same transition, `motion.durationShort2` with the\n// standard easing; the state layer and the ripple sit on a 40dp disc centred\n// on the handle, so they move with it. The adjacent label is body-large on\n// surface, which the page keeps the same whichever way the switch is.\n//\n// The page's pressed handle follows the pointer: it grows, travels with the\n// drag, and the switch flips when it is released past the middle of the\n// track or springs back when it is not. React Aria's `SwitchButton` has no\n// drag of its own, so the travel is this component's — see `useHandleDrag`.\nconst _temp = {\n kLqNvP: \"x1lxsm33\",\n \"$$css\": true\n};\nconst styles = {\n control: {\n kgeoSG: \"x1cpjm7i\",\n kGOzcv: \"x1fb0czk\",\n kpsdNU: \"xm4btww\",\n kEoFBp: \"x1hmns74\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1vqgdyp\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n handle: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xp2scj5\",\n kZKoxP: \"xlup9mm\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kMwMTN: \"xscdzaa\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"x1kky2od\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x7okvu4\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n handleActive: {\n kWkggS: \"x1ccu2yh\",\n $$css: true\n },\n handleDisabled: {\n kWkggS: \"x1crcgwy\",\n $$css: true\n },\n handleOn: {\n kWkggS: \"x1ntwmx2\",\n kZKoxP: \"xxk0z11\",\n kzqmXN: \"xvy4d1p\",\n $$css: true\n },\n handleOnActive: {\n kWkggS: \"xp89om9\",\n $$css: true\n },\n handleOnDisabled: {\n kWkggS: \"x14s9m32\",\n kMwMTN: \"x1gpw424\",\n $$css: true\n },\n handlePressed: {\n kZKoxP: \"x1fgtraw\",\n kzqmXN: \"xgd8bvy\",\n $$css: true\n },\n layer: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1vqgdyp\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kzqmXN: \"x100vrsf\",\n kpwlN0: \"x1qx2jxi\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seat: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kZKoxP: \"x1fgtraw\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kzqmXN: \"xgd8bvy\",\n k87sOh: \"x13vifvy\",\n kLqNvP: \"x1o0tod\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x10l6tqk\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x2hifos\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n seatAt: (offset: number) => [_temp, {\n \"--x-insetInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(`${offset}px`)\n }],\n seatDragging: {\n kIyJzY: \"x1mq3mr6\",\n $$css: true\n },\n seatOn: {\n kLqNvP: \"x1n8ud3w\",\n $$css: true\n },\n track: {\n k6CgDc: \"x12w9bfk\",\n kWkggS: \"x1rrhr5q\",\n kZKoxP: \"x10w6t97\",\n kVAM5u: \"x1fwvt7v\",\n kaIpWk: \"x1dkaolv\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xdh2fpr\",\n kB7OPa: \"x9f619\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"xvni27\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xts7igz\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n trackDisabled: {\n kWkggS: \"x1trd85j\",\n kVAM5u: \"xrh88j3\",\n $$css: true\n },\n trackOn: {\n kWkggS: \"xnety89\",\n kVAM5u: \"x1uajy3w\",\n $$css: true\n },\n trackOnDisabled: {\n kWkggS: \"x19v6zzp\",\n kVAM5u: \"x9r1u3d\",\n $$css: true\n }\n};\n\n// The state layer over the handle: on surface while the switch is off and\n// primary while it is on, at the hover or the pressed opacity.\nconst hoverLayers = {\n off: {\n kWkggS: \"x1b18xnh\",\n $$css: true\n },\n on: {\n kWkggS: \"x659ado\",\n $$css: true\n }\n};\nconst pressedLayers = {\n off: {\n kWkggS: \"xjeeohs\",\n $$css: true\n },\n on: {\n kWkggS: \"x1dvjsmr\",\n $$css: true\n }\n};\n\n// How far the seat travels: the track's 48dp inside its 2dp rule, less the\n// seat's own 28dp.\nconst TRAVEL = 20;\ntype Drag = ReturnType<typeof useHandleDrag>;\ntype Ripple = ReturnType<typeof useRipple<HTMLSpanElement>>;\ntype SwitchProps = {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` instead.\n */\n children?: ReactNode;\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n description?: string;\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state — the message and `aria-invalid` follow\n * from it.\n *\n * Outside a `Form` the message line arrives with the message, so the\n * field grows when this does and moves what is under it. A `Form` holds\n * that space from the start; so does a permanent `description`.\n */\n error?: string;\n /**\n * Draws the check in the handle while the switch is on, the page's\n * \"icon on selected switch\" form.\n * @default false\n */\n icon?: boolean;\n} & Omit<RACSwitchFieldProps, 'children' | 'isInvalid' | 'validationBehavior'>;\n\n// What the label draws, chosen from the render state React Aria hands it.\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler memoises\n// the result on its inputs. The ripple's handlers and surface go on the\n// state layer while the switch can change, and are left off while it\n// cannot, since a press that changes nothing should not look like one.\nfunction buttonContent(children: ReactNode, icon: boolean, ripple: Ripple, drag: Drag) {\n return (state: SwitchButtonRenderProps) => {\n const interactive = !state.isDisabled && !state.isReadOnly;\n const on = state.isSelected;\n const dragging = interactive && drag.offset !== null;\n const active = interactive && (state.isHovered || state.isPressed || state.isFocusVisible);\n return <>\n <span {...stylex.props(styles.control, state.isReadOnly && controlStyles.controlReadOnly, state.isDisabled && controlStyles.controlDisabled)}>\n <span {...stylex.props(styles.track, on && styles.trackOn, state.isDisabled && (on ? styles.trackOnDisabled : styles.trackDisabled), state.isFocusVisible && focus.ringVisible)}>\n <span {...interactive ? drag.handlers(on) : {}} {...stylex.props(styles.seat, on && styles.seatOn, dragging && styles.seatDragging, dragging && styles.seatAt(drag.offset ?? 0))}>\n <span {...interactive ? ripple.handlers : {}} {...stylex.props(styles.layer, interactive && state.isHovered && hoverLayers[on ? 'on' : 'off'], interactive && state.isPressed && pressedLayers[on ? 'on' : 'off'])}>\n {interactive ? ripple.surface : null}\n </span>\n <span {...stylex.props(styles.handle, on && styles.handleOn, active && (on ? styles.handleOnActive : styles.handleActive), (dragging || interactive && state.isPressed) && styles.handlePressed, state.isDisabled && (on ? styles.handleOnDisabled : styles.handleDisabled))}>\n {icon && on ? <CheckGlyph className=\"xlup9mm x1lliihq x1kky2od\" /> : null}\n </span>\n </span>\n </span>\n </span>\n <ControlLabel state={state}>{children}</ControlLabel>\n </>;\n };\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Aria's: pass\n * `isSelected` with `onChange` to control it, or `defaultSelected` to let it\n * keep its own. A switch takes effect as it is flipped, which is what sets\n * it apart from a checkbox in a form.\n *\n * The call site's `className` and `style` land on the field as a whole,\n * which is the element a layout positions.\n */\nfunction Switch({\n children,\n description,\n error,\n icon = false,\n ...props\n}: SwitchProps) {\n const ripple = useRipple<HTMLSpanElement>();\n const drag = useHandleDrag();\n const validationBehavior = useFieldValidationBehavior();\n return <SwitchField isInvalid={invalidFrom(error)} validationBehavior={validationBehavior} {...props} {...mergeStatefulStyles(stylex.props(controlStyles.field), props)}>\n <SwitchButton className=\"xjp7ctv\">\n {buttonContent(children, icon, ripple, drag)}\n </SwitchButton>\n <div {...stylex.props(controlStyles.messages)}>\n <FieldMessage description={description} error={error} inset={false} />\n </div>\n </SwitchField>;\n}\n\n/**\n * The handle following a pointer across the track, as the switch page draws\n * a pressed switch. The seat's inset comes from the drag while one is under\n * way, and the switch settles from where the handle was let go: on past the\n * middle of the track, off before it.\n *\n * What flips the switch on an ordinary tap is React Aria's own press, which\n * ends on the pointer being released and pays no attention to where the\n * handle was dragged to — so a drag has to end that press before releasing,\n * which is what the pointer cancel is for, and settle the switch itself.\n * Settling means clicking the field's own input, the same element a tap\n * reaches in the end: the change goes through React Aria, and a controlled\n * switch stays controlled, since nothing here calls `onChange` or holds any\n * state of the switch's own. The click the pointer's release sends after\n * that is cancelled too, so nothing flips the switch a second time.\n *\n * A press that never moves is left alone entirely, so a tap flips the switch\n * as it did before.\n */\nfunction useHandleDrag() {\n const [offset, setOffset] = useState<null | number>(null);\n const origin = useRef<null | {\n base: number;\n on: boolean;\n rtl: boolean;\n x: number;\n }>(null);\n const settled = useRef<null | number>(null);\n const cancelClick = useRef(false);\n const onPointerCancel = useCallback(() => {\n origin.current = null;\n settled.current = null;\n setOffset(null);\n }, []);\n const onClickCapture = useCallback((event: ReactMouseEvent<HTMLSpanElement>) => {\n if (!cancelClick.current) {\n return;\n }\n cancelClick.current = false;\n // The label's activation is the browser's own, so this is what stops the\n // input being flipped by a drag that settled where it began.\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n if (from === null) {\n return;\n }\n const along = from.rtl ? from.x - event.clientX : event.clientX - from.x;\n const next = Math.min(TRAVEL, Math.max(0, from.base + along));\n settled.current = next;\n setOffset(next);\n }, []);\n const onPointerUp = useCallback((event: ReactPointerEvent<HTMLSpanElement>) => {\n const from = origin.current;\n const stopped = settled.current;\n const seat = event.currentTarget;\n origin.current = null;\n settled.current = null;\n setOffset(null);\n // A press that never moved is a tap, which React Aria flips on its own.\n if (from === null || stopped === null) {\n return;\n }\n // React Aria's press is about to flip the switch from wherever it\n // started, so it is cancelled first — a pointer cancel is what ends a\n // press without firing it — and the drag settles the switch instead.\n seat.dispatchEvent(new PointerEvent('pointercancel', {\n bubbles: true,\n pointerId: event.pointerId,\n pointerType: event.pointerType\n }));\n // The pointer's own click follows this, by which time the switch has\n // already settled.\n cancelClick.current = true;\n if (stopped > TRAVEL / 2 === from.on) {\n return;\n }\n const input = seat.closest('label')?.querySelector('input');\n input?.click();\n }, []);\n const handlers = useCallback((on: boolean) => ({\n onClickCapture,\n onPointerCancel,\n onPointerDown: (event: ReactPointerEvent<HTMLSpanElement>) => {\n if (event.pointerType === 'mouse' && event.button !== 0) {\n return;\n }\n origin.current = {\n base: on ? TRAVEL : 0,\n on,\n rtl: getComputedStyle(event.currentTarget).direction === 'rtl',\n x: event.clientX\n };\n settled.current = null;\n try {\n event.currentTarget.setPointerCapture(event.pointerId);\n } catch {\n // A pointer the browser is not tracking has no capture to take —\n // a synthetic event in a test, where the moves are dispatched on\n // this element anyway.\n }\n },\n onPointerMove,\n onPointerUp\n }), [onClickCapture, onPointerCancel, onPointerMove, onPointerUp]);\n return {\n handlers,\n offset\n };\n}\nexport type { SwitchProps };\nexport default Switch;"],"mappings":"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"}
|
package/dist/control/styles.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","names":["stylex","colors","motion","radii","spacing","stateLayerOpacity","typography","TARGET_SIZE","controlStyles","controlDisabled","kkrTdU","$$css","controlReadOnly","disc","k6CgDc","kGNEyG","kWkggS","kZKoxP","kaIpWk","kB7OPa","k1xSpc","kmuXW","kzqmXN","kjj79g","kVAEAm","kIyJzY","k1ekBW","kAMwcw","field","k1C7PZ","kumcoG","label","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","k8WAf4","labelDisabled","labelReadOnly","messages","kEXP64"],"sources":["../../src/control/styles.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../tokens/design.tokens.stylex';\n\n// The row a selection control draws, shared by Checkbox, Switch and Radio.\n// Each wrote it out in full: the two-column grid, the body-large label with\n// its disabled and read-only fades, the messages cell under the text, and the\n// cursors the control takes in those two states. Switch's own comment already\n// said it drew \"the two-column grid the checkbox uses\" while keeping a second\n// copy, so the coupling was recorded in prose rather than in code — the same\n// thing src/field and src/row were extracted to stop.\n//\n// The set is closed at three. React Aria Components has no fourth component\n// drawing this row, and CheckboxGroup is a container rather than a control.\n// What this is worth is that the three cannot drift apart, and that the\n// repository's own convention — a style more than one component draws lives\n// beside src/components, not inside it — holds here too.\n//\n// Two things deliberately stay with each component.\n//\n// The state layers are three different shapes rather than one shape with\n// three sets of key names. Checkbox carries an `error` key Radio has no\n// equivalent for, Checkbox's pressed set inverts its own key names, and\n// Switch deliberately does not invert at all. One style keyed on a `marked`\n// boolean would have to encode an error branch one caller uses, an inversion\n// another uses, and a documented non-inversion for the third, which costs a\n// reader more than the three short `stylex.create` calls it would replace.\n//\n// And the disc's colour. Checkbox draws it in `onSurface` and Radio in\n// `onSurfaceVariant`, which is the one declaration their otherwise identical\n// discs disagree on, so `disc` holds the other fourteen and each component\n// composes its own colour after.\n// The
|
|
1
|
+
{"version":3,"file":"styles.js","names":["stylex","colors","motion","radii","spacing","stateLayerOpacity","typography","LAYER_SIZE","TARGET_SIZE","TARGET_REACH","controlStyles","controlDisabled","kkrTdU","$$css","controlReadOnly","disc","kgeoSG","kFcpXp","kEoFBp","k6CgDc","kGNEyG","kWkggS","kZKoxP","kaIpWk","kB7OPa","k1xSpc","kmuXW","kzqmXN","kjj79g","kVAEAm","kIyJzY","k1ekBW","kAMwcw","field","k1C7PZ","kumcoG","label","kMwMTN","kMv6JI","kGuDYH","k63SB2","kb6lSQ","kLWn49","k8WAf4","labelDisabled","labelReadOnly","messages","kEXP64"],"sources":["../../src/control/styles.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport '../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../tokens/design.tokens.stylex';\n\n// The row a selection control draws, shared by Checkbox, Switch and Radio.\n// Each wrote it out in full: the two-column grid, the body-large label with\n// its disabled and read-only fades, the messages cell under the text, and the\n// cursors the control takes in those two states. Switch's own comment already\n// said it drew \"the two-column grid the checkbox uses\" while keeping a second\n// copy, so the coupling was recorded in prose rather than in code — the same\n// thing src/field and src/row were extracted to stop.\n//\n// The set is closed at three. React Aria Components has no fourth component\n// drawing this row, and CheckboxGroup is a container rather than a control.\n// What this is worth is that the three cannot drift apart, and that the\n// repository's own convention — a style more than one component draws lives\n// beside src/components, not inside it — holds here too.\n//\n// Two things deliberately stay with each component.\n//\n// The state layers are three different shapes rather than one shape with\n// three sets of key names. Checkbox carries an `error` key Radio has no\n// equivalent for, Checkbox's pressed set inverts its own key names, and\n// Switch deliberately does not invert at all. One style keyed on a `marked`\n// boolean would have to encode an error branch one caller uses, an inversion\n// another uses, and a documented non-inversion for the third, which costs a\n// reader more than the three short `stylex.create` calls it would replace.\n//\n// And the disc's colour. Checkbox draws it in `onSurface` and Radio in\n// `onSurfaceVariant`, which is the one declaration their otherwise identical\n// discs disagree on, so `disc` holds the other fourteen and each component\n// composes its own colour after.\n// The two sizes the checkbox, radio button and switch pages each give, and\n// the decision the three of them share.\n//\n// Every one of those pages lists them as separate measurements — a 40dp state\n// layer and a 48dp target — and all three components here recorded the pair in\n// their header comments while drawing only the first. The target is what the\n// pages ask a press to reach, so it is drawn: `disc` carries a transparent\n// `::before` that reaches the 4dp either side, taking the press because a\n// pseudo-element is part of the element it belongs to. Nothing moves, since\n// that box is out of flow — the alternative, a 48dp disc, would have grown\n// every form in every consuming app by 8dp a row.\n//\n// Switch composes neither of these. Its track is its own 52 by 40, so it\n// carries the same `::before` in its own file, over the one axis that is\n// short.\n//\n// The layer is also what the label centres its first line on, and the two\n// have to agree: a disc resized without the label following it would put the\n// control off its own label again, which is the drift this row already had\n// once. The target is deliberately not in that sum — a label centred on an\n// invisible box would sit 4dp below the disc a reader can see.\n//\n// Literals rather than `sizing.controlSm` and `controlMd`, which happen to\n// hold the same two numbers. Those are steps of the control scale, spent on\n// button heights; these are one page's state layer and one page's target, and\n// a consumer resizing their buttons should not move either.\nconst LAYER_SIZE = '40px';\nconst TARGET_SIZE = '48px';\n\n/** How far the target reaches past the layer on each side: 4dp. */\nconst TARGET_REACH = `calc((${LAYER_SIZE} - ${TARGET_SIZE}) / 2)`;\nconst controlStyles = {\n controlDisabled: {\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n controlReadOnly: {\n kkrTdU: \"xt0e3qv\",\n $$css: true\n },\n disc: {\n kgeoSG: \"x1cpjm7i\",\n kFcpXp: \"x15kbrqr\",\n kEoFBp: \"x1hmns74\",\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x6s0dn4\",\n kWkggS: \"xjbqb8w\",\n kZKoxP: \"x1vqgdyp\",\n kaIpWk: \"x16fbrrb\",\n kB7OPa: \"x9f619\",\n kkrTdU: \"x1ypdohk\",\n k1xSpc: \"x78zum5\",\n kmuXW: \"x2lah0s\",\n kzqmXN: \"x100vrsf\",\n kjj79g: \"xl56j7k\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n },\n field: {\n kGNEyG: \"x7a106z\",\n kB7OPa: \"x9f619\",\n k1C7PZ: \"xpr5407\",\n k1xSpc: \"xrvj5dj\",\n kumcoG: \"x1pmbctz\",\n $$css: true\n },\n label: {\n kB7OPa: \"x9f619\",\n kMwMTN: \"x139gbkf\",\n kkrTdU: \"x1ypdohk\",\n kMv6JI: \"x16svsjw\",\n kGuDYH: \"x1848etk\",\n k63SB2: \"x1c52epr\",\n kb6lSQ: \"x1qn8t5l\",\n kLWn49: \"xh7dzej\",\n k8WAf4: \"x18r0n19\",\n $$css: true\n },\n labelDisabled: {\n kMwMTN: \"x1xj74d8\",\n kkrTdU: \"x1h6gzvc\",\n $$css: true\n },\n labelReadOnly: {\n kkrTdU: \"xt0e3qv\",\n $$css: true\n },\n messages: {\n kEXP64: \"x1xdureb\",\n $$css: true\n }\n};\nexport { controlStyles };"],"mappings":";AA+DA,MAAMU,gBAAgB;CACpBC,iBAAiB;EACfC,QAAQ;EACRC,OAAO;CACT;CACAC,iBAAiB;EACfF,QAAQ;EACRC,OAAO;CACT;CACAE,MAAM;EACJC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRZ,QAAQ;EACRa,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRnB,OAAO;CACT;CACAoB,OAAO;EACLb,QAAQ;EACRI,QAAQ;EACRU,QAAQ;EACRT,QAAQ;EACRU,QAAQ;EACRtB,OAAO;CACT;CACAuB,OAAO;EACLZ,QAAQ;EACRa,QAAQ;EACRzB,QAAQ;EACR0B,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACR9B,OAAO;CACT;CACA+B,eAAe;EACbP,QAAQ;EACRzB,QAAQ;EACRC,OAAO;CACT;CACAgC,eAAe;EACbjC,QAAQ;EACRC,OAAO;CACT;CACAiC,UAAU;EACRC,QAAQ;EACRlC,OAAO;CACT;AACF"}
|
package/dist/styles.css
CHANGED
|
@@ -3209,6 +3209,18 @@
|
|
|
3209
3209
|
}
|
|
3210
3210
|
}
|
|
3211
3211
|
|
|
3212
|
+
.x15kbrqr:before {
|
|
3213
|
+
inset: -4px;
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
.x1q69gdh:before {
|
|
3217
|
+
inset: calc((var(--x1ww3f7m) - 48px) / 2);
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
.x1n6cgzf:before {
|
|
3221
|
+
inset: calc((var(--x67cwyw) - 48px) / 2);
|
|
3222
|
+
}
|
|
3223
|
+
|
|
3212
3224
|
@media (width < 600px) {
|
|
3213
3225
|
.x1upgybz.x1upgybz {
|
|
3214
3226
|
inset-inline-start: 0;
|
|
@@ -3259,6 +3271,10 @@
|
|
|
3259
3271
|
inset-block: -14px;
|
|
3260
3272
|
}
|
|
3261
3273
|
|
|
3274
|
+
.x1fb0czk:before {
|
|
3275
|
+
inset-block: -4px;
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3262
3278
|
.xm4btww:before {
|
|
3263
3279
|
inset-inline: 0;
|
|
3264
3280
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanso-labs/kanso-ui",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"description": "A React component library built on React Aria Components primitives and styled with StyleX, with design tokens sourced from a single W3C DTCG file and compiled via Style Dictionary",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"babel-plugin-react-compiler": "1.0.0",
|
|
94
94
|
"eslint": "10.11.0",
|
|
95
95
|
"eslint-plugin-oxlint": "1.85.0",
|
|
96
|
-
"eslint-plugin-perfectionist": "5.
|
|
96
|
+
"eslint-plugin-perfectionist": "5.12.0",
|
|
97
97
|
"eslint-plugin-react-hooks": "7.1.1",
|
|
98
98
|
"eslint-plugin-react-refresh": "0.5.7",
|
|
99
99
|
"eslint-plugin-storybook": "10.6.0",
|