@xaui/native 0.9.1-alpha.3 → 0.9.1-alpha.5

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.
@@ -3,8 +3,109 @@ import {
3
3
  useXAUITheme
4
4
  } from "./chunk-X2K2FX3W.js";
5
5
 
6
+ // src/system/icon/icon.tsx
7
+ import { cloneElement, isValidElement } from "react";
8
+ import { Image } from "react-native";
9
+
10
+ // src/system/icon/icon-context.ts
11
+ import { createContext, useContext } from "react";
12
+ var IconContext = createContext({});
13
+ IconContext.displayName = "XAUI.Icon.Context";
14
+ function useIconContext() {
15
+ return useContext(IconContext);
16
+ }
17
+
18
+ // src/system/icon/icon.tsx
19
+ function Icon({
20
+ as: Component,
21
+ children,
22
+ source,
23
+ size,
24
+ color,
25
+ style
26
+ }) {
27
+ const inherited = useIconContext();
28
+ const theme = useXAUITheme();
29
+ const resolvedSize = size ?? inherited.size ?? theme.fontSizes.md;
30
+ const resolvedColor = color ?? inherited.color ?? theme.colors.foreground;
31
+ if (Component) {
32
+ return /* @__PURE__ */ React.createElement(Component, { size: resolvedSize, color: resolvedColor });
33
+ }
34
+ if (isValidElement(children)) {
35
+ return cloneElement(children, {
36
+ width: resolvedSize,
37
+ height: resolvedSize,
38
+ color: resolvedColor
39
+ });
40
+ }
41
+ if (source) {
42
+ return /* @__PURE__ */ React.createElement(
43
+ Image,
44
+ {
45
+ source,
46
+ style: [
47
+ { width: resolvedSize, height: resolvedSize, tintColor: resolvedColor },
48
+ style
49
+ ]
50
+ }
51
+ );
52
+ }
53
+ throw new Error(
54
+ "XAUI: Icon needs one of `as` (an icon component), a raw SVG element as its child, or `source` (an image). It renders nothing on its own."
55
+ );
56
+ }
57
+ Icon.displayName = "XAUI.Icon";
58
+
59
+ // src/system/portal/portal.tsx
60
+ import { useContext as useContext2, useId, useLayoutEffect } from "react";
61
+
62
+ // src/system/portal/portal-context.ts
63
+ import { createContext as createContext2 } from "react";
64
+ var PortalContext = createContext2(null);
65
+
66
+ // src/system/portal/portal.tsx
67
+ function Portal({ children }) {
68
+ const context = useContext2(PortalContext);
69
+ const key = useId();
70
+ useLayoutEffect(() => {
71
+ context?.addPortal(key, children);
72
+ }, [children, context, key]);
73
+ useLayoutEffect(() => {
74
+ return () => context?.removePortal(key);
75
+ }, [context, key]);
76
+ return null;
77
+ }
78
+ Portal.displayName = "XAUI.Portal";
79
+
80
+ // src/system/portal/portal-host.tsx
81
+ import { Fragment, useCallback, useMemo, useState } from "react";
82
+ import { StyleSheet, View } from "react-native";
83
+ var styles = StyleSheet.create({
84
+ container: { flex: 1 }
85
+ });
86
+ function PortalHost({ children }) {
87
+ const [portals, setPortals] = useState(/* @__PURE__ */ new Map());
88
+ const addPortal = useCallback((key, element) => {
89
+ setPortals((current) => new Map(current).set(key, element));
90
+ }, []);
91
+ const removePortal = useCallback((key) => {
92
+ setPortals((current) => {
93
+ if (!current.has(key)) return current;
94
+ const next = new Map(current);
95
+ next.delete(key);
96
+ return next;
97
+ });
98
+ }, []);
99
+ const methods = useMemo(
100
+ () => ({ addPortal, removePortal }),
101
+ [addPortal, removePortal]
102
+ );
103
+ return /* @__PURE__ */ React.createElement(PortalContext.Provider, { value: methods }, /* @__PURE__ */ React.createElement(View, { style: styles.container }, children, Array.from(portals, ([key, element]) => /* @__PURE__ */ React.createElement(Fragment, { key }, element))));
104
+ }
105
+ PortalHost.displayName = "XAUI.PortalHost";
106
+
6
107
  // src/system/pressable-feedback/pressable-feedback.tsx
7
- import { forwardRef as forwardRef2, useContext as useContext2, useEffect as useEffect2, useMemo } from "react";
108
+ import { forwardRef as forwardRef2, useContext as useContext4, useEffect as useEffect2, useMemo as useMemo2 } from "react";
8
109
  import { Pressable } from "react-native";
9
110
  import Animated3, {
10
111
  useAnimatedStyle as useAnimatedStyle3,
@@ -13,15 +114,15 @@ import Animated3, {
13
114
  } from "react-native-reanimated";
14
115
 
15
116
  // src/system/pressable-feedback/pressable-feedback-context.ts
16
- import { createContext as createContext2 } from "react";
117
+ import { createContext as createContext4 } from "react";
17
118
 
18
119
  // src/system/slot/create-slot-context.ts
19
- import { createContext, useContext } from "react";
120
+ import { createContext as createContext3, useContext as useContext3 } from "react";
20
121
  function createSlotContext(name) {
21
- const Context = createContext(null);
122
+ const Context = createContext3(null);
22
123
  Context.displayName = `XAUI.${name}.Context`;
23
124
  function useSlotContext() {
24
- const value = useContext(Context);
125
+ const value = useContext3(Context);
25
126
  if (value === null) {
26
127
  const error = new Error(
27
128
  `XAUI: use${name} must be called inside <${name}>. A slot reads the values its root resolved, so it can only be rendered as a child of one.`
@@ -39,11 +140,11 @@ function createSlotContext(name) {
39
140
 
40
141
  // src/system/pressable-feedback/pressable-feedback-context.ts
41
142
  var [FeedbackProvider, useFeedback] = createSlotContext("PressableFeedback");
42
- var DisableAllContext = createContext2(false);
143
+ var DisableAllContext = createContext4(false);
43
144
 
44
145
  // src/system/pressable-feedback/pressable-feedback-highlight.tsx
45
146
  import { useEffect } from "react";
46
- import { StyleSheet, View } from "react-native";
147
+ import { StyleSheet as StyleSheet2, View as View2 } from "react-native";
47
148
  import Animated, {
48
149
  useAnimatedStyle,
49
150
  useSharedValue,
@@ -118,13 +219,13 @@ function PressableFeedbackHighlight({
118
219
  HIGHLIGHT_OPACITY
119
220
  );
120
221
  const base = [
121
- StyleSheet.absoluteFillObject,
222
+ StyleSheet2.absoluteFillObject,
122
223
  { backgroundColor: theme.colors.foreground },
123
224
  style
124
225
  ];
125
226
  if (!progress || !settings.enabled) {
126
227
  return /* @__PURE__ */ React.createElement(
127
- View,
228
+ View2,
128
229
  {
129
230
  pointerEvents: "none",
130
231
  style: [base, { opacity: isPressed ? settings.opacity : 0 }]
@@ -275,7 +376,7 @@ function RippleWave({
275
376
  }
276
377
 
277
378
  // src/system/slot/slot.tsx
278
- import { cloneElement, forwardRef, isValidElement } from "react";
379
+ import { cloneElement as cloneElement2, forwardRef, isValidElement as isValidElement2 } from "react";
279
380
 
280
381
  // src/system/slot/merge-refs.ts
281
382
  function mergeRefs(...refs) {
@@ -333,7 +434,7 @@ function resolveStyle(style, state) {
333
434
 
334
435
  // src/system/slot/slot.tsx
335
436
  var Slot = forwardRef(function Slot2({ children, ...ours }, ref) {
336
- if (!isValidElement(children)) {
437
+ if (!isValidElement2(children)) {
337
438
  throw new Error(
338
439
  "XAUI: asChild expects exactly one React element as its child, and merges the component's props into it. Text, a fragment, several children or none give it nothing to merge into \u2014 drop `asChild` to render the component itself."
339
440
  );
@@ -341,7 +442,7 @@ var Slot = forwardRef(function Slot2({ children, ...ours }, ref) {
341
442
  const child = children;
342
443
  const merged = mergeProps(ours, child.props);
343
444
  merged.ref = mergeRefs(ref, refOf(child));
344
- return cloneElement(child, merged);
445
+ return cloneElement2(child, merged);
345
446
  });
346
447
  Slot.displayName = "XAUI.Slot";
347
448
  function refOf(element) {
@@ -355,7 +456,7 @@ var AnimatedPressable = Animated3.createAnimatedComponent(Pressable);
355
456
  var AnimatedSlot = Animated3.createAnimatedComponent(Slot);
356
457
  var PressableFeedback = forwardRef2(
357
458
  function PressableFeedback2({ animation, feedbackVariant = "scale-highlight", ...rest }, ref) {
358
- const inheritedDisableAll = useContext2(DisableAllContext);
459
+ const inheritedDisableAll = useContext4(DisableAllContext);
359
460
  const resolved = resolveAnimation(animation, inheritedDisableAll);
360
461
  const Feedback = resolved.none || feedbackVariant === "none" ? StaticFeedback : AnimatedFeedback;
361
462
  const body = /* @__PURE__ */ React.createElement(
@@ -380,7 +481,7 @@ var StaticFeedback = forwardRef2(function StaticFeedback2({
380
481
  style,
381
482
  ...rest
382
483
  }, ref) {
383
- const context = useMemo(() => ({ isPressed, animation }), [isPressed, animation]);
484
+ const context = useMemo2(() => ({ isPressed, animation }), [isPressed, animation]);
384
485
  const Root = asChild ? Slot : Pressable;
385
486
  return /* @__PURE__ */ React.createElement(Root, { ref, style, disabled: isDisabled, ...rest }, /* @__PURE__ */ React.createElement(FeedbackProvider, { value: context }, /* @__PURE__ */ React.createElement(DefaultOverlay, { variant: feedbackVariant }), children));
386
487
  });
@@ -408,7 +509,7 @@ var AnimatedFeedback = forwardRef2(function AnimatedFeedback2({
408
509
  const animatedStyle = useAnimatedStyle3(
409
510
  () => animation.scale ? { transform: [{ scale: 1 - (1 - PRESS_SCALE) * progress.value }] } : {}
410
511
  );
411
- const context = useMemo(
512
+ const context = useMemo2(
412
513
  () => ({ isPressed, animation, progress, pressCount, origin, size }),
413
514
  [isPressed, animation, progress, pressCount, origin, size]
414
515
  );
@@ -474,7 +575,7 @@ function resolveTint(tokens, color, theme) {
474
575
  }
475
576
 
476
577
  // src/system/recipe/style-cache.ts
477
- import { StyleSheet as StyleSheet2 } from "react-native";
578
+ import { StyleSheet as StyleSheet3 } from "react-native";
478
579
 
479
580
  // src/system/recipe/variant-map.ts
480
581
  var STATE_ORDER = ["focused", "pressed", "disabled"];
@@ -537,7 +638,7 @@ function createStyleCache(slots) {
537
638
  const built = build();
538
639
  const complete = {};
539
640
  for (const slot of slots) complete[slot] = built[slot] ?? {};
540
- const created = StyleSheet2.create(complete);
641
+ const created = StyleSheet3.create(complete);
541
642
  entries.set(key, created);
542
643
  return created;
543
644
  },
@@ -594,7 +695,7 @@ function apply(fns, theme, colors) {
594
695
  }
595
696
 
596
697
  // src/system/slot/children-to-string.ts
597
- import { isValidElement as isValidElement2 } from "react";
698
+ import { isValidElement as isValidElement3 } from "react";
598
699
  function childrenToString(children) {
599
700
  const text = stringify(children);
600
701
  return text === null || text === "" ? null : text;
@@ -603,7 +704,7 @@ function stringify(node) {
603
704
  if (node === null || node === void 0 || typeof node === "boolean") return "";
604
705
  if (typeof node === "string") return node;
605
706
  if (typeof node === "number") return String(node);
606
- if (isValidElement2(node)) return null;
707
+ if (isValidElement3(node)) return null;
607
708
  if (Array.isArray(node)) {
608
709
  let text = "";
609
710
  for (const child of node) {
@@ -617,6 +718,12 @@ function stringify(node) {
617
718
  }
618
719
 
619
720
  export {
721
+ IconContext,
722
+ useIconContext,
723
+ Icon,
724
+ PortalContext,
725
+ Portal,
726
+ PortalHost,
620
727
  createSlotContext,
621
728
  useFeedback,
622
729
  PRESS_SCALE,
@@ -3,10 +3,111 @@
3
3
 
4
4
  var _chunk3QBT3Q65cjs = require('./chunk-3QBT3Q65.cjs');
5
5
 
6
- // src/system/pressable-feedback/pressable-feedback.tsx
6
+ // src/system/icon/icon.tsx
7
7
  var _react = require('react');
8
8
  var _reactnative = require('react-native');
9
9
 
10
+ // src/system/icon/icon-context.ts
11
+
12
+ var IconContext = _react.createContext.call(void 0, {});
13
+ IconContext.displayName = "XAUI.Icon.Context";
14
+ function useIconContext() {
15
+ return _react.useContext.call(void 0, IconContext);
16
+ }
17
+
18
+ // src/system/icon/icon.tsx
19
+ function Icon({
20
+ as: Component,
21
+ children,
22
+ source,
23
+ size,
24
+ color,
25
+ style
26
+ }) {
27
+ const inherited = useIconContext();
28
+ const theme = _chunk3QBT3Q65cjs.useXAUITheme.call(void 0, );
29
+ const resolvedSize = _nullishCoalesce(_nullishCoalesce(size, () => ( inherited.size)), () => ( theme.fontSizes.md));
30
+ const resolvedColor = _nullishCoalesce(_nullishCoalesce(color, () => ( inherited.color)), () => ( theme.colors.foreground));
31
+ if (Component) {
32
+ return /* @__PURE__ */ React.createElement(Component, { size: resolvedSize, color: resolvedColor });
33
+ }
34
+ if (_react.isValidElement.call(void 0, children)) {
35
+ return _react.cloneElement.call(void 0, children, {
36
+ width: resolvedSize,
37
+ height: resolvedSize,
38
+ color: resolvedColor
39
+ });
40
+ }
41
+ if (source) {
42
+ return /* @__PURE__ */ React.createElement(
43
+ _reactnative.Image,
44
+ {
45
+ source,
46
+ style: [
47
+ { width: resolvedSize, height: resolvedSize, tintColor: resolvedColor },
48
+ style
49
+ ]
50
+ }
51
+ );
52
+ }
53
+ throw new Error(
54
+ "XAUI: Icon needs one of `as` (an icon component), a raw SVG element as its child, or `source` (an image). It renders nothing on its own."
55
+ );
56
+ }
57
+ Icon.displayName = "XAUI.Icon";
58
+
59
+ // src/system/portal/portal.tsx
60
+
61
+
62
+ // src/system/portal/portal-context.ts
63
+
64
+ var PortalContext = _react.createContext.call(void 0, null);
65
+
66
+ // src/system/portal/portal.tsx
67
+ function Portal({ children }) {
68
+ const context = _react.useContext.call(void 0, PortalContext);
69
+ const key = _react.useId.call(void 0, );
70
+ _react.useLayoutEffect.call(void 0, () => {
71
+ _optionalChain([context, 'optionalAccess', _ => _.addPortal, 'call', _2 => _2(key, children)]);
72
+ }, [children, context, key]);
73
+ _react.useLayoutEffect.call(void 0, () => {
74
+ return () => _optionalChain([context, 'optionalAccess', _3 => _3.removePortal, 'call', _4 => _4(key)]);
75
+ }, [context, key]);
76
+ return null;
77
+ }
78
+ Portal.displayName = "XAUI.Portal";
79
+
80
+ // src/system/portal/portal-host.tsx
81
+
82
+
83
+ var styles = _reactnative.StyleSheet.create({
84
+ container: { flex: 1 }
85
+ });
86
+ function PortalHost({ children }) {
87
+ const [portals, setPortals] = _react.useState.call(void 0, /* @__PURE__ */ new Map());
88
+ const addPortal = _react.useCallback.call(void 0, (key, element) => {
89
+ setPortals((current) => new Map(current).set(key, element));
90
+ }, []);
91
+ const removePortal = _react.useCallback.call(void 0, (key) => {
92
+ setPortals((current) => {
93
+ if (!current.has(key)) return current;
94
+ const next = new Map(current);
95
+ next.delete(key);
96
+ return next;
97
+ });
98
+ }, []);
99
+ const methods = _react.useMemo.call(void 0,
100
+ () => ({ addPortal, removePortal }),
101
+ [addPortal, removePortal]
102
+ );
103
+ return /* @__PURE__ */ React.createElement(PortalContext.Provider, { value: methods }, /* @__PURE__ */ React.createElement(_reactnative.View, { style: styles.container }, children, Array.from(portals, ([key, element]) => /* @__PURE__ */ React.createElement(_react.Fragment, { key }, element))));
104
+ }
105
+ PortalHost.displayName = "XAUI.PortalHost";
106
+
107
+ // src/system/pressable-feedback/pressable-feedback.tsx
108
+
109
+
110
+
10
111
 
11
112
 
12
113
 
@@ -26,7 +127,7 @@ function createSlotContext(name) {
26
127
  const error = new Error(
27
128
  `XAUI: use${name} must be called inside <${name}>. A slot reads the values its root resolved, so it can only be rendered as a child of one.`
28
129
  );
29
- _optionalChain([Error, 'access', _ => _.captureStackTrace, 'optionalCall', _2 => _2(
130
+ _optionalChain([Error, 'access', _5 => _5.captureStackTrace, 'optionalCall', _6 => _6(
30
131
  error,
31
132
  useSlotContext
32
133
  )]);
@@ -202,12 +303,12 @@ function AnimatedRipple({
202
303
  const fromB = _reactnativereanimated.useSharedValue.call(void 0, { x: 0, y: 0 });
203
304
  const useA = _reactnativereanimated.useSharedValue.call(void 0, true);
204
305
  _reactnativereanimated.useAnimatedReaction.call(void 0,
205
- () => _nullishCoalesce(_optionalChain([pressCount, 'optionalAccess', _3 => _3.value]), () => ( 0)),
306
+ () => _nullishCoalesce(_optionalChain([pressCount, 'optionalAccess', _7 => _7.value]), () => ( 0)),
206
307
  (count, previous) => {
207
308
  if (previous === null || count === previous) return;
208
309
  const wave = useA.value ? waveA : waveB;
209
310
  const from = useA.value ? fromA : fromB;
210
- from.value = _nullishCoalesce(_optionalChain([origin, 'optionalAccess', _4 => _4.value]), () => ( { x: 0, y: 0 }));
311
+ from.value = _nullishCoalesce(_optionalChain([origin, 'optionalAccess', _8 => _8.value]), () => ( { x: 0, y: 0 }));
211
312
  wave.value = 0;
212
313
  wave.value = _reactnativereanimated.withTiming.call(void 0, 2, { duration: duration * 2 });
213
314
  useA.value = !useA.value;
@@ -244,7 +345,7 @@ function RippleWave({
244
345
  style
245
346
  }) {
246
347
  const animatedStyle = _reactnativereanimated.useAnimatedStyle.call(void 0, () => {
247
- const within = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _5 => _5.value]), () => ( { width: 0, height: 0 }));
348
+ const within = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _9 => _9.value]), () => ( { width: 0, height: 0 }));
248
349
  const radius = Math.sqrt(within.width * within.width + within.height * within.height) * RIPPLE_COVERAGE;
249
350
  const at = from.value;
250
351
  return {
@@ -416,12 +517,12 @@ var AnimatedFeedback = _react.forwardRef.call(void 0, function AnimatedFeedback2
416
517
  const { locationX, locationY } = event.nativeEvent;
417
518
  origin.value = { x: locationX, y: locationY };
418
519
  pressCount.value += 1;
419
- _optionalChain([onPressIn, 'optionalCall', _6 => _6(event)]);
520
+ _optionalChain([onPressIn, 'optionalCall', _10 => _10(event)]);
420
521
  };
421
522
  const handleLayout = (event) => {
422
523
  const { width, height } = event.nativeEvent.layout;
423
524
  size.value = { width, height };
424
- _optionalChain([onLayout, 'optionalCall', _7 => _7(event)]);
525
+ _optionalChain([onLayout, 'optionalCall', _11 => _11(event)]);
425
526
  };
426
527
  const clip = feedbackVariant === "scale-ripple" ? { overflow: "hidden" } : null;
427
528
  const Root = asChild ? AnimatedSlot : AnimatedPressable;
@@ -501,7 +602,7 @@ function resolveVariantColors(tokens, theme) {
501
602
  function activeStateFns(states, active) {
502
603
  const fns = [];
503
604
  for (const state of STATE_ORDER) {
504
- const fn = active[state] ? _optionalChain([states, 'optionalAccess', _8 => _8[state]]) : void 0;
605
+ const fn = active[state] ? _optionalChain([states, 'optionalAccess', _12 => _12[state]]) : void 0;
505
606
  if (fn) fns.push(fn);
506
607
  }
507
608
  return fns;
@@ -558,7 +659,7 @@ function cacheKey(theme, selection, states) {
558
659
  // src/system/recipe/create-recipe.ts
559
660
  function createRecipe(config) {
560
661
  const cache = createStyleCache(config.slots);
561
- const tokensFor = (variant) => variant === void 0 ? void 0 : _optionalChain([config, 'access', _9 => _9.variantTokens, 'optionalAccess', _10 => _10[variant]]);
662
+ const tokensFor = (variant) => variant === void 0 ? void 0 : _optionalChain([config, 'access', _13 => _13.variantTokens, 'optionalAccess', _14 => _14[variant]]);
562
663
  return {
563
664
  slots: config.slots,
564
665
  resolve({ theme, selection, states = {} }) {
@@ -634,4 +735,10 @@ function stringify(node) {
634
735
 
635
736
 
636
737
 
637
- exports.createSlotContext = createSlotContext; exports.useFeedback = useFeedback; exports.PRESS_SCALE = PRESS_SCALE; exports.PRESS_DURATION = PRESS_DURATION; exports.RELEASE_DURATION = RELEASE_DURATION; exports.HIGHLIGHT_OPACITY = HIGHLIGHT_OPACITY; exports.RIPPLE_OPACITY = RIPPLE_OPACITY; exports.RIPPLE_DURATION = RIPPLE_DURATION; exports.RIPPLE_COVERAGE = RIPPLE_COVERAGE; exports.resolveAnimation = resolveAnimation; exports.resolveSlotAnimation = resolveSlotAnimation; exports.mergeRefs = mergeRefs; exports.mergeProps = mergeProps; exports.Slot = Slot; exports.PressableFeedback = PressableFeedback3; exports.createRecipe = createRecipe; exports.childrenToString = childrenToString;
738
+
739
+
740
+
741
+
742
+
743
+
744
+ exports.IconContext = IconContext; exports.useIconContext = useIconContext; exports.Icon = Icon; exports.PortalContext = PortalContext; exports.Portal = Portal; exports.PortalHost = PortalHost; exports.createSlotContext = createSlotContext; exports.useFeedback = useFeedback; exports.PRESS_SCALE = PRESS_SCALE; exports.PRESS_DURATION = PRESS_DURATION; exports.RELEASE_DURATION = RELEASE_DURATION; exports.HIGHLIGHT_OPACITY = HIGHLIGHT_OPACITY; exports.RIPPLE_OPACITY = RIPPLE_OPACITY; exports.RIPPLE_DURATION = RIPPLE_DURATION; exports.RIPPLE_COVERAGE = RIPPLE_COVERAGE; exports.resolveAnimation = resolveAnimation; exports.resolveSlotAnimation = resolveSlotAnimation; exports.mergeRefs = mergeRefs; exports.mergeProps = mergeProps; exports.Slot = Slot; exports.PressableFeedback = PressableFeedback3; exports.createRecipe = createRecipe; exports.childrenToString = childrenToString;
package/dist/index.cjs CHANGED
@@ -16,7 +16,13 @@
16
16
 
17
17
 
18
18
 
19
- var _chunkV63JO65Fcjs = require('./chunk-V63JO65F.cjs');
19
+
20
+
21
+
22
+
23
+
24
+
25
+ var _chunkPSSG6C3Qcjs = require('./chunk-PSSG6C3Q.cjs');
20
26
 
21
27
 
22
28
 
@@ -69,4 +75,10 @@ var _chunk3QBT3Q65cjs = require('./chunk-3QBT3Q65.cjs');
69
75
 
70
76
 
71
77
 
72
- exports.HIGHLIGHT_OPACITY = _chunkV63JO65Fcjs.HIGHLIGHT_OPACITY; exports.PRESS_DURATION = _chunkV63JO65Fcjs.PRESS_DURATION; exports.PRESS_SCALE = _chunkV63JO65Fcjs.PRESS_SCALE; exports.PressableFeedback = _chunkV63JO65Fcjs.PressableFeedback; exports.RELEASE_DURATION = _chunkV63JO65Fcjs.RELEASE_DURATION; exports.RIPPLE_COVERAGE = _chunkV63JO65Fcjs.RIPPLE_COVERAGE; exports.RIPPLE_DURATION = _chunkV63JO65Fcjs.RIPPLE_DURATION; exports.RIPPLE_OPACITY = _chunkV63JO65Fcjs.RIPPLE_OPACITY; exports.Slot = _chunkV63JO65Fcjs.Slot; exports.ThemeContext = _chunk3QBT3Q65cjs.ThemeContext; exports.XAUIProvider = _chunkAW63PTQ4cjs.XAUIProvider; exports.buildRadius = _chunkAW63PTQ4cjs.buildRadius; exports.buildShadows = _chunkAW63PTQ4cjs.buildShadows; exports.childrenToString = _chunkV63JO65Fcjs.childrenToString; exports.createRecipe = _chunkV63JO65Fcjs.createRecipe; exports.createSlotContext = _chunkV63JO65Fcjs.createSlotContext; exports.createTheme = _chunkAW63PTQ4cjs.createTheme; exports.defaultTheme = _chunkAW63PTQ4cjs.defaultTheme; exports.deriveColors = _chunkAW63PTQ4cjs.deriveColors; exports.deriveTint = _chunk3QBT3Q65cjs.deriveTint; exports.mergeProps = _chunkV63JO65Fcjs.mergeProps; exports.mergeRefs = _chunkV63JO65Fcjs.mergeRefs; exports.palette = _chunkAW63PTQ4cjs.palette; exports.primitives = _chunkAW63PTQ4cjs.primitives; exports.resolveAnimation = _chunkV63JO65Fcjs.resolveAnimation; exports.resolveSlotAnimation = _chunkV63JO65Fcjs.resolveSlotAnimation; exports.sourceKeys = _chunkAW63PTQ4cjs.sourceKeys; exports.tokens = _chunkAW63PTQ4cjs.tokens; exports.useColorMode = _chunk3QBT3Q65cjs.useColorMode; exports.useFeedback = _chunkV63JO65Fcjs.useFeedback; exports.useThemeColor = _chunk3QBT3Q65cjs.useThemeColor; exports.useXAUITheme = _chunk3QBT3Q65cjs.useXAUITheme;
78
+
79
+
80
+
81
+
82
+
83
+
84
+ exports.HIGHLIGHT_OPACITY = _chunkPSSG6C3Qcjs.HIGHLIGHT_OPACITY; exports.Icon = _chunkPSSG6C3Qcjs.Icon; exports.IconContext = _chunkPSSG6C3Qcjs.IconContext; exports.PRESS_DURATION = _chunkPSSG6C3Qcjs.PRESS_DURATION; exports.PRESS_SCALE = _chunkPSSG6C3Qcjs.PRESS_SCALE; exports.Portal = _chunkPSSG6C3Qcjs.Portal; exports.PortalContext = _chunkPSSG6C3Qcjs.PortalContext; exports.PortalHost = _chunkPSSG6C3Qcjs.PortalHost; exports.PressableFeedback = _chunkPSSG6C3Qcjs.PressableFeedback; exports.RELEASE_DURATION = _chunkPSSG6C3Qcjs.RELEASE_DURATION; exports.RIPPLE_COVERAGE = _chunkPSSG6C3Qcjs.RIPPLE_COVERAGE; exports.RIPPLE_DURATION = _chunkPSSG6C3Qcjs.RIPPLE_DURATION; exports.RIPPLE_OPACITY = _chunkPSSG6C3Qcjs.RIPPLE_OPACITY; exports.Slot = _chunkPSSG6C3Qcjs.Slot; exports.ThemeContext = _chunk3QBT3Q65cjs.ThemeContext; exports.XAUIProvider = _chunkAW63PTQ4cjs.XAUIProvider; exports.buildRadius = _chunkAW63PTQ4cjs.buildRadius; exports.buildShadows = _chunkAW63PTQ4cjs.buildShadows; exports.childrenToString = _chunkPSSG6C3Qcjs.childrenToString; exports.createRecipe = _chunkPSSG6C3Qcjs.createRecipe; exports.createSlotContext = _chunkPSSG6C3Qcjs.createSlotContext; exports.createTheme = _chunkAW63PTQ4cjs.createTheme; exports.defaultTheme = _chunkAW63PTQ4cjs.defaultTheme; exports.deriveColors = _chunkAW63PTQ4cjs.deriveColors; exports.deriveTint = _chunk3QBT3Q65cjs.deriveTint; exports.mergeProps = _chunkPSSG6C3Qcjs.mergeProps; exports.mergeRefs = _chunkPSSG6C3Qcjs.mergeRefs; exports.palette = _chunkAW63PTQ4cjs.palette; exports.primitives = _chunkAW63PTQ4cjs.primitives; exports.resolveAnimation = _chunkPSSG6C3Qcjs.resolveAnimation; exports.resolveSlotAnimation = _chunkPSSG6C3Qcjs.resolveSlotAnimation; exports.sourceKeys = _chunkAW63PTQ4cjs.sourceKeys; exports.tokens = _chunkAW63PTQ4cjs.tokens; exports.useColorMode = _chunk3QBT3Q65cjs.useColorMode; exports.useFeedback = _chunkPSSG6C3Qcjs.useFeedback; exports.useIconContext = _chunkPSSG6C3Qcjs.useIconContext; exports.useThemeColor = _chunk3QBT3Q65cjs.useThemeColor; exports.useXAUITheme = _chunk3QBT3Q65cjs.useXAUITheme;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { AnimationConfig, AnimationProp, AsChildProps, Axes, CompoundVariant, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, MergeableProps, PRESS_DURATION, PRESS_SCALE, PossibleRef, PressableFeedback, PressableFeedbackHighlightProps, PressableFeedbackProps, PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, Recipe, RecipeConfig, ResolveArgs, ResolvedAnimation, ResolvedSelection, ResolvedStyles, Selection, Slot, SlotAnimation, SlotProps, SlotStyle, SlotStyles, StateName, States, StyleFn, TintArgs, VariantColors, VariantRole, VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback } from './system/index.cjs';
1
+ export { AnimationConfig, AnimationProp, AsChildProps, Axes, CompoundVariant, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, Icon, IconComponentProps, IconContext, IconContextValue, IconProps, MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, PortalHostProps, PortalMethods, PortalProps, PossibleRef, PressableFeedback, PressableFeedbackHighlightProps, PressableFeedbackProps, PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, Recipe, RecipeConfig, ResolveArgs, ResolvedAnimation, ResolvedSelection, ResolvedStyles, Selection, Slot, SlotAnimation, SlotProps, SlotStyle, SlotStyles, StateName, States, StyleFn, TintArgs, VariantColors, VariantRole, VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext } from './system/index.cjs';
2
2
  export { ColorModePreference, PaletteFamily, PaletteShade, ThemeContext, XAUIProvider, XAUIProviderProps, XAUITint, buildRadius, buildShadows, createTheme, defaultTheme, deriveColors, deriveTint, palette, primitives, sourceKeys, tokens, useColorMode, useThemeColor, useXAUITheme } from './theme/index.cjs';
3
3
  export { C as ColorMode, F as FontSizeKey, a as FontWeightKey, R as RadiusKey, S as Size, X as XAUIColors, b as XAUIDerivedColors, c as XAUIPrimitiveColors, d as XAUIRadius, e as XAUIShadow, f as XAUISourceColors, g as XAUITheme, h as XAUIThemeConfig, i as XAUIThemeSet } from './theme.type-C9bFJKFm.cjs';
4
4
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { AnimationConfig, AnimationProp, AsChildProps, Axes, CompoundVariant, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, MergeableProps, PRESS_DURATION, PRESS_SCALE, PossibleRef, PressableFeedback, PressableFeedbackHighlightProps, PressableFeedbackProps, PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, Recipe, RecipeConfig, ResolveArgs, ResolvedAnimation, ResolvedSelection, ResolvedStyles, Selection, Slot, SlotAnimation, SlotProps, SlotStyle, SlotStyles, StateName, States, StyleFn, TintArgs, VariantColors, VariantRole, VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback } from './system/index.js';
1
+ export { AnimationConfig, AnimationProp, AsChildProps, Axes, CompoundVariant, FeedbackContext, FeedbackVariant, HIGHLIGHT_OPACITY, Icon, IconComponentProps, IconContext, IconContextValue, IconProps, MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, PortalHostProps, PortalMethods, PortalProps, PossibleRef, PressableFeedback, PressableFeedbackHighlightProps, PressableFeedbackProps, PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, Recipe, RecipeConfig, ResolveArgs, ResolvedAnimation, ResolvedSelection, ResolvedStyles, Selection, Slot, SlotAnimation, SlotProps, SlotStyle, SlotStyles, StateName, States, StyleFn, TintArgs, VariantColors, VariantRole, VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext } from './system/index.js';
2
2
  export { ColorModePreference, PaletteFamily, PaletteShade, ThemeContext, XAUIProvider, XAUIProviderProps, XAUITint, buildRadius, buildShadows, createTheme, defaultTheme, deriveColors, deriveTint, palette, primitives, sourceKeys, tokens, useColorMode, useThemeColor, useXAUITheme } from './theme/index.js';
3
3
  export { C as ColorMode, F as FontSizeKey, a as FontWeightKey, R as RadiusKey, S as Size, X as XAUIColors, b as XAUIDerivedColors, c as XAUIPrimitiveColors, d as XAUIRadius, e as XAUIShadow, f as XAUISourceColors, g as XAUITheme, h as XAUIThemeConfig, i as XAUIThemeSet } from './theme.type-C9bFJKFm.js';
4
4
  import 'react';
package/dist/index.js CHANGED
@@ -1,7 +1,12 @@
1
1
  import {
2
2
  HIGHLIGHT_OPACITY,
3
+ Icon,
4
+ IconContext,
3
5
  PRESS_DURATION,
4
6
  PRESS_SCALE,
7
+ Portal,
8
+ PortalContext,
9
+ PortalHost,
5
10
  PressableFeedback,
6
11
  RELEASE_DURATION,
7
12
  RIPPLE_COVERAGE,
@@ -15,8 +20,9 @@ import {
15
20
  mergeRefs,
16
21
  resolveAnimation,
17
22
  resolveSlotAnimation,
18
- useFeedback
19
- } from "./chunk-QAMNNTGM.js";
23
+ useFeedback,
24
+ useIconContext
25
+ } from "./chunk-AUDOMZR3.js";
20
26
  import {
21
27
  XAUIProvider,
22
28
  buildRadius,
@@ -38,8 +44,13 @@ import {
38
44
  } from "./chunk-X2K2FX3W.js";
39
45
  export {
40
46
  HIGHLIGHT_OPACITY,
47
+ Icon,
48
+ IconContext,
41
49
  PRESS_DURATION,
42
50
  PRESS_SCALE,
51
+ Portal,
52
+ PortalContext,
53
+ PortalHost,
43
54
  PressableFeedback,
44
55
  RELEASE_DURATION,
45
56
  RIPPLE_COVERAGE,
@@ -67,6 +78,7 @@ export {
67
78
  tokens,
68
79
  useColorMode,
69
80
  useFeedback,
81
+ useIconContext,
70
82
  useThemeColor,
71
83
  useXAUITheme
72
84
  };
@@ -16,7 +16,13 @@
16
16
 
17
17
 
18
18
 
19
- var _chunkV63JO65Fcjs = require('../chunk-V63JO65F.cjs');
19
+
20
+
21
+
22
+
23
+
24
+
25
+ var _chunkPSSG6C3Qcjs = require('../chunk-PSSG6C3Q.cjs');
20
26
  require('../chunk-3QBT3Q65.cjs');
21
27
 
22
28
 
@@ -36,4 +42,10 @@ require('../chunk-3QBT3Q65.cjs');
36
42
 
37
43
 
38
44
 
39
- exports.HIGHLIGHT_OPACITY = _chunkV63JO65Fcjs.HIGHLIGHT_OPACITY; exports.PRESS_DURATION = _chunkV63JO65Fcjs.PRESS_DURATION; exports.PRESS_SCALE = _chunkV63JO65Fcjs.PRESS_SCALE; exports.PressableFeedback = _chunkV63JO65Fcjs.PressableFeedback; exports.RELEASE_DURATION = _chunkV63JO65Fcjs.RELEASE_DURATION; exports.RIPPLE_COVERAGE = _chunkV63JO65Fcjs.RIPPLE_COVERAGE; exports.RIPPLE_DURATION = _chunkV63JO65Fcjs.RIPPLE_DURATION; exports.RIPPLE_OPACITY = _chunkV63JO65Fcjs.RIPPLE_OPACITY; exports.Slot = _chunkV63JO65Fcjs.Slot; exports.childrenToString = _chunkV63JO65Fcjs.childrenToString; exports.createRecipe = _chunkV63JO65Fcjs.createRecipe; exports.createSlotContext = _chunkV63JO65Fcjs.createSlotContext; exports.mergeProps = _chunkV63JO65Fcjs.mergeProps; exports.mergeRefs = _chunkV63JO65Fcjs.mergeRefs; exports.resolveAnimation = _chunkV63JO65Fcjs.resolveAnimation; exports.resolveSlotAnimation = _chunkV63JO65Fcjs.resolveSlotAnimation; exports.useFeedback = _chunkV63JO65Fcjs.useFeedback;
45
+
46
+
47
+
48
+
49
+
50
+
51
+ exports.HIGHLIGHT_OPACITY = _chunkPSSG6C3Qcjs.HIGHLIGHT_OPACITY; exports.Icon = _chunkPSSG6C3Qcjs.Icon; exports.IconContext = _chunkPSSG6C3Qcjs.IconContext; exports.PRESS_DURATION = _chunkPSSG6C3Qcjs.PRESS_DURATION; exports.PRESS_SCALE = _chunkPSSG6C3Qcjs.PRESS_SCALE; exports.Portal = _chunkPSSG6C3Qcjs.Portal; exports.PortalContext = _chunkPSSG6C3Qcjs.PortalContext; exports.PortalHost = _chunkPSSG6C3Qcjs.PortalHost; exports.PressableFeedback = _chunkPSSG6C3Qcjs.PressableFeedback; exports.RELEASE_DURATION = _chunkPSSG6C3Qcjs.RELEASE_DURATION; exports.RIPPLE_COVERAGE = _chunkPSSG6C3Qcjs.RIPPLE_COVERAGE; exports.RIPPLE_DURATION = _chunkPSSG6C3Qcjs.RIPPLE_DURATION; exports.RIPPLE_OPACITY = _chunkPSSG6C3Qcjs.RIPPLE_OPACITY; exports.Slot = _chunkPSSG6C3Qcjs.Slot; exports.childrenToString = _chunkPSSG6C3Qcjs.childrenToString; exports.createRecipe = _chunkPSSG6C3Qcjs.createRecipe; exports.createSlotContext = _chunkPSSG6C3Qcjs.createSlotContext; exports.mergeProps = _chunkPSSG6C3Qcjs.mergeProps; exports.mergeRefs = _chunkPSSG6C3Qcjs.mergeRefs; exports.resolveAnimation = _chunkPSSG6C3Qcjs.resolveAnimation; exports.resolveSlotAnimation = _chunkPSSG6C3Qcjs.resolveSlotAnimation; exports.useFeedback = _chunkPSSG6C3Qcjs.useFeedback; exports.useIconContext = _chunkPSSG6C3Qcjs.useIconContext;
@@ -1,10 +1,108 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, Provider, Ref, RefCallback } from 'react';
2
+ import { ComponentType, ReactNode, Provider, Ref, RefCallback } from 'react';
3
3
  import * as react_native from 'react-native';
4
- import { PressableProps, StyleProp, ViewStyle, TextStyle } from 'react-native';
4
+ import { ImageSourcePropType, StyleProp, ImageStyle, PressableProps, ViewStyle, TextStyle } from 'react-native';
5
5
  import { SharedValue } from 'react-native-reanimated';
6
6
  import { g as XAUITheme, X as XAUIColors } from '../theme.type-C9bFJKFm.cjs';
7
7
 
8
+ /**
9
+ * The props Lucide, Ionicons and `react-native-vector-icons` all accept — the shape
10
+ * `as` is handed. It is a convention rather than an interface anyone published, which is
11
+ * exactly why `Icon` exists: without it every call site computes the two values by hand.
12
+ */
13
+ type IconComponentProps = {
14
+ size?: number;
15
+ color?: string;
16
+ };
17
+ type IconProps = {
18
+ /** An icon component. `size` and `color` are injected into it. */
19
+ as?: ComponentType<IconComponentProps>;
20
+ /** A raw `react-native-svg` element, cloned with the resolved size and colour. */
21
+ children?: ReactNode;
22
+ /** An image, tinted with the resolved colour. */
23
+ source?: ImageSourcePropType;
24
+ /** Overrides what the surrounding slot asked for. */
25
+ size?: number;
26
+ /** A raw value (R7), never a token. Overrides the slot's. */
27
+ color?: string;
28
+ style?: StyleProp<ImageStyle>;
29
+ };
30
+ /** What a component root publishes so the icons inside it need no props at all. */
31
+ type IconContextValue = {
32
+ size?: number;
33
+ color?: string;
34
+ };
35
+
36
+ /**
37
+ * The gap nobody else closes: an icon is a third-party component, so a slot context does
38
+ * not reach it and every call site ends up computing the colour by hand.
39
+ *
40
+ * ```tsx
41
+ * <Button variant="danger">
42
+ * <Button.Icon as={TrashIcon} /> {/* colour and size inherited, nothing to pass *\/}
43
+ * <Button.Label>Supprimer</Button.Label>
44
+ * </Button>
45
+ * ```
46
+ *
47
+ * Three accepted forms — a component through `as`, a raw SVG as children, or an image
48
+ * through `source` — and the resolution is the same for all three: an explicit prop, else
49
+ * what the surrounding slot published, else the theme.
50
+ */
51
+ declare function Icon({ as: Component, children, source, size, color, style, }: IconProps): react.JSX.Element;
52
+ declare namespace Icon {
53
+ var displayName: string;
54
+ }
55
+
56
+ /**
57
+ * Not a `createSlotContext`: that one throws outside its parent, and an `Icon` has to
58
+ * work on its own as much as inside a `Button`. An empty context is the honest default —
59
+ * nothing inherited, so the theme decides.
60
+ */
61
+ declare const IconContext: react.Context<IconContextValue>;
62
+ declare function useIconContext(): IconContextValue;
63
+
64
+ type PortalProps = {
65
+ children: ReactNode;
66
+ };
67
+ /**
68
+ * Renders its children into the nearest `PortalHost` instead of where it sits. What
69
+ * `Dialog`, `Sheet`, `Drawer` and `Snackbar` are built on: an overlay has to escape the
70
+ * clipping and stacking of whatever container happened to hold the trigger.
71
+ *
72
+ * Both halves run in layout effects rather than effects, which is deliberate: the content
73
+ * lands in the same commit as the trigger's, so an overlay neither shows one frame late
74
+ * nor survives one frame past the unmount that closed it. The unpublish sits in its own
75
+ * effect so that it does not depend on `children` — a re-publish then keeps the portal's
76
+ * place in the host's order instead of dropping it and re-adding it at the end.
77
+ */
78
+ declare function Portal({ children }: PortalProps): null;
79
+ declare namespace Portal {
80
+ var displayName: string;
81
+ }
82
+
83
+ type PortalMethods = {
84
+ addPortal: (key: string, element: ReactNode) => void;
85
+ removePortal: (key: string) => void;
86
+ };
87
+ /**
88
+ * `null` outside a host, and `Portal` treats that as "render nothing" rather than
89
+ * throwing: an app that forgot `PortalHost` should lose its overlays, not crash on the
90
+ * first `Dialog`.
91
+ */
92
+ declare const PortalContext: react.Context<PortalMethods | null>;
93
+
94
+ type PortalHostProps = {
95
+ children: ReactNode;
96
+ };
97
+ /**
98
+ * Where every `Portal` in the tree below renders. Mounted once, at the root of the app,
99
+ * above navigation — an overlay that renders inside a screen is clipped by it.
100
+ */
101
+ declare function PortalHost({ children }: PortalHostProps): react.JSX.Element;
102
+ declare namespace PortalHost {
103
+ var displayName: string;
104
+ }
105
+
8
106
  /**
9
107
  * What the root does under the finger. `scale-highlight` and `scale-ripple` mount their
10
108
  * overlay themselves; `scale` mounts none, which is what a root picks when it renders its
@@ -169,7 +267,7 @@ type ResolvedSlotAnimation = {
169
267
  */
170
268
  declare function resolveSlotAnimation(override: SlotAnimation | undefined, enabledByRoot: boolean, defaultOpacity: number, defaultDuration?: number): ResolvedSlotAnimation;
171
269
 
172
- declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "disabled" | "style" | "children"> & {
270
+ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "children" | "style" | "disabled"> & {
173
271
  isPressed?: boolean;
174
272
  isDisabled?: boolean;
175
273
  asChild?: boolean;
@@ -350,4 +448,4 @@ type SlotProps = MergeableProps & {
350
448
  */
351
449
  declare const Slot: react.ForwardRefExoticComponent<Omit<SlotProps, "ref"> & react.RefAttributes<unknown>>;
352
450
 
353
- export { type AnimationConfig, type AnimationProp, type AsChildProps, type Axes, type CompoundVariant, type FeedbackContext, type FeedbackVariant, HIGHLIGHT_OPACITY, type MergeableProps, PRESS_DURATION, PRESS_SCALE, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, type Recipe, type RecipeConfig, type ResolveArgs, type ResolvedAnimation, type ResolvedSelection, type ResolvedStyles, type Selection, Slot, type SlotAnimation, type SlotProps, type SlotStyle, type SlotStyles, type StateName, type States, type StyleFn, type TintArgs, type VariantColors, type VariantRole, type VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback };
451
+ export { type AnimationConfig, type AnimationProp, type AsChildProps, type Axes, type CompoundVariant, type FeedbackContext, type FeedbackVariant, HIGHLIGHT_OPACITY, Icon, type IconComponentProps, IconContext, type IconContextValue, type IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, type Recipe, type RecipeConfig, type ResolveArgs, type ResolvedAnimation, type ResolvedSelection, type ResolvedStyles, type Selection, Slot, type SlotAnimation, type SlotProps, type SlotStyle, type SlotStyles, type StateName, type States, type StyleFn, type TintArgs, type VariantColors, type VariantRole, type VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext };
@@ -1,10 +1,108 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, Provider, Ref, RefCallback } from 'react';
2
+ import { ComponentType, ReactNode, Provider, Ref, RefCallback } from 'react';
3
3
  import * as react_native from 'react-native';
4
- import { PressableProps, StyleProp, ViewStyle, TextStyle } from 'react-native';
4
+ import { ImageSourcePropType, StyleProp, ImageStyle, PressableProps, ViewStyle, TextStyle } from 'react-native';
5
5
  import { SharedValue } from 'react-native-reanimated';
6
6
  import { g as XAUITheme, X as XAUIColors } from '../theme.type-C9bFJKFm.js';
7
7
 
8
+ /**
9
+ * The props Lucide, Ionicons and `react-native-vector-icons` all accept — the shape
10
+ * `as` is handed. It is a convention rather than an interface anyone published, which is
11
+ * exactly why `Icon` exists: without it every call site computes the two values by hand.
12
+ */
13
+ type IconComponentProps = {
14
+ size?: number;
15
+ color?: string;
16
+ };
17
+ type IconProps = {
18
+ /** An icon component. `size` and `color` are injected into it. */
19
+ as?: ComponentType<IconComponentProps>;
20
+ /** A raw `react-native-svg` element, cloned with the resolved size and colour. */
21
+ children?: ReactNode;
22
+ /** An image, tinted with the resolved colour. */
23
+ source?: ImageSourcePropType;
24
+ /** Overrides what the surrounding slot asked for. */
25
+ size?: number;
26
+ /** A raw value (R7), never a token. Overrides the slot's. */
27
+ color?: string;
28
+ style?: StyleProp<ImageStyle>;
29
+ };
30
+ /** What a component root publishes so the icons inside it need no props at all. */
31
+ type IconContextValue = {
32
+ size?: number;
33
+ color?: string;
34
+ };
35
+
36
+ /**
37
+ * The gap nobody else closes: an icon is a third-party component, so a slot context does
38
+ * not reach it and every call site ends up computing the colour by hand.
39
+ *
40
+ * ```tsx
41
+ * <Button variant="danger">
42
+ * <Button.Icon as={TrashIcon} /> {/* colour and size inherited, nothing to pass *\/}
43
+ * <Button.Label>Supprimer</Button.Label>
44
+ * </Button>
45
+ * ```
46
+ *
47
+ * Three accepted forms — a component through `as`, a raw SVG as children, or an image
48
+ * through `source` — and the resolution is the same for all three: an explicit prop, else
49
+ * what the surrounding slot published, else the theme.
50
+ */
51
+ declare function Icon({ as: Component, children, source, size, color, style, }: IconProps): react.JSX.Element;
52
+ declare namespace Icon {
53
+ var displayName: string;
54
+ }
55
+
56
+ /**
57
+ * Not a `createSlotContext`: that one throws outside its parent, and an `Icon` has to
58
+ * work on its own as much as inside a `Button`. An empty context is the honest default —
59
+ * nothing inherited, so the theme decides.
60
+ */
61
+ declare const IconContext: react.Context<IconContextValue>;
62
+ declare function useIconContext(): IconContextValue;
63
+
64
+ type PortalProps = {
65
+ children: ReactNode;
66
+ };
67
+ /**
68
+ * Renders its children into the nearest `PortalHost` instead of where it sits. What
69
+ * `Dialog`, `Sheet`, `Drawer` and `Snackbar` are built on: an overlay has to escape the
70
+ * clipping and stacking of whatever container happened to hold the trigger.
71
+ *
72
+ * Both halves run in layout effects rather than effects, which is deliberate: the content
73
+ * lands in the same commit as the trigger's, so an overlay neither shows one frame late
74
+ * nor survives one frame past the unmount that closed it. The unpublish sits in its own
75
+ * effect so that it does not depend on `children` — a re-publish then keeps the portal's
76
+ * place in the host's order instead of dropping it and re-adding it at the end.
77
+ */
78
+ declare function Portal({ children }: PortalProps): null;
79
+ declare namespace Portal {
80
+ var displayName: string;
81
+ }
82
+
83
+ type PortalMethods = {
84
+ addPortal: (key: string, element: ReactNode) => void;
85
+ removePortal: (key: string) => void;
86
+ };
87
+ /**
88
+ * `null` outside a host, and `Portal` treats that as "render nothing" rather than
89
+ * throwing: an app that forgot `PortalHost` should lose its overlays, not crash on the
90
+ * first `Dialog`.
91
+ */
92
+ declare const PortalContext: react.Context<PortalMethods | null>;
93
+
94
+ type PortalHostProps = {
95
+ children: ReactNode;
96
+ };
97
+ /**
98
+ * Where every `Portal` in the tree below renders. Mounted once, at the root of the app,
99
+ * above navigation — an overlay that renders inside a screen is clipped by it.
100
+ */
101
+ declare function PortalHost({ children }: PortalHostProps): react.JSX.Element;
102
+ declare namespace PortalHost {
103
+ var displayName: string;
104
+ }
105
+
8
106
  /**
9
107
  * What the root does under the finger. `scale-highlight` and `scale-ripple` mount their
10
108
  * overlay themselves; `scale` mounts none, which is what a root picks when it renders its
@@ -169,7 +267,7 @@ type ResolvedSlotAnimation = {
169
267
  */
170
268
  declare function resolveSlotAnimation(override: SlotAnimation | undefined, enabledByRoot: boolean, defaultOpacity: number, defaultDuration?: number): ResolvedSlotAnimation;
171
269
 
172
- declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "disabled" | "style" | "children"> & {
270
+ declare const PressableFeedback: react.ForwardRefExoticComponent<Omit<react_native.PressableProps, "children" | "style" | "disabled"> & {
173
271
  isPressed?: boolean;
174
272
  isDisabled?: boolean;
175
273
  asChild?: boolean;
@@ -350,4 +448,4 @@ type SlotProps = MergeableProps & {
350
448
  */
351
449
  declare const Slot: react.ForwardRefExoticComponent<Omit<SlotProps, "ref"> & react.RefAttributes<unknown>>;
352
450
 
353
- export { type AnimationConfig, type AnimationProp, type AsChildProps, type Axes, type CompoundVariant, type FeedbackContext, type FeedbackVariant, HIGHLIGHT_OPACITY, type MergeableProps, PRESS_DURATION, PRESS_SCALE, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, type Recipe, type RecipeConfig, type ResolveArgs, type ResolvedAnimation, type ResolvedSelection, type ResolvedStyles, type Selection, Slot, type SlotAnimation, type SlotProps, type SlotStyle, type SlotStyles, type StateName, type States, type StyleFn, type TintArgs, type VariantColors, type VariantRole, type VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback };
451
+ export { type AnimationConfig, type AnimationProp, type AsChildProps, type Axes, type CompoundVariant, type FeedbackContext, type FeedbackVariant, HIGHLIGHT_OPACITY, Icon, type IconComponentProps, IconContext, type IconContextValue, type IconProps, type MergeableProps, PRESS_DURATION, PRESS_SCALE, Portal, PortalContext, PortalHost, type PortalHostProps, type PortalMethods, type PortalProps, type PossibleRef, PressableFeedback, type PressableFeedbackHighlightProps, type PressableFeedbackProps, type PressableFeedbackRippleProps, RELEASE_DURATION, RIPPLE_COVERAGE, RIPPLE_DURATION, RIPPLE_OPACITY, type Recipe, type RecipeConfig, type ResolveArgs, type ResolvedAnimation, type ResolvedSelection, type ResolvedStyles, type Selection, Slot, type SlotAnimation, type SlotProps, type SlotStyle, type SlotStyles, type StateName, type States, type StyleFn, type TintArgs, type VariantColors, type VariantRole, type VariantTokens, childrenToString, createRecipe, createSlotContext, mergeProps, mergeRefs, resolveAnimation, resolveSlotAnimation, useFeedback, useIconContext };
@@ -1,7 +1,12 @@
1
1
  import {
2
2
  HIGHLIGHT_OPACITY,
3
+ Icon,
4
+ IconContext,
3
5
  PRESS_DURATION,
4
6
  PRESS_SCALE,
7
+ Portal,
8
+ PortalContext,
9
+ PortalHost,
5
10
  PressableFeedback,
6
11
  RELEASE_DURATION,
7
12
  RIPPLE_COVERAGE,
@@ -15,13 +20,19 @@ import {
15
20
  mergeRefs,
16
21
  resolveAnimation,
17
22
  resolveSlotAnimation,
18
- useFeedback
19
- } from "../chunk-QAMNNTGM.js";
23
+ useFeedback,
24
+ useIconContext
25
+ } from "../chunk-AUDOMZR3.js";
20
26
  import "../chunk-X2K2FX3W.js";
21
27
  export {
22
28
  HIGHLIGHT_OPACITY,
29
+ Icon,
30
+ IconContext,
23
31
  PRESS_DURATION,
24
32
  PRESS_SCALE,
33
+ Portal,
34
+ PortalContext,
35
+ PortalHost,
25
36
  PressableFeedback,
26
37
  RELEASE_DURATION,
27
38
  RIPPLE_COVERAGE,
@@ -35,5 +46,6 @@ export {
35
46
  mergeRefs,
36
47
  resolveAnimation,
37
48
  resolveSlotAnimation,
38
- useFeedback
49
+ useFeedback,
50
+ useIconContext
39
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaui/native",
3
- "version": "0.9.1-alpha.3",
3
+ "version": "0.9.1-alpha.5",
4
4
  "description": "Composition-first React Native UI components with native animations powered by Reanimated",
5
5
  "keywords": [
6
6
  "react-native",