hazo_auth 10.4.13 → 10.6.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/README.md +6 -4
- package/cli-src/lib/ui_shell_config.server.ts +5 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -0
- package/dist/components/user_picker_select.d.ts +58 -0
- package/dist/components/user_picker_select.d.ts.map +1 -0
- package/dist/components/user_picker_select.js +76 -0
- package/dist/lib/ui_shell_config.server.d.ts +4 -0
- package/dist/lib/ui_shell_config.server.d.ts.map +1 -1
- package/dist/lib/ui_shell_config.server.js +5 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1620,11 +1620,11 @@ The component automatically shows/hides tabs based on the user's permissions, so
|
|
|
1620
1620
|
|
|
1621
1621
|
### Choose the UI Shell (Test Sidebar vs Standalone)
|
|
1622
1622
|
|
|
1623
|
-
By default,
|
|
1623
|
+
By default, pages render with a clean, standalone wrapper that inherits your own app shell, layout, and theme tokens. The "test workspace" sidebar (`test_sidebar`) is opt-in and intended only for this package's own demo/dev app (Storybook screenshots, quickly previewing every flow). Set this in `hazo_auth_config.ini`:
|
|
1624
1624
|
|
|
1625
1625
|
```ini
|
|
1626
1626
|
[hazo_auth__ui_shell]
|
|
1627
|
-
# Options:
|
|
1627
|
+
# Options: standalone (default) | test_sidebar
|
|
1628
1628
|
layout_mode = standalone
|
|
1629
1629
|
vertical_center = auto # 'auto' enables vertical centering when navbar is present
|
|
1630
1630
|
# Optional tweaks for the standalone header wrapper/classes:
|
|
@@ -1634,11 +1634,13 @@ vertical_center = auto # 'auto' enables vertical centering when navbar is prese
|
|
|
1634
1634
|
# standalone_content_class = mx-auto w-full max-w-4xl rounded-2xl border bg-card
|
|
1635
1635
|
```
|
|
1636
1636
|
|
|
1637
|
-
- `
|
|
1638
|
-
- `
|
|
1637
|
+
- `standalone` (default): renders the page body directly so it inherits your own app shell, layout, and theme tokens.
|
|
1638
|
+
- `test_sidebar`: keeps the developer sidebar. Opt-in only, meant for this package's own demo/dev app — do not set this in consuming apps.
|
|
1639
1639
|
- `vertical_center`: controls vertical centering of auth content (`auto` enables centering when navbar is present)
|
|
1640
1640
|
- The wrapper and content class overrides let you align spacing/borders with your design system without editing package code.
|
|
1641
1641
|
|
|
1642
|
+
**`pages/*` vs `components/layouts/*`:** The `hazo_auth/pages/*` exports (e.g. `hazo_auth/pages/login`, `/register`, etc.) are full-screen pages meant to be rendered at page root by consumers — they should not be wrapped in a fixed-width card/container. If you need an embedded/card-style form (e.g. inside a modal or a section of an existing page), use the bare `components/layouts/login` component with `layout="form_only"` instead.
|
|
1643
|
+
|
|
1642
1644
|
### Authentication Page Navbar
|
|
1643
1645
|
|
|
1644
1646
|
**The navbar now works automatically** - zero-config server page components include the navbar based on configuration without manual wrapping.
|
|
@@ -27,11 +27,15 @@ export type UiShellConfig = {
|
|
|
27
27
|
/**
|
|
28
28
|
* Reads ui shell configuration controlling whether pages use the sidebar test shell
|
|
29
29
|
* or a clean standalone wrapper that inherits consumer project styling.
|
|
30
|
+
*
|
|
31
|
+
* `standalone` is the default so consuming apps get a clean wrapper out of the box.
|
|
32
|
+
* `test_sidebar` must be explicitly opted into via config and is intended for use
|
|
33
|
+
* by this package's own demo/dev app only.
|
|
30
34
|
*/
|
|
31
35
|
export function get_ui_shell_config(): UiShellConfig {
|
|
32
36
|
const section = "hazo_auth__ui_shell";
|
|
33
37
|
|
|
34
|
-
const layoutModeValue = get_config_value(section, "layout_mode", "
|
|
38
|
+
const layoutModeValue = get_config_value(section, "layout_mode", "standalone").toLowerCase();
|
|
35
39
|
const layout_mode: UiShellLayoutMode =
|
|
36
40
|
layoutModeValue === "standalone" ? "standalone" : "test_sidebar";
|
|
37
41
|
|
package/dist/client.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export * from "./components/layouts/shared/utils/validation.js";
|
|
|
12
12
|
export { requestGoogleScopes } from "./lib/auth/request_google_scopes.js";
|
|
13
13
|
export { PermissionDeniedDialog } from "./components/permission_denied_dialog.client.js";
|
|
14
14
|
export type { PermissionDeniedDialogProps, PermissionDeniedDetails } from "./components/permission_denied_dialog.client";
|
|
15
|
+
export { UserPickerSelect, UserAvatar, userDisplayName } from "./components/user_picker_select.js";
|
|
16
|
+
export type { UserPickerSelectProps, UserAvatarProps, PickableUser, } from "./components/user_picker_select";
|
|
15
17
|
export { AuthIssueCard, registerAuthIssueCardRenderer } from './admin-issues/plugin.client.js';
|
|
16
18
|
export { PermissionDeniedProvider, showPermissionDeniedDialog, handlePermissionDenied, fetchWithPermissionCapture, } from './admin-issues/permission_denied_provider.client.js';
|
|
17
19
|
export type { PermissionDeniedProviderProps } from './admin-issues/permission_denied_provider.client';
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAYA,cAAc,oBAAoB,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAInI,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIpD,cAAc,uBAAuB,CAAC;AAItC,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,mDAAmD,CAAC;AACjH,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC3G,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AACnH,YAAY,EAAE,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAGvI,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAIxG,cAAc,8CAA8C,CAAC;AAG7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,YAAY,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAYA,cAAc,oBAAoB,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAInI,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIpD,cAAc,uBAAuB,CAAC;AAItC,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,mDAAmD,CAAC;AACjH,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC3G,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AACnH,YAAY,EAAE,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAGvI,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAIxG,cAAc,8CAA8C,CAAC;AAG7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,YAAY,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAKzH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAChG,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,YAAY,GACb,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAG5F,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,kDAAkD,CAAC;AAC1D,YAAY,EAAE,6BAA6B,EAAE,MAAM,kDAAkD,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -33,6 +33,10 @@ export * from "./components/layouts/shared/utils/validation.js";
|
|
|
33
33
|
export { requestGoogleScopes } from "./lib/auth/request_google_scopes.js";
|
|
34
34
|
// section: permission_denied_dialog_exports
|
|
35
35
|
export { PermissionDeniedDialog } from "./components/permission_denied_dialog.client.js";
|
|
36
|
+
// section: user_picker_exports
|
|
37
|
+
// Reusable avatar + username dropdown for choosing a user (issue owner,
|
|
38
|
+
// assignee, mention, etc.). Data-agnostic — caller supplies the candidate list.
|
|
39
|
+
export { UserPickerSelect, UserAvatar, userDisplayName } from "./components/user_picker_select.js";
|
|
36
40
|
// admin-issues plugin (client card renderer)
|
|
37
41
|
export { AuthIssueCard, registerAuthIssueCardRenderer } from './admin-issues/plugin.client.js';
|
|
38
42
|
// permission-denied provider + fetch helper
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface PickableUser {
|
|
3
|
+
/** Stable id — the value the picker commits. */
|
|
4
|
+
user_id: string;
|
|
5
|
+
/** Display name; falls back to email, then the id. */
|
|
6
|
+
name?: string | null;
|
|
7
|
+
email?: string | null;
|
|
8
|
+
/** Profile picture URL; absent/failed → tinted initials. */
|
|
9
|
+
profile_picture_url?: string | null;
|
|
10
|
+
}
|
|
11
|
+
export interface UserPickerSelectProps {
|
|
12
|
+
/** Candidate users to choose from. */
|
|
13
|
+
users: PickableUser[];
|
|
14
|
+
/** Selected user_id; null (or "") means unassigned. */
|
|
15
|
+
value: string | null;
|
|
16
|
+
/** Fired with the new user_id, or null when the unassigned row is picked. */
|
|
17
|
+
onChange: (userId: string | null) => void;
|
|
18
|
+
/** Prepend an "Unassigned" row. Default true. */
|
|
19
|
+
includeUnassigned?: boolean;
|
|
20
|
+
/** Label for the unassigned row. Default "Unassigned". */
|
|
21
|
+
unassignedLabel?: string;
|
|
22
|
+
/** Placeholder shown when nothing is selected. Default "Select user". */
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/** Control + avatar sizing. Default "default". */
|
|
26
|
+
size?: "sm" | "default";
|
|
27
|
+
/** Extra classes for the trigger. */
|
|
28
|
+
className?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Classes for the portalled dropdown panel. The list renders in a body-level
|
|
31
|
+
* portal, so it escapes any theme tokens scoped to an ancestor — pass classes
|
|
32
|
+
* here when the surrounding surface pins its own tokens.
|
|
33
|
+
*/
|
|
34
|
+
contentClassName?: string;
|
|
35
|
+
/** Inline styles for the portalled dropdown panel (e.g. pinned CSS token vars). */
|
|
36
|
+
contentStyle?: React.CSSProperties;
|
|
37
|
+
"aria-label"?: string;
|
|
38
|
+
}
|
|
39
|
+
/** name → email → id, so a row is never blank. */
|
|
40
|
+
export declare function userDisplayName(u: PickableUser): string;
|
|
41
|
+
export interface UserAvatarProps {
|
|
42
|
+
user?: PickableUser | null;
|
|
43
|
+
size?: "sm" | "default";
|
|
44
|
+
className?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Standalone avatar: the profile picture when present, else tinted initials,
|
|
48
|
+
* else a muted person glyph for the empty/unassigned slot. Exported so callers
|
|
49
|
+
* can reuse the exact same avatar outside the picker (cards, headers, etc.).
|
|
50
|
+
*/
|
|
51
|
+
export declare function UserAvatar({ user, size, className }: UserAvatarProps): React.JSX.Element;
|
|
52
|
+
/**
|
|
53
|
+
* A Select whose rows show a profile picture + username. The trigger mirrors the
|
|
54
|
+
* selected row (Radix `SelectValue` copies the item's children), so the chosen
|
|
55
|
+
* user's avatar + name show in the closed control automatically.
|
|
56
|
+
*/
|
|
57
|
+
export declare function UserPickerSelect({ users, value, onChange, includeUnassigned, unassignedLabel, placeholder, disabled, size, className, contentClassName, contentStyle, "aria-label": ariaLabel, }: UserPickerSelectProps): React.JSX.Element;
|
|
58
|
+
//# sourceMappingURL=user_picker_select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_picker_select.d.ts","sourceRoot":"","sources":["../../src/components/user_picker_select.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,uDAAuD;IACvD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,YAAY,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAOD,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAEvD;AA+BD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,IAAgB,EAAE,SAAS,EAAE,EAAE,eAAe,qBAsBhF;AAGD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,KAAK,EACL,QAAQ,EACR,iBAAwB,EACxB,eAA8B,EAC9B,WAA2B,EAC3B,QAAQ,EACR,IAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,YAAY,EAAE,SAAS,GACxB,EAAE,qBAAqB,qBAqCvB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// file_description: reusable user-picker dropdown — a Select whose rows render a
|
|
2
|
+
// profile picture (or tinted initials) beside the user's name. Client-safe;
|
|
3
|
+
// built on the shadcn Avatar + Select primitives. Data-agnostic: the caller
|
|
4
|
+
// supplies the candidate users and owns fetching them (e.g. via
|
|
5
|
+
// hazo_get_user_profiles server-side).
|
|
6
|
+
// section: client_directive
|
|
7
|
+
"use client";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { UserRound } from "lucide-react";
|
|
10
|
+
import { Avatar, AvatarImage, AvatarFallback } from "./ui/avatar.js";
|
|
11
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "./ui/select.js";
|
|
12
|
+
import { cn } from "../lib/utils.js";
|
|
13
|
+
// Radix Select forbids an empty-string item value, so the unassigned row uses a
|
|
14
|
+
// sentinel that is mapped back to null across the component boundary.
|
|
15
|
+
const UNASSIGNED = "__hazo_unassigned__";
|
|
16
|
+
// section: helpers
|
|
17
|
+
/** name → email → id, so a row is never blank. */
|
|
18
|
+
export function userDisplayName(u) {
|
|
19
|
+
return (u.name && u.name.trim()) || (u.email && u.email.trim()) || u.user_id;
|
|
20
|
+
}
|
|
21
|
+
/** Up-to-two-letter initials from a label. */
|
|
22
|
+
function initialsOf(label) {
|
|
23
|
+
const s = label.trim();
|
|
24
|
+
if (!s)
|
|
25
|
+
return "?";
|
|
26
|
+
const parts = s.split(/[\s@._-]+/).filter(Boolean);
|
|
27
|
+
if (parts.length === 0)
|
|
28
|
+
return s.slice(0, 2).toUpperCase();
|
|
29
|
+
if (parts.length === 1)
|
|
30
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
31
|
+
return (parts[0][0] + parts[1][0]).toUpperCase();
|
|
32
|
+
}
|
|
33
|
+
// Deterministic fallback tint from a key, so the same user keeps one colour.
|
|
34
|
+
const TINTS = [
|
|
35
|
+
"bg-indigo-500 text-white",
|
|
36
|
+
"bg-emerald-500 text-white",
|
|
37
|
+
"bg-violet-500 text-white",
|
|
38
|
+
"bg-amber-500 text-white",
|
|
39
|
+
"bg-rose-500 text-white",
|
|
40
|
+
"bg-cyan-500 text-white",
|
|
41
|
+
"bg-sky-500 text-white",
|
|
42
|
+
"bg-fuchsia-500 text-white",
|
|
43
|
+
];
|
|
44
|
+
function tintOf(key) {
|
|
45
|
+
let hash = 0;
|
|
46
|
+
for (let i = 0; i < key.length; i++)
|
|
47
|
+
hash = (hash * 31 + key.charCodeAt(i)) | 0;
|
|
48
|
+
return TINTS[Math.abs(hash) % TINTS.length];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Standalone avatar: the profile picture when present, else tinted initials,
|
|
52
|
+
* else a muted person glyph for the empty/unassigned slot. Exported so callers
|
|
53
|
+
* can reuse the exact same avatar outside the picker (cards, headers, etc.).
|
|
54
|
+
*/
|
|
55
|
+
export function UserAvatar({ user, size = "default", className }) {
|
|
56
|
+
const dim = size === "sm" ? "h-5 w-5" : "h-6 w-6";
|
|
57
|
+
if (!user) {
|
|
58
|
+
return (_jsx(Avatar, { className: cn(dim, "bg-muted text-muted-foreground", className), children: _jsx(AvatarFallback, { className: "bg-transparent", children: _jsx(UserRound, { className: size === "sm" ? "h-3 w-3" : "h-3.5 w-3.5" }) }) }));
|
|
59
|
+
}
|
|
60
|
+
const label = userDisplayName(user);
|
|
61
|
+
return (_jsxs(Avatar, { className: cn(dim, className), children: [user.profile_picture_url ? (_jsx(AvatarImage, { src: user.profile_picture_url, alt: "" })) : null, _jsx(AvatarFallback, { className: cn("text-[9px] font-semibold", tintOf(user.user_id)), children: initialsOf(label) })] }));
|
|
62
|
+
}
|
|
63
|
+
// section: user_picker_select
|
|
64
|
+
/**
|
|
65
|
+
* A Select whose rows show a profile picture + username. The trigger mirrors the
|
|
66
|
+
* selected row (Radix `SelectValue` copies the item's children), so the chosen
|
|
67
|
+
* user's avatar + name show in the closed control automatically.
|
|
68
|
+
*/
|
|
69
|
+
export function UserPickerSelect({ users, value, onChange, includeUnassigned = true, unassignedLabel = "Unassigned", placeholder = "Select user", disabled, size = "default", className, contentClassName, contentStyle, "aria-label": ariaLabel, }) {
|
|
70
|
+
const current = value ? value : includeUnassigned ? UNASSIGNED : "";
|
|
71
|
+
const handleChange = (next) => {
|
|
72
|
+
onChange(next === UNASSIGNED ? null : next);
|
|
73
|
+
};
|
|
74
|
+
const triggerSize = size === "sm" ? "h-7 gap-1.5 text-xs" : "h-9 gap-2 text-sm";
|
|
75
|
+
return (_jsxs(Select, { value: current || undefined, onValueChange: handleChange, disabled: disabled, children: [_jsx(SelectTrigger, { "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Select user", className: cn(triggerSize, "min-w-0 [&>span]:truncate", className), children: _jsx(SelectValue, { placeholder: placeholder }) }), _jsxs(SelectContent, { className: contentClassName, style: contentStyle, children: [includeUnassigned ? (_jsx(SelectItem, { value: UNASSIGNED, children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(UserAvatar, { user: null, size: size }), _jsx("span", { className: "truncate", children: unassignedLabel })] }) })) : null, users.map((u) => (_jsx(SelectItem, { value: u.user_id, children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(UserAvatar, { user: u, size: size }), _jsx("span", { className: "truncate", children: userDisplayName(u) })] }) }, u.user_id)))] })] }));
|
|
76
|
+
}
|
|
@@ -17,6 +17,10 @@ export type UiShellConfig = {
|
|
|
17
17
|
/**
|
|
18
18
|
* Reads ui shell configuration controlling whether pages use the sidebar test shell
|
|
19
19
|
* or a clean standalone wrapper that inherits consumer project styling.
|
|
20
|
+
*
|
|
21
|
+
* `standalone` is the default so consuming apps get a clean wrapper out of the box.
|
|
22
|
+
* `test_sidebar` must be explicitly opted into via config and is intended for use
|
|
23
|
+
* by this package's own demo/dev app only.
|
|
20
24
|
*/
|
|
21
25
|
export declare function get_ui_shell_config(): UiShellConfig;
|
|
22
26
|
//# sourceMappingURL=ui_shell_config.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui_shell_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/ui_shell_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAIrB,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG9E,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,YAAY,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,uBAAuB,EAAE,OAAO,CAAC;IACjC,2BAA2B,EAAE,OAAO,CAAC;IACrC,+CAA+C;IAC/C,MAAM,EAAE,YAAY,CAAC;IACrB,mDAAmD;IACnD,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF
|
|
1
|
+
{"version":3,"file":"ui_shell_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/ui_shell_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAIrB,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG9E,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,YAAY,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,uBAAuB,EAAE,OAAO,CAAC;IACjC,2BAA2B,EAAE,OAAO,CAAC;IACrC,+CAA+C;IAC/C,MAAM,EAAE,YAAY,CAAC;IACrB,mDAAmD;IACnD,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CA6DnD"}
|
|
@@ -8,10 +8,14 @@ import { get_navbar_config } from "./navbar_config.server.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* Reads ui shell configuration controlling whether pages use the sidebar test shell
|
|
10
10
|
* or a clean standalone wrapper that inherits consumer project styling.
|
|
11
|
+
*
|
|
12
|
+
* `standalone` is the default so consuming apps get a clean wrapper out of the box.
|
|
13
|
+
* `test_sidebar` must be explicitly opted into via config and is intended for use
|
|
14
|
+
* by this package's own demo/dev app only.
|
|
11
15
|
*/
|
|
12
16
|
export function get_ui_shell_config() {
|
|
13
17
|
const section = "hazo_auth__ui_shell";
|
|
14
|
-
const layoutModeValue = get_config_value(section, "layout_mode", "
|
|
18
|
+
const layoutModeValue = get_config_value(section, "layout_mode", "standalone").toLowerCase();
|
|
15
19
|
const layout_mode = layoutModeValue === "standalone" ? "standalone" : "test_sidebar";
|
|
16
20
|
const standalone_heading = get_config_value(section, "standalone_heading", "Welcome to hazo auth");
|
|
17
21
|
const standalone_description = get_config_value(section, "standalone_description", "Reuse the packaged authentication flows while inheriting your existing app shell styles.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hazo_auth",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.6.0",
|
|
4
4
|
"description": "Zero-config authentication UI components for Next.js with RBAC, OAuth, scope-based multi-tenancy, and invitations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authentication",
|
|
@@ -262,14 +262,14 @@
|
|
|
262
262
|
"@radix-ui/react-switch": "^1.2.0",
|
|
263
263
|
"@radix-ui/react-tabs": "^1.1.0",
|
|
264
264
|
"@radix-ui/react-tooltip": "^1.2.0",
|
|
265
|
-
"hazo_api": "^2.
|
|
265
|
+
"hazo_api": "^2.5.1",
|
|
266
266
|
"hazo_config": "^2.4.1",
|
|
267
267
|
"hazo_connect": "^3.9.0",
|
|
268
|
-
"hazo_core": "^1.2.
|
|
268
|
+
"hazo_core": "^1.2.1",
|
|
269
269
|
"hazo_logs": "^2.1.1",
|
|
270
270
|
"hazo_notify": "^6.1.4",
|
|
271
|
-
"hazo_secure": "^1.
|
|
272
|
-
"hazo_ui": "^4.
|
|
271
|
+
"hazo_secure": "^1.3.0",
|
|
272
|
+
"hazo_ui": "^4.9.0",
|
|
273
273
|
"input-otp": "^1.4.0",
|
|
274
274
|
"lucide-react": "^0.553.0",
|
|
275
275
|
"next": "^14.0.0",
|
|
@@ -408,7 +408,7 @@
|
|
|
408
408
|
"hazo_core": "^1.2.1",
|
|
409
409
|
"hazo_logs": "^2.1.1",
|
|
410
410
|
"hazo_notify": "^6.1.4",
|
|
411
|
-
"hazo_ui": "^4.
|
|
411
|
+
"hazo_ui": "^4.9.0",
|
|
412
412
|
"input-otp": "^1.4.0",
|
|
413
413
|
"jest": "^30.2.0",
|
|
414
414
|
"jest-environment-jsdom": "^30.0.0",
|