@dloizides/ui-nav 1.2.0 → 1.4.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 +63 -22
- package/README.md +15 -2
- package/dist/index.d.mts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +208 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,63 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 1.
|
|
4
|
-
|
|
5
|
-
Add
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
Add an optional **`sidebar`** slot to `AppShell` — the back-office layout.
|
|
6
|
+
|
|
7
|
+
`AppShell` could only stack vertically (header → nav strip → banner → scrolling content),
|
|
8
|
+
so a product with a persistent LEFT RAIL (Agora's merchant admin: products / categories /
|
|
9
|
+
coupons / settings) had to hand-compose `Topbar` + `Sidebar` + a `ScrollView` row and give
|
|
10
|
+
up the shell's auth gate and loading/error/forbidden state cards. Supplying `sidebar` now
|
|
11
|
+
lays the body out as a ROW — the rail on the left, the width-disciplined scrolling content
|
|
12
|
+
column on the right — while every existing feature (gate, state cards, `width`,
|
|
13
|
+
`chromeAlignment`) keeps working.
|
|
14
|
+
|
|
15
|
+
The new region is exposed as `` `${testID}${APP_SHELL_SUFFIX.sidebar}` `` (`-sidebar`).
|
|
16
|
+
|
|
17
|
+
**Backwards compatible.** Omit `sidebar` and the render tree is byte-identical to 1.3.0 —
|
|
18
|
+
erevna / katalogos / kefi / aml-v2 are untouched. Pinned by a test asserting no `-sidebar`
|
|
19
|
+
region exists when the slot is omitted.
|
|
20
|
+
|
|
21
|
+
## 1.3.0
|
|
22
|
+
|
|
23
|
+
Give the `NavBar` the v1 `.gn-links` look + a full accessibility pass (and extend the
|
|
24
|
+
same a11y bar to `Sidebar`/`Topbar`).
|
|
25
|
+
|
|
26
|
+
**Look & hover (NavBar).** Each link is a rounded-pill target with the v1 hover
|
|
27
|
+
affordance — muted at rest, and on HOVER the text brightens to full contrast while a
|
|
28
|
+
subtle rounded-pill background appears; the ACTIVE link is a solid accent pill. All
|
|
29
|
+
theme-driven (rest = `textSecondary`, hover text = `text`, hover bg = `surfaceElevated`,
|
|
30
|
+
active/ring = `palette.primary`). Hover/focus are web-only (`onHoverIn/Out`, `onFocus/Blur`
|
|
31
|
+
via `Pressable`); native stays at the rest style. The hover cross-fade is cheap CSS and is
|
|
32
|
+
disabled under `prefers-reduced-motion: reduce` (new `useReducedMotion`). Backwards
|
|
33
|
+
compatible — the hover pill is the default (aml-v2 is the only `NavBar` consumer) and the
|
|
34
|
+
brand/right slots, responsive hamburger collapse, and `containerStyle` width behaviour are
|
|
35
|
+
unchanged.
|
|
36
|
+
|
|
37
|
+
**Accessibility.** NavBar toggle now carries `aria-controls` pointing at the collapsible
|
|
38
|
+
links region (id via `nativeID`), keeps `aria-expanded`, and gains a themed keyboard focus
|
|
39
|
+
ring; links keep `aria-current="page"` + `role="link"` and gain a focus ring; link/toggle
|
|
40
|
+
touch targets are now ≥44×44. `Sidebar` leaves gain `aria-current="page"` + a focus ring;
|
|
41
|
+
`Topbar` action buttons gain a focus ring (new internal `FocusableTouchable`). Focus rings
|
|
42
|
+
never remove the outline without a themed replacement.
|
|
43
|
+
|
|
44
|
+
## 1.2.0
|
|
45
|
+
|
|
46
|
+
Add `NavBar` — a config-driven **horizontal top navigation bar**, the top-bar
|
|
47
|
+
counterpart to `Sidebar`. It renders the same caller-supplied `NavItem[]` as inline
|
|
48
|
+
links across the top (brand left slot + inline links + free-form right slot), with
|
|
49
|
+
an active-link highlight (`aria-current="page"`) and a responsive collapse to a
|
|
50
|
+
hamburger toggle below a configurable breakpoint (`collapseBelow`, default `760`) —
|
|
51
|
+
mirroring the v1 AML console `.global-nav`. Theme-driven (UiProvider colours),
|
|
52
|
+
`role="navigation"` landmark, keyboard-operable links. Purely additive: `Sidebar`,
|
|
53
|
+
`Topbar`, `AppShell`, and the role-gating helpers are unchanged. New `NAV_TEST_IDS`
|
|
54
|
+
entries `navBarToggle` / `navBarLinks`.
|
|
55
|
+
|
|
56
|
+
## 1.0.0
|
|
57
|
+
|
|
58
|
+
Initial release. `Sidebar` (leaf + expandable items, active-route highlight, header/footer
|
|
59
|
+
slots), `Topbar` (logo/language/notification/user/account/logout slots), and the
|
|
60
|
+
`accessibleNavItems` / `roleRoutesToNavItems` role-gating helpers (reusing
|
|
61
|
+
`resolveAccessibleRoutes` from `@dloizides/auth-web`). Chrome + metrics ported verbatim from
|
|
62
|
+
the byte-identical erevna-web / katalogos-web nav twins; every colour reads from the
|
|
63
|
+
`@dloizides/ui-feedback` UiProvider theme.
|
package/README.md
CHANGED
|
@@ -74,8 +74,21 @@ import { NavBar, type NavItem } from '@dloizides/ui-nav';
|
|
|
74
74
|
An app that renders a `Sidebar` today switches to a top bar by swapping the
|
|
75
75
|
`Sidebar` element for `NavBar` (same `items` / `pathname` / `onNavigate`) — e.g.
|
|
76
76
|
the AML v2 app drops `NavBar` into the `AppShell` `header` (or `nav`) slot so its
|
|
77
|
-
links sit across the top like the rest of the console.
|
|
78
|
-
|
|
77
|
+
links sit across the top like the rest of the console.
|
|
78
|
+
|
|
79
|
+
Each link is a rounded-pill target with the v1 `.gn-links` affordance: muted at
|
|
80
|
+
rest, brightening its text + showing a subtle pill background on **hover**, and a
|
|
81
|
+
solid accent pill when **active**. All colours are theme-driven (rest =
|
|
82
|
+
`textSecondary`, hover text = `text`, hover bg = `surfaceElevated`, active/ring =
|
|
83
|
+
`palette.primary`); hover/focus are web-only and the hover cross-fade honours
|
|
84
|
+
`prefers-reduced-motion`.
|
|
85
|
+
|
|
86
|
+
**Accessibility.** The container is a `role="navigation"` landmark named by
|
|
87
|
+
`regionLabel`; active links expose `aria-current="page"` + `role="link"`; the
|
|
88
|
+
responsive hamburger carries `role="button"`, `aria-expanded`, and `aria-controls`
|
|
89
|
+
pointing at the collapsible links region; every link/toggle is keyboard-operable
|
|
90
|
+
(Enter/Space) with a themed focus ring and a ≥44×44 touch target. `Sidebar` leaves
|
|
91
|
+
carry `aria-current="page"` and `Topbar` buttons a focus ring under the same bar.
|
|
79
92
|
|
|
80
93
|
### Role gating
|
|
81
94
|
|
package/dist/index.d.mts
CHANGED
|
@@ -154,10 +154,17 @@ declare const Topbar: ({ left, language, notificationSlot, user, account, logout
|
|
|
154
154
|
* collapses the links behind a hamburger toggle — mirroring the v1 AML console's
|
|
155
155
|
* responsive `.global-nav`.
|
|
156
156
|
*
|
|
157
|
+
* Look + feel: each link is a rounded-pill target with the v1 `.gn-links a`
|
|
158
|
+
* affordance — muted at rest, brightening text + a subtle pill background on
|
|
159
|
+
* HOVER, and a solid accent pill when ACTIVE. All colours are THEME-DRIVEN from
|
|
160
|
+
* the `@dloizides/ui-feedback` UiProvider (rest=`textSecondary`, hover text=`text`,
|
|
161
|
+
* hover bg=`surfaceElevated`, active=`palette.primary`, ring=`palette.primary`).
|
|
162
|
+
* Hover/focus are web-only (react-native-web); native stays at the rest style.
|
|
163
|
+
*
|
|
157
164
|
* Contract discipline (same as the rest of `@dloizides/ui-nav`): NO FM, router,
|
|
158
165
|
* icon set, or store imports. Labels are pre-localized strings, icons are render
|
|
159
|
-
* slots, and every colour is read from the
|
|
160
|
-
*
|
|
166
|
+
* slots, and every colour is read from the theme. This is purely additive —
|
|
167
|
+
* `Sidebar`/`Topbar` are unchanged.
|
|
161
168
|
*/
|
|
162
169
|
|
|
163
170
|
interface NavBarProps {
|
|
@@ -211,6 +218,13 @@ declare function useContentMaxWidth(width: AppShellWidth): number | 'full';
|
|
|
211
218
|
* (pending spinner / redirect-when-unauthenticated) and page state cards
|
|
212
219
|
* (loading / error / forbidden).
|
|
213
220
|
*
|
|
221
|
+
* A BACK-OFFICE variant is supported via the optional `sidebar` slot (added for
|
|
222
|
+
* Agora's merchant admin): supply a `<Sidebar>` and the body below the header /
|
|
223
|
+
* nav / banner becomes a ROW — a persistent left rail beside the scrolling
|
|
224
|
+
* content column — instead of the default single vertical stack. Omit `sidebar`
|
|
225
|
+
* and the render tree is byte-identical to before, so every existing consumer
|
|
226
|
+
* (erevna / katalogos / kefi) is untouched.
|
|
227
|
+
*
|
|
214
228
|
* Contract discipline (same as the rest of `@dloizides/ui-nav`): NO FM, router,
|
|
215
229
|
* or store imports. The app passes wired elements, pre-localized strings, and
|
|
216
230
|
* callbacks; every colour is routed through the `@dloizides/ui-feedback` theme.
|
|
@@ -226,6 +240,13 @@ interface AppShellProps {
|
|
|
226
240
|
header: React.ReactNode;
|
|
227
241
|
/** Per-app nav region (kefi coral pills / erevna sidebar+drawer). */
|
|
228
242
|
nav?: React.ReactNode;
|
|
243
|
+
/**
|
|
244
|
+
* Optional persistent LEFT RAIL (a `<Sidebar>`), for back-office surfaces. When
|
|
245
|
+
* supplied, the region below header/nav/banner lays out as a row: the rail on the
|
|
246
|
+
* left, the scrolling content column on the right. Omit for the default vertical
|
|
247
|
+
* stack — the tree is then byte-identical to the pre-`sidebar` AppShell.
|
|
248
|
+
*/
|
|
249
|
+
sidebar?: React.ReactNode;
|
|
229
250
|
/** Banner slot (e.g. verification-pending). */
|
|
230
251
|
banner?: React.ReactNode;
|
|
231
252
|
/** Content-width policy. Defaults to full-bleed. */
|
|
@@ -254,7 +275,7 @@ interface AppShellProps {
|
|
|
254
275
|
testID: string;
|
|
255
276
|
children: React.ReactNode;
|
|
256
277
|
}
|
|
257
|
-
declare const AppShell: ({ header, nav, banner, width, contentPadding, chromeAlignment, gate, state, testID, children, }: AppShellProps) => React.ReactElement | null;
|
|
278
|
+
declare const AppShell: ({ header, nav, sidebar, banner, width, contentPadding, chromeAlignment, gate, state, testID, children, }: AppShellProps) => React.ReactElement | null;
|
|
258
279
|
|
|
259
280
|
/**
|
|
260
281
|
* Default testIDs for `@dloizides/ui-nav`. Kept as a small central map (mirrors
|
|
@@ -282,6 +303,8 @@ declare const APP_SHELL_SUFFIX: {
|
|
|
282
303
|
readonly content: "-content";
|
|
283
304
|
readonly header: "-header";
|
|
284
305
|
readonly nav: "-nav";
|
|
306
|
+
/** The persistent left rail of the back-office layout (only when `sidebar` is supplied). */
|
|
307
|
+
readonly sidebar: "-sidebar";
|
|
285
308
|
readonly banner: "-banner";
|
|
286
309
|
readonly pending: "-pending";
|
|
287
310
|
readonly loading: "-loading";
|
package/dist/index.d.ts
CHANGED
|
@@ -154,10 +154,17 @@ declare const Topbar: ({ left, language, notificationSlot, user, account, logout
|
|
|
154
154
|
* collapses the links behind a hamburger toggle — mirroring the v1 AML console's
|
|
155
155
|
* responsive `.global-nav`.
|
|
156
156
|
*
|
|
157
|
+
* Look + feel: each link is a rounded-pill target with the v1 `.gn-links a`
|
|
158
|
+
* affordance — muted at rest, brightening text + a subtle pill background on
|
|
159
|
+
* HOVER, and a solid accent pill when ACTIVE. All colours are THEME-DRIVEN from
|
|
160
|
+
* the `@dloizides/ui-feedback` UiProvider (rest=`textSecondary`, hover text=`text`,
|
|
161
|
+
* hover bg=`surfaceElevated`, active=`palette.primary`, ring=`palette.primary`).
|
|
162
|
+
* Hover/focus are web-only (react-native-web); native stays at the rest style.
|
|
163
|
+
*
|
|
157
164
|
* Contract discipline (same as the rest of `@dloizides/ui-nav`): NO FM, router,
|
|
158
165
|
* icon set, or store imports. Labels are pre-localized strings, icons are render
|
|
159
|
-
* slots, and every colour is read from the
|
|
160
|
-
*
|
|
166
|
+
* slots, and every colour is read from the theme. This is purely additive —
|
|
167
|
+
* `Sidebar`/`Topbar` are unchanged.
|
|
161
168
|
*/
|
|
162
169
|
|
|
163
170
|
interface NavBarProps {
|
|
@@ -211,6 +218,13 @@ declare function useContentMaxWidth(width: AppShellWidth): number | 'full';
|
|
|
211
218
|
* (pending spinner / redirect-when-unauthenticated) and page state cards
|
|
212
219
|
* (loading / error / forbidden).
|
|
213
220
|
*
|
|
221
|
+
* A BACK-OFFICE variant is supported via the optional `sidebar` slot (added for
|
|
222
|
+
* Agora's merchant admin): supply a `<Sidebar>` and the body below the header /
|
|
223
|
+
* nav / banner becomes a ROW — a persistent left rail beside the scrolling
|
|
224
|
+
* content column — instead of the default single vertical stack. Omit `sidebar`
|
|
225
|
+
* and the render tree is byte-identical to before, so every existing consumer
|
|
226
|
+
* (erevna / katalogos / kefi) is untouched.
|
|
227
|
+
*
|
|
214
228
|
* Contract discipline (same as the rest of `@dloizides/ui-nav`): NO FM, router,
|
|
215
229
|
* or store imports. The app passes wired elements, pre-localized strings, and
|
|
216
230
|
* callbacks; every colour is routed through the `@dloizides/ui-feedback` theme.
|
|
@@ -226,6 +240,13 @@ interface AppShellProps {
|
|
|
226
240
|
header: React.ReactNode;
|
|
227
241
|
/** Per-app nav region (kefi coral pills / erevna sidebar+drawer). */
|
|
228
242
|
nav?: React.ReactNode;
|
|
243
|
+
/**
|
|
244
|
+
* Optional persistent LEFT RAIL (a `<Sidebar>`), for back-office surfaces. When
|
|
245
|
+
* supplied, the region below header/nav/banner lays out as a row: the rail on the
|
|
246
|
+
* left, the scrolling content column on the right. Omit for the default vertical
|
|
247
|
+
* stack — the tree is then byte-identical to the pre-`sidebar` AppShell.
|
|
248
|
+
*/
|
|
249
|
+
sidebar?: React.ReactNode;
|
|
229
250
|
/** Banner slot (e.g. verification-pending). */
|
|
230
251
|
banner?: React.ReactNode;
|
|
231
252
|
/** Content-width policy. Defaults to full-bleed. */
|
|
@@ -254,7 +275,7 @@ interface AppShellProps {
|
|
|
254
275
|
testID: string;
|
|
255
276
|
children: React.ReactNode;
|
|
256
277
|
}
|
|
257
|
-
declare const AppShell: ({ header, nav, banner, width, contentPadding, chromeAlignment, gate, state, testID, children, }: AppShellProps) => React.ReactElement | null;
|
|
278
|
+
declare const AppShell: ({ header, nav, sidebar, banner, width, contentPadding, chromeAlignment, gate, state, testID, children, }: AppShellProps) => React.ReactElement | null;
|
|
258
279
|
|
|
259
280
|
/**
|
|
260
281
|
* Default testIDs for `@dloizides/ui-nav`. Kept as a small central map (mirrors
|
|
@@ -282,6 +303,8 @@ declare const APP_SHELL_SUFFIX: {
|
|
|
282
303
|
readonly content: "-content";
|
|
283
304
|
readonly header: "-header";
|
|
284
305
|
readonly nav: "-nav";
|
|
306
|
+
/** The persistent left rail of the back-office layout (only when `sidebar` is supplied). */
|
|
307
|
+
readonly sidebar: "-sidebar";
|
|
285
308
|
readonly banner: "-banner";
|
|
286
309
|
readonly pending: "-pending";
|
|
287
310
|
readonly loading: "-loading";
|