@kanso-labs/react-native-kanso-ui 0.0.0-stage → 0.1.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 (145) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +205 -2
  3. package/dist/button/index.d.ts +56 -0
  4. package/dist/button/index.js +169 -0
  5. package/dist/button/index.js.map +1 -0
  6. package/dist/button/palettes.js +47 -0
  7. package/dist/button/palettes.js.map +1 -0
  8. package/dist/chip/index.js +194 -0
  9. package/dist/chip/index.js.map +1 -0
  10. package/dist/chip/styles.js +36 -0
  11. package/dist/chip/styles.js.map +1 -0
  12. package/dist/clipboard/index.js +58 -0
  13. package/dist/clipboard/index.js.map +1 -0
  14. package/dist/components/avatar/index.d.ts +82 -0
  15. package/dist/components/avatar/index.js +62 -0
  16. package/dist/components/avatar/index.js.map +1 -0
  17. package/dist/components/button/index.d.ts +87 -0
  18. package/dist/components/button/index.js +377 -0
  19. package/dist/components/button/index.js.map +1 -0
  20. package/dist/components/card/index.d.ts +78 -0
  21. package/dist/components/card/index.js +315 -0
  22. package/dist/components/card/index.js.map +1 -0
  23. package/dist/components/checkbox/index.d.ts +76 -0
  24. package/dist/components/checkbox/index.js +360 -0
  25. package/dist/components/checkbox/index.js.map +1 -0
  26. package/dist/components/chip/index.d.ts +84 -0
  27. package/dist/components/chip/index.js +257 -0
  28. package/dist/components/chip/index.js.map +1 -0
  29. package/dist/components/chip-group/index.d.ts +143 -0
  30. package/dist/components/chip-group/index.js +669 -0
  31. package/dist/components/chip-group/index.js.map +1 -0
  32. package/dist/components/copy-field/index.d.ts +60 -0
  33. package/dist/components/copy-field/index.js +277 -0
  34. package/dist/components/copy-field/index.js.map +1 -0
  35. package/dist/components/currency/index.d.ts +69 -0
  36. package/dist/components/currency/index.js +162 -0
  37. package/dist/components/currency/index.js.map +1 -0
  38. package/dist/components/form/index.d.ts +84 -0
  39. package/dist/components/form/index.js +95 -0
  40. package/dist/components/form/index.js.map +1 -0
  41. package/dist/components/icon-button/index.d.ts +68 -0
  42. package/dist/components/icon-button/index.js +289 -0
  43. package/dist/components/icon-button/index.js.map +1 -0
  44. package/dist/components/link/index.d.ts +59 -0
  45. package/dist/components/link/index.js +191 -0
  46. package/dist/components/link/index.js.map +1 -0
  47. package/dist/components/number-field/index.d.ts +151 -0
  48. package/dist/components/number-field/index.js +832 -0
  49. package/dist/components/number-field/index.js.map +1 -0
  50. package/dist/components/product-icon/index.d.ts +70 -0
  51. package/dist/components/product-icon/index.js +60 -0
  52. package/dist/components/product-icon/index.js.map +1 -0
  53. package/dist/components/radio-group/index.d.ts +105 -0
  54. package/dist/components/radio-group/index.js +597 -0
  55. package/dist/components/radio-group/index.js.map +1 -0
  56. package/dist/components/search-field/index.d.ts +98 -0
  57. package/dist/components/search-field/index.js +521 -0
  58. package/dist/components/search-field/index.js.map +1 -0
  59. package/dist/components/segmented-button/index.d.ts +113 -0
  60. package/dist/components/segmented-button/index.js +937 -0
  61. package/dist/components/segmented-button/index.js.map +1 -0
  62. package/dist/components/separator/index.d.ts +45 -0
  63. package/dist/components/separator/index.js +109 -0
  64. package/dist/components/separator/index.js.map +1 -0
  65. package/dist/components/stack/index.d.ts +70 -0
  66. package/dist/components/stack/index.js +107 -0
  67. package/dist/components/stack/index.js.map +1 -0
  68. package/dist/components/switch/index.d.ts +76 -0
  69. package/dist/components/switch/index.js +591 -0
  70. package/dist/components/switch/index.js.map +1 -0
  71. package/dist/components/text/index.d.ts +44 -0
  72. package/dist/components/text/index.js +78 -0
  73. package/dist/components/text/index.js.map +1 -0
  74. package/dist/components/text-field/index.d.ts +146 -0
  75. package/dist/components/text-field/index.js +228 -0
  76. package/dist/components/text-field/index.js.map +1 -0
  77. package/dist/control/index.js +117 -0
  78. package/dist/control/index.js.map +1 -0
  79. package/dist/control/styles.js +36 -0
  80. package/dist/control/styles.js.map +1 -0
  81. package/dist/field/index.d.ts +13 -0
  82. package/dist/field/index.js +1007 -0
  83. package/dist/field/index.js.map +1 -0
  84. package/dist/field/styles.js +131 -0
  85. package/dist/field/styles.js.map +1 -0
  86. package/dist/form/index.d.ts +24 -0
  87. package/dist/form/index.js +209 -0
  88. package/dist/form/index.js.map +1 -0
  89. package/dist/glyphs/icon-style.d.ts +25 -0
  90. package/dist/glyphs/icon-style.js +22 -0
  91. package/dist/glyphs/icon-style.js.map +1 -0
  92. package/dist/glyphs/index.js +170 -0
  93. package/dist/glyphs/index.js.map +1 -0
  94. package/dist/glyphs/styles.js +7 -0
  95. package/dist/glyphs/styles.js.map +1 -0
  96. package/dist/hooks/useWindowSizeClass.d.ts +25 -0
  97. package/dist/hooks/useWindowSizeClass.js +39 -0
  98. package/dist/hooks/useWindowSizeClass.js.map +1 -0
  99. package/dist/index.d.ts +31 -0
  100. package/dist/index.js +27 -0
  101. package/dist/mark/image.js +61 -0
  102. package/dist/mark/image.js.map +1 -0
  103. package/dist/mark/index.d.ts +9 -0
  104. package/dist/mark/index.js +234 -0
  105. package/dist/mark/index.js.map +1 -0
  106. package/dist/mark/initials.js +65 -0
  107. package/dist/mark/initials.js.map +1 -0
  108. package/dist/mark/styles.d.ts +1 -0
  109. package/dist/mark/styles.js +73 -0
  110. package/dist/mark/styles.js.map +1 -0
  111. package/dist/number/parser.js +321 -0
  112. package/dist/number/parser.js.map +1 -0
  113. package/dist/number/state.js +235 -0
  114. package/dist/number/state.js.map +1 -0
  115. package/dist/overlay/host.js +111 -0
  116. package/dist/overlay/host.js.map +1 -0
  117. package/dist/press/index.js +350 -0
  118. package/dist/press/index.js.map +1 -0
  119. package/dist/press/styles.js +31 -0
  120. package/dist/press/styles.js.map +1 -0
  121. package/dist/router/index.d.ts +28 -0
  122. package/dist/router/index.js +82 -0
  123. package/dist/router/index.js.map +1 -0
  124. package/dist/theme/color.js +25 -0
  125. package/dist/theme/color.js.map +1 -0
  126. package/dist/theme/resolve.d.ts +6 -0
  127. package/dist/theme/resolve.js +310 -0
  128. package/dist/theme/resolve.js.map +1 -0
  129. package/dist/theme/scope.d.ts +42 -0
  130. package/dist/theme/scope.js +80 -0
  131. package/dist/theme/scope.js.map +1 -0
  132. package/dist/theme/styles.js +39 -0
  133. package/dist/theme/styles.js.map +1 -0
  134. package/dist/theme-scope.d.ts +56 -0
  135. package/dist/theme-scope.js +127 -0
  136. package/dist/theme-scope.js.map +1 -0
  137. package/dist/tokens/defaults.d.ts +407 -0
  138. package/dist/tokens/defaults.js +403 -0
  139. package/dist/tokens/defaults.js.map +1 -0
  140. package/dist/typography/fonts.js +84 -0
  141. package/dist/typography/fonts.js.map +1 -0
  142. package/dist/typography/roles.d.ts +10 -0
  143. package/dist/typography/roles.js +82 -0
  144. package/dist/typography/roles.js.map +1 -0
  145. package/package.json +132 -4
@@ -0,0 +1,937 @@
1
+ import { IconStyleContext } from "../../glyphs/icon-style.js";
2
+ import { CheckGlyph } from "../../glyphs/index.js";
3
+ import { useTheme } from "../../theme/scope.js";
4
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
5
+ import { useTypeRole } from "../../typography/roles.js";
6
+ import { toggleState } from "../../button/index.js";
7
+ import { withOpacity } from "../../theme/color.js";
8
+ import { hitSlop, usePressFeedback } from "../../press/index.js";
9
+ import { c } from "react/compiler-runtime";
10
+ import { Pressable, StyleSheet, Text, View } from "react-native";
11
+ import { Children, Fragment, createContext, isValidElement, use, useLayoutEffect, useRef, useState } from "react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ import Animated, { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
14
+ import { useToggleGroupState } from "react-stately/useToggleGroupState";
15
+ //#region src/components/segmented-button/index.tsx
16
+ const GLYPH_SIZE = 18;
17
+ const RULE_WIDTH = 1;
18
+ const CHECK = /* @__PURE__ */ jsx(CheckGlyph, {});
19
+ const GroupContext = createContext(null);
20
+ const IndexContext = createContext(0);
21
+ const styles = StyleSheet.create({
22
+ glyph: {
23
+ alignItems: "center",
24
+ flexShrink: 0,
25
+ height: GLYPH_SIZE,
26
+ justifyContent: "center",
27
+ width: GLYPH_SIZE
28
+ },
29
+ glyphSlot: {
30
+ alignItems: "center",
31
+ flexShrink: 0,
32
+ height: GLYPH_SIZE,
33
+ justifyContent: "center",
34
+ overflow: "hidden"
35
+ },
36
+ indicator: {
37
+ bottom: 0,
38
+ position: "absolute",
39
+ start: 0,
40
+ top: 0
41
+ },
42
+ label: {
43
+ flexShrink: 0,
44
+ minWidth: 0
45
+ },
46
+ measurer: {
47
+ alignItems: "flex-start",
48
+ opacity: 0,
49
+ pointerEvents: "none",
50
+ position: "absolute",
51
+ start: 0,
52
+ top: 0
53
+ },
54
+ ownIndicator: {
55
+ bottom: 0,
56
+ end: 0,
57
+ position: "absolute",
58
+ start: 0,
59
+ top: 0
60
+ },
61
+ spacer: {
62
+ alignItems: "center",
63
+ flexDirection: "row",
64
+ flexShrink: 1,
65
+ justifyContent: "flex-end"
66
+ }
67
+ });
68
+ const stylesOf = themedStyles(({ colors, radii, sizing, spacing }) => StyleSheet.create({
69
+ clip: {
70
+ borderRadius: radii.pill,
71
+ bottom: 0,
72
+ end: 0,
73
+ overflow: "hidden",
74
+ pointerEvents: "none",
75
+ position: "absolute",
76
+ start: 0,
77
+ top: 0
78
+ },
79
+ first: { borderStartWidth: RULE_WIDTH },
80
+ segment: {
81
+ alignItems: "center",
82
+ borderColor: colors.outline,
83
+ borderStartWidth: 0,
84
+ borderWidth: RULE_WIDTH,
85
+ flexDirection: "row",
86
+ flexShrink: 1,
87
+ justifyContent: "center",
88
+ minHeight: sizing.controlSm,
89
+ minWidth: 0,
90
+ paddingHorizontal: spacing.sm
91
+ },
92
+ track: {
93
+ alignSelf: "flex-start",
94
+ flexDirection: "row",
95
+ maxWidth: "100%"
96
+ }
97
+ }));
98
+ const reachOf = themedStyles(({ sizing }) => hitSlop(sizing.controlSm));
99
+ /**
100
+ * The width every segment takes: the widest one's, which is its label, its
101
+ * padding, the room it keeps for a glyph and its rule. Undefined until every
102
+ * label has been measured.
103
+ */
104
+ function basisOf(segments, labels, showSelectedIcon, { spacing }) {
105
+ let basis = 0;
106
+ for (const [index, { props }] of segments.entries()) {
107
+ const labelled = hasLabel(props.children);
108
+ const label = labels.get(props.id);
109
+ if (labelled && label === void 0) return;
110
+ const content = labelled ? (label ?? 0) + (reservesGlyph(props, showSelectedIcon) ? GLYPH_SIZE + spacing.sm : 0) : props.icon === void 0 ? 0 : GLYPH_SIZE;
111
+ basis = Math.max(basis, content + spacing.md * 2 + ruleOf(index) + RULE_WIDTH);
112
+ }
113
+ return basis;
114
+ }
115
+ /**
116
+ * The chosen container's colour: the page's secondary container, the
117
+ * stronger secondary where no check marks the choice, and on-surface at the
118
+ * disabled opacity while the segment is disabled.
119
+ */
120
+ function containerOf({ colors, stateLayerOpacity }, disabled, marked) {
121
+ if (disabled) return withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer);
122
+ return marked ? colors.secondaryContainer : colors.secondary;
123
+ }
124
+ /**
125
+ * The label's colour, which the glyph, the state layer and the ripple take
126
+ * too.
127
+ */
128
+ function contentOf({ colors, stateLayerOpacity }, { disabled, marked, selected }) {
129
+ if (disabled) return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent);
130
+ if (!selected) return colors.onSurface;
131
+ return marked ? colors.onSecondaryContainer : colors.onSecondary;
132
+ }
133
+ /** A segment's corners: rounded at the ends of the track, square between. */
134
+ function cornersOf(radius, first, last) {
135
+ return {
136
+ borderBottomEndRadius: last ? radius : 0,
137
+ borderBottomStartRadius: first ? radius : 0,
138
+ borderTopEndRadius: last ? radius : 0,
139
+ borderTopStartRadius: first ? radius : 0
140
+ };
141
+ }
142
+ function hasLabel(children) {
143
+ return children !== void 0 && children !== null && children !== false && children !== "";
144
+ }
145
+ function iconStyleOf(color) {
146
+ return {
147
+ color,
148
+ size: GLYPH_SIZE
149
+ };
150
+ }
151
+ /**
152
+ * The chosen container of a set that chooses one, which slides to the
153
+ * segment chosen from the one chosen before it, fades in where nothing was
154
+ * chosen, and fades out where nothing now is.
155
+ */
156
+ function Indicator(t0) {
157
+ const $ = c(27);
158
+ const { color, place, selected } = t0;
159
+ const theme = useTheme();
160
+ const { motion } = theme;
161
+ const reduceMotion = useReducedMotion();
162
+ const [rest, setRest] = useState(void 0);
163
+ const shift = useSharedValue(0);
164
+ const shown = useSharedValue(0);
165
+ const drawnAt = useRef(void 0);
166
+ const drawn = useRef(false);
167
+ const offset = place === void 0 || rest === void 0 || Math.abs(rest.width - place.width) >= 1 ? void 0 : place.x - rest.x;
168
+ let t1;
169
+ if ($[0] !== motion.durationMedium1 || $[1] !== motion.easingEmphasized || $[2] !== offset || $[3] !== reduceMotion || $[4] !== selected || $[5] !== shift || $[6] !== shown) {
170
+ t1 = () => {
171
+ const slide = {
172
+ duration: motion.durationMedium1,
173
+ easing: Easing.bezier(...motion.easingEmphasized)
174
+ };
175
+ if (selected === void 0) {
176
+ if (drawnAt.current !== void 0) shown.set(reduceMotion ? 0 : withTiming(0, slide));
177
+ drawnAt.current = void 0;
178
+ return;
179
+ }
180
+ if (offset === void 0) return;
181
+ const from = drawnAt.current;
182
+ const moves = from !== void 0 && from !== selected && !reduceMotion;
183
+ shift.set(moves ? withTiming(offset, slide) : offset);
184
+ if (from === void 0) shown.set(drawn.current && !reduceMotion ? withTiming(1, slide) : 1);
185
+ drawnAt.current = selected;
186
+ drawn.current = true;
187
+ };
188
+ $[0] = motion.durationMedium1;
189
+ $[1] = motion.easingEmphasized;
190
+ $[2] = offset;
191
+ $[3] = reduceMotion;
192
+ $[4] = selected;
193
+ $[5] = shift;
194
+ $[6] = shown;
195
+ $[7] = t1;
196
+ } else t1 = $[7];
197
+ let t2;
198
+ if ($[8] !== motion || $[9] !== offset || $[10] !== reduceMotion || $[11] !== selected || $[12] !== shift || $[13] !== shown) {
199
+ t2 = [
200
+ motion,
201
+ offset,
202
+ reduceMotion,
203
+ selected,
204
+ shift,
205
+ shown
206
+ ];
207
+ $[8] = motion;
208
+ $[9] = offset;
209
+ $[10] = reduceMotion;
210
+ $[11] = selected;
211
+ $[12] = shift;
212
+ $[13] = shown;
213
+ $[14] = t2;
214
+ } else t2 = $[14];
215
+ useLayoutEffect(t1, t2);
216
+ const motionStyle = useAnimatedStyle(() => {
217
+ "worklet";
218
+ return {
219
+ opacity: shown.get(),
220
+ transform: [{ translateX: shift.get() }]
221
+ };
222
+ });
223
+ let t3;
224
+ if ($[15] !== theme) {
225
+ t3 = stylesOf(theme);
226
+ $[15] = theme;
227
+ $[16] = t3;
228
+ } else t3 = $[16];
229
+ const t4 = t3.clip;
230
+ let t5;
231
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
232
+ t5 = restThen(setRest);
233
+ $[17] = t5;
234
+ } else t5 = $[17];
235
+ const t6 = place?.width ?? 0;
236
+ let t7;
237
+ if ($[18] !== color || $[19] !== motionStyle || $[20] !== t6) {
238
+ t7 = composeStyles(styles.indicator, {
239
+ backgroundColor: color,
240
+ width: t6
241
+ }, motionStyle);
242
+ $[18] = color;
243
+ $[19] = motionStyle;
244
+ $[20] = t6;
245
+ $[21] = t7;
246
+ } else t7 = $[21];
247
+ let t8;
248
+ if ($[22] !== t7) {
249
+ t8 = /* @__PURE__ */ jsx(Animated.View, {
250
+ onLayout: t5,
251
+ style: t7
252
+ });
253
+ $[22] = t7;
254
+ $[23] = t8;
255
+ } else t8 = $[23];
256
+ let t9;
257
+ if ($[24] !== t3.clip || $[25] !== t8) {
258
+ t9 = /* @__PURE__ */ jsx(View, {
259
+ style: t4,
260
+ children: t8
261
+ });
262
+ $[24] = t3.clip;
263
+ $[25] = t8;
264
+ $[26] = t9;
265
+ } else t9 = $[26];
266
+ return t9;
267
+ }
268
+ /**
269
+ * Records a label's width off screen, for the basis. Built by a call rather
270
+ * than written inline at the prop, which is what react-perf's
271
+ * jsx-no-new-function-as-prop is after; the React Compiler memoises the
272
+ * result on its inputs.
273
+ */
274
+ function measureThen(setLabels, key) {
275
+ return (event) => {
276
+ const { width } = event.nativeEvent.layout;
277
+ setLabels((labels) => labels.get(key) === width ? labels : new Map(labels).set(key, width));
278
+ };
279
+ }
280
+ /**
281
+ * Records where a segment was laid out, then calls the call site's own
282
+ * `onLayout`.
283
+ */
284
+ function placeThen(onPlace, key, onLayout) {
285
+ return (event) => {
286
+ const { width, x } = event.nativeEvent.layout;
287
+ onPlace(key, {
288
+ width,
289
+ x
290
+ });
291
+ onLayout?.(event);
292
+ };
293
+ }
294
+ function reservesGlyph({ children, icon }, showSelectedIcon) {
295
+ return showSelectedIcon && hasLabel(children) || icon !== void 0;
296
+ }
297
+ /** Records where the chosen container rests before it is moved. */
298
+ function restThen(setRest) {
299
+ return (event) => {
300
+ const { width, x } = event.nativeEvent.layout;
301
+ setRest({
302
+ width,
303
+ x
304
+ });
305
+ };
306
+ }
307
+ function ruleOf(index) {
308
+ return index === 0 ? RULE_WIDTH : 0;
309
+ }
310
+ function samePlace(known, place) {
311
+ return known !== void 0 && known.width === place.width && known.x === place.x;
312
+ }
313
+ /**
314
+ * A row of two to five joined segments, of which one, or with
315
+ * `selectionMode="multiple"` several, is chosen. Pass `selectedKeys` with
316
+ * `onSelectionChange` to hold the choice, or `defaultSelectedKeys` to let the
317
+ * set keep its own. Give every segment an `id`, which is the key the choice
318
+ * is reported by.
319
+ *
320
+ * ```tsx
321
+ * <SegmentedButton aria-label="Label" defaultSelectedKeys={['first']}>
322
+ * <SegmentedButton.Segment id="first">First item</SegmentedButton.Segment>
323
+ * <SegmentedButton.Segment id="second">Second item</SegmentedButton.Segment>
324
+ * </SegmentedButton>
325
+ * ```
326
+ *
327
+ * Name the set with `aria-label` or `aria-labelledby`, one of which the
328
+ * props require. Choosing one is announced as a radio group, and choosing
329
+ * several as a toolbar of buttons that each say whether they are selected.
330
+ *
331
+ * `style`, `ref` and `testID` land on the track.
332
+ */
333
+ function SegmentedButton(t0) {
334
+ const $ = c(80);
335
+ let children;
336
+ let defaultSelectedKeys;
337
+ let disallowEmptySelection;
338
+ let onSelectionChange;
339
+ let props;
340
+ let selectedKeys;
341
+ let style;
342
+ let t1;
343
+ let t2;
344
+ let t3;
345
+ if ($[0] !== t0) {
346
+ ({children, defaultSelectedKeys, disallowEmptySelection, isDisabled: t1, onSelectionChange, selectedKeys, selectionMode: t2, showSelectedIcon: t3, style, ...props} = t0);
347
+ $[0] = t0;
348
+ $[1] = children;
349
+ $[2] = defaultSelectedKeys;
350
+ $[3] = disallowEmptySelection;
351
+ $[4] = onSelectionChange;
352
+ $[5] = props;
353
+ $[6] = selectedKeys;
354
+ $[7] = style;
355
+ $[8] = t1;
356
+ $[9] = t2;
357
+ $[10] = t3;
358
+ } else {
359
+ children = $[1];
360
+ defaultSelectedKeys = $[2];
361
+ disallowEmptySelection = $[3];
362
+ onSelectionChange = $[4];
363
+ props = $[5];
364
+ selectedKeys = $[6];
365
+ style = $[7];
366
+ t1 = $[8];
367
+ t2 = $[9];
368
+ t3 = $[10];
369
+ }
370
+ const isDisabled = t1 === void 0 ? false : t1;
371
+ const selectionMode = t2 === void 0 ? "single" : t2;
372
+ const showSelectedIcon = t3 === void 0 ? true : t3;
373
+ const theme = useTheme();
374
+ const role = useTypeRole("labelLarge");
375
+ const single = selectionMode === "single";
376
+ const t4 = disallowEmptySelection ?? single;
377
+ let t5;
378
+ if ($[11] !== defaultSelectedKeys || $[12] !== isDisabled || $[13] !== onSelectionChange || $[14] !== selectedKeys || $[15] !== selectionMode || $[16] !== t4) {
379
+ t5 = {
380
+ defaultSelectedKeys,
381
+ disallowEmptySelection: t4,
382
+ isDisabled,
383
+ onSelectionChange,
384
+ selectedKeys,
385
+ selectionMode
386
+ };
387
+ $[11] = defaultSelectedKeys;
388
+ $[12] = isDisabled;
389
+ $[13] = onSelectionChange;
390
+ $[14] = selectedKeys;
391
+ $[15] = selectionMode;
392
+ $[16] = t4;
393
+ $[17] = t5;
394
+ } else t5 = $[17];
395
+ const state = useToggleGroupState(t5);
396
+ const segments = segmentsOf(children);
397
+ let t6;
398
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
399
+ t6 = /* @__PURE__ */ new Map();
400
+ $[18] = t6;
401
+ } else t6 = $[18];
402
+ const [labels, setLabels] = useState(t6);
403
+ let t7;
404
+ if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
405
+ t7 = /* @__PURE__ */ new Map();
406
+ $[19] = t7;
407
+ } else t7 = $[19];
408
+ const [places, setPlaces] = useState(t7);
409
+ let t8;
410
+ if ($[20] !== state.selectedKeys) {
411
+ t8 = [...state.selectedKeys].at(0);
412
+ $[20] = state.selectedKeys;
413
+ $[21] = t8;
414
+ } else t8 = $[21];
415
+ const chosen = t8;
416
+ const [held, setHeld] = useState(chosen);
417
+ if (chosen !== void 0 && chosen !== held) setHeld(chosen);
418
+ const [opening, setOpening] = useState(chosen);
419
+ if (opening !== void 0 && opening !== chosen) setOpening(void 0);
420
+ const basis = basisOf(segments, labels, showSelectedIcon, theme);
421
+ let t9;
422
+ if ($[22] !== setPlaces) {
423
+ t9 = (key, place) => {
424
+ setPlaces((current) => samePlace(current.get(key), place) ? current : new Map(current).set(key, place));
425
+ };
426
+ $[22] = setPlaces;
427
+ $[23] = t9;
428
+ } else t9 = $[23];
429
+ let t10;
430
+ if ($[24] !== basis || $[25] !== opening || $[26] !== places || $[27] !== segments.length || $[28] !== selectionMode || $[29] !== showSelectedIcon || $[30] !== state || $[31] !== t9) {
431
+ t10 = {
432
+ basis,
433
+ count: segments.length,
434
+ onPlace: t9,
435
+ opening,
436
+ places,
437
+ selectionMode,
438
+ showSelectedIcon,
439
+ state
440
+ };
441
+ $[24] = basis;
442
+ $[25] = opening;
443
+ $[26] = places;
444
+ $[27] = segments.length;
445
+ $[28] = selectionMode;
446
+ $[29] = showSelectedIcon;
447
+ $[30] = state;
448
+ $[31] = t9;
449
+ $[32] = t10;
450
+ } else t10 = $[32];
451
+ const context = t10;
452
+ let T0;
453
+ let t11;
454
+ let t12;
455
+ let t13;
456
+ let t14;
457
+ let t15;
458
+ if ($[33] !== chosen || $[34] !== held || $[35] !== isDisabled || $[36] !== places || $[37] !== props || $[38] !== segments || $[39] !== showSelectedIcon || $[40] !== single || $[41] !== style || $[42] !== theme) {
459
+ let t16;
460
+ if ($[49] !== chosen || $[50] !== held) {
461
+ t16 = (t17) => {
462
+ const { props: own } = t17;
463
+ return own.id === (chosen ?? held);
464
+ };
465
+ $[49] = chosen;
466
+ $[50] = held;
467
+ $[51] = t16;
468
+ } else t16 = $[51];
469
+ const segment = segments.find(t16);
470
+ T0 = View;
471
+ if ($[52] !== theme) {
472
+ t11 = reachOf(theme);
473
+ $[52] = theme;
474
+ $[53] = t11;
475
+ } else t11 = $[53];
476
+ t12 = single ? "radiogroup" : "toolbar";
477
+ t13 = props;
478
+ if ($[54] !== style || $[55] !== theme) {
479
+ t14 = composeStyles(stylesOf(theme).track, style);
480
+ $[54] = style;
481
+ $[55] = theme;
482
+ $[56] = t14;
483
+ } else t14 = $[56];
484
+ t15 = single ? /* @__PURE__ */ jsx(Indicator, {
485
+ color: containerOf(theme, isDisabled || segment?.props.isDisabled === true, showSelectedIcon && hasLabel(segment?.props.children)),
486
+ place: segment === void 0 ? void 0 : places.get(segment.props.id),
487
+ selected: segment === void 0 ? void 0 : chosen
488
+ }) : null;
489
+ $[33] = chosen;
490
+ $[34] = held;
491
+ $[35] = isDisabled;
492
+ $[36] = places;
493
+ $[37] = props;
494
+ $[38] = segments;
495
+ $[39] = showSelectedIcon;
496
+ $[40] = single;
497
+ $[41] = style;
498
+ $[42] = theme;
499
+ $[43] = T0;
500
+ $[44] = t11;
501
+ $[45] = t12;
502
+ $[46] = t13;
503
+ $[47] = t14;
504
+ $[48] = t15;
505
+ } else {
506
+ T0 = $[43];
507
+ t11 = $[44];
508
+ t12 = $[45];
509
+ t13 = $[46];
510
+ t14 = $[47];
511
+ t15 = $[48];
512
+ }
513
+ let t16;
514
+ if ($[57] !== segments) {
515
+ t16 = segments.map(_temp);
516
+ $[57] = segments;
517
+ $[58] = t16;
518
+ } else t16 = $[58];
519
+ let t17;
520
+ if ($[59] !== context || $[60] !== t16) {
521
+ t17 = /* @__PURE__ */ jsx(GroupContext, {
522
+ value: context,
523
+ children: t16
524
+ });
525
+ $[59] = context;
526
+ $[60] = t16;
527
+ $[61] = t17;
528
+ } else t17 = $[61];
529
+ let t18;
530
+ if ($[62] !== role || $[63] !== segments || $[64] !== setLabels) {
531
+ let t19;
532
+ if ($[66] !== role || $[67] !== setLabels) {
533
+ t19 = (t20) => {
534
+ const { props: own_0 } = t20;
535
+ return hasLabel(own_0.children) ? /* @__PURE__ */ jsx(Text, {
536
+ numberOfLines: 1,
537
+ onLayout: measureThen(setLabels, own_0.id),
538
+ style: role,
539
+ children: own_0.children
540
+ }, own_0.id) : null;
541
+ };
542
+ $[66] = role;
543
+ $[67] = setLabels;
544
+ $[68] = t19;
545
+ } else t19 = $[68];
546
+ t18 = segments.map(t19);
547
+ $[62] = role;
548
+ $[63] = segments;
549
+ $[64] = setLabels;
550
+ $[65] = t18;
551
+ } else t18 = $[65];
552
+ let t19;
553
+ if ($[69] !== t18) {
554
+ t19 = /* @__PURE__ */ jsx(View, {
555
+ "aria-hidden": true,
556
+ style: styles.measurer,
557
+ children: t18
558
+ });
559
+ $[69] = t18;
560
+ $[70] = t19;
561
+ } else t19 = $[70];
562
+ let t20;
563
+ if ($[71] !== T0 || $[72] !== t11 || $[73] !== t12 || $[74] !== t13 || $[75] !== t14 || $[76] !== t15 || $[77] !== t17 || $[78] !== t19) {
564
+ t20 = /* @__PURE__ */ jsxs(T0, {
565
+ hitSlop: t11,
566
+ role: t12,
567
+ ...t13,
568
+ style: t14,
569
+ children: [
570
+ t15,
571
+ t17,
572
+ t19
573
+ ]
574
+ });
575
+ $[71] = T0;
576
+ $[72] = t11;
577
+ $[73] = t12;
578
+ $[74] = t13;
579
+ $[75] = t14;
580
+ $[76] = t15;
581
+ $[77] = t17;
582
+ $[78] = t19;
583
+ $[79] = t20;
584
+ } else t20 = $[79];
585
+ return t20;
586
+ }
587
+ /**
588
+ * One segment. Its `id` is the key the choice reports it by, and its label is
589
+ * what names it. A chosen segment draws a check before its label; one not
590
+ * chosen draws its `icon`, if it has one. Renders nothing outside a
591
+ * `SegmentedButton`.
592
+ *
593
+ * `style`, `ref` and `testID` land on the segment's `Pressable`.
594
+ */
595
+ function _temp(each, at) {
596
+ return /* @__PURE__ */ jsx(IndexContext, {
597
+ value: at,
598
+ children: each
599
+ }, each.props.id);
600
+ }
601
+ function SegmentedButtonSegment(t0) {
602
+ const $ = c(55);
603
+ let children;
604
+ let icon;
605
+ let id;
606
+ let onBlur;
607
+ let onFocus;
608
+ let onHoverIn;
609
+ let onHoverOut;
610
+ let onLayout;
611
+ let onPress;
612
+ let onPressIn;
613
+ let onPressOut;
614
+ let ownHitSlop;
615
+ let props;
616
+ let style;
617
+ let t1;
618
+ let t2;
619
+ if ($[0] !== t0) {
620
+ ({children, disableRipple: t1, hitSlop: ownHitSlop, icon, id, isDisabled: t2, onBlur, onFocus, onHoverIn, onHoverOut, onLayout, onPress, onPressIn, onPressOut, style, ...props} = t0);
621
+ $[0] = t0;
622
+ $[1] = children;
623
+ $[2] = icon;
624
+ $[3] = id;
625
+ $[4] = onBlur;
626
+ $[5] = onFocus;
627
+ $[6] = onHoverIn;
628
+ $[7] = onHoverOut;
629
+ $[8] = onLayout;
630
+ $[9] = onPress;
631
+ $[10] = onPressIn;
632
+ $[11] = onPressOut;
633
+ $[12] = ownHitSlop;
634
+ $[13] = props;
635
+ $[14] = style;
636
+ $[15] = t1;
637
+ $[16] = t2;
638
+ } else {
639
+ children = $[1];
640
+ icon = $[2];
641
+ id = $[3];
642
+ onBlur = $[4];
643
+ onFocus = $[5];
644
+ onHoverIn = $[6];
645
+ onHoverOut = $[7];
646
+ onLayout = $[8];
647
+ onPress = $[9];
648
+ onPressIn = $[10];
649
+ onPressOut = $[11];
650
+ ownHitSlop = $[12];
651
+ props = $[13];
652
+ style = $[14];
653
+ t1 = $[15];
654
+ t2 = $[16];
655
+ }
656
+ const disableRipple = t1 === void 0 ? false : t1;
657
+ const ownDisabled = t2 === void 0 ? false : t2;
658
+ const theme = useTheme();
659
+ const group = use(GroupContext);
660
+ const index = use(IndexContext);
661
+ const role = useTypeRole("labelLarge");
662
+ const state = group?.state;
663
+ const several = group?.selectionMode === "multiple";
664
+ const showSelectedIcon = group?.showSelectedIcon ?? true;
665
+ const selected = state?.selectedKeys.has(id) ?? false;
666
+ const disabled = ownDisabled || state?.isDisabled === true;
667
+ const labelled = hasLabel(children);
668
+ const marked = showSelectedIcon && labelled;
669
+ let t3;
670
+ if ($[17] !== children || $[18] !== icon || $[19] !== id || $[20] !== showSelectedIcon) {
671
+ t3 = reservesGlyph({
672
+ children,
673
+ icon,
674
+ id
675
+ }, showSelectedIcon);
676
+ $[17] = children;
677
+ $[18] = icon;
678
+ $[19] = id;
679
+ $[20] = showSelectedIcon;
680
+ $[21] = t3;
681
+ } else t3 = $[21];
682
+ const reserves = t3;
683
+ const glyph = selected && marked ? CHECK : icon ?? null;
684
+ const drawn = glyph !== null;
685
+ const first = index === 0;
686
+ const last = index === (group?.count ?? 0) - 1;
687
+ const { radii, spacing } = theme;
688
+ const content = contentOf(theme, {
689
+ disabled,
690
+ marked,
691
+ selected
692
+ });
693
+ const corners = cornersOf(radii.pill, first, last);
694
+ const own = stylesOf(theme);
695
+ const give = spacing.md - spacing.sm;
696
+ const reserve = GLYPH_SIZE + spacing.sm;
697
+ const leading = reserves ? drawn ? give + (labelled ? reserve : GLYPH_SIZE) : give + reserve / 2 : give;
698
+ const leadingFloor = drawn ? labelled ? reserve : GLYPH_SIZE : 0;
699
+ const trailing = reserves && !drawn ? give + reserve / 2 : give;
700
+ let t4;
701
+ if ($[22] !== group?.places || $[23] !== id) {
702
+ t4 = group?.places.get(id)?.width;
703
+ $[22] = group?.places;
704
+ $[23] = id;
705
+ $[24] = t4;
706
+ } else t4 = $[24];
707
+ const width = t4;
708
+ const room = width === void 0 ? void 0 : width - ruleOf(index) - RULE_WIDTH - spacing.sm * 2 - (drawn && labelled ? reserve : 0);
709
+ const motion = useSegmentMotion({
710
+ content,
711
+ drawn,
712
+ fades: several,
713
+ filled: several ? selected : id === group?.opening,
714
+ labelled,
715
+ leading,
716
+ leadingFloor,
717
+ room,
718
+ trailing
719
+ });
720
+ const feedback = usePressFeedback({
721
+ color: content,
722
+ corners,
723
+ disabled,
724
+ disableRipple,
725
+ onBlur,
726
+ onFocus,
727
+ onHoverIn,
728
+ onHoverOut,
729
+ onPressIn,
730
+ onPressOut
731
+ });
732
+ if (group === null) return null;
733
+ const t5 = feedback.handlers;
734
+ let t6;
735
+ if ($[25] !== ownHitSlop || $[26] !== theme) {
736
+ t6 = ownHitSlop ?? reachOf(theme);
737
+ $[25] = ownHitSlop;
738
+ $[26] = theme;
739
+ $[27] = t6;
740
+ } else t6 = $[27];
741
+ let t7;
742
+ if ($[28] !== group.onPlace || $[29] !== id || $[30] !== onLayout) {
743
+ t7 = placeThen(group.onPlace, id, onLayout);
744
+ $[28] = group.onPlace;
745
+ $[29] = id;
746
+ $[30] = onLayout;
747
+ $[31] = t7;
748
+ } else t7 = $[31];
749
+ let t8;
750
+ if ($[32] !== group.state || $[33] !== id || $[34] !== onPress) {
751
+ t8 = toggleThen(group.state, id, onPress);
752
+ $[32] = group.state;
753
+ $[33] = id;
754
+ $[34] = onPress;
755
+ $[35] = t8;
756
+ } else t8 = $[35];
757
+ const t9 = composeStyles(own.segment, first ? own.first : void 0, corners, disabled ? { borderColor: withOpacity(theme.colors.onSurface, theme.stateLayerOpacity.disabledContainer) } : void 0, group.basis === void 0 ? void 0 : {
758
+ flexGrow: 0,
759
+ width: group.basis
760
+ }, feedback.ring, style);
761
+ const t10 = feedback.layer;
762
+ const t11 = Animated;
763
+ let t12;
764
+ if ($[36] !== motion.leading) {
765
+ t12 = composeStyles(styles.spacer, motion.leading);
766
+ $[36] = motion.leading;
767
+ $[37] = t12;
768
+ } else t12 = $[37];
769
+ const t13 = reserves ? /* @__PURE__ */ jsx(Animated.View, {
770
+ style: composeStyles(styles.glyphSlot, motion.slot),
771
+ children: /* @__PURE__ */ jsx(IconStyleContext, {
772
+ value: iconStyleOf(content),
773
+ children: /* @__PURE__ */ jsx(View, {
774
+ style: styles.glyph,
775
+ children: glyph
776
+ })
777
+ })
778
+ }) : null;
779
+ let t14;
780
+ if ($[38] !== motion.gap || $[39] !== reserves) {
781
+ t14 = reserves ? /* @__PURE__ */ jsx(Animated.View, { style: motion.gap }) : null;
782
+ $[38] = motion.gap;
783
+ $[39] = reserves;
784
+ $[40] = t14;
785
+ } else t14 = $[40];
786
+ let t15;
787
+ if ($[41] !== t11.View || $[42] !== t12 || $[43] !== t13 || $[44] !== t14) {
788
+ t15 = /* @__PURE__ */ jsxs(t11.View, {
789
+ style: t12,
790
+ children: [t13, t14]
791
+ });
792
+ $[41] = t11.View;
793
+ $[42] = t12;
794
+ $[43] = t13;
795
+ $[44] = t14;
796
+ $[45] = t15;
797
+ } else t15 = $[45];
798
+ let t16;
799
+ if ($[46] !== children || $[47] !== labelled || $[48] !== motion.label || $[49] !== role) {
800
+ t16 = labelled ? /* @__PURE__ */ jsx(Animated.Text, {
801
+ numberOfLines: 1,
802
+ style: composeStyles(role, styles.label, motion.label),
803
+ children
804
+ }) : null;
805
+ $[46] = children;
806
+ $[47] = labelled;
807
+ $[48] = motion.label;
808
+ $[49] = role;
809
+ $[50] = t16;
810
+ } else t16 = $[50];
811
+ let t17;
812
+ if ($[51] !== motion.trailing) {
813
+ t17 = composeStyles(styles.spacer, motion.trailing);
814
+ $[51] = motion.trailing;
815
+ $[52] = t17;
816
+ } else t17 = $[52];
817
+ let t18;
818
+ if ($[53] !== t17) {
819
+ t18 = /* @__PURE__ */ jsx(Animated.View, { style: t17 });
820
+ $[53] = t17;
821
+ $[54] = t18;
822
+ } else t18 = $[54];
823
+ return /* @__PURE__ */ jsxs(Pressable, {
824
+ role: several ? "button" : "radio",
825
+ ...several ? toggleState(selected) : { "aria-checked": selected },
826
+ ...props,
827
+ ...t5,
828
+ disabled,
829
+ hitSlop: t6,
830
+ onLayout: t7,
831
+ onPress: t8,
832
+ style: t9,
833
+ children: [
834
+ /* @__PURE__ */ jsx(Animated.View, { style: composeStyles(styles.ownIndicator, corners, { backgroundColor: containerOf(theme, disabled, marked) }, motion.fill) }),
835
+ t10,
836
+ t15,
837
+ t16,
838
+ t18
839
+ ]
840
+ });
841
+ }
842
+ /**
843
+ * The segments among a set's children, with any fragment between them opened,
844
+ * so a set can take its segments as one fragment.
845
+ */
846
+ function segmentsOf(children) {
847
+ return Children.toArray(children).flatMap((child) => {
848
+ if (!isValidElement(child)) return [];
849
+ if (child.type === Fragment) return segmentsOf(child.props.children);
850
+ return isValidElement(child) ? [child] : [];
851
+ });
852
+ }
853
+ /**
854
+ * A press on a segment: the call site's own `onPress`, then the choice, which
855
+ * chooses the segment, or clears it if it was chosen and the set allows that.
856
+ */
857
+ function toggleThen(state, key, onPress) {
858
+ return (event) => {
859
+ onPress?.(event);
860
+ state.toggleKey(key);
861
+ };
862
+ }
863
+ /**
864
+ * What a segment eases: the room either side of its label and the glyph slot
865
+ * between them over `durationShort2`, the label's colour and the most it
866
+ * takes with them, and its own chosen container where it `fades`, in a set
867
+ * that chooses several. All of it is there at once under reduced motion, and
868
+ * the container is in a set that chooses one, where it only stands in for the
869
+ * track's until the choice first moves.
870
+ */
871
+ function useSegmentMotion(t0) {
872
+ const $ = c(7);
873
+ const { content, drawn, fades, filled, labelled, leading, leadingFloor, room, trailing } = t0;
874
+ const { motion, spacing } = useTheme();
875
+ const reduceMotion = useReducedMotion();
876
+ const timing = {
877
+ duration: motion.durationShort2,
878
+ easing: Easing.bezier(...motion.easingStandard)
879
+ };
880
+ const gap = drawn && labelled ? spacing.sm : 0;
881
+ const slot = drawn ? GLYPH_SIZE : 0;
882
+ const opacity = filled ? 1 : 0;
883
+ const t1 = useAnimatedStyle(() => {
884
+ "worklet";
885
+ return { opacity: reduceMotion || !fades ? opacity : withTiming(opacity, timing) };
886
+ });
887
+ const t2 = useAnimatedStyle(() => {
888
+ "worklet";
889
+ return { width: reduceMotion ? gap : withTiming(gap, timing) };
890
+ });
891
+ const t3 = useAnimatedStyle(() => {
892
+ "worklet";
893
+ return {
894
+ color: reduceMotion ? content : withTiming(content, timing),
895
+ ...room === void 0 ? void 0 : { maxWidth: reduceMotion ? room : withTiming(room, timing) }
896
+ };
897
+ });
898
+ const t4 = useAnimatedStyle(() => {
899
+ "worklet";
900
+ return {
901
+ minWidth: reduceMotion ? leadingFloor : withTiming(leadingFloor, timing),
902
+ width: reduceMotion ? leading : withTiming(leading, timing)
903
+ };
904
+ });
905
+ const t5 = useAnimatedStyle(() => {
906
+ "worklet";
907
+ return { width: reduceMotion ? slot : withTiming(slot, timing) };
908
+ });
909
+ const t6 = useAnimatedStyle(() => {
910
+ "worklet";
911
+ return { width: reduceMotion ? trailing : withTiming(trailing, timing) };
912
+ });
913
+ let t7;
914
+ if ($[0] !== t1 || $[1] !== t2 || $[2] !== t3 || $[3] !== t4 || $[4] !== t5 || $[5] !== t6) {
915
+ t7 = {
916
+ fill: t1,
917
+ gap: t2,
918
+ label: t3,
919
+ leading: t4,
920
+ slot: t5,
921
+ trailing: t6
922
+ };
923
+ $[0] = t1;
924
+ $[1] = t2;
925
+ $[2] = t3;
926
+ $[3] = t4;
927
+ $[4] = t5;
928
+ $[5] = t6;
929
+ $[6] = t7;
930
+ } else t7 = $[6];
931
+ return t7;
932
+ }
933
+ SegmentedButton.Segment = SegmentedButtonSegment;
934
+ //#endregion
935
+ export { SegmentedButton, SegmentedButtonSegment };
936
+
937
+ //# sourceMappingURL=index.js.map