@dloizides/ui-forms 1.5.0 → 1.7.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.
- package/CHANGELOG.md +88 -0
- package/README.md +107 -75
- package/dist/index.d.mts +182 -10
- package/dist/index.d.ts +182 -10
- package/dist/index.js +260 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +249 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +110 -108
package/dist/index.mjs
CHANGED
|
@@ -1,45 +1,116 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, { useState, useCallback, useMemo } from 'react';
|
|
2
2
|
import { StyleSheet, Platform, TextInput, View, Text, Switch, Pressable, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { useUi } from '@dloizides/ui-feedback';
|
|
4
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
import { Button } from '@dloizides/ui-buttons';
|
|
5
6
|
|
|
6
7
|
// src/Field/Field.tsx
|
|
8
|
+
function FieldLabel({
|
|
9
|
+
label,
|
|
10
|
+
marker,
|
|
11
|
+
optionalLabel,
|
|
12
|
+
style,
|
|
13
|
+
requiredMarkStyle,
|
|
14
|
+
optionalMarkStyle
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ jsxs(Text, { style, children: [
|
|
17
|
+
label,
|
|
18
|
+
" ",
|
|
19
|
+
marker === "required" ? (
|
|
20
|
+
// The asterisk is decorative — the control's `aria-required` conveys "required" to
|
|
21
|
+
// assistive tech, so a screen reader says "required" instead of "star".
|
|
22
|
+
/* @__PURE__ */ jsx(Text, { "aria-hidden": true, accessibilityElementsHidden: true, importantForAccessibility: "no", style: requiredMarkStyle, children: "*" })
|
|
23
|
+
) : null,
|
|
24
|
+
marker === "optional" && optionalLabel !== "" ? (
|
|
25
|
+
// Also decorative: "optional" is the ABSENCE of `aria-required`, which assistive tech
|
|
26
|
+
// already conveys. Rendering it to a screen reader would double-announce the same fact.
|
|
27
|
+
/* @__PURE__ */ jsx(Text, { "aria-hidden": true, accessibilityElementsHidden: true, importantForAccessibility: "no", style: optionalMarkStyle, children: optionalLabel })
|
|
28
|
+
) : null
|
|
29
|
+
] });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/Field/fieldMarkers.ts
|
|
33
|
+
var DEFAULT_OPTIONAL_LABEL = "(optional)";
|
|
34
|
+
function resolveFieldMarker(required, optional) {
|
|
35
|
+
if (required) return "required";
|
|
36
|
+
if (optional) return "optional";
|
|
37
|
+
return "none";
|
|
38
|
+
}
|
|
39
|
+
var FIELD_FONT_SIZE = 13;
|
|
40
|
+
var FIELD_FONT_WEIGHT = "600";
|
|
41
|
+
var CONTROL_FONT_SIZE = 11;
|
|
42
|
+
var CONTROL_FONT_WEIGHT = "700";
|
|
43
|
+
var CONTROL_LETTER_SPACING = 0.4;
|
|
44
|
+
var labelVariantStyles = StyleSheet.create({
|
|
45
|
+
field: {
|
|
46
|
+
fontSize: FIELD_FONT_SIZE,
|
|
47
|
+
fontWeight: FIELD_FONT_WEIGHT
|
|
48
|
+
},
|
|
49
|
+
control: {
|
|
50
|
+
fontSize: CONTROL_FONT_SIZE,
|
|
51
|
+
fontWeight: CONTROL_FONT_WEIGHT,
|
|
52
|
+
letterSpacing: CONTROL_LETTER_SPACING,
|
|
53
|
+
textTransform: "uppercase"
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
function resolveLabelVariantStyle(variant) {
|
|
57
|
+
return variant === "control" ? labelVariantStyles.control : labelVariantStyles.field;
|
|
58
|
+
}
|
|
7
59
|
var CONTAINER_MARGIN_BOTTOM = 16;
|
|
8
|
-
var LABEL_FONT_SIZE = 13;
|
|
9
|
-
var LABEL_FONT_WEIGHT = "600";
|
|
10
60
|
var LABEL_MARGIN_BOTTOM = 4;
|
|
11
61
|
var ERROR_FONT_SIZE = 12;
|
|
12
62
|
var ERROR_MARGIN_TOP = 4;
|
|
63
|
+
var HINT_FONT_SIZE = 12;
|
|
64
|
+
var HINT_MARGIN_TOP = 4;
|
|
65
|
+
var OPTIONAL_MARK_FONT_WEIGHT = "400";
|
|
13
66
|
var styles = StyleSheet.create({
|
|
14
67
|
container: {
|
|
15
68
|
marginBottom: CONTAINER_MARGIN_BOTTOM
|
|
16
69
|
},
|
|
17
70
|
label: {
|
|
18
|
-
marginBottom: LABEL_MARGIN_BOTTOM
|
|
19
|
-
|
|
20
|
-
|
|
71
|
+
marginBottom: LABEL_MARGIN_BOTTOM
|
|
72
|
+
},
|
|
73
|
+
hintText: {
|
|
74
|
+
fontSize: HINT_FONT_SIZE,
|
|
75
|
+
marginTop: HINT_MARGIN_TOP
|
|
21
76
|
},
|
|
22
77
|
errorText: {
|
|
23
78
|
fontSize: ERROR_FONT_SIZE,
|
|
24
79
|
marginTop: ERROR_MARGIN_TOP
|
|
80
|
+
},
|
|
81
|
+
optionalMark: {
|
|
82
|
+
fontWeight: OPTIONAL_MARK_FONT_WEIGHT
|
|
25
83
|
}
|
|
26
84
|
});
|
|
27
85
|
var fieldSeq = 0;
|
|
28
|
-
function
|
|
29
|
-
const [
|
|
86
|
+
function useFieldIds() {
|
|
87
|
+
const [ids] = React.useState(() => {
|
|
30
88
|
fieldSeq += 1;
|
|
31
|
-
|
|
89
|
+
const seq = String(fieldSeq);
|
|
90
|
+
return { hintId: `field-hint-${seq}`, errorId: `field-error-${seq}` };
|
|
32
91
|
});
|
|
33
|
-
return
|
|
92
|
+
return ids;
|
|
93
|
+
}
|
|
94
|
+
function isPresent(value) {
|
|
95
|
+
return typeof value === "string" && value !== "";
|
|
34
96
|
}
|
|
35
97
|
function hasFieldError(error) {
|
|
36
|
-
return
|
|
98
|
+
return isPresent(error);
|
|
99
|
+
}
|
|
100
|
+
function joinDescribedBy(hintId, errorId) {
|
|
101
|
+
const ids = [hintId, errorId].filter((id) => isPresent(id));
|
|
102
|
+
return ids.length > 0 ? ids.join(" ") : void 0;
|
|
37
103
|
}
|
|
38
104
|
var Field = ({
|
|
39
105
|
label,
|
|
40
106
|
children,
|
|
41
107
|
required = false,
|
|
108
|
+
optional = false,
|
|
109
|
+
optionalLabel = DEFAULT_OPTIONAL_LABEL,
|
|
110
|
+
hint,
|
|
42
111
|
error,
|
|
112
|
+
labelVariant,
|
|
113
|
+
labelStyle,
|
|
43
114
|
containerStyle,
|
|
44
115
|
testID
|
|
45
116
|
}) => {
|
|
@@ -47,30 +118,89 @@ var Field = ({
|
|
|
47
118
|
const { colors, semantic } = theme;
|
|
48
119
|
const errorColor = semantic.error["500"];
|
|
49
120
|
const hasError = hasFieldError(error);
|
|
50
|
-
const
|
|
51
|
-
const
|
|
121
|
+
const hasHint = isPresent(hint);
|
|
122
|
+
const labelText = label ?? "";
|
|
123
|
+
const hasLabel = labelText !== "";
|
|
124
|
+
const marker = resolveFieldMarker(required, optional);
|
|
125
|
+
const { hintId, errorId } = useFieldIds();
|
|
126
|
+
const themeStyles = React.useMemo(
|
|
52
127
|
() => ({
|
|
53
128
|
label: { color: colors.textSecondary },
|
|
54
129
|
requiredMark: { color: errorColor },
|
|
130
|
+
// The optional marker is an aside, so it sits a step back from the label's own ink.
|
|
131
|
+
optionalMark: { color: colors.textSecondary },
|
|
132
|
+
hintText: { color: colors.textSecondary },
|
|
55
133
|
errorText: { color: errorColor }
|
|
56
134
|
}),
|
|
57
135
|
[colors.textSecondary, errorColor]
|
|
58
136
|
);
|
|
59
|
-
const
|
|
137
|
+
const describedById = joinDescribedBy(hasHint ? hintId : void 0, hasError ? errorId : void 0);
|
|
138
|
+
const control = typeof children === "function" ? children({ describedById, hasError }) : children;
|
|
60
139
|
return /* @__PURE__ */ jsxs(View, { style: [styles.container, containerStyle], testID, children: [
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
140
|
+
hasLabel ? /* @__PURE__ */ jsx(
|
|
141
|
+
FieldLabel,
|
|
142
|
+
{
|
|
143
|
+
label: labelText,
|
|
144
|
+
marker,
|
|
145
|
+
optionalLabel,
|
|
146
|
+
optionalMarkStyle: [styles.optionalMark, themeStyles.optionalMark],
|
|
147
|
+
requiredMarkStyle: themeStyles.requiredMark,
|
|
148
|
+
style: [styles.label, resolveLabelVariantStyle(labelVariant), themeStyles.label, labelStyle]
|
|
149
|
+
}
|
|
150
|
+
) : null,
|
|
70
151
|
control,
|
|
152
|
+
hasHint ? /* @__PURE__ */ jsx(Text, { nativeID: hintId, style: [styles.hintText, themeStyles.hintText], children: hint }) : null,
|
|
71
153
|
hasError ? /* @__PURE__ */ jsx(Text, { nativeID: errorId, role: "alert", style: [styles.errorText, themeStyles.errorText], children: error }) : null
|
|
72
154
|
] });
|
|
73
155
|
};
|
|
156
|
+
var ACTIONS_GAP = 12;
|
|
157
|
+
var styles2 = StyleSheet.create({
|
|
158
|
+
container: {
|
|
159
|
+
flexDirection: "row",
|
|
160
|
+
justifyContent: "flex-end",
|
|
161
|
+
gap: ACTIONS_GAP
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
var FormActions = ({
|
|
165
|
+
onSave,
|
|
166
|
+
onCancel,
|
|
167
|
+
saveLabel,
|
|
168
|
+
cancelLabel = "",
|
|
169
|
+
saveHint,
|
|
170
|
+
cancelHint,
|
|
171
|
+
saving = false,
|
|
172
|
+
saveDisabled = false,
|
|
173
|
+
containerStyle,
|
|
174
|
+
saveTestID = "save-button",
|
|
175
|
+
cancelTestID = "cancel-button",
|
|
176
|
+
testID
|
|
177
|
+
}) => /* @__PURE__ */ jsxs(View, { style: [styles2.container, containerStyle], testID, children: [
|
|
178
|
+
typeof onCancel === "function" ? /* @__PURE__ */ jsx(
|
|
179
|
+
Button,
|
|
180
|
+
{
|
|
181
|
+
accessibilityHint: cancelHint ?? cancelLabel,
|
|
182
|
+
accessibilityLabel: cancelLabel,
|
|
183
|
+
disabled: saving,
|
|
184
|
+
label: cancelLabel,
|
|
185
|
+
testID: cancelTestID,
|
|
186
|
+
variant: "outline",
|
|
187
|
+
onPress: onCancel
|
|
188
|
+
}
|
|
189
|
+
) : null,
|
|
190
|
+
/* @__PURE__ */ jsx(
|
|
191
|
+
Button,
|
|
192
|
+
{
|
|
193
|
+
accessibilityHint: saveHint ?? saveLabel,
|
|
194
|
+
accessibilityLabel: saveLabel,
|
|
195
|
+
disabled: saveDisabled,
|
|
196
|
+
label: saveLabel,
|
|
197
|
+
loading: saving,
|
|
198
|
+
testID: saveTestID,
|
|
199
|
+
variant: "primary",
|
|
200
|
+
onPress: onSave
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
] });
|
|
74
204
|
var IS_WEB = Platform.OS === "web";
|
|
75
205
|
var TRANSITION_PROPERTY = "border-color, background-color, box-shadow";
|
|
76
206
|
var TRANSITION_DURATION = "0.14s";
|
|
@@ -130,7 +260,8 @@ function useThemedInput(options = {}) {
|
|
|
130
260
|
const backgroundColor = isFocused ? colors.surface : colors.surfaceElevated;
|
|
131
261
|
const base = { color: colors.text, borderColor, backgroundColor };
|
|
132
262
|
if (!IS_WEB) return base;
|
|
133
|
-
const
|
|
263
|
+
const ringColor = hasError ? errorColor : primary;
|
|
264
|
+
const ring = isFocused ? `0 0 0 ${FOCUS_RING_WIDTH}px ${withAlpha(ringColor, FOCUS_RING_ALPHA)}` : "none";
|
|
134
265
|
const webStyle = {
|
|
135
266
|
transitionProperty: TRANSITION_PROPERTY,
|
|
136
267
|
// Collapse the eased transition to instant when the user prefers reduced motion.
|
|
@@ -166,7 +297,7 @@ function useThemedInput(options = {}) {
|
|
|
166
297
|
};
|
|
167
298
|
}
|
|
168
299
|
var IS_WEB2 = Platform.OS === "web";
|
|
169
|
-
var ThemedTextInput =
|
|
300
|
+
var ThemedTextInput = React.forwardRef(function ThemedTextInput2({ hasError = false, describedById, requiredField = false, onFocus, onBlur, style, placeholderTextColor, ...rest }, ref) {
|
|
170
301
|
const {
|
|
171
302
|
style: themedStyle,
|
|
172
303
|
placeholderTextColor: themedPlaceholder,
|
|
@@ -196,7 +327,7 @@ var INPUT_PADDING_V = 10;
|
|
|
196
327
|
var INPUT_PADDING_H = 12;
|
|
197
328
|
var INPUT_BORDER_RADIUS = 8;
|
|
198
329
|
var INPUT_BORDER_WIDTH = 1;
|
|
199
|
-
var
|
|
330
|
+
var styles3 = StyleSheet.create({
|
|
200
331
|
input: {
|
|
201
332
|
paddingVertical: INPUT_PADDING_V,
|
|
202
333
|
paddingHorizontal: INPUT_PADDING_H,
|
|
@@ -218,7 +349,7 @@ var FormField = ({
|
|
|
218
349
|
describedById,
|
|
219
350
|
hasError,
|
|
220
351
|
requiredField: required,
|
|
221
|
-
style:
|
|
352
|
+
style: styles3.input,
|
|
222
353
|
testID: "form-field-input",
|
|
223
354
|
...textInputProps
|
|
224
355
|
}
|
|
@@ -238,6 +369,14 @@ var RGB_R_END = 2;
|
|
|
238
369
|
var RGB_G_END = 4;
|
|
239
370
|
var RGB_B_END = 6;
|
|
240
371
|
var CHIP_HIT_SLOP = { top: 10, bottom: 10, left: 4, right: 4 };
|
|
372
|
+
var CHIP_GUTTER = 8;
|
|
373
|
+
var DEFAULT_CHIP_TESTID_PREFIX = "chip-selector-chip";
|
|
374
|
+
var ON_BRAND_SCALE = "onBrand";
|
|
375
|
+
var MAIN_STEP = "500";
|
|
376
|
+
function onBrandInk(palette) {
|
|
377
|
+
const scales = palette;
|
|
378
|
+
return scales[ON_BRAND_SCALE]?.[MAIN_STEP] ?? WHITE_COLOR;
|
|
379
|
+
}
|
|
241
380
|
function withAlpha2(hex, alpha) {
|
|
242
381
|
const normalized = hex.replace("#", "");
|
|
243
382
|
const isShort = normalized.length === HEX_SHORT_LENGTH2;
|
|
@@ -248,18 +387,18 @@ function withAlpha2(hex, alpha) {
|
|
|
248
387
|
const isValid = !Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b);
|
|
249
388
|
return isValid ? `rgba(${r}, ${g}, ${b}, ${alpha})` : hex;
|
|
250
389
|
}
|
|
251
|
-
var
|
|
252
|
-
label: {
|
|
253
|
-
marginBottom: 8,
|
|
254
|
-
fontWeight: "600"
|
|
255
|
-
},
|
|
390
|
+
var styles4 = StyleSheet.create({
|
|
256
391
|
chipContainer: {
|
|
257
392
|
flexDirection: "row",
|
|
258
|
-
flexWrap: "wrap"
|
|
393
|
+
flexWrap: "wrap",
|
|
394
|
+
// Each chip's bottom gutter also hangs off the LAST row, stacking on `Field`'s container
|
|
395
|
+
// margin (8 + 16 = 24) and dropping the block below the `FormField` beside it. Cancelling it
|
|
396
|
+
// is standard gutter compensation: inner rows keep their 8px, the block ends at Field's 16.
|
|
397
|
+
marginBottom: -CHIP_GUTTER
|
|
259
398
|
},
|
|
260
399
|
chipWrapper: {
|
|
261
|
-
marginRight:
|
|
262
|
-
marginBottom:
|
|
400
|
+
marginRight: CHIP_GUTTER,
|
|
401
|
+
marginBottom: CHIP_GUTTER
|
|
263
402
|
},
|
|
264
403
|
chip: {
|
|
265
404
|
paddingHorizontal: 12,
|
|
@@ -277,14 +416,26 @@ var styles3 = StyleSheet.create({
|
|
|
277
416
|
chipText: {},
|
|
278
417
|
chipTextOutline: { fontSize: OUTLINE_FONT_SIZE }
|
|
279
418
|
});
|
|
419
|
+
function chipIdentity(option, selected, config) {
|
|
420
|
+
return {
|
|
421
|
+
testID: `${config.prefix}-${String(option.value)}`,
|
|
422
|
+
// The English default is retained verbatim: erevna/katalogos assert the exact string
|
|
423
|
+
// `Selects Red`. Consumers that localize pass `optionAccessibilityHint`.
|
|
424
|
+
accessibilityHint: config.hint ?? `Selects ${option.label}`,
|
|
425
|
+
ariaPressed: config.multiple ? selected : void 0
|
|
426
|
+
};
|
|
427
|
+
}
|
|
280
428
|
function OutlineChip({
|
|
281
429
|
option,
|
|
282
430
|
selected,
|
|
283
431
|
disabled,
|
|
284
432
|
colors,
|
|
433
|
+
testID,
|
|
434
|
+
accessibilityHint,
|
|
435
|
+
ariaPressed,
|
|
285
436
|
onPress
|
|
286
437
|
}) {
|
|
287
|
-
const [hovered, setHovered] =
|
|
438
|
+
const [hovered, setHovered] = React.useState(false);
|
|
288
439
|
const active = selected || hovered;
|
|
289
440
|
const borderColor = active ? colors.primary : colors.border;
|
|
290
441
|
const backgroundColor = selected ? colors.tint : colors.muted;
|
|
@@ -292,18 +443,19 @@ function OutlineChip({
|
|
|
292
443
|
return /* @__PURE__ */ jsx(
|
|
293
444
|
Pressable,
|
|
294
445
|
{
|
|
295
|
-
accessibilityHint
|
|
446
|
+
accessibilityHint,
|
|
296
447
|
accessibilityLabel: option.label,
|
|
297
448
|
accessibilityRole: "button",
|
|
298
449
|
accessibilityState: { selected, disabled },
|
|
450
|
+
"aria-pressed": ariaPressed,
|
|
299
451
|
disabled,
|
|
300
452
|
hitSlop: CHIP_HIT_SLOP,
|
|
301
|
-
style:
|
|
302
|
-
testID
|
|
453
|
+
style: styles4.chipWrapper,
|
|
454
|
+
testID,
|
|
303
455
|
onHoverIn: () => setHovered(true),
|
|
304
456
|
onHoverOut: () => setHovered(false),
|
|
305
457
|
onPress,
|
|
306
|
-
children: /* @__PURE__ */ jsx(View, { style: [
|
|
458
|
+
children: /* @__PURE__ */ jsx(View, { style: [styles4.chipOutline, { borderColor, backgroundColor }], children: /* @__PURE__ */ jsx(Text, { style: [styles4.chipText, styles4.chipTextOutline, { color: textColor }], children: option.label }) })
|
|
307
459
|
}
|
|
308
460
|
);
|
|
309
461
|
}
|
|
@@ -312,26 +464,35 @@ function SolidChip({
|
|
|
312
464
|
selected,
|
|
313
465
|
disabled,
|
|
314
466
|
colors,
|
|
467
|
+
testID,
|
|
468
|
+
accessibilityHint,
|
|
469
|
+
ariaPressed,
|
|
315
470
|
onPress
|
|
316
471
|
}) {
|
|
317
472
|
const backgroundColor = selected ? colors.primary : TRANSPARENT_COLOR;
|
|
318
|
-
const textColor = selected ?
|
|
473
|
+
const textColor = selected ? colors.onPrimary : colors.textStrong;
|
|
319
474
|
return /* @__PURE__ */ jsx(
|
|
320
475
|
TouchableOpacity,
|
|
321
476
|
{
|
|
322
|
-
accessibilityHint
|
|
477
|
+
accessibilityHint,
|
|
323
478
|
accessibilityLabel: option.label,
|
|
324
479
|
accessibilityRole: "button",
|
|
325
480
|
accessibilityState: { selected, disabled },
|
|
481
|
+
"aria-pressed": ariaPressed,
|
|
326
482
|
disabled,
|
|
327
483
|
hitSlop: CHIP_HIT_SLOP,
|
|
328
|
-
style:
|
|
329
|
-
testID
|
|
484
|
+
style: styles4.chipWrapper,
|
|
485
|
+
testID,
|
|
330
486
|
onPress,
|
|
331
|
-
children: /* @__PURE__ */ jsx(View, { style: [
|
|
487
|
+
children: /* @__PURE__ */ jsx(View, { style: [styles4.chip, { borderColor: colors.border, backgroundColor }], children: /* @__PURE__ */ jsx(Text, { style: [styles4.chipText, { color: textColor }], children: option.label }) })
|
|
332
488
|
}
|
|
333
489
|
);
|
|
334
490
|
}
|
|
491
|
+
var IS_WEB3 = Platform.OS === "web";
|
|
492
|
+
function groupA11yProps(describedById, hasError) {
|
|
493
|
+
if (!IS_WEB3) return {};
|
|
494
|
+
return { "aria-invalid": hasError ? true : void 0, "aria-describedby": describedById };
|
|
495
|
+
}
|
|
335
496
|
var ChipSelector = ({
|
|
336
497
|
label,
|
|
337
498
|
options,
|
|
@@ -340,59 +501,53 @@ var ChipSelector = ({
|
|
|
340
501
|
multiple = false,
|
|
341
502
|
disabled = false,
|
|
342
503
|
variant = "solid",
|
|
343
|
-
containerStyle
|
|
504
|
+
containerStyle,
|
|
505
|
+
required = false,
|
|
506
|
+
error,
|
|
507
|
+
testID,
|
|
508
|
+
chipTestIDPrefix = DEFAULT_CHIP_TESTID_PREFIX,
|
|
509
|
+
optionAccessibilityHint
|
|
344
510
|
}) => {
|
|
345
511
|
const { theme } = useUi();
|
|
346
512
|
const { colors, palette } = theme;
|
|
347
|
-
const
|
|
348
|
-
const chipColors = React3.useMemo(() => {
|
|
513
|
+
const chipColors = React.useMemo(() => {
|
|
349
514
|
const primary = palette.primary["500"];
|
|
350
515
|
return {
|
|
351
516
|
border: colors.border,
|
|
352
517
|
textStrong: colors.text,
|
|
353
518
|
textMuted: colors.textSecondary,
|
|
354
519
|
primary,
|
|
520
|
+
onPrimary: onBrandInk(palette),
|
|
355
521
|
muted: colors.background,
|
|
356
522
|
tint: withAlpha2(primary, OUTLINE_TINT_ALPHA)
|
|
357
523
|
};
|
|
358
|
-
}, [colors.border, colors.text, colors.textSecondary, colors.background, palette
|
|
359
|
-
const labelStyle = React3.useMemo(() => ({ color: colors.text }), [colors.text]);
|
|
524
|
+
}, [colors.border, colors.text, colors.textSecondary, colors.background, palette]);
|
|
360
525
|
function isSelected(optionValue) {
|
|
361
526
|
if (multiple && Array.isArray(value))
|
|
362
527
|
return value.includes(optionValue);
|
|
363
528
|
return value === optionValue;
|
|
364
529
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
colors: chipColors,
|
|
384
|
-
disabled,
|
|
385
|
-
option,
|
|
386
|
-
selected,
|
|
387
|
-
onPress
|
|
388
|
-
},
|
|
389
|
-
String(option.value)
|
|
390
|
-
);
|
|
391
|
-
}) })
|
|
392
|
-
] });
|
|
530
|
+
function renderChip(option) {
|
|
531
|
+
const selected = isSelected(option.value);
|
|
532
|
+
const chipProps = {
|
|
533
|
+
colors: chipColors,
|
|
534
|
+
disabled,
|
|
535
|
+
option,
|
|
536
|
+
selected,
|
|
537
|
+
...chipIdentity(option, selected, {
|
|
538
|
+
prefix: chipTestIDPrefix,
|
|
539
|
+
hint: optionAccessibilityHint,
|
|
540
|
+
multiple
|
|
541
|
+
}),
|
|
542
|
+
onPress: () => onChange(option.value)
|
|
543
|
+
};
|
|
544
|
+
const key = String(option.value);
|
|
545
|
+
return variant === "outline" ? /* @__PURE__ */ jsx(OutlineChip, { ...chipProps }, key) : /* @__PURE__ */ jsx(SolidChip, { ...chipProps }, key);
|
|
546
|
+
}
|
|
547
|
+
return /* @__PURE__ */ jsx(Field, { containerStyle, error, label, required, testID, children: ({ describedById, hasError }) => /* @__PURE__ */ jsx(View, { style: styles4.chipContainer, ...groupA11yProps(describedById, hasError), children: options.map(renderChip) }) });
|
|
393
548
|
};
|
|
394
549
|
var DESCRIPTION_FONT_SIZE = 12;
|
|
395
|
-
var
|
|
550
|
+
var styles5 = StyleSheet.create({
|
|
396
551
|
container: {
|
|
397
552
|
flexDirection: "row",
|
|
398
553
|
justifyContent: "space-between",
|
|
@@ -423,7 +578,7 @@ var FormSwitch = ({
|
|
|
423
578
|
const { theme } = useUi();
|
|
424
579
|
const { colors } = theme;
|
|
425
580
|
const hasDescription = typeof description === "string" && description !== "";
|
|
426
|
-
const themeStyles =
|
|
581
|
+
const themeStyles = React.useMemo(() => {
|
|
427
582
|
const labelStyle = { color: colors.text };
|
|
428
583
|
const descriptionStyle = { color: colors.textSecondary };
|
|
429
584
|
return { label: labelStyle, description: descriptionStyle };
|
|
@@ -432,13 +587,13 @@ var FormSwitch = ({
|
|
|
432
587
|
View,
|
|
433
588
|
{
|
|
434
589
|
style: [
|
|
435
|
-
|
|
590
|
+
styles5.container,
|
|
436
591
|
containerStyle
|
|
437
592
|
],
|
|
438
593
|
children: [
|
|
439
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
440
|
-
/* @__PURE__ */ jsx(Text, { style: [
|
|
441
|
-
hasDescription ? /* @__PURE__ */ jsx(Text, { style: [
|
|
594
|
+
/* @__PURE__ */ jsxs(View, { style: styles5.textColumn, children: [
|
|
595
|
+
/* @__PURE__ */ jsx(Text, { style: [styles5.label, themeStyles.label], children: label }),
|
|
596
|
+
hasDescription ? /* @__PURE__ */ jsx(Text, { style: [styles5.description, themeStyles.description], children: description }) : null
|
|
442
597
|
] }),
|
|
443
598
|
/* @__PURE__ */ jsx(
|
|
444
599
|
Switch,
|
|
@@ -458,12 +613,12 @@ var FormSwitch = ({
|
|
|
458
613
|
);
|
|
459
614
|
};
|
|
460
615
|
var ACTIVATION_KEYS = ["Enter", " ", "Spacebar"];
|
|
461
|
-
var
|
|
616
|
+
var HINT_FONT_SIZE2 = 12;
|
|
462
617
|
var BOX_SIZE = 20;
|
|
463
618
|
var BOX_RADIUS = 5;
|
|
464
619
|
var CHECK_FONT_SIZE = 14;
|
|
465
620
|
var DISABLED_OPACITY = 0.5;
|
|
466
|
-
var
|
|
621
|
+
var styles6 = StyleSheet.create({
|
|
467
622
|
container: {
|
|
468
623
|
flexDirection: "row",
|
|
469
624
|
alignItems: "flex-start",
|
|
@@ -492,7 +647,7 @@ var styles5 = StyleSheet.create({
|
|
|
492
647
|
fontWeight: "600"
|
|
493
648
|
},
|
|
494
649
|
hint: {
|
|
495
|
-
fontSize:
|
|
650
|
+
fontSize: HINT_FONT_SIZE2,
|
|
496
651
|
marginTop: 2
|
|
497
652
|
}
|
|
498
653
|
});
|
|
@@ -514,7 +669,7 @@ var FormCheckbox = ({
|
|
|
514
669
|
const brand = palette.primary["500"];
|
|
515
670
|
const hintText = typeof hint === "string" && hint !== "" ? hint : description;
|
|
516
671
|
const hasHint = typeof hintText === "string" && hintText !== "";
|
|
517
|
-
const themeStyles =
|
|
672
|
+
const themeStyles = React.useMemo(() => {
|
|
518
673
|
const boxOn = { backgroundColor: brand, borderColor: brand };
|
|
519
674
|
const boxOff = { backgroundColor: "transparent", borderColor: colors.border };
|
|
520
675
|
const labelStyle = { color: colors.text };
|
|
@@ -545,20 +700,20 @@ var FormCheckbox = ({
|
|
|
545
700
|
disabled,
|
|
546
701
|
onPress: toggle,
|
|
547
702
|
role: "checkbox",
|
|
548
|
-
style: [
|
|
703
|
+
style: [styles6.container, containerStyle, disabled ? { opacity: DISABLED_OPACITY } : null],
|
|
549
704
|
testID,
|
|
550
705
|
...keyboardProps,
|
|
551
706
|
children: [
|
|
552
|
-
/* @__PURE__ */ jsx(View, { style: [
|
|
553
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
554
|
-
/* @__PURE__ */ jsx(Text, { style: [
|
|
555
|
-
hasHint ? /* @__PURE__ */ jsx(Text, { style: [
|
|
707
|
+
/* @__PURE__ */ jsx(View, { style: [styles6.box, value ? themeStyles.boxOn : themeStyles.boxOff], children: value ? /* @__PURE__ */ jsx(Text, { style: [styles6.check, { color: colors.surface }], accessibilityElementsHidden: true, children: "\u2713" }) : null }),
|
|
708
|
+
/* @__PURE__ */ jsxs(View, { style: styles6.textColumn, children: [
|
|
709
|
+
/* @__PURE__ */ jsx(Text, { style: [styles6.label, themeStyles.label], children: label }),
|
|
710
|
+
hasHint ? /* @__PURE__ */ jsx(Text, { style: [styles6.hint, themeStyles.hint], children: hintText }) : null
|
|
556
711
|
] })
|
|
557
712
|
]
|
|
558
713
|
}
|
|
559
714
|
);
|
|
560
715
|
};
|
|
561
716
|
|
|
562
|
-
export { ChipSelector, Field, FormCheckbox, FormField, FormSwitch, ThemedTextInput, useThemedInput };
|
|
717
|
+
export { ChipSelector, DEFAULT_OPTIONAL_LABEL, Field, FormActions, FormCheckbox, FormField, FormSwitch, ThemedTextInput, useThemedInput };
|
|
563
718
|
//# sourceMappingURL=index.mjs.map
|
|
564
719
|
//# sourceMappingURL=index.mjs.map
|