@dloizides/ui-forms 1.8.0 → 1.9.1

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/dist/index.js CHANGED
@@ -42,6 +42,40 @@ function resolveFieldMarker(required, optional) {
42
42
  if (optional) return "optional";
43
43
  return "none";
44
44
  }
45
+ var FIELD_STACK_MARGIN_BOTTOM = 16;
46
+ var FIELD_STACK_LABEL_MARGIN_BOTTOM = 4;
47
+ var FIELD_STACK_CHILD_MARGIN_TOP = 4;
48
+ var FIELD_CONTRACT_GAP = 6;
49
+ var fieldSpacingStyles = reactNative.StyleSheet.create({
50
+ stackContainer: { marginBottom: FIELD_STACK_MARGIN_BOTTOM },
51
+ stackLabel: { marginBottom: FIELD_STACK_LABEL_MARGIN_BOTTOM },
52
+ stackChild: { marginTop: FIELD_STACK_CHILD_MARGIN_TOP },
53
+ /**
54
+ * The gap model sets NO margins — not even zeroed ones. An explicit `marginBottom: 0` here would
55
+ * defeat a caller who legitimately wants to push one field down via `containerStyle`, because
56
+ * `containerStyle` composes AFTER this and a zero is indistinguishable from "unset" to a reader.
57
+ */
58
+ gapContainer: { gap: FIELD_CONTRACT_GAP },
59
+ none: {}
60
+ });
61
+ function resolveFieldSpacing(explicit, insideGrid) {
62
+ if (explicit !== void 0) return explicit;
63
+ return insideGrid ? "gap" : "stack";
64
+ }
65
+ function fieldSpacingStyleSet(spacing) {
66
+ if (spacing === "gap") {
67
+ return {
68
+ container: fieldSpacingStyles.gapContainer,
69
+ label: fieldSpacingStyles.none,
70
+ child: fieldSpacingStyles.none
71
+ };
72
+ }
73
+ return {
74
+ container: fieldSpacingStyles.stackContainer,
75
+ label: fieldSpacingStyles.stackLabel,
76
+ child: fieldSpacingStyles.stackChild
77
+ };
78
+ }
45
79
  var FIELD_FONT_SIZE = 13;
46
80
  var FIELD_FONT_WEIGHT = "600";
47
81
  var CONTROL_FONT_SIZE = 11;
@@ -62,27 +96,25 @@ var labelVariantStyles = reactNative.StyleSheet.create({
62
96
  function resolveLabelVariantStyle(variant) {
63
97
  return variant === "control" ? labelVariantStyles.control : labelVariantStyles.field;
64
98
  }
65
- var CONTAINER_MARGIN_BOTTOM = 16;
66
- var LABEL_MARGIN_BOTTOM = 4;
99
+ var FormGridContext = React__default.default.createContext(null);
100
+ var GapOwnedContext = React__default.default.createContext(false);
101
+ var FormGridProvider = FormGridContext.Provider;
102
+ var GapOwnedProvider = GapOwnedContext.Provider;
103
+ function useFormGridMetrics() {
104
+ return React__default.default.useContext(FormGridContext);
105
+ }
106
+ function useIsGapOwned() {
107
+ return React__default.default.useContext(GapOwnedContext);
108
+ }
67
109
  var ERROR_FONT_SIZE = 12;
68
- var ERROR_MARGIN_TOP = 4;
69
110
  var HINT_FONT_SIZE = 12;
70
- var HINT_MARGIN_TOP = 4;
71
111
  var OPTIONAL_MARK_FONT_WEIGHT = "400";
72
112
  var styles = reactNative.StyleSheet.create({
73
- container: {
74
- marginBottom: CONTAINER_MARGIN_BOTTOM
75
- },
76
- label: {
77
- marginBottom: LABEL_MARGIN_BOTTOM
78
- },
79
113
  hintText: {
80
- fontSize: HINT_FONT_SIZE,
81
- marginTop: HINT_MARGIN_TOP
114
+ fontSize: HINT_FONT_SIZE
82
115
  },
83
116
  errorText: {
84
- fontSize: ERROR_FONT_SIZE,
85
- marginTop: ERROR_MARGIN_TOP
117
+ fontSize: ERROR_FONT_SIZE
86
118
  },
87
119
  optionalMark: {
88
120
  fontWeight: OPTIONAL_MARK_FONT_WEIGHT
@@ -118,9 +150,12 @@ var Field = ({
118
150
  labelVariant,
119
151
  labelStyle,
120
152
  containerStyle,
153
+ spacing,
121
154
  testID
122
155
  }) => {
123
156
  const { theme } = uiFeedback.useUi();
157
+ const gapOwned = useIsGapOwned();
158
+ const spacingStyles = fieldSpacingStyleSet(resolveFieldSpacing(spacing, gapOwned));
124
159
  const { colors, semantic } = theme;
125
160
  const errorColor = semantic.error["500"];
126
161
  const hasError = hasFieldError(error);
@@ -142,7 +177,7 @@ var Field = ({
142
177
  );
143
178
  const describedById = joinDescribedBy(hasHint ? hintId : void 0, hasError ? errorId : void 0);
144
179
  const control = typeof children === "function" ? children({ describedById, hasError }) : children;
145
- return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles.container, containerStyle], testID, children: [
180
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [spacingStyles.container, containerStyle], testID, children: [
146
181
  hasLabel ? /* @__PURE__ */ jsxRuntime.jsx(
147
182
  FieldLabel,
148
183
  {
@@ -151,16 +186,107 @@ var Field = ({
151
186
  optionalLabel,
152
187
  optionalMarkStyle: [styles.optionalMark, themeStyles.optionalMark],
153
188
  requiredMarkStyle: themeStyles.requiredMark,
154
- style: [styles.label, resolveLabelVariantStyle(labelVariant), themeStyles.label, labelStyle]
189
+ style: [spacingStyles.label, resolveLabelVariantStyle(labelVariant), themeStyles.label, labelStyle]
155
190
  }
156
191
  ) : null,
157
192
  control,
158
- hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: hintId, style: [styles.hintText, themeStyles.hintText], children: hint }) : null,
159
- hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: errorId, role: "alert", style: [styles.errorText, themeStyles.errorText], children: error }) : null
193
+ hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: hintId, style: [styles.hintText, spacingStyles.child, themeStyles.hintText], children: hint }) : null,
194
+ hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: errorId, role: "alert", style: [styles.errorText, spacingStyles.child, themeStyles.errorText], children: error }) : null
160
195
  ] });
161
196
  };
162
- var ACTIONS_GAP = 12;
197
+ var FORM_GRID_DEFAULT_GAP = 12;
198
+ var FORM_GRID_DEFAULT_MIN_WIDTH = 220;
199
+ var FORM_GRID_DEFAULT_BASIS = 260;
163
200
  var styles2 = reactNative.StyleSheet.create({
201
+ grid: {
202
+ flexDirection: "row",
203
+ flexWrap: "wrap"
204
+ }
205
+ });
206
+ var FormGrid = ({
207
+ children,
208
+ gap = FORM_GRID_DEFAULT_GAP,
209
+ minWidth = FORM_GRID_DEFAULT_MIN_WIDTH,
210
+ basis = FORM_GRID_DEFAULT_BASIS,
211
+ style,
212
+ testID
213
+ }) => {
214
+ const metrics = React__default.default.useMemo(() => ({ minWidth, basis }), [minWidth, basis]);
215
+ return /* @__PURE__ */ jsxRuntime.jsx(FormGridProvider, { value: metrics, children: /* @__PURE__ */ jsxRuntime.jsx(GapOwnedProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles2.grid, { gap }, style], testID, children }) }) });
216
+ };
217
+ var GROW = 1;
218
+ var NO_GROW = 0;
219
+ var FormCell = ({
220
+ children,
221
+ minWidth,
222
+ basis,
223
+ grow = true,
224
+ style,
225
+ testID
226
+ }) => {
227
+ const metrics = useFormGridMetrics();
228
+ const resolvedMinWidth = minWidth ?? metrics?.minWidth ?? FORM_GRID_DEFAULT_MIN_WIDTH;
229
+ const resolvedBasis = basis ?? metrics?.basis ?? FORM_GRID_DEFAULT_BASIS;
230
+ const cellStyle = {
231
+ minWidth: resolvedMinWidth,
232
+ flexBasis: resolvedBasis,
233
+ flexGrow: grow ? GROW : NO_GROW
234
+ };
235
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [cellStyle, style], testID, children });
236
+ };
237
+ var SECTION_GAP = 10;
238
+ var DESCRIPTION_FONT_SIZE = 12;
239
+ var styles3 = reactNative.StyleSheet.create({
240
+ section: {
241
+ gap: SECTION_GAP
242
+ },
243
+ description: {
244
+ fontSize: DESCRIPTION_FONT_SIZE
245
+ }
246
+ });
247
+ var sectionSeq = 0;
248
+ function useSectionLegendId() {
249
+ const [id] = React__default.default.useState(() => {
250
+ sectionSeq += 1;
251
+ return `form-section-legend-${String(sectionSeq)}`;
252
+ });
253
+ return id;
254
+ }
255
+ var FormSection = ({
256
+ title,
257
+ description,
258
+ children,
259
+ labelVariant,
260
+ titleStyle,
261
+ style,
262
+ testID
263
+ }) => {
264
+ const { theme } = uiFeedback.useUi();
265
+ const { colors } = theme;
266
+ const legendId = useSectionLegendId();
267
+ const hasTitle = typeof title === "string" && title !== "";
268
+ const hasDescription = typeof description === "string" && description !== "";
269
+ const a11y = { "aria-labelledby": hasTitle ? legendId : void 0 };
270
+ return (
271
+ // The section spaces its children with `gap`, so it owns their vertical rhythm exactly as a
272
+ // `FormGrid` owns a row's — without this a `Field` placed directly in a section would stack its
273
+ // 16px margin on the section's gap and recreate the F3 bug one level up.
274
+ /* @__PURE__ */ jsxRuntime.jsx(GapOwnedProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { role: "group", style: [styles3.section, style], testID, ...a11y, children: [
275
+ hasTitle ? /* @__PURE__ */ jsxRuntime.jsx(
276
+ reactNative.Text,
277
+ {
278
+ nativeID: legendId,
279
+ style: [resolveLabelVariantStyle(labelVariant), { color: colors.text }, titleStyle],
280
+ children: title
281
+ }
282
+ ) : null,
283
+ hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles3.description, { color: colors.textSecondary }], children: description }) : null,
284
+ children
285
+ ] }) })
286
+ );
287
+ };
288
+ var ACTIONS_GAP = 12;
289
+ var styles4 = reactNative.StyleSheet.create({
164
290
  container: {
165
291
  flexDirection: "row",
166
292
  justifyContent: "flex-end",
@@ -180,7 +306,7 @@ var FormActions = ({
180
306
  saveTestID = "save-button",
181
307
  cancelTestID = "cancel-button",
182
308
  testID
183
- }) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles2.container, containerStyle], testID, children: [
309
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles4.container, containerStyle], testID, children: [
184
310
  typeof onCancel === "function" ? /* @__PURE__ */ jsxRuntime.jsx(
185
311
  uiButtons.Button,
186
312
  {
@@ -303,6 +429,16 @@ function useThemedInput(options = {}) {
303
429
  };
304
430
  }
305
431
  var IS_WEB2 = reactNative.Platform.OS === "web";
432
+ function webFieldA11y({ describedById, hasError = false, required = false }) {
433
+ if (!IS_WEB2) {
434
+ return {};
435
+ }
436
+ return {
437
+ "aria-invalid": hasError ? true : void 0,
438
+ "aria-describedby": describedById,
439
+ "aria-required": required ? true : void 0
440
+ };
441
+ }
306
442
  var ThemedTextInput = React__default.default.forwardRef(function ThemedTextInput2({ hasError = false, describedById, requiredField = false, onFocus, onBlur, style, placeholderTextColor, ...rest }, ref) {
307
443
  const {
308
444
  style: themedStyle,
@@ -310,11 +446,7 @@ var ThemedTextInput = React__default.default.forwardRef(function ThemedTextInput
310
446
  focusBind,
311
447
  hoverBind
312
448
  } = useThemedInput({ hasError, onFocus, onBlur });
313
- const webA11y = IS_WEB2 ? {
314
- "aria-invalid": hasError ? true : void 0,
315
- "aria-describedby": describedById,
316
- "aria-required": requiredField ? true : void 0
317
- } : {};
449
+ const webA11y = webFieldA11y({ describedById, hasError, required: requiredField });
318
450
  return /* @__PURE__ */ jsxRuntime.jsx(
319
451
  reactNative.TextInput,
320
452
  {
@@ -333,7 +465,7 @@ var INPUT_PADDING_V = 10;
333
465
  var INPUT_PADDING_H = 12;
334
466
  var INPUT_BORDER_RADIUS = 8;
335
467
  var INPUT_BORDER_WIDTH = 1;
336
- var styles3 = reactNative.StyleSheet.create({
468
+ var styles5 = reactNative.StyleSheet.create({
337
469
  input: {
338
470
  paddingVertical: INPUT_PADDING_V,
339
471
  paddingHorizontal: INPUT_PADDING_H,
@@ -355,7 +487,7 @@ var FormField = ({
355
487
  describedById,
356
488
  hasError,
357
489
  requiredField: required,
358
- style: styles3.input,
490
+ style: styles5.input,
359
491
  testID: "form-field-input",
360
492
  ...textInputProps
361
493
  }
@@ -393,18 +525,22 @@ function withAlpha2(hex, alpha) {
393
525
  const isValid = !Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b);
394
526
  return isValid ? `rgba(${r}, ${g}, ${b}, ${alpha})` : hex;
395
527
  }
396
- var styles4 = reactNative.StyleSheet.create({
528
+ var styles6 = reactNative.StyleSheet.create({
397
529
  chipContainer: {
398
530
  flexDirection: "row",
399
531
  flexWrap: "wrap",
400
- // Each chip's bottom gutter also hangs off the LAST row, stacking on `Field`'s container
401
- // margin (8 + 16 = 24) and dropping the block below the `FormField` beside it. Cancelling it
402
- // is standard gutter compensation: inner rows keep their 8px, the block ends at Field's 16.
403
- marginBottom: -CHIP_GUTTER
404
- },
405
- chipWrapper: {
406
- marginRight: CHIP_GUTTER,
407
- marginBottom: CHIP_GUTTER
532
+ // `gap`, NOT per-chip margins plus a compensating negative container margin.
533
+ //
534
+ // The old form was `chipWrapper { marginRight: 8, marginBottom: 8 }` with
535
+ // `chipContainer { marginBottom: -8 }`. Its comment blamed `Field`'s 16px container margin —
536
+ // that was WRONG, and worth recording: F3 was briefed on the belief that the -8 compensated for
537
+ // `Field` and had to move in lockstep with it. It did not. -8 cancelled the CHIP's own gutter
538
+ // hanging off the last row, identically whether `Field` contributed 16, 0, or anything else.
539
+ //
540
+ // The pair is still the wrong tool: it holds only while the two constants agree, and it leaves
541
+ // a real negative margin any measuring parent inherits. `gap` produces the byte-identical box
542
+ // and is correct under BOTH of `Field`'s spacing models, not just the one it was tuned against.
543
+ gap: CHIP_GUTTER
408
544
  },
409
545
  chip: {
410
546
  paddingHorizontal: 12,
@@ -456,12 +592,11 @@ function OutlineChip({
456
592
  "aria-pressed": ariaPressed,
457
593
  disabled,
458
594
  hitSlop: CHIP_HIT_SLOP,
459
- style: styles4.chipWrapper,
460
595
  testID,
461
596
  onHoverIn: () => setHovered(true),
462
597
  onHoverOut: () => setHovered(false),
463
598
  onPress,
464
- children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.chipOutline, { borderColor, backgroundColor }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles4.chipText, styles4.chipTextOutline, { color: textColor }], children: option.label }) })
599
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.chipOutline, { borderColor, backgroundColor }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.chipText, styles6.chipTextOutline, { color: textColor }], children: option.label }) })
465
600
  }
466
601
  );
467
602
  }
@@ -487,18 +622,12 @@ function SolidChip({
487
622
  "aria-pressed": ariaPressed,
488
623
  disabled,
489
624
  hitSlop: CHIP_HIT_SLOP,
490
- style: styles4.chipWrapper,
491
625
  testID,
492
626
  onPress,
493
- children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.chip, { borderColor: colors.border, backgroundColor }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles4.chipText, { color: textColor }], children: option.label }) })
627
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.chip, { borderColor: colors.border, backgroundColor }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.chipText, { color: textColor }], children: option.label }) })
494
628
  }
495
629
  );
496
630
  }
497
- var IS_WEB3 = reactNative.Platform.OS === "web";
498
- function groupA11yProps(describedById, hasError) {
499
- if (!IS_WEB3) return {};
500
- return { "aria-invalid": hasError ? true : void 0, "aria-describedby": describedById };
501
- }
502
631
  var ChipSelector = ({
503
632
  label,
504
633
  options,
@@ -508,6 +637,7 @@ var ChipSelector = ({
508
637
  disabled = false,
509
638
  variant = "solid",
510
639
  containerStyle,
640
+ spacing,
511
641
  required = false,
512
642
  error,
513
643
  testID,
@@ -550,10 +680,21 @@ var ChipSelector = ({
550
680
  const key = String(option.value);
551
681
  return variant === "outline" ? /* @__PURE__ */ jsxRuntime.jsx(OutlineChip, { ...chipProps }, key) : /* @__PURE__ */ jsxRuntime.jsx(SolidChip, { ...chipProps }, key);
552
682
  }
553
- return /* @__PURE__ */ jsxRuntime.jsx(Field, { containerStyle, error, label, required, testID, children: ({ describedById, hasError }) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles4.chipContainer, ...groupA11yProps(describedById, hasError), children: options.map(renderChip) }) });
683
+ return /* @__PURE__ */ jsxRuntime.jsx(
684
+ Field,
685
+ {
686
+ containerStyle,
687
+ error,
688
+ label,
689
+ required,
690
+ spacing,
691
+ testID,
692
+ children: ({ describedById, hasError }) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles6.chipContainer, ...webFieldA11y({ describedById, hasError }), children: options.map(renderChip) })
693
+ }
694
+ );
554
695
  };
555
- var DESCRIPTION_FONT_SIZE = 12;
556
- var styles5 = reactNative.StyleSheet.create({
696
+ var DESCRIPTION_FONT_SIZE2 = 12;
697
+ var styles7 = reactNative.StyleSheet.create({
557
698
  container: {
558
699
  flexDirection: "row",
559
700
  justifyContent: "space-between",
@@ -567,7 +708,7 @@ var styles5 = reactNative.StyleSheet.create({
567
708
  fontWeight: "600"
568
709
  },
569
710
  description: {
570
- fontSize: DESCRIPTION_FONT_SIZE,
711
+ fontSize: DESCRIPTION_FONT_SIZE2,
571
712
  marginTop: 2
572
713
  }
573
714
  });
@@ -593,13 +734,13 @@ var FormSwitch = ({
593
734
  reactNative.View,
594
735
  {
595
736
  style: [
596
- styles5.container,
737
+ styles7.container,
597
738
  containerStyle
598
739
  ],
599
740
  children: [
600
- /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles5.textColumn, children: [
601
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.label, themeStyles.label], children: label }),
602
- hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.description, themeStyles.description], children: description }) : null
741
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles7.textColumn, children: [
742
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles7.label, themeStyles.label], children: label }),
743
+ hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles7.description, themeStyles.description], children: description }) : null
603
744
  ] }),
604
745
  /* @__PURE__ */ jsxRuntime.jsx(
605
746
  reactNative.Switch,
@@ -624,7 +765,7 @@ var BOX_SIZE = 20;
624
765
  var BOX_RADIUS = 5;
625
766
  var CHECK_FONT_SIZE = 14;
626
767
  var DISABLED_OPACITY = 0.5;
627
- var styles6 = reactNative.StyleSheet.create({
768
+ var styles8 = reactNative.StyleSheet.create({
628
769
  container: {
629
770
  flexDirection: "row",
630
771
  alignItems: "flex-start",
@@ -706,14 +847,14 @@ var FormCheckbox = ({
706
847
  disabled,
707
848
  onPress: toggle,
708
849
  role: "checkbox",
709
- style: [styles6.container, containerStyle, disabled ? { opacity: DISABLED_OPACITY } : null],
850
+ style: [styles8.container, containerStyle, disabled ? { opacity: DISABLED_OPACITY } : null],
710
851
  testID,
711
852
  ...keyboardProps,
712
853
  children: [
713
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.box, value ? themeStyles.boxOn : themeStyles.boxOff], children: value ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.check, { color: colors.surface }], accessibilityElementsHidden: true, children: "\u2713" }) : null }),
714
- /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles6.textColumn, children: [
715
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.label, themeStyles.label], children: label }),
716
- hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles6.hint, themeStyles.hint], children: hintText }) : null
854
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles8.box, value ? themeStyles.boxOn : themeStyles.boxOff], children: value ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.check, { color: colors.surface }], accessibilityElementsHidden: true, children: "\u2713" }) : null }),
855
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.textColumn, children: [
856
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.label, themeStyles.label], children: label }),
857
+ hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.hint, themeStyles.hint], children: hintText }) : null
717
858
  ] })
718
859
  ]
719
860
  }
@@ -794,13 +935,13 @@ var controlStyles = reactNative.StyleSheet.create({
794
935
  optionText: { fontSize: OPTION_FONT },
795
936
  error: { fontSize: ERROR_FONT, marginTop: ERROR_GAP }
796
937
  });
797
- var IS_WEB4 = typeof document !== "undefined";
938
+ var IS_WEB3 = typeof document !== "undefined";
798
939
  var ESCAPE_KEY = "Escape";
799
940
  var ACTIVE_WEIGHT = "700";
800
941
  var IDLE_WEIGHT = "400";
801
942
  function useDismiss(anchorRef, menuRef, onDismiss) {
802
943
  React.useEffect(() => {
803
- if (!IS_WEB4) return void 0;
944
+ if (!IS_WEB3) return void 0;
804
945
  const onMouseDown = (event) => {
805
946
  const anchorNode = anchorRef.current;
806
947
  const menuNode = menuRef.current;
@@ -1127,8 +1268,11 @@ exports.DEFAULT_TYPEAHEAD_MIN_CHARS = DEFAULT_TYPEAHEAD_MIN_CHARS;
1127
1268
  exports.DateRangeControl = DateRangeControl;
1128
1269
  exports.Field = Field;
1129
1270
  exports.FormActions = FormActions;
1271
+ exports.FormCell = FormCell;
1130
1272
  exports.FormCheckbox = FormCheckbox;
1131
1273
  exports.FormField = FormField;
1274
+ exports.FormGrid = FormGrid;
1275
+ exports.FormSection = FormSection;
1132
1276
  exports.FormSwitch = FormSwitch;
1133
1277
  exports.SelectControl = SelectControl;
1134
1278
  exports.ThemedTextInput = ThemedTextInput;