@xaui/native 0.9.1-alpha.16 → 0.9.1-alpha.18

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 (42) hide show
  1. package/dist/chunk-4K3LZS7M.js +448 -0
  2. package/dist/chunk-5SU7FXWH.cjs +448 -0
  3. package/dist/chunk-6PZF4PI7.js +100 -0
  4. package/dist/chunk-6VTBGBPP.cjs +100 -0
  5. package/dist/{chunk-KCUT47FY.cjs → chunk-BHAHJHAI.cjs} +5 -1
  6. package/dist/{chunk-UOJBK5Z4.js → chunk-L3AQNVRN.js} +1 -1
  7. package/dist/{chunk-BAACHVM4.cjs → chunk-M2VYRHVS.cjs} +2 -2
  8. package/dist/{chunk-E3756MJC.js → chunk-MBLPPOSO.js} +16 -15
  9. package/dist/{chunk-NLFE3CRM.cjs → chunk-ODH5WAVM.cjs} +24 -23
  10. package/dist/{chunk-PUER6Y4M.cjs → chunk-P5MKOLIW.cjs} +110 -409
  11. package/dist/chunk-VQPP6FCB.js +728 -0
  12. package/dist/{chunk-EHHSY2KB.js → chunk-XQE5PXOD.js} +5 -1
  13. package/dist/components/button/index.cjs +4 -3
  14. package/dist/components/button/index.d.cts +179 -178
  15. package/dist/components/button/index.d.ts +179 -178
  16. package/dist/components/button/index.js +3 -2
  17. package/dist/components/typography/index.cjs +12 -0
  18. package/dist/components/typography/index.d.cts +115 -0
  19. package/dist/components/typography/index.d.ts +115 -0
  20. package/dist/components/typography/index.js +12 -0
  21. package/dist/create-recipe-3_ElpCYt.d.cts +117 -0
  22. package/dist/create-recipe-DImq1AZA.d.ts +117 -0
  23. package/dist/index.cjs +17 -7
  24. package/dist/index.d.cts +4 -2
  25. package/dist/index.d.ts +4 -2
  26. package/dist/index.js +21 -11
  27. package/dist/pressable-feedback.type-UwqIG6ES.d.ts +195 -0
  28. package/dist/pressable-feedback.type-lgW5wQx5.d.cts +195 -0
  29. package/dist/system/index.cjs +5 -3
  30. package/dist/system/index.d.cts +10 -4
  31. package/dist/system/index.d.ts +10 -4
  32. package/dist/system/index.js +11 -9
  33. package/dist/theme/index.cjs +2 -2
  34. package/dist/theme/index.d.cts +2 -2
  35. package/dist/theme/index.d.ts +2 -2
  36. package/dist/theme/index.js +1 -1
  37. package/dist/{theme.type-C9bFJKFm.d.cts → theme.type-C2gNHpEx.d.cts} +1 -1
  38. package/dist/{theme.type-C9bFJKFm.d.ts → theme.type-C2gNHpEx.d.ts} +1 -1
  39. package/package.json +11 -1
  40. package/dist/chunk-64L44HEI.js +0 -1021
  41. package/dist/create-recipe-BcUu9b2I.d.cts +0 -280
  42. package/dist/create-recipe-DD9W6m9b.d.ts +0 -280
@@ -1,280 +0,0 @@
1
- import { ComponentType, ReactNode } from 'react';
2
- import { ImageStyle, TextStyle, ViewStyle, ImageSourcePropType, StyleProp, PressableProps } from 'react-native';
3
- import { SharedValue } from 'react-native-reanimated';
4
- import { g as XAUITheme, X as XAUIColors } from './theme.type-C9bFJKFm.cjs';
5
-
6
- /**
7
- * R13 — React Native mirrors a layout under RTL through the Start/End properties and only
8
- * those. A props API is exactly where someone writes `paddingLeft` without thinking, so
9
- * the type removes the temptation instead of leaving it to a review.
10
- */
11
- type DirectionalStyleKey = 'left' | 'right' | 'paddingLeft' | 'paddingRight' | 'marginLeft' | 'marginRight' | 'borderLeftWidth' | 'borderRightWidth' | 'borderLeftColor' | 'borderRightColor' | 'borderTopLeftRadius' | 'borderTopRightRadius' | 'borderBottomLeftRadius' | 'borderBottomRightRadius';
12
- /**
13
- * `pointerEvents` is a style key *and* a `View` prop. R14 says the component's own prop
14
- * wins, so it stays the prop it has always been and is not exposed twice — the one name
15
- * where the two vocabularies collide.
16
- */
17
- type ComponentOwnedStyleKey = 'pointerEvents';
18
- /**
19
- * The style keys of a node, exposed as props (R14). Not a maintained list: it derives
20
- * from the React Native type, minus what R13 forbids.
21
- *
22
- * ```ts
23
- * type CardProps = ViewStyleProps & { variant?: CardVariant }
24
- * ```
25
- */
26
- type StyleProps<Style> = Omit<Style, DirectionalStyleKey | ComponentOwnedStyleKey>;
27
- /** A root, or any slot that renders a view. */
28
- type ViewStyleProps = StyleProps<ViewStyle>;
29
- /** A text slot — `color`, `fontSize`, `letterSpacing`… */
30
- type TextStyleProps = StyleProps<TextStyle>;
31
- /** An image slot — `resizeMode`, `tintColor`… */
32
- type ImageStyleProps = StyleProps<ImageStyle>;
33
-
34
- /**
35
- * The props Lucide, Ionicons and `react-native-vector-icons` all accept — the shape
36
- * `as` is handed. It is a convention rather than an interface anyone published, which is
37
- * exactly why `Icon` exists: without it every call site computes the two values by hand.
38
- */
39
- type IconComponentProps = {
40
- size?: number;
41
- color?: string;
42
- };
43
- /**
44
- * R14 reaches the **`source` form only**, exactly like `style` below and for the same
45
- * reason: it is the one of the three forms where we render the node. On the other two,
46
- * `size` and `color` are what shapes the icon.
47
- */
48
- type IconProps = ImageStyleProps & {
49
- /** An icon component. `size` and `color` are injected into it. */
50
- as?: ComponentType<IconComponentProps>;
51
- /** A raw `react-native-svg` element, cloned with the resolved size and colour. */
52
- children?: ReactNode;
53
- /** An image, tinted with the resolved colour. */
54
- source?: ImageSourcePropType;
55
- /** Overrides what the surrounding slot asked for. */
56
- size?: number;
57
- /** A raw value (R7), never a token. Overrides the slot's. */
58
- color?: string;
59
- /**
60
- * The **`source` form only** — it is the one of the three where we render the view.
61
- * `as` hands its props to a third-party component and the children form clones an
62
- * element the caller made; neither is a view this can style, and wrapping them would
63
- * add a level of depth to every icon in the library. `size` and `color` are the
64
- * escape hatch there.
65
- */
66
- style?: StyleProp<ImageStyle>;
67
- };
68
- /** What a component root publishes so the icons inside it need no props at all. */
69
- type IconContextValue = {
70
- size?: number;
71
- color?: string;
72
- };
73
-
74
- type AnimationConfig = {
75
- scale?: boolean;
76
- highlight?: boolean;
77
- ripple?: boolean;
78
- };
79
- /**
80
- * `false` and `'disabled'` turn this component's animations off. `'disable-all'` turns
81
- * them off for its descendants too — a long list kills every row's worklets with one
82
- * prop instead of threading it down. An object switches them off one at a time.
83
- */
84
- type AnimationProp = boolean | 'disabled' | 'disable-all' | AnimationConfig;
85
- /** `animation` once normalised — what the components actually read. */
86
- type ResolvedAnimation = {
87
- scale: boolean;
88
- highlight: boolean;
89
- ripple: boolean;
90
- /** True when every sub-animation is off: the branch that mounts no worklet at all. */
91
- none: boolean;
92
- /** Propagated to descendants through context. */
93
- disableAll: boolean;
94
- };
95
- /**
96
- * R14 — it renders a `Pressable`, so it takes that node's style keys as props. The
97
- * primitive every pressable component in the library is built on cannot be the one place
98
- * where `padding={16}` has to become an object again.
99
- */
100
- type PressableFeedbackProps = Omit<PressableProps, 'style' | 'children' | 'disabled'> & ViewStyleProps & {
101
- /** Controlled: the root owns the state, because its recipe resolves on it (R5). */
102
- isPressed?: boolean;
103
- /** R8: `disabled` is not part of the public vocabulary, `isX` is. */
104
- isDisabled?: boolean;
105
- /**
106
- * Merge into the single child instead of rendering a pressable (R12) — **keeping the
107
- * feedback**. Swapping this component out for a bare `Slot` would silently drop the
108
- * touch feedback of every `asChild` control.
109
- */
110
- asChild?: boolean;
111
- animation?: AnimationProp;
112
- style?: StyleProp<ViewStyle>;
113
- /**
114
- * The overlays are children, not a prop — `<PressableFeedback.Highlight />` or
115
- * `<PressableFeedback.Ripple />`, in any order: the root paints them under everything
116
- * else wherever they sit. The scale is the root's own and needs nothing rendered.
117
- *
118
- * `Pressable`'s function form is dropped on purpose. It exists to hand the press state
119
- * to children; here the root above already owns that state and this publishes it
120
- * through context, so the function form would be a second, quieter source of truth.
121
- */
122
- children?: ReactNode;
123
- };
124
- /**
125
- * A slot's own animation, overriding the blanket one on the root. `false` switches that
126
- * slot off; the object tunes it. Deliberately two knobs rather than a full timing
127
- * surface — anything past this is a different animation, and that is a component's job,
128
- * not a prop's.
129
- */
130
- type SlotAnimation = boolean | {
131
- /** Milliseconds. Falls back to the shared press timing. */
132
- duration?: number;
133
- /** How far the overlay goes at full press, 0 to 1. */
134
- opacity?: number;
135
- };
136
- /** One ripple wave. Two of them, so a rapid double tap does not cut the one in flight. */
137
- type RippleWave = {
138
- /** `0 → 1` as the circle opens. */
139
- expand: SharedValue<number>;
140
- /** `0 → 1` as the ink arrives, on its own curve. */
141
- alpha: SharedValue<number>;
142
- /** Where the finger landed, in the root's coordinates. */
143
- origin: SharedValue<{
144
- x: number;
145
- y: number;
146
- }>;
147
- };
148
- /**
149
- * The corner keys an overlay copies off the root. The `Left`/`Right` forms are absent
150
- * rather than forgotten: R13 bans them, because RN mirrors only the logical ones under RTL.
151
- */
152
- type RadiusStyle = Pick<ViewStyle, 'borderRadius' | 'borderStartStartRadius' | 'borderStartEndRadius' | 'borderEndStartRadius' | 'borderEndEndRadius'>;
153
- type FeedbackContext = {
154
- /**
155
- * The overlay's ink, resolved by the root from its own background.
156
- *
157
- * A wash or a wave has to contrast with what it sits on, and only the root knows that —
158
- * it flattens its own `style` and reads `backgroundColor`, then takes the contrasting
159
- * side the same way a tint does. Black ink at 10% on a saturated fill is close to
160
- * invisible, which is the one thing a press indicator cannot be.
161
- */
162
- ink: string;
163
- /**
164
- * The root's own corners, so an overlay rounds itself to match. `corners` and not
165
- * `radius`: the ripple already has a radius, and it is a length in points rather than a
166
- * shape.
167
- *
168
- * An absolute fill has square corners and every control here is rounded, so without this
169
- * both the wash and the wave paint outside the surface at each corner. The overlay
170
- * carries the clip rather than the root: clipping the root would also cut a child that
171
- * legitimately overflows — a badge on a button's corner — and that child has nothing to
172
- * do with the press.
173
- */
174
- corners: RadiusStyle;
175
- isPressed: boolean;
176
- animation: ResolvedAnimation;
177
- /** Absent on the static branch, where nothing animates and no worklet is mounted. */
178
- progress?: SharedValue<number>;
179
- /** How big the root is — what the scale coefficient is computed from. */
180
- size?: SharedValue<{
181
- width: number;
182
- height: number;
183
- }>;
184
- /**
185
- * The two ripple waves, driven by the **root**.
186
- *
187
- * They belong to the root because the root is the touch surface. An overlay carrying its
188
- * own handlers only hears touches that land on *it* — and it is a sibling of the label,
189
- * not its parent, so pressing the text of a button would do nothing. Touches bubble to
190
- * the `Pressable`, which is why the handlers live there and the waves are published down.
191
- */
192
- waves?: readonly [RippleWave, RippleWave];
193
- };
194
-
195
- /**
196
- * A slot is a view or a text node, and a recipe writes one object per slot, so the two
197
- * RN style shapes are merged rather than discriminated per slot.
198
- */
199
- type SlotStyle = ViewStyle & TextStyle;
200
- type SlotStyles<Slot extends string> = Partial<Record<Slot, SlotStyle>>;
201
- /** The roles a variant consumes. The variant names tokens; `paint` says where they land. */
202
- type VariantRole = 'bg' | 'bgPressed' | 'fg' | 'border';
203
- /** Token names per role — no colour value ever appears in a recipe. */
204
- type VariantTokens = Partial<Record<VariantRole, keyof XAUIColors>>;
205
- /** The same roles resolved: theme colours, or the slices of a raw `color`. */
206
- type VariantColors = Partial<Record<VariantRole, string>>;
207
- /**
208
- * `disabled` is applied last of the three: a control that is both pressed and disabled
209
- * has to read disabled.
210
- */
211
- type StateName = 'focused' | 'pressed' | 'disabled';
212
- type States = Partial<Record<StateName, boolean>>;
213
- /** Reads the theme and the variant's resolved colours; returns one style per slot. */
214
- type StyleFn<Slot extends string> = (theme: XAUITheme, colors: VariantColors) => SlotStyles<Slot>;
215
- /** Named axes of finite token values — `{ size: { sm: fn, md: fn } }`. */
216
- type Axes<Slot extends string> = Record<string, Record<string, StyleFn<Slot>>>;
217
- /** One value per axis, plus the variant. Missing keys fall back to `defaultVariants`. */
218
- type Selection<Variant extends string, A extends Axes<string>> = {
219
- variant?: Variant;
220
- } & {
221
- [Axis in keyof A]?: Extract<keyof A[Axis], string>;
222
- };
223
- type CompoundVariant<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
224
- when: Selection<Variant, A>;
225
- style: StyleFn<Slot>;
226
- };
227
- type RecipeConfig<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
228
- /** Every slot the component publishes. Slots a recipe never styles resolve to `{}`. */
229
- slots: readonly Slot[];
230
- base?: StyleFn<Slot>;
231
- variantTokens?: Record<Variant, VariantTokens>;
232
- /** Where the variant's colours land — written once, and it holds for every variant. */
233
- paint?: StyleFn<Slot>;
234
- variants?: A;
235
- compoundVariants?: ReadonlyArray<CompoundVariant<Slot, Variant, A>>;
236
- states?: Partial<Record<StateName, StyleFn<Slot>>>;
237
- /**
238
- * `NoInfer`, because this is the one place a single variant name appears on its own:
239
- * without it, inference reads `Variant` off `{ variant: 'primary' }` and narrows the
240
- * whole recipe to that one value, so every other variant becomes a type error at the
241
- * call site. `variantTokens` is the declaration; this only picks a default from it.
242
- */
243
- defaultVariants?: Selection<NoInfer<Variant>, A>;
244
- };
245
- /** Stable references: the same object for the same tokens, for the app's lifetime. */
246
- type ResolvedStyles<Slot extends string> = Readonly<Record<Slot, SlotStyle>>;
247
- /** A selection with `defaultVariants` already folded in, keyed by axis name. */
248
- type ResolvedSelection = Readonly<Record<string, string | undefined>>;
249
-
250
- type ResolveArgs<Variant extends string, A extends Axes<string>> = {
251
- theme: XAUITheme;
252
- selection?: Selection<Variant, A>;
253
- states?: States;
254
- };
255
- type TintArgs<Variant extends string, A extends Axes<string>> = ResolveArgs<Variant, A> & {
256
- color: string;
257
- };
258
- type Recipe<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
259
- readonly slots: readonly Slot[];
260
- /** The cached pass: stable `StyleSheet` references, keyed by tokens alone. */
261
- resolve(args: ResolveArgs<Variant, A>): ResolvedStyles<Slot>;
262
- /**
263
- * The tint pass: the same functions run again with `color`'s slices in place of the
264
- * theme's tokens. Uncached and allocating, and only ever called when `color` is set.
265
- */
266
- tint(args: TintArgs<Variant, A>): SlotStyles<Slot>;
267
- };
268
- /**
269
- * A component's style, declared once. Resolution splits in two because the two halves
270
- * have different lifetimes: everything keyed by a finite token is cached forever, and
271
- * an arbitrary `color` is recomputed per render — which is what keeps the cache bounded
272
- * by the number of token combinations rather than by the palette users invent.
273
- *
274
- * const styles = buttonRecipe.resolve({ theme, selection: { variant, size }, states })
275
- * const tint = color ? buttonRecipe.tint({ theme, color, selection, states }) : undefined
276
- * <View style={[styles.root, tint?.root, style]} />
277
- */
278
- declare function createRecipe<Slot extends string, Variant extends string, const A extends Axes<Slot>>(config: RecipeConfig<Slot, Variant, A>): Recipe<Slot, Variant, A>;
279
-
280
- export { type AnimationConfig as A, type CompoundVariant as C, type DirectionalStyleKey as D, type FeedbackContext as F, type IconComponentProps as I, type PressableFeedbackProps as P, type RadiusStyle as R, type SlotAnimation as S, type TintArgs as T, type VariantColors as V, type IconContextValue as a, type IconProps as b, type AnimationProp as c, type ResolvedAnimation as d, type RippleWave as e, createRecipe as f, type Recipe as g, type ResolveArgs as h, type Axes as i, type RecipeConfig as j, type ResolvedSelection as k, type ResolvedStyles as l, type Selection as m, type SlotStyle as n, type SlotStyles as o, type StateName as p, type States as q, type StyleFn as r, type VariantRole as s, type VariantTokens as t, type ImageStyleProps as u, type StyleProps as v, type TextStyleProps as w, type ViewStyleProps as x };
@@ -1,280 +0,0 @@
1
- import { ComponentType, ReactNode } from 'react';
2
- import { ImageStyle, TextStyle, ViewStyle, ImageSourcePropType, StyleProp, PressableProps } from 'react-native';
3
- import { SharedValue } from 'react-native-reanimated';
4
- import { g as XAUITheme, X as XAUIColors } from './theme.type-C9bFJKFm.js';
5
-
6
- /**
7
- * R13 — React Native mirrors a layout under RTL through the Start/End properties and only
8
- * those. A props API is exactly where someone writes `paddingLeft` without thinking, so
9
- * the type removes the temptation instead of leaving it to a review.
10
- */
11
- type DirectionalStyleKey = 'left' | 'right' | 'paddingLeft' | 'paddingRight' | 'marginLeft' | 'marginRight' | 'borderLeftWidth' | 'borderRightWidth' | 'borderLeftColor' | 'borderRightColor' | 'borderTopLeftRadius' | 'borderTopRightRadius' | 'borderBottomLeftRadius' | 'borderBottomRightRadius';
12
- /**
13
- * `pointerEvents` is a style key *and* a `View` prop. R14 says the component's own prop
14
- * wins, so it stays the prop it has always been and is not exposed twice — the one name
15
- * where the two vocabularies collide.
16
- */
17
- type ComponentOwnedStyleKey = 'pointerEvents';
18
- /**
19
- * The style keys of a node, exposed as props (R14). Not a maintained list: it derives
20
- * from the React Native type, minus what R13 forbids.
21
- *
22
- * ```ts
23
- * type CardProps = ViewStyleProps & { variant?: CardVariant }
24
- * ```
25
- */
26
- type StyleProps<Style> = Omit<Style, DirectionalStyleKey | ComponentOwnedStyleKey>;
27
- /** A root, or any slot that renders a view. */
28
- type ViewStyleProps = StyleProps<ViewStyle>;
29
- /** A text slot — `color`, `fontSize`, `letterSpacing`… */
30
- type TextStyleProps = StyleProps<TextStyle>;
31
- /** An image slot — `resizeMode`, `tintColor`… */
32
- type ImageStyleProps = StyleProps<ImageStyle>;
33
-
34
- /**
35
- * The props Lucide, Ionicons and `react-native-vector-icons` all accept — the shape
36
- * `as` is handed. It is a convention rather than an interface anyone published, which is
37
- * exactly why `Icon` exists: without it every call site computes the two values by hand.
38
- */
39
- type IconComponentProps = {
40
- size?: number;
41
- color?: string;
42
- };
43
- /**
44
- * R14 reaches the **`source` form only**, exactly like `style` below and for the same
45
- * reason: it is the one of the three forms where we render the node. On the other two,
46
- * `size` and `color` are what shapes the icon.
47
- */
48
- type IconProps = ImageStyleProps & {
49
- /** An icon component. `size` and `color` are injected into it. */
50
- as?: ComponentType<IconComponentProps>;
51
- /** A raw `react-native-svg` element, cloned with the resolved size and colour. */
52
- children?: ReactNode;
53
- /** An image, tinted with the resolved colour. */
54
- source?: ImageSourcePropType;
55
- /** Overrides what the surrounding slot asked for. */
56
- size?: number;
57
- /** A raw value (R7), never a token. Overrides the slot's. */
58
- color?: string;
59
- /**
60
- * The **`source` form only** — it is the one of the three where we render the view.
61
- * `as` hands its props to a third-party component and the children form clones an
62
- * element the caller made; neither is a view this can style, and wrapping them would
63
- * add a level of depth to every icon in the library. `size` and `color` are the
64
- * escape hatch there.
65
- */
66
- style?: StyleProp<ImageStyle>;
67
- };
68
- /** What a component root publishes so the icons inside it need no props at all. */
69
- type IconContextValue = {
70
- size?: number;
71
- color?: string;
72
- };
73
-
74
- type AnimationConfig = {
75
- scale?: boolean;
76
- highlight?: boolean;
77
- ripple?: boolean;
78
- };
79
- /**
80
- * `false` and `'disabled'` turn this component's animations off. `'disable-all'` turns
81
- * them off for its descendants too — a long list kills every row's worklets with one
82
- * prop instead of threading it down. An object switches them off one at a time.
83
- */
84
- type AnimationProp = boolean | 'disabled' | 'disable-all' | AnimationConfig;
85
- /** `animation` once normalised — what the components actually read. */
86
- type ResolvedAnimation = {
87
- scale: boolean;
88
- highlight: boolean;
89
- ripple: boolean;
90
- /** True when every sub-animation is off: the branch that mounts no worklet at all. */
91
- none: boolean;
92
- /** Propagated to descendants through context. */
93
- disableAll: boolean;
94
- };
95
- /**
96
- * R14 — it renders a `Pressable`, so it takes that node's style keys as props. The
97
- * primitive every pressable component in the library is built on cannot be the one place
98
- * where `padding={16}` has to become an object again.
99
- */
100
- type PressableFeedbackProps = Omit<PressableProps, 'style' | 'children' | 'disabled'> & ViewStyleProps & {
101
- /** Controlled: the root owns the state, because its recipe resolves on it (R5). */
102
- isPressed?: boolean;
103
- /** R8: `disabled` is not part of the public vocabulary, `isX` is. */
104
- isDisabled?: boolean;
105
- /**
106
- * Merge into the single child instead of rendering a pressable (R12) — **keeping the
107
- * feedback**. Swapping this component out for a bare `Slot` would silently drop the
108
- * touch feedback of every `asChild` control.
109
- */
110
- asChild?: boolean;
111
- animation?: AnimationProp;
112
- style?: StyleProp<ViewStyle>;
113
- /**
114
- * The overlays are children, not a prop — `<PressableFeedback.Highlight />` or
115
- * `<PressableFeedback.Ripple />`, in any order: the root paints them under everything
116
- * else wherever they sit. The scale is the root's own and needs nothing rendered.
117
- *
118
- * `Pressable`'s function form is dropped on purpose. It exists to hand the press state
119
- * to children; here the root above already owns that state and this publishes it
120
- * through context, so the function form would be a second, quieter source of truth.
121
- */
122
- children?: ReactNode;
123
- };
124
- /**
125
- * A slot's own animation, overriding the blanket one on the root. `false` switches that
126
- * slot off; the object tunes it. Deliberately two knobs rather than a full timing
127
- * surface — anything past this is a different animation, and that is a component's job,
128
- * not a prop's.
129
- */
130
- type SlotAnimation = boolean | {
131
- /** Milliseconds. Falls back to the shared press timing. */
132
- duration?: number;
133
- /** How far the overlay goes at full press, 0 to 1. */
134
- opacity?: number;
135
- };
136
- /** One ripple wave. Two of them, so a rapid double tap does not cut the one in flight. */
137
- type RippleWave = {
138
- /** `0 → 1` as the circle opens. */
139
- expand: SharedValue<number>;
140
- /** `0 → 1` as the ink arrives, on its own curve. */
141
- alpha: SharedValue<number>;
142
- /** Where the finger landed, in the root's coordinates. */
143
- origin: SharedValue<{
144
- x: number;
145
- y: number;
146
- }>;
147
- };
148
- /**
149
- * The corner keys an overlay copies off the root. The `Left`/`Right` forms are absent
150
- * rather than forgotten: R13 bans them, because RN mirrors only the logical ones under RTL.
151
- */
152
- type RadiusStyle = Pick<ViewStyle, 'borderRadius' | 'borderStartStartRadius' | 'borderStartEndRadius' | 'borderEndStartRadius' | 'borderEndEndRadius'>;
153
- type FeedbackContext = {
154
- /**
155
- * The overlay's ink, resolved by the root from its own background.
156
- *
157
- * A wash or a wave has to contrast with what it sits on, and only the root knows that —
158
- * it flattens its own `style` and reads `backgroundColor`, then takes the contrasting
159
- * side the same way a tint does. Black ink at 10% on a saturated fill is close to
160
- * invisible, which is the one thing a press indicator cannot be.
161
- */
162
- ink: string;
163
- /**
164
- * The root's own corners, so an overlay rounds itself to match. `corners` and not
165
- * `radius`: the ripple already has a radius, and it is a length in points rather than a
166
- * shape.
167
- *
168
- * An absolute fill has square corners and every control here is rounded, so without this
169
- * both the wash and the wave paint outside the surface at each corner. The overlay
170
- * carries the clip rather than the root: clipping the root would also cut a child that
171
- * legitimately overflows — a badge on a button's corner — and that child has nothing to
172
- * do with the press.
173
- */
174
- corners: RadiusStyle;
175
- isPressed: boolean;
176
- animation: ResolvedAnimation;
177
- /** Absent on the static branch, where nothing animates and no worklet is mounted. */
178
- progress?: SharedValue<number>;
179
- /** How big the root is — what the scale coefficient is computed from. */
180
- size?: SharedValue<{
181
- width: number;
182
- height: number;
183
- }>;
184
- /**
185
- * The two ripple waves, driven by the **root**.
186
- *
187
- * They belong to the root because the root is the touch surface. An overlay carrying its
188
- * own handlers only hears touches that land on *it* — and it is a sibling of the label,
189
- * not its parent, so pressing the text of a button would do nothing. Touches bubble to
190
- * the `Pressable`, which is why the handlers live there and the waves are published down.
191
- */
192
- waves?: readonly [RippleWave, RippleWave];
193
- };
194
-
195
- /**
196
- * A slot is a view or a text node, and a recipe writes one object per slot, so the two
197
- * RN style shapes are merged rather than discriminated per slot.
198
- */
199
- type SlotStyle = ViewStyle & TextStyle;
200
- type SlotStyles<Slot extends string> = Partial<Record<Slot, SlotStyle>>;
201
- /** The roles a variant consumes. The variant names tokens; `paint` says where they land. */
202
- type VariantRole = 'bg' | 'bgPressed' | 'fg' | 'border';
203
- /** Token names per role — no colour value ever appears in a recipe. */
204
- type VariantTokens = Partial<Record<VariantRole, keyof XAUIColors>>;
205
- /** The same roles resolved: theme colours, or the slices of a raw `color`. */
206
- type VariantColors = Partial<Record<VariantRole, string>>;
207
- /**
208
- * `disabled` is applied last of the three: a control that is both pressed and disabled
209
- * has to read disabled.
210
- */
211
- type StateName = 'focused' | 'pressed' | 'disabled';
212
- type States = Partial<Record<StateName, boolean>>;
213
- /** Reads the theme and the variant's resolved colours; returns one style per slot. */
214
- type StyleFn<Slot extends string> = (theme: XAUITheme, colors: VariantColors) => SlotStyles<Slot>;
215
- /** Named axes of finite token values — `{ size: { sm: fn, md: fn } }`. */
216
- type Axes<Slot extends string> = Record<string, Record<string, StyleFn<Slot>>>;
217
- /** One value per axis, plus the variant. Missing keys fall back to `defaultVariants`. */
218
- type Selection<Variant extends string, A extends Axes<string>> = {
219
- variant?: Variant;
220
- } & {
221
- [Axis in keyof A]?: Extract<keyof A[Axis], string>;
222
- };
223
- type CompoundVariant<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
224
- when: Selection<Variant, A>;
225
- style: StyleFn<Slot>;
226
- };
227
- type RecipeConfig<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
228
- /** Every slot the component publishes. Slots a recipe never styles resolve to `{}`. */
229
- slots: readonly Slot[];
230
- base?: StyleFn<Slot>;
231
- variantTokens?: Record<Variant, VariantTokens>;
232
- /** Where the variant's colours land — written once, and it holds for every variant. */
233
- paint?: StyleFn<Slot>;
234
- variants?: A;
235
- compoundVariants?: ReadonlyArray<CompoundVariant<Slot, Variant, A>>;
236
- states?: Partial<Record<StateName, StyleFn<Slot>>>;
237
- /**
238
- * `NoInfer`, because this is the one place a single variant name appears on its own:
239
- * without it, inference reads `Variant` off `{ variant: 'primary' }` and narrows the
240
- * whole recipe to that one value, so every other variant becomes a type error at the
241
- * call site. `variantTokens` is the declaration; this only picks a default from it.
242
- */
243
- defaultVariants?: Selection<NoInfer<Variant>, A>;
244
- };
245
- /** Stable references: the same object for the same tokens, for the app's lifetime. */
246
- type ResolvedStyles<Slot extends string> = Readonly<Record<Slot, SlotStyle>>;
247
- /** A selection with `defaultVariants` already folded in, keyed by axis name. */
248
- type ResolvedSelection = Readonly<Record<string, string | undefined>>;
249
-
250
- type ResolveArgs<Variant extends string, A extends Axes<string>> = {
251
- theme: XAUITheme;
252
- selection?: Selection<Variant, A>;
253
- states?: States;
254
- };
255
- type TintArgs<Variant extends string, A extends Axes<string>> = ResolveArgs<Variant, A> & {
256
- color: string;
257
- };
258
- type Recipe<Slot extends string, Variant extends string, A extends Axes<Slot>> = {
259
- readonly slots: readonly Slot[];
260
- /** The cached pass: stable `StyleSheet` references, keyed by tokens alone. */
261
- resolve(args: ResolveArgs<Variant, A>): ResolvedStyles<Slot>;
262
- /**
263
- * The tint pass: the same functions run again with `color`'s slices in place of the
264
- * theme's tokens. Uncached and allocating, and only ever called when `color` is set.
265
- */
266
- tint(args: TintArgs<Variant, A>): SlotStyles<Slot>;
267
- };
268
- /**
269
- * A component's style, declared once. Resolution splits in two because the two halves
270
- * have different lifetimes: everything keyed by a finite token is cached forever, and
271
- * an arbitrary `color` is recomputed per render — which is what keeps the cache bounded
272
- * by the number of token combinations rather than by the palette users invent.
273
- *
274
- * const styles = buttonRecipe.resolve({ theme, selection: { variant, size }, states })
275
- * const tint = color ? buttonRecipe.tint({ theme, color, selection, states }) : undefined
276
- * <View style={[styles.root, tint?.root, style]} />
277
- */
278
- declare function createRecipe<Slot extends string, Variant extends string, const A extends Axes<Slot>>(config: RecipeConfig<Slot, Variant, A>): Recipe<Slot, Variant, A>;
279
-
280
- export { type AnimationConfig as A, type CompoundVariant as C, type DirectionalStyleKey as D, type FeedbackContext as F, type IconComponentProps as I, type PressableFeedbackProps as P, type RadiusStyle as R, type SlotAnimation as S, type TintArgs as T, type VariantColors as V, type IconContextValue as a, type IconProps as b, type AnimationProp as c, type ResolvedAnimation as d, type RippleWave as e, createRecipe as f, type Recipe as g, type ResolveArgs as h, type Axes as i, type RecipeConfig as j, type ResolvedSelection as k, type ResolvedStyles as l, type Selection as m, type SlotStyle as n, type SlotStyles as o, type StateName as p, type States as q, type StyleFn as r, type VariantRole as s, type VariantTokens as t, type ImageStyleProps as u, type StyleProps as v, type TextStyleProps as w, type ViewStyleProps as x };