@kanso-labs/react-native-kanso-ui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/button/index.d.ts +8 -0
  2. package/dist/button/index.js +38 -26
  3. package/dist/button/index.js.map +1 -1
  4. package/dist/button/slots.js +7 -0
  5. package/dist/button/slots.js.map +1 -0
  6. package/dist/components/avatar/index.d.ts +2 -2
  7. package/dist/components/avatar/index.js.map +1 -1
  8. package/dist/components/button/index.d.ts +3 -3
  9. package/dist/components/button/index.js +115 -109
  10. package/dist/components/button/index.js.map +1 -1
  11. package/dist/components/card/index.d.ts +2 -2
  12. package/dist/components/card/index.js.map +1 -1
  13. package/dist/components/checkbox/index.d.ts +2 -2
  14. package/dist/components/checkbox/index.js.map +1 -1
  15. package/dist/components/chip/index.d.ts +2 -2
  16. package/dist/components/chip/index.js.map +1 -1
  17. package/dist/components/chip-group/index.d.ts +3 -3
  18. package/dist/components/chip-group/index.js.map +1 -1
  19. package/dist/components/copy-field/index.d.ts +2 -2
  20. package/dist/components/copy-field/index.js.map +1 -1
  21. package/dist/components/dialog/index.d.ts +131 -0
  22. package/dist/components/dialog/index.js +861 -0
  23. package/dist/components/dialog/index.js.map +1 -0
  24. package/dist/components/icon-button/index.d.ts +3 -3
  25. package/dist/components/icon-button/index.js +128 -122
  26. package/dist/components/icon-button/index.js.map +1 -1
  27. package/dist/components/link/index.js +1 -1
  28. package/dist/components/link/index.js.map +1 -1
  29. package/dist/components/meter/index.d.ts +2 -2
  30. package/dist/components/meter/index.js.map +1 -1
  31. package/dist/components/number-field/index.d.ts +3 -3
  32. package/dist/components/number-field/index.js.map +1 -1
  33. package/dist/components/product-icon/index.d.ts +2 -2
  34. package/dist/components/product-icon/index.js.map +1 -1
  35. package/dist/components/progress-indicator/index.d.ts +2 -2
  36. package/dist/components/progress-indicator/index.js.map +1 -1
  37. package/dist/components/radio-group/index.d.ts +3 -3
  38. package/dist/components/radio-group/index.js.map +1 -1
  39. package/dist/components/search-field/index.d.ts +3 -3
  40. package/dist/components/search-field/index.js.map +1 -1
  41. package/dist/components/segmented-button/index.d.ts +3 -3
  42. package/dist/components/segmented-button/index.js.map +1 -1
  43. package/dist/components/snackbar/index.d.ts +2 -2
  44. package/dist/components/snackbar/index.js.map +1 -1
  45. package/dist/components/switch/index.d.ts +2 -2
  46. package/dist/components/switch/index.js.map +1 -1
  47. package/dist/components/text-field/index.d.ts +3 -3
  48. package/dist/components/text-field/index.js.map +1 -1
  49. package/dist/field/index.d.ts +1 -1
  50. package/dist/field/index.js.map +1 -1
  51. package/dist/form/index.d.ts +1 -1
  52. package/dist/form/index.js.map +1 -1
  53. package/dist/index.d.ts +2 -1
  54. package/dist/index.js +3 -2
  55. package/dist/mark/index.d.ts +1 -1
  56. package/dist/mark/index.js.map +1 -1
  57. package/dist/overlay/host.js.map +1 -1
  58. package/dist/press/index.js +59 -60
  59. package/dist/press/index.js.map +1 -1
  60. package/package.json +11 -11
@@ -18,6 +18,7 @@ type ButtonLinkForm = {
18
18
  readonly isSelected?: never;
19
19
  readonly onChange?: never;
20
20
  readonly pendingLabel?: never;
21
+ readonly slot?: never;
21
22
  readonly type?: never;
22
23
  };
23
24
  /**
@@ -45,6 +46,12 @@ type ButtonPressForm = ButtonPending & {
45
46
  readonly href?: never;
46
47
  readonly isSelected?: never;
47
48
  readonly onChange?: never;
49
+ /**
50
+ * `close` closes the overlay the button is in, as web's React Aria slot of
51
+ * that name does: a `Dialog` given one inside its content closes when it is
52
+ * pressed, after the button's own `onPress`.
53
+ */
54
+ readonly slot?: 'close';
48
55
  /**
49
56
  * What a press does past `onPress`. `submit` submits the `Form` the button
50
57
  * is in, as a submit button does on web; `button` does nothing more.
@@ -71,6 +78,7 @@ type ButtonToggleForm = ButtonPending & {
71
78
  * a toggle.
72
79
  */
73
80
  readonly onChange?: (isSelected: boolean) => void;
81
+ readonly slot?: never;
74
82
  readonly type?: never;
75
83
  };
76
84
  //#endregion
@@ -1,6 +1,7 @@
1
1
  import { useTheme } from "../theme/scope.js";
2
2
  import { FormContext } from "../form/index.js";
3
3
  import { useOpenLink } from "../router/index.js";
4
+ import { ButtonSlotContext } from "./slots.js";
4
5
  import { c } from "react/compiler-runtime";
5
6
  import { Platform, Pressable, StyleSheet } from "react-native";
6
7
  import { use, useState } from "react";
@@ -50,7 +51,7 @@ function measureThen(height, onLayout) {
50
51
  function pressThen(onPress, then) {
51
52
  return (event) => {
52
53
  onPress?.(event);
53
- then();
54
+ then(event);
54
55
  };
55
56
  }
56
57
  /**
@@ -60,50 +61,61 @@ function pressThen(onPress, then) {
60
61
  * in. A toggle keeps its own state from `defaultSelected` unless the call
61
62
  * site holds it in `isSelected`. A submit button outside a form submits
62
63
  * nothing, as on web.
64
+ *
65
+ * Given a `slot`, a button that is not a link then does what that slot of
66
+ * the overlay around it does, as src/button's slots.ts sets out: opens it
67
+ * from the trigger, or closes it from its content.
63
68
  */
64
69
  function useButtonAction(t0) {
65
- const $ = c(14);
66
- const { defaultSelected, href, isSelected, isToggle, onChange, onPress, type } = t0;
70
+ const $ = c(15);
71
+ const { defaultSelected, href, isSelected, isToggle, onChange, onPress, slot, type } = t0;
67
72
  const openLink = useOpenLink();
68
73
  const form = use(FormContext);
74
+ const slots = use(ButtonSlotContext);
69
75
  const [ownSelected, setOwnSelected] = useState(defaultSelected ?? false);
70
76
  const selected = isToggle && (isSelected ?? ownSelected);
77
+ const filled = slot === void 0 ? void 0 : slots?.[slot];
71
78
  let t1;
72
- if ($[0] !== form || $[1] !== href || $[2] !== isToggle || $[3] !== onChange || $[4] !== openLink || $[5] !== selected || $[6] !== type) {
73
- t1 = function follow() {
74
- if (href !== void 0) openLink(href);
75
- else if (isToggle) {
79
+ if ($[0] !== filled || $[1] !== form || $[2] !== href || $[3] !== isToggle || $[4] !== onChange || $[5] !== openLink || $[6] !== selected || $[7] !== type) {
80
+ t1 = function follow(event) {
81
+ if (href !== void 0) {
82
+ openLink(href);
83
+ return;
84
+ }
85
+ if (isToggle) {
76
86
  setOwnSelected(!selected);
77
87
  onChange?.(!selected);
78
88
  } else if (type === "submit") form?.requestSubmit();
89
+ filled?.(event);
79
90
  };
80
- $[0] = form;
81
- $[1] = href;
82
- $[2] = isToggle;
83
- $[3] = onChange;
84
- $[4] = openLink;
85
- $[5] = selected;
86
- $[6] = type;
87
- $[7] = t1;
88
- } else t1 = $[7];
91
+ $[0] = filled;
92
+ $[1] = form;
93
+ $[2] = href;
94
+ $[3] = isToggle;
95
+ $[4] = onChange;
96
+ $[5] = openLink;
97
+ $[6] = selected;
98
+ $[7] = type;
99
+ $[8] = t1;
100
+ } else t1 = $[8];
89
101
  const follow = t1;
90
102
  let t2;
91
- if ($[8] !== follow || $[9] !== onPress) {
103
+ if ($[9] !== follow || $[10] !== onPress) {
92
104
  t2 = pressThen(onPress, follow);
93
- $[8] = follow;
94
- $[9] = onPress;
95
- $[10] = t2;
96
- } else t2 = $[10];
105
+ $[9] = follow;
106
+ $[10] = onPress;
107
+ $[11] = t2;
108
+ } else t2 = $[11];
97
109
  let t3;
98
- if ($[11] !== selected || $[12] !== t2) {
110
+ if ($[12] !== selected || $[13] !== t2) {
99
111
  t3 = {
100
112
  onPress: t2,
101
113
  selected
102
114
  };
103
- $[11] = selected;
104
- $[12] = t2;
105
- $[13] = t3;
106
- } else t3 = $[13];
115
+ $[12] = selected;
116
+ $[13] = t2;
117
+ $[14] = t3;
118
+ } else t3 = $[14];
107
119
  return t3;
108
120
  }
109
121
  /**
@@ -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","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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"}
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","ButtonSlotContext","ButtonLinkForm","defaultSelected","href","isPending","isSelected","onChange","pendingLabel","slot","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","slots","ownSelected","setOwnSelected","filled","undefined","t1","follow","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'\nimport { ButtonSlotContext } from './slots'\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, and what the slot it\n// fills in an overlay adds to it, the corner that eases between shapes, and\n// 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 slot?: 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 * `close` closes the overlay the button is in, as web's React Aria slot of\n * that name does: a `Dialog` given one inside its content closes when it is\n * pressed, after the button's own `onPress`.\n */\n readonly slot?: 'close'\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 slot?: never\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(\n onPress: PressableProps['onPress'],\n then: (event: GestureResponderEvent) => void,\n) {\n return (event: GestureResponderEvent) => {\n onPress?.(event)\n then(event)\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 *\n * Given a `slot`, a button that is not a link then does what that slot of\n * the overlay around it does, as src/button's slots.ts sets out: opens it\n * from the trigger, or closes it from its content.\n */\nfunction useButtonAction({\n defaultSelected,\n href,\n isSelected,\n isToggle,\n onChange,\n onPress,\n slot,\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 slot?: 'close' | 'default'\n readonly type: 'button' | 'submit' | undefined\n}) {\n const openLink = useOpenLink()\n const form = use(FormContext)\n const slots = use(ButtonSlotContext)\n const [ownSelected, setOwnSelected] = useState(defaultSelected ?? false)\n const selected = isToggle && (isSelected ?? ownSelected)\n const filled = slot === undefined ? undefined : slots?.[slot]\n\n function follow(event: GestureResponderEvent) {\n if (href !== undefined) {\n openLink(href)\n return\n }\n if (isToggle) {\n setOwnSelected(!selected)\n onChange?.(!selected)\n } else if (type === 'submit') {\n form?.requestSubmit()\n }\n filled?.(event)\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,7 @@
1
+ import { createContext } from "react";
2
+ //#region src/button/slots.ts
3
+ const ButtonSlotContext = createContext(null);
4
+ //#endregion
5
+ export { ButtonSlotContext };
6
+
7
+ //# sourceMappingURL=slots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.js","names":["GestureResponderEvent","createContext","ButtonSlots","close","event","default","ButtonSlotContext"],"sources":["../../src/button/slots.ts"],"sourcesContent":["import type { GestureResponderEvent } from 'react-native'\n\nimport { createContext } from 'react'\n\n/**\n * What a button does past its own press when it sits in an overlay's trigger\n * or content, as web's React Aria hands the same through a button's `slot`:\n * the default slot opens the overlay, which a button inside `Dialog` and\n * outside its content takes, and `close` closes it, which one given\n * `slot=\"close\"` inside the content takes. The overlay provides the slots it\n * fills, and resets the default one inside its content, so a button there\n * opens nothing.\n */\ntype ButtonSlots = {\n readonly close?: (event: GestureResponderEvent) => void\n readonly default?: (event: GestureResponderEvent) => void\n}\n\nconst ButtonSlotContext = createContext<ButtonSlots | null>(null)\n\nexport { ButtonSlotContext }\nexport type { ButtonSlots }\n"],"mappings":";;AAkBA,MAAMM,oBAAoBL,cAAkC,IAAI"}
@@ -1,6 +1,6 @@
1
1
  import { MarkImageProps } from "../../mark/index.js";
2
2
  import { StyleProp, View, ViewProps, ViewStyle } from "react-native";
3
- import { Ref } from "react";
3
+ import { ComponentRef, Ref } from "react";
4
4
  //#region src/components/avatar/index.d.ts
5
5
  type AvatarProps = Omit<ViewProps, 'children' | 'style'> & {
6
6
  /**
@@ -30,7 +30,7 @@ type AvatarProps = Omit<ViewProps, 'children' | 'style'> & {
30
30
  * names are, is one word, and takes one initial.
31
31
  */
32
32
  readonly name: string;
33
- readonly ref?: Ref<View>;
33
+ readonly ref?: Ref<ComponentRef<typeof View>>;
34
34
  /**
35
35
  * Whether an avatar with no initials to take, for a blank `name`, draws
36
36
  * Material Design's anonymous person. `false` leaves the tinted disc
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Ref","StyleProp","View","ViewProps","ViewStyle","MarkImageProps","Mark","AvatarProps","Omit","decorative","imgProps","name","ref","showPersonIcon","size","src","style","tone","Avatar","t0","$","_c","props","t1","t2","undefined","t3","_c"],"sources":["../../../src/components/avatar/index.tsx"],"sourcesContent":["import type { Ref } from 'react'\nimport type { StyleProp, View, ViewProps, ViewStyle } from 'react-native'\n\nimport type { MarkImageProps } from '../../mark'\n\nimport { Mark } from '../../mark'\n\n// A person, drawn as a disc with the photo cropped to fill it, as kanso-ui's\n// Avatar draws one. The box, the sizes, the tones, the photo's loading and\n// the labelling are the mark's in `src/mark`, which ProductIcon draws a thing\n// through as well, so a person and a thing fill the same slot.\n//\n// Which tone a given person gets is the consuming app's decision, since the\n// cycle of colours belongs where the list of people is.\n\ntype AvatarProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * Hides the avatar from screen readers, for one beside the person's name,\n * such as a row whose headline is the name or a byline, where it would\n * otherwise announce the name a second time. `name` still supplies the\n * initials, and is not announced.\n * @default false\n */\n readonly decorative?: boolean\n /**\n * Props for the photo's own `Image`: `crossOrigin` and `referrerPolicy`\n * for where it is served from, and `resizeMethod`, `fadeDuration` and\n * `progressiveRenderingEnabled` for how Android decodes and shows it.\n */\n readonly imgProps?: MarkImageProps\n /**\n * The person this represents. Supplies both the initials and the\n * accessible name, so a screen reader announces who it is rather than\n * reading two letters aloud.\n *\n * A display name, as a reader would see it written: the initials are its\n * first and last words. A title before the name (\"Dr.\"), a generational\n * suffix after it (\"Jr.\", \"III\") and an aside in brackets at its end\n * (\"(she/her)\") are passed over, as is punctuation a word opens with. A\n * name written without spaces between its words, as Japanese and Chinese\n * names are, is one word, and takes one initial.\n */\n readonly name: string\n readonly ref?: Ref<View>\n /**\n * Whether an avatar with no initials to take, for a blank `name`, draws\n * Material Design's anonymous person. `false` leaves the tinted disc\n * empty, for a loading skeleton.\n * @default true\n */\n readonly showPersonIcon?: boolean\n /**\n * Diameter: `sm` 36dp, `md` 40dp, `lg` 56dp.\n * @default 'md'\n */\n readonly size?: 'lg' | 'md' | 'sm'\n /**\n * A photo to show in place of the initials. The initials stay until it has\n * loaded, and come back if it fails.\n */\n readonly src?: string\n readonly style?: StyleProp<ViewStyle>\n /**\n * Which container and on-container colour pair to tint with.\n * @default 'primary'\n */\n readonly tone?: 'negative' | 'positive' | 'primary' | 'secondary' | 'tertiary'\n}\n\n/**\n * A person, as a disc holding their photo or, until it loads or when there\n * is none, their initials. `name` is both where the initials come from and\n * what a screen reader announces, so it is required even with a photo.\n *\n * ```tsx\n * <Avatar name=\"Ada Lovelace\" size=\"lg\" src={photo} />\n * ```\n *\n * It is announced as an image named by `name`. When the person's name is\n * already written next to the avatar, mark it `decorative`, so a screen\n * reader reads the name once. A blank name names nothing, so the avatar is\n * then a plain view, which a screen reader passes over rather than reading\n * as an image with no name.\n *\n * Reach for ProductIcon when what is drawn is not a person; the two share\n * their sizes, so either fills the same slot in a row or a card.\n *\n * The initials are taken in the device's locale. `style`, `ref` and `testID`\n * land on the disc.\n */\nfunction Avatar({ size = 'md', tone = 'primary', ...props }: AvatarProps) {\n return <Mark {...props} kind=\"person\" size={size} tone={tone} />\n}\n\nexport type { AvatarProps }\n\nexport { Avatar }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,SAAAkB,OAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,IAAA;EAAgB,CAAA,CAAAL,MAAAS,IAAAN,MAAAO,IAAA,GAAAF,SAAAH;EAAwDC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAF,QAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;CAAA;CAAtD,MAAAN,OAAAS,OAAAE,KAAAA,IAAA,OAAAF;CAAa,MAAAN,OAAAO,OAAAC,KAAAA,IAAA,YAAAD;CAAgB,IAAAE;CAAA,IAAAN,EAAA,OAAAE,SAAAF,EAAA,OAAAN,QAAAM,EAAA,OAAAH,MAAA;EACtCS,KAAA,oBAAC,MAAD;GAAK,GAAKJ;GAAY,MAAA;GAAeR;GAAYG;EAAI,CAAA;EAAIG,EAAA,KAAAE;EAAAF,EAAA,KAAAN;EAAAM,EAAA,KAAAH;EAAAG,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAAzDM;AAAyD"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","StyleProp","View","ViewProps","ViewStyle","MarkImageProps","Mark","AvatarProps","Omit","decorative","imgProps","name","ref","showPersonIcon","size","src","style","tone","Avatar","t0","$","_c","props","t1","t2","undefined","t3","_c"],"sources":["../../../src/components/avatar/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { StyleProp, View, ViewProps, ViewStyle } from 'react-native'\n\nimport type { MarkImageProps } from '../../mark'\n\nimport { Mark } from '../../mark'\n\n// A person, drawn as a disc with the photo cropped to fill it, as kanso-ui's\n// Avatar draws one. The box, the sizes, the tones, the photo's loading and\n// the labelling are the mark's in `src/mark`, which ProductIcon draws a thing\n// through as well, so a person and a thing fill the same slot.\n//\n// Which tone a given person gets is the consuming app's decision, since the\n// cycle of colours belongs where the list of people is.\n\ntype AvatarProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * Hides the avatar from screen readers, for one beside the person's name,\n * such as a row whose headline is the name or a byline, where it would\n * otherwise announce the name a second time. `name` still supplies the\n * initials, and is not announced.\n * @default false\n */\n readonly decorative?: boolean\n /**\n * Props for the photo's own `Image`: `crossOrigin` and `referrerPolicy`\n * for where it is served from, and `resizeMethod`, `fadeDuration` and\n * `progressiveRenderingEnabled` for how Android decodes and shows it.\n */\n readonly imgProps?: MarkImageProps\n /**\n * The person this represents. Supplies both the initials and the\n * accessible name, so a screen reader announces who it is rather than\n * reading two letters aloud.\n *\n * A display name, as a reader would see it written: the initials are its\n * first and last words. A title before the name (\"Dr.\"), a generational\n * suffix after it (\"Jr.\", \"III\") and an aside in brackets at its end\n * (\"(she/her)\") are passed over, as is punctuation a word opens with. A\n * name written without spaces between its words, as Japanese and Chinese\n * names are, is one word, and takes one initial.\n */\n readonly name: string\n readonly ref?: Ref<ComponentRef<typeof View>>\n /**\n * Whether an avatar with no initials to take, for a blank `name`, draws\n * Material Design's anonymous person. `false` leaves the tinted disc\n * empty, for a loading skeleton.\n * @default true\n */\n readonly showPersonIcon?: boolean\n /**\n * Diameter: `sm` 36dp, `md` 40dp, `lg` 56dp.\n * @default 'md'\n */\n readonly size?: 'lg' | 'md' | 'sm'\n /**\n * A photo to show in place of the initials. The initials stay until it has\n * loaded, and come back if it fails.\n */\n readonly src?: string\n readonly style?: StyleProp<ViewStyle>\n /**\n * Which container and on-container colour pair to tint with.\n * @default 'primary'\n */\n readonly tone?: 'negative' | 'positive' | 'primary' | 'secondary' | 'tertiary'\n}\n\n/**\n * A person, as a disc holding their photo or, until it loads or when there\n * is none, their initials. `name` is both where the initials come from and\n * what a screen reader announces, so it is required even with a photo.\n *\n * ```tsx\n * <Avatar name=\"Ada Lovelace\" size=\"lg\" src={photo} />\n * ```\n *\n * It is announced as an image named by `name`. When the person's name is\n * already written next to the avatar, mark it `decorative`, so a screen\n * reader reads the name once. A blank name names nothing, so the avatar is\n * then a plain view, which a screen reader passes over rather than reading\n * as an image with no name.\n *\n * Reach for ProductIcon when what is drawn is not a person; the two share\n * their sizes, so either fills the same slot in a row or a card.\n *\n * The initials are taken in the device's locale. `style`, `ref` and `testID`\n * land on the disc.\n */\nfunction Avatar({ size = 'md', tone = 'primary', ...props }: AvatarProps) {\n return <Mark {...props} kind=\"person\" size={size} tone={tone} />\n}\n\nexport type { AvatarProps }\n\nexport { Avatar }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,SAAAmB,OAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,IAAA;EAAgB,CAAA,CAAAL,MAAAS,IAAAN,MAAAO,IAAA,GAAAF,SAAAH;EAAwDC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAF,QAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;CAAA;CAAtD,MAAAN,OAAAS,OAAAE,KAAAA,IAAA,OAAAF;CAAa,MAAAN,OAAAO,OAAAC,KAAAA,IAAA,YAAAD;CAAgB,IAAAE;CAAA,IAAAN,EAAA,OAAAE,SAAAF,EAAA,OAAAN,QAAAM,EAAA,OAAAH,MAAA;EACtCS,KAAA,oBAAC,MAAD;GAAK,GAAKJ;GAAY,MAAA;GAAeR;GAAYG;EAAI,CAAA;EAAIG,EAAA,KAAAE;EAAAF,EAAA,KAAAN;EAAAM,EAAA,KAAAH;EAAAG,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAAzDM;AAAyD"}
@@ -1,6 +1,6 @@
1
1
  import { ButtonLinkForm, ButtonPressForm, ButtonToggleForm } from "../../button/index.js";
2
2
  import { PressableProps, StyleProp, View, ViewStyle } from "react-native";
3
- import { ReactNode, Ref } from "react";
3
+ import { ComponentRef, ReactNode, Ref } from "react";
4
4
  //#region src/components/button/index.d.ts
5
5
  type ButtonForm = ButtonLinkForm | ButtonPressForm | (ButtonToggleForm & {
6
6
  /**
@@ -29,7 +29,7 @@ type ButtonProps = ButtonForm & Omit<PressableProps, 'children' | 'disabled' | '
29
29
  * @default false
30
30
  */
31
31
  readonly isDisabled?: boolean;
32
- readonly ref?: Ref<View>;
32
+ readonly ref?: Ref<ComponentRef<typeof View>>;
33
33
  /**
34
34
  * The corner the button rests at: `round` is the pill, `square` the
35
35
  * page's rounded rectangle, 12dp up to `md`, 16dp at `lg` and 28dp above.
@@ -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, isPending, isSelected, onBlur, onChange, onFocus, onHoverIn, onHoverOut, onLayout, onLongPress, onPress, onPressIn, onPressOut, pendingLabel, 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, slot, 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
@@ -161,7 +161,7 @@ const outlinedSizesOf = themedStyles((theme) => {
161
161
  * `style`, `ref` and `testID` land on the `Pressable`.
162
162
  */
163
163
  function Button(t0) {
164
- const $ = c(71);
164
+ const $ = c(73);
165
165
  let children;
166
166
  let defaultSelected;
167
167
  let href;
@@ -180,6 +180,7 @@ function Button(t0) {
180
180
  let ownHitSlop;
181
181
  let pendingLabel;
182
182
  let props;
183
+ let slot;
183
184
  let style;
184
185
  let t1;
185
186
  let t2;
@@ -189,7 +190,7 @@ function Button(t0) {
189
190
  let t6;
190
191
  let type;
191
192
  if ($[0] !== t0) {
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);
193
+ ({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, slot, style, type, variant: t6, ...props} = t0);
193
194
  $[0] = t0;
194
195
  $[1] = children;
195
196
  $[2] = defaultSelected;
@@ -209,14 +210,15 @@ function Button(t0) {
209
210
  $[16] = ownHitSlop;
210
211
  $[17] = pendingLabel;
211
212
  $[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
+ $[19] = slot;
214
+ $[20] = style;
215
+ $[21] = t1;
216
+ $[22] = t2;
217
+ $[23] = t3;
218
+ $[24] = t4;
219
+ $[25] = t5;
220
+ $[26] = t6;
221
+ $[27] = type;
220
222
  } else {
221
223
  children = $[1];
222
224
  defaultSelected = $[2];
@@ -236,14 +238,15 @@ function Button(t0) {
236
238
  ownHitSlop = $[16];
237
239
  pendingLabel = $[17];
238
240
  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];
241
+ slot = $[19];
242
+ style = $[20];
243
+ t1 = $[21];
244
+ t2 = $[22];
245
+ t3 = $[23];
246
+ t4 = $[24];
247
+ t5 = $[25];
248
+ t6 = $[26];
249
+ type = $[27];
247
250
  }
248
251
  const disableRipple = t1 === void 0 ? false : t1;
249
252
  const isDisabled = t2 === void 0 ? false : t2;
@@ -257,27 +260,30 @@ function Button(t0) {
257
260
  const pending = href === void 0 && isPending;
258
261
  const ringLabel = usePending(pending, pendingLabel);
259
262
  const isToggle = variant !== "text" && (defaultSelected !== void 0 || isSelected !== void 0 || onChange !== void 0);
260
- let t7;
261
- if ($[27] !== defaultSelected || $[28] !== href || $[29] !== isSelected || $[30] !== isToggle || $[31] !== onChange || $[32] !== onPress || $[33] !== type) {
262
- t7 = {
263
+ const t7 = slot ?? "default";
264
+ let t8;
265
+ if ($[28] !== defaultSelected || $[29] !== href || $[30] !== isSelected || $[31] !== isToggle || $[32] !== onChange || $[33] !== onPress || $[34] !== t7 || $[35] !== type) {
266
+ t8 = {
263
267
  defaultSelected,
264
268
  href,
265
269
  isSelected,
266
270
  isToggle,
267
271
  onChange,
268
272
  onPress,
273
+ slot: t7,
269
274
  type
270
275
  };
271
- $[27] = defaultSelected;
272
- $[28] = href;
273
- $[29] = isSelected;
274
- $[30] = isToggle;
275
- $[31] = onChange;
276
- $[32] = onPress;
277
- $[33] = type;
276
+ $[28] = defaultSelected;
277
+ $[29] = href;
278
+ $[30] = isSelected;
279
+ $[31] = isToggle;
280
+ $[32] = onChange;
281
+ $[33] = onPress;
278
282
  $[34] = t7;
279
- } else t7 = $[34];
280
- const action = useButtonAction(t7);
283
+ $[35] = type;
284
+ $[36] = t8;
285
+ } else t8 = $[36];
286
+ const action = useButtonAction(t8);
281
287
  const colors = palettesOf(theme)[isDisabled ? DISABLED[variant] : variant !== "text" && isToggle ? TOGGLE_PALETTES[variant][action.selected ? "selected" : "unselected"] : variant];
282
288
  const feedback = usePressFeedback({
283
289
  color: colors.content,
@@ -295,111 +301,111 @@ function Button(t0) {
295
301
  const resting = shape === "square" !== action.selected ? radii[SQUARE_CORNERS[size]] : radii.pill;
296
302
  const shaped = useCorner(feedback.pressed ? radii[PRESSED_CORNERS[size]] : resting, onLayout);
297
303
  const T0 = AnimatedPressable;
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];
304
+ const t9 = href === void 0 ? "button" : "link";
305
+ let t10;
306
+ if ($[37] !== action.selected || $[38] !== isToggle) {
307
+ t10 = isToggle ? toggleState(action.selected) : void 0;
308
+ $[37] = action.selected;
309
+ $[38] = isToggle;
310
+ $[39] = t10;
311
+ } else t10 = $[39];
312
+ const t11 = pending ? BUSY : void 0;
313
+ const t12 = feedback.handlers;
314
+ let t13;
315
+ if ($[40] !== ownHitSlop || $[41] !== size || $[42] !== theme.sizing) {
316
+ t13 = ownHitSlop ?? hitSlop(theme.sizing[HEIGHTS[size]]);
317
+ $[40] = ownHitSlop;
318
+ $[41] = size;
319
+ $[42] = theme.sizing;
320
+ $[43] = t13;
321
+ } else t13 = $[43];
322
+ const t14 = shaped.onLayout;
323
+ const t15 = pending ? void 0 : onLongPress;
324
+ const t16 = pending ? void 0 : action.onPress;
325
+ const t17 = 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);
326
326
  let t18;
327
- if ($[44] !== feedback.layer || $[45] !== t17) {
328
- t18 = /* @__PURE__ */ jsx(Animated.View, {
329
- style: t17,
327
+ if ($[44] !== shaped.corner) {
328
+ t18 = composeStyles(buttonStyles.clip, shaped.corner);
329
+ $[44] = shaped.corner;
330
+ $[45] = t18;
331
+ } else t18 = $[45];
332
+ let t19;
333
+ if ($[46] !== feedback.layer || $[47] !== t18) {
334
+ t19 = /* @__PURE__ */ jsx(Animated.View, {
335
+ style: t18,
330
336
  children: feedback.layer
331
337
  });
332
- $[44] = feedback.layer;
333
- $[45] = t17;
334
- $[46] = t18;
335
- } else t18 = $[46];
336
- const t19 = icon === void 0 ? null : /* @__PURE__ */ jsx(PendingContent, {
338
+ $[46] = feedback.layer;
339
+ $[47] = t18;
340
+ $[48] = t19;
341
+ } else t19 = $[48];
342
+ const t20 = icon === void 0 ? null : /* @__PURE__ */ jsx(PendingContent, {
337
343
  isPending: pending,
338
344
  children: /* @__PURE__ */ jsx(IconStyleContext, {
339
345
  value: iconStyleOf(colors.content, size),
340
346
  children: icon
341
347
  })
342
348
  });
343
- const t20 = children === void 0 ? null : /* @__PURE__ */ jsx(Text, {
349
+ const t21 = children === void 0 ? null : /* @__PURE__ */ jsx(Text, {
344
350
  ...pending ? CONCEALED : void 0,
345
351
  style: composeStyles(role, styles.label, colors.label, pending ? pendingStyles.hidden : void 0),
346
352
  children
347
353
  });
348
- let t21;
349
- if ($[47] !== colors || $[48] !== fontScale || $[49] !== pending || $[50] !== ringLabel || $[51] !== size || $[52] !== theme.typography) {
350
- t21 = pending ? /* @__PURE__ */ jsx(PendingRing, {
354
+ let t22;
355
+ if ($[49] !== colors || $[50] !== fontScale || $[51] !== pending || $[52] !== ringLabel || $[53] !== size || $[54] !== theme.typography) {
356
+ t22 = pending ? /* @__PURE__ */ jsx(PendingRing, {
351
357
  color: colors.content,
352
358
  diameter: theme.typography[`${ROLES[size]}Size`] * fontScale,
353
359
  label: ringLabel
354
360
  }) : 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,
367
- ...t9,
361
+ $[49] = colors;
362
+ $[50] = fontScale;
363
+ $[51] = pending;
364
+ $[52] = ringLabel;
365
+ $[53] = size;
366
+ $[54] = theme.typography;
367
+ $[55] = t22;
368
+ } else t22 = $[55];
369
+ let t23;
370
+ if ($[56] !== T0 || $[57] !== feedback.handlers || $[58] !== isDisabled || $[59] !== props || $[60] !== shaped.onLayout || $[61] !== t10 || $[62] !== t11 || $[63] !== t13 || $[64] !== t15 || $[65] !== t16 || $[66] !== t17 || $[67] !== t19 || $[68] !== t20 || $[69] !== t21 || $[70] !== t22 || $[71] !== t9) {
371
+ t23 = /* @__PURE__ */ jsxs(T0, {
372
+ role: t9,
368
373
  ...t10,
369
- ...props,
370
374
  ...t11,
375
+ ...props,
376
+ ...t12,
371
377
  disabled: isDisabled,
372
- hitSlop: t12,
373
- onLayout: t13,
374
- onLongPress: t14,
375
- onPress: t15,
376
- style: t16,
378
+ hitSlop: t13,
379
+ onLayout: t14,
380
+ onLongPress: t15,
381
+ onPress: t16,
382
+ style: t17,
377
383
  children: [
378
- t18,
379
384
  t19,
380
385
  t20,
381
- t21
386
+ t21,
387
+ t22
382
388
  ]
383
389
  });
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;
390
+ $[56] = T0;
391
+ $[57] = feedback.handlers;
392
+ $[58] = isDisabled;
393
+ $[59] = props;
394
+ $[60] = shaped.onLayout;
395
+ $[61] = t10;
396
+ $[62] = t11;
397
+ $[63] = t13;
398
+ $[64] = t15;
399
+ $[65] = t16;
400
+ $[66] = t17;
401
+ $[67] = t19;
402
+ $[68] = t20;
403
+ $[69] = t21;
400
404
  $[70] = t22;
401
- } else t22 = $[70];
402
- return t22;
405
+ $[71] = t9;
406
+ $[72] = t23;
407
+ } else t23 = $[72];
408
+ return t23;
403
409
  }
404
410
  function iconStyleOf(color, size) {
405
411
  return {