@vertebr/react 0.15.0 → 0.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.
@@ -2,6 +2,9 @@ import type { AdminEnvironment, HealthCheck } from "@vertebr/client";
2
2
  import type { VbTheme } from "../../hooks/useVertebrTheme";
3
3
  export type AdminTopBarProps = {
4
4
  brand: string;
5
+ brandLogoUrl?: string;
6
+ /** Optional mark for dark surfaces (skips CSS invert). */
7
+ brandLogoUrlDark?: string;
5
8
  hostName?: string;
6
9
  hostLogoUrl?: string;
7
10
  envList: AdminEnvironment[];
@@ -28,5 +31,5 @@ export type AdminTopBarProps = {
28
31
  healthChecks?: HealthCheck[] | null;
29
32
  onRefreshHealth?: () => Promise<void>;
30
33
  };
31
- export declare function AdminTopBar({ brand, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }: AdminTopBarProps): import("react").JSX.Element;
34
+ export declare function AdminTopBar({ brand, brandLogoUrl, brandLogoUrlDark, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }: AdminTopBarProps): import("react").JSX.Element;
32
35
  //# sourceMappingURL=AdminTopBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminTopBar.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminTopBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAI3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAiBF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,EAAE,gBAAgB,+BA0JlB"}
1
+ {"version":3,"file":"AdminTopBar.d.ts","sourceRoot":"","sources":["../../../src/components/admin/AdminTopBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAI3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAiBF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,EAAE,gBAAgB,+BAoLlB"}
@@ -20,11 +20,15 @@ function healthLabel(tone) {
20
20
  return "Attention";
21
21
  return "Degraded";
22
22
  }
23
- export function AdminTopBar({ brand, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }) {
23
+ export function AdminTopBar({ brand, brandLogoUrl, brandLogoUrlDark, hostName, hostLogoUrl, envList, environment, onEnvironmentChange, authUserLabel, onSignOut, getAccessToken, authViaTokenOnly, authRequired, token, tokenDraft, onTokenDraftChange, onSaveToken, onClearToken, theme, onThemeChange, sidebarCollapsed, onToggleSidebar, syncEnabled, onOpenSync, onOpenSearch, healthChecks, onRefreshHealth, }) {
24
24
  const [healthOpen, setHealthOpen] = useState(false);
25
25
  const healthTone = healthOverall(healthChecks);
26
26
  const showTokenField = !getAccessToken &&
27
27
  !authViaTokenOnly &&
28
28
  (authRequired || Boolean(token));
29
- return (_jsxs(_Fragment, { children: [_jsxs("header", { className: "vertebr-topbar", children: [_jsxs("div", { className: "vertebr-topbar-start", children: [_jsx("button", { type: "button", className: "vertebr-topbar-toggle", "aria-label": sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar", onClick: onToggleSidebar, children: _jsx(IconMenu, {}) }), _jsx("div", { className: "vertebr-topbar-brand-wrap", children: hostName ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-topbar-host", "data-primary": "true", children: [hostLogoUrl ? (_jsx("img", { className: "vertebr-topbar-host-logo", src: hostLogoUrl, alt: "" })) : null, _jsx("strong", { className: "vertebr-topbar-host-label", children: hostName })] }), _jsx("span", { className: "vertebr-topbar-product", children: brand })] })) : (_jsx("strong", { className: "vertebr-topbar-brand", children: brand })) }), envList.length > 1 ? (_jsx("div", { className: "vertebr-topbar-env", children: _jsx(EnvSelect, { environments: envList, value: environment, onChange: onEnvironmentChange }) })) : null] }), _jsx("div", { className: "vertebr-topbar-center", children: _jsxs("button", { type: "button", className: "vertebr-topbar-search", onClick: onOpenSearch, children: [_jsx(IconSearch, {}), _jsx("span", { children: "Search admin" }), _jsx("kbd", { children: "\u2318K" })] }) }), _jsxs("div", { className: "vertebr-topbar-end", children: [_jsxs("div", { className: "vertebr-topbar-cluster", "aria-label": "Operations", children: [healthTone && healthChecks?.length ? (_jsxs("button", { type: "button", className: "vertebr-topbar-health", "data-tone": healthTone, "aria-haspopup": "dialog", "aria-expanded": healthOpen, onClick: () => setHealthOpen(true), children: [_jsx("span", { className: "vertebr-topbar-health-dot", "aria-hidden": true }), _jsx("span", { className: "vertebr-topbar-health-text", children: healthLabel(healthTone) })] })) : null, syncEnabled && onOpenSync ? (_jsxs("button", { type: "button", className: "vertebr-topbar-action", onClick: onOpenSync, children: [_jsx(IconSync, {}), _jsx("span", { children: "Sync" })] })) : null] }), showTokenField ? (_jsxs("div", { className: "vertebr-topbar-token", children: [_jsx("input", { className: "vertebr-auth-input", type: "password", placeholder: "Access token", value: tokenDraft, onChange: (event) => onTokenDraftChange(event.target.value), autoComplete: "off" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onSaveToken, children: "Use" }), token ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onClearToken, children: "Clear" })) : null] })) : null, getAccessToken || onSignOut ? (_jsxs("div", { className: "vertebr-topbar-account", children: [getAccessToken && authUserLabel ? (_jsx("span", { className: "vertebr-topbar-user", title: authUserLabel, children: authUserLabel })) : null, onSignOut ? (_jsx("button", { type: "button", className: "vertebr-topbar-signout", onClick: () => void onSignOut(), children: "Sign out" })) : null] })) : null, _jsx(ThemeToggle, { theme: theme, onChange: onThemeChange, compact: true })] })] }), healthOpen && healthChecks?.length ? (_jsx(HealthModal, { checks: healthChecks, environment: environment, onClose: () => setHealthOpen(false), onRefresh: onRefreshHealth })) : null] }));
29
+ return (_jsxs(_Fragment, { children: [_jsxs("header", { className: "vertebr-topbar", children: [_jsxs("div", { className: "vertebr-topbar-start", children: [_jsx("button", { type: "button", className: "vertebr-topbar-toggle", "aria-label": sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar", onClick: onToggleSidebar, children: _jsx(IconMenu, {}) }), _jsx("div", { className: "vertebr-topbar-brand-wrap", children: hostName ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "vertebr-topbar-host", "data-primary": "true", children: [hostLogoUrl ? (_jsx("img", { className: "vertebr-topbar-host-logo", src: hostLogoUrl, alt: "" })) : null, _jsx("strong", { className: "vertebr-topbar-host-label", children: hostName })] }), brandLogoUrl ? (_jsx("span", { className: "vertebr-topbar-product", "data-mark": "true", children: _jsx("img", { className: "vertebr-topbar-brand-mark", src: theme === "light"
30
+ ? brandLogoUrl
31
+ : (brandLogoUrlDark ?? brandLogoUrl), alt: brand }) })) : (_jsx("span", { className: "vertebr-topbar-product", children: brand }))] })) : brandLogoUrl ? (_jsx("span", { className: "vertebr-topbar-brand", children: _jsx("img", { className: "vertebr-topbar-brand-mark", src: theme === "light"
32
+ ? brandLogoUrl
33
+ : (brandLogoUrlDark ?? brandLogoUrl), alt: brand }) })) : (_jsx("strong", { className: "vertebr-topbar-brand", children: brand })) }), envList.length > 1 ? (_jsx("div", { className: "vertebr-topbar-env", children: _jsx(EnvSelect, { environments: envList, value: environment, onChange: onEnvironmentChange }) })) : null] }), _jsx("div", { className: "vertebr-topbar-center", children: _jsxs("button", { type: "button", className: "vertebr-topbar-search", onClick: onOpenSearch, children: [_jsx(IconSearch, {}), _jsx("span", { children: "Search admin" }), _jsx("kbd", { children: "\u2318K" })] }) }), _jsxs("div", { className: "vertebr-topbar-end", children: [_jsxs("div", { className: "vertebr-topbar-cluster", "aria-label": "Operations", children: [healthTone && healthChecks?.length ? (_jsxs("button", { type: "button", className: "vertebr-topbar-health", "data-tone": healthTone, "aria-haspopup": "dialog", "aria-expanded": healthOpen, onClick: () => setHealthOpen(true), children: [_jsx("span", { className: "vertebr-topbar-health-dot", "aria-hidden": true }), _jsx("span", { className: "vertebr-topbar-health-text", children: healthLabel(healthTone) })] })) : null, syncEnabled && onOpenSync ? (_jsxs("button", { type: "button", className: "vertebr-topbar-action", onClick: onOpenSync, children: [_jsx(IconSync, {}), _jsx("span", { children: "Sync" })] })) : null] }), showTokenField ? (_jsxs("div", { className: "vertebr-topbar-token", children: [_jsx("input", { className: "vertebr-auth-input", type: "password", placeholder: "Access token", value: tokenDraft, onChange: (event) => onTokenDraftChange(event.target.value), autoComplete: "off" }), _jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onSaveToken, children: "Use" }), token ? (_jsx("button", { type: "button", className: "vertebr-btn vertebr-btn-quiet", onClick: onClearToken, children: "Clear" })) : null] })) : null, getAccessToken || onSignOut ? (_jsxs("div", { className: "vertebr-topbar-account", children: [getAccessToken && authUserLabel ? (_jsx("span", { className: "vertebr-topbar-user", title: authUserLabel, children: authUserLabel })) : null, onSignOut ? (_jsx("button", { type: "button", className: "vertebr-topbar-signout", onClick: () => void onSignOut(), children: "Sign out" })) : null] })) : null, _jsx(ThemeToggle, { theme: theme, onChange: onThemeChange, compact: true })] })] }), healthOpen && healthChecks?.length ? (_jsx(HealthModal, { checks: healthChecks, environment: environment, onClose: () => setHealthOpen(false), onRefresh: onRefreshHealth })) : null] }));
30
34
  }
@@ -1,4 +1,4 @@
1
1
  import type { VertebrAdminProps } from "./types";
2
2
  export type { VertebrAdminProps } from "./types";
3
- export declare function VertebrAdmin({ apiBase, basePath: basePathProp, title, envStorageKey, tokenStorageKey, themeStorageKey, metricsRangeStorageKey, getAccessToken, authUserLabel, onSignOut, }: VertebrAdminProps): import("react").JSX.Element;
3
+ export declare function VertebrAdmin({ apiBase, basePath: basePathProp, title, envStorageKey, tokenStorageKey, themeStorageKey, metricsRangeStorageKey, getAccessToken, authUserLabel, onSignOut, brandLogoUrl, brandLogoUrlDark, }: VertebrAdminProps): import("react").JSX.Element;
4
4
  //# sourceMappingURL=VertebrAdmin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,YAAY,CAAC,EAC3B,OAAsB,EACtB,QAAQ,EAAE,YAAY,EACtB,KAAuB,EACvB,aAA6B,EAC7B,eAAiC,EACjC,eAAiC,EACjC,sBAAgD,EAChD,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,+BA+xBnB"}
1
+ {"version":3,"file":"VertebrAdmin.d.ts","sourceRoot":"","sources":["../../../src/components/admin/VertebrAdmin.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,YAAY,CAAC,EAC3B,OAAsB,EACtB,QAAQ,EAAE,YAAY,EACtB,KAAuB,EACvB,aAA6B,EAC7B,eAAiC,EACjC,eAAiC,EACjC,sBAAgD,EAChD,cAAc,EACd,aAAa,EACb,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,EAAE,iBAAiB,+BAiyBnB"}
@@ -18,7 +18,7 @@ import { clearStored, readStored, writeStored } from "./storage";
18
18
  import { SaveBarProvider } from "../../hooks/useSaveBar";
19
19
  import { ToastProvider } from "../../hooks/useToast";
20
20
  import { resolveNavIcon } from "../ui/icons";
21
- export function VertebrAdmin({ apiBase = "/admin/api", basePath: basePathProp, title = "Control plane", envStorageKey = "vertebr:env", tokenStorageKey = "vertebr:token", themeStorageKey = "vertebr:theme", metricsRangeStorageKey = "vertebr:metrics-range", getAccessToken, authUserLabel, onSignOut, }) {
21
+ export function VertebrAdmin({ apiBase = "/admin/api", basePath: basePathProp, title = "Control plane", envStorageKey = "vertebr:env", tokenStorageKey = "vertebr:token", themeStorageKey = "vertebr:theme", metricsRangeStorageKey = "vertebr:metrics-range", getAccessToken, authUserLabel, onSignOut, brandLogoUrl, brandLogoUrlDark, }) {
22
22
  const basePath = basePathProp ?? adminBaseFromApiBase(apiBase);
23
23
  const { theme, setTheme } = useVertebrTheme(themeStorageKey);
24
24
  const [environment, setEnvironment] = useState(() => readStored(envStorageKey) ?? "");
@@ -669,5 +669,5 @@ export function VertebrAdmin({ apiBase = "/admin/api", basePath: basePathProp, t
669
669
  : selection?.kind === "addon"
670
670
  ? catalog?.addons?.find((item) => item.id === selection.id)?.description
671
671
  : undefined;
672
- return (_jsx(SaveBarProvider, { children: _jsx(ToastProvider, { children: _jsxs("div", { className: "vertebr-root", "data-env": environment, "data-sidebar-collapsed": sidebarCollapsed || undefined, children: [_jsx(AdminTopBar, { brand: bootstrap?.brand ?? catalog?.brand ?? "Vertebr", hostName: bootstrap?.appearance?.hostName ?? catalog?.appearance?.hostName, hostLogoUrl: bootstrap?.appearance?.hostLogoUrl ?? catalog?.appearance?.hostLogoUrl, envList: envList, environment: environment, onEnvironmentChange: switchEnvironment, authUserLabel: authUserLabel, onSignOut: onSignOut, getAccessToken: getAccessToken, authViaTokenOnly: authViaTokenOnly, authRequired: authRequired, token: token, tokenDraft: tokenDraft, onTokenDraftChange: setTokenDraft, onSaveToken: saveToken, onClearToken: clearToken, theme: theme, onThemeChange: setTheme, sidebarCollapsed: sidebarCollapsed, onToggleSidebar: () => setSidebarCollapsed((prev) => !prev), syncEnabled: syncEnabled, onOpenSync: () => setSelection({ kind: "sync" }), onOpenSearch: () => setSearchOpen(true), healthChecks: healthChecks, onRefreshHealth: catalog?.health ? refreshHealth : undefined }), catalog && searchOpen ? (_jsx(AdminCommandPalette, { catalog: catalog, onClose: () => setSearchOpen(false), onSelect: setSelection })) : null, _jsx(AdminSidebar, { navGroups: navGroups, collapsed: sidebarCollapsed }), _jsxs("main", { className: "vertebr-main", children: [_jsx(AdminHeader, { activeLabel: activeLabel ?? (catalog ? "Dashboard" : "Sign in"), catalogLoaded: Boolean(catalog), authRequired: authRequired, selection: selection, isPageSelection: isPageSelection, hasPagePreview: hasPagePreview, selectionDescription: selectionDescription, error: error, breadcrumbs: breadcrumbsForSelection(selection, catalog) }), _jsx(AdminContent, { client: client, catalog: catalog, selection: selection, onSelectionChange: setSelection, authRequired: authRequired, loading: loading, isPageSelection: isPageSelection, metricsData: metricsData, metricsLoading: metricsLoading, metricsRange: metricsRange, onMetricsRangeChange: changeMetricsRange, onRefreshMetrics: refreshMetrics, galleryData: galleryData, galleryLoading: galleryLoading, onRefreshGallery: refreshGallery, fontLibraryData: fontLibraryData, fontLibraryLoading: fontLibraryLoading, onRefreshFonts: refreshFonts, emailsData: emailsData, emailsLoading: emailsLoading, onRefreshEmails: refreshEmails, resourceData: resourceData, resourceSearch: resourceSearch, onResourceSearchChange: setResourceSearch, onRefreshResource: refreshResource, configData: configData, onConfigSaved: setConfigData, onRefreshConfig: refreshConfig, galleryPicker: galleryPicker, fontLibraryPicker: fontLibraryPicker }), _jsx(AdminSaveBar, {})] }), _jsx(AdminToastStack, {})] }) }) }));
672
+ return (_jsx(SaveBarProvider, { children: _jsx(ToastProvider, { children: _jsxs("div", { className: "vertebr-root", "data-env": environment, "data-sidebar-collapsed": sidebarCollapsed || undefined, children: [_jsx(AdminTopBar, { brand: bootstrap?.brand ?? catalog?.brand ?? "Vertebr", brandLogoUrl: brandLogoUrl, brandLogoUrlDark: brandLogoUrlDark, hostName: bootstrap?.appearance?.hostName ?? catalog?.appearance?.hostName, hostLogoUrl: bootstrap?.appearance?.hostLogoUrl ?? catalog?.appearance?.hostLogoUrl, envList: envList, environment: environment, onEnvironmentChange: switchEnvironment, authUserLabel: authUserLabel, onSignOut: onSignOut, getAccessToken: getAccessToken, authViaTokenOnly: authViaTokenOnly, authRequired: authRequired, token: token, tokenDraft: tokenDraft, onTokenDraftChange: setTokenDraft, onSaveToken: saveToken, onClearToken: clearToken, theme: theme, onThemeChange: setTheme, sidebarCollapsed: sidebarCollapsed, onToggleSidebar: () => setSidebarCollapsed((prev) => !prev), syncEnabled: syncEnabled, onOpenSync: () => setSelection({ kind: "sync" }), onOpenSearch: () => setSearchOpen(true), healthChecks: healthChecks, onRefreshHealth: catalog?.health ? refreshHealth : undefined }), catalog && searchOpen ? (_jsx(AdminCommandPalette, { catalog: catalog, onClose: () => setSearchOpen(false), onSelect: setSelection })) : null, _jsx(AdminSidebar, { navGroups: navGroups, collapsed: sidebarCollapsed }), _jsxs("main", { className: "vertebr-main", children: [_jsx(AdminHeader, { activeLabel: activeLabel ?? (catalog ? "Dashboard" : "Sign in"), catalogLoaded: Boolean(catalog), authRequired: authRequired, selection: selection, isPageSelection: isPageSelection, hasPagePreview: hasPagePreview, selectionDescription: selectionDescription, error: error, breadcrumbs: breadcrumbsForSelection(selection, catalog) }), _jsx(AdminContent, { client: client, catalog: catalog, selection: selection, onSelectionChange: setSelection, authRequired: authRequired, loading: loading, isPageSelection: isPageSelection, metricsData: metricsData, metricsLoading: metricsLoading, metricsRange: metricsRange, onMetricsRangeChange: changeMetricsRange, onRefreshMetrics: refreshMetrics, galleryData: galleryData, galleryLoading: galleryLoading, onRefreshGallery: refreshGallery, fontLibraryData: fontLibraryData, fontLibraryLoading: fontLibraryLoading, onRefreshFonts: refreshFonts, emailsData: emailsData, emailsLoading: emailsLoading, onRefreshEmails: refreshEmails, resourceData: resourceData, resourceSearch: resourceSearch, onResourceSearchChange: setResourceSearch, onRefreshResource: refreshResource, configData: configData, onConfigSaved: setConfigData, onRefreshConfig: refreshConfig, galleryPicker: galleryPicker, fontLibraryPicker: fontLibraryPicker }), _jsx(AdminSaveBar, {})] }), _jsx(AdminToastStack, {})] }) }) }));
673
673
  }
@@ -21,6 +21,15 @@ export type VertebrAdminProps = {
21
21
  authUserLabel?: string;
22
22
  /** Host-provided sign-out action. */
23
23
  onSignOut?: () => void | Promise<void>;
24
+ /**
25
+ * Optional product mark for light UI (dark ink on transparent).
26
+ */
27
+ brandLogoUrl?: string;
28
+ /**
29
+ * Optional product mark for dark UI (light ink on transparent).
30
+ * Falls back to `brandLogoUrl` when omitted.
31
+ */
32
+ brandLogoUrlDark?: string;
24
33
  };
25
34
  import type { ReactElement } from "react";
26
35
  export type EmailsTab = "compose" | "templates" | "activity";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/admin/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oEAAoE;IACpE,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC,CAAC;AAEF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAE7D,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAEtE,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B,IAAI,CAAC;AAET,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/admin/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oEAAoE;IACpE,cAAc,CAAC,EAAE,MACb,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvC,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAE7D,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAEtE,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B,IAAI,CAAC;AAET,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC"}
@@ -91,6 +91,16 @@
91
91
  letter-spacing: -0.01em;
92
92
  white-space: nowrap;
93
93
  color: var(--vb-text);
94
+ display: inline-flex;
95
+ align-items: center;
96
+ line-height: 0;
97
+ }
98
+
99
+ .vertebr-topbar-brand-mark {
100
+ display: block;
101
+ height: 1.55rem;
102
+ width: auto;
103
+ aspect-ratio: 1;
94
104
  }
95
105
 
96
106
  .vertebr-topbar-brand-wrap {
@@ -134,6 +144,16 @@
134
144
  white-space: nowrap;
135
145
  }
136
146
 
147
+ .vertebr-topbar-product[data-mark="true"] {
148
+ line-height: 0;
149
+ letter-spacing: 0;
150
+ text-transform: none;
151
+ }
152
+
153
+ .vertebr-topbar-product[data-mark="true"] .vertebr-topbar-brand-mark {
154
+ height: 1.15rem;
155
+ }
156
+
137
157
  .vertebr-topbar-host-logo {
138
158
  width: 1.15rem;
139
159
  height: 1.15rem;
@@ -64,6 +64,13 @@
64
64
  padding: 0.15rem 0.55rem 0.35rem;
65
65
  }
66
66
 
67
+ .vertebr-brand-mark {
68
+ display: block;
69
+ width: 2.25rem;
70
+ height: 2.25rem;
71
+ margin-bottom: 0.35rem;
72
+ }
73
+
67
74
  .vertebr-brand strong {
68
75
  font-size: 1.05rem;
69
76
  letter-spacing: 0.14em;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertebr/react",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Vertebr admin dashboard UI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",