@kanso-labs/react-native-kanso-ui 0.8.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 (78) hide show
  1. package/dist/badge/index.js +9 -70
  2. package/dist/badge/index.js.map +1 -1
  3. package/dist/button/index.js +1 -1
  4. package/dist/button/palettes.d.ts +2 -0
  5. package/dist/components/badge/index.d.ts +48 -0
  6. package/dist/components/badge/index.js +122 -0
  7. package/dist/components/badge/index.js.map +1 -0
  8. package/dist/{badge → components/badge}/styles.js +10 -6
  9. package/dist/components/badge/styles.js.map +1 -0
  10. package/dist/components/breadcrumbs/index.d.ts +66 -0
  11. package/dist/components/breadcrumbs/index.js +285 -0
  12. package/dist/components/breadcrumbs/index.js.map +1 -0
  13. package/dist/components/checkbox/index.d.ts +7 -1
  14. package/dist/components/checkbox/index.js +183 -138
  15. package/dist/components/checkbox/index.js.map +1 -1
  16. package/dist/components/checkbox-group/index.d.ts +93 -0
  17. package/dist/components/checkbox-group/index.js +306 -0
  18. package/dist/components/checkbox-group/index.js.map +1 -0
  19. package/dist/components/code/index.d.ts +25 -0
  20. package/dist/components/code/index.js +87 -0
  21. package/dist/components/code/index.js.map +1 -0
  22. package/dist/components/container/index.d.ts +47 -0
  23. package/dist/components/container/index.js +85 -0
  24. package/dist/components/container/index.js.map +1 -0
  25. package/dist/components/fab/index.d.ts +80 -0
  26. package/dist/components/fab/index.js +231 -0
  27. package/dist/components/fab/index.js.map +1 -0
  28. package/dist/components/fab-menu/index.d.ts +120 -0
  29. package/dist/components/fab-menu/index.js +640 -0
  30. package/dist/components/fab-menu/index.js.map +1 -0
  31. package/dist/components/feed/index.d.ts +57 -0
  32. package/dist/components/feed/index.js +167 -0
  33. package/dist/components/feed/index.js.map +1 -0
  34. package/dist/components/keycap/index.d.ts +27 -0
  35. package/dist/components/keycap/index.js +136 -0
  36. package/dist/components/keycap/index.js.map +1 -0
  37. package/dist/components/menu/index.js +1 -1
  38. package/dist/components/separator/index.d.ts +3 -2
  39. package/dist/components/separator/index.js +29 -26
  40. package/dist/components/separator/index.js.map +1 -1
  41. package/dist/components/supporting-pane/index.d.ts +44 -0
  42. package/dist/components/supporting-pane/index.js +109 -0
  43. package/dist/components/supporting-pane/index.js.map +1 -0
  44. package/dist/components/text/index.d.ts +1 -1
  45. package/dist/components/text/index.js +49 -21
  46. package/dist/components/text/index.js.map +1 -1
  47. package/dist/components/text-area/index.d.ts +145 -0
  48. package/dist/components/text-area/index.js +231 -0
  49. package/dist/components/text-area/index.js.map +1 -0
  50. package/dist/components/toolbar/index.d.ts +53 -0
  51. package/dist/components/toolbar/index.js +185 -0
  52. package/dist/components/toolbar/index.js.map +1 -0
  53. package/dist/control/group.js +23 -0
  54. package/dist/control/group.js.map +1 -0
  55. package/dist/fab/index.d.ts +19 -0
  56. package/dist/fab/index.js +147 -0
  57. package/dist/fab/index.js.map +1 -0
  58. package/dist/field/index.js +84 -43
  59. package/dist/field/index.js.map +1 -1
  60. package/dist/field/styles.js +18 -0
  61. package/dist/field/styles.js.map +1 -1
  62. package/dist/form/index.d.ts +1 -2
  63. package/dist/form/index.js +1 -1
  64. package/dist/form/index.js.map +1 -1
  65. package/dist/index.d.ts +17 -4
  66. package/dist/index.js +15 -3
  67. package/dist/modal/index.js +59 -46
  68. package/dist/modal/index.js.map +1 -1
  69. package/dist/navigation/index.js +8 -5
  70. package/dist/navigation/index.js.map +1 -1
  71. package/dist/overlay/placement.js +3 -1
  72. package/dist/overlay/placement.js.map +1 -1
  73. package/dist/separator/index.js +7 -0
  74. package/dist/separator/index.js.map +1 -0
  75. package/dist/typography/size.js +14 -0
  76. package/dist/typography/size.js.map +1 -0
  77. package/package.json +1 -1
  78. package/dist/badge/styles.js.map +0 -1
@@ -0,0 +1,147 @@
1
+ import { themedStyles } from "../theme/styles.js";
2
+ import { palettesOf } from "../button/palettes.js";
3
+ import { StyleSheet } from "react-native";
4
+ //#region src/fab/index.ts
5
+ const MEDIUM_SIZE = 80;
6
+ const MEDIUM_CORNER = 20;
7
+ /** The icon each size draws, from the pages' size token sets. */
8
+ const FAB_ICON_SIZES = {
9
+ lg: 28,
10
+ md: 24,
11
+ xl: 36
12
+ };
13
+ /** The type role the extended form sets its label in at each size. */
14
+ const EXTENDED_FAB_ROLES = {
15
+ lg: "titleLarge",
16
+ md: "titleMedium",
17
+ xl: "headlineSmall"
18
+ };
19
+ /**
20
+ * Each size's corner, apart from its size so the press feedback can clip to
21
+ * the same one.
22
+ */
23
+ const fabCornersOf = themedStyles(({ radii }) => StyleSheet.create({
24
+ lg: { borderRadius: MEDIUM_CORNER },
25
+ md: { borderRadius: radii.lg },
26
+ xl: { borderRadius: radii.xl }
27
+ }));
28
+ /** The FAB on its own: a square of the size's edge. */
29
+ const fabSizesOf = themedStyles(({ sizing }) => StyleSheet.create({
30
+ lg: {
31
+ height: MEDIUM_SIZE,
32
+ width: MEDIUM_SIZE
33
+ },
34
+ md: {
35
+ height: sizing.controlLg,
36
+ width: sizing.controlLg
37
+ },
38
+ xl: {
39
+ height: sizing.controlXl,
40
+ width: sizing.controlXl
41
+ }
42
+ }));
43
+ /**
44
+ * The extended form: the size's height, with its padding at either end and
45
+ * the gap before the label. The 26dp and 28dp paddings fall between steps of
46
+ * the spacing scale and are written out, as on web.
47
+ *
48
+ * The height is a floor rather than a fixed size, so a label the device's
49
+ * text size enlarges grows the button rather than spilling out of it, which
50
+ * web's fixed height has no need to allow for.
51
+ */
52
+ const extendedFabSizesOf = themedStyles(({ sizing, spacing }) => StyleSheet.create({
53
+ lg: {
54
+ columnGap: spacing.md,
55
+ minHeight: MEDIUM_SIZE,
56
+ paddingHorizontal: 26
57
+ },
58
+ md: {
59
+ columnGap: spacing.sm,
60
+ minHeight: sizing.controlLg,
61
+ paddingHorizontal: spacing.lg
62
+ },
63
+ xl: {
64
+ columnGap: spacing.lg,
65
+ minHeight: sizing.controlXl,
66
+ paddingHorizontal: 28
67
+ }
68
+ }));
69
+ /**
70
+ * The six colour pairs, by variant and tone: each tone's container pair, and
71
+ * the tone itself. Plain colours, for FabMenu's FAB, which eases from one
72
+ * pair to another as its menu opens.
73
+ */
74
+ const fabColorsOf = themedStyles(({ colors }) => ({
75
+ filled: {
76
+ primary: {
77
+ container: colors.primary,
78
+ content: colors.onPrimary
79
+ },
80
+ secondary: {
81
+ container: colors.secondary,
82
+ content: colors.onSecondary
83
+ },
84
+ tertiary: {
85
+ container: colors.tertiary,
86
+ content: colors.onTertiary
87
+ }
88
+ },
89
+ tonal: {
90
+ primary: {
91
+ container: colors.primaryContainer,
92
+ content: colors.onPrimaryContainer
93
+ },
94
+ secondary: {
95
+ container: colors.secondaryContainer,
96
+ content: colors.onSecondaryContainer
97
+ },
98
+ tertiary: {
99
+ container: colors.tertiaryContainer,
100
+ content: colors.onTertiaryContainer
101
+ }
102
+ }
103
+ }));
104
+ /**
105
+ * The six colour pairs as the palettes a button draws, and the one disabled
106
+ * container every button shares: on-surface at the two disabled opacities,
107
+ * as src/button/palettes.ts draws it.
108
+ */
109
+ const fabPalettesOf = themedStyles((theme) => {
110
+ const pairs = fabColorsOf(theme);
111
+ return {
112
+ disabled: palettesOf(theme).filledDisabled,
113
+ filled: palettesFor(pairs.filled),
114
+ tonal: palettesFor(pairs.tonal)
115
+ };
116
+ });
117
+ const fabShadowsOf = themedStyles(({ shadows }) => StyleSheet.create({
118
+ elevation3: { boxShadow: shadows.elevation3 },
119
+ elevation4: { boxShadow: shadows.elevation4 }
120
+ }));
121
+ /**
122
+ * The shadow a FAB draws in its state: level 3 at rest and while pressed,
123
+ * level 4 under a hovering pointer, and none while disabled, since a shadow
124
+ * says a control is there to press.
125
+ */
126
+ function fabShadowOf({ hovered, pressed }, isDisabled, theme) {
127
+ if (isDisabled) return;
128
+ return fabShadowsOf(theme)[hovered && !pressed ? "elevation4" : "elevation3"];
129
+ }
130
+ function palette({ container, content }) {
131
+ return {
132
+ container: { backgroundColor: container },
133
+ content,
134
+ label: { color: content }
135
+ };
136
+ }
137
+ function palettesFor(pairs) {
138
+ return {
139
+ primary: palette(pairs.primary),
140
+ secondary: palette(pairs.secondary),
141
+ tertiary: palette(pairs.tertiary)
142
+ };
143
+ }
144
+ //#endregion
145
+ export { EXTENDED_FAB_ROLES, FAB_ICON_SIZES, extendedFabSizesOf, fabColorsOf, fabCornersOf, fabPalettesOf, fabShadowOf, fabSizesOf };
146
+
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ViewStyle","StyleSheet","Palette","ResolvedTheme","TypeRole","palettesOf","themedStyles","FabSize","FabTone","FabVariant","MEDIUM_SIZE","MEDIUM_CORNER","FAB_ICON_SIZES","Readonly","Record","lg","md","xl","EXTENDED_FAB_ROLES","fabCornersOf","radii","create","borderRadius","fabSizesOf","sizing","height","width","controlLg","controlXl","extendedFabSizesOf","spacing","columnGap","minHeight","paddingHorizontal","sm","FabColors","container","content","fabColorsOf","colors","filled","primary","onPrimary","secondary","onSecondary","tertiary","onTertiary","tonal","primaryContainer","onPrimaryContainer","secondaryContainer","onSecondaryContainer","tertiaryContainer","onTertiaryContainer","fabPalettesOf","theme","disabled","pairs","filledDisabled","palettesFor","fabShadowsOf","shadows","elevation3","boxShadow","elevation4","fabShadowOf","hovered","pressed","isDisabled","undefined","palette","backgroundColor","label","color"],"sources":["../../src/fab/index.ts"],"sourcesContent":["import type { ViewStyle } from 'react-native'\n\nimport { StyleSheet } from 'react-native'\n\nimport type { Palette } from '../button/palettes'\nimport type { ResolvedTheme } from '../theme/scope'\nimport type { TypeRole } from '../typography/roles'\n\nimport { palettesOf } from '../button/palettes'\nimport { themedStyles } from '../theme/styles'\n\n// The FAB's metrics and colours, shared by Fab and by the FAB that opens\n// FabMenu, which is the same button until its menu opens, as web's\n// src/fab/styles.ts is shared. Apart from either component, and outside\n// `src/components`, which holds the public components alone. Fab's header\n// gives the values and where they come from.\n\n/**\n * The pages' three sizes: `md` the FAB at 56dp, `lg` the medium FAB at 80dp\n * and `xl` the large FAB at 96dp.\n */\ntype FabSize = 'lg' | 'md' | 'xl'\n\n/** The colour role a FAB is drawn in. */\ntype FabTone = 'primary' | 'secondary' | 'tertiary'\n\n/**\n * `tonal` draws the tone's container pair, the pages' default; `filled`\n * draws the tone itself.\n */\ntype FabVariant = 'filled' | 'tonal'\n\n// The medium FAB's container and corner, between the steps of the control\n// and radius scales, so written out as web writes them.\nconst MEDIUM_SIZE = 80\nconst MEDIUM_CORNER = 20\n\n/** The icon each size draws, from the pages' size token sets. */\nconst FAB_ICON_SIZES: Readonly<Record<FabSize, number>> = {\n lg: 28,\n md: 24,\n xl: 36,\n}\n\n/** The type role the extended form sets its label in at each size. */\nconst EXTENDED_FAB_ROLES: Readonly<Record<FabSize, TypeRole>> = {\n lg: 'titleLarge',\n md: 'titleMedium',\n xl: 'headlineSmall',\n}\n\n/**\n * Each size's corner, apart from its size so the press feedback can clip to\n * the same one.\n */\nconst fabCornersOf = themedStyles(({ radii }) =>\n StyleSheet.create({\n lg: { borderRadius: MEDIUM_CORNER },\n md: { borderRadius: radii.lg },\n xl: { borderRadius: radii.xl },\n }),\n)\n\n/** The FAB on its own: a square of the size's edge. */\nconst fabSizesOf = themedStyles(({ sizing }) =>\n StyleSheet.create({\n lg: { height: MEDIUM_SIZE, width: MEDIUM_SIZE },\n md: { height: sizing.controlLg, width: sizing.controlLg },\n xl: { height: sizing.controlXl, width: sizing.controlXl },\n }),\n)\n\n/**\n * The extended form: the size's height, with its padding at either end and\n * the gap before the label. The 26dp and 28dp paddings fall between steps of\n * the spacing scale and are written out, as on web.\n *\n * The height is a floor rather than a fixed size, so a label the device's\n * text size enlarges grows the button rather than spilling out of it, which\n * web's fixed height has no need to allow for.\n */\nconst extendedFabSizesOf = themedStyles(({ sizing, spacing }) =>\n StyleSheet.create({\n lg: {\n columnGap: spacing.md,\n minHeight: MEDIUM_SIZE,\n paddingHorizontal: 26,\n },\n md: {\n columnGap: spacing.sm,\n minHeight: sizing.controlLg,\n paddingHorizontal: spacing.lg,\n },\n xl: {\n columnGap: spacing.lg,\n minHeight: sizing.controlXl,\n paddingHorizontal: 28,\n },\n }),\n)\n\n/** A FAB's container colour and the colour drawn on it. */\ntype FabColors = { readonly container: string; readonly content: string }\n\n/**\n * The six colour pairs, by variant and tone: each tone's container pair, and\n * the tone itself. Plain colours, for FabMenu's FAB, which eases from one\n * pair to another as its menu opens.\n */\nconst fabColorsOf = themedStyles(\n ({\n colors,\n }): Readonly<Record<FabVariant, Readonly<Record<FabTone, FabColors>>>> => ({\n filled: {\n primary: { container: colors.primary, content: colors.onPrimary },\n secondary: { container: colors.secondary, content: colors.onSecondary },\n tertiary: { container: colors.tertiary, content: colors.onTertiary },\n },\n tonal: {\n primary: {\n container: colors.primaryContainer,\n content: colors.onPrimaryContainer,\n },\n secondary: {\n container: colors.secondaryContainer,\n content: colors.onSecondaryContainer,\n },\n tertiary: {\n container: colors.tertiaryContainer,\n content: colors.onTertiaryContainer,\n },\n },\n }),\n)\n\n/**\n * The six colour pairs as the palettes a button draws, and the one disabled\n * container every button shares: on-surface at the two disabled opacities,\n * as src/button/palettes.ts draws it.\n */\nconst fabPalettesOf = themedStyles(\n (\n theme,\n ): {\n readonly disabled: Palette\n readonly filled: Readonly<Record<FabTone, Palette>>\n readonly tonal: Readonly<Record<FabTone, Palette>>\n } => {\n const pairs = fabColorsOf(theme)\n\n return {\n disabled: palettesOf(theme).filledDisabled,\n filled: palettesFor(pairs.filled),\n tonal: palettesFor(pairs.tonal),\n }\n },\n)\n\nconst fabShadowsOf = themedStyles(({ shadows }) =>\n StyleSheet.create({\n elevation3: { boxShadow: shadows.elevation3 },\n elevation4: { boxShadow: shadows.elevation4 },\n }),\n)\n\n/**\n * The shadow a FAB draws in its state: level 3 at rest and while pressed,\n * level 4 under a hovering pointer, and none while disabled, since a shadow\n * says a control is there to press.\n */\nfunction fabShadowOf(\n {\n hovered,\n pressed,\n }: { readonly hovered: boolean; readonly pressed: boolean },\n isDisabled: boolean,\n theme: ResolvedTheme,\n): undefined | ViewStyle {\n if (isDisabled) {\n return undefined\n }\n\n return fabShadowsOf(theme)[hovered && !pressed ? 'elevation4' : 'elevation3']\n}\n\nfunction palette({ container, content }: FabColors): Palette {\n return {\n container: { backgroundColor: container },\n content,\n label: { color: content },\n }\n}\n\nfunction palettesFor(\n pairs: Readonly<Record<FabTone, FabColors>>,\n): Readonly<Record<FabTone, Palette>> {\n return {\n primary: palette(pairs.primary),\n secondary: palette(pairs.secondary),\n tertiary: palette(pairs.tertiary),\n }\n}\n\nexport {\n EXTENDED_FAB_ROLES,\n extendedFabSizesOf,\n FAB_ICON_SIZES,\n fabColorsOf,\n fabCornersOf,\n fabPalettesOf,\n fabShadowOf,\n fabSizesOf,\n}\nexport type { FabColors, FabSize, FabTone, FabVariant }\n"],"mappings":";;;;AAkCA,MAAMU,cAAc;AACpB,MAAMC,gBAAgB;;AAGtB,MAAMC,iBAAoD;CACxDG,IAAI;CACJC,IAAI;CACJC,IAAI;AACN;;AAGA,MAAMC,qBAA0D;CAC9DH,IAAI;CACJC,IAAI;CACJC,IAAI;AACN;;;;;AAMA,MAAME,eAAeb,cAAc,EAAEc,YACnCnB,WAAWoB,OAAO;CAChBN,IAAI,EAAEO,cAAcX,cAAc;CAClCK,IAAI,EAAEM,cAAcF,MAAML,GAAG;CAC7BE,IAAI,EAAEK,cAAcF,MAAMH,GAAG;AAC/B,CAAC,CACH;;AAGA,MAAMM,aAAajB,cAAc,EAAEkB,aACjCvB,WAAWoB,OAAO;CAChBN,IAAI;EAAEU,QAAQf;EAAagB,OAAOhB;CAAY;CAC9CM,IAAI;EAAES,QAAQD,OAAOG;EAAWD,OAAOF,OAAOG;CAAU;CACxDV,IAAI;EAAEQ,QAAQD,OAAOI;EAAWF,OAAOF,OAAOI;CAAU;AAC1D,CAAC,CACH;;;;;;;;;;AAWA,MAAMC,qBAAqBvB,cAAc,EAAEkB,QAAQM,cACjD7B,WAAWoB,OAAO;CAChBN,IAAI;EACFgB,WAAWD,QAAQd;EACnBgB,WAAWtB;EACXuB,mBAAmB;CACrB;CACAjB,IAAI;EACFe,WAAWD,QAAQI;EACnBF,WAAWR,OAAOG;EAClBM,mBAAmBH,QAAQf;CAC7B;CACAE,IAAI;EACFc,WAAWD,QAAQf;EACnBiB,WAAWR,OAAOI;EAClBK,mBAAmB;CACrB;AACF,CAAC,CACH;;;;;;AAUA,MAAMK,cAAchC,cACjB,EACCiC,cACyE;CACzEC,QAAQ;EACNC,SAAS;GAAEL,WAAWG,OAAOE;GAASJ,SAASE,OAAOG;EAAU;EAChEC,WAAW;GAAEP,WAAWG,OAAOI;GAAWN,SAASE,OAAOK;EAAY;EACtEC,UAAU;GAAET,WAAWG,OAAOM;GAAUR,SAASE,OAAOO;EAAW;CACrE;CACAC,OAAO;EACLN,SAAS;GACPL,WAAWG,OAAOS;GAClBX,SAASE,OAAOU;EAClB;EACAN,WAAW;GACTP,WAAWG,OAAOW;GAClBb,SAASE,OAAOY;EAClB;EACAN,UAAU;GACRT,WAAWG,OAAOa;GAClBf,SAASE,OAAOc;EAClB;CACF;AACF,EACF;;;;;;AAOA,MAAMC,gBAAgBhD,cAElBiD,UAKG;CACH,MAAME,QAAQnB,YAAYiB,KAAK;CAE/B,OAAO;EACLC,UAAUnD,WAAWkD,KAAK,CAAC,CAACG;EAC5BlB,QAAQmB,YAAYF,MAAMjB,MAAM;EAChCO,OAAOY,YAAYF,MAAMV,KAAK;CAChC;AACF,CACF;AAEA,MAAMa,eAAetD,cAAc,EAAEuD,cACnC5D,WAAWoB,OAAO;CAChByC,YAAY,EAAEC,WAAWF,QAAQC,WAAW;CAC5CE,YAAY,EAAED,WAAWF,QAAQG,WAAW;AAC9C,CAAC,CACH;;;;;;AAOA,SAASC,YACP,EACEC,SACAC,WAEFC,YACAb,OACuB;CACvB,IAAIa,YACF;CAGF,OAAOR,aAAaL,KAAK,CAAC,CAACW,WAAW,CAACC,UAAU,eAAe;AAClE;AAEA,SAASG,QAAQ,EAAElC,WAAWC,WAA+B;CAC3D,OAAO;EACLD,WAAW,EAAEmC,iBAAiBnC,UAAU;EACxCC;EACAmC,OAAO,EAAEC,OAAOpC,QAAQ;CAC1B;AACF;AAEA,SAASsB,YACPF,OACoC;CACpC,OAAO;EACLhB,SAAS6B,QAAQb,MAAMhB,OAAO;EAC9BE,WAAW2B,QAAQb,MAAMd,SAAS;EAClCE,UAAUyB,QAAQb,MAAMZ,QAAQ;CAClC;AACF"}
@@ -321,31 +321,52 @@ function FieldBox(t0) {
321
321
  * in `described`, so a reader hears the unit the value is read against as a
322
322
  * sighted one sees it beside the value: on iOS and Android as its hint, and
323
323
  * under React Native Web through `aria-describedby`, which drops the hint.
324
+ *
325
+ * `multiline` makes it a text area, `rows` lines of body large tall at the
326
+ * least, its text from the top. iOS and Android grow a multi-line input with
327
+ * what it holds by themselves, so a height floor is all `autosize` asks of
328
+ * them, and `autosize={false}` sets the height instead, which they scroll
329
+ * inside. React Native Web's textarea keeps the height it is given, so there
330
+ * the control lies over a hidden copy of `value` that takes the height the
331
+ * text would, as web's text area lies over its replica. A control that grows
332
+ * is therefore handed its `value`.
324
333
  */
325
334
  function FieldInput(t0) {
326
- const $ = c(23);
335
+ const $ = c(26);
327
336
  let prefix;
328
337
  let props;
329
338
  let suffix;
330
339
  let t1;
331
340
  let t2;
341
+ let t3;
342
+ let t4;
343
+ let t5;
332
344
  if ($[0] !== t0) {
333
- ({described: t1, numeric: t2, prefix, suffix, ...props} = t0);
345
+ ({autosize: t1, described: t2, multiline: t3, numeric: t4, prefix, rows: t5, suffix, ...props} = t0);
334
346
  $[0] = t0;
335
347
  $[1] = prefix;
336
348
  $[2] = props;
337
349
  $[3] = suffix;
338
350
  $[4] = t1;
339
351
  $[5] = t2;
352
+ $[6] = t3;
353
+ $[7] = t4;
354
+ $[8] = t5;
340
355
  } else {
341
356
  prefix = $[1];
342
357
  props = $[2];
343
358
  suffix = $[3];
344
359
  t1 = $[4];
345
360
  t2 = $[5];
361
+ t3 = $[6];
362
+ t4 = $[7];
363
+ t5 = $[8];
346
364
  }
347
- const described = t1 === void 0 ? NO_PARTS : t1;
348
- const numeric = t2 === void 0 ? false : t2;
365
+ const autosize = t1 === void 0 ? true : t1;
366
+ const described = t2 === void 0 ? NO_PARTS : t2;
367
+ const multiline = t3 === void 0 ? false : t3;
368
+ const numeric = t4 === void 0 ? false : t4;
369
+ const rows = t5 === void 0 ? 1 : t5;
349
370
  const box = use(BoxContext);
350
371
  const theme = useTheme();
351
372
  const styles = fieldStylesOf(theme);
@@ -360,72 +381,84 @@ function FieldInput(t0) {
360
381
  const affixed = prefix !== void 0 || suffix !== void 0;
361
382
  const clearance = box.underLabel ? marginTopOf(typography.bodySmallLineHeight * fontScale) : void 0;
362
383
  const affixStyle = composeStyles(role, colorOf(muted));
363
- let t3;
364
- if ($[6] !== described || $[7] !== id || $[8] !== prefix || $[9] !== suffix) {
365
- t3 = descriptionOf([
384
+ const lines = typography.bodyLargeLineHeight * fontScale * (multiline ? rows : 1);
385
+ const copied = multiline && autosize && Platform.OS === "web";
386
+ const extent = multiline && !autosize ? heightOf(lines) : minHeightOf(lines);
387
+ let t6;
388
+ if ($[9] !== described || $[10] !== id || $[11] !== prefix || $[12] !== suffix) {
389
+ t6 = descriptionOf([
366
390
  ...affixPart(`${id}-prefix`, prefix),
367
391
  ...affixPart(`${id}-suffix`, suffix),
368
392
  ...described
369
393
  ]);
370
- $[6] = described;
371
- $[7] = id;
372
- $[8] = prefix;
373
- $[9] = suffix;
374
- $[10] = t3;
375
- } else t3 = $[10];
376
- let t4;
377
- if ($[11] !== box) {
378
- t4 = webStateOf(box);
379
- $[11] = box;
380
- $[12] = t4;
381
- } else t4 = $[12];
394
+ $[9] = described;
395
+ $[10] = id;
396
+ $[11] = prefix;
397
+ $[12] = suffix;
398
+ $[13] = t6;
399
+ } else t6 = $[13];
400
+ let t7;
401
+ if ($[14] !== box) {
402
+ t7 = webStateOf(box);
403
+ $[14] = box;
404
+ $[15] = t7;
405
+ } else t7 = $[15];
382
406
  const control = /* @__PURE__ */ jsx(TextInput, {
383
407
  ...Platform.OS === "web" ? INHERITS_DIRECTION : void 0,
384
408
  ...props,
385
- ...t3,
386
- ...t4,
409
+ ...t6,
410
+ ...t7,
387
411
  "aria-disabled": box.disabled,
388
412
  cursorColor: caret,
413
+ multiline,
389
414
  placeholderTextColor: muted,
390
415
  selectionColor: caret,
391
- style: composeStyles(role, styles.input, colorOf(content), numeric ? numericOf(mono) : void 0, minHeightOf(typography.bodyLargeLineHeight * fontScale), affixed ? void 0 : clearance),
416
+ style: composeStyles(role, styles.input, colorOf(content), numeric ? numericOf(mono) : void 0, multiline ? styles.inputMultiline : void 0, copied ? styles.inputOverCopy : extent, affixed || copied ? void 0 : clearance),
392
417
  underlineColorAndroid: "transparent"
393
418
  });
419
+ if (copied) return /* @__PURE__ */ jsxs(View, {
420
+ style: composeStyles(styles.copied, clearance),
421
+ children: [/* @__PURE__ */ jsx(Text, {
422
+ "aria-hidden": true,
423
+ style: composeStyles(role, styles.copy, extent),
424
+ children: `${props.value ?? ""} `
425
+ }), control]
426
+ });
394
427
  if (!affixed) return control;
395
- let t5;
396
- if ($[13] !== affixStyle || $[14] !== box.floated || $[15] !== id || $[16] !== prefix) {
397
- t5 = prefix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
428
+ let t8;
429
+ if ($[16] !== affixStyle || $[17] !== box.floated || $[18] !== id || $[19] !== prefix) {
430
+ t8 = prefix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
398
431
  floated: box.floated,
399
432
  id: `${id}-prefix`,
400
433
  style: affixStyle,
401
434
  children: prefix
402
435
  });
403
- $[13] = affixStyle;
404
- $[14] = box.floated;
405
- $[15] = id;
406
- $[16] = prefix;
407
- $[17] = t5;
408
- } else t5 = $[17];
409
- let t6;
410
- if ($[18] !== affixStyle || $[19] !== box.floated || $[20] !== id || $[21] !== suffix) {
411
- t6 = suffix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
436
+ $[16] = affixStyle;
437
+ $[17] = box.floated;
438
+ $[18] = id;
439
+ $[19] = prefix;
440
+ $[20] = t8;
441
+ } else t8 = $[20];
442
+ let t9;
443
+ if ($[21] !== affixStyle || $[22] !== box.floated || $[23] !== id || $[24] !== suffix) {
444
+ t9 = suffix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
412
445
  floated: box.floated,
413
446
  id: `${id}-suffix`,
414
447
  style: affixStyle,
415
448
  children: suffix
416
449
  });
417
- $[18] = affixStyle;
418
- $[19] = box.floated;
419
- $[20] = id;
420
- $[21] = suffix;
421
- $[22] = t6;
422
- } else t6 = $[22];
450
+ $[21] = affixStyle;
451
+ $[22] = box.floated;
452
+ $[23] = id;
453
+ $[24] = suffix;
454
+ $[25] = t9;
455
+ } else t9 = $[25];
423
456
  return /* @__PURE__ */ jsxs(View, {
424
457
  style: composeStyles(styles.affixLine, clearance),
425
458
  children: [
426
- t5,
459
+ t8,
427
460
  control,
428
- t6
461
+ t9
429
462
  ]
430
463
  });
431
464
  }
@@ -789,6 +822,9 @@ function focusOf(control) {
789
822
  control.current?.focus();
790
823
  };
791
824
  }
825
+ function heightOf(height) {
826
+ return { height };
827
+ }
792
828
  function iconStyleOf(color) {
793
829
  return {
794
830
  color,
@@ -917,6 +953,11 @@ function FieldStroke(t0) {
917
953
  } else t2 = $[4];
918
954
  return t2;
919
955
  }
956
+ /**
957
+ * Says an error on iOS as it arrives, where a live region says nothing. An
958
+ * error the field opened with is not said, and neither is one that has not
959
+ * changed.
960
+ */
920
961
  function useErrorAnnouncement(error) {
921
962
  const $ = c(3);
922
963
  const said = useRef(error);
@@ -1005,6 +1046,6 @@ function widthTo(onMeasure) {
1005
1046
  };
1006
1047
  }
1007
1048
  //#endregion
1008
- export { FieldBox, FieldInput, FieldMessage, FieldStates, FieldStroke, describedBy, useFieldFocus, useStrokeMotion };
1049
+ export { FieldBox, FieldInput, FieldMessage, FieldStates, FieldStroke, describedBy, useErrorAnnouncement, useFieldFocus, useStrokeMotion };
1009
1050
 
1010
1051
  //# sourceMappingURL=index.js.map