@dloizides/ui-forms 1.18.7 → 1.20.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 +437 -429
- package/dist/index.d.mts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +121 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -264,10 +264,41 @@ interface FormCellProps {
|
|
|
264
264
|
basis?: number;
|
|
265
265
|
/** `false` pins the cell to its basis instead of letting it absorb the row's slack. */
|
|
266
266
|
grow?: boolean;
|
|
267
|
+
/** Puts an unlabelled control (a button) on the input line of the labelled cells beside it. */
|
|
268
|
+
alignToControl?: boolean;
|
|
267
269
|
style?: StyleProp<ViewStyle>;
|
|
268
270
|
testID?: string;
|
|
269
271
|
}
|
|
270
|
-
declare const FormCell: ({ children, minWidth, basis, grow, style, testID, }: FormCellProps) => React.ReactElement;
|
|
272
|
+
declare const FormCell: ({ children, minWidth, basis, grow, alignToControl, style, testID, }: FormCellProps) => React.ReactElement;
|
|
273
|
+
|
|
274
|
+
interface AlignToControlProps {
|
|
275
|
+
children: React.ReactNode;
|
|
276
|
+
labelVariant?: FieldLabelVariant;
|
|
277
|
+
spacing?: FieldSpacing;
|
|
278
|
+
style?: StyleProp<ViewStyle>;
|
|
279
|
+
testID?: string;
|
|
280
|
+
}
|
|
281
|
+
/** Puts a button or other unlabelled control on the input line of the labelled `Field`s beside it. */
|
|
282
|
+
declare const AlignToControl: ({ children, labelVariant, spacing, style, testID, }: AlignToControlProps) => React.ReactElement;
|
|
283
|
+
|
|
284
|
+
interface InlineFieldRowProps {
|
|
285
|
+
field: React.ReactNode;
|
|
286
|
+
action: React.ReactNode;
|
|
287
|
+
fieldMaxWidth: number;
|
|
288
|
+
inlineMinWidth?: number;
|
|
289
|
+
gap?: number;
|
|
290
|
+
testID?: string;
|
|
291
|
+
}
|
|
292
|
+
/** A labelled field and its action: stacked on phones, one row on desktop with the action on the input line. */
|
|
293
|
+
declare const InlineFieldRow: ({ field, action, fieldMaxWidth, inlineMinWidth, gap, testID, }: InlineFieldRowProps) => React.ReactElement;
|
|
294
|
+
|
|
295
|
+
declare const INLINE_FIELD_ROW_MIN_WIDTH = 1024;
|
|
296
|
+
interface InlineFieldRowLayout {
|
|
297
|
+
inline: boolean;
|
|
298
|
+
fieldMaxWidth: number | undefined;
|
|
299
|
+
}
|
|
300
|
+
/** Field and action share one row only at `inlineMinWidth` and wider; below it they stack. */
|
|
301
|
+
declare function inlineFieldRowLayout(windowWidth: number, fieldMaxWidth: number, inlineMinWidth?: number): InlineFieldRowLayout;
|
|
271
302
|
|
|
272
303
|
/**
|
|
273
304
|
* `FormSection` — a titled group of fields. The React answer to v1's `<fieldset>` / `<legend>`.
|
|
@@ -470,6 +501,8 @@ interface UseThemedInputOptions {
|
|
|
470
501
|
onFocus?: (e: FocusEvent) => void;
|
|
471
502
|
/** Consumer blur handler — composed with the internal focus-state toggle. */
|
|
472
503
|
onBlur?: (e: BlurEvent) => void;
|
|
504
|
+
/** `false` renders the read-only treatment: the recessed ground fill and the secondary ink. */
|
|
505
|
+
editable?: boolean;
|
|
473
506
|
}
|
|
474
507
|
interface ThemedInput {
|
|
475
508
|
/** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
|
|
@@ -1029,4 +1062,4 @@ declare function groupAriaChecked(state: GroupSelection): boolean | 'mixed';
|
|
|
1029
1062
|
*/
|
|
1030
1063
|
declare function toggleGroupSelection<T>(selected: readonly T[], groupKeys: readonly T[], order?: readonly T[]): T[];
|
|
1031
1064
|
|
|
1032
|
-
export { AnchoredMenu, type AnchoredMenuColors, type AnchoredMenuProps, type ChipOption, ChipSelector, type ChipSelectorProps, type ChipSingleSelectRole, type ChipVariant, type ControlOption, DEFAULT_MAX_RECENTS, DEFAULT_OPTIONAL_LABEL, DEFAULT_TYPEAHEAD_MAX_SUGGESTIONS, DEFAULT_TYPEAHEAD_MIN_CHARS, DateRangeControl, type DateRangeControlProps, type DateRangeValue, Field, type FieldChildContext, type FieldChildren, type FieldLabelVariant, type FieldMarker, type FieldProps, type FieldSpacing, FormActions, type FormActionsProps, FormCell, type FormCellProps, FormCheckbox, type FormCheckboxProps, FormField, type FormFieldProps, FormGrid, type FormGridProps, FormSection, type FormSectionProps, FormSwitch, type FormSwitchProps, type GroupSelection, type RecentValues, SelectControl, type SelectControlProps, type ThemedInput, ThemedTextInput, type ThemedTextInputProps, TypeaheadControl, type TypeaheadControlProps, type UseThemedInputOptions, controlStyles, groupAriaChecked, isUnmatched, resolveGroupSelection, suggestOptions, toggleGroupSelection, useRecentValues, useThemedInput };
|
|
1065
|
+
export { AlignToControl, type AlignToControlProps, AnchoredMenu, type AnchoredMenuColors, type AnchoredMenuProps, type ChipOption, ChipSelector, type ChipSelectorProps, type ChipSingleSelectRole, type ChipVariant, type ControlOption, DEFAULT_MAX_RECENTS, DEFAULT_OPTIONAL_LABEL, DEFAULT_TYPEAHEAD_MAX_SUGGESTIONS, DEFAULT_TYPEAHEAD_MIN_CHARS, DateRangeControl, type DateRangeControlProps, type DateRangeValue, Field, type FieldChildContext, type FieldChildren, type FieldLabelVariant, type FieldMarker, type FieldProps, type FieldSpacing, FormActions, type FormActionsProps, FormCell, type FormCellProps, FormCheckbox, type FormCheckboxProps, FormField, type FormFieldProps, FormGrid, type FormGridProps, FormSection, type FormSectionProps, FormSwitch, type FormSwitchProps, type GroupSelection, INLINE_FIELD_ROW_MIN_WIDTH, InlineFieldRow, type InlineFieldRowLayout, type InlineFieldRowProps, type RecentValues, SelectControl, type SelectControlProps, type ThemedInput, ThemedTextInput, type ThemedTextInputProps, TypeaheadControl, type TypeaheadControlProps, type UseThemedInputOptions, controlStyles, groupAriaChecked, inlineFieldRowLayout, isUnmatched, resolveGroupSelection, suggestOptions, toggleGroupSelection, useRecentValues, useThemedInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -264,10 +264,41 @@ interface FormCellProps {
|
|
|
264
264
|
basis?: number;
|
|
265
265
|
/** `false` pins the cell to its basis instead of letting it absorb the row's slack. */
|
|
266
266
|
grow?: boolean;
|
|
267
|
+
/** Puts an unlabelled control (a button) on the input line of the labelled cells beside it. */
|
|
268
|
+
alignToControl?: boolean;
|
|
267
269
|
style?: StyleProp<ViewStyle>;
|
|
268
270
|
testID?: string;
|
|
269
271
|
}
|
|
270
|
-
declare const FormCell: ({ children, minWidth, basis, grow, style, testID, }: FormCellProps) => React.ReactElement;
|
|
272
|
+
declare const FormCell: ({ children, minWidth, basis, grow, alignToControl, style, testID, }: FormCellProps) => React.ReactElement;
|
|
273
|
+
|
|
274
|
+
interface AlignToControlProps {
|
|
275
|
+
children: React.ReactNode;
|
|
276
|
+
labelVariant?: FieldLabelVariant;
|
|
277
|
+
spacing?: FieldSpacing;
|
|
278
|
+
style?: StyleProp<ViewStyle>;
|
|
279
|
+
testID?: string;
|
|
280
|
+
}
|
|
281
|
+
/** Puts a button or other unlabelled control on the input line of the labelled `Field`s beside it. */
|
|
282
|
+
declare const AlignToControl: ({ children, labelVariant, spacing, style, testID, }: AlignToControlProps) => React.ReactElement;
|
|
283
|
+
|
|
284
|
+
interface InlineFieldRowProps {
|
|
285
|
+
field: React.ReactNode;
|
|
286
|
+
action: React.ReactNode;
|
|
287
|
+
fieldMaxWidth: number;
|
|
288
|
+
inlineMinWidth?: number;
|
|
289
|
+
gap?: number;
|
|
290
|
+
testID?: string;
|
|
291
|
+
}
|
|
292
|
+
/** A labelled field and its action: stacked on phones, one row on desktop with the action on the input line. */
|
|
293
|
+
declare const InlineFieldRow: ({ field, action, fieldMaxWidth, inlineMinWidth, gap, testID, }: InlineFieldRowProps) => React.ReactElement;
|
|
294
|
+
|
|
295
|
+
declare const INLINE_FIELD_ROW_MIN_WIDTH = 1024;
|
|
296
|
+
interface InlineFieldRowLayout {
|
|
297
|
+
inline: boolean;
|
|
298
|
+
fieldMaxWidth: number | undefined;
|
|
299
|
+
}
|
|
300
|
+
/** Field and action share one row only at `inlineMinWidth` and wider; below it they stack. */
|
|
301
|
+
declare function inlineFieldRowLayout(windowWidth: number, fieldMaxWidth: number, inlineMinWidth?: number): InlineFieldRowLayout;
|
|
271
302
|
|
|
272
303
|
/**
|
|
273
304
|
* `FormSection` — a titled group of fields. The React answer to v1's `<fieldset>` / `<legend>`.
|
|
@@ -470,6 +501,8 @@ interface UseThemedInputOptions {
|
|
|
470
501
|
onFocus?: (e: FocusEvent) => void;
|
|
471
502
|
/** Consumer blur handler — composed with the internal focus-state toggle. */
|
|
472
503
|
onBlur?: (e: BlurEvent) => void;
|
|
504
|
+
/** `false` renders the read-only treatment: the recessed ground fill and the secondary ink. */
|
|
505
|
+
editable?: boolean;
|
|
473
506
|
}
|
|
474
507
|
interface ThemedInput {
|
|
475
508
|
/** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
|
|
@@ -1029,4 +1062,4 @@ declare function groupAriaChecked(state: GroupSelection): boolean | 'mixed';
|
|
|
1029
1062
|
*/
|
|
1030
1063
|
declare function toggleGroupSelection<T>(selected: readonly T[], groupKeys: readonly T[], order?: readonly T[]): T[];
|
|
1031
1064
|
|
|
1032
|
-
export { AnchoredMenu, type AnchoredMenuColors, type AnchoredMenuProps, type ChipOption, ChipSelector, type ChipSelectorProps, type ChipSingleSelectRole, type ChipVariant, type ControlOption, DEFAULT_MAX_RECENTS, DEFAULT_OPTIONAL_LABEL, DEFAULT_TYPEAHEAD_MAX_SUGGESTIONS, DEFAULT_TYPEAHEAD_MIN_CHARS, DateRangeControl, type DateRangeControlProps, type DateRangeValue, Field, type FieldChildContext, type FieldChildren, type FieldLabelVariant, type FieldMarker, type FieldProps, type FieldSpacing, FormActions, type FormActionsProps, FormCell, type FormCellProps, FormCheckbox, type FormCheckboxProps, FormField, type FormFieldProps, FormGrid, type FormGridProps, FormSection, type FormSectionProps, FormSwitch, type FormSwitchProps, type GroupSelection, type RecentValues, SelectControl, type SelectControlProps, type ThemedInput, ThemedTextInput, type ThemedTextInputProps, TypeaheadControl, type TypeaheadControlProps, type UseThemedInputOptions, controlStyles, groupAriaChecked, isUnmatched, resolveGroupSelection, suggestOptions, toggleGroupSelection, useRecentValues, useThemedInput };
|
|
1065
|
+
export { AlignToControl, type AlignToControlProps, AnchoredMenu, type AnchoredMenuColors, type AnchoredMenuProps, type ChipOption, ChipSelector, type ChipSelectorProps, type ChipSingleSelectRole, type ChipVariant, type ControlOption, DEFAULT_MAX_RECENTS, DEFAULT_OPTIONAL_LABEL, DEFAULT_TYPEAHEAD_MAX_SUGGESTIONS, DEFAULT_TYPEAHEAD_MIN_CHARS, DateRangeControl, type DateRangeControlProps, type DateRangeValue, Field, type FieldChildContext, type FieldChildren, type FieldLabelVariant, type FieldMarker, type FieldProps, type FieldSpacing, FormActions, type FormActionsProps, FormCell, type FormCellProps, FormCheckbox, type FormCheckboxProps, FormField, type FormFieldProps, FormGrid, type FormGridProps, FormSection, type FormSectionProps, FormSwitch, type FormSwitchProps, type GroupSelection, INLINE_FIELD_ROW_MIN_WIDTH, InlineFieldRow, type InlineFieldRowLayout, type InlineFieldRowProps, type RecentValues, SelectControl, type SelectControlProps, type ThemedInput, ThemedTextInput, type ThemedTextInputProps, TypeaheadControl, type TypeaheadControlProps, type UseThemedInputOptions, controlStyles, groupAriaChecked, inlineFieldRowLayout, isUnmatched, resolveGroupSelection, suggestOptions, toggleGroupSelection, useRecentValues, useThemedInput };
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,10 @@ var React2 = require('react');
|
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
5
|
var uiFeedback = require('@dloizides/ui-feedback');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var designTokens = require('@dloizides/design-tokens');
|
|
7
8
|
var uiButtons = require('@dloizides/ui-buttons');
|
|
8
9
|
var reactDom = require('react-dom');
|
|
9
10
|
var a11y = require('@dloizides/a11y');
|
|
10
|
-
var designTokens = require('@dloizides/design-tokens');
|
|
11
11
|
|
|
12
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
|
|
@@ -146,6 +146,11 @@ function useFormGridMetrics() {
|
|
|
146
146
|
function useIsGapOwned() {
|
|
147
147
|
return React2__default.default.useContext(GapOwnedContext);
|
|
148
148
|
}
|
|
149
|
+
var ERROR_LIGHT_STEPS = ["500", "600", "700"];
|
|
150
|
+
var ERROR_DARK_STEPS = ["300", "200", "400", "100", "500"];
|
|
151
|
+
function fieldErrorInk(theme) {
|
|
152
|
+
return designTokens.readableScaleInk({ ...theme.semantic.error }, theme.colors.surface, ERROR_LIGHT_STEPS, ERROR_DARK_STEPS);
|
|
153
|
+
}
|
|
149
154
|
var ERROR_FONT_SIZE = 12;
|
|
150
155
|
var HINT_FONT_SIZE = 12;
|
|
151
156
|
var OPTIONAL_MARK_FONT_WEIGHT = "400";
|
|
@@ -201,8 +206,8 @@ var Field = ({
|
|
|
201
206
|
const { theme } = uiFeedback.useUi();
|
|
202
207
|
const gapOwned = useIsGapOwned();
|
|
203
208
|
const spacingStyles = fieldSpacingStyleSet(resolveFieldSpacing(spacing, gapOwned));
|
|
204
|
-
const { colors
|
|
205
|
-
const errorColor =
|
|
209
|
+
const { colors } = theme;
|
|
210
|
+
const errorColor = fieldErrorInk(theme);
|
|
206
211
|
const hasError = hasFieldError(error);
|
|
207
212
|
const hasHint = isPresent(hint);
|
|
208
213
|
const labelText = label ?? "";
|
|
@@ -248,6 +253,7 @@ var FORM_GRID_DEFAULT_MIN_WIDTH = 220;
|
|
|
248
253
|
var FORM_GRID_DEFAULT_BASIS = 260;
|
|
249
254
|
var styles2 = reactNative.StyleSheet.create({
|
|
250
255
|
grid: {
|
|
256
|
+
alignItems: "flex-start",
|
|
251
257
|
flexDirection: "row",
|
|
252
258
|
flexWrap: "wrap"
|
|
253
259
|
}
|
|
@@ -263,6 +269,36 @@ var FormGrid = ({
|
|
|
263
269
|
const metrics = React2__default.default.useMemo(() => ({ minWidth, basis }), [minWidth, basis]);
|
|
264
270
|
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 }) }) });
|
|
265
271
|
};
|
|
272
|
+
var LABEL_LINE_PLACEHOLDER = "\xA0";
|
|
273
|
+
var styles3 = reactNative.StyleSheet.create({
|
|
274
|
+
labelLine: {
|
|
275
|
+
userSelect: "none"
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
var AlignToControl = ({
|
|
279
|
+
children,
|
|
280
|
+
labelVariant,
|
|
281
|
+
spacing,
|
|
282
|
+
style,
|
|
283
|
+
testID
|
|
284
|
+
}) => {
|
|
285
|
+
const spacingStyles = fieldSpacingStyleSet(resolveFieldSpacing(spacing, useIsGapOwned()));
|
|
286
|
+
const labelLineTestID = testID !== void 0 ? `${testID}-label-line` : void 0;
|
|
287
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [spacingStyles.container, style], testID, children: [
|
|
288
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
289
|
+
reactNative.Text,
|
|
290
|
+
{
|
|
291
|
+
accessibilityElementsHidden: true,
|
|
292
|
+
"aria-hidden": true,
|
|
293
|
+
importantForAccessibility: "no",
|
|
294
|
+
style: [spacingStyles.label, resolveLabelVariantStyle(labelVariant), styles3.labelLine],
|
|
295
|
+
testID: labelLineTestID,
|
|
296
|
+
children: LABEL_LINE_PLACEHOLDER
|
|
297
|
+
}
|
|
298
|
+
),
|
|
299
|
+
children
|
|
300
|
+
] });
|
|
301
|
+
};
|
|
266
302
|
var GROW = 1;
|
|
267
303
|
var NO_GROW = 0;
|
|
268
304
|
var FormCell = ({
|
|
@@ -270,6 +306,7 @@ var FormCell = ({
|
|
|
270
306
|
minWidth,
|
|
271
307
|
basis,
|
|
272
308
|
grow = true,
|
|
309
|
+
alignToControl = false,
|
|
273
310
|
style,
|
|
274
311
|
testID
|
|
275
312
|
}) => {
|
|
@@ -281,11 +318,54 @@ var FormCell = ({
|
|
|
281
318
|
flexBasis: resolvedBasis,
|
|
282
319
|
flexGrow: grow ? GROW : NO_GROW
|
|
283
320
|
};
|
|
284
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [cellStyle, style], testID, children });
|
|
321
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [cellStyle, style], testID, children: alignToControl ? /* @__PURE__ */ jsxRuntime.jsx(AlignToControl, { children }) : children });
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// src/InlineFieldRow/inlineFieldRowLayout.ts
|
|
325
|
+
var INLINE_FIELD_ROW_MIN_WIDTH = 1024;
|
|
326
|
+
function inlineFieldRowLayout(windowWidth, fieldMaxWidth, inlineMinWidth = INLINE_FIELD_ROW_MIN_WIDTH) {
|
|
327
|
+
const inline = windowWidth >= inlineMinWidth;
|
|
328
|
+
return { inline, fieldMaxWidth: inline ? fieldMaxWidth : void 0 };
|
|
329
|
+
}
|
|
330
|
+
var styles4 = reactNative.StyleSheet.create({
|
|
331
|
+
action: {
|
|
332
|
+
flexShrink: 0
|
|
333
|
+
},
|
|
334
|
+
field: {
|
|
335
|
+
flexBasis: 0,
|
|
336
|
+
flexGrow: 1,
|
|
337
|
+
flexShrink: 1
|
|
338
|
+
},
|
|
339
|
+
row: {
|
|
340
|
+
alignItems: "flex-start",
|
|
341
|
+
flexDirection: "row"
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
var InlineFieldRow = ({
|
|
345
|
+
field,
|
|
346
|
+
action,
|
|
347
|
+
fieldMaxWidth,
|
|
348
|
+
inlineMinWidth,
|
|
349
|
+
gap = FORM_GRID_DEFAULT_GAP,
|
|
350
|
+
testID
|
|
351
|
+
}) => {
|
|
352
|
+
const { width } = reactNative.useWindowDimensions();
|
|
353
|
+
const layout = inlineFieldRowLayout(width, fieldMaxWidth, inlineMinWidth);
|
|
354
|
+
const rowStyle = React2.useMemo(() => [styles4.row, { gap }], [gap]);
|
|
355
|
+
const fieldStyle = React2.useMemo(() => [styles4.field, { maxWidth: layout.fieldMaxWidth }], [layout.fieldMaxWidth]);
|
|
356
|
+
if (!layout.inline)
|
|
357
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
358
|
+
field,
|
|
359
|
+
action
|
|
360
|
+
] });
|
|
361
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: rowStyle, testID, children: [
|
|
362
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: fieldStyle, children: field }),
|
|
363
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlignToControl, { style: styles4.action, children: action })
|
|
364
|
+
] });
|
|
285
365
|
};
|
|
286
366
|
var SECTION_GAP = 10;
|
|
287
367
|
var DESCRIPTION_FONT_SIZE = 12;
|
|
288
|
-
var
|
|
368
|
+
var styles5 = reactNative.StyleSheet.create({
|
|
289
369
|
section: {
|
|
290
370
|
gap: SECTION_GAP
|
|
291
371
|
},
|
|
@@ -320,7 +400,7 @@ var FormSection = ({
|
|
|
320
400
|
// The section spaces its children with `gap`, so it owns their vertical rhythm exactly as a
|
|
321
401
|
// `FormGrid` owns a row's — without this a `Field` placed directly in a section would stack its
|
|
322
402
|
// 16px margin on the section's gap and recreate the F3 bug one level up.
|
|
323
|
-
/* @__PURE__ */ jsxRuntime.jsx(GapOwnedProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { role: "group", style: [
|
|
403
|
+
/* @__PURE__ */ jsxRuntime.jsx(GapOwnedProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { role: "group", style: [styles5.section, style], testID, ...a11y, children: [
|
|
324
404
|
hasTitle ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
325
405
|
reactNative.Text,
|
|
326
406
|
{
|
|
@@ -329,13 +409,13 @@ var FormSection = ({
|
|
|
329
409
|
children: title
|
|
330
410
|
}
|
|
331
411
|
) : null,
|
|
332
|
-
hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
412
|
+
hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles5.description, { color: colors.textSecondary }], children: description }) : null,
|
|
333
413
|
children
|
|
334
414
|
] }) })
|
|
335
415
|
);
|
|
336
416
|
};
|
|
337
417
|
var ACTIONS_GAP = 12;
|
|
338
|
-
var
|
|
418
|
+
var styles6 = reactNative.StyleSheet.create({
|
|
339
419
|
container: {
|
|
340
420
|
flexDirection: "row",
|
|
341
421
|
justifyContent: "flex-end",
|
|
@@ -355,7 +435,7 @@ var FormActions = ({
|
|
|
355
435
|
saveTestID = "save-button",
|
|
356
436
|
cancelTestID = "cancel-button",
|
|
357
437
|
testID
|
|
358
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
438
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles6.container, containerStyle], testID, children: [
|
|
359
439
|
typeof onCancel === "function" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
360
440
|
uiButtons.Button,
|
|
361
441
|
{
|
|
@@ -635,9 +715,9 @@ function withAlpha(color, alpha) {
|
|
|
635
715
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
636
716
|
}
|
|
637
717
|
function useThemedInput(options = {}) {
|
|
638
|
-
const { hasError = false, onFocus, onBlur } = options;
|
|
718
|
+
const { hasError = false, onFocus, onBlur, editable = true } = options;
|
|
639
719
|
const { theme } = uiFeedback.useUi();
|
|
640
|
-
const { colors, palette
|
|
720
|
+
const { colors, palette } = theme;
|
|
641
721
|
const [isFocused, setIsFocused] = React2.useState(false);
|
|
642
722
|
const [isHovered, setIsHovered] = React2.useState(false);
|
|
643
723
|
const handleFocus = React2.useCallback(
|
|
@@ -657,13 +737,14 @@ function useThemedInput(options = {}) {
|
|
|
657
737
|
const handleHoverIn = React2.useCallback(() => setIsHovered(true), []);
|
|
658
738
|
const handleHoverOut = React2.useCallback(() => setIsHovered(false), []);
|
|
659
739
|
const primary = palette.primary["500"];
|
|
660
|
-
const errorColor =
|
|
740
|
+
const errorColor = fieldErrorInk(theme);
|
|
661
741
|
const style = React2.useMemo(() => {
|
|
662
742
|
const restBorder = hasError ? errorColor : colors.border;
|
|
663
743
|
const focusBorder = hasError ? errorColor : primary;
|
|
664
744
|
const borderColor = isFocused ? focusBorder : isHovered ? withAlpha(colors.text, HOVER_BORDER_ALPHA) : restBorder;
|
|
665
|
-
const
|
|
666
|
-
const
|
|
745
|
+
const editableFill = isFocused ? colors.surface : colors.surfaceElevated;
|
|
746
|
+
const backgroundColor = editable ? editableFill : colors.background;
|
|
747
|
+
const base = { color: editable ? colors.text : colors.textSecondary, borderColor, backgroundColor };
|
|
667
748
|
if (!IS_WEB5) return base;
|
|
668
749
|
const ringColor = hasError ? errorColor : uiButtons.themeFocusRingColor(theme);
|
|
669
750
|
const ring = isFocused ? designTokens.focusRingOutline(ringColor) : NO_RING;
|
|
@@ -683,6 +764,9 @@ function useThemedInput(options = {}) {
|
|
|
683
764
|
colors.border,
|
|
684
765
|
colors.surface,
|
|
685
766
|
colors.surfaceElevated,
|
|
767
|
+
colors.background,
|
|
768
|
+
colors.textSecondary,
|
|
769
|
+
editable,
|
|
686
770
|
primary,
|
|
687
771
|
errorColor,
|
|
688
772
|
theme
|
|
@@ -735,7 +819,7 @@ var ThemedTextInput = React2__default.default.forwardRef(function ThemedTextInpu
|
|
|
735
819
|
placeholderTextColor: themedPlaceholder,
|
|
736
820
|
focusBind,
|
|
737
821
|
hoverBind
|
|
738
|
-
} = useThemedInput({ hasError, onFocus, onBlur });
|
|
822
|
+
} = useThemedInput({ hasError, onFocus, onBlur, editable: rest.editable });
|
|
739
823
|
const webA11y = webFieldA11y({ describedById, hasError, required: requiredField });
|
|
740
824
|
const boxStyle = unstyledBox ? null : controlStyles.input;
|
|
741
825
|
const multilineStyle = rest.multiline === true && !unstyledBox ? boxStyles.multiline : null;
|
|
@@ -1171,7 +1255,7 @@ function chipIdentity(option, selected, config) {
|
|
|
1171
1255
|
ariaChecked: isRadio ? selected : void 0
|
|
1172
1256
|
};
|
|
1173
1257
|
}
|
|
1174
|
-
var
|
|
1258
|
+
var styles7 = reactNative.StyleSheet.create({
|
|
1175
1259
|
chipContainer: {
|
|
1176
1260
|
flexDirection: "row",
|
|
1177
1261
|
flexWrap: "wrap",
|
|
@@ -1257,7 +1341,7 @@ var ChipSelector = ({
|
|
|
1257
1341
|
reactNative.View,
|
|
1258
1342
|
{
|
|
1259
1343
|
accessibilityRole: isRadioGroup ? "radiogroup" : void 0,
|
|
1260
|
-
style:
|
|
1344
|
+
style: styles7.chipContainer,
|
|
1261
1345
|
...webFieldA11y({ describedById, hasError }),
|
|
1262
1346
|
...radio.groupProps,
|
|
1263
1347
|
children: options.map(renderChip)
|
|
@@ -1267,7 +1351,7 @@ var ChipSelector = ({
|
|
|
1267
1351
|
);
|
|
1268
1352
|
};
|
|
1269
1353
|
var DESCRIPTION_FONT_SIZE2 = 12;
|
|
1270
|
-
var
|
|
1354
|
+
var styles8 = reactNative.StyleSheet.create({
|
|
1271
1355
|
container: {
|
|
1272
1356
|
flexDirection: "row",
|
|
1273
1357
|
justifyContent: "space-between",
|
|
@@ -1328,15 +1412,15 @@ var FormSwitch = ({
|
|
|
1328
1412
|
accessible: false,
|
|
1329
1413
|
disabled,
|
|
1330
1414
|
onPress: toggle,
|
|
1331
|
-
style: [
|
|
1415
|
+
style: [styles8.container, containerStyle],
|
|
1332
1416
|
tabIndex: -1,
|
|
1333
1417
|
testID: `${testID}-row`,
|
|
1334
1418
|
children: [
|
|
1335
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1336
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1337
|
-
hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1419
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.textColumn, children: [
|
|
1420
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.label, themeStyles.label], children: label }),
|
|
1421
|
+
hasDescription ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles8.description, themeStyles.description], children: description }) : null
|
|
1338
1422
|
] }),
|
|
1339
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { pointerEvents: "none", style:
|
|
1423
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { pointerEvents: "none", style: styles8.switchSlot, testID: `${testID}-hitbox`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1340
1424
|
reactNative.Switch,
|
|
1341
1425
|
{
|
|
1342
1426
|
accessibilityHint: accessibilityHint ?? label,
|
|
@@ -1359,7 +1443,7 @@ var BOX_SIZE = 20;
|
|
|
1359
1443
|
var BOX_RADIUS = 5;
|
|
1360
1444
|
var CHECK_FONT_SIZE = 14;
|
|
1361
1445
|
var DISABLED_OPACITY = 0.5;
|
|
1362
|
-
var
|
|
1446
|
+
var styles9 = reactNative.StyleSheet.create({
|
|
1363
1447
|
container: {
|
|
1364
1448
|
flexDirection: "row",
|
|
1365
1449
|
alignItems: "flex-start",
|
|
@@ -1451,18 +1535,18 @@ var FormCheckbox = ({
|
|
|
1451
1535
|
onPress: toggle,
|
|
1452
1536
|
role: "checkbox",
|
|
1453
1537
|
style: [
|
|
1454
|
-
|
|
1455
|
-
hasHint ? null :
|
|
1538
|
+
styles9.container,
|
|
1539
|
+
hasHint ? null : styles9.centered,
|
|
1456
1540
|
containerStyle,
|
|
1457
1541
|
disabled ? { opacity: DISABLED_OPACITY } : null
|
|
1458
1542
|
],
|
|
1459
1543
|
testID,
|
|
1460
1544
|
...keyboardProps,
|
|
1461
1545
|
children: [
|
|
1462
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
1463
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
1464
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [
|
|
1465
|
-
hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: hintId, style: [
|
|
1546
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles9.box, value ? themeStyles.boxOn : themeStyles.boxOff], children: value ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles9.check, { color: colors.surface }], accessibilityElementsHidden: true, children: "\u2713" }) : null }),
|
|
1547
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles9.textColumn, children: [
|
|
1548
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles9.label, themeStyles.label], children: label }),
|
|
1549
|
+
hasHint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: hintId, style: [styles9.hint, themeStyles.hint], children: hintText }) : null
|
|
1466
1550
|
] })
|
|
1467
1551
|
]
|
|
1468
1552
|
}
|
|
@@ -1588,7 +1672,7 @@ function TypeaheadControl({
|
|
|
1588
1672
|
testID
|
|
1589
1673
|
}) {
|
|
1590
1674
|
const { theme } = uiFeedback.useUi();
|
|
1591
|
-
const { colors, palette
|
|
1675
|
+
const { colors, palette } = theme;
|
|
1592
1676
|
const anchorRef = React2.useRef(null);
|
|
1593
1677
|
const [isOpen, setIsOpen] = React2.useState(false);
|
|
1594
1678
|
const exactPick = React2.useMemo(() => options.some((o) => o.label === value), [options, value]);
|
|
@@ -1636,7 +1720,7 @@ function TypeaheadControl({
|
|
|
1636
1720
|
onFocus: () => setIsOpen(true),
|
|
1637
1721
|
onBlur: handleBlur,
|
|
1638
1722
|
onSubmitEditing: handleSubmit,
|
|
1639
|
-
style: [controlStyles.input, { borderColor: hasError ?
|
|
1723
|
+
style: [controlStyles.input, { borderColor: hasError ? fieldErrorInk(theme) : colors.border, backgroundColor: colors.surface, color: colors.text }],
|
|
1640
1724
|
testID: `${testID}-input`
|
|
1641
1725
|
}
|
|
1642
1726
|
),
|
|
@@ -1654,7 +1738,7 @@ function TypeaheadControl({
|
|
|
1654
1738
|
usePortal: true
|
|
1655
1739
|
}
|
|
1656
1740
|
) : null,
|
|
1657
|
-
hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { role: "alert", style: [controlStyles.error, { color:
|
|
1741
|
+
hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { role: "alert", style: [controlStyles.error, { color: fieldErrorInk(theme) }], testID: `${testID}-error`, children: error }) : null
|
|
1658
1742
|
] });
|
|
1659
1743
|
}
|
|
1660
1744
|
var WEB_DATE_PROPS = typeof document !== "undefined" ? { type: "date" } : {};
|
|
@@ -1754,6 +1838,7 @@ function toggleGroupSelection(selected, groupKeys, order) {
|
|
|
1754
1838
|
return order === void 0 ? merged : order.filter((key) => merged.includes(key));
|
|
1755
1839
|
}
|
|
1756
1840
|
|
|
1841
|
+
exports.AlignToControl = AlignToControl;
|
|
1757
1842
|
exports.AnchoredMenu = AnchoredMenu;
|
|
1758
1843
|
exports.ChipSelector = ChipSelector;
|
|
1759
1844
|
exports.DEFAULT_MAX_RECENTS = DEFAULT_MAX_RECENTS;
|
|
@@ -1769,11 +1854,14 @@ exports.FormField = FormField;
|
|
|
1769
1854
|
exports.FormGrid = FormGrid;
|
|
1770
1855
|
exports.FormSection = FormSection;
|
|
1771
1856
|
exports.FormSwitch = FormSwitch;
|
|
1857
|
+
exports.INLINE_FIELD_ROW_MIN_WIDTH = INLINE_FIELD_ROW_MIN_WIDTH;
|
|
1858
|
+
exports.InlineFieldRow = InlineFieldRow;
|
|
1772
1859
|
exports.SelectControl = SelectControl;
|
|
1773
1860
|
exports.ThemedTextInput = ThemedTextInput;
|
|
1774
1861
|
exports.TypeaheadControl = TypeaheadControl;
|
|
1775
1862
|
exports.controlStyles = controlStyles;
|
|
1776
1863
|
exports.groupAriaChecked = groupAriaChecked;
|
|
1864
|
+
exports.inlineFieldRowLayout = inlineFieldRowLayout;
|
|
1777
1865
|
exports.isUnmatched = isUnmatched;
|
|
1778
1866
|
exports.resolveGroupSelection = resolveGroupSelection;
|
|
1779
1867
|
exports.suggestOptions = suggestOptions;
|