@kanso-labs/react-native-kanso-ui 0.7.0 → 0.9.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 (150) hide show
  1. package/README.md +37 -0
  2. package/dist/badge/index.js +9 -68
  3. package/dist/badge/index.js.map +1 -1
  4. package/dist/button/index.d.ts +2 -1
  5. package/dist/button/index.js +1 -1
  6. package/dist/button/index.js.map +1 -1
  7. package/dist/button/palettes.d.ts +2 -0
  8. package/dist/button/pending.js +17 -21
  9. package/dist/button/pending.js.map +1 -1
  10. package/dist/calendar/index.js +1 -1
  11. package/dist/components/autocomplete/index.js +28 -26
  12. package/dist/components/autocomplete/index.js.map +1 -1
  13. package/dist/components/avatar/index.d.ts +2 -2
  14. package/dist/components/avatar/index.js +2 -2
  15. package/dist/components/avatar/index.js.map +1 -1
  16. package/dist/components/badge/index.d.ts +48 -0
  17. package/dist/components/badge/index.js +122 -0
  18. package/dist/components/badge/index.js.map +1 -0
  19. package/dist/{badge → components/badge}/styles.js +10 -6
  20. package/dist/components/badge/styles.js.map +1 -0
  21. package/dist/components/breadcrumbs/index.d.ts +66 -0
  22. package/dist/components/breadcrumbs/index.js +285 -0
  23. package/dist/components/breadcrumbs/index.js.map +1 -0
  24. package/dist/components/calendar/index.d.ts +1 -1
  25. package/dist/components/calendar/index.js +77 -38
  26. package/dist/components/calendar/index.js.map +1 -1
  27. package/dist/components/checkbox/index.d.ts +7 -1
  28. package/dist/components/checkbox/index.js +183 -138
  29. package/dist/components/checkbox/index.js.map +1 -1
  30. package/dist/components/checkbox-group/index.d.ts +93 -0
  31. package/dist/components/checkbox-group/index.js +306 -0
  32. package/dist/components/checkbox-group/index.js.map +1 -0
  33. package/dist/components/chip-group/index.d.ts +4 -3
  34. package/dist/components/chip-group/index.js +47 -45
  35. package/dist/components/chip-group/index.js.map +1 -1
  36. package/dist/components/code/index.d.ts +25 -0
  37. package/dist/components/code/index.js +87 -0
  38. package/dist/components/code/index.js.map +1 -0
  39. package/dist/components/container/index.d.ts +47 -0
  40. package/dist/components/container/index.js +85 -0
  41. package/dist/components/container/index.js.map +1 -0
  42. package/dist/components/copy-field/index.d.ts +5 -5
  43. package/dist/components/copy-field/index.js +30 -28
  44. package/dist/components/copy-field/index.js.map +1 -1
  45. package/dist/components/currency/index.d.ts +2 -2
  46. package/dist/components/currency/index.js +3 -1
  47. package/dist/components/currency/index.js.map +1 -1
  48. package/dist/components/fab/index.d.ts +80 -0
  49. package/dist/components/fab/index.js +231 -0
  50. package/dist/components/fab/index.js.map +1 -0
  51. package/dist/components/fab-menu/index.d.ts +120 -0
  52. package/dist/components/fab-menu/index.js +640 -0
  53. package/dist/components/fab-menu/index.js.map +1 -0
  54. package/dist/components/feed/index.d.ts +57 -0
  55. package/dist/components/feed/index.js +167 -0
  56. package/dist/components/feed/index.js.map +1 -0
  57. package/dist/components/keycap/index.d.ts +27 -0
  58. package/dist/components/keycap/index.js +136 -0
  59. package/dist/components/keycap/index.js.map +1 -0
  60. package/dist/components/list/index.d.ts +6 -5
  61. package/dist/components/list/index.js +97 -106
  62. package/dist/components/list/index.js.map +1 -1
  63. package/dist/components/menu/index.d.ts +4 -3
  64. package/dist/components/menu/index.js +33 -40
  65. package/dist/components/menu/index.js.map +1 -1
  66. package/dist/components/meter/index.d.ts +2 -1
  67. package/dist/components/meter/index.js +9 -7
  68. package/dist/components/meter/index.js.map +1 -1
  69. package/dist/components/number-field/index.d.ts +7 -3
  70. package/dist/components/number-field/index.js +214 -192
  71. package/dist/components/number-field/index.js.map +1 -1
  72. package/dist/components/product-icon/index.d.ts +2 -2
  73. package/dist/components/product-icon/index.js +2 -2
  74. package/dist/components/product-icon/index.js.map +1 -1
  75. package/dist/components/progress-indicator/index.d.ts +2 -1
  76. package/dist/components/progress-indicator/index.js +15 -13
  77. package/dist/components/progress-indicator/index.js.map +1 -1
  78. package/dist/components/search-field/index.d.ts +3 -3
  79. package/dist/components/search-field/index.js +105 -104
  80. package/dist/components/search-field/index.js.map +1 -1
  81. package/dist/components/separator/index.d.ts +3 -2
  82. package/dist/components/separator/index.js +29 -26
  83. package/dist/components/separator/index.js.map +1 -1
  84. package/dist/components/sheet/index.d.ts +2 -2
  85. package/dist/components/sheet/index.js +22 -26
  86. package/dist/components/sheet/index.js.map +1 -1
  87. package/dist/components/snackbar/index.d.ts +3 -3
  88. package/dist/components/snackbar/index.js +36 -34
  89. package/dist/components/snackbar/index.js.map +1 -1
  90. package/dist/components/supporting-pane/index.d.ts +44 -0
  91. package/dist/components/supporting-pane/index.js +109 -0
  92. package/dist/components/supporting-pane/index.js.map +1 -0
  93. package/dist/components/tag/index.d.ts +58 -0
  94. package/dist/components/tag/index.js +205 -0
  95. package/dist/components/tag/index.js.map +1 -0
  96. package/dist/components/text/index.d.ts +1 -1
  97. package/dist/components/text/index.js +49 -21
  98. package/dist/components/text/index.js.map +1 -1
  99. package/dist/components/text-area/index.d.ts +145 -0
  100. package/dist/components/text-area/index.js +231 -0
  101. package/dist/components/text-area/index.js.map +1 -0
  102. package/dist/components/text-field/index.d.ts +6 -3
  103. package/dist/components/text-field/index.js +3 -0
  104. package/dist/components/text-field/index.js.map +1 -1
  105. package/dist/components/toolbar/index.d.ts +53 -0
  106. package/dist/components/toolbar/index.js +185 -0
  107. package/dist/components/toolbar/index.js.map +1 -0
  108. package/dist/control/group.js +23 -0
  109. package/dist/control/group.js.map +1 -0
  110. package/dist/fab/index.d.ts +19 -0
  111. package/dist/fab/index.js +147 -0
  112. package/dist/fab/index.js.map +1 -0
  113. package/dist/field/index.js +123 -79
  114. package/dist/field/index.js.map +1 -1
  115. package/dist/field/styles.js +18 -0
  116. package/dist/field/styles.js.map +1 -1
  117. package/dist/form/index.d.ts +1 -2
  118. package/dist/form/index.js +1 -1
  119. package/dist/form/index.js.map +1 -1
  120. package/dist/i18n/index.js +12 -1
  121. package/dist/i18n/index.js.map +1 -1
  122. package/dist/i18n/messages.js +367 -0
  123. package/dist/i18n/messages.js.map +1 -1
  124. package/dist/i18n/provider.d.ts +53 -0
  125. package/dist/i18n/provider.js +96 -0
  126. package/dist/i18n/provider.js.map +1 -0
  127. package/dist/index.d.ts +19 -4
  128. package/dist/index.js +17 -3
  129. package/dist/indicator/index.js +1 -2
  130. package/dist/indicator/index.js.map +1 -1
  131. package/dist/mark/index.js +77 -117
  132. package/dist/mark/index.js.map +1 -1
  133. package/dist/mark/initials.js.map +1 -1
  134. package/dist/modal/index.js +59 -46
  135. package/dist/modal/index.js.map +1 -1
  136. package/dist/navigation/index.js +8 -5
  137. package/dist/navigation/index.js.map +1 -1
  138. package/dist/number/count.js +15 -0
  139. package/dist/number/count.js.map +1 -0
  140. package/dist/number/locale.js.map +1 -1
  141. package/dist/overlay/host.js +30 -21
  142. package/dist/overlay/host.js.map +1 -1
  143. package/dist/overlay/placement.js +3 -1
  144. package/dist/overlay/placement.js.map +1 -1
  145. package/dist/separator/index.js +7 -0
  146. package/dist/separator/index.js.map +1 -0
  147. package/dist/typography/size.js +14 -0
  148. package/dist/typography/size.js.map +1 -0
  149. package/package.json +1 -1
  150. package/dist/badge/styles.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","StyleProp","TextStyle","ViewProps","ViewStyle","Children","Text","NativeText","StyleSheet","View","IconStyle","IconStyleContext","useTheme","composeStyles","themedStyles","useTypeRole","styles","create","label","flexShrink","fontVariant","stylesOf","radii","spacing","base","alignItems","borderRadius","sm","borderWidth","flexDirection","gap","xs","paddingHorizontal","paddingVertical","xxs","tonesOf","colors","filled","negative","toneOf","negativeContainer","onNegativeContainer","neutral","surfaceContainerHighest","onSurfaceVariant","positive","positiveContainer","onPositiveContainer","primary","primaryContainer","onPrimaryContainer","outlined","outlineVariant","TagProps","children","ref","tone","TagTone","variant","TagVariant","contentOf","content","text","flush","undefined","push","String","length","child","toArray","iconStyleOf","color","size","Tag","t0","$","_c","props","style","t1","t2","theme","role","T0","T1","t3","t4","t5","t6","toned","container","typography","labelSmallLineHeight","t7","t8","background","border","backgroundColor","borderColor","NativeText","_c"],"sources":["../../../src/components/tag/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type { StyleProp, TextStyle, ViewProps, ViewStyle } from 'react-native'\n\nimport { Children } from 'react'\nimport { Text as NativeText, StyleSheet, View } from 'react-native'\n\nimport type { IconStyle } from '../../glyphs/icon-style'\n\nimport { IconStyleContext } from '../../glyphs/icon-style'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// A tag states something about what it sits beside, such as a count, a status\n// or a version, and is never itself the thing you press. That is the whole\n// line between this and Chip: a chip is a two-state button, so reaching for\n// one to draw a read-only label puts a control in the accessibility tree that\n// nothing can operate. The view takes no press and no role.\n//\n// Both variants carry a 1dp border, and `filled` makes it transparent rather\n// than dropping it, so a tag is the same size either way. Emphasising one tag\n// in a row otherwise nudges its neighbours by a dp each side.\n//\n// Tabular figures are unconditional, for the same reason Currency sets them:\n// what ends up in a tag is mostly numeric, such as counts, versions and ports,\n// and a stack of them down a list wobbles on proportional digits. Text that\n// carries no digits is unaffected.\n//\n// No Material Design page draws a tag, as on web. The badges page's large\n// badge is the nearest, a label-small count on an 8dp corner, and that is the\n// type and the corner here. A tag stands beside a word rather than on an icon,\n// so it takes the padding and the 1dp rule above in place of the badge's 16dp\n// box, and the container roles in place of the badge's error pair, since it\n// names a state rather than flagging one.\n//\n// A tag labels something else, so it is never what makes a row wrap or\n// shrink: `flexShrink: 0` holds its width, and its label stays on one line.\nconst styles = StyleSheet.create({\n label: {\n flexShrink: 0,\n fontVariant: ['tabular-nums'],\n },\n})\n\nconst stylesOf = themedStyles(({ radii, spacing }) =>\n StyleSheet.create({\n base: {\n alignItems: 'center',\n borderRadius: radii.sm,\n borderWidth: 1,\n flexDirection: 'row',\n flexShrink: 0,\n gap: spacing.xs,\n paddingHorizontal: spacing.sm,\n paddingVertical: spacing.xxs,\n },\n }),\n)\n\n// `neutral` draws from the surface roles rather than a colour of its own,\n// which is what lets it state something without ranking it. The other three\n// name a direction, and are the same three Currency uses, plus primary for the\n// notable-but-not-good-or-bad case.\n//\n// Outlined takes the tone at full strength for both the rule and the text,\n// rather than the on-container pairing filled uses. There is no container\n// there for an on-colour to be legible against, since the surface is the\n// background, so the container roles would read as washed out.\nconst tonesOf = themedStyles(({ colors }) => ({\n filled: {\n negative: toneOf(\n colors.negativeContainer,\n 'transparent',\n colors.onNegativeContainer,\n ),\n neutral: toneOf(\n colors.surfaceContainerHighest,\n 'transparent',\n colors.onSurfaceVariant,\n ),\n positive: toneOf(\n colors.positiveContainer,\n 'transparent',\n colors.onPositiveContainer,\n ),\n primary: toneOf(\n colors.primaryContainer,\n 'transparent',\n colors.onPrimaryContainer,\n ),\n },\n outlined: {\n negative: toneOf('transparent', colors.negative, colors.negative),\n neutral: toneOf(\n 'transparent',\n colors.outlineVariant,\n colors.onSurfaceVariant,\n ),\n positive: toneOf('transparent', colors.positive, colors.positive),\n primary: toneOf('transparent', colors.primary, colors.primary),\n },\n}))\n\ntype TagProps = ViewProps & {\n /**\n * What the tag says. A string or a number is drawn as its label, and runs\n * of them as one label; anything else, such as an icon, is drawn as given,\n * handed the tag's colour and size through `useIconStyle()`.\n */\n readonly children?: ReactNode\n readonly ref?: Ref<ComponentRef<typeof View>>\n /**\n * Which colour role the tag carries. `neutral` states without ranking; the\n * other three read as good, bad, or worth noticing.\n *\n * Each is a container under its own on-colour, legible on the surface\n * family, which is what the library's own tokens and every demo scheme are\n * held to. Over a container of its own the pair is one colour family on top\n * of another and is not guaranteed, so a custom theme placing a tag there\n * has to check that pair itself.\n * @default 'neutral'\n */\n readonly tone?: TagTone\n /**\n * How much weight the tag pulls. `filled` sits on a container of its own;\n * `outlined` is a rule on the surface, for a tag that should not compete\n * with the thing it labels.\n * @default 'filled'\n */\n readonly variant?: TagVariant\n}\n\ntype TagTone = 'negative' | 'neutral' | 'positive' | 'primary'\n\ntype TagVariant = 'filled' | 'outlined'\n\n/**\n * The children in order, with each run of strings and numbers drawn as one\n * label, so `{count} items` is one Text rather than three. A React Native\n * string has to sit inside a Text, and anything else is drawn as given. A\n * label is keyed by where it falls among what is drawn, which a render of the\n * same children always repeats.\n */\nfunction contentOf(\n children: ReactNode,\n label: StyleProp<TextStyle>,\n): ReactNode[] {\n const content: ReactNode[] = []\n let text: string | undefined\n\n const flush = () => {\n if (text !== undefined) {\n content.push(\n <NativeText\n key={`label-${String(content.length)}`}\n numberOfLines={1}\n style={label}\n >\n {text}\n </NativeText>,\n )\n text = undefined\n }\n }\n\n for (const child of Children.toArray(children)) {\n if (\n typeof child === 'string' ||\n typeof child === 'number' ||\n typeof child === 'bigint'\n ) {\n text = (text ?? '') + String(child)\n } else {\n flush()\n content.push(child)\n }\n }\n flush()\n\n return content\n}\n\n/**\n * The colour and size the tag hands an icon beside its label. Built by a call\n * rather than written inline, which is what react-perf's\n * jsx-no-new-object-as-prop is after; the React Compiler memoises the result\n * on its inputs.\n */\nfunction iconStyleOf(color: string, size: number): IconStyle {\n return { color, size }\n}\n\n/**\n * A short, read-only label attached to something else, such as a count or a\n * status beside a row's headline. It takes no press: for a label that can be\n * selected, reach for Chip.\n *\n * ```tsx\n * <ListItem trailing={<Tag tone=\"positive\">Label</Tag>}>Headline</ListItem>\n * ```\n *\n * The label is set in label small with tabular figures, on one line. An icon\n * given beside it is drawn at the label's line height in the label's colour,\n * so a tag with an icon is the same height as one without. A screen reader\n * reads the label where the tag sits; the tag adds no role of its own.\n *\n * Like any view, a tag stretches across a column it sits in on its own, so a\n * call site placing one there sets `alignSelf`. A row slot, such as\n * ListItem's trailing one, already holds it at its own width.\n *\n * `style`, `ref` and `testID` land on the `View`, and a `style` there applies\n * over the tag's own.\n */\nfunction Tag({\n children,\n style,\n tone = 'neutral',\n variant = 'filled',\n ...props\n}: TagProps) {\n const theme = useTheme()\n const role = useTypeRole('labelSmall')\n const toned = tonesOf(theme)[variant][tone]\n\n return (\n <View\n {...props}\n style={composeStyles<ViewStyle>(\n stylesOf(theme).base,\n toned.container,\n style,\n )}\n >\n <IconStyleContext\n value={iconStyleOf(\n toned.content,\n theme.typography.labelSmallLineHeight,\n )}\n >\n {contentOf(\n children,\n composeStyles<TextStyle>(role, styles.label, toned.label),\n )}\n </IconStyleContext>\n </View>\n )\n}\n\n/**\n * One tone's styles: the container's fill and rule, the label's colour, and\n * that colour on its own for an icon beside the label.\n */\nfunction toneOf(background: string, border: string, content: string) {\n return {\n content,\n ...StyleSheet.create({\n container: { backgroundColor: background, borderColor: border },\n label: { color: content },\n }),\n }\n}\n\nexport type { TagProps, TagTone, TagVariant }\n\nexport { Tag }\n"],"mappings":"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"}
@@ -38,7 +38,7 @@ type TextProps$1 = TextProps & {
38
38
  * rather than an element. `style`, `ref` and `testID` land on React Native's
39
39
  * own Text.
40
40
  */
41
- declare function Text$1({ style, tone, variant, ...props }: TextProps$1): import("react").JSX.Element;
41
+ declare function Text$1({ children, style, tone, variant, ...props }: TextProps$1): import("react").JSX.Element;
42
42
  //#endregion
43
43
  export { Text$1 as Text, type TextProps$1 as TextProps };
44
44
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,8 @@
1
1
  import { useTheme } from "../../theme/scope.js";
2
2
  import { composeStyles, themedStyles } from "../../theme/styles.js";
3
3
  import { useTypeRole } from "../../typography/roles.js";
4
+ import { TextSizeContext } from "../../typography/size.js";
5
+ import { sentenceLabel } from "../keycap/index.js";
4
6
  import { c } from "react/compiler-runtime";
5
7
  import { StyleSheet, Text } from "react-native";
6
8
  import { jsx } from "react/jsx-runtime";
@@ -36,41 +38,67 @@ const stylesOf = themedStyles(({ colors }) => StyleSheet.create({
36
38
  * own Text.
37
39
  */
38
40
  function Text$1(t0) {
39
- const $ = c(9);
41
+ const $ = c(18);
42
+ let children;
40
43
  let props;
41
44
  let style;
42
45
  let t1;
43
46
  let t2;
44
47
  if ($[0] !== t0) {
45
- ({style, tone: t1, variant: t2, ...props} = t0);
48
+ ({children, style, tone: t1, variant: t2, ...props} = t0);
46
49
  $[0] = t0;
47
- $[1] = props;
48
- $[2] = style;
49
- $[3] = t1;
50
- $[4] = t2;
50
+ $[1] = children;
51
+ $[2] = props;
52
+ $[3] = style;
53
+ $[4] = t1;
54
+ $[5] = t2;
51
55
  } else {
52
- props = $[1];
53
- style = $[2];
54
- t1 = $[3];
55
- t2 = $[4];
56
+ children = $[1];
57
+ props = $[2];
58
+ style = $[3];
59
+ t1 = $[4];
60
+ t2 = $[5];
56
61
  }
57
62
  const tone = t1 === void 0 ? "neutral" : t1;
58
63
  const role = useTypeRole(t2 === void 0 ? "bodyMedium" : t2);
59
64
  const tones = stylesOf(useTheme());
60
- const T0 = Text;
61
- const t3 = composeStyles(role, tones[tone], style);
65
+ const composed = composeStyles(role, tones[tone], style);
66
+ const size = StyleSheet.flatten(composed)?.fontSize;
67
+ const plain = typeof children === "string" || typeof children === "number";
68
+ let t3;
69
+ if ($[6] !== children || $[7] !== props) {
70
+ t3 = props.accessibilityLabel ?? (props["aria-label"] === void 0 ? sentenceLabel(children) : void 0);
71
+ $[6] = children;
72
+ $[7] = props;
73
+ $[8] = t3;
74
+ } else t3 = $[8];
75
+ const label = t3;
62
76
  let t4;
63
- if ($[5] !== T0 || $[6] !== props || $[7] !== t3) {
64
- t4 = /* @__PURE__ */ jsx(T0, {
77
+ if ($[9] !== children || $[10] !== plain || $[11] !== size) {
78
+ t4 = plain ? children : /* @__PURE__ */ jsx(TextSizeContext, {
79
+ value: size,
80
+ children
81
+ });
82
+ $[9] = children;
83
+ $[10] = plain;
84
+ $[11] = size;
85
+ $[12] = t4;
86
+ } else t4 = $[12];
87
+ let t5;
88
+ if ($[13] !== composed || $[14] !== label || $[15] !== props || $[16] !== t4) {
89
+ t5 = /* @__PURE__ */ jsx(Text, {
65
90
  ...props,
66
- style: t3
91
+ accessibilityLabel: label,
92
+ style: composed,
93
+ children: t4
67
94
  });
68
- $[5] = T0;
69
- $[6] = props;
70
- $[7] = t3;
71
- $[8] = t4;
72
- } else t4 = $[8];
73
- return t4;
95
+ $[13] = composed;
96
+ $[14] = label;
97
+ $[15] = props;
98
+ $[16] = t4;
99
+ $[17] = t5;
100
+ } else t5 = $[17];
101
+ return t5;
74
102
  }
75
103
  //#endregion
76
104
  export { Text$1 as Text };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ComponentRef","Ref","TextProps","NativeTextProps","Text","NativeText","StyleSheet","TypeRole","useTheme","composeStyles","themedStyles","useTypeRole","stylesOf","colors","create","error","color","inherit","muted","onSurfaceVariant","negative","neutral","onSurface","positive","primary","ref","tone","variant","t0","$","_c","props","style","t1","t2","undefined","role","tones","T0","t3","t4","Text","_c","NativeText"],"sources":["../../../src/components/text/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { TextProps as NativeTextProps } from 'react-native'\n\nimport { Text as NativeText, StyleSheet } from 'react-native'\n\nimport type { TypeRole } from '../../typography/roles'\n\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// Tone is a separate axis from variant so the two compose freely: any of the\n// fifteen roles in any of these colours, the same set web's Text takes.\n// `inherit` sets no colour, so a Text inside another takes the outer one's.\nconst stylesOf = themedStyles(({ colors }) =>\n StyleSheet.create({\n error: { color: colors.error },\n inherit: {},\n muted: { color: colors.onSurfaceVariant },\n negative: { color: colors.negative },\n neutral: { color: colors.onSurface },\n positive: { color: colors.positive },\n primary: { color: colors.primary },\n }),\n)\n\ntype TextProps = NativeTextProps & {\n readonly ref?: Ref<ComponentRef<typeof NativeText>>\n /**\n * The colour role to draw in. `neutral` is the on-surface role, as it is on\n * web; `inherit` takes the colour of the Text around it instead of setting\n * one.\n * @default 'neutral'\n */\n readonly tone?:\n | 'error'\n | 'inherit'\n | 'muted'\n | 'negative'\n | 'neutral'\n | 'positive'\n | 'primary'\n /**\n * Which role of the type scale to draw in.\n * @default 'bodyMedium'\n */\n readonly variant?: TypeRole\n}\n\n/**\n * A run of text in one role of Material Design's type scale and one colour\n * role, with web's props and values.\n *\n * ```tsx\n * <Text accessibilityRole=\"header\" variant=\"titleLarge\">\n * Headline\n * </Text>\n * ```\n *\n * Each role reads its family, size, line height, weight and tracking from the\n * theme, so an override of the plain or brand family reaches every role drawn\n * in it. The family is the token's first when the app has registered it with\n * expo-font, and the system font otherwise. The OS text size scales every\n * role, as `allowFontScaling` leaves it.\n *\n * Web's `render` and `block` have no counterpart: a native Text is a block\n * unless it sits inside another, and a heading is an `accessibilityRole`\n * rather than an element. `style`, `ref` and `testID` land on React Native's\n * own Text.\n */\nfunction Text({\n style,\n tone = 'neutral',\n variant = 'bodyMedium',\n ...props\n}: TextProps) {\n const role = useTypeRole(variant)\n const tones = stylesOf(useTheme())\n\n return (\n <NativeText {...props} style={composeStyles(role, tones[tone], style)} />\n )\n}\n\nexport type { TextProps }\n\nexport { Text }\n"],"mappings":";;;;;;;AAcA,MAAMY,WAAWF,cAAc,EAAEG,aAC/BP,WAAWQ,OAAO;CAChBC,OAAO,EAAEC,OAAOH,OAAOE,MAAM;CAC7BE,SAAS,CAAC;CACVC,OAAO,EAAEF,OAAOH,OAAOM,iBAAiB;CACxCC,UAAU,EAAEJ,OAAOH,OAAOO,SAAS;CACnCC,SAAS,EAAEL,OAAOH,OAAOS,UAAU;CACnCC,UAAU,EAAEP,OAAOH,OAAOU,SAAS;CACnCC,SAAS,EAAER,OAAOH,OAAOW,QAAQ;AACnC,CAAC,CACH;;;;;;;;;;;;;;;;;;;;;;AA8CA,SAAApB,OAAAwB,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAD,IAAA;EAAc,CAAA,CAAAI,OAAAN,MAAAO,IAAAN,SAAAO,IAAA,GAAAH,SAAAH;EAKFC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAH,QAAAF,EAAA;EAAAG,QAAAH,EAAA;EAAAI,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAHV,MAAAH,OAAAO,OAAAE,KAAAA,IAAA,YAAAF;CAIA,MAAAG,OAAazB,YAHbuB,OAAAC,KAAAA,IAAA,eAAAD,EAGgC;CAChC,MAAAG,QAAczB,SAASJ,SAAS,CAAC;CAG9B,MAAA8B,KAAAjC;CAA6B,MAAAkC,KAAA9B,cAAc2B,MAAMC,MAAMX,OAAOM,KAAK;CAAC,IAAAQ;CAAA,IAAAX,EAAA,OAAAS,MAAAT,EAAA,OAAAE,SAAAF,EAAA,OAAAU,IAAA;EAArEC,KAAA,oBAAC,IAAD;GAAW,GAAKT;GAAc,OAAAQ;EAAuC,CAAA;EAAIV,EAAA,KAAAS;EAAAT,EAAA,KAAAE;EAAAF,EAAA,KAAAU;EAAAV,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,OAAzEW;AAAyE"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","TextProps","NativeTextProps","TextStyle","Text","NativeText","StyleSheet","TypeRole","useTheme","composeStyles","themedStyles","useTypeRole","TextSizeContext","sentenceLabel","stylesOf","colors","create","error","color","inherit","muted","onSurfaceVariant","negative","neutral","onSurface","positive","primary","ref","tone","variant","t0","$","_c","children","props","style","t1","t2","undefined","role","tones","composed","size","flatten","fontSize","plain","t3","accessibilityLabel","label","t4","t5","Text","_c","NativeText"],"sources":["../../../src/components/text/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { TextProps as NativeTextProps, TextStyle } from 'react-native'\n\nimport { Text as NativeText, StyleSheet } from 'react-native'\n\nimport type { TypeRole } from '../../typography/roles'\n\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\nimport { TextSizeContext } from '../../typography/size'\nimport { sentenceLabel } from '../keycap'\n\n// Tone is a separate axis from variant so the two compose freely: any of the\n// fifteen roles in any of these colours, the same set web's Text takes.\n// `inherit` sets no colour, so a Text inside another takes the outer one's.\nconst stylesOf = themedStyles(({ colors }) =>\n StyleSheet.create({\n error: { color: colors.error },\n inherit: {},\n muted: { color: colors.onSurfaceVariant },\n negative: { color: colors.negative },\n neutral: { color: colors.onSurface },\n positive: { color: colors.positive },\n primary: { color: colors.primary },\n }),\n)\n\ntype TextProps = NativeTextProps & {\n readonly ref?: Ref<ComponentRef<typeof NativeText>>\n /**\n * The colour role to draw in. `neutral` is the on-surface role, as it is on\n * web; `inherit` takes the colour of the Text around it instead of setting\n * one.\n * @default 'neutral'\n */\n readonly tone?:\n | 'error'\n | 'inherit'\n | 'muted'\n | 'negative'\n | 'neutral'\n | 'positive'\n | 'primary'\n /**\n * Which role of the type scale to draw in.\n * @default 'bodyMedium'\n */\n readonly variant?: TypeRole\n}\n\n/**\n * A run of text in one role of Material Design's type scale and one colour\n * role, with web's props and values.\n *\n * ```tsx\n * <Text accessibilityRole=\"header\" variant=\"titleLarge\">\n * Headline\n * </Text>\n * ```\n *\n * Each role reads its family, size, line height, weight and tracking from the\n * theme, so an override of the plain or brand family reaches every role drawn\n * in it. The family is the token's first when the app has registered it with\n * expo-font, and the system font otherwise. The OS text size scales every\n * role, as `allowFontScaling` leaves it.\n *\n * Web's `render` and `block` have no counterpart: a native Text is a block\n * unless it sits inside another, and a heading is an `accessibilityRole`\n * rather than an element. `style`, `ref` and `testID` land on React Native's\n * own Text.\n */\nfunction Text({\n children,\n style,\n tone = 'neutral',\n variant = 'bodyMedium',\n ...props\n}: TextProps) {\n const role = useTypeRole(variant)\n const tones = stylesOf(useTheme())\n const composed = composeStyles<TextStyle>(role, tones[tone], style)\n // The size the text ends up at, the call site's over the role's, which a\n // Code or a Keycap inside it sets a share of. Plain text holds neither, so\n // it goes in as it is, and a host Text's children stay the string a call\n // site wrote.\n const size = StyleSheet.flatten(composed)?.fontSize\n const plain = typeof children === 'string' || typeof children === 'number'\n // A Keycap is an inline View, whose name a native screen reader leaves out\n // of the sentence, so a Text holding one says the sentence itself unless\n // the call site has labelled it.\n const label =\n props.accessibilityLabel ??\n (props['aria-label'] === undefined ? sentenceLabel(children) : undefined)\n\n return (\n <NativeText {...props} accessibilityLabel={label} style={composed}>\n {plain ? (\n children\n ) : (\n <TextSizeContext value={size}>{children}</TextSizeContext>\n )}\n </NativeText>\n )\n}\n\nexport type { TextProps }\n\nexport { Text }\n"],"mappings":";;;;;;;;;AAgBA,MAAMe,WAAWJ,cAAc,EAAEK,aAC/BT,WAAWU,OAAO;CAChBC,OAAO,EAAEC,OAAOH,OAAOE,MAAM;CAC7BE,SAAS,CAAC;CACVC,OAAO,EAAEF,OAAOH,OAAOM,iBAAiB;CACxCC,UAAU,EAAEJ,OAAOH,OAAOO,SAAS;CACnCC,SAAS,EAAEL,OAAOH,OAAOS,UAAU;CACnCC,UAAU,EAAEP,OAAOH,OAAOU,SAAS;CACnCC,SAAS,EAAER,OAAOH,OAAOW,QAAQ;AACnC,CAAC,CACH;;;;;;;;;;;;;;;;;;;;;;AA8CA,SAAAtB,OAAA0B,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAD,IAAA;EAAc,CAAA,CAAAG,UAAAE,OAAAP,MAAAQ,IAAAP,SAAAQ,IAAA,GAAAH,SAAAJ;EAMFC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAJ,WAAAF,EAAA;EAAAG,QAAAH,EAAA;EAAAI,QAAAJ,EAAA;EAAAK,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAHV,MAAAH,OAAAQ,OAAAE,KAAAA,IAAA,YAAAF;CAIA,MAAAG,OAAa5B,YAHb0B,OAAAC,KAAAA,IAAA,eAAAD,EAGgC;CAChC,MAAAG,QAAc1B,SAASN,SAAS,CAAC;CACjC,MAAAiC,WAAiBhC,cAAyB8B,MAAMC,MAAMZ,OAAOO,KAAK;CAKlE,MAAAO,OAAapC,WAAUqC,QAASF,QAAkB,CAAC,EAAAG;CACnD,MAAAC,QAAc,OAAOZ,aAAa,YAAY,OAAOA,aAAa;CAAQ,IAAAa;CAAA,IAAAf,EAAA,OAAAE,YAAAF,EAAA,OAAAG,OAAA;EAKxEY,KAAAZ,MAAKa,uBACJb,MAAM,kBAAkBI,KAAAA,IAAYzB,cAAcoB,QAAoB,IAAtEK,KAAAA;EAAwEP,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAe;CAAA,OAAAA,KAAAf,EAAA;CAF3E,MAAAiB,QACEF;CACyE,IAAAG;CAAA,IAAAlB,EAAA,OAAAE,YAAAF,EAAA,QAAAc,SAAAd,EAAA,QAAAW,MAAA;EAItEO,KAAAJ,QAAAZ,WAGC,oBAAC,iBAAD;GAAwBS,OAAAA;GAAOT;EAAf,CAAA;EACjBF,EAAA,KAAAE;EAAAF,EAAA,MAAAc;EAAAd,EAAA,MAAAW;EAAAX,EAAA,MAAAkB;CAAA,OAAAA,KAAAlB,EAAA;CAAA,IAAAmB;CAAA,IAAAnB,EAAA,QAAAU,YAAAV,EAAA,QAAAiB,SAAAjB,EAAA,QAAAG,SAAAH,EAAA,QAAAkB,IAAA;EALHC,KAAA,oBAACG,MAAD;GAAW,GAAKnB;GAA2Bc,oBAAAA;GAAcP,OAAAA;GACtDQ,UAAAA;EADQ,CAAA;EAMElB,EAAA,MAAAU;EAAAV,EAAA,MAAAiB;EAAAjB,EAAA,MAAAG;EAAAH,EAAA,MAAAkB;EAAAlB,EAAA,MAAAmB;CAAA,OAAAA,KAAAnB,EAAA;CAAA,OANbmB;AAMa"}
@@ -0,0 +1,145 @@
1
+ import { ValidationResult } from "../../form/index.js";
2
+ import { FieldVariant } from "../../field/index.js";
3
+ import { StyleProp, TextInput, TextInputProps, View, ViewStyle } from "react-native";
4
+ import { ComponentRef, ReactNode, Ref } from "react";
5
+ //#region src/components/text-area/index.d.ts
6
+ type TextAreaProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityLabel' | 'aria-disabled' | 'aria-label' | 'children' | 'cursorColor' | 'defaultValue' | 'editable' | 'multiline' | 'numberOfLines' | 'onChange' | 'onChangeText' | 'placeholder' | 'placeholderTextColor' | 'readOnly' | 'rows' | 'selectionColor' | 'style' | 'underlineColorAndroid' | 'value'> & {
7
+ /**
8
+ * Whether the field grows with the text it holds, from `rows` up. `false`
9
+ * keeps it at `rows` and scrolls the text inside.
10
+ * @default true
11
+ */
12
+ readonly autosize?: boolean;
13
+ /**
14
+ * Counts the characters the field holds at the end of the supporting line,
15
+ * against `maxLength` where there is one, as the text fields page's
16
+ * character counter does. The count is written in the digits of the
17
+ * `I18nProvider`'s locale, or the device's outside one.
18
+ * @default false
19
+ */
20
+ readonly characterCount?: boolean;
21
+ /**
22
+ * How the limit is said to a screen reader, where there is a `maxLength`.
23
+ * Read with the field rather than as the value changes, so it names the
24
+ * limit and not what is left of it; the visible count is hidden from
25
+ * screen readers, which is what this replaces. Left out, it is the
26
+ * library's sentence in the `I18nProvider`'s locale, or the device's
27
+ * outside one, in the plural form the limit takes there: "Up to 20
28
+ * characters" in English, singular for a limit of one.
29
+ */
30
+ readonly characterLimitLabel?: string;
31
+ /** The value the field opens with, when it keeps its own. */
32
+ readonly defaultValue?: string;
33
+ /**
34
+ * A hint shown under the field. Replaced by `error` when there is one, so
35
+ * the two never stack.
36
+ */
37
+ readonly description?: string;
38
+ /**
39
+ * The problem with the current value, in words. Its presence is what puts
40
+ * the field in its error state: the message, the error colours, and the
41
+ * invalid state a screen reader reads all follow from it. The line under
42
+ * the field arrives with the message, so the field grows when this does,
43
+ * unless it is inside a `Form`, which keeps the line drawn. It wins over
44
+ * what `validate` and the form say, and holds a `native` form back.
45
+ */
46
+ readonly error?: string;
47
+ /**
48
+ * Whether the label sits in the empty box and floats to the top once the
49
+ * field is focused or holds a value, as the text fields page draws it.
50
+ * `false` keeps it small at the top in every state.
51
+ * @default true
52
+ */
53
+ readonly floatingLabel?: boolean;
54
+ /**
55
+ * A ref to the field's own `TextInput`, which is what a call site moves
56
+ * focus to, after a server's error, say. `ref` is the field as a whole.
57
+ */
58
+ readonly inputRef?: Ref<ComponentRef<typeof TextInput>>;
59
+ /**
60
+ * Draws the field disabled: it takes no focus and no input.
61
+ * @default false
62
+ */
63
+ readonly isDisabled?: boolean;
64
+ /**
65
+ * Shows the value and takes focus, but takes no input.
66
+ * @default false
67
+ */
68
+ readonly isReadOnly?: boolean;
69
+ /**
70
+ * Marks the label with an asterisk, as the text fields page marks a field
71
+ * that must be filled.
72
+ * @default false
73
+ */
74
+ readonly isRequired?: boolean;
75
+ /**
76
+ * What the field is for, and the name a screen reader reads for it.
77
+ * Required, since a text area with no label is a box nobody can name.
78
+ */
79
+ readonly label: string;
80
+ /**
81
+ * An icon at the start of the box, before the label and the text: the
82
+ * page's 24dp leading icon, in the muted role. The slot hands it that
83
+ * colour and size through `useIconStyle()`.
84
+ */
85
+ readonly leadingIcon?: ReactNode;
86
+ /**
87
+ * The name the value is submitted under by the `Form` around the field,
88
+ * and the key its `validationErrors` reach the field by.
89
+ */
90
+ readonly name?: string;
91
+ /** Called with the new value as it is edited. */
92
+ readonly onChange?: (value: string) => void;
93
+ readonly ref?: Ref<ComponentRef<typeof View>>;
94
+ /**
95
+ * How many lines of text the field shows: the least it shows while it
96
+ * grows, or all it shows when it does not.
97
+ * @default 3
98
+ */
99
+ readonly rows?: number;
100
+ /** Positions and sizes the field as a whole. */
101
+ readonly style?: StyleProp<ViewStyle>;
102
+ /**
103
+ * An icon at the end of the box, after the text: the page's 24dp trailing
104
+ * icon, in the muted role and the error role while the field has an
105
+ * error. The slot hands it that colour and size through `useIconStyle()`.
106
+ */
107
+ readonly trailingIcon?: ReactNode;
108
+ /**
109
+ * Checks the value, and returns its problem in words, or several, where
110
+ * there is one, and `true`, `null` or `undefined` where there is none.
111
+ * Under the default `aria` validation the error shows as the value
112
+ * changes; inside a `native` form it shows once a submission is tried, or
113
+ * once the field loses focus after an edit, and holds the form back.
114
+ */
115
+ readonly validate?: (value: string) => ValidationResult;
116
+ /** The value, when the call site keeps it. */
117
+ readonly value?: string;
118
+ /**
119
+ * The filled box, or the outlined one: no fill, an outline that thickens
120
+ * and takes the primary role while focused, and the label cutting it once
121
+ * it floats, the text fields page's two fields.
122
+ * @default 'filled'
123
+ */
124
+ readonly variant?: FieldVariant;
125
+ };
126
+ /**
127
+ * A labelled multi-line input, the text fields page's filled or outlined
128
+ * field holding several lines. Pass `value` with `onChange` to control it, or
129
+ * `defaultValue` to let it keep its own; `onChange` is handed the string.
130
+ *
131
+ * It shows `rows` lines at the least and grows with what it holds, or holds
132
+ * at `rows` and scrolls with `autosize={false}`. The page's configurations
133
+ * are props: `leadingIcon` and `trailingIcon` at the box's ends, and
134
+ * `characterCount` opposite the supporting text, counting against
135
+ * `maxLength`. React Native's own `TextInput` props reach the control;
136
+ * `style` and `ref` are the field as a whole, and `inputRef` the control.
137
+ *
138
+ * ```tsx
139
+ * <TextArea label="Label" description="Supporting line" />
140
+ * ```
141
+ */
142
+ declare function TextArea({ autosize, characterCount, characterLimitLabel, defaultValue, description, error, floatingLabel, inputRef, isDisabled, isReadOnly, isRequired, label, leadingIcon, name, onBlur, onChange, onFocus, ref, rows, style, trailingIcon, validate, value, variant, ...props }: TextAreaProps): import("react").JSX.Element;
143
+ //#endregion
144
+ export { TextArea, type TextAreaProps };
145
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,231 @@
1
+ import { useLocaleOf } from "../../i18n/provider.js";
2
+ import { useFieldValidation } from "../../form/index.js";
3
+ import { FieldBox, FieldInput, FieldMessage, describedBy, useFieldFocus } from "../../field/index.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { View } from "react-native";
6
+ import { useId, useImperativeHandle, useRef, useState } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/text-area/index.tsx
9
+ function blurThen(onBlur, then) {
10
+ return (event) => {
11
+ onBlur();
12
+ then?.(event);
13
+ };
14
+ }
15
+ function editInto(setOwn, onChange, onEdit) {
16
+ return (text) => {
17
+ setOwn(text);
18
+ onEdit();
19
+ onChange?.(text);
20
+ };
21
+ }
22
+ /**
23
+ * A labelled multi-line input, the text fields page's filled or outlined
24
+ * field holding several lines. Pass `value` with `onChange` to control it, or
25
+ * `defaultValue` to let it keep its own; `onChange` is handed the string.
26
+ *
27
+ * It shows `rows` lines at the least and grows with what it holds, or holds
28
+ * at `rows` and scrolls with `autosize={false}`. The page's configurations
29
+ * are props: `leadingIcon` and `trailingIcon` at the box's ends, and
30
+ * `characterCount` opposite the supporting text, counting against
31
+ * `maxLength`. React Native's own `TextInput` props reach the control;
32
+ * `style` and `ref` are the field as a whole, and `inputRef` the control.
33
+ *
34
+ * ```tsx
35
+ * <TextArea label="Label" description="Supporting line" />
36
+ * ```
37
+ */
38
+ function TextArea(t0) {
39
+ const $ = c(59);
40
+ const { autosize: t1, characterCount: t2, characterLimitLabel, defaultValue: t3, description, error, floatingLabel: t4, inputRef, isDisabled: t5, isReadOnly: t6, isRequired: t7, label, leadingIcon, name, onBlur, onChange, onFocus, ref, rows: t8, style, trailingIcon, validate, value, variant: t9, ...props } = t0;
41
+ const autosize = t1 === void 0 ? true : t1;
42
+ const characterCount = t2 === void 0 ? false : t2;
43
+ const defaultValue = t3 === void 0 ? "" : t3;
44
+ const floatingLabel = t4 === void 0 ? true : t4;
45
+ const isDisabled = t5 === void 0 ? false : t5;
46
+ const isReadOnly = t6 === void 0 ? false : t6;
47
+ const isRequired = t7 === void 0 ? false : t7;
48
+ const rows = t8 === void 0 ? 3 : t8;
49
+ const variant = t9 === void 0 ? "filled" : t9;
50
+ const id = useId();
51
+ const control = useRef(null);
52
+ const [own, setOwn] = useState(defaultValue);
53
+ const current = value ?? own;
54
+ const t10 = current === "";
55
+ let t11;
56
+ if ($[0] !== current || $[1] !== error || $[2] !== isDisabled || $[3] !== isReadOnly || $[4] !== isRequired || $[5] !== name || $[6] !== t10 || $[7] !== validate) {
57
+ t11 = {
58
+ control,
59
+ error,
60
+ isDisabled,
61
+ isEmpty: t10,
62
+ isReadOnly,
63
+ isRequired,
64
+ name,
65
+ submitted: current,
66
+ validate,
67
+ value: current
68
+ };
69
+ $[0] = current;
70
+ $[1] = error;
71
+ $[2] = isDisabled;
72
+ $[3] = isReadOnly;
73
+ $[4] = isRequired;
74
+ $[5] = name;
75
+ $[6] = t10;
76
+ $[7] = validate;
77
+ $[8] = t11;
78
+ } else t11 = $[8];
79
+ const validation = useFieldValidation(t11);
80
+ let t12;
81
+ if ($[9] !== onBlur || $[10] !== validation.onBlur) {
82
+ t12 = blurThen(validation.onBlur, onBlur);
83
+ $[9] = onBlur;
84
+ $[10] = validation.onBlur;
85
+ $[11] = t12;
86
+ } else t12 = $[11];
87
+ let t13;
88
+ if ($[12] !== onFocus || $[13] !== t12) {
89
+ t13 = {
90
+ onBlur: t12,
91
+ onFocus
92
+ };
93
+ $[12] = onFocus;
94
+ $[13] = t12;
95
+ $[14] = t13;
96
+ } else t13 = $[14];
97
+ const focus = useFieldFocus(t13);
98
+ const shownError = validation.error;
99
+ const locale = useLocaleOf(void 0);
100
+ let t14;
101
+ let t15;
102
+ if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
103
+ t14 = () => control.current;
104
+ t15 = [];
105
+ $[15] = t14;
106
+ $[16] = t15;
107
+ } else {
108
+ t14 = $[15];
109
+ t15 = $[16];
110
+ }
111
+ useImperativeHandle(inputRef, t14, t15);
112
+ const T0 = View;
113
+ const T1 = FieldBox;
114
+ const t16 = focus.focused;
115
+ const t17 = shownError !== void 0;
116
+ const t18 = current !== "";
117
+ const T2 = FieldInput;
118
+ const t19 = focus.handlers;
119
+ const t20 = describedBy(id, {
120
+ characterLimitLabel,
121
+ description,
122
+ error: shownError,
123
+ locale,
124
+ maxLength: props.maxLength
125
+ });
126
+ const t21 = !isDisabled && !isReadOnly;
127
+ let t22;
128
+ if ($[17] !== onChange || $[18] !== setOwn || $[19] !== validation.onEdit) {
129
+ t22 = editInto(setOwn, onChange, validation.onEdit);
130
+ $[17] = onChange;
131
+ $[18] = setOwn;
132
+ $[19] = validation.onEdit;
133
+ $[20] = t22;
134
+ } else t22 = $[20];
135
+ let t23;
136
+ if ($[21] !== T2 || $[22] !== autosize || $[23] !== current || $[24] !== focus.handlers || $[25] !== label || $[26] !== props || $[27] !== rows || $[28] !== t20 || $[29] !== t21 || $[30] !== t22) {
137
+ t23 = /* @__PURE__ */ jsx(T2, {
138
+ ...props,
139
+ ...t19,
140
+ "aria-label": label,
141
+ autosize,
142
+ described: t20,
143
+ editable: t21,
144
+ multiline: true,
145
+ onChangeText: t22,
146
+ ref: control,
147
+ rows,
148
+ value: current
149
+ });
150
+ $[21] = T2;
151
+ $[22] = autosize;
152
+ $[23] = current;
153
+ $[24] = focus.handlers;
154
+ $[25] = label;
155
+ $[26] = props;
156
+ $[27] = rows;
157
+ $[28] = t20;
158
+ $[29] = t21;
159
+ $[30] = t22;
160
+ $[31] = t23;
161
+ } else t23 = $[31];
162
+ let t24;
163
+ if ($[32] !== T1 || $[33] !== floatingLabel || $[34] !== focus.focused || $[35] !== isDisabled || $[36] !== isRequired || $[37] !== label || $[38] !== leadingIcon || $[39] !== t17 || $[40] !== t18 || $[41] !== t23 || $[42] !== trailingIcon || $[43] !== variant) {
164
+ t24 = /* @__PURE__ */ jsx(T1, {
165
+ control,
166
+ floatingLabel,
167
+ isDisabled,
168
+ isFocused: t16,
169
+ isInvalid: t17,
170
+ isPopulated: t18,
171
+ isRequired,
172
+ label,
173
+ leading: leadingIcon,
174
+ trailing: trailingIcon,
175
+ variant,
176
+ children: t23
177
+ });
178
+ $[32] = T1;
179
+ $[33] = floatingLabel;
180
+ $[34] = focus.focused;
181
+ $[35] = isDisabled;
182
+ $[36] = isRequired;
183
+ $[37] = label;
184
+ $[38] = leadingIcon;
185
+ $[39] = t17;
186
+ $[40] = t18;
187
+ $[41] = t23;
188
+ $[42] = trailingIcon;
189
+ $[43] = variant;
190
+ $[44] = t24;
191
+ } else t24 = $[44];
192
+ let t25;
193
+ if ($[45] !== characterCount || $[46] !== characterLimitLabel || $[47] !== current.length || $[48] !== description || $[49] !== id || $[50] !== props.maxLength || $[51] !== shownError) {
194
+ t25 = /* @__PURE__ */ jsx(FieldMessage, {
195
+ characterCount,
196
+ characterLimitLabel,
197
+ description,
198
+ error: shownError,
199
+ id,
200
+ length: current.length,
201
+ maxLength: props.maxLength
202
+ });
203
+ $[45] = characterCount;
204
+ $[46] = characterLimitLabel;
205
+ $[47] = current.length;
206
+ $[48] = description;
207
+ $[49] = id;
208
+ $[50] = props.maxLength;
209
+ $[51] = shownError;
210
+ $[52] = t25;
211
+ } else t25 = $[52];
212
+ let t26;
213
+ if ($[53] !== T0 || $[54] !== ref || $[55] !== style || $[56] !== t24 || $[57] !== t25) {
214
+ t26 = /* @__PURE__ */ jsxs(T0, {
215
+ ref,
216
+ style,
217
+ children: [t24, t25]
218
+ });
219
+ $[53] = T0;
220
+ $[54] = ref;
221
+ $[55] = style;
222
+ $[56] = t24;
223
+ $[57] = t25;
224
+ $[58] = t26;
225
+ } else t26 = $[58];
226
+ return t26;
227
+ }
228
+ //#endregion
229
+ export { TextArea };
230
+
231
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","StyleProp","TextInput","TextInputProps","ViewStyle","useId","useImperativeHandle","useRef","useState","View","FieldVariant","ValidationResult","describedBy","FieldBox","FieldInput","FieldMessage","useFieldFocus","useFieldValidation","useLocaleOf","TextAreaProps","Omit","autosize","characterCount","characterLimitLabel","defaultValue","description","error","floatingLabel","inputRef","isDisabled","isReadOnly","isRequired","label","leadingIcon","name","onChange","value","ref","rows","style","trailingIcon","validate","variant","blurThen","onBlur","then","event","editInto","setOwn","onEdit","text","TextArea","t0","$","_c","t1","t2","t3","t4","t5","t6","t7","onFocus","t8","t9","props","undefined","id","control","own","current","t10","t11","isEmpty","submitted","validation","t12","t13","focus","shownError","locale","t14","t15","Symbol","for","T0","T1","t16","focused","t17","t18","T2","t19","handlers","t20","maxLength","t21","t22","t23","t24","t25","length","t26","_c"],"sources":["../../../src/components/text-area/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n StyleProp,\n TextInput,\n TextInputProps,\n ViewStyle,\n} from 'react-native'\n\nimport { useId, useImperativeHandle, useRef, useState } from 'react'\nimport { View } from 'react-native'\n\nimport type { FieldVariant } from '../../field'\nimport type { ValidationResult } from '../../form'\n\nimport {\n describedBy,\n FieldBox,\n FieldInput,\n FieldMessage,\n useFieldFocus,\n} from '../../field'\nimport { useFieldValidation } from '../../form'\nimport { useLocaleOf } from '../../i18n/provider'\n\n// kanso-ui's TextArea, the text fields page's multi-line configuration of the\n// field: the same box, floating label, icons, rule and supporting line as\n// TextField, drawn through the field chrome in src/field, around a control\n// that holds several lines. The page gives the box 56dp at the least, with\n// 8dp above and below the text and the label resting on its first line; a box\n// holding more grows a line at a time, which the chrome's height floor\n// already does, and its icons stay centred in its height, as web's do. The\n// page draws no resize handle, and React Native draws none.\n//\n// Its own component rather than a prop of TextField, as on web, so `rows` and\n// `autosize` stay off TextField's type and `numeric`, `prefix` and `suffix`\n// off this one.\n//\n// The value is the field's own or the call site's, as TextField's is, and\n// `onChange` is handed the string. The error shown is `error`, or what the\n// field's `validate` and the `Form` around it say, which src/form decides.\n\ntype TextAreaProps = Omit<\n TextInputProps,\n | 'accessibilityHint'\n | 'accessibilityLabel'\n | 'aria-disabled'\n | 'aria-label'\n | 'children'\n | 'cursorColor'\n | 'defaultValue'\n | 'editable'\n | 'multiline'\n | 'numberOfLines'\n | 'onChange'\n | 'onChangeText'\n | 'placeholder'\n | 'placeholderTextColor'\n | 'readOnly'\n | 'rows'\n | 'selectionColor'\n | 'style'\n | 'underlineColorAndroid'\n | 'value'\n> & {\n /**\n * Whether the field grows with the text it holds, from `rows` up. `false`\n * keeps it at `rows` and scrolls the text inside.\n * @default true\n */\n readonly autosize?: boolean\n /**\n * Counts the characters the field holds at the end of the supporting line,\n * against `maxLength` where there is one, as the text fields page's\n * character counter does. The count is written in the digits of the\n * `I18nProvider`'s locale, or the device's outside one.\n * @default false\n */\n readonly characterCount?: boolean\n /**\n * How the limit is said to a screen reader, where there is a `maxLength`.\n * Read with the field rather than as the value changes, so it names the\n * limit and not what is left of it; the visible count is hidden from\n * screen readers, which is what this replaces. Left out, it is the\n * library's sentence in the `I18nProvider`'s locale, or the device's\n * outside one, in the plural form the limit takes there: \"Up to 20\n * characters\" in English, singular for a limit of one.\n */\n readonly characterLimitLabel?: string\n /** The value the field opens with, when it keeps its own. */\n readonly defaultValue?: string\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state: the message, the error colours, and the\n * invalid state a screen reader reads all follow from it. The line under\n * the field arrives with the message, so the field grows when this does,\n * unless it is inside a `Form`, which keeps the line drawn. It wins over\n * what `validate` and the form say, and holds a `native` form back.\n */\n readonly error?: string\n /**\n * Whether the label sits in the empty box and floats to the top once the\n * field is focused or holds a value, as the text fields page draws it.\n * `false` keeps it small at the top in every state.\n * @default true\n */\n readonly floatingLabel?: boolean\n /**\n * A ref to the field's own `TextInput`, which is what a call site moves\n * focus to, after a server's error, say. `ref` is the field as a whole.\n */\n readonly inputRef?: Ref<ComponentRef<typeof TextInput>>\n /**\n * Draws the field disabled: it takes no focus and no input.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the value and takes focus, but takes no input.\n * @default false\n */\n readonly isReadOnly?: boolean\n /**\n * Marks the label with an asterisk, as the text fields page marks a field\n * that must be filled.\n * @default false\n */\n readonly isRequired?: boolean\n /**\n * What the field is for, and the name a screen reader reads for it.\n * Required, since a text area with no label is a box nobody can name.\n */\n readonly label: string\n /**\n * An icon at the start of the box, before the label and the text: the\n * page's 24dp leading icon, in the muted role. The slot hands it that\n * colour and size through `useIconStyle()`.\n */\n readonly leadingIcon?: ReactNode\n /**\n * The name the value is submitted under by the `Form` around the field,\n * and the key its `validationErrors` reach the field by.\n */\n readonly name?: string\n /** Called with the new value as it is edited. */\n readonly onChange?: (value: string) => void\n readonly ref?: Ref<ComponentRef<typeof View>>\n /**\n * How many lines of text the field shows: the least it shows while it\n * grows, or all it shows when it does not.\n * @default 3\n */\n readonly rows?: number\n /** Positions and sizes the field as a whole. */\n readonly style?: StyleProp<ViewStyle>\n /**\n * An icon at the end of the box, after the text: the page's 24dp trailing\n * icon, in the muted role and the error role while the field has an\n * error. The slot hands it that colour and size through `useIconStyle()`.\n */\n readonly trailingIcon?: ReactNode\n /**\n * Checks the value, and returns its problem in words, or several, where\n * there is one, and `true`, `null` or `undefined` where there is none.\n * Under the default `aria` validation the error shows as the value\n * changes; inside a `native` form it shows once a submission is tried, or\n * once the field loses focus after an edit, and holds the form back.\n */\n readonly validate?: (value: string) => ValidationResult\n /** The value, when the call site keeps it. */\n readonly value?: string\n /**\n * The filled box, or the outlined one: no fill, an outline that thickens\n * and takes the primary role while focused, and the label cutting it once\n * it floats, the text fields page's two fields.\n * @default 'filled'\n */\n readonly variant?: FieldVariant\n}\n\n// The field's own blur handling, then the call site's.\nfunction blurThen(\n onBlur: () => void,\n then: TextInputProps['onBlur'],\n): TextInputProps['onBlur'] {\n return (event) => {\n onBlur()\n then?.(event)\n }\n}\n\n// Keeps an edit as the field's own value and reports it, so a field the call\n// site controls is told and one it does not still shows what was typed, and\n// tells the field's validation it was edited.\nfunction editInto(\n setOwn: (value: string) => void,\n onChange: ((value: string) => void) | undefined,\n onEdit: () => void,\n) {\n return (text: string) => {\n setOwn(text)\n onEdit()\n onChange?.(text)\n }\n}\n\n/**\n * A labelled multi-line input, the text fields page's filled or outlined\n * field holding several lines. Pass `value` with `onChange` to control it, or\n * `defaultValue` to let it keep its own; `onChange` is handed the string.\n *\n * It shows `rows` lines at the least and grows with what it holds, or holds\n * at `rows` and scrolls with `autosize={false}`. The page's configurations\n * are props: `leadingIcon` and `trailingIcon` at the box's ends, and\n * `characterCount` opposite the supporting text, counting against\n * `maxLength`. React Native's own `TextInput` props reach the control;\n * `style` and `ref` are the field as a whole, and `inputRef` the control.\n *\n * ```tsx\n * <TextArea label=\"Label\" description=\"Supporting line\" />\n * ```\n */\nfunction TextArea({\n autosize = true,\n characterCount = false,\n characterLimitLabel,\n defaultValue = '',\n description,\n error,\n floatingLabel = true,\n inputRef,\n isDisabled = false,\n isReadOnly = false,\n isRequired = false,\n label,\n leadingIcon,\n name,\n onBlur,\n onChange,\n onFocus,\n ref,\n rows = 3,\n style,\n trailingIcon,\n validate,\n value,\n variant = 'filled',\n ...props\n}: TextAreaProps) {\n const id = useId()\n const control = useRef<ComponentRef<typeof TextInput>>(null)\n const [own, setOwn] = useState(defaultValue)\n const current = value ?? own\n const validation = useFieldValidation({\n control,\n error,\n isDisabled,\n isEmpty: current === '',\n isReadOnly,\n isRequired,\n name,\n submitted: current,\n validate,\n value: current,\n })\n const focus = useFieldFocus({\n onBlur: blurThen(validation.onBlur, onBlur),\n onFocus,\n })\n const shownError = validation.error\n const locale = useLocaleOf(undefined)\n\n useImperativeHandle<\n ComponentRef<typeof TextInput> | null,\n ComponentRef<typeof TextInput> | null\n >(inputRef, () => control.current, [])\n\n return (\n <View ref={ref} style={style}>\n <FieldBox\n control={control}\n floatingLabel={floatingLabel}\n isDisabled={isDisabled}\n isFocused={focus.focused}\n isInvalid={shownError !== undefined}\n isPopulated={current !== ''}\n isRequired={isRequired}\n label={label}\n leading={leadingIcon}\n trailing={trailingIcon}\n variant={variant}\n >\n <FieldInput\n {...props}\n {...focus.handlers}\n aria-label={label}\n autosize={autosize}\n described={describedBy(id, {\n characterLimitLabel,\n description,\n error: shownError,\n locale,\n maxLength: props.maxLength,\n })}\n editable={!isDisabled && !isReadOnly}\n multiline\n onChangeText={editInto(setOwn, onChange, validation.onEdit)}\n ref={control}\n rows={rows}\n value={current}\n />\n </FieldBox>\n <FieldMessage\n characterCount={characterCount}\n characterLimitLabel={characterLimitLabel}\n description={description}\n error={shownError}\n id={id}\n length={current.length}\n maxLength={props.maxLength}\n />\n </View>\n )\n}\n\nexport { TextArea }\nexport type { TextAreaProps }\n"],"mappings":"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"}
@@ -7,7 +7,8 @@ type TextFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityL
7
7
  /**
8
8
  * Counts the characters the field holds at the end of the supporting line,
9
9
  * against `maxLength` where there is one, as the text fields page's
10
- * character counter does. The count is written in the device's digits.
10
+ * character counter does. The count is written in the digits of the
11
+ * `I18nProvider`'s locale, or the device's outside one.
11
12
  * @default false
12
13
  */
13
14
  readonly characterCount?: boolean;
@@ -15,8 +16,10 @@ type TextFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityL
15
16
  * How the limit is said to a screen reader, where there is a `maxLength`.
16
17
  * Read with the field rather than as the value changes, so it names the
17
18
  * limit and not what is left of it; the visible count is hidden from
18
- * screen readers, which is what this replaces. Left out, it is the English
19
- * sentence, "Up to 20 characters", singular for a limit of one.
19
+ * screen readers, which is what this replaces. Left out, it is the
20
+ * library's sentence in the `I18nProvider`'s locale, or the device's
21
+ * outside one, in the plural form the limit takes there: "Up to 20
22
+ * characters" in English, singular for a limit of one.
20
23
  */
21
24
  readonly characterLimitLabel?: string;
22
25
  /** The value the field opens with, when it keeps its own. */
@@ -1,3 +1,4 @@
1
+ import { useLocaleOf } from "../../i18n/provider.js";
1
2
  import { useFieldValidation } from "../../form/index.js";
2
3
  import { FieldBox, FieldInput, FieldMessage, describedBy, useFieldFocus } from "../../field/index.js";
3
4
  import { c } from "react/compiler-runtime";
@@ -94,6 +95,7 @@ function TextField(t0) {
94
95
  } else t12 = $[14];
95
96
  const focus = useFieldFocus(t12);
96
97
  const shownError = validation.error;
98
+ const locale = useLocaleOf(void 0);
97
99
  let t13;
98
100
  let t14;
99
101
  if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
@@ -117,6 +119,7 @@ function TextField(t0) {
117
119
  characterLimitLabel,
118
120
  description,
119
121
  error: shownError,
122
+ locale,
120
123
  maxLength: props.maxLength
121
124
  });
122
125
  const t20 = !isDisabled && !isReadOnly;