@kanso-labs/react-native-kanso-ui 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +4 -1
  2. package/dist/badge/index.js +74 -0
  3. package/dist/badge/index.js.map +1 -0
  4. package/dist/badge/styles.js +51 -0
  5. package/dist/badge/styles.js.map +1 -0
  6. package/dist/button/index.d.ts +1 -1
  7. package/dist/button/index.js +1 -1
  8. package/dist/button/pending.js +1 -1
  9. package/dist/button/slots.d.ts +2 -2
  10. package/dist/chip/index.js +2 -2
  11. package/dist/components/app-bar/index.d.ts +111 -0
  12. package/dist/components/app-bar/index.js +341 -0
  13. package/dist/components/app-bar/index.js.map +1 -0
  14. package/dist/components/avatar/index.d.ts +1 -1
  15. package/dist/components/button/index.d.ts +1 -1
  16. package/dist/components/button/index.js +2 -2
  17. package/dist/components/card/index.d.ts +1 -1
  18. package/dist/components/card/index.js +3 -3
  19. package/dist/components/checkbox/index.d.ts +1 -1
  20. package/dist/components/checkbox/index.js +1 -1
  21. package/dist/components/chip/index.d.ts +1 -1
  22. package/dist/components/chip/index.js +1 -1
  23. package/dist/components/chip-group/index.d.ts +1 -1
  24. package/dist/components/chip-group/index.js +4 -4
  25. package/dist/components/copy-field/index.d.ts +1 -1
  26. package/dist/components/copy-field/index.js +1 -1
  27. package/dist/components/currency/index.d.ts +1 -1
  28. package/dist/components/currency/index.js +1 -1
  29. package/dist/components/dialog/index.d.ts +1 -1
  30. package/dist/components/dialog/index.js +2 -2
  31. package/dist/components/icon-button/index.d.ts +1 -1
  32. package/dist/components/icon-button/index.js +2 -2
  33. package/dist/components/link/index.d.ts +1 -1
  34. package/dist/components/link/index.js +3 -3
  35. package/dist/components/list/index.d.ts +1 -1
  36. package/dist/components/list/index.js +5 -5
  37. package/dist/components/list-detail/index.d.ts +56 -0
  38. package/dist/components/list-detail/index.js +169 -0
  39. package/dist/components/list-detail/index.js.map +1 -0
  40. package/dist/components/list-item/index.d.ts +1 -1
  41. package/dist/components/list-item/index.js +1 -1
  42. package/dist/components/menu/index.d.ts +1 -1
  43. package/dist/components/menu/index.js +6 -6
  44. package/dist/components/meter/index.d.ts +1 -1
  45. package/dist/components/meter/index.js +1 -1
  46. package/dist/components/navigation-bar/index.d.ts +170 -0
  47. package/dist/components/navigation-bar/index.js +494 -0
  48. package/dist/components/navigation-bar/index.js.map +1 -0
  49. package/dist/components/number-field/index.d.ts +1 -1
  50. package/dist/components/number-field/index.js +5 -5
  51. package/dist/components/popover/index.d.ts +1 -1
  52. package/dist/components/popover/index.js +2 -2
  53. package/dist/components/product-icon/index.d.ts +1 -1
  54. package/dist/components/progress-indicator/index.d.ts +1 -1
  55. package/dist/components/progress-indicator/index.js +3 -3
  56. package/dist/components/radio-group/index.d.ts +1 -1
  57. package/dist/components/radio-group/index.js +3 -3
  58. package/dist/components/search-field/index.d.ts +1 -1
  59. package/dist/components/search-field/index.js +5 -5
  60. package/dist/components/segmented-button/index.d.ts +1 -1
  61. package/dist/components/segmented-button/index.js +5 -5
  62. package/dist/components/separator/index.d.ts +1 -1
  63. package/dist/components/separator/index.js +1 -1
  64. package/dist/components/sheet/index.d.ts +1 -1
  65. package/dist/components/sheet/index.js +3 -3
  66. package/dist/components/snackbar/index.d.ts +1 -1
  67. package/dist/components/snackbar/index.js +4 -4
  68. package/dist/components/stack/index.d.ts +1 -1
  69. package/dist/components/stack/index.js +1 -1
  70. package/dist/components/switch/index.d.ts +1 -1
  71. package/dist/components/switch/index.js +4 -4
  72. package/dist/components/text/index.d.ts +1 -1
  73. package/dist/components/text/index.js +1 -1
  74. package/dist/components/text-field/index.d.ts +1 -1
  75. package/dist/components/text-field/index.js +1 -1
  76. package/dist/control/checkbox-box.js +2 -2
  77. package/dist/control/index.js +1 -1
  78. package/dist/field/index.d.ts +1 -1
  79. package/dist/field/index.js +4 -4
  80. package/dist/form/index.d.ts +1 -1
  81. package/dist/glyphs/index.js +2 -2
  82. package/dist/hooks/useAppBarScroll.d.ts +56 -0
  83. package/dist/hooks/useAppBarScroll.js +87 -0
  84. package/dist/hooks/useAppBarScroll.js.map +1 -0
  85. package/dist/index.d.ts +7 -3
  86. package/dist/index.js +7 -3
  87. package/dist/indicator/index.d.ts +2 -2
  88. package/dist/indicator/index.js +3 -3
  89. package/dist/indicator/motion.js +1 -1
  90. package/dist/mark/index.d.ts +1 -1
  91. package/dist/mark/index.js +2 -2
  92. package/dist/modal/index.d.ts +1 -1
  93. package/dist/modal/index.js +2 -2
  94. package/dist/navigation/index.d.ts +29 -0
  95. package/dist/navigation/index.js +405 -0
  96. package/dist/navigation/index.js.map +1 -0
  97. package/dist/navigation/styles.js +61 -0
  98. package/dist/navigation/styles.js.map +1 -0
  99. package/dist/overlay/anchored.d.ts +2 -2
  100. package/dist/overlay/anchored.js +1 -1
  101. package/dist/overlay/host.d.ts +2 -2
  102. package/dist/overlay/host.js +1 -1
  103. package/dist/overlay/panel.js +2 -2
  104. package/dist/press/index.js +75 -69
  105. package/dist/press/index.js.map +1 -1
  106. package/dist/router/index.js +1 -1
  107. package/dist/row/index.js +1 -1
  108. package/dist/theme/scope.js +1 -1
  109. package/dist/theme-scope.d.ts +1 -1
  110. package/dist/theme-scope.js +1 -1
  111. package/dist/typography/fonts.js +1 -1
  112. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  import "./styles.js";
2
- import { ComponentRef, Ref } from "react";
3
2
  import { ImageProps, StyleProp, View, ViewProps, ViewStyle } from "react-native";
3
+ import { ComponentRef, Ref } from "react";
4
4
  //#region src/mark/index.d.ts
5
5
  /** The native props a picture's own `Image` takes, as Avatar and ProductIcon take them. */
6
6
  type MarkImageProps = Pick<ImageProps, 'crossOrigin' | 'fadeDuration' | 'progressiveRenderingEnabled' | 'referrerPolicy' | 'resizeMethod'>;
@@ -1,13 +1,13 @@
1
- import { PersonGlyph } from "../glyphs/index.js";
2
1
  import { useTheme } from "../theme/scope.js";
3
2
  import { composeStyles } from "../theme/styles.js";
4
3
  import { useTypeRole } from "../typography/roles.js";
4
+ import { PersonGlyph } from "../glyphs/index.js";
5
5
  import { useImageLoadingStatus } from "./image.js";
6
6
  import { initialOfThing, initialsOfPerson } from "./initials.js";
7
7
  import { DIAMETERS, GLYPH_SHARE, initialsStylesOf, markStyles, markStylesOf } from "./styles.js";
8
8
  import { c } from "react/compiler-runtime";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
9
  import { Image, Text, View } from "react-native";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
11
  //#region src/mark/index.tsx
12
12
  const KINDS = {
13
13
  person: {
@@ -1,8 +1,8 @@
1
1
  import "../button/slots.js";
2
- import { ReactNode } from "react";
3
2
  import { HostInstance, ViewProps, ViewStyle } from "react-native";
4
3
  import "react-native-reanimated";
5
4
  import "react-native-safe-area-context";
5
+ import { ReactNode } from "react";
6
6
  import "react-stately/useOverlayTriggerState";
7
7
  //#region src/modal/index.d.ts
8
8
  /** Whether a modal surface is open, and who holds that state. */
@@ -1,13 +1,13 @@
1
1
  import { useTheme } from "../theme/scope.js";
2
2
  import { composeStyles, themedStyles } from "../theme/styles.js";
3
+ import { withOpacity } from "../theme/color.js";
3
4
  import { ButtonSlotContext } from "../button/slots.js";
4
5
  import { AnimatedPressable } from "../button/index.js";
5
- import { withOpacity } from "../theme/color.js";
6
6
  import { OverlayHost } from "../overlay/host.js";
7
7
  import { c } from "react/compiler-runtime";
8
+ import { AccessibilityInfo, I18nManager, Modal, Platform, StyleSheet } from "react-native";
8
9
  import { useEffect, useRef, useState } from "react";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
- import { AccessibilityInfo, I18nManager, Modal, Platform, StyleSheet } from "react-native";
11
11
  import { useOverlayTriggerState } from "react-stately/useOverlayTriggerState";
12
12
  //#region src/modal/index.tsx
13
13
  const NO_INSETS = {
@@ -0,0 +1,29 @@
1
+ import { PressableProps, StyleProp, View, ViewStyle } from "react-native";
2
+ import { ComponentRef, ReactNode, Ref } from "react";
3
+ //#region src/navigation/index.d.ts
4
+ type NavigationDestinationProps = Omit<PressableProps, 'children' | 'disabled' | 'style'> & {
5
+ /**
6
+ * A badge on the icon: `true` for the badges page's small dot, a number
7
+ * for the large badge holding it. The badge is hidden from a screen
8
+ * reader, so say what it says in the destination's `aria-label` too:
9
+ * "First item, 3 new".
10
+ */
11
+ readonly badge?: boolean | number | undefined;
12
+ /** The destination's name, drawn as its label. */
13
+ readonly children?: ReactNode;
14
+ /**
15
+ * The destination's icon, at the page's 24dp, which the destination hands
16
+ * its colour and size through `useIconStyle()`.
17
+ */
18
+ readonly icon?: ReactNode;
19
+ /**
20
+ * Draws the destination disabled, and it takes no press.
21
+ * @default false
22
+ */
23
+ readonly isDisabled?: boolean;
24
+ readonly ref?: Ref<ComponentRef<typeof View>>;
25
+ readonly style?: StyleProp<ViewStyle>;
26
+ };
27
+ //#endregion
28
+ export type { NavigationDestinationProps };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,405 @@
1
+ import { IconStyleContext } from "../glyphs/icon-style.js";
2
+ import { useTheme } from "../theme/scope.js";
3
+ import { composeStyles } from "../theme/styles.js";
4
+ import { hitSlop, usePressFeedback } from "../press/index.js";
5
+ import { useTypeRole } from "../typography/roles.js";
6
+ import { withOpacity } from "../theme/color.js";
7
+ import { Badge } from "../badge/index.js";
8
+ import { INDICATOR, styles, stylesOf } from "./styles.js";
9
+ import { c } from "react/compiler-runtime";
10
+ import { Pressable, Text, View } from "react-native";
11
+ import Animated, { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
12
+ import { createContext, use, useEffect } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+ //#region src/navigation/index.tsx
15
+ const GROWN_FROM = .4;
16
+ const FADE_SHARE = .2;
17
+ const ICON_SIZE = 24;
18
+ const NavigationContext = createContext({
19
+ form: "vertical",
20
+ measuring: false
21
+ });
22
+ /**
23
+ * The active indicator's fill, which grows from its centre while its
24
+ * destination is current and shrinks back once it is not.
25
+ */
26
+ function ActiveIndicator(t0) {
27
+ const $ = c(12);
28
+ const { selected } = t0;
29
+ const theme = useTheme();
30
+ const { colors, motion } = theme;
31
+ const reduceMotion = useReducedMotion();
32
+ const progress = useSharedValue(selected ? 1 : 0);
33
+ let t1;
34
+ let t2;
35
+ if ($[0] !== motion || $[1] !== progress || $[2] !== reduceMotion || $[3] !== selected) {
36
+ t1 = () => {
37
+ const target = selected ? 1 : 0;
38
+ progress.set(reduceMotion ? target : withTiming(target, {
39
+ duration: motion.durationLong2,
40
+ easing: Easing.bezier(...motion.easingEmphasized)
41
+ }));
42
+ };
43
+ t2 = [
44
+ motion,
45
+ progress,
46
+ reduceMotion,
47
+ selected
48
+ ];
49
+ $[0] = motion;
50
+ $[1] = progress;
51
+ $[2] = reduceMotion;
52
+ $[3] = selected;
53
+ $[4] = t1;
54
+ $[5] = t2;
55
+ } else {
56
+ t1 = $[4];
57
+ t2 = $[5];
58
+ }
59
+ useEffect(t1, t2);
60
+ const motionStyle = useAnimatedStyle(() => {
61
+ "worklet";
62
+ const grown = progress.get();
63
+ return {
64
+ opacity: Math.min(1, grown / FADE_SHARE),
65
+ transform: [{ scaleX: GROWN_FROM + .6 * grown }]
66
+ };
67
+ });
68
+ let t3;
69
+ if ($[6] !== colors.secondaryContainer || $[7] !== motionStyle || $[8] !== theme) {
70
+ t3 = composeStyles(styles.fill, stylesOf(theme).pill, { backgroundColor: colors.secondaryContainer }, motionStyle);
71
+ $[6] = colors.secondaryContainer;
72
+ $[7] = motionStyle;
73
+ $[8] = theme;
74
+ $[9] = t3;
75
+ } else t3 = $[9];
76
+ let t4;
77
+ if ($[10] !== t3) {
78
+ t4 = /* @__PURE__ */ jsx(Animated.View, { style: t3 });
79
+ $[10] = t3;
80
+ $[11] = t4;
81
+ } else t4 = $[11];
82
+ return t4;
83
+ }
84
+ /**
85
+ * What a destination draws over its indicator: the icon and its badge, and
86
+ * in a horizontal destination the label before them in the tree, which the
87
+ * pill's reversed row draws after them.
88
+ */
89
+ function DestinationContent(t0) {
90
+ const $ = c(20);
91
+ const { badge, form, icon, isDisabled, label, selected } = t0;
92
+ const theme = useTheme();
93
+ const horizontal = form === "horizontal";
94
+ let t1;
95
+ if ($[0] !== form || $[1] !== horizontal || $[2] !== isDisabled || $[3] !== label || $[4] !== selected) {
96
+ t1 = horizontal ? /* @__PURE__ */ jsx(Label, {
97
+ form,
98
+ isDisabled,
99
+ selected,
100
+ children: label
101
+ }) : null;
102
+ $[0] = form;
103
+ $[1] = horizontal;
104
+ $[2] = isDisabled;
105
+ $[3] = label;
106
+ $[4] = selected;
107
+ $[5] = t1;
108
+ } else t1 = $[5];
109
+ let t2;
110
+ if ($[6] !== isDisabled || $[7] !== selected || $[8] !== theme) {
111
+ t2 = iconStyleOf(iconColorOf(theme, isDisabled, selected));
112
+ $[6] = isDisabled;
113
+ $[7] = selected;
114
+ $[8] = theme;
115
+ $[9] = t2;
116
+ } else t2 = $[9];
117
+ let t3;
118
+ if ($[10] !== badge || $[11] !== horizontal || $[12] !== icon) {
119
+ t3 = badge === void 0 || badge === false ? icon : /* @__PURE__ */ jsx(Badge, {
120
+ count: badge === true ? void 0 : badge,
121
+ inFlow: horizontal,
122
+ children: icon
123
+ });
124
+ $[10] = badge;
125
+ $[11] = horizontal;
126
+ $[12] = icon;
127
+ $[13] = t3;
128
+ } else t3 = $[13];
129
+ let t4;
130
+ if ($[14] !== t2 || $[15] !== t3) {
131
+ t4 = /* @__PURE__ */ jsx(View, {
132
+ style: styles.icon,
133
+ children: /* @__PURE__ */ jsx(IconStyleContext, {
134
+ value: t2,
135
+ children: t3
136
+ })
137
+ });
138
+ $[14] = t2;
139
+ $[15] = t3;
140
+ $[16] = t4;
141
+ } else t4 = $[16];
142
+ let t5;
143
+ if ($[17] !== t1 || $[18] !== t4) {
144
+ t5 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t1, t4] });
145
+ $[17] = t1;
146
+ $[18] = t4;
147
+ $[19] = t5;
148
+ } else t5 = $[19];
149
+ return t5;
150
+ }
151
+ /** The colour a destination draws its icon in. */
152
+ function iconColorOf({ colors, stateLayerOpacity }, isDisabled, selected) {
153
+ if (isDisabled) return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent);
154
+ return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant;
155
+ }
156
+ function iconStyleOf(color) {
157
+ return {
158
+ color,
159
+ size: ICON_SIZE
160
+ };
161
+ }
162
+ /** A destination's label, on one line, in label medium. */
163
+ function Label(t0) {
164
+ const $ = c(9);
165
+ const { children, form, isDisabled, selected } = t0;
166
+ const theme = useTheme();
167
+ const role = useTypeRole("labelMedium");
168
+ let t1;
169
+ if ($[0] !== form || $[1] !== isDisabled || $[2] !== role || $[3] !== selected || $[4] !== theme) {
170
+ t1 = composeStyles(role, styles.label, { color: labelColorOf(theme, form, isDisabled, selected) });
171
+ $[0] = form;
172
+ $[1] = isDisabled;
173
+ $[2] = role;
174
+ $[3] = selected;
175
+ $[4] = theme;
176
+ $[5] = t1;
177
+ } else t1 = $[5];
178
+ let t2;
179
+ if ($[6] !== children || $[7] !== t1) {
180
+ t2 = /* @__PURE__ */ jsx(Text, {
181
+ numberOfLines: 1,
182
+ style: t1,
183
+ children
184
+ });
185
+ $[6] = children;
186
+ $[7] = t1;
187
+ $[8] = t2;
188
+ } else t2 = $[8];
189
+ return t2;
190
+ }
191
+ /** The colour a destination draws its label in, which its form decides. */
192
+ function labelColorOf(theme, form, isDisabled, selected) {
193
+ return selected && !isDisabled && form === "vertical" ? theme.colors.secondary : iconColorOf(theme, isDisabled, selected);
194
+ }
195
+ function nameOf(children) {
196
+ return typeof children === "string" ? children : void 0;
197
+ }
198
+ /**
199
+ * One destination, in the form the bar around it asks for: an icon and a
200
+ * label, and the active indicator behind the icon while it is current. A
201
+ * `tab` reporting whether it is selected.
202
+ */
203
+ function NavigationDestination(t0) {
204
+ const $ = c(54);
205
+ let ariaLabel;
206
+ let badge;
207
+ let children;
208
+ let icon;
209
+ let onBlur;
210
+ let onFocus;
211
+ let onHoverIn;
212
+ let onHoverOut;
213
+ let onPressIn;
214
+ let onPressOut;
215
+ let props;
216
+ let selected;
217
+ let style;
218
+ let t1;
219
+ if ($[0] !== t0) {
220
+ ({"aria-label": ariaLabel, badge, children, icon, isDisabled: t1, onBlur, onFocus, onHoverIn, onHoverOut, onPressIn, onPressOut, selected, style, ...props} = t0);
221
+ $[0] = t0;
222
+ $[1] = ariaLabel;
223
+ $[2] = badge;
224
+ $[3] = children;
225
+ $[4] = icon;
226
+ $[5] = onBlur;
227
+ $[6] = onFocus;
228
+ $[7] = onHoverIn;
229
+ $[8] = onHoverOut;
230
+ $[9] = onPressIn;
231
+ $[10] = onPressOut;
232
+ $[11] = props;
233
+ $[12] = selected;
234
+ $[13] = style;
235
+ $[14] = t1;
236
+ } else {
237
+ ariaLabel = $[1];
238
+ badge = $[2];
239
+ children = $[3];
240
+ icon = $[4];
241
+ onBlur = $[5];
242
+ onFocus = $[6];
243
+ onHoverIn = $[7];
244
+ onHoverOut = $[8];
245
+ onPressIn = $[9];
246
+ onPressOut = $[10];
247
+ props = $[11];
248
+ selected = $[12];
249
+ style = $[13];
250
+ t1 = $[14];
251
+ }
252
+ const isDisabled = t1 === void 0 ? false : t1;
253
+ const theme = useTheme();
254
+ const { form, measuring } = use(NavigationContext);
255
+ const own = stylesOf(theme);
256
+ const horizontal = form === "horizontal";
257
+ const feedback = usePressFeedback({
258
+ area: horizontal ? void 0 : INDICATOR,
259
+ color: theme.colors.onSecondaryContainer,
260
+ corners: own.pill,
261
+ disabled: isDisabled,
262
+ onBlur,
263
+ onFocus,
264
+ onHoverIn,
265
+ onHoverOut,
266
+ onPressIn,
267
+ onPressOut
268
+ });
269
+ let t2;
270
+ if ($[15] !== badge || $[16] !== children || $[17] !== form || $[18] !== icon || $[19] !== isDisabled || $[20] !== selected) {
271
+ t2 = /* @__PURE__ */ jsx(DestinationContent, {
272
+ badge,
273
+ form,
274
+ icon,
275
+ isDisabled,
276
+ label: children,
277
+ selected
278
+ });
279
+ $[15] = badge;
280
+ $[16] = children;
281
+ $[17] = form;
282
+ $[18] = icon;
283
+ $[19] = isDisabled;
284
+ $[20] = selected;
285
+ $[21] = t2;
286
+ } else t2 = $[21];
287
+ const content = t2;
288
+ if (measuring) return /* @__PURE__ */ jsx(View, {
289
+ style: own.horizontal,
290
+ children: content
291
+ });
292
+ if (horizontal) {
293
+ let t3;
294
+ if ($[22] !== ariaLabel || $[23] !== children) {
295
+ t3 = ariaLabel ?? nameOf(children);
296
+ $[22] = ariaLabel;
297
+ $[23] = children;
298
+ $[24] = t3;
299
+ } else t3 = $[24];
300
+ let t4;
301
+ if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
302
+ t4 = hitSlop(40);
303
+ $[25] = t4;
304
+ } else t4 = $[25];
305
+ let t5;
306
+ if ($[26] !== selected) {
307
+ t5 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
308
+ $[26] = selected;
309
+ $[27] = t5;
310
+ } else t5 = $[27];
311
+ return /* @__PURE__ */ jsxs(Pressable, {
312
+ "aria-label": t3,
313
+ "aria-selected": selected,
314
+ hitSlop: t4,
315
+ role: "tab",
316
+ ...props,
317
+ ...feedback.handlers,
318
+ disabled: isDisabled,
319
+ style: composeStyles(own.horizontal, feedback.ring, style),
320
+ children: [
321
+ t5,
322
+ feedback.layer,
323
+ content
324
+ ]
325
+ });
326
+ }
327
+ const T0 = Pressable;
328
+ let t3;
329
+ if ($[28] !== ariaLabel || $[29] !== children) {
330
+ t3 = ariaLabel ?? nameOf(children);
331
+ $[28] = ariaLabel;
332
+ $[29] = children;
333
+ $[30] = t3;
334
+ } else t3 = $[30];
335
+ const t4 = "tab";
336
+ const t5 = feedback.handlers;
337
+ const t6 = composeStyles(own.vertical, style);
338
+ let t7;
339
+ if ($[31] !== children || $[32] !== form || $[33] !== isDisabled || $[34] !== selected) {
340
+ t7 = /* @__PURE__ */ jsx(Label, {
341
+ form,
342
+ isDisabled,
343
+ selected,
344
+ children
345
+ });
346
+ $[31] = children;
347
+ $[32] = form;
348
+ $[33] = isDisabled;
349
+ $[34] = selected;
350
+ $[35] = t7;
351
+ } else t7 = $[35];
352
+ const T1 = View;
353
+ const t8 = composeStyles(own.indicator, feedback.ring);
354
+ let t9;
355
+ if ($[36] !== selected) {
356
+ t9 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
357
+ $[36] = selected;
358
+ $[37] = t9;
359
+ } else t9 = $[37];
360
+ let t10;
361
+ if ($[38] !== T1 || $[39] !== content || $[40] !== feedback.layer || $[41] !== t8 || $[42] !== t9) {
362
+ t10 = /* @__PURE__ */ jsxs(T1, {
363
+ style: t8,
364
+ children: [
365
+ t9,
366
+ feedback.layer,
367
+ content
368
+ ]
369
+ });
370
+ $[38] = T1;
371
+ $[39] = content;
372
+ $[40] = feedback.layer;
373
+ $[41] = t8;
374
+ $[42] = t9;
375
+ $[43] = t10;
376
+ } else t10 = $[43];
377
+ let t11;
378
+ if ($[44] !== T0 || $[45] !== feedback.handlers || $[46] !== isDisabled || $[47] !== props || $[48] !== selected || $[49] !== t10 || $[50] !== t3 || $[51] !== t6 || $[52] !== t7) {
379
+ t11 = /* @__PURE__ */ jsxs(T0, {
380
+ "aria-label": t3,
381
+ "aria-selected": selected,
382
+ role: t4,
383
+ ...props,
384
+ ...t5,
385
+ disabled: isDisabled,
386
+ style: t6,
387
+ children: [t7, t10]
388
+ });
389
+ $[44] = T0;
390
+ $[45] = feedback.handlers;
391
+ $[46] = isDisabled;
392
+ $[47] = props;
393
+ $[48] = selected;
394
+ $[49] = t10;
395
+ $[50] = t3;
396
+ $[51] = t6;
397
+ $[52] = t7;
398
+ $[53] = t11;
399
+ } else t11 = $[53];
400
+ return t11;
401
+ }
402
+ //#endregion
403
+ export { NavigationContext, NavigationDestination, iconColorOf, labelColorOf };
404
+
405
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","ColorValue","PressableProps","StyleProp","TextStyle","ViewStyle","AnimatedStyle","createContext","use","useEffect","Text","NativeText","Pressable","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","IconStyle","ResolvedTheme","Badge","IconStyleContext","hitSlop","usePressFeedback","withOpacity","useTheme","composeStyles","useTypeRole","INDICATOR","PILL_HEIGHT","styles","stylesOf","NavigationContextValue","form","NavigationForm","measuring","selectedRoute","NavigationDestinationProps","Omit","badge","children","icon","isDisabled","ref","style","GROWN_FROM","FADE_SHARE","ICON_SIZE","NavigationContext","ActiveIndicator","t0","$","_c","selected","theme","colors","motion","reduceMotion","progress","t1","t2","target","set","duration","durationLong2","easing","bezier","easingEmphasized","motionStyle","grown","get","opacity","Math","min","transform","scaleX","t3","secondaryContainer","fill","pill","backgroundColor","t4","DestinationContent","label","horizontal","iconStyleOf","iconColorOf","undefined","t5","stateLayerOpacity","onSurface","disabledContent","onSecondaryContainer","onSurfaceVariant","color","size","Label","role","labelColorOf","secondary","nameOf","NavigationDestination","ariaLabel","onBlur","onFocus","onHoverIn","onHoverOut","onPressIn","onPressOut","props","own","feedback","area","corners","disabled","content","Symbol","for","handlers","ring","layer","T0","t6","vertical","t7","T1","t8","indicator","t9","t10","t11","_c","NativeText"],"sources":["../../src/navigation/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n ColorValue,\n PressableProps,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { createContext, use, useEffect } from 'react'\nimport { Text as NativeText, Pressable, View } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { IconStyle } from '../glyphs/icon-style'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { Badge } from '../badge'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { hitSlop, usePressFeedback } from '../press'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles } from '../theme/styles'\nimport { useTypeRole } from '../typography/roles'\nimport { INDICATOR, PILL_HEIGHT, styles, stylesOf } from './styles'\n\n// The destination NavigationBar draws, in the two forms its page gives it,\n// as kanso-ui's src/navigation draws it. Apart from the bar, so the forms it\n// shares with a rail cannot drift.\n//\n// A vertical destination puts its icon in the page's 56dp by 32dp active\n// indicator with the label 4dp under it, in label medium. A horizontal one is\n// a 40dp pill holding the icon and the label side by side, 16dp in at either\n// end with 4dp between the two, in label medium too. Which one a destination\n// draws is the bar's to say, through the context it hands them.\n//\n// The current destination's indicator is the secondary container, with its\n// icon in on secondary container and, under the indicator, its label in\n// secondary; every other is on surface variant. A label set inside the pill,\n// as a horizontal destination sets it, takes on secondary container instead,\n// as on web: secondary over secondary container is not a pair a scheme is\n// held to, and on secondary container is.\n//\n// **The indicator grows** when its destination becomes current, and shrinks\n// back when another does: from 40% of its width to the whole of it from its\n// centre over `durationLong2` on the emphasized curve, fading in over the\n// first fifth of that, as Material's Android components draw it. Web draws it\n// at once. Under reduced motion it does here too.\n//\n// The state layer, the ripple and the focus ring are src/press's, in on\n// secondary container, drawn on the pill: the indicator in a vertical\n// destination, which its ripple grows from the centre of wherever it is\n// pressed, and the whole destination in a horizontal one. A horizontal pill's\n// press reaches 4dp above and below it, to the 48dp target; a vertical\n// destination is the bar's full height already. A disabled one draws its icon\n// and label on surface at the disabled content opacity, with no layer.\n//\n// A destination is a `tab`, reporting whether it is the selected one, and is\n// named by its label, or by `aria-label` where that is given: the badge on\n// its icon is hidden from a screen reader, so what it says belongs there.\n//\n// **The label comes first in the tree and is drawn after the icon**, through\n// a reversed column or row, so the text inside a destination starts with its\n// name. A badge's count is text, hidden from a screen reader but still\n// written inside the destination under React Native Web, and first in the\n// tree it put the count ahead of the name: a destination named \"Second item,\n// 3 new\" read \"3 Second item\", which is not what a speech-input user would\n// say, and is what axe's label-in-name check fails. src/badge sets the count\n// apart from the label with a space for the same reason.\n\n/** What a bar hands each of its destinations. */\ntype NavigationContextValue = {\n readonly form: NavigationForm\n /**\n * Whether the destinations are being drawn off screen to measure the\n * horizontal form, which draws each one's content and nothing else.\n */\n readonly measuring: boolean\n /** The route of the current destination, matched against an `href`. */\n readonly selectedRoute?: string | undefined\n}\n\ntype NavigationDestinationProps = Omit<\n PressableProps,\n 'children' | 'disabled' | 'style'\n> & {\n /**\n * A badge on the icon: `true` for the badges page's small dot, a number\n * for the large badge holding it. The badge is hidden from a screen\n * reader, so say what it says in the destination's `aria-label` too:\n * \"First item, 3 new\".\n */\n readonly badge?: boolean | number | undefined\n /** The destination's name, drawn as its label. */\n readonly children?: ReactNode\n /**\n * The destination's icon, at the page's 24dp, which the destination hands\n * its colour and size through `useIconStyle()`.\n */\n readonly icon?: ReactNode\n /**\n * Draws the destination disabled, and it takes no press.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * Which of the page's two forms a destination draws: the label under the\n * icon, or beside it.\n */\ntype NavigationForm = 'horizontal' | 'vertical'\n\n// The indicator's width when it starts to grow, as a share of its whole\n// width, and the share of the move it fades in over.\nconst GROWN_FROM = 0.4\nconst FADE_SHARE = 0.2\n\nconst ICON_SIZE = 24\n\nconst NavigationContext = createContext<NavigationContextValue>({\n form: 'vertical',\n measuring: false,\n})\n\n/**\n * The active indicator's fill, which grows from its centre while its\n * destination is current and shrinks back once it is not.\n */\nfunction ActiveIndicator({ selected }: { readonly selected: boolean }) {\n const theme = useTheme()\n const { colors, motion } = theme\n const reduceMotion = useReducedMotion()\n const progress = useSharedValue(selected ? 1 : 0)\n\n useEffect(() => {\n const target = selected ? 1 : 0\n\n progress.set(\n reduceMotion\n ? target\n : withTiming(target, {\n duration: motion.durationLong2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }),\n )\n }, [motion, progress, reduceMotion, selected])\n\n const motionStyle = useAnimatedStyle(() => {\n 'worklet'\n const grown = progress.get()\n\n return {\n opacity: Math.min(1, grown / FADE_SHARE),\n transform: [{ scaleX: GROWN_FROM + (1 - GROWN_FROM) * grown }],\n }\n })\n\n return (\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.fill,\n stylesOf(theme).pill,\n { backgroundColor: colors.secondaryContainer },\n motionStyle,\n )}\n />\n )\n}\n\n/**\n * What a destination draws over its indicator: the icon and its badge, and\n * in a horizontal destination the label before them in the tree, which the\n * pill's reversed row draws after them.\n */\nfunction DestinationContent({\n badge,\n form,\n icon,\n isDisabled,\n label,\n selected,\n}: {\n readonly badge: boolean | number | undefined\n readonly form: NavigationForm\n readonly icon: ReactNode\n readonly isDisabled: boolean\n readonly label: ReactNode\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const horizontal = form === 'horizontal'\n\n return (\n <>\n {horizontal ? (\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {label}\n </Label>\n ) : null}\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(iconColorOf(theme, isDisabled, selected))}\n >\n {badge === undefined || badge === false ? (\n icon\n ) : (\n <Badge\n count={badge === true ? undefined : badge}\n inFlow={horizontal}\n >\n {icon}\n </Badge>\n )}\n </IconStyleContext>\n </View>\n </>\n )\n}\n\n/** The colour a destination draws its icon in. */\nfunction iconColorOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n isDisabled: boolean,\n selected: boolean,\n): string {\n if (isDisabled) {\n return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n }\n return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant\n}\n\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's jsx-no-new-object-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction iconStyleOf(color: ColorValue): IconStyle {\n return { color, size: ICON_SIZE }\n}\n\n/** A destination's label, on one line, in label medium. */\nfunction Label({\n children,\n form,\n isDisabled,\n selected,\n}: {\n readonly children: ReactNode\n readonly form: NavigationForm\n readonly isDisabled: boolean\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const role = useTypeRole('labelMedium')\n\n return (\n <NativeText\n numberOfLines={1}\n style={composeStyles<TextStyle>(role, styles.label, {\n color: labelColorOf(theme, form, isDisabled, selected),\n })}\n >\n {children}\n </NativeText>\n )\n}\n\n/** The colour a destination draws its label in, which its form decides. */\nfunction labelColorOf(\n theme: ResolvedTheme,\n form: NavigationForm,\n isDisabled: boolean,\n selected: boolean,\n): string {\n return selected && !isDisabled && form === 'vertical'\n ? theme.colors.secondary\n : iconColorOf(theme, isDisabled, selected)\n}\n\n// A label that is a string names its destination; anything else leaves the\n// name to `aria-label`.\nfunction nameOf(children: ReactNode): string | undefined {\n return typeof children === 'string' ? children : undefined\n}\n\n/**\n * One destination, in the form the bar around it asks for: an icon and a\n * label, and the active indicator behind the icon while it is current. A\n * `tab` reporting whether it is selected.\n */\nfunction NavigationDestination({\n 'aria-label': ariaLabel,\n badge,\n children,\n icon,\n isDisabled = false,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n selected,\n style,\n ...props\n}: NavigationDestinationProps & { readonly selected: boolean }) {\n const theme = useTheme()\n const { form, measuring } = use(NavigationContext)\n const own = stylesOf(theme)\n const horizontal = form === 'horizontal'\n const feedback = usePressFeedback({\n area: horizontal ? undefined : INDICATOR,\n color: theme.colors.onSecondaryContainer,\n corners: own.pill,\n disabled: isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n })\n const content = (\n <DestinationContent\n badge={badge}\n form={form}\n icon={icon}\n isDisabled={isDisabled}\n label={children}\n selected={selected}\n />\n )\n\n if (measuring) {\n return <View style={own.horizontal}>{content}</View>\n }\n\n if (horizontal) {\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n hitSlop={hitSlop(PILL_HEIGHT)}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own.horizontal, feedback.ring, style)}\n >\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </Pressable>\n )\n }\n\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own.vertical, style)}\n >\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {children}\n </Label>\n <View style={composeStyles<ViewStyle>(own.indicator, feedback.ring)}>\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </View>\n </Pressable>\n )\n}\n\nexport type {\n NavigationContextValue,\n NavigationDestinationProps,\n NavigationForm,\n}\n\nexport { iconColorOf, labelColorOf, NavigationContext, NavigationDestination }\n"],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { themedStyles } from "../theme/styles.js";
2
+ import { StyleSheet } from "react-native";
3
+ //#region src/navigation/styles.ts
4
+ const INDICATOR = {
5
+ height: 32,
6
+ width: 56
7
+ };
8
+ const VERTICAL_PADDING = 6;
9
+ const styles = StyleSheet.create({
10
+ fill: {
11
+ bottom: 0,
12
+ end: 0,
13
+ position: "absolute",
14
+ start: 0,
15
+ top: 0
16
+ },
17
+ icon: {
18
+ alignItems: "center",
19
+ flexShrink: 0,
20
+ justifyContent: "center"
21
+ },
22
+ label: {
23
+ flexShrink: 1,
24
+ maxWidth: "100%"
25
+ }
26
+ });
27
+ const stylesOf = themedStyles(({ radii, spacing }) => StyleSheet.create({
28
+ horizontal: {
29
+ alignItems: "center",
30
+ borderRadius: radii.pill,
31
+ flexDirection: "row-reverse",
32
+ flexShrink: 0,
33
+ gap: spacing.xs,
34
+ justifyContent: "center",
35
+ minHeight: 40,
36
+ paddingHorizontal: spacing.lg
37
+ },
38
+ indicator: {
39
+ alignItems: "center",
40
+ borderRadius: radii.pill,
41
+ flexShrink: 0,
42
+ height: INDICATOR.height,
43
+ justifyContent: "center",
44
+ width: INDICATOR.width
45
+ },
46
+ pill: { borderRadius: radii.pill },
47
+ vertical: {
48
+ alignItems: "center",
49
+ flexBasis: 0,
50
+ flexDirection: "column-reverse",
51
+ flexGrow: 1,
52
+ gap: spacing.xs,
53
+ justifyContent: "center",
54
+ minWidth: 0,
55
+ paddingVertical: VERTICAL_PADDING
56
+ }
57
+ }));
58
+ //#endregion
59
+ export { INDICATOR, styles, stylesOf };
60
+
61
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","names":["StyleSheet","themedStyles","INDICATOR","height","width","const","PILL_HEIGHT","VERTICAL_PADDING","styles","create","fill","bottom","end","position","start","top","icon","alignItems","flexShrink","justifyContent","label","maxWidth","stylesOf","radii","spacing","horizontal","borderRadius","pill","flexDirection","gap","xs","minHeight","paddingHorizontal","lg","indicator","vertical","flexBasis","flexGrow","minWidth","paddingVertical"],"sources":["../../src/navigation/styles.ts"],"sourcesContent":["import { StyleSheet } from 'react-native'\n\nimport { themedStyles } from '../theme/styles'\n\n// The page's active indicator in a vertical destination: 56dp by 32dp, the\n// icon centred in it.\nconst INDICATOR = { height: 32, width: 56 } as const\n\n// A horizontal destination's pill, the page's 40dp, which its press reaches\n// past to the 48dp target.\nconst PILL_HEIGHT = 40\n\n// A vertical destination's padding above the indicator and below the label,\n// which puts the two in the bar's 64dp: 6, 32, 4 and 16, then 6.\nconst VERTICAL_PADDING = 6\n\nconst styles = StyleSheet.create({\n // The active indicator's fill, behind the icon in a vertical destination\n // and behind the whole pill in a horizontal one.\n fill: {\n bottom: 0,\n end: 0,\n position: 'absolute',\n start: 0,\n top: 0,\n },\n // An icon, and the badge on it, never squeezed by a long label.\n icon: {\n alignItems: 'center',\n flexShrink: 0,\n justifyContent: 'center',\n },\n // The label never wraps: a destination's name is a word or two, and one\n // broken over two lines would push its neighbours apart. Cut short with an\n // ellipsis where the destination is narrower than it.\n label: {\n flexShrink: 1,\n maxWidth: '100%',\n },\n})\n\nconst stylesOf = themedStyles(({ radii, spacing }) =>\n StyleSheet.create({\n // A horizontal destination: the pill, holding the icon and the label side\n // by side, 16dp in at either end and 4dp between the two, as wide as what\n // it holds. Reversed, since the label comes first in the tree.\n horizontal: {\n alignItems: 'center',\n borderRadius: radii.pill,\n flexDirection: 'row-reverse',\n flexShrink: 0,\n gap: spacing.xs,\n justifyContent: 'center',\n minHeight: PILL_HEIGHT,\n paddingHorizontal: spacing.lg,\n },\n // The active indicator of a vertical destination, which draws the layers\n // and the ring as well as the fill.\n indicator: {\n alignItems: 'center',\n borderRadius: radii.pill,\n flexShrink: 0,\n height: INDICATOR.height,\n justifyContent: 'center',\n width: INDICATOR.width,\n },\n // The fill's corners, the pill's.\n pill: {\n borderRadius: radii.pill,\n },\n // A vertical destination: the indicator with the label 4dp under it,\n // sharing the bar's width with the others. Its press is the whole of\n // that share, so it needs no reach of its own. Reversed, since the label\n // comes first in the tree.\n vertical: {\n alignItems: 'center',\n flexBasis: 0,\n flexDirection: 'column-reverse',\n flexGrow: 1,\n gap: spacing.xs,\n justifyContent: 'center',\n minWidth: 0,\n paddingVertical: VERTICAL_PADDING,\n },\n }),\n)\n\nexport { INDICATOR, PILL_HEIGHT, styles, stylesOf }\n"],"mappings":";;;AAMA,MAAME,YAAY;CAAEC,QAAQ;CAAIC,OAAO;AAAG;AAQ1C,MAAMG,mBAAmB;AAEzB,MAAMC,SAASR,WAAWS,OAAO;CAG/BC,MAAM;EACJC,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;EACPC,KAAK;CACP;CAEAC,MAAM;EACJC,YAAY;EACZC,YAAY;EACZC,gBAAgB;CAClB;CAIAC,OAAO;EACLF,YAAY;EACZG,UAAU;CACZ;AACF,CAAC;AAED,MAAMC,WAAWrB,cAAc,EAAEsB,OAAOC,cACtCxB,WAAWS,OAAO;CAIhBgB,YAAY;EACVR,YAAY;EACZS,cAAcH,MAAMI;EACpBC,eAAe;EACfV,YAAY;EACZW,KAAKL,QAAQM;EACbX,gBAAgB;EAChBY,WAAAA;EACAC,mBAAmBR,QAAQS;CAC7B;CAGAC,WAAW;EACTjB,YAAY;EACZS,cAAcH,MAAMI;EACpBT,YAAY;EACZf,QAAQD,UAAUC;EAClBgB,gBAAgB;EAChBf,OAAOF,UAAUE;CACnB;CAEAuB,MAAM,EACJD,cAAcH,MAAMI,KACtB;CAKAQ,UAAU;EACRlB,YAAY;EACZmB,WAAW;EACXR,eAAe;EACfS,UAAU;EACVR,KAAKL,QAAQM;EACbX,gBAAgB;EAChBmB,UAAU;EACVC,iBAAiBhC;CACnB;AACF,CAAC,CACH"}
@@ -1,2 +1,2 @@
1
- import { RefObject } from "react";
2
- import { HostInstance, ViewStyle } from "react-native";
1
+ import { HostInstance, LayoutChangeEvent, ViewStyle } from "react-native";
2
+ import { RefObject } from "react";
@@ -2,9 +2,9 @@ import { useTheme } from "../theme/scope.js";
2
2
  import { OverlayHostContext } from "./host.js";
3
3
  import { boundsOf, place } from "./placement.js";
4
4
  import { c } from "react/compiler-runtime";
5
- import { use, useEffect, useState } from "react";
6
5
  import { Dimensions, I18nManager, useWindowDimensions } from "react-native";
7
6
  import { SafeAreaInsetsContext } from "react-native-safe-area-context";
7
+ import { use, useEffect, useState } from "react";
8
8
  //#region src/overlay/anchored.ts
9
9
  const HIDDEN = {
10
10
  left: 0,
@@ -1,2 +1,2 @@
1
- import { ComponentRef, ReactNode } from "react";
2
- import { View } from "react-native";
1
+ import { View } from "react-native";
2
+ import { ComponentRef, ReactNode } from "react";
@@ -1,8 +1,8 @@
1
1
  import { ScopeContext, useScope } from "../theme/scope.js";
2
2
  import { c } from "react/compiler-runtime";
3
+ import { StyleSheet, View } from "react-native";
3
4
  import { createContext, use, useId, useLayoutEffect, useState, useSyncExternalStore } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { StyleSheet, View } from "react-native";
6
6
  //#region src/overlay/host.tsx
7
7
  const OverlayHostContext = createContext(null);
8
8
  const styles = StyleSheet.create({ fill: {
@@ -1,9 +1,9 @@
1
1
  import { useTheme } from "../theme/scope.js";
2
2
  import { c } from "react/compiler-runtime";
3
- import { useEffect, useRef } from "react";
4
- import { jsx } from "react/jsx-runtime";
5
3
  import { AccessibilityInfo, BackHandler, Platform, Pressable, StyleSheet } from "react-native";
6
4
  import { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
5
+ import { useEffect, useRef } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
7
  //#region src/overlay/panel.tsx
8
8
  const SCALE_FROM = .95;
9
9
  /** The edge a panel grows from, the one facing its anchor. */