@geomak/ui 6.22.0 → 6.23.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.cts CHANGED
@@ -2867,8 +2867,20 @@ interface SecureLayoutProps {
2867
2867
  /** Required permission(s). One needed (or all, with `requireAllPermissions`). */
2868
2868
  requiredPermissions?: string[];
2869
2869
  requireAllPermissions?: boolean;
2870
- /** Final say. Runs after the built-in checks; may be async. Return false to deny. */
2871
- canAccess?: () => boolean | Promise<boolean>;
2870
+ /**
2871
+ * The current route path (e.g. `location.pathname`). Pass it from your
2872
+ * router to do **per-route** access from a single root wrapper: the check
2873
+ * re-runs whenever `route` changes (i.e. on navigation), and the value is
2874
+ * forwarded to `canAccess`. Omit it for a static, app-wide gate.
2875
+ */
2876
+ route?: string;
2877
+ /**
2878
+ * Final say. Runs after the built-in checks; may be async; return false to
2879
+ * deny. Receives the current `route`, so a single wrapper can decide access
2880
+ * per path (e.g. consult a route → permissions map). Keep it synchronous
2881
+ * for instant, flash-free per-route guarding.
2882
+ */
2883
+ canAccess?: (route?: string) => boolean | Promise<boolean>;
2872
2884
  /** Shown while the (possibly async) check resolves. Pass `null` to render nothing. */
2873
2885
  loadingFallback?: React__default.ReactNode;
2874
2886
  /** Shown when access is denied. Defaults to a simple "Access denied" panel;
@@ -2911,8 +2923,19 @@ interface SecureLayoutProps {
2911
2923
  * >
2912
2924
  * <AppRoutes />
2913
2925
  * </SecureLayout>
2926
+ *
2927
+ * @example Per-route access from a single root wrapper
2928
+ * // Pass the path so the check re-runs on navigation; decide per route.
2929
+ * const allowed = { '/admin': ['admin'], '/reports': ['analyst', 'admin'] }
2930
+ * <SecureLayout
2931
+ * route={location.pathname}
2932
+ * canAccess={(path) => (allowed[path] ?? []).some((r) => user.roles.includes(r))}
2933
+ * onDeny={() => navigate('/403')}
2934
+ * >
2935
+ * <AppRoutes />
2936
+ * </SecureLayout>
2914
2937
  */
2915
- declare function SecureLayout({ children, isAuthenticated, token, roles, requiredRoles, requireAllRoles, permissions, requiredPermissions, requireAllPermissions, canAccess, loadingFallback, fallback, onGranted, onDeny, className, }: SecureLayoutProps): react_jsx_runtime.JSX.Element;
2938
+ declare function SecureLayout({ children, isAuthenticated, token, roles, requiredRoles, requireAllRoles, permissions, requiredPermissions, requireAllPermissions, route, canAccess, loadingFallback, fallback, onGranted, onDeny, className, }: SecureLayoutProps): react_jsx_runtime.JSX.Element;
2916
2939
 
2917
2940
  interface ThemeColors {
2918
2941
  background?: string;
package/dist/index.d.ts CHANGED
@@ -2867,8 +2867,20 @@ interface SecureLayoutProps {
2867
2867
  /** Required permission(s). One needed (or all, with `requireAllPermissions`). */
2868
2868
  requiredPermissions?: string[];
2869
2869
  requireAllPermissions?: boolean;
2870
- /** Final say. Runs after the built-in checks; may be async. Return false to deny. */
2871
- canAccess?: () => boolean | Promise<boolean>;
2870
+ /**
2871
+ * The current route path (e.g. `location.pathname`). Pass it from your
2872
+ * router to do **per-route** access from a single root wrapper: the check
2873
+ * re-runs whenever `route` changes (i.e. on navigation), and the value is
2874
+ * forwarded to `canAccess`. Omit it for a static, app-wide gate.
2875
+ */
2876
+ route?: string;
2877
+ /**
2878
+ * Final say. Runs after the built-in checks; may be async; return false to
2879
+ * deny. Receives the current `route`, so a single wrapper can decide access
2880
+ * per path (e.g. consult a route → permissions map). Keep it synchronous
2881
+ * for instant, flash-free per-route guarding.
2882
+ */
2883
+ canAccess?: (route?: string) => boolean | Promise<boolean>;
2872
2884
  /** Shown while the (possibly async) check resolves. Pass `null` to render nothing. */
2873
2885
  loadingFallback?: React__default.ReactNode;
2874
2886
  /** Shown when access is denied. Defaults to a simple "Access denied" panel;
@@ -2911,8 +2923,19 @@ interface SecureLayoutProps {
2911
2923
  * >
2912
2924
  * <AppRoutes />
2913
2925
  * </SecureLayout>
2926
+ *
2927
+ * @example Per-route access from a single root wrapper
2928
+ * // Pass the path so the check re-runs on navigation; decide per route.
2929
+ * const allowed = { '/admin': ['admin'], '/reports': ['analyst', 'admin'] }
2930
+ * <SecureLayout
2931
+ * route={location.pathname}
2932
+ * canAccess={(path) => (allowed[path] ?? []).some((r) => user.roles.includes(r))}
2933
+ * onDeny={() => navigate('/403')}
2934
+ * >
2935
+ * <AppRoutes />
2936
+ * </SecureLayout>
2914
2937
  */
2915
- declare function SecureLayout({ children, isAuthenticated, token, roles, requiredRoles, requireAllRoles, permissions, requiredPermissions, requireAllPermissions, canAccess, loadingFallback, fallback, onGranted, onDeny, className, }: SecureLayoutProps): react_jsx_runtime.JSX.Element;
2938
+ declare function SecureLayout({ children, isAuthenticated, token, roles, requiredRoles, requireAllRoles, permissions, requiredPermissions, requireAllPermissions, route, canAccess, loadingFallback, fallback, onGranted, onDeny, className, }: SecureLayoutProps): react_jsx_runtime.JSX.Element;
2916
2939
 
2917
2940
  interface ThemeColors {
2918
2941
  background?: string;
package/dist/index.js CHANGED
@@ -5847,6 +5847,7 @@ function SecureLayout({
5847
5847
  permissions,
5848
5848
  requiredPermissions,
5849
5849
  requireAllPermissions,
5850
+ route,
5850
5851
  canAccess,
5851
5852
  loadingFallback,
5852
5853
  fallback,
@@ -5884,8 +5885,13 @@ function SecureLayout({
5884
5885
  } else if (!canAccess) {
5885
5886
  finish(true);
5886
5887
  } else {
5887
- setState("checking");
5888
- Promise.resolve(canAccess()).then((ok) => finish(Boolean(ok)));
5888
+ const result = canAccess(route);
5889
+ if (result && typeof result.then === "function") {
5890
+ setState("checking");
5891
+ result.then((ok) => finish(Boolean(ok)));
5892
+ } else {
5893
+ finish(Boolean(result));
5894
+ }
5889
5895
  }
5890
5896
  return () => {
5891
5897
  cancelled = true;
@@ -5893,6 +5899,7 @@ function SecureLayout({
5893
5899
  }, [
5894
5900
  isAuthenticated,
5895
5901
  token,
5902
+ route,
5896
5903
  requireAllRoles,
5897
5904
  requireAllPermissions,
5898
5905
  canAccess,