@xaui/native 0.9.1-alpha.11 → 0.9.1-alpha.13

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 (31) hide show
  1. package/dist/{chunk-7XGOXTGT.js → chunk-4O3PXFQ7.js} +15 -31
  2. package/dist/{chunk-3QBT3Q65.cjs → chunk-6N5JXRUZ.cjs} +26 -3
  3. package/dist/chunk-B3EAZ2CC.js +1010 -0
  4. package/dist/{chunk-2FEDC7U5.cjs → chunk-DDYMIWLW.cjs} +41 -57
  5. package/dist/chunk-IVVFYUDW.cjs +1044 -0
  6. package/dist/{chunk-6OHFG32Y.cjs → chunk-MLJ543GP.cjs} +41 -53
  7. package/dist/{chunk-NQ5WWF77.js → chunk-RWLODK55.js} +35 -47
  8. package/dist/{chunk-X2K2FX3W.js → chunk-XJARE6SC.js} +24 -1
  9. package/dist/components/button/index.cjs +4 -4
  10. package/dist/components/button/index.d.cts +162 -13
  11. package/dist/components/button/index.d.ts +162 -13
  12. package/dist/components/button/index.js +3 -3
  13. package/dist/{create-recipe-Dn9kj5Rs.d.ts → create-recipe-3OPwcC6P.d.ts} +81 -21
  14. package/dist/{create-recipe-BjSP0zL_.d.cts → create-recipe-oiLAlJ4u.d.cts} +81 -21
  15. package/dist/index.cjs +28 -8
  16. package/dist/index.d.cts +2 -2
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.js +32 -12
  19. package/dist/system/index.cjs +24 -4
  20. package/dist/system/index.d.cts +160 -35
  21. package/dist/system/index.d.ts +160 -35
  22. package/dist/system/index.js +31 -11
  23. package/dist/theme/index.cjs +3 -3
  24. package/dist/theme/index.d.cts +19 -8
  25. package/dist/theme/index.d.ts +19 -8
  26. package/dist/theme/index.js +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-E2UGZJBT.cjs +0 -959
  29. package/dist/chunk-R4HJCQPI.js +0 -889
  30. /package/dist/{chunk-LMUPNKPH.cjs → chunk-2FOEFUPM.cjs} +0 -0
  31. /package/dist/{chunk-3TIDEII6.js → chunk-TO6DAGFB.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
- import { Ref, ReactNode, Provider, RefCallback } from 'react';
3
- import { b as IconProps, a as IconContextValue, S as SlotAnimation, F as FeedbackContext, c as AnimationProp, R as ResolvedAnimation, d as FeedbackVariant } from '../create-recipe-BjSP0zL_.cjs';
4
- export { A as AnimationConfig, h as Axes, C as CompoundVariant, I as IconComponentProps, P as PressableFeedbackProps, f as Recipe, i as RecipeConfig, g as ResolveArgs, j as ResolvedSelection, k as ResolvedStyles, l as Selection, m as SlotStyle, n as SlotStyles, o as StateName, p as States, q as StyleFn, T as TintArgs, V as VariantColors, r as VariantRole, s as VariantTokens, e as createRecipe } from '../create-recipe-BjSP0zL_.cjs';
2
+ import { ReactNode, Ref, Provider, RefCallback } from 'react';
3
+ import { b as IconProps, a as IconContextValue, S as SlotAnimation, F as FeedbackContext, c as AnimationProp, d as ResolvedAnimation } from '../create-recipe-oiLAlJ4u.cjs';
4
+ export { A as AnimationConfig, i as Axes, C as CompoundVariant, D as DirectionalStyleKey, I as IconComponentProps, u as ImageStyleProps, P as PressableFeedbackProps, R as RadiusStyle, g as Recipe, j as RecipeConfig, h as ResolveArgs, k as ResolvedSelection, l as ResolvedStyles, e as RippleWave, m as Selection, n as SlotStyle, o as SlotStyles, p as StateName, q as States, r as StyleFn, v as StyleProps, w as TextStyleProps, T as TintArgs, V as VariantColors, s as VariantRole, t as VariantTokens, x as ViewStyleProps, f as createRecipe } from '../create-recipe-oiLAlJ4u.cjs';
5
5
  import * as react_native from 'react-native';
6
6
  import { StyleProp, ViewStyle } from 'react-native';
7
7
  import 'react-native-reanimated';
@@ -37,8 +37,12 @@ declare function useIconContext(): IconContextValue;
37
37
 
38
38
  type PressableFeedbackHighlightProps = {
39
39
  style?: StyleProp<ViewStyle>;
40
- /** Overrides the blanket `animation` on the root, for this overlay only. */
41
40
  animation?: SlotAnimation;
41
+ /**
42
+ * The content the wash sits under. Optional: `<Highlight />` on its own is an overlay
43
+ * among the root's other children, and the root hoists it so order does not matter.
44
+ */
45
+ children?: ReactNode;
42
46
  };
43
47
  /**
44
48
  * The press wash: one flat overlay fading in under the finger.
@@ -46,33 +50,75 @@ type PressableFeedbackHighlightProps = {
46
50
  * It is a **neutral** wash, not the variant's pressed colour. A component picks one or
47
51
  * the other — this overlay, or a `pressed` state in its recipe swapping `bg` for
48
52
  * `bgPressed` — never both, or a pressed button darkens twice.
53
+ *
54
+ * **Wrapping is the readable form**, and it costs nothing:
55
+ *
56
+ * ```tsx
57
+ * <PressableFeedback style={{ flexDirection: 'row', gap: 8 }}>
58
+ * <PressableFeedback.Highlight>
59
+ * <Icon />
60
+ * <Label />
61
+ * </PressableFeedback.Highlight>
62
+ * </PressableFeedback>
63
+ * ```
64
+ *
65
+ * The children are **not** put inside a box. They are returned as siblings of the wash in
66
+ * a fragment, which has no presence in the host tree — so the root's `flexDirection`,
67
+ * `gap` and `alignItems` still reach the icon and the label directly, and the rendered
68
+ * tree is identical to writing the wash as a bare sibling. A real wrapping `View` would
69
+ * have made the root's layout apply to the wrapper instead, and would have added the depth
70
+ * §8 removed.
49
71
  */
50
- declare function PressableFeedbackHighlight({ style, animation: override, }: PressableFeedbackHighlightProps): react.JSX.Element;
72
+ declare function PressableFeedbackHighlight({ style, animation: override, children, }: PressableFeedbackHighlightProps): react.JSX.Element;
51
73
  declare namespace PressableFeedbackHighlight {
52
74
  var displayName: string;
53
75
  }
54
76
 
55
77
  type PressableFeedbackRippleProps = {
78
+ /** Applies to the wave itself, not to the container that clips it. */
56
79
  style?: StyleProp<ViewStyle>;
57
- /** Overrides the blanket `animation` on the root, for this overlay only. */
58
80
  animation?: SlotAnimation;
81
+ /**
82
+ * The content the wave washes under. Optional: `<Ripple />` on its own is an overlay
83
+ * among the root's other children, and the root hoists it so order does not matter.
84
+ */
85
+ children?: ReactNode;
59
86
  };
60
87
  /**
61
88
  * A circle washing outwards from where the finger landed.
62
89
  *
63
- * **Two animations, not one, and that is the whole shape of it.** The circle *expands*
64
- * once per touch, from the point of contact to past the far corner. Its *opacity* follows
65
- * the finger — up on press, held while the press lasts, out on release. Driving both from
66
- * one curve is what makes a ripple read wrong: tie opacity to the expansion and the wave
67
- * is invisible under the finger and brightest once it covers everything, which is a flash
68
- * of the whole control rather than a wave leaving the touch point.
90
+ * **The root drives it, this only draws it.** The root is the touch surface: touches on a
91
+ * component's own children a button's label bubble up to the `Pressable`, and never to
92
+ * this overlay, which is their sibling rather than their parent. An overlay owning the
93
+ * handlers works on the padding and does nothing on the text, which is the kind of bug that
94
+ * looks like a rendering problem.
95
+ *
96
+ * Its ink and its corners come from the root, which reads both off its own style — only
97
+ * the root knows what the wave sits on, or what shape it has to stay inside.
98
+ *
99
+ * **Wrapping is the readable form**, and it costs nothing:
100
+ *
101
+ * ```tsx
102
+ * <PressableFeedback style={{ flexDirection: 'row', gap: 8 }}>
103
+ * <PressableFeedback.Ripple>
104
+ * <Icon />
105
+ * <Label />
106
+ * </PressableFeedback.Ripple>
107
+ * </PressableFeedback>
108
+ * ```
109
+ *
110
+ * The children are **not** put inside a box. They come back as siblings of the wave's
111
+ * container in a fragment, which has no presence in the host tree — so the root's
112
+ * `flexDirection`, `gap` and `alignItems` still reach the icon and the label directly, and
113
+ * the rendered tree is identical to writing the wave as a bare sibling. Written on its own,
114
+ * `<Ripple />` is that bare sibling, and the root hoists it so order does not matter.
69
115
  *
70
- * It needs the root to clip `PressableFeedback` sets `overflow: 'hidden'` when it
71
- * mounts one and it renders nothing on the static branch: a ripple that cannot expand
72
- * is a coloured disc sitting on the control, which reads as a defect rather than as
73
- * reduced motion.
116
+ * The motion is Material's `InkRipple`, and the parts that matter are the ones that are not
117
+ * obvious: the ink is **independent of the expansion**, the circle **starts at 30%** of its
118
+ * target rather than at a point, the target is **half the diagonal**, and the centre
119
+ * **travels** from the finger to the middle of the control. The constants carry the why.
74
120
  */
75
- declare function PressableFeedbackRipple({ style, animation: override, }: PressableFeedbackRippleProps): react.JSX.Element | null;
121
+ declare function PressableFeedbackRipple({ style, animation: override, children, }: PressableFeedbackRippleProps): react.JSX.Element;
76
122
  declare namespace PressableFeedbackRipple {
77
123
  var displayName: string;
78
124
  }
@@ -80,24 +126,66 @@ declare namespace PressableFeedbackRipple {
80
126
  declare const useFeedback: () => FeedbackContext;
81
127
 
82
128
  /**
83
- * The values the v0 tree shipped with (`Animated.spring` to `0.975`, `bounciness: 0`,
84
- * over roughly 100ms). Kept identical on purpose: the touch feedback is the part of a
85
- * library users feel rather than read, and changing its timing in a rewrite would be a
86
- * regression nobody asked for. `bounciness: 0` is why a duration replaces the spring
87
- * a spring with no bounce is a curve.
129
+ * What marks a component as a press overlay.
130
+ *
131
+ * `Symbol.for` rather than a boolean field or an identity check against our own two
132
+ * components: the registry is global, so two copies of `@xaui/native` in one tree still
133
+ * agree on what an overlay is, and a third party writing their own overlay — anything that
134
+ * reads `useFeedback()` and paints under the content — opts into the same treatment
135
+ * instead of being a second-class citizen.
88
136
  */
89
- declare const PRESS_SCALE = 0.975;
90
- declare const PRESS_DURATION = 100;
91
- declare const RELEASE_DURATION = 150;
92
- /** How far the wash and the ripple go at full press. */
93
- declare const HIGHLIGHT_OPACITY = 0.08;
94
- declare const RIPPLE_OPACITY = 0.12;
95
- declare const RIPPLE_DURATION = 350;
137
+ declare const FEEDBACK_OVERLAY: unique symbol;
138
+ /** Tags a component so `PressableFeedback` paints it under its content. */
139
+ declare function markOverlay<T extends object>(component: T): T;
140
+
96
141
  /**
97
- * The circle's radius as a multiple of the control's diagonal. Above 1 it covers from
98
- * any point on the control, so where the finger landed never enters the calculation.
142
+ * How far a control shrinks under the finger **before** the width coefficient below.
143
+ *
144
+ * The v0 tree shrank everything to a flat `0.975`, which is why a wide button read as
145
+ * lurching: a ratio applied to a 360pt row moves nine points, and the same ratio on a
146
+ * 96pt chip moves two. What the eye reads is the displacement, not the ratio.
99
147
  */
100
- declare const RIPPLE_COVERAGE = 1.25;
148
+ declare const PRESS_SCALE = 0.985;
149
+ declare const PRESS_DURATION = 300;
150
+ /**
151
+ * The width at which `PRESS_SCALE` is applied as written. Wider controls shrink
152
+ * proportionally less, narrower ones more, so the movement stays roughly constant in
153
+ * points across a 96pt chip and a full-width button.
154
+ */
155
+ declare const SCALE_REFERENCE_WIDTH = 300;
156
+ /** The scale a control of `width` should reach when pressed. */
157
+ declare function pressScaleFor(width: number): number;
158
+ /** How far the wash goes at full press, and how long it takes to get there. */
159
+ declare const HIGHLIGHT_OPACITY = 0.1;
160
+ declare const HIGHLIGHT_DURATION = 200;
161
+ /**
162
+ * The ripple, taken from Material's reference implementation (`InkRipple`) rather than
163
+ * approximated. Four of its numbers are load-bearing and none of them is obvious:
164
+ *
165
+ * - **The opacity is not tied to the expansion.** It reaches full ink in 75ms and stays
166
+ * there while the circle keeps growing. Tying the two — the obvious thing to write —
167
+ * means the ink is faintest exactly when the circle is small enough to be read as a
168
+ * circle, which is why such a ripple looks like nothing at all.
169
+ * - **The circle starts at 30% of its target**, not at a point. A wave from a dot spends
170
+ * its visible life too small to see.
171
+ * - **The target radius is half the diagonal**, which is what covers the box. Larger and
172
+ * the edge leaves the control before the eye catches it, so the effect reads as the
173
+ * surface tinting rather than as something spreading.
174
+ * - **The centre travels** from the finger to the middle of the control as it opens, which
175
+ * is what makes it settle into the control instead of flooding out of a corner.
176
+ *
177
+ * The expansion runs a full second while the finger is down, and finishes in 225ms once it
178
+ * lifts — the wave catches up rather than being cut.
179
+ */
180
+ declare const RIPPLE_OPACITY = 0.1;
181
+ declare const RIPPLE_START_SCALE = 0.3;
182
+ declare const RIPPLE_EXPAND_DURATION = 1000;
183
+ declare const RIPPLE_CONFIRM_DURATION = 225;
184
+ declare const RIPPLE_FADE_IN = 75;
185
+ declare const RIPPLE_FADE_OUT_DELAY = 225;
186
+ declare const RIPPLE_FADE_OUT = 150;
187
+ /** Half the diagonal covers the box from its centre; the 5 is Material's own overshoot. */
188
+ declare function rippleRadiusFor(width: number, height: number): number;
101
189
  /**
102
190
  * One shape out of four accepted ones, so the components read a record instead of
103
191
  * re-deciding what `'disable-all'` meant.
@@ -118,11 +206,16 @@ type ResolvedSlotAnimation = {
118
206
  */
119
207
  declare function resolveSlotAnimation(override: SlotAnimation | undefined, enabledByRoot: boolean, defaultOpacity: number, defaultDuration?: number): ResolvedSlotAnimation;
120
208
 
121
- declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "style" | "children" | "disabled"> & {
209
+ /**
210
+ * The root scales; what else happens under the finger is **composed**, not named by a
211
+ * prop. An overlay a caller can reach is an overlay a caller can place, style and switch
212
+ * off — and it is the only shape that survives `asChild`, where the caller's own element
213
+ * is the pressable and there is no sibling for the primitive to inject.
214
+ */
215
+ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "children" | "style" | "disabled"> & {
122
216
  isPressed?: boolean;
123
217
  isDisabled?: boolean;
124
218
  asChild?: boolean;
125
- feedbackVariant?: FeedbackVariant;
126
219
  animation?: AnimationProp;
127
220
  style?: react_native.StyleProp<react_native.ViewStyle>;
128
221
  children?: react.ReactNode;
@@ -131,6 +224,38 @@ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_nati
131
224
  Ripple: typeof PressableFeedbackRipple;
132
225
  };
133
226
 
227
+ /**
228
+ * The runtime half of R14. The type half lives in `system/style-props/`, and the two are
229
+ * pinned to each other by a compile-time check there: a React Native upgrade that adds or
230
+ * removes a style key fails `type-check` with the key's name rather than drifting.
231
+ *
232
+ * One set for the three style types rather than one per node. A caller cannot write
233
+ * `fontSize` on a view slot — that slot's props are typed `ViewStyleProps` — so the split
234
+ * never has to know which node it runs for, and every component shares one table.
235
+ */
236
+ declare const STYLE_PROP_KEYS: readonly ["alignContent", "alignItems", "alignSelf", "aspectRatio", "boxSizing", "columnGap", "direction", "display", "flex", "flexBasis", "flexDirection", "flexGrow", "flexShrink", "flexWrap", "gap", "justifyContent", "overflow", "rowGap", "bottom", "end", "inset", "insetBlock", "insetBlockEnd", "insetBlockStart", "insetInline", "insetInlineEnd", "insetInlineStart", "position", "start", "top", "zIndex", "margin", "marginBlock", "marginBlockEnd", "marginBlockStart", "marginBottom", "marginEnd", "marginHorizontal", "marginInline", "marginInlineEnd", "marginInlineStart", "marginStart", "marginTop", "marginVertical", "padding", "paddingBlock", "paddingBlockEnd", "paddingBlockStart", "paddingBottom", "paddingEnd", "paddingHorizontal", "paddingInline", "paddingInlineEnd", "paddingInlineStart", "paddingStart", "paddingTop", "paddingVertical", "height", "maxHeight", "maxWidth", "minHeight", "minWidth", "width", "borderBlockColor", "borderBlockEndColor", "borderBlockStartColor", "borderBottomColor", "borderBottomEndRadius", "borderBottomStartRadius", "borderBottomWidth", "borderColor", "borderCurve", "borderEndColor", "borderEndEndRadius", "borderEndStartRadius", "borderEndWidth", "borderRadius", "borderStartColor", "borderStartEndRadius", "borderStartStartRadius", "borderStartWidth", "borderStyle", "borderTopColor", "borderTopEndRadius", "borderTopStartRadius", "borderTopWidth", "borderWidth", "backfaceVisibility", "backgroundColor", "boxShadow", "cursor", "elevation", "experimental_backgroundImage", "filter", "isolation", "mixBlendMode", "opacity", "outlineColor", "outlineOffset", "outlineStyle", "outlineWidth", "shadowColor", "shadowOffset", "shadowOpacity", "shadowRadius", "rotation", "scaleX", "scaleY", "transform", "transformMatrix", "transformOrigin", "translateX", "translateY", "color", "fontFamily", "fontSize", "fontStyle", "fontVariant", "fontWeight", "includeFontPadding", "letterSpacing", "lineHeight", "textAlign", "textAlignVertical", "textDecorationColor", "textDecorationLine", "textDecorationStyle", "textShadowColor", "textShadowOffset", "textShadowRadius", "textTransform", "userSelect", "verticalAlign", "writingDirection", "objectFit", "overlayColor", "resizeMode", "tintColor"];
237
+ type StylePropKey = (typeof STYLE_PROP_KEYS)[number];
238
+ /** What `splitStyleProps` takes out of a props object. */
239
+ type StylePropsOf<P> = Pick<P, Extract<keyof P, StylePropKey>>;
240
+ /** What it leaves in it. */
241
+ type RestPropsOf<P> = Omit<P, StylePropKey>;
242
+
243
+ /**
244
+ * `splitStyleProps`, memoized on the values (R14). A component calls it on what is left
245
+ * after destructuring its own props, applies the style half between the tint and its
246
+ * `style`, and forwards the rest:
247
+ *
248
+ * ```tsx
249
+ * const [styleProps, rest] = useStyleProps(props)
250
+ * <Pressable style={[styles.root, tint, styleProps, style]} {...rest} />
251
+ * ```
252
+ *
253
+ * The identity is stable while the values are, which is what a memoized child or an
254
+ * animated style depends on. It is keyed on a hash rather than on the object, because the
255
+ * object is a fresh rest-spread on every render and would never hit.
256
+ */
257
+ declare function useStyleProps<P extends object>(props: P): [StylePropsOf<P>, RestPropsOf<P>];
258
+
134
259
  /** Anything React accepts as a ref, plus the absence of one. */
135
260
  type PossibleRef<T> = Ref<T> | undefined;
136
261
  /**
@@ -262,4 +387,4 @@ type SlotProps = MergeableProps & {
262
387
  */
263
388
  declare const Slot: react.ForwardRefExoticComponent<Omit<SlotProps, "ref"> & react.RefAttributes<unknown>>;
264
389
 
265
- export { AnimationProp, type AsChildProps, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, Icon, IconContext, IconContextValue, IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, ResolvedAnimation, Slot, SlotAnimation, type SlotProps, childrenToString, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext };
390
+ export { AnimationProp, type AsChildProps, FEEDBACK_OVERLAY, FeedbackContext, HIGHLIGHT_DURATION, HIGHLIGHT_OPACITY, Icon, IconContext, IconContextValue, IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackRippleProps, RIPPLE_CONFIRM_DURATION, RIPPLE_EXPAND_DURATION, RIPPLE_FADE_IN, RIPPLE_FADE_OUT, RIPPLE_FADE_OUT_DELAY, RIPPLE_OPACITY, RIPPLE_START_SCALE, ResolvedAnimation, SCALE_REFERENCE_WIDTH, Slot, SlotAnimation, type SlotProps, childrenToString, createSlotContext, markOverlay, mergeProps, mergeRefs, pressScaleFor, resolveAnimation, resolveSlotAnimation, rippleRadiusFor, useFeedback, useIconContext, useStyleProps };
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
- import { Ref, ReactNode, Provider, RefCallback } from 'react';
3
- import { b as IconProps, a as IconContextValue, S as SlotAnimation, F as FeedbackContext, c as AnimationProp, R as ResolvedAnimation, d as FeedbackVariant } from '../create-recipe-Dn9kj5Rs.js';
4
- export { A as AnimationConfig, h as Axes, C as CompoundVariant, I as IconComponentProps, P as PressableFeedbackProps, f as Recipe, i as RecipeConfig, g as ResolveArgs, j as ResolvedSelection, k as ResolvedStyles, l as Selection, m as SlotStyle, n as SlotStyles, o as StateName, p as States, q as StyleFn, T as TintArgs, V as VariantColors, r as VariantRole, s as VariantTokens, e as createRecipe } from '../create-recipe-Dn9kj5Rs.js';
2
+ import { ReactNode, Ref, Provider, RefCallback } from 'react';
3
+ import { b as IconProps, a as IconContextValue, S as SlotAnimation, F as FeedbackContext, c as AnimationProp, d as ResolvedAnimation } from '../create-recipe-3OPwcC6P.js';
4
+ export { A as AnimationConfig, i as Axes, C as CompoundVariant, D as DirectionalStyleKey, I as IconComponentProps, u as ImageStyleProps, P as PressableFeedbackProps, R as RadiusStyle, g as Recipe, j as RecipeConfig, h as ResolveArgs, k as ResolvedSelection, l as ResolvedStyles, e as RippleWave, m as Selection, n as SlotStyle, o as SlotStyles, p as StateName, q as States, r as StyleFn, v as StyleProps, w as TextStyleProps, T as TintArgs, V as VariantColors, s as VariantRole, t as VariantTokens, x as ViewStyleProps, f as createRecipe } from '../create-recipe-3OPwcC6P.js';
5
5
  import * as react_native from 'react-native';
6
6
  import { StyleProp, ViewStyle } from 'react-native';
7
7
  import 'react-native-reanimated';
@@ -37,8 +37,12 @@ declare function useIconContext(): IconContextValue;
37
37
 
38
38
  type PressableFeedbackHighlightProps = {
39
39
  style?: StyleProp<ViewStyle>;
40
- /** Overrides the blanket `animation` on the root, for this overlay only. */
41
40
  animation?: SlotAnimation;
41
+ /**
42
+ * The content the wash sits under. Optional: `<Highlight />` on its own is an overlay
43
+ * among the root's other children, and the root hoists it so order does not matter.
44
+ */
45
+ children?: ReactNode;
42
46
  };
43
47
  /**
44
48
  * The press wash: one flat overlay fading in under the finger.
@@ -46,33 +50,75 @@ type PressableFeedbackHighlightProps = {
46
50
  * It is a **neutral** wash, not the variant's pressed colour. A component picks one or
47
51
  * the other — this overlay, or a `pressed` state in its recipe swapping `bg` for
48
52
  * `bgPressed` — never both, or a pressed button darkens twice.
53
+ *
54
+ * **Wrapping is the readable form**, and it costs nothing:
55
+ *
56
+ * ```tsx
57
+ * <PressableFeedback style={{ flexDirection: 'row', gap: 8 }}>
58
+ * <PressableFeedback.Highlight>
59
+ * <Icon />
60
+ * <Label />
61
+ * </PressableFeedback.Highlight>
62
+ * </PressableFeedback>
63
+ * ```
64
+ *
65
+ * The children are **not** put inside a box. They are returned as siblings of the wash in
66
+ * a fragment, which has no presence in the host tree — so the root's `flexDirection`,
67
+ * `gap` and `alignItems` still reach the icon and the label directly, and the rendered
68
+ * tree is identical to writing the wash as a bare sibling. A real wrapping `View` would
69
+ * have made the root's layout apply to the wrapper instead, and would have added the depth
70
+ * §8 removed.
49
71
  */
50
- declare function PressableFeedbackHighlight({ style, animation: override, }: PressableFeedbackHighlightProps): react.JSX.Element;
72
+ declare function PressableFeedbackHighlight({ style, animation: override, children, }: PressableFeedbackHighlightProps): react.JSX.Element;
51
73
  declare namespace PressableFeedbackHighlight {
52
74
  var displayName: string;
53
75
  }
54
76
 
55
77
  type PressableFeedbackRippleProps = {
78
+ /** Applies to the wave itself, not to the container that clips it. */
56
79
  style?: StyleProp<ViewStyle>;
57
- /** Overrides the blanket `animation` on the root, for this overlay only. */
58
80
  animation?: SlotAnimation;
81
+ /**
82
+ * The content the wave washes under. Optional: `<Ripple />` on its own is an overlay
83
+ * among the root's other children, and the root hoists it so order does not matter.
84
+ */
85
+ children?: ReactNode;
59
86
  };
60
87
  /**
61
88
  * A circle washing outwards from where the finger landed.
62
89
  *
63
- * **Two animations, not one, and that is the whole shape of it.** The circle *expands*
64
- * once per touch, from the point of contact to past the far corner. Its *opacity* follows
65
- * the finger — up on press, held while the press lasts, out on release. Driving both from
66
- * one curve is what makes a ripple read wrong: tie opacity to the expansion and the wave
67
- * is invisible under the finger and brightest once it covers everything, which is a flash
68
- * of the whole control rather than a wave leaving the touch point.
90
+ * **The root drives it, this only draws it.** The root is the touch surface: touches on a
91
+ * component's own children a button's label bubble up to the `Pressable`, and never to
92
+ * this overlay, which is their sibling rather than their parent. An overlay owning the
93
+ * handlers works on the padding and does nothing on the text, which is the kind of bug that
94
+ * looks like a rendering problem.
95
+ *
96
+ * Its ink and its corners come from the root, which reads both off its own style — only
97
+ * the root knows what the wave sits on, or what shape it has to stay inside.
98
+ *
99
+ * **Wrapping is the readable form**, and it costs nothing:
100
+ *
101
+ * ```tsx
102
+ * <PressableFeedback style={{ flexDirection: 'row', gap: 8 }}>
103
+ * <PressableFeedback.Ripple>
104
+ * <Icon />
105
+ * <Label />
106
+ * </PressableFeedback.Ripple>
107
+ * </PressableFeedback>
108
+ * ```
109
+ *
110
+ * The children are **not** put inside a box. They come back as siblings of the wave's
111
+ * container in a fragment, which has no presence in the host tree — so the root's
112
+ * `flexDirection`, `gap` and `alignItems` still reach the icon and the label directly, and
113
+ * the rendered tree is identical to writing the wave as a bare sibling. Written on its own,
114
+ * `<Ripple />` is that bare sibling, and the root hoists it so order does not matter.
69
115
  *
70
- * It needs the root to clip `PressableFeedback` sets `overflow: 'hidden'` when it
71
- * mounts one and it renders nothing on the static branch: a ripple that cannot expand
72
- * is a coloured disc sitting on the control, which reads as a defect rather than as
73
- * reduced motion.
116
+ * The motion is Material's `InkRipple`, and the parts that matter are the ones that are not
117
+ * obvious: the ink is **independent of the expansion**, the circle **starts at 30%** of its
118
+ * target rather than at a point, the target is **half the diagonal**, and the centre
119
+ * **travels** from the finger to the middle of the control. The constants carry the why.
74
120
  */
75
- declare function PressableFeedbackRipple({ style, animation: override, }: PressableFeedbackRippleProps): react.JSX.Element | null;
121
+ declare function PressableFeedbackRipple({ style, animation: override, children, }: PressableFeedbackRippleProps): react.JSX.Element;
76
122
  declare namespace PressableFeedbackRipple {
77
123
  var displayName: string;
78
124
  }
@@ -80,24 +126,66 @@ declare namespace PressableFeedbackRipple {
80
126
  declare const useFeedback: () => FeedbackContext;
81
127
 
82
128
  /**
83
- * The values the v0 tree shipped with (`Animated.spring` to `0.975`, `bounciness: 0`,
84
- * over roughly 100ms). Kept identical on purpose: the touch feedback is the part of a
85
- * library users feel rather than read, and changing its timing in a rewrite would be a
86
- * regression nobody asked for. `bounciness: 0` is why a duration replaces the spring
87
- * a spring with no bounce is a curve.
129
+ * What marks a component as a press overlay.
130
+ *
131
+ * `Symbol.for` rather than a boolean field or an identity check against our own two
132
+ * components: the registry is global, so two copies of `@xaui/native` in one tree still
133
+ * agree on what an overlay is, and a third party writing their own overlay — anything that
134
+ * reads `useFeedback()` and paints under the content — opts into the same treatment
135
+ * instead of being a second-class citizen.
88
136
  */
89
- declare const PRESS_SCALE = 0.975;
90
- declare const PRESS_DURATION = 100;
91
- declare const RELEASE_DURATION = 150;
92
- /** How far the wash and the ripple go at full press. */
93
- declare const HIGHLIGHT_OPACITY = 0.08;
94
- declare const RIPPLE_OPACITY = 0.12;
95
- declare const RIPPLE_DURATION = 350;
137
+ declare const FEEDBACK_OVERLAY: unique symbol;
138
+ /** Tags a component so `PressableFeedback` paints it under its content. */
139
+ declare function markOverlay<T extends object>(component: T): T;
140
+
96
141
  /**
97
- * The circle's radius as a multiple of the control's diagonal. Above 1 it covers from
98
- * any point on the control, so where the finger landed never enters the calculation.
142
+ * How far a control shrinks under the finger **before** the width coefficient below.
143
+ *
144
+ * The v0 tree shrank everything to a flat `0.975`, which is why a wide button read as
145
+ * lurching: a ratio applied to a 360pt row moves nine points, and the same ratio on a
146
+ * 96pt chip moves two. What the eye reads is the displacement, not the ratio.
99
147
  */
100
- declare const RIPPLE_COVERAGE = 1.25;
148
+ declare const PRESS_SCALE = 0.985;
149
+ declare const PRESS_DURATION = 300;
150
+ /**
151
+ * The width at which `PRESS_SCALE` is applied as written. Wider controls shrink
152
+ * proportionally less, narrower ones more, so the movement stays roughly constant in
153
+ * points across a 96pt chip and a full-width button.
154
+ */
155
+ declare const SCALE_REFERENCE_WIDTH = 300;
156
+ /** The scale a control of `width` should reach when pressed. */
157
+ declare function pressScaleFor(width: number): number;
158
+ /** How far the wash goes at full press, and how long it takes to get there. */
159
+ declare const HIGHLIGHT_OPACITY = 0.1;
160
+ declare const HIGHLIGHT_DURATION = 200;
161
+ /**
162
+ * The ripple, taken from Material's reference implementation (`InkRipple`) rather than
163
+ * approximated. Four of its numbers are load-bearing and none of them is obvious:
164
+ *
165
+ * - **The opacity is not tied to the expansion.** It reaches full ink in 75ms and stays
166
+ * there while the circle keeps growing. Tying the two — the obvious thing to write —
167
+ * means the ink is faintest exactly when the circle is small enough to be read as a
168
+ * circle, which is why such a ripple looks like nothing at all.
169
+ * - **The circle starts at 30% of its target**, not at a point. A wave from a dot spends
170
+ * its visible life too small to see.
171
+ * - **The target radius is half the diagonal**, which is what covers the box. Larger and
172
+ * the edge leaves the control before the eye catches it, so the effect reads as the
173
+ * surface tinting rather than as something spreading.
174
+ * - **The centre travels** from the finger to the middle of the control as it opens, which
175
+ * is what makes it settle into the control instead of flooding out of a corner.
176
+ *
177
+ * The expansion runs a full second while the finger is down, and finishes in 225ms once it
178
+ * lifts — the wave catches up rather than being cut.
179
+ */
180
+ declare const RIPPLE_OPACITY = 0.1;
181
+ declare const RIPPLE_START_SCALE = 0.3;
182
+ declare const RIPPLE_EXPAND_DURATION = 1000;
183
+ declare const RIPPLE_CONFIRM_DURATION = 225;
184
+ declare const RIPPLE_FADE_IN = 75;
185
+ declare const RIPPLE_FADE_OUT_DELAY = 225;
186
+ declare const RIPPLE_FADE_OUT = 150;
187
+ /** Half the diagonal covers the box from its centre; the 5 is Material's own overshoot. */
188
+ declare function rippleRadiusFor(width: number, height: number): number;
101
189
  /**
102
190
  * One shape out of four accepted ones, so the components read a record instead of
103
191
  * re-deciding what `'disable-all'` meant.
@@ -118,11 +206,16 @@ type ResolvedSlotAnimation = {
118
206
  */
119
207
  declare function resolveSlotAnimation(override: SlotAnimation | undefined, enabledByRoot: boolean, defaultOpacity: number, defaultDuration?: number): ResolvedSlotAnimation;
120
208
 
121
- declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "style" | "children" | "disabled"> & {
209
+ /**
210
+ * The root scales; what else happens under the finger is **composed**, not named by a
211
+ * prop. An overlay a caller can reach is an overlay a caller can place, style and switch
212
+ * off — and it is the only shape that survives `asChild`, where the caller's own element
213
+ * is the pressable and there is no sibling for the primitive to inject.
214
+ */
215
+ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "children" | "style" | "disabled"> & {
122
216
  isPressed?: boolean;
123
217
  isDisabled?: boolean;
124
218
  asChild?: boolean;
125
- feedbackVariant?: FeedbackVariant;
126
219
  animation?: AnimationProp;
127
220
  style?: react_native.StyleProp<react_native.ViewStyle>;
128
221
  children?: react.ReactNode;
@@ -131,6 +224,38 @@ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_nati
131
224
  Ripple: typeof PressableFeedbackRipple;
132
225
  };
133
226
 
227
+ /**
228
+ * The runtime half of R14. The type half lives in `system/style-props/`, and the two are
229
+ * pinned to each other by a compile-time check there: a React Native upgrade that adds or
230
+ * removes a style key fails `type-check` with the key's name rather than drifting.
231
+ *
232
+ * One set for the three style types rather than one per node. A caller cannot write
233
+ * `fontSize` on a view slot — that slot's props are typed `ViewStyleProps` — so the split
234
+ * never has to know which node it runs for, and every component shares one table.
235
+ */
236
+ declare const STYLE_PROP_KEYS: readonly ["alignContent", "alignItems", "alignSelf", "aspectRatio", "boxSizing", "columnGap", "direction", "display", "flex", "flexBasis", "flexDirection", "flexGrow", "flexShrink", "flexWrap", "gap", "justifyContent", "overflow", "rowGap", "bottom", "end", "inset", "insetBlock", "insetBlockEnd", "insetBlockStart", "insetInline", "insetInlineEnd", "insetInlineStart", "position", "start", "top", "zIndex", "margin", "marginBlock", "marginBlockEnd", "marginBlockStart", "marginBottom", "marginEnd", "marginHorizontal", "marginInline", "marginInlineEnd", "marginInlineStart", "marginStart", "marginTop", "marginVertical", "padding", "paddingBlock", "paddingBlockEnd", "paddingBlockStart", "paddingBottom", "paddingEnd", "paddingHorizontal", "paddingInline", "paddingInlineEnd", "paddingInlineStart", "paddingStart", "paddingTop", "paddingVertical", "height", "maxHeight", "maxWidth", "minHeight", "minWidth", "width", "borderBlockColor", "borderBlockEndColor", "borderBlockStartColor", "borderBottomColor", "borderBottomEndRadius", "borderBottomStartRadius", "borderBottomWidth", "borderColor", "borderCurve", "borderEndColor", "borderEndEndRadius", "borderEndStartRadius", "borderEndWidth", "borderRadius", "borderStartColor", "borderStartEndRadius", "borderStartStartRadius", "borderStartWidth", "borderStyle", "borderTopColor", "borderTopEndRadius", "borderTopStartRadius", "borderTopWidth", "borderWidth", "backfaceVisibility", "backgroundColor", "boxShadow", "cursor", "elevation", "experimental_backgroundImage", "filter", "isolation", "mixBlendMode", "opacity", "outlineColor", "outlineOffset", "outlineStyle", "outlineWidth", "shadowColor", "shadowOffset", "shadowOpacity", "shadowRadius", "rotation", "scaleX", "scaleY", "transform", "transformMatrix", "transformOrigin", "translateX", "translateY", "color", "fontFamily", "fontSize", "fontStyle", "fontVariant", "fontWeight", "includeFontPadding", "letterSpacing", "lineHeight", "textAlign", "textAlignVertical", "textDecorationColor", "textDecorationLine", "textDecorationStyle", "textShadowColor", "textShadowOffset", "textShadowRadius", "textTransform", "userSelect", "verticalAlign", "writingDirection", "objectFit", "overlayColor", "resizeMode", "tintColor"];
237
+ type StylePropKey = (typeof STYLE_PROP_KEYS)[number];
238
+ /** What `splitStyleProps` takes out of a props object. */
239
+ type StylePropsOf<P> = Pick<P, Extract<keyof P, StylePropKey>>;
240
+ /** What it leaves in it. */
241
+ type RestPropsOf<P> = Omit<P, StylePropKey>;
242
+
243
+ /**
244
+ * `splitStyleProps`, memoized on the values (R14). A component calls it on what is left
245
+ * after destructuring its own props, applies the style half between the tint and its
246
+ * `style`, and forwards the rest:
247
+ *
248
+ * ```tsx
249
+ * const [styleProps, rest] = useStyleProps(props)
250
+ * <Pressable style={[styles.root, tint, styleProps, style]} {...rest} />
251
+ * ```
252
+ *
253
+ * The identity is stable while the values are, which is what a memoized child or an
254
+ * animated style depends on. It is keyed on a hash rather than on the object, because the
255
+ * object is a fresh rest-spread on every render and would never hit.
256
+ */
257
+ declare function useStyleProps<P extends object>(props: P): [StylePropsOf<P>, RestPropsOf<P>];
258
+
134
259
  /** Anything React accepts as a ref, plus the absence of one. */
135
260
  type PossibleRef<T> = Ref<T> | undefined;
136
261
  /**
@@ -262,4 +387,4 @@ type SlotProps = MergeableProps & {
262
387
  */
263
388
  declare const Slot: react.ForwardRefExoticComponent<Omit<SlotProps, "ref"> & react.RefAttributes<unknown>>;
264
389
 
265
- export { AnimationProp, type AsChildProps, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, Icon, IconContext, IconContextValue, IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, ResolvedAnimation, Slot, SlotAnimation, type SlotProps, childrenToString, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext };
390
+ export { AnimationProp, type AsChildProps, FEEDBACK_OVERLAY, FeedbackContext, HIGHLIGHT_DURATION, HIGHLIGHT_OPACITY, Icon, IconContext, IconContextValue, IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackRippleProps, RIPPLE_CONFIRM_DURATION, RIPPLE_EXPAND_DURATION, RIPPLE_FADE_IN, RIPPLE_FADE_OUT, RIPPLE_FADE_OUT_DELAY, RIPPLE_OPACITY, RIPPLE_START_SCALE, ResolvedAnimation, SCALE_REFERENCE_WIDTH, Slot, SlotAnimation, type SlotProps, childrenToString, createSlotContext, markOverlay, mergeProps, mergeRefs, pressScaleFor, resolveAnimation, resolveSlotAnimation, rippleRadiusFor, useFeedback, useIconContext, useStyleProps };
@@ -2,31 +2,43 @@ import {
2
2
  Portal,
3
3
  PortalContext,
4
4
  PortalHost
5
- } from "../chunk-3TIDEII6.js";
5
+ } from "../chunk-TO6DAGFB.js";
6
6
  import {
7
+ FEEDBACK_OVERLAY,
8
+ HIGHLIGHT_DURATION,
7
9
  HIGHLIGHT_OPACITY,
8
10
  Icon,
9
11
  IconContext,
10
12
  PRESS_DURATION,
11
13
  PRESS_SCALE,
12
14
  PressableFeedback,
13
- RELEASE_DURATION,
14
- RIPPLE_COVERAGE,
15
- RIPPLE_DURATION,
15
+ RIPPLE_CONFIRM_DURATION,
16
+ RIPPLE_EXPAND_DURATION,
17
+ RIPPLE_FADE_IN,
18
+ RIPPLE_FADE_OUT,
19
+ RIPPLE_FADE_OUT_DELAY,
16
20
  RIPPLE_OPACITY,
21
+ RIPPLE_START_SCALE,
22
+ SCALE_REFERENCE_WIDTH,
17
23
  Slot,
18
24
  childrenToString,
19
25
  createRecipe,
20
26
  createSlotContext,
27
+ markOverlay,
21
28
  mergeProps,
22
29
  mergeRefs,
30
+ pressScaleFor,
23
31
  resolveAnimation,
24
32
  resolveSlotAnimation,
33
+ rippleRadiusFor,
25
34
  useFeedback,
26
- useIconContext
27
- } from "../chunk-R4HJCQPI.js";
28
- import "../chunk-X2K2FX3W.js";
35
+ useIconContext,
36
+ useStyleProps
37
+ } from "../chunk-B3EAZ2CC.js";
38
+ import "../chunk-XJARE6SC.js";
29
39
  export {
40
+ FEEDBACK_OVERLAY,
41
+ HIGHLIGHT_DURATION,
30
42
  HIGHLIGHT_OPACITY,
31
43
  Icon,
32
44
  IconContext,
@@ -36,18 +48,26 @@ export {
36
48
  PortalContext,
37
49
  PortalHost,
38
50
  PressableFeedback,
39
- RELEASE_DURATION,
40
- RIPPLE_COVERAGE,
41
- RIPPLE_DURATION,
51
+ RIPPLE_CONFIRM_DURATION,
52
+ RIPPLE_EXPAND_DURATION,
53
+ RIPPLE_FADE_IN,
54
+ RIPPLE_FADE_OUT,
55
+ RIPPLE_FADE_OUT_DELAY,
42
56
  RIPPLE_OPACITY,
57
+ RIPPLE_START_SCALE,
58
+ SCALE_REFERENCE_WIDTH,
43
59
  Slot,
44
60
  childrenToString,
45
61
  createRecipe,
46
62
  createSlotContext,
63
+ markOverlay,
47
64
  mergeProps,
48
65
  mergeRefs,
66
+ pressScaleFor,
49
67
  resolveAnimation,
50
68
  resolveSlotAnimation,
69
+ rippleRadiusFor,
51
70
  useFeedback,
52
- useIconContext
71
+ useIconContext,
72
+ useStyleProps
53
73
  };