@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,306 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useTypeRole } from "../../typography/roles.js";
4
+ import { withOpacity } from "../../theme/color.js";
5
+ import { useFieldValidation, useInsideForm } from "../../form/index.js";
6
+ import { messageOf } from "../../control/index.js";
7
+ import { CheckboxGroupContext, createMembers } from "../../control/group.js";
8
+ import { useErrorAnnouncement } from "../../field/index.js";
9
+ import { c } from "react/compiler-runtime";
10
+ import { Platform, StyleSheet, Text, View, useWindowDimensions } from "react-native";
11
+ import { useId, useState } from "react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ import { useCheckboxGroupState } from "react-stately/useCheckboxGroupState";
14
+ //#region src/components/checkbox-group/index.tsx
15
+ const REQUIRED_MARK = "*";
16
+ const ATOMIC = { "aria-atomic": true };
17
+ const stylesOf = themedStyles(({ colors, spacing, stateLayerOpacity }) => StyleSheet.create({
18
+ items: { flexDirection: "column" },
19
+ label: { color: colors.onSurfaceVariant },
20
+ labelDisabled: { color: withOpacity(colors.onSurface, stateLayerOpacity.disabledContent) },
21
+ labelError: { color: colors.error },
22
+ message: { color: colors.onSurfaceVariant },
23
+ messageError: { color: colors.error },
24
+ messageLine: { marginTop: spacing.xs },
25
+ messageLineCollapsed: {
26
+ marginTop: 0,
27
+ position: "absolute"
28
+ },
29
+ outOfFlow: { position: "absolute" },
30
+ root: {
31
+ flexDirection: "column",
32
+ rowGap: spacing.xs
33
+ }
34
+ }));
35
+ /**
36
+ * A labelled set of checkboxes with one value between them. The value is
37
+ * React Stately's, as web's is React Aria's: pass `value` with `onChange` to
38
+ * control it, or `defaultValue` to let the group keep its own, and each
39
+ * `Checkbox` inside names the entry it stands for with `value`. Disabled,
40
+ * read-only and the error state reach every checkbox from here.
41
+ *
42
+ * ```tsx
43
+ * <CheckboxGroup defaultValue={['first']} label="Label">
44
+ * <Checkbox value="first">First item</Checkbox>
45
+ * <Checkbox value="second">Second item</Checkbox>
46
+ * </CheckboxGroup>
47
+ * ```
48
+ *
49
+ * A screen reader hears it as a group named by its label. On the web the
50
+ * line under it describes the group, as web's does; on iOS and Android it is
51
+ * read after the checkboxes, where it sits, and an error is announced as it
52
+ * arrives. `style`, `ref` and `testID` land on the group as a whole, which is
53
+ * the element a layout positions.
54
+ */
55
+ function CheckboxGroup(t0) {
56
+ const $ = c(61);
57
+ let children;
58
+ let defaultValue;
59
+ let description;
60
+ let error;
61
+ let label;
62
+ let name;
63
+ let onChange;
64
+ let props;
65
+ let style;
66
+ let t1;
67
+ let t2;
68
+ let t3;
69
+ let validate;
70
+ let value;
71
+ if ($[0] !== t0) {
72
+ ({children, defaultValue, description, error, isDisabled: t1, isReadOnly: t2, isRequired: t3, label, name, onChange, style, validate, value, ...props} = t0);
73
+ $[0] = t0;
74
+ $[1] = children;
75
+ $[2] = defaultValue;
76
+ $[3] = description;
77
+ $[4] = error;
78
+ $[5] = label;
79
+ $[6] = name;
80
+ $[7] = onChange;
81
+ $[8] = props;
82
+ $[9] = style;
83
+ $[10] = t1;
84
+ $[11] = t2;
85
+ $[12] = t3;
86
+ $[13] = validate;
87
+ $[14] = value;
88
+ } else {
89
+ children = $[1];
90
+ defaultValue = $[2];
91
+ description = $[3];
92
+ error = $[4];
93
+ label = $[5];
94
+ name = $[6];
95
+ onChange = $[7];
96
+ props = $[8];
97
+ style = $[9];
98
+ t1 = $[10];
99
+ t2 = $[11];
100
+ t3 = $[12];
101
+ validate = $[13];
102
+ value = $[14];
103
+ }
104
+ const isDisabled = t1 === void 0 ? false : t1;
105
+ const isReadOnly = t2 === void 0 ? false : t2;
106
+ const isRequired = t3 === void 0 ? false : t3;
107
+ const theme = useTheme();
108
+ let t4;
109
+ if ($[15] !== defaultValue) {
110
+ t4 = copyOf(defaultValue);
111
+ $[15] = defaultValue;
112
+ $[16] = t4;
113
+ } else t4 = $[16];
114
+ let t5;
115
+ if ($[17] !== value) {
116
+ t5 = copyOf(value);
117
+ $[17] = value;
118
+ $[18] = t5;
119
+ } else t5 = $[18];
120
+ let t6;
121
+ if ($[19] !== isDisabled || $[20] !== isReadOnly || $[21] !== onChange || $[22] !== t4 || $[23] !== t5) {
122
+ t6 = {
123
+ defaultValue: t4,
124
+ isDisabled,
125
+ isReadOnly,
126
+ onChange,
127
+ value: t5
128
+ };
129
+ $[19] = isDisabled;
130
+ $[20] = isReadOnly;
131
+ $[21] = onChange;
132
+ $[22] = t4;
133
+ $[23] = t5;
134
+ $[24] = t6;
135
+ } else t6 = $[24];
136
+ const state = useCheckboxGroupState(t6);
137
+ const [members] = useState(createMembers);
138
+ const t7 = state.value.length === 0;
139
+ let t8;
140
+ if ($[25] !== error || $[26] !== isDisabled || $[27] !== isReadOnly || $[28] !== isRequired || $[29] !== members || $[30] !== name || $[31] !== state.value || $[32] !== t7 || $[33] !== validate) {
141
+ t8 = {
142
+ control: members,
143
+ error,
144
+ isDisabled,
145
+ isEmpty: t7,
146
+ isReadOnly,
147
+ isRequired,
148
+ name,
149
+ submitted: void 0,
150
+ validate,
151
+ value: state.value
152
+ };
153
+ $[25] = error;
154
+ $[26] = isDisabled;
155
+ $[27] = isReadOnly;
156
+ $[28] = isRequired;
157
+ $[29] = members;
158
+ $[30] = name;
159
+ $[31] = state.value;
160
+ $[32] = t7;
161
+ $[33] = validate;
162
+ $[34] = t8;
163
+ } else t8 = $[34];
164
+ const validation = useFieldValidation(t8);
165
+ const labelId = useId();
166
+ const messageId = useId();
167
+ const labelRole = useTypeRole("labelLarge");
168
+ const messageRole = useTypeRole("bodySmall");
169
+ const insideForm = useInsideForm();
170
+ const { fontScale } = useWindowDimensions();
171
+ const own = stylesOf(theme);
172
+ const shown = validation.error;
173
+ const invalid = shown !== void 0;
174
+ const message = messageOf(description, shown);
175
+ const holdsLine = insideForm || message !== void 0;
176
+ let t9;
177
+ if ($[35] !== invalid || $[36] !== members || $[37] !== state || $[38] !== validation) {
178
+ t9 = contextOf(state, members, validation, invalid);
179
+ $[35] = invalid;
180
+ $[36] = members;
181
+ $[37] = state;
182
+ $[38] = validation;
183
+ $[39] = t9;
184
+ } else t9 = $[39];
185
+ const context = t9;
186
+ const messageStyle = composeStyles(messageRole, own.message, invalid ? own.messageError : void 0);
187
+ useErrorAnnouncement(shown);
188
+ const t10 = lineOf(messageId, message);
189
+ const t11 = composeStyles(own.root, style);
190
+ let t12;
191
+ if ($[40] !== children || $[41] !== context) {
192
+ t12 = /* @__PURE__ */ jsx(CheckboxGroupContext, {
193
+ value: context,
194
+ children
195
+ });
196
+ $[40] = children;
197
+ $[41] = context;
198
+ $[42] = t12;
199
+ } else t12 = $[42];
200
+ const T0 = View;
201
+ const t13 = composeStyles(own.messageLine, holdsLine ? minHeightOf(theme.typography.bodySmallLineHeight * fontScale) : own.messageLineCollapsed);
202
+ const t14 = invalid && shown !== "" ? void 0 : own.outOfFlow;
203
+ let t15;
204
+ if ($[43] !== invalid || $[44] !== messageId || $[45] !== messageStyle || $[46] !== shown) {
205
+ t15 = invalid && shown !== "" ? /* @__PURE__ */ jsx(Text, {
206
+ id: messageId,
207
+ style: messageStyle,
208
+ children: shown
209
+ }) : null;
210
+ $[43] = invalid;
211
+ $[44] = messageId;
212
+ $[45] = messageStyle;
213
+ $[46] = shown;
214
+ $[47] = t15;
215
+ } else t15 = $[47];
216
+ let t16;
217
+ if ($[48] !== t14 || $[49] !== t15) {
218
+ t16 = /* @__PURE__ */ jsx(View, {
219
+ "aria-live": "polite",
220
+ ...Platform.OS === "web" ? ATOMIC : void 0,
221
+ style: t14,
222
+ children: t15
223
+ });
224
+ $[48] = t14;
225
+ $[49] = t15;
226
+ $[50] = t16;
227
+ } else t16 = $[50];
228
+ let t17;
229
+ if ($[51] !== description || $[52] !== invalid || $[53] !== messageId || $[54] !== messageStyle) {
230
+ t17 = invalid || description === void 0 ? null : /* @__PURE__ */ jsx(Text, {
231
+ id: messageId,
232
+ style: messageStyle,
233
+ children: description
234
+ });
235
+ $[51] = description;
236
+ $[52] = invalid;
237
+ $[53] = messageId;
238
+ $[54] = messageStyle;
239
+ $[55] = t17;
240
+ } else t17 = $[55];
241
+ let t18;
242
+ if ($[56] !== T0 || $[57] !== t13 || $[58] !== t16 || $[59] !== t17) {
243
+ t18 = /* @__PURE__ */ jsxs(T0, {
244
+ style: t13,
245
+ children: [t16, t17]
246
+ });
247
+ $[56] = T0;
248
+ $[57] = t13;
249
+ $[58] = t16;
250
+ $[59] = t17;
251
+ $[60] = t18;
252
+ } else t18 = $[60];
253
+ return /* @__PURE__ */ jsxs(View, {
254
+ ...props,
255
+ "aria-labelledby": labelId,
256
+ role: "group",
257
+ ...t10,
258
+ style: t11,
259
+ children: [
260
+ /* @__PURE__ */ jsxs(Text, {
261
+ id: labelId,
262
+ style: composeStyles(labelRole, own.label, isDisabled ? own.labelDisabled : void 0, invalid ? own.labelError : void 0),
263
+ children: [label, isRequired ? REQUIRED_MARK : null]
264
+ }),
265
+ /* @__PURE__ */ jsx(View, {
266
+ style: own.items,
267
+ children: t12
268
+ }),
269
+ t18
270
+ ]
271
+ });
272
+ }
273
+ function contextOf(state, members, { onBlur, onEdit }, isInvalid) {
274
+ return {
275
+ isDisabled: state.isDisabled,
276
+ isInvalid,
277
+ isReadOnly: state.isReadOnly,
278
+ isSelected: (entry) => state.isSelected(entry),
279
+ members,
280
+ set: (entry, isSelected) => {
281
+ if (isSelected) state.addValue(entry);
282
+ else state.removeValue(entry);
283
+ onEdit();
284
+ onBlur();
285
+ }
286
+ };
287
+ }
288
+ function copyOf(entries) {
289
+ return entries === void 0 ? void 0 : [...entries];
290
+ }
291
+ /**
292
+ * How the group is described by the line under it. On the web it points at
293
+ * the line with `aria-describedby`, as web's group does. iOS and Android
294
+ * focus the checkboxes rather than the group, so there the line is left
295
+ * where a screen reader reaches it in order, after the last checkbox.
296
+ */
297
+ function lineOf(id, message) {
298
+ return Platform.OS === "web" && message !== void 0 ? { "aria-describedby": id } : void 0;
299
+ }
300
+ function minHeightOf(minHeight) {
301
+ return { minHeight };
302
+ }
303
+ //#endregion
304
+ export { CheckboxGroup };
305
+
306
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","StyleProp","TextStyle","ViewProps","ViewStyle","CheckboxGroupState","useId","useState","Text","NativeText","Platform","StyleSheet","useWindowDimensions","View","useCheckboxGroupState","CheckboxGroupContextValue","ValidationResult","messageOf","CheckboxGroupContext","createMembers","useErrorAnnouncement","useFieldValidation","useInsideForm","withOpacity","useTheme","composeStyles","themedStyles","useTypeRole","CheckboxGroupProps","Omit","children","defaultValue","description","error","isDisabled","isReadOnly","isRequired","label","name","onChange","value","ref","style","validate","REQUIRED_MARK","ATOMIC","const","stylesOf","colors","spacing","stateLayerOpacity","create","items","flexDirection","color","onSurfaceVariant","labelDisabled","onSurface","disabledContent","labelError","message","messageError","messageLine","marginTop","xs","messageLineCollapsed","position","outOfFlow","root","rowGap","CheckboxGroup","t0","$","_c","props","t1","t2","t3","undefined","theme","t4","copyOf","t5","t6","state","members","t7","length","t8","control","isEmpty","submitted","validation","labelId","messageId","labelRole","messageRole","insideForm","fontScale","own","shown","invalid","holdsLine","t9","contextOf","context","messageStyle","t10","lineOf","t11","t12","T0","t13","minHeightOf","typography","bodySmallLineHeight","t14","t15","t16","OS","t17","t18","onBlur","onEdit","isInvalid","isSelected","entry","set","addValue","removeValue","entries","id","minHeight","_c","NativeText"],"sources":["../../../src/components/checkbox-group/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type { StyleProp, TextStyle, ViewProps, ViewStyle } from 'react-native'\nimport type { CheckboxGroupState } from 'react-stately/useCheckboxGroupState'\n\nimport { useId, useState } from 'react'\nimport {\n Text as NativeText,\n Platform,\n StyleSheet,\n useWindowDimensions,\n View,\n} from 'react-native'\nimport { useCheckboxGroupState } from 'react-stately/useCheckboxGroupState'\n\nimport type { CheckboxGroupContextValue } from '../../control/group'\nimport type { ValidationResult } from '../../form'\n\nimport { messageOf } from '../../control'\nimport { CheckboxGroupContext, createMembers } from '../../control/group'\nimport { useErrorAnnouncement } from '../../field'\nimport { useFieldValidation, useInsideForm } from '../../form'\nimport { withOpacity } from '../../theme/color'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// kanso-ui's CheckboxGroup: a labelled set of checkboxes sharing one value.\n// The checkbox page draws the boxes; the group is what the pattern asks for\n// around them, a group named by its label, described by the line under it\n// and invalid as a whole, and its label and that line are the field chrome's,\n// so a group reads like the fields beside it.\n//\n// The group is a column: its label in label large, the checkboxes, and the\n// line under them, 4dp apart, with the line a further 4dp down, as web's\n// field chrome sets them out and RadioGroup does here. The label is on\n// surface variant, error while the group has one, and on surface at the\n// disabled opacity while disabled, with the required mark a field's label\n// carries. The line is not inset, since a group has no box to line it up\n// with.\n//\n// The value is React Stately's, as web's is React Aria's, and the group hands\n// it to its checkboxes through src/control/group, as RadioGroup hands its\n// buttons theirs. Its validation is src/form's, as a field's is: `isRequired`,\n// `validate`, and the form's errors under the group's `name`. A native Form\n// holding it back focuses its first checkbox.\n//\n// Inside a Form the line is held from the start, as web's is, so an error\n// arriving on submit moves nothing under the group. Outside one it takes\n// space only while there is something in it, and stays mounted for the live\n// region inside it, which has to be in place before the error it announces.\n\ntype CheckboxGroupProps = Omit<ViewProps, 'children' | 'style'> & {\n /** The checkboxes, each with a `value` of its own. */\n readonly children?: ReactNode\n /** The entries selected at first, when the group keeps its own value. */\n readonly defaultValue?: readonly string[]\n /**\n * A hint under the group. Replaced by `error` when there is one, so the\n * two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current selection, in words. Its presence is what\n * puts the group in its error state: the message, the label's colour and\n * every box's error colours follow from it.\n *\n * Outside a `Form` the line under the group arrives with the message, so\n * the group grows when this does and moves what is under it. A `Form`\n * holds that space from the start; so does a permanent `description`.\n */\n readonly error?: string\n /**\n * Draws every checkbox disabled, and takes no presses.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the selection without letting a press change it.\n * @default false\n */\n readonly isReadOnly?: boolean\n /**\n * Marks the group's label, and has a `native` form hold submission back\n * while nothing is selected.\n * @default false\n */\n readonly isRequired?: boolean\n /**\n * What the group is for. Required rather than optional: a group of\n * checkboxes with no name is a set of boxes a screen reader cannot\n * introduce.\n */\n readonly label: string\n /**\n * The name the form around the group knows it by, which its\n * `validationErrors` are keyed on. A form hands `onSubmit` one string per\n * name, so a group's selection is not among those values: read it through\n * `onChange`, or hold it with `value`.\n */\n readonly name?: string\n /** Called with the newly selected entries whenever a press changes them. */\n readonly onChange?: (value: string[]) => void\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n /**\n * Checks the selection, returning its problem in words, or `true`, `null`\n * or `undefined` when there is none. Shown as it changes, or under a\n * `native` form once a submission is tried.\n */\n readonly validate?: (value: readonly string[]) => ValidationResult\n /**\n * The selected entries, for a call site holding the value itself with\n * `onChange`.\n */\n readonly value?: readonly string[]\n}\n\n// What marks a required group's label, as a field's label marks one.\nconst REQUIRED_MARK = '*'\n\n// What has a live region on the web read its whole content again whenever\n// any of it changes, as the field's line does.\nconst ATOMIC = { 'aria-atomic': true } as const\n\nconst stylesOf = themedStyles(({ colors, spacing, stateLayerOpacity }) =>\n StyleSheet.create({\n // The group's checkboxes, one under another.\n items: {\n flexDirection: 'column',\n },\n label: {\n color: colors.onSurfaceVariant,\n },\n labelDisabled: {\n color: withOpacity(colors.onSurface, stateLayerOpacity.disabledContent),\n },\n labelError: {\n color: colors.error,\n },\n message: {\n color: colors.onSurfaceVariant,\n },\n messageError: {\n color: colors.error,\n },\n messageLine: {\n marginTop: spacing.xs,\n },\n // The line with nothing to show: out of the flow, so the group ends at\n // its last checkbox, and still there for the live region inside it.\n messageLineCollapsed: {\n marginTop: 0,\n position: 'absolute',\n },\n // The live region with nothing in it, which takes no place in the line.\n outOfFlow: {\n position: 'absolute',\n },\n root: {\n flexDirection: 'column',\n rowGap: spacing.xs,\n },\n }),\n)\n\n/**\n * A labelled set of checkboxes with one value between them. The value is\n * React Stately's, as web's is React Aria's: pass `value` with `onChange` to\n * control it, or `defaultValue` to let the group keep its own, and each\n * `Checkbox` inside names the entry it stands for with `value`. Disabled,\n * read-only and the error state reach every checkbox from here.\n *\n * ```tsx\n * <CheckboxGroup defaultValue={['first']} label=\"Label\">\n * <Checkbox value=\"first\">First item</Checkbox>\n * <Checkbox value=\"second\">Second item</Checkbox>\n * </CheckboxGroup>\n * ```\n *\n * A screen reader hears it as a group named by its label. On the web the\n * line under it describes the group, as web's does; on iOS and Android it is\n * read after the checkboxes, where it sits, and an error is announced as it\n * arrives. `style`, `ref` and `testID` land on the group as a whole, which is\n * the element a layout positions.\n */\nfunction CheckboxGroup({\n children,\n defaultValue,\n description,\n error,\n isDisabled = false,\n isReadOnly = false,\n isRequired = false,\n label,\n name,\n onChange,\n style,\n validate,\n value,\n ...props\n}: CheckboxGroupProps) {\n const theme = useTheme()\n const state = useCheckboxGroupState({\n defaultValue: copyOf(defaultValue),\n isDisabled,\n isReadOnly,\n onChange,\n value: copyOf(value),\n })\n const [members] = useState(createMembers)\n const validation = useFieldValidation({\n control: members,\n error,\n isDisabled,\n isEmpty: state.value.length === 0,\n isReadOnly,\n isRequired,\n name,\n submitted: undefined,\n validate,\n value: state.value,\n })\n const labelId = useId()\n const messageId = useId()\n const labelRole = useTypeRole('labelLarge')\n const messageRole = useTypeRole('bodySmall')\n const insideForm = useInsideForm()\n const { fontScale } = useWindowDimensions()\n\n const own = stylesOf(theme)\n const shown = validation.error\n const invalid = shown !== undefined\n const message = messageOf(description, shown)\n const holdsLine = insideForm || message !== undefined\n const context = contextOf(state, members, validation, invalid)\n const messageStyle = composeStyles<TextStyle>(\n messageRole,\n own.message,\n invalid ? own.messageError : undefined,\n )\n\n useErrorAnnouncement(shown)\n\n return (\n <View\n {...props}\n aria-labelledby={labelId}\n role=\"group\"\n {...lineOf(messageId, message)}\n style={composeStyles<ViewStyle>(own.root, style)}\n >\n <NativeText\n id={labelId}\n style={composeStyles<TextStyle>(\n labelRole,\n own.label,\n isDisabled ? own.labelDisabled : undefined,\n invalid ? own.labelError : undefined,\n )}\n >\n {label}\n {isRequired ? REQUIRED_MARK : null}\n </NativeText>\n <View style={own.items}>\n <CheckboxGroupContext value={context}>{children}</CheckboxGroupContext>\n </View>\n <View\n style={composeStyles<ViewStyle>(\n own.messageLine,\n holdsLine\n ? minHeightOf(theme.typography.bodySmallLineHeight * fontScale)\n : own.messageLineCollapsed,\n )}\n >\n <View\n aria-live=\"polite\"\n {...(Platform.OS === 'web' ? ATOMIC : undefined)}\n style={invalid && shown !== '' ? undefined : own.outOfFlow}\n >\n {invalid && shown !== '' ? (\n <NativeText id={messageId} style={messageStyle}>\n {shown}\n </NativeText>\n ) : null}\n </View>\n {invalid || description === undefined ? null : (\n <NativeText id={messageId} style={messageStyle}>\n {description}\n </NativeText>\n )}\n </View>\n </View>\n )\n}\n\n// What the group tells its checkboxes. A press selects or clears an entry\n// and then counts as the edit and the commit both, since a checkbox changes\n// the value at once rather than as a control loses focus, which is what a\n// native form shows an error after.\nfunction contextOf(\n state: CheckboxGroupState,\n members: CheckboxGroupContextValue['members'],\n {\n onBlur,\n onEdit,\n }: { readonly onBlur: () => void; readonly onEdit: () => void },\n isInvalid: boolean,\n): CheckboxGroupContextValue {\n return {\n isDisabled: state.isDisabled,\n isInvalid,\n isReadOnly: state.isReadOnly,\n isSelected: (entry) => state.isSelected(entry),\n members,\n set: (entry, isSelected) => {\n if (isSelected) {\n state.addValue(entry)\n } else {\n state.removeValue(entry)\n }\n onEdit()\n onBlur()\n },\n }\n}\n\n// A list the call site may hold as read-only, as the mutable copy React\n// Stately takes.\nfunction copyOf(entries: readonly string[] | undefined) {\n return entries === undefined ? undefined : [...entries]\n}\n\n/**\n * How the group is described by the line under it. On the web it points at\n * the line with `aria-describedby`, as web's group does. iOS and Android\n * focus the checkboxes rather than the group, so there the line is left\n * where a screen reader reaches it in order, after the last checkbox.\n */\nfunction lineOf(id: string, message: string | undefined) {\n return Platform.OS === 'web' && message !== undefined\n ? { 'aria-describedby': id }\n : undefined\n}\n\nfunction minHeightOf(minHeight: number): ViewStyle {\n return { minHeight }\n}\n\nexport { CheckboxGroup }\nexport type { CheckboxGroupProps }\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { Text, TextProps } from "react-native";
2
+ import { ComponentRef, Ref } from "react";
3
+ //#region src/components/code/index.d.ts
4
+ type CodeProps = TextProps & {
5
+ readonly ref?: Ref<ComponentRef<typeof Text>>;
6
+ };
7
+ /**
8
+ * A fragment of code, a path or an identifier set in the mono face, inside a
9
+ * run of text.
10
+ *
11
+ * ```tsx
12
+ * <Text variant="bodyLarge">
13
+ * A sentence naming <Code>identifier</Code>
14
+ * </Text>
15
+ * ```
16
+ *
17
+ * It takes its colour from the Text around it and 0.875 of its size, so the
18
+ * same Code serves a heading and a footnote. `style`, `ref` and `testID` land
19
+ * on React Native's own Text, and a `style` there applies over the face and
20
+ * the size.
21
+ */
22
+ declare function Code({ children, style, ...props }: CodeProps): import("react").JSX.Element;
23
+ //#endregion
24
+ export { Code, type CodeProps };
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,87 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useFontFamily } from "../../typography/fonts.js";
4
+ import { familyStyle, useTypeRole } from "../../typography/roles.js";
5
+ import { TextSizeContext, useTextSize } from "../../typography/size.js";
6
+ import { c } from "react/compiler-runtime";
7
+ import { StyleSheet, Text } from "react-native";
8
+ import { jsx } from "react/jsx-runtime";
9
+ //#region src/components/code/index.tsx
10
+ const SHARE = .875;
11
+ const stylesOf = themedStyles(({ colors }) => StyleSheet.create({ outside: { color: colors.onSurface } }));
12
+ /**
13
+ * A fragment of code, a path or an identifier set in the mono face, inside a
14
+ * run of text.
15
+ *
16
+ * ```tsx
17
+ * <Text variant="bodyLarge">
18
+ * A sentence naming <Code>identifier</Code>
19
+ * </Text>
20
+ * ```
21
+ *
22
+ * It takes its colour from the Text around it and 0.875 of its size, so the
23
+ * same Code serves a heading and a footnote. `style`, `ref` and `testID` land
24
+ * on React Native's own Text, and a `style` there applies over the face and
25
+ * the size.
26
+ */
27
+ function Code(t0) {
28
+ const $ = c(18);
29
+ let children;
30
+ let props;
31
+ let style;
32
+ if ($[0] !== t0) {
33
+ ({children, style, ...props} = t0);
34
+ $[0] = t0;
35
+ $[1] = children;
36
+ $[2] = props;
37
+ $[3] = style;
38
+ } else {
39
+ children = $[1];
40
+ props = $[2];
41
+ style = $[3];
42
+ }
43
+ const theme = useTheme();
44
+ const around = useTextSize();
45
+ const body = useTypeRole("bodyMedium");
46
+ const mono = useFontFamily(theme.typography.fontFamilyMono);
47
+ const outside = around === void 0;
48
+ const size = (around ?? theme.typography.bodyMediumSize) * SHARE;
49
+ let t1;
50
+ if ($[4] !== body || $[5] !== mono || $[6] !== outside || $[7] !== size || $[8] !== style || $[9] !== theme) {
51
+ t1 = composeStyles(outside ? body : null, outside ? stylesOf(theme).outside : null, familyStyle(mono), { fontSize: size }, style);
52
+ $[4] = body;
53
+ $[5] = mono;
54
+ $[6] = outside;
55
+ $[7] = size;
56
+ $[8] = style;
57
+ $[9] = theme;
58
+ $[10] = t1;
59
+ } else t1 = $[10];
60
+ let t2;
61
+ if ($[11] !== children || $[12] !== size) {
62
+ t2 = /* @__PURE__ */ jsx(TextSizeContext, {
63
+ value: size,
64
+ children
65
+ });
66
+ $[11] = children;
67
+ $[12] = size;
68
+ $[13] = t2;
69
+ } else t2 = $[13];
70
+ let t3;
71
+ if ($[14] !== props || $[15] !== t1 || $[16] !== t2) {
72
+ t3 = /* @__PURE__ */ jsx(Text, {
73
+ ...props,
74
+ style: t1,
75
+ children: t2
76
+ });
77
+ $[14] = props;
78
+ $[15] = t1;
79
+ $[16] = t2;
80
+ $[17] = t3;
81
+ } else t3 = $[17];
82
+ return t3;
83
+ }
84
+ //#endregion
85
+ export { Code };
86
+
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","TextProps","NativeTextProps","TextStyle","Text","NativeText","StyleSheet","useTheme","composeStyles","themedStyles","useFontFamily","familyStyle","useTypeRole","TextSizeContext","useTextSize","SHARE","stylesOf","colors","create","outside","color","onSurface","CodeProps","ref","Code","t0","$","_c","children","props","style","theme","around","body","mono","typography","fontFamilyMono","undefined","size","bodyMediumSize","t1","fontSize","t2","t3","_c","NativeText"],"sources":["../../../src/components/code/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 { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useFontFamily } from '../../typography/fonts'\nimport { familyStyle, useTypeRole } from '../../typography/roles'\nimport { TextSizeContext, useTextSize } from '../../typography/size'\n\n// kanso-ui's Code. No Material Design page draws inline code, so it follows\n// web's reading, which follows the type it interrupts: the role and the colour\n// of the text around it, in the mono face the type tokens carry, at 0.875 of\n// its size. A mono face at the same nominal size as the prose around it reads\n// a little larger, its glyphs being wider and its x-height taller, so the\n// ratio is what makes the two look level rather than what makes them measure\n// the same.\n//\n// No background, as on web. The mono face against the faces the rest of the\n// system uses is already the signal, and a tint would put a second surface\n// inside a Card or a Sheet. A call site wanting one can wrap this.\n//\n// It is a native Text nested in the one it interrupts, which hands it the\n// colour, the weight, the line height and the tracking with nothing set here.\n// The size is the one it cannot take as it stands, since 0.875 of a size needs\n// the number and a nested Text cannot read its parent's, so the library's Text\n// provides the size it ends up at and this sets the share of it. Outside a\n// Text there is no text around to take anything from, so it draws as a Text\n// of the default role and tone would, in body medium on surface, at the same\n// share of body medium's size. Inside some other component's text, which\n// provides no size, it does the same, so nest it in a Text.\n//\n// React Native has no `overflow-wrap: anywhere`. iOS and Android break a word\n// wider than its line between characters rather than letting it run past the\n// edge, and React Native Web's Text sets `overflow-wrap: break-word`, so a\n// package path or a hash still stays inside its container, breaking at the\n// hyphens and slashes in it where a line allows. The LongIdentifier story\n// shows it.\n\n// The size against the text around it, web's `0.875em`.\nconst SHARE = 0.875\n\nconst stylesOf = themedStyles(({ colors }) =>\n StyleSheet.create({\n // The colour of a Text's default tone, for a Code with no text around it.\n outside: {\n color: colors.onSurface,\n },\n }),\n)\n\ntype CodeProps = NativeTextProps & {\n readonly ref?: Ref<ComponentRef<typeof NativeText>>\n}\n\n/**\n * A fragment of code, a path or an identifier set in the mono face, inside a\n * run of text.\n *\n * ```tsx\n * <Text variant=\"bodyLarge\">\n * A sentence naming <Code>identifier</Code>\n * </Text>\n * ```\n *\n * It takes its colour from the Text around it and 0.875 of its size, so the\n * same Code serves a heading and a footnote. `style`, `ref` and `testID` land\n * on React Native's own Text, and a `style` there applies over the face and\n * the size.\n */\nfunction Code({ children, style, ...props }: CodeProps) {\n const theme = useTheme()\n const around = useTextSize()\n const body = useTypeRole('bodyMedium')\n const mono = useFontFamily(theme.typography.fontFamilyMono)\n const outside = around === undefined\n const size = (around ?? theme.typography.bodyMediumSize) * SHARE\n\n return (\n <NativeText\n {...props}\n style={composeStyles<TextStyle>(\n outside ? body : null,\n outside ? stylesOf(theme).outside : null,\n familyStyle(mono),\n { fontSize: size },\n style,\n )}\n >\n <TextSizeContext value={size}>{children}</TextSizeContext>\n </NativeText>\n )\n}\n\nexport type { CodeProps }\n\nexport { Code }\n"],"mappings":";;;;;;;;;AAyCA,MAAMgB,QAAQ;AAEd,MAAMC,WAAWP,cAAc,EAAEQ,aAC/BX,WAAWY,OAAO,EAEhBC,SAAS,EACPC,OAAOH,OAAOI,UAChB,EACF,CAAC,CACH;;;;;;;;;;;;;;;;AAqBA,SAAAG,KAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,IAAA;EAAc,CAAA,CAAAG,UAAAE,OAAA,GAAAD,SAAAJ;EAAwCC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAF,WAAAF,EAAA;EAAAG,QAAAH,EAAA;EAAAI,QAAAJ,EAAA;CAAA;CACpD,MAAAK,QAAcxB,SAAS;CACvB,MAAAyB,SAAelB,YAAY;CAC3B,MAAAmB,OAAarB,YAAY,YAAY;CACrC,MAAAsB,OAAaxB,cAAcqB,MAAKI,WAAWC,cAAe;CAC1D,MAAAjB,UAAgBa,WAAWK,KAAAA;CAC3B,MAAAC,QAAcN,UAAUD,MAAKI,WAAWI,kBAAmBxB;CAAK,IAAAyB;CAAA,IAAAd,EAAA,OAAAO,QAAAP,EAAA,OAAAQ,QAAAR,EAAA,OAAAP,WAAAO,EAAA,OAAAY,QAAAZ,EAAA,OAAAI,SAAAJ,EAAA,OAAAK,OAAA;EAKrDS,KAAAhC,cACLW,UAAAc,OAAA,MACAd,UAAUH,SAASe,KAAK,CAAC,CAAAZ,UAAzB,MACAR,YAAYuB,IAAI,GAChB,EAAAO,UAAYH,KAAK,GACjBR,KACF;EAACJ,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;EAAAR,EAAA,KAAAP;EAAAO,EAAA,KAAAY;EAAAZ,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;EAAAL,EAAA,MAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,IAAAgB;CAAA,IAAAhB,EAAA,QAAAE,YAAAF,EAAA,QAAAY,MAAA;EAEDI,KAAA,oBAAC,iBAAD;GAAwBJ,OAAAA;GAAOV;EAAf,CAAA;EAA0CF,EAAA,MAAAE;EAAAF,EAAA,MAAAY;EAAAZ,EAAA,MAAAgB;CAAA,OAAAA,KAAAhB,EAAA;CAAA,IAAAiB;CAAA,IAAAjB,EAAA,QAAAG,SAAAH,EAAA,QAAAc,MAAAd,EAAA,QAAAgB,IAAA;EAV5DC,KAAA,oBAACE,MAAD;GAAW,GACLhB;GACG,OAAAW;GAQPE,UAAAA;EAVS,CAAA;EAWEhB,EAAA,MAAAG;EAAAH,EAAA,MAAAc;EAAAd,EAAA,MAAAgB;EAAAhB,EAAA,MAAAiB;CAAA,OAAAA,KAAAjB,EAAA;CAAA,OAXbiB;AAWa"}
@@ -0,0 +1,47 @@
1
+ import { View, ViewProps } from "react-native";
2
+ import { ComponentRef, Ref } from "react";
3
+ //#region src/components/container/index.d.ts
4
+ type ContainerPadding = 'default' | 'none';
5
+ type ContainerProps = ViewProps & {
6
+ /**
7
+ * How wide the content may run before it stops growing, in dp or as a
8
+ * share of the width it is given. The container stands in the middle of
9
+ * whatever is left over.
10
+ *
11
+ * Worth setting. The default suits a page of mixed components; prose wants
12
+ * a narrower measure, since what makes a line hard to read is how many
13
+ * characters it holds.
14
+ * @default 960
15
+ */
16
+ readonly maxInlineSize?: `${number}%` | number;
17
+ /**
18
+ * Horizontal padding, which is what keeps the content off the edge of the
19
+ * window once it is narrower than the measure: 16dp in a compact window and
20
+ * 24dp from medium up. `none` is for a container nested inside one that
21
+ * already has it.
22
+ * @default 'default'
23
+ */
24
+ readonly padding?: ContainerPadding;
25
+ readonly ref?: Ref<ComponentRef<typeof View>>;
26
+ };
27
+ /**
28
+ * A centred measure for a screen or a section of one: content grows to a
29
+ * width and stops, with the leftover space split evenly either side.
30
+ *
31
+ * ```tsx
32
+ * <Container maxInlineSize={600}>
33
+ * <Text>Supporting line</Text>
34
+ * </Container>
35
+ * ```
36
+ *
37
+ * Layout only: it paints no surface and gives its children no container of
38
+ * their own, which is what separates it from Card. It sets no gaps either, so
39
+ * reach for Stack inside it for the rhythm between sections.
40
+ *
41
+ * `style`, `ref` and `testID` land on the `View`, and a `style` there applies
42
+ * over the container's own.
43
+ */
44
+ declare function Container({ maxInlineSize, padding, style, ...props }: ContainerProps): import("react").JSX.Element;
45
+ //#endregion
46
+ export { Container, type ContainerPadding, type ContainerProps };
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,85 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useWindowSizeClass } from "../../hooks/useWindowSizeClass.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { StyleSheet, View } from "react-native";
6
+ import { jsx } from "react/jsx-runtime";
7
+ //#region src/components/container/index.tsx
8
+ const DEFAULT_MAX_INLINE_SIZE = 960;
9
+ const styles = StyleSheet.create({ root: {
10
+ alignSelf: "center",
11
+ width: "100%"
12
+ } });
13
+ const stylesOf = themedStyles(({ spacing }) => StyleSheet.create({
14
+ compact: { paddingHorizontal: spacing.lg },
15
+ none: { paddingHorizontal: 0 },
16
+ wider: { paddingHorizontal: spacing.xl }
17
+ }));
18
+ /**
19
+ * A centred measure for a screen or a section of one: content grows to a
20
+ * width and stops, with the leftover space split evenly either side.
21
+ *
22
+ * ```tsx
23
+ * <Container maxInlineSize={600}>
24
+ * <Text>Supporting line</Text>
25
+ * </Container>
26
+ * ```
27
+ *
28
+ * Layout only: it paints no surface and gives its children no container of
29
+ * their own, which is what separates it from Card. It sets no gaps either, so
30
+ * reach for Stack inside it for the rhythm between sections.
31
+ *
32
+ * `style`, `ref` and `testID` land on the `View`, and a `style` there applies
33
+ * over the container's own.
34
+ */
35
+ function Container(t0) {
36
+ const $ = c(9);
37
+ let props;
38
+ let style;
39
+ let t1;
40
+ let t2;
41
+ if ($[0] !== t0) {
42
+ ({maxInlineSize: t1, padding: t2, style, ...props} = t0);
43
+ $[0] = t0;
44
+ $[1] = props;
45
+ $[2] = style;
46
+ $[3] = t1;
47
+ $[4] = t2;
48
+ } else {
49
+ props = $[1];
50
+ style = $[2];
51
+ t1 = $[3];
52
+ t2 = $[4];
53
+ }
54
+ const maxInlineSize = t1 === void 0 ? DEFAULT_MAX_INLINE_SIZE : t1;
55
+ const padding = t2 === void 0 ? "default" : t2;
56
+ const own = stylesOf(useTheme());
57
+ const sizeClass = useWindowSizeClass();
58
+ const padded = padding === "none" ? own.none : sizeClass === "compact" ? own.compact : own.wider;
59
+ const T0 = View;
60
+ const t3 = composeStyles(styles.root, measureOf(maxInlineSize), padded, style);
61
+ let t4;
62
+ if ($[5] !== T0 || $[6] !== props || $[7] !== t3) {
63
+ t4 = /* @__PURE__ */ jsx(T0, {
64
+ ...props,
65
+ style: t3
66
+ });
67
+ $[5] = T0;
68
+ $[6] = props;
69
+ $[7] = t3;
70
+ $[8] = t4;
71
+ } else t4 = $[8];
72
+ return t4;
73
+ }
74
+ /**
75
+ * The measure as a style. Built by a call rather than written inline, which
76
+ * is what react-perf's jsx-no-new-object-as-prop is after; the React Compiler
77
+ * memoises the result on its input.
78
+ */
79
+ function measureOf(maxWidth) {
80
+ return { maxWidth };
81
+ }
82
+ //#endregion
83
+ export { Container };
84
+
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","ViewProps","ViewStyle","StyleSheet","View","useWindowSizeClass","useTheme","composeStyles","themedStyles","DEFAULT_MAX_INLINE_SIZE","styles","create","root","alignSelf","width","stylesOf","spacing","compact","paddingHorizontal","lg","none","wider","xl","ContainerPadding","ContainerProps","maxInlineSize","padding","ref","Container","t0","$","_c","props","style","t1","t2","undefined","own","sizeClass","padded","T0","t3","measureOf","t4","maxWidth","_c"],"sources":["../../../src/components/container/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { ViewProps, ViewStyle } from 'react-native'\n\nimport { StyleSheet, View } from 'react-native'\n\nimport { useWindowSizeClass } from '../../hooks/useWindowSizeClass'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\n\n// The measure kanso-ui's Container takes by default, the width its own story\n// files centre their page on. A measure is a property of the content: 960dp\n// suits a page of mixed components, and prose wants something narrower. Say\n// which one you mean rather than taking this.\nconst DEFAULT_MAX_INLINE_SIZE = 960\n\n// No Material Design page draws a page container; the layout pages give the\n// margins one keeps. The gutter is the margin those pages give a window of\n// each size, 16dp while the window is compact and 24dp from medium up, read\n// off the window's size class as web reads it off a media query. The measure\n// is the call site's, since the pages leave a pane's width to its content.\n//\n// The container fills the width it is given up to its measure and stands in\n// the middle of what is left, `alignSelf` doing what web's `marginInline:\n// auto` does, so it centres in a column whatever the column aligns its other\n// children to.\nconst styles = StyleSheet.create({\n root: {\n alignSelf: 'center',\n width: '100%',\n },\n})\n\nconst stylesOf = themedStyles(({ spacing }) =>\n StyleSheet.create({\n compact: {\n paddingHorizontal: spacing.lg,\n },\n none: {\n paddingHorizontal: 0,\n },\n wider: {\n paddingHorizontal: spacing.xl,\n },\n }),\n)\n\ntype ContainerPadding = 'default' | 'none'\n\ntype ContainerProps = ViewProps & {\n /**\n * How wide the content may run before it stops growing, in dp or as a\n * share of the width it is given. The container stands in the middle of\n * whatever is left over.\n *\n * Worth setting. The default suits a page of mixed components; prose wants\n * a narrower measure, since what makes a line hard to read is how many\n * characters it holds.\n * @default 960\n */\n readonly maxInlineSize?: `${number}%` | number\n /**\n * Horizontal padding, which is what keeps the content off the edge of the\n * window once it is narrower than the measure: 16dp in a compact window and\n * 24dp from medium up. `none` is for a container nested inside one that\n * already has it.\n * @default 'default'\n */\n readonly padding?: ContainerPadding\n readonly ref?: Ref<ComponentRef<typeof View>>\n}\n\n/**\n * A centred measure for a screen or a section of one: content grows to a\n * width and stops, with the leftover space split evenly either side.\n *\n * ```tsx\n * <Container maxInlineSize={600}>\n * <Text>Supporting line</Text>\n * </Container>\n * ```\n *\n * Layout only: it paints no surface and gives its children no container of\n * their own, which is what separates it from Card. It sets no gaps either, so\n * reach for Stack inside it for the rhythm between sections.\n *\n * `style`, `ref` and `testID` land on the `View`, and a `style` there applies\n * over the container's own.\n */\nfunction Container({\n maxInlineSize = DEFAULT_MAX_INLINE_SIZE,\n padding = 'default',\n style,\n ...props\n}: ContainerProps) {\n const own = stylesOf(useTheme())\n const sizeClass = useWindowSizeClass()\n const padded =\n padding === 'none'\n ? own.none\n : sizeClass === 'compact'\n ? own.compact\n : own.wider\n\n return (\n <View\n {...props}\n style={composeStyles<ViewStyle>(\n styles.root,\n measureOf(maxInlineSize),\n padded,\n style,\n )}\n />\n )\n}\n\n/**\n * The measure as a style. Built by a call rather than written inline, which\n * is what react-perf's jsx-no-new-object-as-prop is after; the React Compiler\n * memoises the result on its input.\n */\nfunction measureOf(maxWidth: ContainerProps['maxInlineSize']): ViewStyle {\n return { maxWidth }\n}\n\nexport type { ContainerPadding, ContainerProps }\n\nexport { Container }\n"],"mappings":";;;;;;;AAaA,MAAMU,0BAA0B;AAYhC,MAAMC,SAASP,WAAWQ,OAAO,EAC/BC,MAAM;CACJC,WAAW;CACXC,OAAO;AACT,EACF,CAAC;AAED,MAAMC,WAAWP,cAAc,EAAEQ,cAC/Bb,WAAWQ,OAAO;CAChBM,SAAS,EACPC,mBAAmBF,QAAQG,GAC7B;CACAC,MAAM,EACJF,mBAAmB,EACrB;CACAG,OAAO,EACLH,mBAAmBF,QAAQM,GAC7B;AACF,CAAC,CACH;;;;;;;;;;;;;;;;;;AA4CA,SAAAM,UAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAD,IAAA;EAAmB,CAAA,CAAAJ,eAAAS,IAAAR,SAAAS,IAAAF,OAAA,GAAAD,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;CAJf,MAAAL,gBAAAS,OAAAE,KAAAA,IAAA3B,0BAAAyB;CACA,MAAAR,UAAAS,OAAAC,KAAAA,IAAA,YAAAD;CAIA,MAAAE,MAAYtB,SAAST,SAAS,CAAC;CAC/B,MAAAgC,YAAkBjC,mBAAmB;CACrC,MAAAkC,SACEb,YAAY,SACRW,IAAGjB,OACHkB,cAAc,YACZD,IAAGpB,UACHoB,IAAGhB;CAGR,MAAAmB,KAAApC;CAEQ,MAAAqC,KAAAlC,cACLG,OAAME,MACN8B,UAAUjB,aAAa,GACvBc,QACAN,KACF;CAAC,IAAAU;CAAA,IAAAb,EAAA,OAAAU,MAAAV,EAAA,OAAAE,SAAAF,EAAA,OAAAW,IAAA;EAPHE,KAAA,oBAAC,IAAD;GAAK,GACCX;GACG,OAAAS;EAKN,CAAA;EACDX,EAAA,KAAAU;EAAAV,EAAA,KAAAE;EAAAF,EAAA,KAAAW;EAAAX,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,OARFa;AAQE;;;;;;AASN,SAASD,UAAUE,UAAsD;CACvE,OAAO,EAAEA,SAAS;AACpB"}