@kanso-labs/react-native-kanso-ui 0.6.0 → 0.8.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 (97) hide show
  1. package/README.md +37 -0
  2. package/dist/badge/index.js +25 -23
  3. package/dist/badge/index.js.map +1 -1
  4. package/dist/button/index.d.ts +2 -1
  5. package/dist/button/index.js.map +1 -1
  6. package/dist/button/pending.js +17 -21
  7. package/dist/button/pending.js.map +1 -1
  8. package/dist/calendar/index.js +1182 -0
  9. package/dist/calendar/index.js.map +1 -0
  10. package/dist/calendar/styles.js +120 -0
  11. package/dist/calendar/styles.js.map +1 -0
  12. package/dist/components/autocomplete/index.js +28 -26
  13. package/dist/components/autocomplete/index.js.map +1 -1
  14. package/dist/components/avatar/index.d.ts +2 -2
  15. package/dist/components/avatar/index.js +2 -2
  16. package/dist/components/avatar/index.js.map +1 -1
  17. package/dist/components/calendar/index.d.ts +51 -0
  18. package/dist/components/calendar/index.js +121 -0
  19. package/dist/components/calendar/index.js.map +1 -0
  20. package/dist/components/chip-group/index.d.ts +4 -3
  21. package/dist/components/chip-group/index.js +47 -45
  22. package/dist/components/chip-group/index.js.map +1 -1
  23. package/dist/components/copy-field/index.d.ts +5 -5
  24. package/dist/components/copy-field/index.js +30 -28
  25. package/dist/components/copy-field/index.js.map +1 -1
  26. package/dist/components/currency/index.d.ts +2 -2
  27. package/dist/components/currency/index.js +3 -1
  28. package/dist/components/currency/index.js.map +1 -1
  29. package/dist/components/list/index.d.ts +6 -5
  30. package/dist/components/list/index.js +97 -106
  31. package/dist/components/list/index.js.map +1 -1
  32. package/dist/components/menu/index.d.ts +4 -3
  33. package/dist/components/menu/index.js +33 -40
  34. package/dist/components/menu/index.js.map +1 -1
  35. package/dist/components/meter/index.d.ts +2 -1
  36. package/dist/components/meter/index.js +9 -7
  37. package/dist/components/meter/index.js.map +1 -1
  38. package/dist/components/navigation-bar/index.d.ts +3 -9
  39. package/dist/components/navigation-bar/index.js +10 -34
  40. package/dist/components/navigation-bar/index.js.map +1 -1
  41. package/dist/components/navigation-rail/index.d.ts +68 -0
  42. package/dist/components/navigation-rail/index.js +294 -0
  43. package/dist/components/navigation-rail/index.js.map +1 -0
  44. package/dist/components/number-field/index.d.ts +7 -3
  45. package/dist/components/number-field/index.js +214 -192
  46. package/dist/components/number-field/index.js.map +1 -1
  47. package/dist/components/popover/index.js +1 -1
  48. package/dist/components/product-icon/index.d.ts +2 -2
  49. package/dist/components/product-icon/index.js +2 -2
  50. package/dist/components/product-icon/index.js.map +1 -1
  51. package/dist/components/progress-indicator/index.d.ts +2 -1
  52. package/dist/components/progress-indicator/index.js +15 -13
  53. package/dist/components/progress-indicator/index.js.map +1 -1
  54. package/dist/components/search-field/index.d.ts +3 -3
  55. package/dist/components/search-field/index.js +105 -104
  56. package/dist/components/search-field/index.js.map +1 -1
  57. package/dist/components/sheet/index.d.ts +2 -2
  58. package/dist/components/sheet/index.js +22 -26
  59. package/dist/components/sheet/index.js.map +1 -1
  60. package/dist/components/snackbar/index.d.ts +3 -3
  61. package/dist/components/snackbar/index.js +36 -34
  62. package/dist/components/snackbar/index.js.map +1 -1
  63. package/dist/components/tag/index.d.ts +58 -0
  64. package/dist/components/tag/index.js +205 -0
  65. package/dist/components/tag/index.js.map +1 -0
  66. package/dist/components/text-field/index.d.ts +6 -3
  67. package/dist/components/text-field/index.js +3 -0
  68. package/dist/components/text-field/index.js.map +1 -1
  69. package/dist/field/index.js +39 -36
  70. package/dist/field/index.js.map +1 -1
  71. package/dist/glyphs/index.js +19 -1
  72. package/dist/glyphs/index.js.map +1 -1
  73. package/dist/i18n/index.js +12 -1
  74. package/dist/i18n/index.js.map +1 -1
  75. package/dist/i18n/messages.js +741 -0
  76. package/dist/i18n/messages.js.map +1 -1
  77. package/dist/i18n/provider.d.ts +53 -0
  78. package/dist/i18n/provider.js +96 -0
  79. package/dist/i18n/provider.js.map +1 -0
  80. package/dist/index.d.ts +5 -1
  81. package/dist/index.js +6 -2
  82. package/dist/indicator/index.js +1 -2
  83. package/dist/indicator/index.js.map +1 -1
  84. package/dist/mark/index.js +77 -117
  85. package/dist/mark/index.js.map +1 -1
  86. package/dist/mark/initials.js.map +1 -1
  87. package/dist/navigation/index.d.ts +8 -1
  88. package/dist/navigation/index.js +113 -64
  89. package/dist/navigation/index.js.map +1 -1
  90. package/dist/navigation/styles.js +22 -0
  91. package/dist/navigation/styles.js.map +1 -1
  92. package/dist/number/count.js +15 -0
  93. package/dist/number/count.js.map +1 -0
  94. package/dist/number/locale.js.map +1 -1
  95. package/dist/overlay/host.js +30 -21
  96. package/dist/overlay/host.js.map +1 -1
  97. package/package.json +3 -2
@@ -4,6 +4,7 @@ import { composeStyles } from "../theme/styles.js";
4
4
  import { hitSlop, usePressFeedback } from "../press/index.js";
5
5
  import { useTypeRole } from "../typography/roles.js";
6
6
  import { withOpacity } from "../theme/color.js";
7
+ import { useLinkPress } from "../router/index.js";
7
8
  import { Badge } from "../badge/index.js";
8
9
  import { INDICATOR, styles, stylesOf } from "./styles.js";
9
10
  import { c } from "react/compiler-runtime";
@@ -15,6 +16,12 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
16
  const GROWN_FROM = .4;
16
17
  const FADE_SHARE = .2;
17
18
  const ICON_SIZE = 24;
19
+ const BESIDE = {
20
+ collapsed: false,
21
+ expanded: true,
22
+ horizontal: true,
23
+ vertical: false
24
+ };
18
25
  const NavigationContext = createContext({
19
26
  form: "vertical",
20
27
  measuring: false
@@ -83,24 +90,24 @@ function ActiveIndicator(t0) {
83
90
  }
84
91
  /**
85
92
  * 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.
93
+ * where the label is beside the icon the label before them in the tree,
94
+ * which the pill's reversed row draws after them.
88
95
  */
89
96
  function DestinationContent(t0) {
90
97
  const $ = c(20);
91
98
  const { badge, form, icon, isDisabled, label, selected } = t0;
92
99
  const theme = useTheme();
93
- const horizontal = form === "horizontal";
100
+ const beside = BESIDE[form];
94
101
  let t1;
95
- if ($[0] !== form || $[1] !== horizontal || $[2] !== isDisabled || $[3] !== label || $[4] !== selected) {
96
- t1 = horizontal ? /* @__PURE__ */ jsx(Label, {
102
+ if ($[0] !== beside || $[1] !== form || $[2] !== isDisabled || $[3] !== label || $[4] !== selected) {
103
+ t1 = beside ? /* @__PURE__ */ jsx(Label, {
97
104
  form,
98
105
  isDisabled,
99
106
  selected,
100
107
  children: label
101
108
  }) : null;
102
- $[0] = form;
103
- $[1] = horizontal;
109
+ $[0] = beside;
110
+ $[1] = form;
104
111
  $[2] = isDisabled;
105
112
  $[3] = label;
106
113
  $[4] = selected;
@@ -115,14 +122,14 @@ function DestinationContent(t0) {
115
122
  $[9] = t2;
116
123
  } else t2 = $[9];
117
124
  let t3;
118
- if ($[10] !== badge || $[11] !== horizontal || $[12] !== icon) {
125
+ if ($[10] !== badge || $[11] !== beside || $[12] !== icon) {
119
126
  t3 = badge === void 0 || badge === false ? icon : /* @__PURE__ */ jsx(Badge, {
120
127
  count: badge === true ? void 0 : badge,
121
- inFlow: horizontal,
128
+ inFlow: beside,
122
129
  children: icon
123
130
  });
124
131
  $[10] = badge;
125
- $[11] = horizontal;
132
+ $[11] = beside;
126
133
  $[12] = icon;
127
134
  $[13] = t3;
128
135
  } else t3 = $[13];
@@ -159,12 +166,15 @@ function iconStyleOf(color) {
159
166
  size: ICON_SIZE
160
167
  };
161
168
  }
162
- /** A destination's label, on one line, in label medium. */
169
+ /**
170
+ * A destination's label, on one line: in label large in an expanded rail,
171
+ * and in label medium everywhere else.
172
+ */
163
173
  function Label(t0) {
164
174
  const $ = c(9);
165
175
  const { children, form, isDisabled, selected } = t0;
166
176
  const theme = useTheme();
167
- const role = useTypeRole("labelMedium");
177
+ const role = useTypeRole(form === "expanded" ? "labelLarge" : "labelMedium");
168
178
  let t1;
169
179
  if ($[0] !== form || $[1] !== isDisabled || $[2] !== role || $[3] !== selected || $[4] !== theme) {
170
180
  t1 = composeStyles(role, styles.label, { color: labelColorOf(theme, form, isDisabled, selected) });
@@ -190,7 +200,7 @@ function Label(t0) {
190
200
  }
191
201
  /** The colour a destination draws its label in, which its form decides. */
192
202
  function labelColorOf(theme, form, isDisabled, selected) {
193
- return selected && !isDisabled && form === "vertical" ? theme.colors.secondary : iconColorOf(theme, isDisabled, selected);
203
+ return selected && !isDisabled && !BESIDE[form] ? theme.colors.secondary : iconColorOf(theme, isDisabled, selected);
194
204
  }
195
205
  function nameOf(children) {
196
206
  return typeof children === "string" ? children : void 0;
@@ -201,7 +211,7 @@ function nameOf(children) {
201
211
  * `tab` reporting whether it is selected.
202
212
  */
203
213
  function NavigationDestination(t0) {
204
- const $ = c(54);
214
+ const $ = c(55);
205
215
  let ariaLabel;
206
216
  let badge;
207
217
  let children;
@@ -253,9 +263,9 @@ function NavigationDestination(t0) {
253
263
  const theme = useTheme();
254
264
  const { form, measuring } = use(NavigationContext);
255
265
  const own = stylesOf(theme);
256
- const horizontal = form === "horizontal";
266
+ const beside = BESIDE[form];
257
267
  const feedback = usePressFeedback({
258
- area: horizontal ? void 0 : INDICATOR,
268
+ area: beside ? void 0 : INDICATOR,
259
269
  color: theme.colors.onSecondaryContainer,
260
270
  corners: own.pill,
261
271
  disabled: isDisabled,
@@ -289,7 +299,7 @@ function NavigationDestination(t0) {
289
299
  style: own.horizontal,
290
300
  children: content
291
301
  });
292
- if (horizontal) {
302
+ if (beside) {
293
303
  let t3;
294
304
  if ($[22] !== ariaLabel || $[23] !== children) {
295
305
  t3 = ariaLabel ?? nameOf(children);
@@ -298,16 +308,17 @@ function NavigationDestination(t0) {
298
308
  $[24] = t3;
299
309
  } else t3 = $[24];
300
310
  let t4;
301
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
302
- t4 = hitSlop(40);
303
- $[25] = t4;
304
- } else t4 = $[25];
311
+ if ($[25] !== form) {
312
+ t4 = form === "horizontal" ? hitSlop(40) : void 0;
313
+ $[25] = form;
314
+ $[26] = t4;
315
+ } else t4 = $[26];
305
316
  let t5;
306
- if ($[26] !== selected) {
317
+ if ($[27] !== selected) {
307
318
  t5 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
308
- $[26] = selected;
309
- $[27] = t5;
310
- } else t5 = $[27];
319
+ $[27] = selected;
320
+ $[28] = t5;
321
+ } else t5 = $[28];
311
322
  return /* @__PURE__ */ jsxs(Pressable, {
312
323
  "aria-label": t3,
313
324
  "aria-selected": selected,
@@ -316,7 +327,7 @@ function NavigationDestination(t0) {
316
327
  ...props,
317
328
  ...feedback.handlers,
318
329
  disabled: isDisabled,
319
- style: composeStyles(own.horizontal, feedback.ring, style),
330
+ style: composeStyles(own[form], feedback.ring, style),
320
331
  children: [
321
332
  t5,
322
333
  feedback.layer,
@@ -326,39 +337,39 @@ function NavigationDestination(t0) {
326
337
  }
327
338
  const T0 = Pressable;
328
339
  let t3;
329
- if ($[28] !== ariaLabel || $[29] !== children) {
340
+ if ($[29] !== ariaLabel || $[30] !== children) {
330
341
  t3 = ariaLabel ?? nameOf(children);
331
- $[28] = ariaLabel;
332
- $[29] = children;
333
- $[30] = t3;
334
- } else t3 = $[30];
342
+ $[29] = ariaLabel;
343
+ $[30] = children;
344
+ $[31] = t3;
345
+ } else t3 = $[31];
335
346
  const t4 = "tab";
336
347
  const t5 = feedback.handlers;
337
- const t6 = composeStyles(own.vertical, style);
348
+ const t6 = composeStyles(own[form], style);
338
349
  let t7;
339
- if ($[31] !== children || $[32] !== form || $[33] !== isDisabled || $[34] !== selected) {
350
+ if ($[32] !== children || $[33] !== form || $[34] !== isDisabled || $[35] !== selected) {
340
351
  t7 = /* @__PURE__ */ jsx(Label, {
341
352
  form,
342
353
  isDisabled,
343
354
  selected,
344
355
  children
345
356
  });
346
- $[31] = children;
347
- $[32] = form;
348
- $[33] = isDisabled;
349
- $[34] = selected;
350
- $[35] = t7;
351
- } else t7 = $[35];
357
+ $[32] = children;
358
+ $[33] = form;
359
+ $[34] = isDisabled;
360
+ $[35] = selected;
361
+ $[36] = t7;
362
+ } else t7 = $[36];
352
363
  const T1 = View;
353
364
  const t8 = composeStyles(own.indicator, feedback.ring);
354
365
  let t9;
355
- if ($[36] !== selected) {
366
+ if ($[37] !== selected) {
356
367
  t9 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
357
- $[36] = selected;
358
- $[37] = t9;
359
- } else t9 = $[37];
368
+ $[37] = selected;
369
+ $[38] = t9;
370
+ } else t9 = $[38];
360
371
  let t10;
361
- if ($[38] !== T1 || $[39] !== content || $[40] !== feedback.layer || $[41] !== t8 || $[42] !== t9) {
372
+ if ($[39] !== T1 || $[40] !== content || $[41] !== feedback.layer || $[42] !== t8 || $[43] !== t9) {
362
373
  t10 = /* @__PURE__ */ jsxs(T1, {
363
374
  style: t8,
364
375
  children: [
@@ -367,15 +378,15 @@ function NavigationDestination(t0) {
367
378
  content
368
379
  ]
369
380
  });
370
- $[38] = T1;
371
- $[39] = content;
372
- $[40] = feedback.layer;
373
- $[41] = t8;
374
- $[42] = t9;
375
- $[43] = t10;
376
- } else t10 = $[43];
381
+ $[39] = T1;
382
+ $[40] = content;
383
+ $[41] = feedback.layer;
384
+ $[42] = t8;
385
+ $[43] = t9;
386
+ $[44] = t10;
387
+ } else t10 = $[44];
377
388
  let t11;
378
- if ($[44] !== T0 || $[45] !== feedback.handlers || $[46] !== isDisabled || $[47] !== props || $[48] !== selected || $[49] !== t10 || $[50] !== t3 || $[51] !== t6 || $[52] !== t7) {
389
+ if ($[45] !== T0 || $[46] !== feedback.handlers || $[47] !== isDisabled || $[48] !== props || $[49] !== selected || $[50] !== t10 || $[51] !== t3 || $[52] !== t6 || $[53] !== t7) {
379
390
  t11 = /* @__PURE__ */ jsxs(T0, {
380
391
  "aria-label": t3,
381
392
  "aria-selected": selected,
@@ -386,20 +397,58 @@ function NavigationDestination(t0) {
386
397
  style: t6,
387
398
  children: [t7, t10]
388
399
  });
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
+ $[45] = T0;
401
+ $[46] = feedback.handlers;
402
+ $[47] = isDisabled;
403
+ $[48] = props;
404
+ $[49] = selected;
405
+ $[50] = t10;
406
+ $[51] = t3;
407
+ $[52] = t6;
408
+ $[53] = t7;
409
+ $[54] = t11;
410
+ } else t11 = $[54];
400
411
  return t11;
401
412
  }
413
+ /**
414
+ * A destination that goes to its `href` through the app's router, selected
415
+ * while the `selectedRoute` around it is that `href`: the item of a bar and
416
+ * of a rail alike.
417
+ */
418
+ function NavigationItem(t0) {
419
+ const $ = c(8);
420
+ let href;
421
+ let onPress;
422
+ let props;
423
+ if ($[0] !== t0) {
424
+ ({href, onPress, ...props} = t0);
425
+ $[0] = t0;
426
+ $[1] = href;
427
+ $[2] = onPress;
428
+ $[3] = props;
429
+ } else {
430
+ href = $[1];
431
+ onPress = $[2];
432
+ props = $[3];
433
+ }
434
+ const { selectedRoute } = use(NavigationContext);
435
+ const press = useLinkPress(href, onPress);
436
+ const t1 = selectedRoute !== void 0 && href === selectedRoute;
437
+ let t2;
438
+ if ($[4] !== press || $[5] !== props || $[6] !== t1) {
439
+ t2 = /* @__PURE__ */ jsx(NavigationDestination, {
440
+ ...props,
441
+ onPress: press,
442
+ selected: t1
443
+ });
444
+ $[4] = press;
445
+ $[5] = props;
446
+ $[6] = t1;
447
+ $[7] = t2;
448
+ } else t2 = $[7];
449
+ return t2;
450
+ }
402
451
  //#endregion
403
- export { NavigationContext, NavigationDestination, iconColorOf, labelColorOf };
452
+ export { NavigationContext, NavigationDestination, NavigationItem, iconColorOf, labelColorOf };
404
453
 
405
454
  //# sourceMappingURL=index.js.map
@@ -1 +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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"}
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","useLinkPress","withOpacity","useTheme","composeStyles","useTypeRole","INDICATOR","PILL_HEIGHT","styles","stylesOf","NavigationContextValue","form","NavigationForm","measuring","selectedRoute","NavigationDestinationProps","Omit","badge","children","icon","isDisabled","ref","style","NavigationItemProps","href","GROWN_FROM","FADE_SHARE","ICON_SIZE","BESIDE","Readonly","Record","collapsed","expanded","horizontal","vertical","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","beside","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","handlers","ring","layer","T0","t6","t7","T1","t8","indicator","t9","t10","t11","NavigationItem","onPress","press","_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 { useLinkPress } from '../router'\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 and NavigationRail both draw, in the four\n// forms their pages give it, as kanso-ui's src/navigation draws it. Apart\n// from either component, so the two 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: the bar in a\n// compact window, sharing its width with the others, and the collapsed rail,\n// as wide as the rail. A horizontal one is a pill holding the icon and the\n// label side by side, 16dp in at either end: the bar from the medium window\n// size class at 40dp with 4dp between the two in label medium, and the\n// expanded rail at 56dp with 8dp between them in label large. Which form a\n// destination draws is its bar's or its rail's to say, through the context\n// 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. The bar's 40dp\n// pill's press reaches 4dp above and below it, to the 48dp target; a\n// vertical destination is the bar's full height already, and the other two\n// forms are 56dp and 64dp tall. 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 form a destination draws: the bar's `vertical` and `horizontal`,\n * and the rail's `collapsed` and `expanded`. The label is under the icon in\n * the first and the third, and beside it in the other two.\n */\ntype NavigationForm = 'collapsed' | 'expanded' | 'horizontal' | 'vertical'\n\ntype NavigationItemProps = NavigationDestinationProps & {\n /**\n * Where the destination goes, through the app's router, and what the\n * `selectedRoute` around it is matched against.\n */\n readonly href: string\n}\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\n// Whether a form sets the label beside the icon rather than under it.\nconst BESIDE: Readonly<Record<NavigationForm, boolean>> = {\n collapsed: false,\n expanded: true,\n horizontal: true,\n vertical: false,\n}\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 * where the label is beside the icon the label before them in the tree,\n * which the 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 beside = BESIDE[form]\n\n return (\n <>\n {beside ? (\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 count={badge === true ? undefined : badge} inFlow={beside}>\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/**\n * A destination's label, on one line: in label large in an expanded rail,\n * and in label medium everywhere else.\n */\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(form === 'expanded' ? 'labelLarge' : '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 && !BESIDE[form]\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 beside = BESIDE[form]\n const feedback = usePressFeedback({\n area: beside ? 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 (beside) {\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n hitSlop={form === 'horizontal' ? hitSlop(PILL_HEIGHT) : undefined}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own[form], 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[form], 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\n/**\n * A destination that goes to its `href` through the app's router, selected\n * while the `selectedRoute` around it is that `href`: the item of a bar and\n * of a rail alike.\n */\nfunction NavigationItem({ href, onPress, ...props }: NavigationItemProps) {\n const { selectedRoute } = use(NavigationContext)\n const press = useLinkPress(href, onPress)\n\n return (\n <NavigationDestination\n {...props}\n onPress={press}\n selected={selectedRoute !== undefined && href === selectedRoute}\n />\n )\n}\n\nexport type {\n NavigationContextValue,\n NavigationDestinationProps,\n NavigationForm,\n NavigationItemProps,\n}\n\nexport {\n iconColorOf,\n labelColorOf,\n NavigationContext,\n NavigationDestination,\n NavigationItem,\n}\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ const INDICATOR = {
5
5
  height: 32,
6
6
  width: 56
7
7
  };
8
+ const EXPANDED_PILL_HEIGHT = 56;
8
9
  const VERTICAL_PADDING = 6;
9
10
  const styles = StyleSheet.create({
10
11
  fill: {
@@ -25,6 +26,27 @@ const styles = StyleSheet.create({
25
26
  }
26
27
  });
27
28
  const stylesOf = themedStyles(({ radii, spacing }) => StyleSheet.create({
29
+ collapsed: {
30
+ alignItems: "center",
31
+ alignSelf: "stretch",
32
+ flexDirection: "column-reverse",
33
+ flexShrink: 0,
34
+ gap: spacing.xs,
35
+ justifyContent: "center",
36
+ paddingHorizontal: spacing.xs,
37
+ paddingVertical: VERTICAL_PADDING
38
+ },
39
+ expanded: {
40
+ alignItems: "center",
41
+ alignSelf: "flex-start",
42
+ borderRadius: radii.pill,
43
+ flexDirection: "row-reverse",
44
+ flexShrink: 0,
45
+ gap: spacing.sm,
46
+ maxWidth: "100%",
47
+ minHeight: EXPANDED_PILL_HEIGHT,
48
+ paddingHorizontal: spacing.lg
49
+ },
28
50
  horizontal: {
29
51
  alignItems: "center",
30
52
  borderRadius: radii.pill,
@@ -1 +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
+ {"version":3,"file":"styles.js","names":["StyleSheet","themedStyles","INDICATOR","height","width","const","PILL_HEIGHT","EXPANDED_PILL_HEIGHT","VERTICAL_PADDING","styles","create","fill","bottom","end","position","start","top","icon","alignItems","flexShrink","justifyContent","label","maxWidth","stylesOf","radii","spacing","collapsed","alignSelf","flexDirection","gap","xs","paddingHorizontal","paddingVertical","expanded","borderRadius","pill","sm","minHeight","lg","horizontal","indicator","vertical","flexBasis","flexGrow","minWidth"],"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, and an expanded rail's, the rail page's 56dp.\nconst PILL_HEIGHT = 40\nconst EXPANDED_PILL_HEIGHT = 56\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 or collapsed\n // destination and behind the whole pill in a horizontal or expanded 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 collapsed rail's destination: the indicator with the label 4dp under\n // it, as wide as the rail and 4dp in from either edge, which leaves a\n // label 88dp of the rail's 96. It keeps its 64dp in a rail too short for\n // every destination, which scrolls them instead. Reversed, since the\n // label comes first in the tree.\n collapsed: {\n alignItems: 'center',\n alignSelf: 'stretch',\n flexDirection: 'column-reverse',\n flexShrink: 0,\n gap: spacing.xs,\n justifyContent: 'center',\n paddingHorizontal: spacing.xs,\n paddingVertical: VERTICAL_PADDING,\n },\n // An expanded rail's destination: the rail page's 56dp pill, holding the\n // icon and the label side by side, 16dp in at either end and 8dp between\n // the two, as wide as what it holds and no wider than the rail. A height\n // that is a minimum, so a larger text size grows the pill rather than\n // cutting its label. Reversed, since the label comes first in the tree.\n expanded: {\n alignItems: 'center',\n alignSelf: 'flex-start',\n borderRadius: radii.pill,\n flexDirection: 'row-reverse',\n flexShrink: 0,\n gap: spacing.sm,\n maxWidth: '100%',\n minHeight: EXPANDED_PILL_HEIGHT,\n paddingHorizontal: spacing.lg,\n },\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;AAK1C,MAAMG,uBAAuB;AAI7B,MAAMC,mBAAmB;AAEzB,MAAMC,SAAST,WAAWU,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,WAAWtB,cAAc,EAAEuB,OAAOC,cACtCzB,WAAWU,OAAO;CAMhBgB,WAAW;EACTR,YAAY;EACZS,WAAW;EACXC,eAAe;EACfT,YAAY;EACZU,KAAKJ,QAAQK;EACbV,gBAAgB;EAChBW,mBAAmBN,QAAQK;EAC3BE,iBAAiBxB;CACnB;CAMAyB,UAAU;EACRf,YAAY;EACZS,WAAW;EACXO,cAAcV,MAAMW;EACpBP,eAAe;EACfT,YAAY;EACZU,KAAKJ,QAAQW;EACbd,UAAU;EACVe,WAAW9B;EACXwB,mBAAmBN,QAAQa;CAC7B;CAIAC,YAAY;EACVrB,YAAY;EACZgB,cAAcV,MAAMW;EACpBP,eAAe;EACfT,YAAY;EACZU,KAAKJ,QAAQK;EACbV,gBAAgB;EAChBiB,WAAAA;EACAN,mBAAmBN,QAAQa;CAC7B;CAGAE,WAAW;EACTtB,YAAY;EACZgB,cAAcV,MAAMW;EACpBhB,YAAY;EACZhB,QAAQD,UAAUC;EAClBiB,gBAAgB;EAChBhB,OAAOF,UAAUE;CACnB;CAEA+B,MAAM,EACJD,cAAcV,MAAMW,KACtB;CAKAM,UAAU;EACRvB,YAAY;EACZwB,WAAW;EACXd,eAAe;EACfe,UAAU;EACVd,KAAKJ,QAAQK;EACbV,gBAAgB;EAChBwB,UAAU;EACVZ,iBAAiBxB;CACnB;AACF,CAAC,CACH"}
@@ -0,0 +1,15 @@
1
+ //#region src/number/count.ts
2
+ const formats = /* @__PURE__ */ new Map();
3
+ /** A count in `locale`'s digits and grouping. */
4
+ function formatCount(count, locale) {
5
+ let format = formats.get(locale);
6
+ if (format === void 0) {
7
+ format = new Intl.NumberFormat(locale);
8
+ formats.set(locale, format);
9
+ }
10
+ return format.format(count);
11
+ }
12
+ //#endregion
13
+ export { formatCount };
14
+
15
+ //# sourceMappingURL=count.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"count.js","names":["formats","Map","Intl","NumberFormat","formatCount","count","locale","format","get","undefined","set"],"sources":["../../src/number/count.ts"],"sourcesContent":["// One plain formatter per locale, for the counts a badge and a field's counter\n// write, which change often enough that building a formatter on each would\n// show. The keys are the locales an app renders in, so the map settles at that\n// size.\nconst formats = new Map<string, Intl.NumberFormat>()\n\n/** A count in `locale`'s digits and grouping. */\nfunction formatCount(count: number, locale: string) {\n let format = formats.get(locale)\n\n if (format === undefined) {\n format = new Intl.NumberFormat(locale)\n formats.set(locale, format)\n }\n\n return format.format(count)\n}\n\nexport { formatCount }\n"],"mappings":";AAIA,MAAMA,0BAAU,IAAIC,IAA+B;;AAGnD,SAASG,YAAYC,OAAeC,QAAgB;CAClD,IAAIC,SAASP,QAAQQ,IAAIF,MAAM;CAE/B,IAAIC,WAAWE,KAAAA,GAAW;EACxBF,SAAS,IAAIL,KAAKC,aAAaG,MAAM;EACrCN,QAAQU,IAAIJ,QAAQC,MAAM;CAC5B;CAEA,OAAOA,OAAOA,OAAOF,KAAK;AAC5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"locale.js","names":["deviceLocale","localeOf","locale","undefined","Intl","NumberFormat","supportedLocalesOf","resolvedOptions"],"sources":["../../src/number/locale.ts"],"sourcesContent":["// The locale a component writes its numbers in, and src/i18n its words: the\n// one given, where the runtime takes it as a locale at all, or the device's.\n// Web reads the page's from React Aria's `I18nProvider`; React Native has no\n// such context, so a component that formats a number takes the locale as a\n// prop and falls back to this.\n\nlet deviceLocale: string | undefined\n\nfunction localeOf(locale: string | undefined) {\n if (locale !== undefined) {\n try {\n Intl.NumberFormat.supportedLocalesOf(locale)\n return locale\n } catch {\n // A malformed tag, which falls back to the device's.\n }\n }\n\n deviceLocale ??= new Intl.NumberFormat().resolvedOptions().locale\n return deviceLocale\n}\n\nexport { localeOf }\n"],"mappings":";AAMA,IAAIA;AAEJ,SAASC,SAASC,QAA4B;CAC5C,IAAIA,WAAWC,KAAAA,GACb,IAAI;EACFC,KAAKC,aAAaC,mBAAmBJ,MAAM;EAC3C,OAAOA;CACT,QAAQ,CACN;CAIJF,iBAAiB,IAAII,KAAKC,aAAa,CAAC,CAACE,gBAAgB,CAAC,CAACL;CAC3D,OAAOF;AACT"}
1
+ {"version":3,"file":"locale.js","names":["deviceLocale","localeOf","locale","undefined","Intl","NumberFormat","supportedLocalesOf","resolvedOptions"],"sources":["../../src/number/locale.ts"],"sourcesContent":["// The locale a component writes its numbers in, and src/i18n its words: the\n// one given, where the runtime takes it as a locale at all, or the device's.\n// Which one is given is `useLocaleOf`'s in src/i18n/provider.tsx, the\n// component's own prop or the `I18nProvider`'s, as web reads the page's from\n// React Aria's provider.\n\nlet deviceLocale: string | undefined\n\nfunction localeOf(locale: string | undefined) {\n if (locale !== undefined) {\n try {\n Intl.NumberFormat.supportedLocalesOf(locale)\n return locale\n } catch {\n // A malformed tag, which falls back to the device's.\n }\n }\n\n deviceLocale ??= new Intl.NumberFormat().resolvedOptions().locale\n return deviceLocale\n}\n\nexport { localeOf }\n"],"mappings":";AAMA,IAAIA;AAEJ,SAASC,SAASC,QAA4B;CAC5C,IAAIA,WAAWC,KAAAA,GACb,IAAI;EACFC,KAAKC,aAAaC,mBAAmBJ,MAAM;EAC3C,OAAOA;CACT,QAAQ,CACN;CAIJF,iBAAiB,IAAII,KAAKC,aAAa,CAAC,CAACE,gBAAgB,CAAC,CAACL;CAC3D,OAAOF;AACT"}
@@ -1,4 +1,5 @@
1
1
  import { ScopeContext, useScope } from "../theme/scope.js";
2
+ import { I18nProvider, useProvidedLocale } from "../i18n/provider.js";
2
3
  import { c } from "react/compiler-runtime";
3
4
  import { StyleSheet, View } from "react-native";
4
5
  import { createContext, use, useId, useLayoutEffect, useState, useSyncExternalStore } from "react";
@@ -18,59 +19,67 @@ const styles = StyleSheet.create({ fill: {
18
19
  * outermost `ThemeScope`, for as long as it is mounted. A later overlay draws
19
20
  * above an earlier one.
20
21
  *
21
- * The content reads the `ThemeScope` around the `Overlay`, as anything else
22
- * there would. Other context set between the host and the `Overlay` does not
23
- * reach it: an overlay is a surface of its own, as web's `OverlayScope` makes
24
- * one, so it starts from what is around the app rather than from what is
25
- * around the control that opened it.
22
+ * The content reads the `ThemeScope` and the `I18nProvider` around the
23
+ * `Overlay`, as anything else there would, so a dialog writes in the locale
24
+ * of the screen that opened it, as web's portal does. Other context set
25
+ * between the host and the `Overlay` does not reach it: an overlay is a
26
+ * surface of its own, as web's `OverlayScope` makes one, so it starts from
27
+ * what is around the app rather than from what is around the control that
28
+ * opened it.
26
29
  */
27
30
  function Overlay(t0) {
28
- const $ = c(10);
31
+ const $ = c(11);
29
32
  const { children } = t0;
30
33
  const store = use(OverlayHostContext);
31
34
  const scope = useScope();
35
+ const locale = useProvidedLocale();
32
36
  const key = useId();
33
37
  if (store === null) throw new Error("An overlay draws in the host of the outermost ThemeScope, and there is no ThemeScope around this one. Wrap the app in a ThemeScope.");
34
38
  let t1;
35
39
  let t2;
36
- if ($[0] !== children || $[1] !== key || $[2] !== scope || $[3] !== store) {
40
+ if ($[0] !== children || $[1] !== key || $[2] !== locale || $[3] !== scope || $[4] !== store) {
37
41
  t1 = () => {
38
42
  store.set(key, /* @__PURE__ */ jsx(ScopeContext, {
39
43
  value: scope,
40
- children
44
+ children: /* @__PURE__ */ jsx(I18nProvider, {
45
+ locale,
46
+ children
47
+ })
41
48
  }));
42
49
  };
43
50
  t2 = [
44
51
  children,
45
52
  key,
53
+ locale,
46
54
  scope,
47
55
  store
48
56
  ];
49
57
  $[0] = children;
50
58
  $[1] = key;
51
- $[2] = scope;
52
- $[3] = store;
53
- $[4] = t1;
54
- $[5] = t2;
59
+ $[2] = locale;
60
+ $[3] = scope;
61
+ $[4] = store;
62
+ $[5] = t1;
63
+ $[6] = t2;
55
64
  } else {
56
- t1 = $[4];
57
- t2 = $[5];
65
+ t1 = $[5];
66
+ t2 = $[6];
58
67
  }
59
68
  useLayoutEffect(t1, t2);
60
69
  let t3;
61
70
  let t4;
62
- if ($[6] !== key || $[7] !== store) {
71
+ if ($[7] !== key || $[8] !== store) {
63
72
  t3 = () => () => {
64
73
  store.remove(key);
65
74
  };
66
75
  t4 = [key, store];
67
- $[6] = key;
68
- $[7] = store;
69
- $[8] = t3;
70
- $[9] = t4;
76
+ $[7] = key;
77
+ $[8] = store;
78
+ $[9] = t3;
79
+ $[10] = t4;
71
80
  } else {
72
- t3 = $[8];
73
- t4 = $[9];
81
+ t3 = $[9];
82
+ t4 = $[10];
74
83
  }
75
84
  useLayoutEffect(t3, t4);
76
85
  return null;