@kanso-labs/react-native-kanso-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/button/index.d.ts +24 -2
- package/dist/button/index.js.map +1 -1
- package/dist/button/pending.js +144 -0
- package/dist/button/pending.js.map +1 -0
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.js +154 -112
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +1 -1
- package/dist/components/icon-button/index.js +160 -110
- package/dist/components/icon-button/index.js.map +1 -1
- package/dist/components/meter/index.d.ts +73 -0
- package/dist/components/meter/index.js +179 -0
- package/dist/components/meter/index.js.map +1 -0
- package/dist/components/number-field/index.js +1 -9
- package/dist/components/number-field/index.js.map +1 -1
- package/dist/components/progress-indicator/index.d.ts +113 -0
- package/dist/components/progress-indicator/index.js +1024 -0
- package/dist/components/progress-indicator/index.js.map +1 -0
- package/dist/components/snackbar/index.d.ts +120 -0
- package/dist/components/snackbar/index.js +540 -0
- package/dist/components/snackbar/index.js.map +1 -0
- package/dist/glyphs/hidden.js +13 -0
- package/dist/glyphs/hidden.js.map +1 -0
- package/dist/glyphs/index.js +2 -8
- package/dist/glyphs/index.js.map +1 -1
- package/dist/i18n/index.js +23 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/messages.js +41 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +6 -3
- package/dist/indicator/index.d.ts +15 -0
- package/dist/indicator/index.js +256 -0
- package/dist/indicator/index.js.map +1 -0
- package/dist/indicator/motion.js +86 -0
- package/dist/indicator/motion.js.map +1 -0
- package/dist/indicator/paths.js +72 -0
- package/dist/indicator/paths.js.map +1 -0
- package/dist/indicator/styles.js +62 -0
- package/dist/indicator/styles.js.map +1 -0
- package/dist/number/locale.js +14 -0
- package/dist/number/locale.js.map +1 -0
- package/dist/overlay/host.js +65 -2
- package/dist/overlay/host.js.map +1 -1
- package/dist/press/index.js +10 -9
- package/dist/press/index.js.map +1 -1
- package/dist/theme/resolve.js +1 -1
- package/dist/theme/resolve.js.map +1 -1
- package/package.json +2 -2
package/dist/button/index.d.ts
CHANGED
|
@@ -14,11 +14,33 @@ type ButtonLinkForm = {
|
|
|
14
14
|
* with a scheme of its own, and the button is announced as a link.
|
|
15
15
|
*/
|
|
16
16
|
readonly href: string;
|
|
17
|
+
readonly isPending?: never;
|
|
17
18
|
readonly isSelected?: never;
|
|
18
19
|
readonly onChange?: never;
|
|
20
|
+
readonly pendingLabel?: never;
|
|
19
21
|
readonly type?: never;
|
|
20
22
|
};
|
|
21
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Whether the button's action is under way, which the plain button and the
|
|
25
|
+
* toggle both take and the link does not.
|
|
26
|
+
*/
|
|
27
|
+
type ButtonPending = {
|
|
28
|
+
/**
|
|
29
|
+
* Shows that the button's action is under way: a ring takes the place of
|
|
30
|
+
* the label and the icon, which keep their space, and the button keeps its
|
|
31
|
+
* focus and takes no press until it clears. A toggle may be pending, for a
|
|
32
|
+
* state saved somewhere slow.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
readonly isPending?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The name of the ring shown while the button is pending, for a screen
|
|
38
|
+
* reader. The content it replaces is hidden while it shows. Left out, it is
|
|
39
|
+
* the word for it in the device's locale, "Loading" in English.
|
|
40
|
+
*/
|
|
41
|
+
readonly pendingLabel?: string;
|
|
42
|
+
};
|
|
43
|
+
type ButtonPressForm = ButtonPending & {
|
|
22
44
|
readonly defaultSelected?: never;
|
|
23
45
|
readonly href?: never;
|
|
24
46
|
readonly isSelected?: never;
|
|
@@ -30,7 +52,7 @@ type ButtonPressForm = {
|
|
|
30
52
|
*/
|
|
31
53
|
readonly type?: 'button' | 'submit';
|
|
32
54
|
};
|
|
33
|
-
type ButtonToggleForm = {
|
|
55
|
+
type ButtonToggleForm = ButtonPending & {
|
|
34
56
|
/**
|
|
35
57
|
* Whether a toggle starts selected, when it keeps its own state. Passing
|
|
36
58
|
* this, `isSelected` or `onChange` is what makes the button a toggle.
|
package/dist/button/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["GestureResponderEvent","LayoutChangeEvent","PressableProps","SharedValue","use","useState","Platform","Pressable","StyleSheet","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","ResolvedTheme","FormContext","useOpenLink","useTheme","ButtonLinkForm","defaultSelected","href","isSelected","onChange","type","ButtonPressForm","ButtonToggleForm","ControlSize","ToggleState","HEIGHTS","lg","md","xl","xs","xxl","const","Record","OUTLINE_WIDTHS","Readonly","PRESSED_CORNERS","AnimatedPressable","createAnimatedComponent","toggleState","select","selected","default","web","buttonStyles","create","clip","bottom","left","overflow","pointerEvents","position","right","top","measureThen","height","onLayout","event","set","nativeEvent","layout","pressThen","onPress","then","useButtonAction","t0","$","_c","isToggle","openLink","form","ownSelected","setOwnSelected","t1","follow","undefined","requestSubmit","t2","t3","useCorner","radius","motion","reduceMotion","durationShort2","easingEmphasized","bezier","duration","easing","timing","corner","measured","get","target","Math","min","borderRadius","t4","_c"],"sources":["../../src/button/index.ts"],"sourcesContent":["import type {\n GestureResponderEvent,\n LayoutChangeEvent,\n PressableProps,\n} from 'react-native'\nimport type { SharedValue } from 'react-native-reanimated'\n\nimport { use, useState } from 'react'\nimport { Platform, Pressable, StyleSheet } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { FormContext } from '../form'\nimport { useOpenLink } from '../router'\nimport { useTheme } from '../theme/scope'\n\n// What every button does past its own styles, shared by Button and\n// IconButton as web's src/button is: the three forms a button takes, the\n// toggle's state and how it is announced, what a press does after the call\n// site's own `onPress`, a submit button's included, the corner that eases\n// between shapes, and the metrics\n// the two components' pages give alike, since the two share their five\n// heights so that they line up in a row.\n\n/**\n * A plain button, a link, or a toggle, of which a call site writes exactly\n * one. Each form names the props of the other two as `never`, so a toggle\n * given `href` is a compile error rather than a prop that silently does\n * nothing.\n */\ntype ButtonLinkForm = {\n readonly defaultSelected?: never\n /**\n * Where the button leads. Given one, a press opens it through the\n * `RouterProvider` around the button, or through the platform for a URL\n * with a scheme of its own, and the button is announced as a link.\n */\n readonly href: string\n readonly isSelected?: never\n readonly onChange?: never\n readonly type?: never\n}\n\ntype ButtonPressForm = {\n readonly defaultSelected?: never\n readonly href?: never\n readonly isSelected?: never\n readonly onChange?: never\n /**\n * What a press does past `onPress`. `submit` submits the `Form` the button\n * is in, as a submit button does on web; `button` does nothing more.\n * @default 'button'\n */\n readonly type?: 'button' | 'submit'\n}\n\ntype ButtonToggleForm = {\n /**\n * Whether a toggle starts selected, when it keeps its own state. Passing\n * this, `isSelected` or `onChange` is what makes the button a toggle.\n */\n readonly defaultSelected?: boolean\n readonly href?: never\n /**\n * Whether a toggle is selected, when the call site holds the state. Pass\n * it with `onChange`; passing this, `defaultSelected` or `onChange` is what\n * makes the button a toggle.\n */\n readonly isSelected?: boolean\n /**\n * Called with the new state when a toggle is pressed, after `onPress`.\n * Passing this, `isSelected` or `defaultSelected` is what makes the button\n * a toggle.\n */\n readonly onChange?: (isSelected: boolean) => void\n readonly type?: never\n}\n\n/** The five control heights both pages give, by the names both props take. */\ntype ControlSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl'\n\n/** How a toggle reports its state to a screen reader. */\ntype ToggleState = {\n readonly 'aria-pressed'?: boolean\n readonly 'aria-selected'?: boolean\n}\n\n// The control height each size reads: the page's XS, S, M, L and XL, which\n// the theme's sizing scale names one step apart from this prop.\nconst HEIGHTS = {\n lg: 'controlLg',\n md: 'controlSm',\n xl: 'controlXl',\n xs: 'controlXs',\n xxl: 'controlXxl',\n} as const satisfies Record<ControlSize, keyof ResolvedTheme['sizing']>\n\n// The outlined rule thickens with the size, as the buttons page's size tokens\n// have it: 1dp up to M, 2dp at L, 3dp at XL. The icon buttons page keeps its\n// widths in a token set its widget will not open, so the icon button takes\n// these, which a 96dp icon button beside a 96dp outlined button needs anyway.\nconst OUTLINE_WIDTHS: Readonly<Record<ControlSize, number>> = {\n lg: 1,\n md: 1,\n xl: 2,\n xs: 1,\n xxl: 3,\n}\n\n// The corner each size presses to, which both pages give alike.\nconst PRESSED_CORNERS = {\n lg: 'md',\n md: 'sm',\n xl: 'lg',\n xs: 'sm',\n xxl: 'lg',\n} as const satisfies Record<ControlSize, keyof ResolvedTheme['radii']>\n\nconst AnimatedPressable = Animated.createAnimatedComponent(Pressable)\n\n// Web's toggle reports `aria-pressed`, which React Native Web writes onto the\n// element. React Native has no pressed state to report, and reports the\n// selected one instead, which VoiceOver and TalkBack both read out.\nconst toggleState = Platform.select<(selected: boolean) => ToggleState>({\n default: (selected) => ({ 'aria-selected': selected }),\n web: (selected) => ({ 'aria-pressed': selected }),\n})\n\nconst buttonStyles = StyleSheet.create({\n // Clips the state layer and the ripple to the corner as it morphs, and\n // takes no touches.\n clip: {\n bottom: 0,\n left: 0,\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n right: 0,\n top: 0,\n },\n})\n\n// Records the button's height for the corner, then calls the call site's own\n// `onLayout`. Built by a call rather than declared in a component, which is\n// what react-perf's jsx-no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction measureThen(\n height: SharedValue<number>,\n onLayout: PressableProps['onLayout'],\n) {\n return (event: LayoutChangeEvent) => {\n height.set(event.nativeEvent.layout.height)\n onLayout?.(event)\n }\n}\n\n// The call site's own `onPress`, then what the button does with the press.\n// Built by a call for the reason `measureThen` is.\nfunction pressThen(onPress: PressableProps['onPress'], then: () => void) {\n return (event: GestureResponderEvent) => {\n onPress?.(event)\n then()\n }\n}\n\n/**\n * What a press does, and whether a toggle is selected. A press calls the call\n * site's own `onPress` first, then opens the link, changes the toggle's state\n * or submits the form the button is in, which is the order web reports them\n * in. A toggle keeps its own state from `defaultSelected` unless the call\n * site holds it in `isSelected`. A submit button outside a form submits\n * nothing, as on web.\n */\nfunction useButtonAction({\n defaultSelected,\n href,\n isSelected,\n isToggle,\n onChange,\n onPress,\n type,\n}: {\n readonly defaultSelected: boolean | undefined\n readonly href: string | undefined\n readonly isSelected: boolean | undefined\n readonly isToggle: boolean\n readonly onChange: ((isSelected: boolean) => void) | undefined\n readonly onPress: PressableProps['onPress']\n readonly type: 'button' | 'submit' | undefined\n}) {\n const openLink = useOpenLink()\n const form = use(FormContext)\n const [ownSelected, setOwnSelected] = useState(defaultSelected ?? false)\n const selected = isToggle && (isSelected ?? ownSelected)\n\n function follow() {\n if (href !== undefined) {\n openLink(href)\n } else if (isToggle) {\n setOwnSelected(!selected)\n onChange?.(!selected)\n } else if (type === 'submit') {\n form?.requestSubmit()\n }\n }\n\n return { onPress: pressThen(onPress, follow), selected }\n}\n\n/**\n * The corner a button eases to, over the motion tokens' short duration on the\n * emphasised curve, and at once for a reader who asks the device for reduced\n * motion. The pill is the radius scale's `pill`, far larger than any button,\n * so the ease runs from half the button's measured height rather than from\n * that: otherwise the corner would hold the pill for most of the ease and\n * jump at its end. The `onLayout` it hands back measures the button, then\n * calls the call site's own.\n */\nfunction useCorner(radius: number, onLayout: PressableProps['onLayout']) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const height = useSharedValue(0)\n const timing = {\n duration: motion.durationShort2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }\n const corner = useAnimatedStyle(() => {\n 'worklet'\n const measured = height.get()\n const target = measured > 0 ? Math.min(radius, measured / 2) : radius\n\n return {\n borderRadius: reduceMotion ? target : withTiming(target, timing),\n }\n })\n\n return { corner, onLayout: measureThen(height, onLayout) }\n}\n\nexport {\n AnimatedPressable,\n buttonStyles,\n HEIGHTS,\n OUTLINE_WIDTHS,\n PRESSED_CORNERS,\n toggleState,\n useButtonAction,\n useCorner,\n}\nexport type { ButtonLinkForm, ButtonPressForm, ButtonToggleForm, ControlSize }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["GestureResponderEvent","LayoutChangeEvent","PressableProps","SharedValue","use","useState","Platform","Pressable","StyleSheet","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","ResolvedTheme","FormContext","useOpenLink","useTheme","ButtonLinkForm","defaultSelected","href","isPending","isSelected","onChange","pendingLabel","type","ButtonPending","ButtonPressForm","ButtonToggleForm","ControlSize","ToggleState","HEIGHTS","lg","md","xl","xs","xxl","const","Record","OUTLINE_WIDTHS","Readonly","PRESSED_CORNERS","AnimatedPressable","createAnimatedComponent","toggleState","select","selected","default","web","buttonStyles","create","clip","bottom","left","overflow","pointerEvents","position","right","top","measureThen","height","onLayout","event","set","nativeEvent","layout","pressThen","onPress","then","useButtonAction","t0","$","_c","isToggle","openLink","form","ownSelected","setOwnSelected","t1","follow","undefined","requestSubmit","t2","t3","useCorner","radius","motion","reduceMotion","durationShort2","easingEmphasized","bezier","duration","easing","timing","corner","measured","get","target","Math","min","borderRadius","t4","_c"],"sources":["../../src/button/index.ts"],"sourcesContent":["import type {\n GestureResponderEvent,\n LayoutChangeEvent,\n PressableProps,\n} from 'react-native'\nimport type { SharedValue } from 'react-native-reanimated'\n\nimport { use, useState } from 'react'\nimport { Platform, Pressable, StyleSheet } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { FormContext } from '../form'\nimport { useOpenLink } from '../router'\nimport { useTheme } from '../theme/scope'\n\n// What every button does past its own styles, shared by Button and\n// IconButton as web's src/button is: the three forms a button takes, the\n// toggle's state and how it is announced, what a press does after the call\n// site's own `onPress`, a submit button's included, the corner that eases\n// between shapes, and the metrics\n// the two components' pages give alike, since the two share their five\n// heights so that they line up in a row. What a pending button draws and\n// says is ./pending.tsx.\n\n/**\n * A plain button, a link, or a toggle, of which a call site writes exactly\n * one. Each form names the props of the other two as `never`, so a toggle\n * given `href` is a compile error rather than a prop that silently does\n * nothing.\n */\ntype ButtonLinkForm = {\n readonly defaultSelected?: never\n /**\n * Where the button leads. Given one, a press opens it through the\n * `RouterProvider` around the button, or through the platform for a URL\n * with a scheme of its own, and the button is announced as a link.\n */\n readonly href: string\n readonly isPending?: never\n readonly isSelected?: never\n readonly onChange?: never\n readonly pendingLabel?: never\n readonly type?: never\n}\n\n/**\n * Whether the button's action is under way, which the plain button and the\n * toggle both take and the link does not.\n */\ntype ButtonPending = {\n /**\n * Shows that the button's action is under way: a ring takes the place of\n * the label and the icon, which keep their space, and the button keeps its\n * focus and takes no press until it clears. A toggle may be pending, for a\n * state saved somewhere slow.\n * @default false\n */\n readonly isPending?: boolean\n /**\n * The name of the ring shown while the button is pending, for a screen\n * reader. The content it replaces is hidden while it shows. Left out, it is\n * the word for it in the device's locale, \"Loading\" in English.\n */\n readonly pendingLabel?: string\n}\n\ntype ButtonPressForm = ButtonPending & {\n readonly defaultSelected?: never\n readonly href?: never\n readonly isSelected?: never\n readonly onChange?: never\n /**\n * What a press does past `onPress`. `submit` submits the `Form` the button\n * is in, as a submit button does on web; `button` does nothing more.\n * @default 'button'\n */\n readonly type?: 'button' | 'submit'\n}\n\ntype ButtonToggleForm = ButtonPending & {\n /**\n * Whether a toggle starts selected, when it keeps its own state. Passing\n * this, `isSelected` or `onChange` is what makes the button a toggle.\n */\n readonly defaultSelected?: boolean\n readonly href?: never\n /**\n * Whether a toggle is selected, when the call site holds the state. Pass\n * it with `onChange`; passing this, `defaultSelected` or `onChange` is what\n * makes the button a toggle.\n */\n readonly isSelected?: boolean\n /**\n * Called with the new state when a toggle is pressed, after `onPress`.\n * Passing this, `isSelected` or `defaultSelected` is what makes the button\n * a toggle.\n */\n readonly onChange?: (isSelected: boolean) => void\n readonly type?: never\n}\n\n/** The five control heights both pages give, by the names both props take. */\ntype ControlSize = 'lg' | 'md' | 'xl' | 'xs' | 'xxl'\n\n/** How a toggle reports its state to a screen reader. */\ntype ToggleState = {\n readonly 'aria-pressed'?: boolean\n readonly 'aria-selected'?: boolean\n}\n\n// The control height each size reads: the page's XS, S, M, L and XL, which\n// the theme's sizing scale names one step apart from this prop.\nconst HEIGHTS = {\n lg: 'controlLg',\n md: 'controlSm',\n xl: 'controlXl',\n xs: 'controlXs',\n xxl: 'controlXxl',\n} as const satisfies Record<ControlSize, keyof ResolvedTheme['sizing']>\n\n// The outlined rule thickens with the size, as the buttons page's size tokens\n// have it: 1dp up to M, 2dp at L, 3dp at XL. The icon buttons page keeps its\n// widths in a token set its widget will not open, so the icon button takes\n// these, which a 96dp icon button beside a 96dp outlined button needs anyway.\nconst OUTLINE_WIDTHS: Readonly<Record<ControlSize, number>> = {\n lg: 1,\n md: 1,\n xl: 2,\n xs: 1,\n xxl: 3,\n}\n\n// The corner each size presses to, which both pages give alike.\nconst PRESSED_CORNERS = {\n lg: 'md',\n md: 'sm',\n xl: 'lg',\n xs: 'sm',\n xxl: 'lg',\n} as const satisfies Record<ControlSize, keyof ResolvedTheme['radii']>\n\nconst AnimatedPressable = Animated.createAnimatedComponent(Pressable)\n\n// Web's toggle reports `aria-pressed`, which React Native Web writes onto the\n// element. React Native has no pressed state to report, and reports the\n// selected one instead, which VoiceOver and TalkBack both read out.\nconst toggleState = Platform.select<(selected: boolean) => ToggleState>({\n default: (selected) => ({ 'aria-selected': selected }),\n web: (selected) => ({ 'aria-pressed': selected }),\n})\n\nconst buttonStyles = StyleSheet.create({\n // Clips the state layer and the ripple to the corner as it morphs, and\n // takes no touches.\n clip: {\n bottom: 0,\n left: 0,\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n right: 0,\n top: 0,\n },\n})\n\n// Records the button's height for the corner, then calls the call site's own\n// `onLayout`. Built by a call rather than declared in a component, which is\n// what react-perf's jsx-no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction measureThen(\n height: SharedValue<number>,\n onLayout: PressableProps['onLayout'],\n) {\n return (event: LayoutChangeEvent) => {\n height.set(event.nativeEvent.layout.height)\n onLayout?.(event)\n }\n}\n\n// The call site's own `onPress`, then what the button does with the press.\n// Built by a call for the reason `measureThen` is.\nfunction pressThen(onPress: PressableProps['onPress'], then: () => void) {\n return (event: GestureResponderEvent) => {\n onPress?.(event)\n then()\n }\n}\n\n/**\n * What a press does, and whether a toggle is selected. A press calls the call\n * site's own `onPress` first, then opens the link, changes the toggle's state\n * or submits the form the button is in, which is the order web reports them\n * in. A toggle keeps its own state from `defaultSelected` unless the call\n * site holds it in `isSelected`. A submit button outside a form submits\n * nothing, as on web.\n */\nfunction useButtonAction({\n defaultSelected,\n href,\n isSelected,\n isToggle,\n onChange,\n onPress,\n type,\n}: {\n readonly defaultSelected: boolean | undefined\n readonly href: string | undefined\n readonly isSelected: boolean | undefined\n readonly isToggle: boolean\n readonly onChange: ((isSelected: boolean) => void) | undefined\n readonly onPress: PressableProps['onPress']\n readonly type: 'button' | 'submit' | undefined\n}) {\n const openLink = useOpenLink()\n const form = use(FormContext)\n const [ownSelected, setOwnSelected] = useState(defaultSelected ?? false)\n const selected = isToggle && (isSelected ?? ownSelected)\n\n function follow() {\n if (href !== undefined) {\n openLink(href)\n } else if (isToggle) {\n setOwnSelected(!selected)\n onChange?.(!selected)\n } else if (type === 'submit') {\n form?.requestSubmit()\n }\n }\n\n return { onPress: pressThen(onPress, follow), selected }\n}\n\n/**\n * The corner a button eases to, over the motion tokens' short duration on the\n * emphasised curve, and at once for a reader who asks the device for reduced\n * motion. The pill is the radius scale's `pill`, far larger than any button,\n * so the ease runs from half the button's measured height rather than from\n * that: otherwise the corner would hold the pill for most of the ease and\n * jump at its end. The `onLayout` it hands back measures the button, then\n * calls the call site's own.\n */\nfunction useCorner(radius: number, onLayout: PressableProps['onLayout']) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const height = useSharedValue(0)\n const timing = {\n duration: motion.durationShort2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }\n const corner = useAnimatedStyle(() => {\n 'worklet'\n const measured = height.get()\n const target = measured > 0 ? Math.min(radius, measured / 2) : radius\n\n return {\n borderRadius: reduceMotion ? target : withTiming(target, timing),\n }\n })\n\n return { corner, onLayout: measureThen(height, onLayout) }\n}\n\nexport {\n AnimatedPressable,\n buttonStyles,\n HEIGHTS,\n OUTLINE_WIDTHS,\n PRESSED_CORNERS,\n toggleState,\n useButtonAction,\n useCorner,\n}\nexport type { ButtonLinkForm, ButtonPressForm, ButtonToggleForm, ControlSize }\n"],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { IconStyleContext } from "../glyphs/icon-style.js";
|
|
2
|
+
import { ProgressIndicator } from "../components/progress-indicator/index.js";
|
|
3
|
+
import { messagesFor } from "../i18n/index.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import { AccessibilityInfo, Platform, StyleSheet, View } from "react-native";
|
|
6
|
+
import { useEffect, useRef } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
//#region src/button/pending.tsx
|
|
9
|
+
const pendingStyles = StyleSheet.create({
|
|
10
|
+
hidden: { opacity: 0 },
|
|
11
|
+
ring: {
|
|
12
|
+
alignItems: "center",
|
|
13
|
+
bottom: 0,
|
|
14
|
+
justifyContent: "center",
|
|
15
|
+
left: 0,
|
|
16
|
+
pointerEvents: "none",
|
|
17
|
+
position: "absolute",
|
|
18
|
+
right: 0,
|
|
19
|
+
top: 0
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const BUSY = { "aria-busy": true };
|
|
23
|
+
const CONCEALED = { "aria-hidden": true };
|
|
24
|
+
/**
|
|
25
|
+
* The icon a button draws, in a view that hides it in place while the button
|
|
26
|
+
* is pending. The view is there whether or not the button is, so an icon
|
|
27
|
+
* keeps its state when the button goes pending and comes back.
|
|
28
|
+
*/
|
|
29
|
+
function PendingContent(t0) {
|
|
30
|
+
const $ = c(4);
|
|
31
|
+
const { children, isPending } = t0;
|
|
32
|
+
const t1 = isPending ? CONCEALED : void 0;
|
|
33
|
+
const t2 = isPending ? pendingStyles.hidden : void 0;
|
|
34
|
+
let t3;
|
|
35
|
+
if ($[0] !== children || $[1] !== t1 || $[2] !== t2) {
|
|
36
|
+
t3 = /* @__PURE__ */ jsx(View, {
|
|
37
|
+
...t1,
|
|
38
|
+
style: t2,
|
|
39
|
+
children
|
|
40
|
+
});
|
|
41
|
+
$[0] = children;
|
|
42
|
+
$[1] = t1;
|
|
43
|
+
$[2] = t2;
|
|
44
|
+
$[3] = t3;
|
|
45
|
+
} else t3 = $[3];
|
|
46
|
+
return t3;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The indeterminate ring a pending button draws over its content, in the
|
|
50
|
+
* button's content colour rather than the progress page's primary, which on a
|
|
51
|
+
* filled button is the fill itself. `diameter` is what the content it
|
|
52
|
+
* replaces measures, the label's type size on Button and the icon on
|
|
53
|
+
* IconButton, which is what web's `1em` reads in each.
|
|
54
|
+
*/
|
|
55
|
+
function PendingRing(t0) {
|
|
56
|
+
const $ = c(9);
|
|
57
|
+
const { color, diameter, label } = t0;
|
|
58
|
+
let t1;
|
|
59
|
+
if ($[0] !== color || $[1] !== diameter) {
|
|
60
|
+
t1 = slotOf(color, diameter);
|
|
61
|
+
$[0] = color;
|
|
62
|
+
$[1] = diameter;
|
|
63
|
+
$[2] = t1;
|
|
64
|
+
} else t1 = $[2];
|
|
65
|
+
const t2 = `${diameter}px`;
|
|
66
|
+
let t3;
|
|
67
|
+
if ($[3] !== label || $[4] !== t2) {
|
|
68
|
+
t3 = /* @__PURE__ */ jsx(ProgressIndicator, {
|
|
69
|
+
"aria-label": label,
|
|
70
|
+
diameter: t2,
|
|
71
|
+
isIndeterminate: true,
|
|
72
|
+
tone: "inherit",
|
|
73
|
+
variant: "circular"
|
|
74
|
+
});
|
|
75
|
+
$[3] = label;
|
|
76
|
+
$[4] = t2;
|
|
77
|
+
$[5] = t3;
|
|
78
|
+
} else t3 = $[5];
|
|
79
|
+
let t4;
|
|
80
|
+
if ($[6] !== t1 || $[7] !== t3) {
|
|
81
|
+
t4 = /* @__PURE__ */ jsx(View, {
|
|
82
|
+
style: pendingStyles.ring,
|
|
83
|
+
children: /* @__PURE__ */ jsx(IconStyleContext, {
|
|
84
|
+
value: t1,
|
|
85
|
+
children: t3
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
$[6] = t1;
|
|
89
|
+
$[7] = t3;
|
|
90
|
+
$[8] = t4;
|
|
91
|
+
} else t4 = $[8];
|
|
92
|
+
return t4;
|
|
93
|
+
}
|
|
94
|
+
function slotOf(color, size) {
|
|
95
|
+
return {
|
|
96
|
+
color,
|
|
97
|
+
size
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The ring's name, and the announcement a button makes as it goes pending.
|
|
102
|
+
* The name is `pendingLabel`, or the word for loading in the device's locale.
|
|
103
|
+
*
|
|
104
|
+
* On iOS and Android the change is said through VoiceOver and TalkBack, as
|
|
105
|
+
* web's is said through React Aria's live announcer, since a ring appearing
|
|
106
|
+
* under them is not reliably read. Web says it only to a reader whose focus
|
|
107
|
+
* is on the button; a screen reader's focus is not something a component
|
|
108
|
+
* here can read, so it is said whatever has focus. A button pending as it
|
|
109
|
+
* mounts says nothing, as on web, which announces a change. React Native Web
|
|
110
|
+
* has no announcer, so there the ring is read when the button next is.
|
|
111
|
+
*/
|
|
112
|
+
function usePending(isPending, pendingLabel) {
|
|
113
|
+
const $ = c(6);
|
|
114
|
+
let t0;
|
|
115
|
+
if ($[0] !== pendingLabel) {
|
|
116
|
+
t0 = pendingLabel ?? messagesFor().loading;
|
|
117
|
+
$[0] = pendingLabel;
|
|
118
|
+
$[1] = t0;
|
|
119
|
+
} else t0 = $[1];
|
|
120
|
+
const label = t0;
|
|
121
|
+
const was = useRef(isPending);
|
|
122
|
+
let t1;
|
|
123
|
+
let t2;
|
|
124
|
+
if ($[2] !== isPending || $[3] !== label) {
|
|
125
|
+
t1 = () => {
|
|
126
|
+
if (isPending && !was.current && (Platform.OS === "ios" || Platform.OS === "android")) AccessibilityInfo.announceForAccessibility(label);
|
|
127
|
+
was.current = isPending;
|
|
128
|
+
};
|
|
129
|
+
t2 = [isPending, label];
|
|
130
|
+
$[2] = isPending;
|
|
131
|
+
$[3] = label;
|
|
132
|
+
$[4] = t1;
|
|
133
|
+
$[5] = t2;
|
|
134
|
+
} else {
|
|
135
|
+
t1 = $[4];
|
|
136
|
+
t2 = $[5];
|
|
137
|
+
}
|
|
138
|
+
useEffect(t1, t2);
|
|
139
|
+
return label;
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
export { BUSY, CONCEALED, PendingContent, PendingRing, pendingStyles, usePending };
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=pending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending.js","names":["ReactNode","ColorValue","useEffect","useRef","AccessibilityInfo","Platform","StyleSheet","View","IconStyle","ProgressIndicator","IconStyleContext","messagesFor","pendingStyles","create","hidden","opacity","ring","alignItems","bottom","justifyContent","left","pointerEvents","position","right","top","BUSY","const","CONCEALED","PendingContent","t0","$","_c","children","isPending","t1","undefined","t2","t3","PendingRing","color","diameter","label","slotOf","t4","size","usePending","pendingLabel","loading","was","current","OS","announceForAccessibility","_c"],"sources":["../../src/button/pending.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type { ColorValue } from 'react-native'\n\nimport { useEffect, useRef } from 'react'\nimport { AccessibilityInfo, Platform, StyleSheet, View } from 'react-native'\n\nimport type { IconStyle } from '../glyphs/icon-style'\n\nimport { ProgressIndicator } from '../components/progress-indicator'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { messagesFor } from '../i18n'\n\n// What a pending button draws and says, shared by Button and IconButton as\n// web's ButtonBase draws it for both: the content hidden in place, the ring\n// over it, and the announcement that the button has gone pending.\n\nconst pendingStyles = StyleSheet.create({\n // The label and the icon while the ring shows: still laid out, so the\n // button keeps its width, which is what stops a form jumping the moment it\n // is submitted, and not drawn.\n hidden: {\n opacity: 0,\n },\n // The ring sits over the hidden content, centred in the button, and takes\n // no touches.\n ring: {\n alignItems: 'center',\n bottom: 0,\n justifyContent: 'center',\n left: 0,\n pointerEvents: 'none',\n position: 'absolute',\n right: 0,\n top: 0,\n },\n})\n\n// What a pending button reports to a screen reader, spread before the call\n// site's own props, so an `aria-busy` of its own still wins, as on web.\nconst BUSY = { 'aria-busy': true } as const\n\n// What takes the hidden content out of what a screen reader reads, so the\n// button is named by the ring while it shows.\nconst CONCEALED = { 'aria-hidden': true } as const\n\n/**\n * The icon a button draws, in a view that hides it in place while the button\n * is pending. The view is there whether or not the button is, so an icon\n * keeps its state when the button goes pending and comes back.\n */\nfunction PendingContent({\n children,\n isPending,\n}: {\n readonly children: ReactNode\n readonly isPending: boolean\n}) {\n return (\n <View\n {...(isPending ? CONCEALED : undefined)}\n style={isPending ? pendingStyles.hidden : undefined}\n >\n {children}\n </View>\n )\n}\n\n/**\n * The indeterminate ring a pending button draws over its content, in the\n * button's content colour rather than the progress page's primary, which on a\n * filled button is the fill itself. `diameter` is what the content it\n * replaces measures, the label's type size on Button and the icon on\n * IconButton, which is what web's `1em` reads in each.\n */\nfunction PendingRing({\n color,\n diameter,\n label,\n}: {\n readonly color: ColorValue\n readonly diameter: number\n readonly label: string\n}) {\n return (\n <View style={pendingStyles.ring}>\n <IconStyleContext value={slotOf(color, diameter)}>\n <ProgressIndicator\n aria-label={label}\n diameter={`${diameter}px`}\n isIndeterminate\n tone=\"inherit\"\n variant=\"circular\"\n />\n </IconStyleContext>\n </View>\n )\n}\n\nfunction slotOf(color: ColorValue, size: number): IconStyle {\n return { color, size }\n}\n\n/**\n * The ring's name, and the announcement a button makes as it goes pending.\n * The name is `pendingLabel`, or the word for loading in the device's locale.\n *\n * On iOS and Android the change is said through VoiceOver and TalkBack, as\n * web's is said through React Aria's live announcer, since a ring appearing\n * under them is not reliably read. Web says it only to a reader whose focus\n * is on the button; a screen reader's focus is not something a component\n * here can read, so it is said whatever has focus. A button pending as it\n * mounts says nothing, as on web, which announces a change. React Native Web\n * has no announcer, so there the ring is read when the button next is.\n */\nfunction usePending(isPending: boolean, pendingLabel: string | undefined) {\n const label = pendingLabel ?? messagesFor().loading\n const was = useRef(isPending)\n\n useEffect(() => {\n if (\n isPending &&\n !was.current &&\n (Platform.OS === 'ios' || Platform.OS === 'android')\n ) {\n AccessibilityInfo.announceForAccessibility(label)\n }\n was.current = isPending\n }, [isPending, label])\n\n return label\n}\n\nexport {\n BUSY,\n CONCEALED,\n PendingContent,\n PendingRing,\n pendingStyles,\n usePending,\n}\n"],"mappings":"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"}
|
|
@@ -81,7 +81,7 @@ type ButtonVariant = 'elevated' | 'filled' | 'outlined' | 'text' | 'tonal';
|
|
|
81
81
|
* target through `hitSlop`, which a `hitSlop` of the call site's own replaces.
|
|
82
82
|
* `style`, `ref` and `testID` land on the `Pressable`.
|
|
83
83
|
*/
|
|
84
|
-
declare function Button({ children, defaultSelected, disableRipple, hitSlop: ownHitSlop, href, icon, isDisabled, isSelected, onBlur, onChange, onFocus, onHoverIn, onHoverOut, onLayout, onPress, onPressIn, onPressOut, shape, size, style, type, variant, ...props }: ButtonProps): import("react").JSX.Element;
|
|
84
|
+
declare function Button({ children, defaultSelected, disableRipple, hitSlop: ownHitSlop, href, icon, isDisabled, isPending, isSelected, onBlur, onChange, onFocus, onHoverIn, onHoverOut, onLayout, onLongPress, onPress, onPressIn, onPressOut, pendingLabel, shape, size, style, type, variant, ...props }: ButtonProps): import("react").JSX.Element;
|
|
85
85
|
//#endregion
|
|
86
86
|
export { Button, type ButtonProps, type ButtonShape, type ButtonSize, type ButtonVariant };
|
|
87
87
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -4,9 +4,10 @@ import { composeStyles, themedStyles } from "../../theme/styles.js";
|
|
|
4
4
|
import { useTypeRole } from "../../typography/roles.js";
|
|
5
5
|
import { AnimatedPressable, HEIGHTS, OUTLINE_WIDTHS, PRESSED_CORNERS, buttonStyles, toggleState, useButtonAction, useCorner } from "../../button/index.js";
|
|
6
6
|
import { palettesOf } from "../../button/palettes.js";
|
|
7
|
+
import { BUSY, CONCEALED, PendingContent, PendingRing, pendingStyles, usePending } from "../../button/pending.js";
|
|
7
8
|
import { hitSlop, usePressFeedback } from "../../press/index.js";
|
|
8
9
|
import { c } from "react/compiler-runtime";
|
|
9
|
-
import { StyleSheet, Text } from "react-native";
|
|
10
|
+
import { StyleSheet, Text, useWindowDimensions } from "react-native";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import Animated from "react-native-reanimated";
|
|
12
13
|
//#region src/components/button/index.tsx
|
|
@@ -160,7 +161,7 @@ const outlinedSizesOf = themedStyles((theme) => {
|
|
|
160
161
|
* `style`, `ref` and `testID` land on the `Pressable`.
|
|
161
162
|
*/
|
|
162
163
|
function Button(t0) {
|
|
163
|
-
const $ = c(
|
|
164
|
+
const $ = c(71);
|
|
164
165
|
let children;
|
|
165
166
|
let defaultSelected;
|
|
166
167
|
let href;
|
|
@@ -172,10 +173,12 @@ function Button(t0) {
|
|
|
172
173
|
let onHoverIn;
|
|
173
174
|
let onHoverOut;
|
|
174
175
|
let onLayout;
|
|
176
|
+
let onLongPress;
|
|
175
177
|
let onPress;
|
|
176
178
|
let onPressIn;
|
|
177
179
|
let onPressOut;
|
|
178
180
|
let ownHitSlop;
|
|
181
|
+
let pendingLabel;
|
|
179
182
|
let props;
|
|
180
183
|
let style;
|
|
181
184
|
let t1;
|
|
@@ -183,9 +186,10 @@ function Button(t0) {
|
|
|
183
186
|
let t3;
|
|
184
187
|
let t4;
|
|
185
188
|
let t5;
|
|
189
|
+
let t6;
|
|
186
190
|
let type;
|
|
187
191
|
if ($[0] !== t0) {
|
|
188
|
-
({children, defaultSelected, disableRipple: t1, hitSlop: ownHitSlop, href, icon, isDisabled: t2, isSelected, onBlur, onChange, onFocus, onHoverIn, onHoverOut, onLayout, onPress, onPressIn, onPressOut, shape:
|
|
192
|
+
({children, defaultSelected, disableRipple: t1, hitSlop: ownHitSlop, href, icon, isDisabled: t2, isPending: t3, isSelected, onBlur, onChange, onFocus, onHoverIn, onHoverOut, onLayout, onLongPress, onPress, onPressIn, onPressOut, pendingLabel, shape: t4, size: t5, style, type, variant: t6, ...props} = t0);
|
|
189
193
|
$[0] = t0;
|
|
190
194
|
$[1] = children;
|
|
191
195
|
$[2] = defaultSelected;
|
|
@@ -198,18 +202,21 @@ function Button(t0) {
|
|
|
198
202
|
$[9] = onHoverIn;
|
|
199
203
|
$[10] = onHoverOut;
|
|
200
204
|
$[11] = onLayout;
|
|
201
|
-
$[12] =
|
|
202
|
-
$[13] =
|
|
203
|
-
$[14] =
|
|
204
|
-
$[15] =
|
|
205
|
-
$[16] =
|
|
206
|
-
$[17] =
|
|
207
|
-
$[18] =
|
|
208
|
-
$[19] =
|
|
209
|
-
$[20] =
|
|
210
|
-
$[21] =
|
|
211
|
-
$[22] =
|
|
212
|
-
$[23] =
|
|
205
|
+
$[12] = onLongPress;
|
|
206
|
+
$[13] = onPress;
|
|
207
|
+
$[14] = onPressIn;
|
|
208
|
+
$[15] = onPressOut;
|
|
209
|
+
$[16] = ownHitSlop;
|
|
210
|
+
$[17] = pendingLabel;
|
|
211
|
+
$[18] = props;
|
|
212
|
+
$[19] = style;
|
|
213
|
+
$[20] = t1;
|
|
214
|
+
$[21] = t2;
|
|
215
|
+
$[22] = t3;
|
|
216
|
+
$[23] = t4;
|
|
217
|
+
$[24] = t5;
|
|
218
|
+
$[25] = t6;
|
|
219
|
+
$[26] = type;
|
|
213
220
|
} else {
|
|
214
221
|
children = $[1];
|
|
215
222
|
defaultSelected = $[2];
|
|
@@ -222,30 +229,37 @@ function Button(t0) {
|
|
|
222
229
|
onHoverIn = $[9];
|
|
223
230
|
onHoverOut = $[10];
|
|
224
231
|
onLayout = $[11];
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
232
|
+
onLongPress = $[12];
|
|
233
|
+
onPress = $[13];
|
|
234
|
+
onPressIn = $[14];
|
|
235
|
+
onPressOut = $[15];
|
|
236
|
+
ownHitSlop = $[16];
|
|
237
|
+
pendingLabel = $[17];
|
|
238
|
+
props = $[18];
|
|
239
|
+
style = $[19];
|
|
240
|
+
t1 = $[20];
|
|
241
|
+
t2 = $[21];
|
|
242
|
+
t3 = $[22];
|
|
243
|
+
t4 = $[23];
|
|
244
|
+
t5 = $[24];
|
|
245
|
+
t6 = $[25];
|
|
246
|
+
type = $[26];
|
|
237
247
|
}
|
|
238
248
|
const disableRipple = t1 === void 0 ? false : t1;
|
|
239
249
|
const isDisabled = t2 === void 0 ? false : t2;
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
const
|
|
250
|
+
const isPending = t3 === void 0 ? false : t3;
|
|
251
|
+
const shape = t4 === void 0 ? "round" : t4;
|
|
252
|
+
const size = t5 === void 0 ? "md" : t5;
|
|
253
|
+
const variant = t6 === void 0 ? "filled" : t6;
|
|
243
254
|
const theme = useTheme();
|
|
244
255
|
const role = useTypeRole(ROLES[size]);
|
|
256
|
+
const { fontScale } = useWindowDimensions();
|
|
257
|
+
const pending = href === void 0 && isPending;
|
|
258
|
+
const ringLabel = usePending(pending, pendingLabel);
|
|
245
259
|
const isToggle = variant !== "text" && (defaultSelected !== void 0 || isSelected !== void 0 || onChange !== void 0);
|
|
246
|
-
let
|
|
247
|
-
if ($[
|
|
248
|
-
|
|
260
|
+
let t7;
|
|
261
|
+
if ($[27] !== defaultSelected || $[28] !== href || $[29] !== isSelected || $[30] !== isToggle || $[31] !== onChange || $[32] !== onPress || $[33] !== type) {
|
|
262
|
+
t7 = {
|
|
249
263
|
defaultSelected,
|
|
250
264
|
href,
|
|
251
265
|
isSelected,
|
|
@@ -254,16 +268,16 @@ function Button(t0) {
|
|
|
254
268
|
onPress,
|
|
255
269
|
type
|
|
256
270
|
};
|
|
257
|
-
$[
|
|
258
|
-
$[
|
|
259
|
-
$[
|
|
260
|
-
$[
|
|
261
|
-
$[
|
|
262
|
-
$[
|
|
263
|
-
$[
|
|
264
|
-
$[
|
|
265
|
-
} else
|
|
266
|
-
const action = useButtonAction(
|
|
271
|
+
$[27] = defaultSelected;
|
|
272
|
+
$[28] = href;
|
|
273
|
+
$[29] = isSelected;
|
|
274
|
+
$[30] = isToggle;
|
|
275
|
+
$[31] = onChange;
|
|
276
|
+
$[32] = onPress;
|
|
277
|
+
$[33] = type;
|
|
278
|
+
$[34] = t7;
|
|
279
|
+
} else t7 = $[34];
|
|
280
|
+
const action = useButtonAction(t7);
|
|
267
281
|
const colors = palettesOf(theme)[isDisabled ? DISABLED[variant] : variant !== "text" && isToggle ? TOGGLE_PALETTES[variant][action.selected ? "selected" : "unselected"] : variant];
|
|
268
282
|
const feedback = usePressFeedback({
|
|
269
283
|
color: colors.content,
|
|
@@ -274,90 +288,118 @@ function Button(t0) {
|
|
|
274
288
|
onHoverIn,
|
|
275
289
|
onHoverOut,
|
|
276
290
|
onPressIn,
|
|
277
|
-
onPressOut
|
|
291
|
+
onPressOut,
|
|
292
|
+
pending
|
|
278
293
|
});
|
|
279
294
|
const { radii } = theme;
|
|
280
295
|
const resting = shape === "square" !== action.selected ? radii[SQUARE_CORNERS[size]] : radii.pill;
|
|
281
296
|
const shaped = useCorner(feedback.pressed ? radii[PRESSED_CORNERS[size]] : resting, onLayout);
|
|
282
297
|
const T0 = AnimatedPressable;
|
|
283
|
-
const
|
|
284
|
-
let
|
|
285
|
-
if ($[
|
|
286
|
-
|
|
287
|
-
$[
|
|
288
|
-
$[
|
|
289
|
-
$[
|
|
290
|
-
} else
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
$[
|
|
297
|
-
$[
|
|
298
|
-
$[
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
298
|
+
const t8 = href === void 0 ? "button" : "link";
|
|
299
|
+
let t9;
|
|
300
|
+
if ($[35] !== action.selected || $[36] !== isToggle) {
|
|
301
|
+
t9 = isToggle ? toggleState(action.selected) : void 0;
|
|
302
|
+
$[35] = action.selected;
|
|
303
|
+
$[36] = isToggle;
|
|
304
|
+
$[37] = t9;
|
|
305
|
+
} else t9 = $[37];
|
|
306
|
+
const t10 = pending ? BUSY : void 0;
|
|
307
|
+
const t11 = feedback.handlers;
|
|
308
|
+
let t12;
|
|
309
|
+
if ($[38] !== ownHitSlop || $[39] !== size || $[40] !== theme.sizing) {
|
|
310
|
+
t12 = ownHitSlop ?? hitSlop(theme.sizing[HEIGHTS[size]]);
|
|
311
|
+
$[38] = ownHitSlop;
|
|
312
|
+
$[39] = size;
|
|
313
|
+
$[40] = theme.sizing;
|
|
314
|
+
$[41] = t12;
|
|
315
|
+
} else t12 = $[41];
|
|
316
|
+
const t13 = shaped.onLayout;
|
|
317
|
+
const t14 = pending ? void 0 : onLongPress;
|
|
318
|
+
const t15 = pending ? void 0 : action.onPress;
|
|
319
|
+
const t16 = composeStyles(styles.base, sizesOf(theme)[size], variant === "outlined" ? outlinedSizesOf(theme)[size] : void 0, colors.container, shadowOf(variant, feedback, isDisabled, theme), shaped.corner, feedback.ring, style);
|
|
320
|
+
let t17;
|
|
321
|
+
if ($[42] !== shaped.corner) {
|
|
322
|
+
t17 = composeStyles(buttonStyles.clip, shaped.corner);
|
|
323
|
+
$[42] = shaped.corner;
|
|
324
|
+
$[43] = t17;
|
|
325
|
+
} else t17 = $[43];
|
|
326
|
+
let t18;
|
|
327
|
+
if ($[44] !== feedback.layer || $[45] !== t17) {
|
|
328
|
+
t18 = /* @__PURE__ */ jsx(Animated.View, {
|
|
329
|
+
style: t17,
|
|
313
330
|
children: feedback.layer
|
|
314
331
|
});
|
|
315
|
-
$[
|
|
316
|
-
$[
|
|
317
|
-
$[
|
|
318
|
-
} else
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
children:
|
|
332
|
+
$[44] = feedback.layer;
|
|
333
|
+
$[45] = t17;
|
|
334
|
+
$[46] = t18;
|
|
335
|
+
} else t18 = $[46];
|
|
336
|
+
const t19 = icon === void 0 ? null : /* @__PURE__ */ jsx(PendingContent, {
|
|
337
|
+
isPending: pending,
|
|
338
|
+
children: /* @__PURE__ */ jsx(IconStyleContext, {
|
|
339
|
+
value: iconStyleOf(colors.content, size),
|
|
340
|
+
children: icon
|
|
341
|
+
})
|
|
322
342
|
});
|
|
323
|
-
const
|
|
324
|
-
|
|
343
|
+
const t20 = children === void 0 ? null : /* @__PURE__ */ jsx(Text, {
|
|
344
|
+
...pending ? CONCEALED : void 0,
|
|
345
|
+
style: composeStyles(role, styles.label, colors.label, pending ? pendingStyles.hidden : void 0),
|
|
325
346
|
children
|
|
326
347
|
});
|
|
327
|
-
let
|
|
328
|
-
if ($[
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
348
|
+
let t21;
|
|
349
|
+
if ($[47] !== colors || $[48] !== fontScale || $[49] !== pending || $[50] !== ringLabel || $[51] !== size || $[52] !== theme.typography) {
|
|
350
|
+
t21 = pending ? /* @__PURE__ */ jsx(PendingRing, {
|
|
351
|
+
color: colors.content,
|
|
352
|
+
diameter: theme.typography[`${ROLES[size]}Size`] * fontScale,
|
|
353
|
+
label: ringLabel
|
|
354
|
+
}) : null;
|
|
355
|
+
$[47] = colors;
|
|
356
|
+
$[48] = fontScale;
|
|
357
|
+
$[49] = pending;
|
|
358
|
+
$[50] = ringLabel;
|
|
359
|
+
$[51] = size;
|
|
360
|
+
$[52] = theme.typography;
|
|
361
|
+
$[53] = t21;
|
|
362
|
+
} else t21 = $[53];
|
|
363
|
+
let t22;
|
|
364
|
+
if ($[54] !== T0 || $[55] !== feedback.handlers || $[56] !== isDisabled || $[57] !== props || $[58] !== shaped.onLayout || $[59] !== t10 || $[60] !== t12 || $[61] !== t14 || $[62] !== t15 || $[63] !== t16 || $[64] !== t18 || $[65] !== t19 || $[66] !== t20 || $[67] !== t21 || $[68] !== t8 || $[69] !== t9) {
|
|
365
|
+
t22 = /* @__PURE__ */ jsxs(T0, {
|
|
366
|
+
role: t8,
|
|
333
367
|
...t9,
|
|
368
|
+
...t10,
|
|
369
|
+
...props,
|
|
370
|
+
...t11,
|
|
334
371
|
disabled: isDisabled,
|
|
335
|
-
hitSlop:
|
|
336
|
-
onLayout:
|
|
337
|
-
|
|
338
|
-
|
|
372
|
+
hitSlop: t12,
|
|
373
|
+
onLayout: t13,
|
|
374
|
+
onLongPress: t14,
|
|
375
|
+
onPress: t15,
|
|
376
|
+
style: t16,
|
|
339
377
|
children: [
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
378
|
+
t18,
|
|
379
|
+
t19,
|
|
380
|
+
t20,
|
|
381
|
+
t21
|
|
343
382
|
]
|
|
344
383
|
});
|
|
345
|
-
$[
|
|
346
|
-
$[
|
|
347
|
-
$[
|
|
348
|
-
$[
|
|
349
|
-
$[
|
|
350
|
-
$[
|
|
351
|
-
$[
|
|
352
|
-
$[
|
|
353
|
-
$[
|
|
354
|
-
$[
|
|
355
|
-
$[
|
|
356
|
-
$[
|
|
357
|
-
$[
|
|
358
|
-
$[
|
|
359
|
-
|
|
360
|
-
|
|
384
|
+
$[54] = T0;
|
|
385
|
+
$[55] = feedback.handlers;
|
|
386
|
+
$[56] = isDisabled;
|
|
387
|
+
$[57] = props;
|
|
388
|
+
$[58] = shaped.onLayout;
|
|
389
|
+
$[59] = t10;
|
|
390
|
+
$[60] = t12;
|
|
391
|
+
$[61] = t14;
|
|
392
|
+
$[62] = t15;
|
|
393
|
+
$[63] = t16;
|
|
394
|
+
$[64] = t18;
|
|
395
|
+
$[65] = t19;
|
|
396
|
+
$[66] = t20;
|
|
397
|
+
$[67] = t21;
|
|
398
|
+
$[68] = t8;
|
|
399
|
+
$[69] = t9;
|
|
400
|
+
$[70] = t22;
|
|
401
|
+
} else t22 = $[70];
|
|
402
|
+
return t22;
|
|
361
403
|
}
|
|
362
404
|
function iconStyleOf(color, size) {
|
|
363
405
|
return {
|