@dloizides/ui-forms 1.13.2 → 1.13.4

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.13.3
4
+
5
+ **Placeholder text was too dark — it read like an already-filled value.**
6
+
7
+ `useThemedInput` painted the placeholder with the theme's `textSecondary` — a deliberately
8
+ dark, accessible grey (design-tokens UX-11) that also renders readable secondary *copy*. At
9
+ full strength a placeholder (e.g. `follower` in a "Dance role" box) was hard to tell apart
10
+ from entered text. It is now `textSecondary` composited toward the field background at 0.6
11
+ alpha, so a hint reads clearly lighter than the solid entered text (`colors.text`) while
12
+ keeping the theme hue — and it works in dark mode too (it composites toward whatever the
13
+ field background is). The field's visible label still carries the accessible name, so this
14
+ is a usability win, not an a11y regression. Affects every `@dloizides/ui-forms`-driven input
15
+ (`FormField`, `Field`, `ThemedTextInput`, the `ui-tables` `Filters` search box) across all
16
+ seven portals.
17
+
3
18
  ## 1.12.0
4
19
 
5
20
  **`FormField` gained `labelHidden` — hide the visible label, keep the accessible name.**
package/dist/index.d.mts CHANGED
@@ -461,7 +461,11 @@ interface UseThemedInputOptions {
461
461
  interface ThemedInput {
462
462
  /** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
463
463
  style: TextStyle;
464
- /** A readable mid-grey placeholder colour from the theme. */
464
+ /**
465
+ * The placeholder colour: the theme's `textSecondary` composited toward the field
466
+ * background ({@link PLACEHOLDER_ALPHA}) so a placeholder reads as a faint hint, clearly
467
+ * lighter than the solid entered text rather than looking like an already-filled value.
468
+ */
465
469
  placeholderTextColor: string;
466
470
  isFocused: boolean;
467
471
  isHovered: boolean;
@@ -733,12 +737,13 @@ declare function DateRangeControl({ value, onChange, onSubmit, fromLabel, toLabe
733
737
  /**
734
738
  * `AnchoredMenu` — the floating option list shared by `SelectControl` and `TypeaheadControl`.
735
739
  *
736
- * By default it renders an in-tree, absolutely-positioned popover under its anchor
737
- * (`position:absolute; top:100%; zIndex; elevation`). Set {@link AnchoredMenuProps.usePortal} to
738
- * render it — on web only — in a PORTAL to `document.body` with `position: fixed` at the trigger's
739
- * measured rect instead: that escapes react-native-web's trapped `z-index: 0` stacking contexts and
740
- * any ancestor `overflow: hidden`, so the menu is never painted under / clipped by later siblings
741
- * (the fix for the Country typeahead menu that hid behind the content below it). See {@link menuPortal}.
740
+ * By DEFAULT (web) it renders in a PORTAL to `document.body` with `position: fixed` at the trigger's
741
+ * measured rect: that escapes react-native-web's trapped `z-index: 0` stacking contexts and any
742
+ * ancestor `overflow: hidden`, so the menu is never painted under / clipped by later siblings (a
743
+ * table, a card, the next filter field). On native, and when {@link AnchoredMenuProps.usePortal} is
744
+ * explicitly `false`, it renders an in-tree, absolutely-positioned popover under its anchor
745
+ * (`position:absolute; top:100%; zIndex; elevation`) — which is exactly what left `SelectControl`'s
746
+ * menu hidden behind the attendee table until the default flipped. See {@link menuPortal}.
742
747
  * On web it dismisses on outside-click / Escape; on native the caller closes it on blur/select.
743
748
  * Purely presentational + theme-flat, so it stays reusable.
744
749
  *
@@ -773,8 +778,13 @@ interface AnchoredMenuProps {
773
778
  * On web, render the popover in a portal to `document.body` with `position: fixed` at the anchor's
774
779
  * measured rect, so it escapes react-native-web's trapped stacking contexts and any ancestor
775
780
  * `overflow: hidden` (the fix for a menu that paints under / is clipped by the content below it).
776
- * No effect on native. Default `false` — the existing in-tree behaviour, so `SelectControl`
777
- * usages are unchanged; `TypeaheadControl` opts in.
781
+ * No effect on native (the `IS_WEB` guard keeps native in-tree regardless).
782
+ *
783
+ * Default `true` — portalling is the CORRECT default: an in-tree popover is always at risk of
784
+ * being painted under a later-painting sibling (a table, a card, the next filter field). The old
785
+ * default was `false`, which silently left `SelectControl`'s menu hidden behind the attendee table
786
+ * (a recurrence of the exact bug this mechanism fixed for `TypeaheadControl`). Pass `usePortal={false}`
787
+ * only for the rare case that genuinely wants the menu clipped to its container.
778
788
  */
779
789
  usePortal?: boolean;
780
790
  }
package/dist/index.d.ts CHANGED
@@ -461,7 +461,11 @@ interface UseThemedInputOptions {
461
461
  interface ThemedInput {
462
462
  /** The themed input style for the current focus/hover state (memoised). Merge AFTER your box style. */
463
463
  style: TextStyle;
464
- /** A readable mid-grey placeholder colour from the theme. */
464
+ /**
465
+ * The placeholder colour: the theme's `textSecondary` composited toward the field
466
+ * background ({@link PLACEHOLDER_ALPHA}) so a placeholder reads as a faint hint, clearly
467
+ * lighter than the solid entered text rather than looking like an already-filled value.
468
+ */
465
469
  placeholderTextColor: string;
466
470
  isFocused: boolean;
467
471
  isHovered: boolean;
@@ -733,12 +737,13 @@ declare function DateRangeControl({ value, onChange, onSubmit, fromLabel, toLabe
733
737
  /**
734
738
  * `AnchoredMenu` — the floating option list shared by `SelectControl` and `TypeaheadControl`.
735
739
  *
736
- * By default it renders an in-tree, absolutely-positioned popover under its anchor
737
- * (`position:absolute; top:100%; zIndex; elevation`). Set {@link AnchoredMenuProps.usePortal} to
738
- * render it — on web only — in a PORTAL to `document.body` with `position: fixed` at the trigger's
739
- * measured rect instead: that escapes react-native-web's trapped `z-index: 0` stacking contexts and
740
- * any ancestor `overflow: hidden`, so the menu is never painted under / clipped by later siblings
741
- * (the fix for the Country typeahead menu that hid behind the content below it). See {@link menuPortal}.
740
+ * By DEFAULT (web) it renders in a PORTAL to `document.body` with `position: fixed` at the trigger's
741
+ * measured rect: that escapes react-native-web's trapped `z-index: 0` stacking contexts and any
742
+ * ancestor `overflow: hidden`, so the menu is never painted under / clipped by later siblings (a
743
+ * table, a card, the next filter field). On native, and when {@link AnchoredMenuProps.usePortal} is
744
+ * explicitly `false`, it renders an in-tree, absolutely-positioned popover under its anchor
745
+ * (`position:absolute; top:100%; zIndex; elevation`) — which is exactly what left `SelectControl`'s
746
+ * menu hidden behind the attendee table until the default flipped. See {@link menuPortal}.
742
747
  * On web it dismisses on outside-click / Escape; on native the caller closes it on blur/select.
743
748
  * Purely presentational + theme-flat, so it stays reusable.
744
749
  *
@@ -773,8 +778,13 @@ interface AnchoredMenuProps {
773
778
  * On web, render the popover in a portal to `document.body` with `position: fixed` at the anchor's
774
779
  * measured rect, so it escapes react-native-web's trapped stacking contexts and any ancestor
775
780
  * `overflow: hidden` (the fix for a menu that paints under / is clipped by the content below it).
776
- * No effect on native. Default `false` — the existing in-tree behaviour, so `SelectControl`
777
- * usages are unchanged; `TypeaheadControl` opts in.
781
+ * No effect on native (the `IS_WEB` guard keeps native in-tree regardless).
782
+ *
783
+ * Default `true` — portalling is the CORRECT default: an in-tree popover is always at risk of
784
+ * being painted under a later-painting sibling (a table, a card, the next filter field). The old
785
+ * default was `false`, which silently left `SelectControl`'s menu hidden behind the attendee table
786
+ * (a recurrence of the exact bug this mechanism fixed for `TypeaheadControl`). Pass `usePortal={false}`
787
+ * only for the rare case that genuinely wants the menu clipped to its container.
778
788
  */
779
789
  usePortal?: boolean;
780
790
  }
package/dist/index.js CHANGED
@@ -471,6 +471,7 @@ var TRANSITION_TIMING = "ease";
471
471
  var FOCUS_RING_WIDTH = 3;
472
472
  var FOCUS_RING_ALPHA = 0.16;
473
473
  var HOVER_BORDER_ALPHA = 0.22;
474
+ var PLACEHOLDER_ALPHA = 0.6;
474
475
  var HEX_RADIX = 16;
475
476
  var HEX_SHORT_LENGTH = 4;
476
477
  var HEX_FULL_LENGTH = 7;
@@ -552,7 +553,7 @@ function useThemedInput(options = {}) {
552
553
  );
553
554
  return {
554
555
  style,
555
- placeholderTextColor: colors.textSecondary,
556
+ placeholderTextColor: withAlpha(colors.textSecondary, PLACEHOLDER_ALPHA),
556
557
  isFocused,
557
558
  isHovered,
558
559
  focusBind,
@@ -1106,7 +1107,7 @@ function AnchoredMenu({
1106
1107
  optionHint,
1107
1108
  testID,
1108
1109
  anchorRef,
1109
- usePortal = false
1110
+ usePortal = true
1110
1111
  }) {
1111
1112
  const menuRef = React2__default.default.useRef(null);
1112
1113
  useDismiss(anchorRef, menuRef, onDismiss);