@dloizides/ui-forms 1.18.7 → 1.19.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/dist/index.d.mts CHANGED
@@ -470,6 +470,8 @@ interface UseThemedInputOptions {
470
470
  onFocus?: (e: FocusEvent) => void;
471
471
  /** Consumer blur handler — composed with the internal focus-state toggle. */
472
472
  onBlur?: (e: BlurEvent) => void;
473
+ /** `false` renders the read-only treatment: the recessed ground fill and the secondary ink. */
474
+ editable?: boolean;
473
475
  }
474
476
  interface ThemedInput {
475
477
  /** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
package/dist/index.d.ts CHANGED
@@ -470,6 +470,8 @@ interface UseThemedInputOptions {
470
470
  onFocus?: (e: FocusEvent) => void;
471
471
  /** Consumer blur handler — composed with the internal focus-state toggle. */
472
472
  onBlur?: (e: BlurEvent) => void;
473
+ /** `false` renders the read-only treatment: the recessed ground fill and the secondary ink. */
474
+ editable?: boolean;
473
475
  }
474
476
  interface ThemedInput {
475
477
  /** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
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, semantic } = theme;
205
- const errorColor = semantic.error["500"];
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 ?? "";
@@ -635,9 +640,9 @@ function withAlpha(color, alpha) {
635
640
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
636
641
  }
637
642
  function useThemedInput(options = {}) {
638
- const { hasError = false, onFocus, onBlur } = options;
643
+ const { hasError = false, onFocus, onBlur, editable = true } = options;
639
644
  const { theme } = uiFeedback.useUi();
640
- const { colors, palette, semantic } = theme;
645
+ const { colors, palette } = theme;
641
646
  const [isFocused, setIsFocused] = React2.useState(false);
642
647
  const [isHovered, setIsHovered] = React2.useState(false);
643
648
  const handleFocus = React2.useCallback(
@@ -657,13 +662,14 @@ function useThemedInput(options = {}) {
657
662
  const handleHoverIn = React2.useCallback(() => setIsHovered(true), []);
658
663
  const handleHoverOut = React2.useCallback(() => setIsHovered(false), []);
659
664
  const primary = palette.primary["500"];
660
- const errorColor = semantic.error["500"];
665
+ const errorColor = fieldErrorInk(theme);
661
666
  const style = React2.useMemo(() => {
662
667
  const restBorder = hasError ? errorColor : colors.border;
663
668
  const focusBorder = hasError ? errorColor : primary;
664
669
  const borderColor = isFocused ? focusBorder : isHovered ? withAlpha(colors.text, HOVER_BORDER_ALPHA) : restBorder;
665
- const backgroundColor = isFocused ? colors.surface : colors.surfaceElevated;
666
- const base = { color: colors.text, borderColor, backgroundColor };
670
+ const editableFill = isFocused ? colors.surface : colors.surfaceElevated;
671
+ const backgroundColor = editable ? editableFill : colors.background;
672
+ const base = { color: editable ? colors.text : colors.textSecondary, borderColor, backgroundColor };
667
673
  if (!IS_WEB5) return base;
668
674
  const ringColor = hasError ? errorColor : uiButtons.themeFocusRingColor(theme);
669
675
  const ring = isFocused ? designTokens.focusRingOutline(ringColor) : NO_RING;
@@ -683,6 +689,9 @@ function useThemedInput(options = {}) {
683
689
  colors.border,
684
690
  colors.surface,
685
691
  colors.surfaceElevated,
692
+ colors.background,
693
+ colors.textSecondary,
694
+ editable,
686
695
  primary,
687
696
  errorColor,
688
697
  theme
@@ -735,7 +744,7 @@ var ThemedTextInput = React2__default.default.forwardRef(function ThemedTextInpu
735
744
  placeholderTextColor: themedPlaceholder,
736
745
  focusBind,
737
746
  hoverBind
738
- } = useThemedInput({ hasError, onFocus, onBlur });
747
+ } = useThemedInput({ hasError, onFocus, onBlur, editable: rest.editable });
739
748
  const webA11y = webFieldA11y({ describedById, hasError, required: requiredField });
740
749
  const boxStyle = unstyledBox ? null : controlStyles.input;
741
750
  const multilineStyle = rest.multiline === true && !unstyledBox ? boxStyles.multiline : null;
@@ -1588,7 +1597,7 @@ function TypeaheadControl({
1588
1597
  testID
1589
1598
  }) {
1590
1599
  const { theme } = uiFeedback.useUi();
1591
- const { colors, palette, semantic } = theme;
1600
+ const { colors, palette } = theme;
1592
1601
  const anchorRef = React2.useRef(null);
1593
1602
  const [isOpen, setIsOpen] = React2.useState(false);
1594
1603
  const exactPick = React2.useMemo(() => options.some((o) => o.label === value), [options, value]);
@@ -1636,7 +1645,7 @@ function TypeaheadControl({
1636
1645
  onFocus: () => setIsOpen(true),
1637
1646
  onBlur: handleBlur,
1638
1647
  onSubmitEditing: handleSubmit,
1639
- style: [controlStyles.input, { borderColor: hasError ? semantic.error["500"] : colors.border, backgroundColor: colors.surface, color: colors.text }],
1648
+ style: [controlStyles.input, { borderColor: hasError ? fieldErrorInk(theme) : colors.border, backgroundColor: colors.surface, color: colors.text }],
1640
1649
  testID: `${testID}-input`
1641
1650
  }
1642
1651
  ),
@@ -1654,7 +1663,7 @@ function TypeaheadControl({
1654
1663
  usePortal: true
1655
1664
  }
1656
1665
  ) : null,
1657
- hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { role: "alert", style: [controlStyles.error, { color: semantic.error["500"] }], testID: `${testID}-error`, children: error }) : null
1666
+ hasError ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { role: "alert", style: [controlStyles.error, { color: fieldErrorInk(theme) }], testID: `${testID}-error`, children: error }) : null
1658
1667
  ] });
1659
1668
  }
1660
1669
  var WEB_DATE_PROPS = typeof document !== "undefined" ? { type: "date" } : {};