@dloizides/ui-nav 1.16.1 → 1.17.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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.17.0
4
+
5
+ Two live-defect fixes to the shared sidebar chrome. Behavioral/additive — no breaking API.
6
+
7
+ - **Fix (two search bars on desktop → mutually exclusive by affordance).** 1.16.1 shipped the
8
+ desktop inline `SidebarSearch` field, but the ⌘K `CommandPaletteTrigger` could be present at
9
+ the same time, so a wide viewport showed BOTH. `Sidebar` now owns both affordances and renders
10
+ exactly ONE, chosen by its own viewport width via `resolveSearchAffordance`:
11
+ - inline affordance (≥768) → the inline field ONLY; the ⌘K trigger is suppressed.
12
+ - palette affordance (<768) → the ⌘K trigger ONLY; the inline field is suppressed.
13
+ - The ⌘K keyboard shortcut (`useCommandPaletteHotkey`) is untouched and stays bound at every width.
14
+ - **Additive API**: new `Sidebar.paletteTrigger?: SidebarPaletteTriggerConfig`
15
+ (`{ label, hint, shortcut, onOpen, testID? }`), forwarded from `NavShellSideRail.paletteTrigger`.
16
+ Consumers that wire neither, or only the inline field, are unchanged (the inline field simply
17
+ no longer renders below 768, where a persistent field would steal vertical space).
18
+
19
+ - **Fix (hover wash never appeared on RN-web).** The nav rows were `TouchableOpacity`, which in
20
+ react-native-web has NO hover support and silently drops `onHoverIn`/`onHoverOut` — so the row's
21
+ `hovered` state never toggled and the primary-tinted overlay stayed at opacity 0. The leaf and
22
+ group-header rows in `NavExpandableItem` are now `Pressable`, whose `useHover` responder actually
23
+ drives `hovered`, lifting the token-tinted overlay to the hover wash (`HOVER_TINT_OPACITY`, ~160ms
24
+ reduced-motion-gated transition) — distinct from and lighter than the active tint. Token-only
25
+ (colours via the theme; no raw hex/rgb/hsl). aria wiring (`aria-current` / `aria-expanded`, which
26
+ `MobileDrawer` depends on) is preserved across the switch.
27
+
3
28
  ## 1.16.1
4
29
 
5
30
  - **Fix (NavShell forwards inline-search props to the inner `Sidebar`).** 1.16.0 added
package/dist/index.d.mts CHANGED
@@ -100,6 +100,24 @@ interface SidebarSearchConfig extends SidebarSearchLabels {
100
100
  /** Shown in place of the list when the query matches nothing. */
101
101
  emptyText: string;
102
102
  }
103
+ /**
104
+ * The ⌘K command-palette trigger the sidebar renders as its NARROW-viewport search
105
+ * affordance (a persistent inline field would steal scarce vertical space on mobile
106
+ * — see {@link resolveSearchAffordance}). Pre-localized strings + the open handler;
107
+ * wire `onOpen` to the same handler as the ⌘K hotkey ({@link useCommandPaletteHotkey}).
108
+ */
109
+ interface SidebarPaletteTriggerConfig {
110
+ /** Placeholder-style label, e.g. "Search". */
111
+ label: string;
112
+ /** a11y hint describing what activating it does. */
113
+ hint: string;
114
+ /** The shortcut badge text, e.g. "⌘K". */
115
+ shortcut: string;
116
+ /** Open the palette (same handler as the ⌘K hotkey). */
117
+ onOpen: () => void;
118
+ /** testID for the trigger. Defaults to `sidebar-command-palette-trigger`. */
119
+ testID?: string;
120
+ }
103
121
  interface SidebarProps {
104
122
  /** Nav entries — already role-filtered / grouped by the app. */
105
123
  items: NavItem[];
@@ -121,12 +139,21 @@ interface SidebarProps {
121
139
  renderChevron?: (expanded: boolean, color: string, size: number) => React.ReactNode;
122
140
  /**
123
141
  * Opt into the persistent inline search field (desktop). Requires `search`
124
- * labels; when omitted the sidebar renders exactly as before. Prefer this on
125
- * the wide/full rail and the ⌘K palette on the mobile drawer.
142
+ * labels; when omitted the sidebar renders exactly as before. The field shows
143
+ * ONLY at the inline affordance (viewport 768, {@link resolveSearchAffordance});
144
+ * on a narrow viewport the ⌘K `paletteTrigger` is the search affordance instead.
126
145
  */
127
146
  enableInlineSearch?: boolean;
128
147
  /** Pre-localized inline-search strings — required for `enableInlineSearch`. */
129
148
  search?: SidebarSearchConfig;
149
+ /**
150
+ * Opt into the ⌘K {@link CommandPaletteTrigger} as the NARROW-viewport search
151
+ * affordance. Rendered ONLY at the palette affordance (viewport < 768); on a wide
152
+ * viewport it is suppressed so the inline field and the trigger are never both
153
+ * shown — they are mutually exclusive by affordance. The ⌘K hotkey stays bound at
154
+ * every width independently ({@link useCommandPaletteHotkey}).
155
+ */
156
+ paletteTrigger?: SidebarPaletteTriggerConfig;
130
157
  /** Controlled search query (optional — the sidebar owns the state when omitted). */
131
158
  searchQuery?: string;
132
159
  /** Called on each query change (with either controlled or internal state). */
@@ -138,7 +165,7 @@ interface SidebarProps {
138
165
  /** Extra container style overrides. */
139
166
  containerStyle?: ViewStyle | ViewStyle[];
140
167
  }
141
- declare const Sidebar: ({ items, pathname, onNavigate, title, regionLabel, navigateHint, expandHint, collapseHint, renderChevron, enableInlineSearch, search, searchQuery, onSearchChange, header, footer, containerStyle, }: SidebarProps) => React.ReactElement;
168
+ declare const Sidebar: ({ items, pathname, onNavigate, title, regionLabel, navigateHint, expandHint, collapseHint, renderChevron, enableInlineSearch, search, paletteTrigger, searchQuery, onSearchChange, header, footer, containerStyle, }: SidebarProps) => React.ReactElement;
142
169
 
143
170
  /**
144
171
  * SidebarChevron — the built-in disclosure caret for an expandable sidebar
@@ -737,6 +764,12 @@ interface NavShellSideRail {
737
764
  enableInlineSearch?: boolean;
738
765
  /** Pre-localized inline-search strings — required for `enableInlineSearch`. Forwarded to `Sidebar.search`. */
739
766
  search?: SidebarSearchConfig;
767
+ /**
768
+ * Opt the inner `Sidebar` into the ⌘K palette trigger as its narrow-viewport
769
+ * search affordance. Mutually exclusive with the inline field by viewport width
770
+ * (never both shown). Forwarded to `Sidebar.paletteTrigger`.
771
+ */
772
+ paletteTrigger?: SidebarPaletteTriggerConfig;
740
773
  /** Controlled search query (optional — the Sidebar owns the state when omitted). Forwarded to `Sidebar.searchQuery`. */
741
774
  searchQuery?: string;
742
775
  /** Called on each query change (controlled or internal). Forwarded to `Sidebar.onSearchChange`. */
@@ -1233,6 +1266,9 @@ declare const navStyles: {
1233
1266
  sidebarSpacer: {
1234
1267
  flex: number;
1235
1268
  };
1269
+ sidebarTriggerSlot: {
1270
+ marginBottom: number;
1271
+ };
1236
1272
  sidebarEmpty: {
1237
1273
  fontSize: number;
1238
1274
  paddingVertical: number;
@@ -1453,4 +1489,4 @@ declare const NAV_ICON_SIZE = 14;
1453
1489
  /** Chevron icon size for expandable sections. */
1454
1490
  declare const CHEVRON_ICON_SIZE = 12;
1455
1491
 
1456
- export { ACTIVE_BORDER_RADIUS, ACTIVE_TINT_OPACITY, APP_SHELL_SUFFIX, type AccountPlan, type AccountState, AppShell, type AppShellProps, type AppShellWidth, BASE_INDENT, CHEVRON_ICON_SIZE, CollapsedRail, type CollapsedRailProps, type CollapsedRailRange, type CommandItem, CommandPalette, type CommandPaletteLabels, type CommandPaletteProps, CommandPaletteTrigger, type CommandPaletteTriggerProps, DEFAULT_COLLAPSED_RAIL_MAX, DEFAULT_SEARCH_BREAKPOINT, DarkModeControl, type DarkModeControlProps, type DarkModeOption, type DarkModeVariant, HOVER_TINT_OPACITY, NAV_ICON_SIZE, NAV_LINK_GAP, NAV_ROW_RADIUS, NAV_TEST_IDS, Nav, NavBar, type NavBarProps, NavExpandableItem, type NavExpandableItemProps, type NavItem, type NavOrientation, NavOverflowMenu, type NavOverflowMenuProps, type NavProps, NavShell, type NavShellCollapsedRail, type NavShellLayout, type NavShellProps, type NavShellSideRail, type NavShellTopBar, type NavUser, PillNav, type PillNavProps, RAIL_FULL_BREAKPOINT, type RailMode, type ResolveRailModeArgs, type SearchAffordance, type ShellMessage, Sidebar, SidebarChevron, type SidebarChevronProps, type SidebarProps, SidebarSearch, type SidebarSearchConfig, type SidebarSearchLabels, type SidebarSearchProps, Topbar, type TopbarAction, type TopbarProps, type TopbarUser, accessibleNavItems, collapsedRailStyles, darkModeStyles, expandableStyles, filterCommands, filterNavItems, isFilterActive, isRouteActive, navStyles, pillNavStyles, resolveContentMaxWidth, resolveRailMode, resolveSearchAffordance, roleRoutesToNavItems, searchTokens, useCommandPaletteHotkey, useContentMaxWidth };
1492
+ export { ACTIVE_BORDER_RADIUS, ACTIVE_TINT_OPACITY, APP_SHELL_SUFFIX, type AccountPlan, type AccountState, AppShell, type AppShellProps, type AppShellWidth, BASE_INDENT, CHEVRON_ICON_SIZE, CollapsedRail, type CollapsedRailProps, type CollapsedRailRange, type CommandItem, CommandPalette, type CommandPaletteLabels, type CommandPaletteProps, CommandPaletteTrigger, type CommandPaletteTriggerProps, DEFAULT_COLLAPSED_RAIL_MAX, DEFAULT_SEARCH_BREAKPOINT, DarkModeControl, type DarkModeControlProps, type DarkModeOption, type DarkModeVariant, HOVER_TINT_OPACITY, NAV_ICON_SIZE, NAV_LINK_GAP, NAV_ROW_RADIUS, NAV_TEST_IDS, Nav, NavBar, type NavBarProps, NavExpandableItem, type NavExpandableItemProps, type NavItem, type NavOrientation, NavOverflowMenu, type NavOverflowMenuProps, type NavProps, NavShell, type NavShellCollapsedRail, type NavShellLayout, type NavShellProps, type NavShellSideRail, type NavShellTopBar, type NavUser, PillNav, type PillNavProps, RAIL_FULL_BREAKPOINT, type RailMode, type ResolveRailModeArgs, type SearchAffordance, type ShellMessage, Sidebar, SidebarChevron, type SidebarChevronProps, type SidebarPaletteTriggerConfig, type SidebarProps, SidebarSearch, type SidebarSearchConfig, type SidebarSearchLabels, type SidebarSearchProps, Topbar, type TopbarAction, type TopbarProps, type TopbarUser, accessibleNavItems, collapsedRailStyles, darkModeStyles, expandableStyles, filterCommands, filterNavItems, isFilterActive, isRouteActive, navStyles, pillNavStyles, resolveContentMaxWidth, resolveRailMode, resolveSearchAffordance, roleRoutesToNavItems, searchTokens, useCommandPaletteHotkey, useContentMaxWidth };
package/dist/index.d.ts CHANGED
@@ -100,6 +100,24 @@ interface SidebarSearchConfig extends SidebarSearchLabels {
100
100
  /** Shown in place of the list when the query matches nothing. */
101
101
  emptyText: string;
102
102
  }
103
+ /**
104
+ * The ⌘K command-palette trigger the sidebar renders as its NARROW-viewport search
105
+ * affordance (a persistent inline field would steal scarce vertical space on mobile
106
+ * — see {@link resolveSearchAffordance}). Pre-localized strings + the open handler;
107
+ * wire `onOpen` to the same handler as the ⌘K hotkey ({@link useCommandPaletteHotkey}).
108
+ */
109
+ interface SidebarPaletteTriggerConfig {
110
+ /** Placeholder-style label, e.g. "Search". */
111
+ label: string;
112
+ /** a11y hint describing what activating it does. */
113
+ hint: string;
114
+ /** The shortcut badge text, e.g. "⌘K". */
115
+ shortcut: string;
116
+ /** Open the palette (same handler as the ⌘K hotkey). */
117
+ onOpen: () => void;
118
+ /** testID for the trigger. Defaults to `sidebar-command-palette-trigger`. */
119
+ testID?: string;
120
+ }
103
121
  interface SidebarProps {
104
122
  /** Nav entries — already role-filtered / grouped by the app. */
105
123
  items: NavItem[];
@@ -121,12 +139,21 @@ interface SidebarProps {
121
139
  renderChevron?: (expanded: boolean, color: string, size: number) => React.ReactNode;
122
140
  /**
123
141
  * Opt into the persistent inline search field (desktop). Requires `search`
124
- * labels; when omitted the sidebar renders exactly as before. Prefer this on
125
- * the wide/full rail and the ⌘K palette on the mobile drawer.
142
+ * labels; when omitted the sidebar renders exactly as before. The field shows
143
+ * ONLY at the inline affordance (viewport 768, {@link resolveSearchAffordance});
144
+ * on a narrow viewport the ⌘K `paletteTrigger` is the search affordance instead.
126
145
  */
127
146
  enableInlineSearch?: boolean;
128
147
  /** Pre-localized inline-search strings — required for `enableInlineSearch`. */
129
148
  search?: SidebarSearchConfig;
149
+ /**
150
+ * Opt into the ⌘K {@link CommandPaletteTrigger} as the NARROW-viewport search
151
+ * affordance. Rendered ONLY at the palette affordance (viewport < 768); on a wide
152
+ * viewport it is suppressed so the inline field and the trigger are never both
153
+ * shown — they are mutually exclusive by affordance. The ⌘K hotkey stays bound at
154
+ * every width independently ({@link useCommandPaletteHotkey}).
155
+ */
156
+ paletteTrigger?: SidebarPaletteTriggerConfig;
130
157
  /** Controlled search query (optional — the sidebar owns the state when omitted). */
131
158
  searchQuery?: string;
132
159
  /** Called on each query change (with either controlled or internal state). */
@@ -138,7 +165,7 @@ interface SidebarProps {
138
165
  /** Extra container style overrides. */
139
166
  containerStyle?: ViewStyle | ViewStyle[];
140
167
  }
141
- declare const Sidebar: ({ items, pathname, onNavigate, title, regionLabel, navigateHint, expandHint, collapseHint, renderChevron, enableInlineSearch, search, searchQuery, onSearchChange, header, footer, containerStyle, }: SidebarProps) => React.ReactElement;
168
+ declare const Sidebar: ({ items, pathname, onNavigate, title, regionLabel, navigateHint, expandHint, collapseHint, renderChevron, enableInlineSearch, search, paletteTrigger, searchQuery, onSearchChange, header, footer, containerStyle, }: SidebarProps) => React.ReactElement;
142
169
 
143
170
  /**
144
171
  * SidebarChevron — the built-in disclosure caret for an expandable sidebar
@@ -737,6 +764,12 @@ interface NavShellSideRail {
737
764
  enableInlineSearch?: boolean;
738
765
  /** Pre-localized inline-search strings — required for `enableInlineSearch`. Forwarded to `Sidebar.search`. */
739
766
  search?: SidebarSearchConfig;
767
+ /**
768
+ * Opt the inner `Sidebar` into the ⌘K palette trigger as its narrow-viewport
769
+ * search affordance. Mutually exclusive with the inline field by viewport width
770
+ * (never both shown). Forwarded to `Sidebar.paletteTrigger`.
771
+ */
772
+ paletteTrigger?: SidebarPaletteTriggerConfig;
740
773
  /** Controlled search query (optional — the Sidebar owns the state when omitted). Forwarded to `Sidebar.searchQuery`. */
741
774
  searchQuery?: string;
742
775
  /** Called on each query change (controlled or internal). Forwarded to `Sidebar.onSearchChange`. */
@@ -1233,6 +1266,9 @@ declare const navStyles: {
1233
1266
  sidebarSpacer: {
1234
1267
  flex: number;
1235
1268
  };
1269
+ sidebarTriggerSlot: {
1270
+ marginBottom: number;
1271
+ };
1236
1272
  sidebarEmpty: {
1237
1273
  fontSize: number;
1238
1274
  paddingVertical: number;
@@ -1453,4 +1489,4 @@ declare const NAV_ICON_SIZE = 14;
1453
1489
  /** Chevron icon size for expandable sections. */
1454
1490
  declare const CHEVRON_ICON_SIZE = 12;
1455
1491
 
1456
- export { ACTIVE_BORDER_RADIUS, ACTIVE_TINT_OPACITY, APP_SHELL_SUFFIX, type AccountPlan, type AccountState, AppShell, type AppShellProps, type AppShellWidth, BASE_INDENT, CHEVRON_ICON_SIZE, CollapsedRail, type CollapsedRailProps, type CollapsedRailRange, type CommandItem, CommandPalette, type CommandPaletteLabels, type CommandPaletteProps, CommandPaletteTrigger, type CommandPaletteTriggerProps, DEFAULT_COLLAPSED_RAIL_MAX, DEFAULT_SEARCH_BREAKPOINT, DarkModeControl, type DarkModeControlProps, type DarkModeOption, type DarkModeVariant, HOVER_TINT_OPACITY, NAV_ICON_SIZE, NAV_LINK_GAP, NAV_ROW_RADIUS, NAV_TEST_IDS, Nav, NavBar, type NavBarProps, NavExpandableItem, type NavExpandableItemProps, type NavItem, type NavOrientation, NavOverflowMenu, type NavOverflowMenuProps, type NavProps, NavShell, type NavShellCollapsedRail, type NavShellLayout, type NavShellProps, type NavShellSideRail, type NavShellTopBar, type NavUser, PillNav, type PillNavProps, RAIL_FULL_BREAKPOINT, type RailMode, type ResolveRailModeArgs, type SearchAffordance, type ShellMessage, Sidebar, SidebarChevron, type SidebarChevronProps, type SidebarProps, SidebarSearch, type SidebarSearchConfig, type SidebarSearchLabels, type SidebarSearchProps, Topbar, type TopbarAction, type TopbarProps, type TopbarUser, accessibleNavItems, collapsedRailStyles, darkModeStyles, expandableStyles, filterCommands, filterNavItems, isFilterActive, isRouteActive, navStyles, pillNavStyles, resolveContentMaxWidth, resolveRailMode, resolveSearchAffordance, roleRoutesToNavItems, searchTokens, useCommandPaletteHotkey, useContentMaxWidth };
1492
+ export { ACTIVE_BORDER_RADIUS, ACTIVE_TINT_OPACITY, APP_SHELL_SUFFIX, type AccountPlan, type AccountState, AppShell, type AppShellProps, type AppShellWidth, BASE_INDENT, CHEVRON_ICON_SIZE, CollapsedRail, type CollapsedRailProps, type CollapsedRailRange, type CommandItem, CommandPalette, type CommandPaletteLabels, type CommandPaletteProps, CommandPaletteTrigger, type CommandPaletteTriggerProps, DEFAULT_COLLAPSED_RAIL_MAX, DEFAULT_SEARCH_BREAKPOINT, DarkModeControl, type DarkModeControlProps, type DarkModeOption, type DarkModeVariant, HOVER_TINT_OPACITY, NAV_ICON_SIZE, NAV_LINK_GAP, NAV_ROW_RADIUS, NAV_TEST_IDS, Nav, NavBar, type NavBarProps, NavExpandableItem, type NavExpandableItemProps, type NavItem, type NavOrientation, NavOverflowMenu, type NavOverflowMenuProps, type NavProps, NavShell, type NavShellCollapsedRail, type NavShellLayout, type NavShellProps, type NavShellSideRail, type NavShellTopBar, type NavUser, PillNav, type PillNavProps, RAIL_FULL_BREAKPOINT, type RailMode, type ResolveRailModeArgs, type SearchAffordance, type ShellMessage, Sidebar, SidebarChevron, type SidebarChevronProps, type SidebarPaletteTriggerConfig, type SidebarProps, SidebarSearch, type SidebarSearchConfig, type SidebarSearchLabels, type SidebarSearchProps, Topbar, type TopbarAction, type TopbarProps, type TopbarUser, accessibleNavItems, collapsedRailStyles, darkModeStyles, expandableStyles, filterCommands, filterNavItems, isFilterActive, isRouteActive, navStyles, pillNavStyles, resolveContentMaxWidth, resolveRailMode, resolveSearchAffordance, roleRoutesToNavItems, searchTokens, useCommandPaletteHotkey, useContentMaxWidth };