@vef-framework-react/starter 2.2.0 → 2.2.2

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.
Files changed (118) hide show
  1. package/dist/cjs/components/layout/components/header/index.cjs +1 -1
  2. package/dist/cjs/components/layout/components/header/user-avatar.cjs +1 -1
  3. package/dist/cjs/components/layout/index.cjs +1 -1
  4. package/dist/cjs/components/login/index.cjs +1 -1
  5. package/dist/es/components/access-denied/access-denied-icon.js +1 -1
  6. package/dist/es/components/access-denied/index.js +1 -1
  7. package/dist/es/components/app/index.js +1 -1
  8. package/dist/es/components/base-layout/index.js +1 -1
  9. package/dist/es/components/base-layout/styles.js +1 -1
  10. package/dist/es/components/base-layout/use-base-layout.js +1 -1
  11. package/dist/es/components/error/error-icon.js +1 -1
  12. package/dist/es/components/error/index.js +1 -1
  13. package/dist/es/components/index.js +1 -1
  14. package/dist/es/components/layout/components/footer.js +1 -1
  15. package/dist/es/components/layout/components/header/boy-icon.js +1 -1
  16. package/dist/es/components/layout/components/header/breadcrumb-navigation.js +1 -1
  17. package/dist/es/components/layout/components/header/color-scheme.js +1 -1
  18. package/dist/es/components/layout/components/header/fullscreen.js +1 -1
  19. package/dist/es/components/layout/components/header/girl-icon.js +1 -1
  20. package/dist/es/components/layout/components/header/index.js +12 -11
  21. package/dist/es/components/layout/components/header/menu-burger.js +1 -1
  22. package/dist/es/components/layout/components/header/menu-fold-left-icon.js +1 -1
  23. package/dist/es/components/layout/components/header/menu-unfold-left-icon.js +1 -1
  24. package/dist/es/components/layout/components/header/search.js +1 -1
  25. package/dist/es/components/layout/components/header/theme-config.js +1 -1
  26. package/dist/es/components/layout/components/header/user-avatar.js +39 -40
  27. package/dist/es/components/layout/components/honeycomb-pattern.js +1 -1
  28. package/dist/es/components/layout/components/index.js +1 -1
  29. package/dist/es/components/layout/components/logo.js +1 -1
  30. package/dist/es/components/layout/components/menu.js +1 -1
  31. package/dist/es/components/layout/components/search/index.js +1 -1
  32. package/dist/es/components/layout/components/search/keyboard-arrow-down-icon.js +1 -1
  33. package/dist/es/components/layout/components/search/keyboard-arrow-up-icon.js +1 -1
  34. package/dist/es/components/layout/components/search/keyboard-control-icon.js +1 -1
  35. package/dist/es/components/layout/components/search/keyboard-esc-icon.js +1 -1
  36. package/dist/es/components/layout/components/search/keyboard-help.js +1 -1
  37. package/dist/es/components/layout/components/search/keyboard-return-icon.js +1 -1
  38. package/dist/es/components/layout/components/search/keyboard-shift-icon.js +1 -1
  39. package/dist/es/components/layout/components/search/keyboard.js +1 -1
  40. package/dist/es/components/layout/components/search/letter-s-icon.js +1 -1
  41. package/dist/es/components/layout/components/search/search-result-item.js +1 -1
  42. package/dist/es/components/layout/components/search/search-result.js +1 -1
  43. package/dist/es/components/layout/components/sidebar.js +1 -1
  44. package/dist/es/components/layout/components/tabs/context-menu.js +1 -1
  45. package/dist/es/components/layout/components/tabs/index.js +1 -1
  46. package/dist/es/components/layout/components/tabs/main-content-maximum.js +1 -1
  47. package/dist/es/components/layout/components/tabs/reload.js +1 -1
  48. package/dist/es/components/layout/components/tabs/tab-item.js +1 -1
  49. package/dist/es/components/layout/components/tabs/tab-list.js +1 -1
  50. package/dist/es/components/layout/components/tabs/tabs-container.js +1 -1
  51. package/dist/es/components/layout/components/theme-config/color-scheme-switcher.js +1 -1
  52. package/dist/es/components/layout/components/theme-config/color-scheme.js +1 -1
  53. package/dist/es/components/layout/components/theme-config/config-item.js +1 -1
  54. package/dist/es/components/layout/components/theme-config/index.js +1 -1
  55. package/dist/es/components/layout/components/theme-config/menu-layout-card.js +1 -1
  56. package/dist/es/components/layout/components/theme-config/menu-layout.js +1 -1
  57. package/dist/es/components/layout/components/theme-config/operations.js +1 -1
  58. package/dist/es/components/layout/components/theme-config/theme-color-picker.js +1 -1
  59. package/dist/es/components/layout/components/theme-config/theme-colors.js +1 -1
  60. package/dist/es/components/layout/hooks/index.js +1 -1
  61. package/dist/es/components/layout/hooks/use-color-scheme-updater.js +1 -1
  62. package/dist/es/components/layout/hooks/use-menu-navigate.js +1 -1
  63. package/dist/es/components/layout/hooks/use-tab-navigate.js +1 -1
  64. package/dist/es/components/layout/index.js +12 -11
  65. package/dist/es/components/layout/store.js +1 -1
  66. package/dist/es/components/layout/styles.js +1 -1
  67. package/dist/es/components/login/icon-login.js +1 -1
  68. package/dist/es/components/login/index.js +4 -4
  69. package/dist/es/components/login/styles.js +1 -1
  70. package/dist/es/components/login/welcome-messages.js +1 -1
  71. package/dist/es/components/n-progress/components/bar.js +1 -1
  72. package/dist/es/components/n-progress/components/container.js +1 -1
  73. package/dist/es/components/n-progress/components/index.js +1 -1
  74. package/dist/es/components/n-progress/event.js +1 -1
  75. package/dist/es/components/n-progress/index.js +1 -1
  76. package/dist/es/components/not-found/index.js +1 -1
  77. package/dist/es/components/not-found/not-found-icon.js +1 -1
  78. package/dist/es/components/router-provider/context.js +1 -1
  79. package/dist/es/components/router-provider/index.js +1 -1
  80. package/dist/es/components/theme-config-provider/global-style.js +1 -1
  81. package/dist/es/components/theme-config-provider/index.js +1 -1
  82. package/dist/es/components/theme-config-provider/use-color-mode-effect.js +1 -1
  83. package/dist/es/components/theme-config-provider/use-theme-config.js +1 -1
  84. package/dist/es/constants/event.js +1 -1
  85. package/dist/es/constants/index.js +1 -1
  86. package/dist/es/constants/router.js +1 -1
  87. package/dist/es/constants/storage.js +1 -1
  88. package/dist/es/helpers/api.js +1 -1
  89. package/dist/es/helpers/app-version.js +1 -1
  90. package/dist/es/helpers/app.js +1 -1
  91. package/dist/es/helpers/auth.js +1 -1
  92. package/dist/es/helpers/event.js +1 -1
  93. package/dist/es/helpers/index.js +1 -1
  94. package/dist/es/helpers/query.js +1 -1
  95. package/dist/es/helpers/router.js +1 -1
  96. package/dist/es/hooks/index.js +1 -1
  97. package/dist/es/hooks/use-route-full-path.js +1 -1
  98. package/dist/es/index.js +1 -1
  99. package/dist/es/routes/access-denied.js +1 -1
  100. package/dist/es/routes/index.js +1 -1
  101. package/dist/es/routes/layout.js +1 -1
  102. package/dist/es/routes/login.js +1 -1
  103. package/dist/es/routes/root.js +1 -1
  104. package/dist/es/stores/app.js +1 -1
  105. package/dist/es/stores/index.js +1 -1
  106. package/dist/es/stores/tab.js +1 -1
  107. package/dist/es/stores/theme.js +1 -1
  108. package/dist/types/components/index.d.ts +1 -1
  109. package/dist/types/components/layout/components/header/index.d.ts +2 -2
  110. package/dist/types/components/layout/components/header/user-avatar.d.ts +2 -2
  111. package/dist/types/components/layout/index.d.ts +1 -1
  112. package/dist/types/components/layout/props.d.ts +7 -1
  113. package/dist/types/components/login/index.d.ts +1 -1
  114. package/dist/types/components/login/payload.d.ts +13 -14
  115. package/dist/types/components/login/props.d.ts +23 -7
  116. package/dist/types/index.d.ts +1 -1
  117. package/dist/types/types/common.d.ts +25 -1
  118. package/package.json +5 -5
@@ -1,4 +1,4 @@
1
- /*! @vef-framework-react/starter v2.2.0 made by Venus | 2026-05-18T05:49:20.358Z */
1
+ /*! @vef-framework-react/starter v2.2.2 made by Venus | 2026-05-18T12:44:01.943Z */
2
2
  import { useAppStore as e } from "../stores/app.js";
3
3
  import { jsx as t } from "@emotion/react/jsx-runtime";
4
4
  import { Outlet as n, useLocation as r, useRouteContext as i } from "@tanstack/react-router";
@@ -1,4 +1,4 @@
1
- /*! @vef-framework-react/starter v2.2.0 made by Venus | 2026-05-18T05:49:20.358Z */
1
+ /*! @vef-framework-react/starter v2.2.2 made by Venus | 2026-05-18T12:44:01.943Z */
2
2
  import { createPersistedStore as e } from "@vef-framework-react/core";
3
3
  //#region src/stores/app.ts
4
4
  var t = e(() => ({ isAuthenticated: !1 }), {
@@ -1,4 +1,4 @@
1
- /*! @vef-framework-react/starter v2.2.0 made by Venus | 2026-05-18T05:49:20.358Z */
1
+ /*! @vef-framework-react/starter v2.2.2 made by Venus | 2026-05-18T12:44:01.943Z */
2
2
  import "./app.js";
3
3
  import "./tab.js";
4
4
  import "./theme.js";
@@ -1,4 +1,4 @@
1
- /*! @vef-framework-react/starter v2.2.0 made by Venus | 2026-05-18T05:49:20.358Z */
1
+ /*! @vef-framework-react/starter v2.2.2 made by Venus | 2026-05-18T12:44:01.943Z */
2
2
  import "../constants/router.js";
3
3
  import { createPersistedStore as e, originalState as t } from "@vef-framework-react/core";
4
4
  //#region src/stores/tab.ts
@@ -1,4 +1,4 @@
1
- /*! @vef-framework-react/starter v2.2.0 made by Venus | 2026-05-18T05:49:20.358Z */
1
+ /*! @vef-framework-react/starter v2.2.2 made by Venus | 2026-05-18T12:44:01.943Z */
2
2
  import { createPersistedStore as e } from "@vef-framework-react/core";
3
3
  import { omit as t } from "@vef-framework-react/shared";
4
4
  //#region src/stores/theme.ts
@@ -3,7 +3,7 @@ export { App, type AppProps } from './app';
3
3
  export { BaseLayout, type BaseLayoutProps } from './base-layout';
4
4
  export { Error } from './error';
5
5
  export { Layout, type LayoutProps } from './layout';
6
- export { Login, type LoginChallenge, type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginParams, type LoginProps, type LoginResult, type PasswordLoginParams, type ResolveChallengeParams } from './login';
6
+ export { Login, type LoginChallenge, type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginChallengeRenderers, type LoginParams, type LoginProps, type LoginResult, type PasswordLoginParams, type ResolveChallengeParams } from './login';
7
7
  export { NProgress, nProgressEventEmitter } from './n-progress';
8
8
  export { NotFound } from './not-found';
9
9
  export { RouterContextHookProvider, RouterProvider, type RouterProviderProps, type UseRouterContext } from './router-provider';
@@ -1,5 +1,5 @@
1
1
  import { LayoutProps } from '../../props';
2
- interface HeaderProps extends Pick<LayoutProps, "title" | "logo" | "headerActions" | "userMenuItems" | "onLogout"> {
2
+ interface HeaderProps extends Pick<LayoutProps, "title" | "logo" | "headerActions" | "userMenuItems" | "onUserMenuClick" | "onLogout"> {
3
3
  }
4
- export declare function Header({ title, logo, headerActions, userMenuItems, onLogout }: HeaderProps): import("@emotion/react/jsx-runtime").JSX.Element;
4
+ export declare function Header({ title, logo, headerActions, userMenuItems, onUserMenuClick, onLogout }: HeaderProps): import("@emotion/react/jsx-runtime").JSX.Element;
5
5
  export {};
@@ -1,6 +1,6 @@
1
1
  import { LayoutProps } from '../../props';
2
- interface UserAvatarProps extends Pick<LayoutProps, "userMenuItems" | "onLogout"> {
2
+ interface UserAvatarProps extends Pick<LayoutProps, "userMenuItems" | "onUserMenuClick" | "onLogout"> {
3
3
  className?: string;
4
4
  }
5
- export declare function UserAvatar({ className, userMenuItems, onLogout }: UserAvatarProps): import("@emotion/react/jsx-runtime").JSX.Element;
5
+ export declare function UserAvatar({ className, userMenuItems, onUserMenuClick, onLogout }: UserAvatarProps): import("@emotion/react/jsx-runtime").JSX.Element;
6
6
  export {};
@@ -1,3 +1,3 @@
1
1
  import { LayoutProps } from './props';
2
- export declare function Layout({ title, logo, headerActions, userMenuItems, onLogout, children }: LayoutProps): import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare function Layout({ title, logo, headerActions, userMenuItems, onUserMenuClick, onLogout, children }: LayoutProps): import("@emotion/react/jsx-runtime").JSX.Element;
3
3
  export { type LayoutProps } from './props';
@@ -18,9 +18,15 @@ export interface LayoutProps extends PropsWithChildren {
18
18
  */
19
19
  headerActions?: ReactNode;
20
20
  /**
21
- * The user menu items of the layout.
21
+ * Extra items appended to the user dropdown menu. They render before the
22
+ * built-in items (e.g. logout), with an automatic divider in between.
22
23
  */
23
24
  userMenuItems?: DropdownMenuProps["items"];
25
+ /**
26
+ * Handles clicks on user menu items. The built-in `logout` key is owned by
27
+ * the framework and never forwarded; all other keys are delivered here.
28
+ */
29
+ onUserMenuClick?: (key: string) => void;
24
30
  /**
25
31
  * The logout api function.
26
32
  */
@@ -1,4 +1,4 @@
1
1
  import { LoginProps } from './props';
2
2
  export declare function Login({ logo, title, description, publicKey, onLogin, onResolveChallenge, challengeRenderers }: LoginProps): import("@emotion/react/jsx-runtime").JSX.Element;
3
3
  export { type LoginChallenge, type LoginParams, type LoginResult, type PasswordLoginParams, type ResolveChallengeParams } from './payload';
4
- export { type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginProps } from './props';
4
+ export { type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginChallengeRenderers, type LoginProps } from './props';
@@ -1,4 +1,5 @@
1
1
  import { AuthTokens } from '../../models';
2
+ import { ResolvedChallenges } from '../../types/common';
2
3
  /**
3
4
  * The payload for login
4
5
  */
@@ -31,21 +32,19 @@ export interface PasswordLoginParams extends BaseLoginParams<string> {
31
32
  }
32
33
  /**
33
34
  * A challenge the user must complete during login (e.g., 2FA, department selection).
35
+ *
36
+ * When `Register['challenges']` is augmented by the consuming project, this becomes
37
+ * a discriminated union narrowed per `type`, with `data` typed to the augmented
38
+ * spec. Without augmentation, it degrades to `{ type: string; data: unknown }` —
39
+ * exactly today's wire shape.
34
40
  */
35
- export interface LoginChallenge {
36
- /**
37
- * The challenge type identifier (e.g., "totp", "select_department")
38
- */
39
- type: string;
40
- /**
41
- * Optional challenge-specific data
42
- */
43
- data?: unknown;
44
- /**
45
- * Whether the challenge is required
46
- */
47
- required: boolean;
48
- }
41
+ export type LoginChallenge = {
42
+ [K in keyof ResolvedChallenges]: {
43
+ type: K;
44
+ data: ResolvedChallenges[K]["data"];
45
+ required: boolean;
46
+ };
47
+ }[keyof ResolvedChallenges];
49
48
  /**
50
49
  * The result of a login attempt.
51
50
  * When a challenge is pending, tokens is undefined and challengeToken + challenge are set.
@@ -1,23 +1,30 @@
1
1
  import { ReactNode } from 'react';
2
+ import { ResolvedChallenges } from '../../types/common';
2
3
  import { LoginChallenge, LoginParams, LoginResult, ResolveChallengeParams } from './payload';
3
4
  /**
4
5
  * Arguments passed to a challenge renderer. Renderers are stateless from the
5
6
  * Login component's perspective — they consume `challenge` for prompt data
6
7
  * and call `resolve` / `cancel` to drive the flow forward or backward.
8
+ *
9
+ * Parameterised by `K`, the specific challenge type the renderer is bound to.
10
+ * When projects augment `Register['challenges']`, `challenge.data` and the
11
+ * `resolve` argument are both narrowed to the corresponding spec entry.
7
12
  */
8
- export interface LoginChallengeRendererProps {
13
+ export interface LoginChallengeRendererProps<K extends keyof ResolvedChallenges = keyof ResolvedChallenges> {
9
14
  /**
10
15
  * The pending challenge to present (type identifier and challenge-specific data).
11
16
  */
12
- challenge: LoginChallenge;
17
+ challenge: Extract<LoginChallenge, {
18
+ type: K;
19
+ }>;
13
20
  /**
14
21
  * Submit the user's answer to the current challenge. The concrete shape of
15
- * `response` is decided by each challenge type — renderers narrow it
16
- * internally before calling this.
22
+ * `response` is dictated by the augmented `ResolvedChallenges[K]['response']`;
23
+ * without augmentation, it falls back to `unknown`.
17
24
  * Returns once the resulting `LoginResult` has been applied — either the
18
25
  * next challenge is shown or authentication completes and navigation runs.
19
26
  */
20
- resolve: (response: unknown) => Promise<void>;
27
+ resolve: (response: ResolvedChallenges[K]["response"]) => Promise<void>;
21
28
  /**
22
29
  * Abandon the challenge and return to the initial credentials form.
23
30
  * The held challenge token is discarded; the user must log in again.
@@ -46,7 +53,16 @@ export interface LoginChallengeRendererProps {
46
53
  * Business apps register one per challenge type they support; the Login
47
54
  * component looks up the renderer by `challenge.type` at runtime.
48
55
  */
49
- export type LoginChallengeRenderer = (props: LoginChallengeRendererProps) => ReactNode;
56
+ export type LoginChallengeRenderer<K extends keyof ResolvedChallenges = keyof ResolvedChallenges> = (props: LoginChallengeRendererProps<K>) => ReactNode;
57
+ /**
58
+ * The full renderer registry — one renderer per known challenge type. When
59
+ * `Register['challenges']` is augmented, TypeScript enforces exhaustiveness
60
+ * (every declared challenge must have a renderer) and per-key typing of the
61
+ * `challenge.data` / `resolve` payloads.
62
+ */
63
+ export type LoginChallengeRenderers = {
64
+ [K in keyof ResolvedChallenges]: LoginChallengeRenderer<K>;
65
+ };
50
66
  /**
51
67
  * The shared subset of LoginProps, independent of whether the flow may
52
68
  * surface challenges.
@@ -81,7 +97,7 @@ interface BaseLoginProps {
81
97
  */
82
98
  interface LoginPropsWithChallenge {
83
99
  onResolveChallenge: (params: ResolveChallengeParams) => Promise<LoginResult>;
84
- challengeRenderers: Record<string, LoginChallengeRenderer>;
100
+ challengeRenderers: LoginChallengeRenderers;
85
101
  }
86
102
  /**
87
103
  * Login wiring for backends that never issue challenges.
@@ -1,4 +1,4 @@
1
- export { type LoginChallenge, type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginParams, type LoginProps, type LoginResult, type PasswordLoginParams, type ResolveChallengeParams } from './components';
1
+ export { type LoginChallenge, type LoginChallengeRenderer, type LoginChallengeRendererProps, type LoginChallengeRenderers, type LoginParams, type LoginProps, type LoginResult, type PasswordLoginParams, type ResolveChallengeParams } from './components';
2
2
  export { ACCESS_DENIED_ROUTE_ID, ACCESS_DENIED_ROUTE_PATH, INDEX_ROUTE_ID, INDEX_ROUTE_PATH, LOGIN_ROUTE_ID, LOGIN_ROUTE_PATH } from './constants';
3
3
  export { createApiClient, createApp, createRouter, dispatchCustomEvent, emitAccessDenied, emitUnauthenticated, extractQueryParams, handleClientLogout, noopMutationFn, setupAppVersionNotification, type ApiClientOptions, type AppChangelog, type AppVersionNotificationOptions, type RouterOptions } from './helpers';
4
4
  export { createAccessDeniedRouteOptions, createLayoutRouteOptions, createLoginRouteOptions, createRootRouteOptions } from './routes';
@@ -13,7 +13,8 @@ export interface UserMenu {
13
13
  * Extension registry for framework types.
14
14
  *
15
15
  * Projects augment this interface via `declare module` to refine
16
- * extensible fields such as `UserInfo['details']`.
16
+ * extensible fields such as `UserInfo['details']` or the set of
17
+ * login challenge types the backend may issue.
17
18
  *
18
19
  * @example
19
20
  * declare module "@vef-framework-react/starter" {
@@ -22,6 +23,13 @@ export interface UserMenu {
22
23
  * department: string;
23
24
  * organization: string;
24
25
  * };
26
+ * challenges: {
27
+ * department_selection: {
28
+ * data: { departments: Array<{ id: string; name: string }> };
29
+ * response: string;
30
+ * };
31
+ * totp: { response: string };
32
+ * };
25
33
  * }
26
34
  * }
27
35
  */
@@ -34,6 +42,22 @@ export type UserDetails = Record<string, unknown>;
34
42
  type ResolvedUserDetails = Register extends {
35
43
  userDetails: infer T extends UserDetails;
36
44
  } ? T : UserDetails;
45
+ /**
46
+ * Contract for a single login challenge type. `data` is the payload the
47
+ * server attaches to the challenge for the renderer to display; `response`
48
+ * is the value the renderer feeds back to `resolve`.
49
+ */
50
+ export interface ChallengeSpec {
51
+ data?: unknown;
52
+ response: unknown;
53
+ }
54
+ /**
55
+ * Resolved challenge registry. Falls back to an open `Record` so codebases
56
+ * that never augment `Register['challenges']` retain today's loose typing.
57
+ */
58
+ export type ResolvedChallenges = Register extends {
59
+ challenges: infer T extends Record<string, ChallengeSpec>;
60
+ } ? T : Record<string, ChallengeSpec>;
37
61
  export interface UserInfo {
38
62
  id: string;
39
63
  name: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vef-framework-react/starter",
3
3
  "type": "module",
4
- "version": "2.2.0",
4
+ "version": "2.2.2",
5
5
  "private": false,
6
6
  "description": "Starter for VEF framework",
7
7
  "author": {
@@ -64,10 +64,10 @@
64
64
  "@tanstack/react-router": "^1.170.1",
65
65
  "react": "^19.2.6",
66
66
  "react-dom": "^19.2.6",
67
- "@vef-framework-react/components": "2.2.0",
68
- "@vef-framework-react/core": "2.2.0",
69
- "@vef-framework-react/hooks": "2.2.0",
70
- "@vef-framework-react/shared": "2.2.0"
67
+ "@vef-framework-react/components": "2.2.2",
68
+ "@vef-framework-react/core": "2.2.2",
69
+ "@vef-framework-react/shared": "2.2.2",
70
+ "@vef-framework-react/hooks": "2.2.2"
71
71
  },
72
72
  "scripts": {
73
73
  "clean": "rimraf dist",