@cboxdk/cbox-ui 0.7.0 → 0.9.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 +71 -17
- package/dist/app-switcher.d.ts +19 -0
- package/dist/app-switcher.js +7 -0
- package/dist/app-switcher.js.map +1 -0
- package/dist/catalog-BroZWvws.d.ts +100 -0
- package/dist/chunk-AJCYF7SS.js +808 -0
- package/dist/chunk-AJCYF7SS.js.map +1 -0
- package/dist/index.d.ts +56 -48
- package/dist/index.js +60 -201
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
- package/tokens/cbox.css +7 -0
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { cn } from './chunk-OFTNLF7H.js';
|
|
2
2
|
export { cn, niceTicks, timeTicks } from './chunk-OFTNLF7H.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { defineCboxAppSwitcher, subscribeKnownAppCatalog, readKnownAppCatalog, secureIconUrl, initials } from './chunk-AJCYF7SS.js';
|
|
4
|
+
export { authorizeHref, parseAppCatalog, readKnownAppCatalog, rememberAppCatalog, secureIconUrl, signInTarget } from './chunk-AJCYF7SS.js';
|
|
5
|
+
import { createContext, useContext, useMemo, useSyncExternalStore, useState, useEffect, useRef, useCallback, useId, createElement } from 'react';
|
|
6
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
7
|
import { X, Menu, PanelLeftOpen, PanelLeftClose, PinOff, Pin } from 'lucide-react';
|
|
6
8
|
|
|
7
9
|
var CboxIdContext = createContext(null);
|
|
@@ -60,6 +62,30 @@ function useCboxLocalization() {
|
|
|
60
62
|
function defaultDate(value) {
|
|
61
63
|
return new Date(value).toLocaleString();
|
|
62
64
|
}
|
|
65
|
+
var EMPTY = [];
|
|
66
|
+
function useKnownAppCatalog() {
|
|
67
|
+
return useSyncExternalStore(subscribeKnownAppCatalog, readKnownAppCatalog, () => EMPTY);
|
|
68
|
+
}
|
|
69
|
+
function CboxAppIcon({ name, iconUrl, iconDarkUrl, className = "h-6 w-6", fallback }) {
|
|
70
|
+
const light = secureIconUrl(iconUrl);
|
|
71
|
+
const dark = secureIconUrl(iconDarkUrl);
|
|
72
|
+
const [failed, setFailed] = useState(null);
|
|
73
|
+
const key = `${light ?? ""}|${dark ?? ""}`;
|
|
74
|
+
if (light === null || failed === key) {
|
|
75
|
+
if (fallback !== void 0) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
76
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("grid shrink-0 place-items-center rounded bg-secondary text-[11px] font-semibold text-foreground", className), children: initials(name) });
|
|
77
|
+
}
|
|
78
|
+
const lost = () => setFailed(key);
|
|
79
|
+
return /* @__PURE__ */ jsxs("span", { "aria-hidden": true, className: cn("cbx-app-icon-box inline-flex shrink-0 items-center justify-center", className), children: [
|
|
80
|
+
/* @__PURE__ */ jsx("img", { src: light, alt: "", decoding: "async", onError: lost, className: cn("cbx-app-icon", dark === null ? "cbx-app-icon-single" : "cbx-app-icon-light", "h-full w-full") }),
|
|
81
|
+
dark !== null && /* @__PURE__ */ jsx("img", { src: dark, alt: "", decoding: "async", onError: lost, className: "cbx-app-icon cbx-app-icon-dark h-full w-full" })
|
|
82
|
+
] });
|
|
83
|
+
}
|
|
84
|
+
function CboxServiceMark({ appKey, className = "h-6 w-6", fallback = null }) {
|
|
85
|
+
const app = useKnownAppCatalog().find((entry) => entry.key === appKey);
|
|
86
|
+
if (app === void 0 || app.icon_url === null) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
87
|
+
return /* @__PURE__ */ jsx(CboxAppIcon, { name: app.name, iconUrl: app.icon_url, iconDarkUrl: app.icon_dark_url, className, fallback: fallback ?? void 0 });
|
|
88
|
+
}
|
|
63
89
|
function CboxBrand({
|
|
64
90
|
appKey,
|
|
65
91
|
submark,
|
|
@@ -69,7 +95,7 @@ function CboxBrand({
|
|
|
69
95
|
className
|
|
70
96
|
}) {
|
|
71
97
|
if (collapsed) {
|
|
72
|
-
|
|
98
|
+
const cboxIcon = /* @__PURE__ */ jsx(
|
|
73
99
|
"img",
|
|
74
100
|
{
|
|
75
101
|
src: `${assetBase}/cbox-icon.png`,
|
|
@@ -80,6 +106,7 @@ function CboxBrand({
|
|
|
80
106
|
className: cn("h-9 w-9 rounded-md", className)
|
|
81
107
|
}
|
|
82
108
|
);
|
|
109
|
+
return /* @__PURE__ */ jsx(CboxServiceMark, { appKey, className: cn("h-9 w-9", className), fallback: cboxIcon });
|
|
83
110
|
}
|
|
84
111
|
const wordmark = tone === "light" ? `${assetBase}/cbox-logo-white.png` : `${assetBase}/cbox-logo.png`;
|
|
85
112
|
const wordmarkRetina = tone === "light" ? `${assetBase}/cbox-logo-white@2x.png` : `${assetBase}/cbox-logo@2x.png`;
|
|
@@ -467,21 +494,13 @@ function AppSwitcher({ className, onLockedAppClick }) {
|
|
|
467
494
|
/* @__PURE__ */ jsx(
|
|
468
495
|
"span",
|
|
469
496
|
{
|
|
470
|
-
style: triggerAccent !== void 0 ? {
|
|
497
|
+
style: triggerAccent !== void 0 && secureIconUrl(currentApp?.iconUrl) === null ? {
|
|
471
498
|
backgroundColor: triggerAccent,
|
|
472
499
|
color: "#fff",
|
|
473
500
|
borderColor: triggerAccent
|
|
474
501
|
} : void 0,
|
|
475
502
|
className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-sm border border-border bg-secondary text-[10px] font-bold",
|
|
476
|
-
children: currentApp
|
|
477
|
-
"img",
|
|
478
|
-
{
|
|
479
|
-
src: currentApp.iconUrl,
|
|
480
|
-
alt: "",
|
|
481
|
-
className: "h-3.5 w-3.5",
|
|
482
|
-
loading: "eager"
|
|
483
|
-
}
|
|
484
|
-
) : triggerMonogram
|
|
503
|
+
children: currentApp ? /* @__PURE__ */ jsx(CboxAppIcon, { name: currentApp.name, iconUrl: currentApp.iconUrl, iconDarkUrl: currentApp.iconDarkUrl, className: "h-3.5 w-3.5", fallback: /* @__PURE__ */ jsx(Fragment, { children: triggerMonogram }) }) : triggerMonogram
|
|
485
504
|
}
|
|
486
505
|
),
|
|
487
506
|
/* @__PURE__ */ jsx("span", { className: "max-w-[140px] truncate", children: triggerName }),
|
|
@@ -581,7 +600,7 @@ function AppRow({
|
|
|
581
600
|
const isLocked = app.entitled === false || isComingSoon;
|
|
582
601
|
const monogram = app.monogram ?? app.name.slice(0, 1).toUpperCase();
|
|
583
602
|
const accent = app.accentColor;
|
|
584
|
-
const tileStyle = accent !== void 0 && app.iconUrl ===
|
|
603
|
+
const tileStyle = accent !== void 0 && secureIconUrl(app.iconUrl) === null ? { backgroundColor: accent, color: "#fff", borderColor: accent } : void 0;
|
|
585
604
|
const href = orgSlug !== void 0 && app.current !== true ? buildOrgUrl(app.url, orgSlug) : app.url;
|
|
586
605
|
const tile = /* @__PURE__ */ jsx(
|
|
587
606
|
"div",
|
|
@@ -592,7 +611,7 @@ function AppRow({
|
|
|
592
611
|
app.current && "ring-2 ring-accent-edge ring-offset-1 ring-offset-popover",
|
|
593
612
|
isLocked && "opacity-60 grayscale"
|
|
594
613
|
),
|
|
595
|
-
children:
|
|
614
|
+
children: /* @__PURE__ */ jsx(CboxAppIcon, { name: app.name, iconUrl: app.iconUrl, iconDarkUrl: app.iconDarkUrl, className: "h-5 w-5", fallback: /* @__PURE__ */ jsx("span", { children: monogram }) })
|
|
596
615
|
}
|
|
597
616
|
);
|
|
598
617
|
const body = /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
@@ -1491,7 +1510,7 @@ function UserMenu({ extras, className, placement = "bottom-end", LinkComponent:
|
|
|
1491
1510
|
const { t } = useCboxLocalization();
|
|
1492
1511
|
const { user, currentOrganization, urls } = useCboxId();
|
|
1493
1512
|
const [open, setOpen] = useState(false);
|
|
1494
|
-
const
|
|
1513
|
+
const initials2 = user.name.split(/\s+/).filter(Boolean).slice(0, 2).map((n) => n[0]?.toUpperCase() ?? "").join("");
|
|
1495
1514
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), onKeyDown: (event) => {
|
|
1496
1515
|
if (event.key === "Escape") setOpen(false);
|
|
1497
1516
|
}, onBlur: (event) => {
|
|
@@ -1515,7 +1534,7 @@ function UserMenu({ extras, className, placement = "bottom-end", LinkComponent:
|
|
|
1515
1534
|
alt: "",
|
|
1516
1535
|
className: "h-7 w-7 rounded-full object-cover"
|
|
1517
1536
|
}
|
|
1518
|
-
) : /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-[11px] font-semibold text-foreground", children:
|
|
1537
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-[11px] font-semibold text-foreground", children: initials2 || "?" })
|
|
1519
1538
|
}
|
|
1520
1539
|
),
|
|
1521
1540
|
open ? /* @__PURE__ */ jsxs("div", { className: cn("absolute z-50 w-64 rounded-lg border border-border bg-popover p-1 shadow-md", placement === "top-start" ? "bottom-full left-0 mb-2" : "right-0 top-full mt-1"), children: [
|
|
@@ -1946,7 +1965,7 @@ function ContextAvatarChip({
|
|
|
1946
1965
|
fallbackLabel,
|
|
1947
1966
|
size = "md"
|
|
1948
1967
|
}) {
|
|
1949
|
-
const
|
|
1968
|
+
const initials2 = avatar.initials ?? deriveInitials(fallbackLabel);
|
|
1950
1969
|
const sizeClass = size === "sm" ? "h-[26px] w-[26px] text-[10px]" : "h-7 w-7 text-[11px]";
|
|
1951
1970
|
const style = avatar.src === void 0 && avatar.accent !== void 0 ? {
|
|
1952
1971
|
backgroundColor: avatar.accent,
|
|
@@ -1975,7 +1994,7 @@ function ContextAvatarChip({
|
|
|
1975
1994
|
avatar.accent === void 0 && "bg-info-soft text-info",
|
|
1976
1995
|
sizeClass
|
|
1977
1996
|
),
|
|
1978
|
-
children:
|
|
1997
|
+
children: initials2
|
|
1979
1998
|
}
|
|
1980
1999
|
);
|
|
1981
2000
|
}
|
|
@@ -2432,7 +2451,7 @@ function AppRow2({ app, orgSlug, onLockedAppClick }) {
|
|
|
2432
2451
|
const isLocked = app.entitled === false || isComingSoon;
|
|
2433
2452
|
const monogram = app.monogram ?? app.name.slice(0, 1).toUpperCase();
|
|
2434
2453
|
const accent = app.accentColor;
|
|
2435
|
-
const tileStyle = accent !== void 0 && app.iconUrl ===
|
|
2454
|
+
const tileStyle = accent !== void 0 && secureIconUrl(app.iconUrl) === null ? { backgroundColor: accent, color: "#fff", borderColor: accent } : void 0;
|
|
2436
2455
|
const href = orgSlug !== void 0 && app.current !== true ? buildOrgUrl2(app.url, orgSlug) : app.url;
|
|
2437
2456
|
const tile = /* @__PURE__ */ jsx(
|
|
2438
2457
|
"div",
|
|
@@ -2443,7 +2462,7 @@ function AppRow2({ app, orgSlug, onLockedAppClick }) {
|
|
|
2443
2462
|
app.current && "ring-2 ring-accent-edge ring-offset-1 ring-offset-popover",
|
|
2444
2463
|
isLocked && "opacity-60 grayscale"
|
|
2445
2464
|
),
|
|
2446
|
-
children:
|
|
2465
|
+
children: /* @__PURE__ */ jsx(CboxAppIcon, { name: app.name, iconUrl: app.iconUrl, iconDarkUrl: app.iconDarkUrl, className: "h-5 w-5", fallback: /* @__PURE__ */ jsx("span", { children: monogram }) })
|
|
2447
2466
|
}
|
|
2448
2467
|
);
|
|
2449
2468
|
const body = /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
@@ -2573,182 +2592,22 @@ function Lock2() {
|
|
|
2573
2592
|
}
|
|
2574
2593
|
);
|
|
2575
2594
|
}
|
|
2576
|
-
|
|
2577
|
-
function
|
|
2578
|
-
const data = typeof body === "object" && body !== null ? body : {};
|
|
2579
|
-
if (!ok) {
|
|
2580
|
-
const authorize = typeof data.authorize_url === "string" ? data.authorize_url : null;
|
|
2581
|
-
if (authorize !== null || data.state === "authorization_required") {
|
|
2582
|
-
return { status: "authorization_required", authorizeUrl: authorize };
|
|
2583
|
-
}
|
|
2584
|
-
return { status: "unavailable" };
|
|
2585
|
-
}
|
|
2586
|
-
if (!Array.isArray(data.apps)) {
|
|
2587
|
-
return { status: "unavailable" };
|
|
2588
|
-
}
|
|
2589
|
-
const apps = [];
|
|
2590
|
-
for (const entry of data.apps) {
|
|
2591
|
-
if (typeof entry !== "object" || entry === null) continue;
|
|
2592
|
-
const app = entry;
|
|
2593
|
-
if (typeof app.key !== "string" || typeof app.name !== "string" || typeof app.launch_url !== "string") continue;
|
|
2594
|
-
if (!/^https?:\/\//.test(app.launch_url)) continue;
|
|
2595
|
-
apps.push({
|
|
2596
|
-
key: app.key,
|
|
2597
|
-
name: app.name,
|
|
2598
|
-
launch_url: app.launch_url,
|
|
2599
|
-
icon_url: typeof app.icon_url === "string" ? app.icon_url : null,
|
|
2600
|
-
description: typeof app.description === "string" ? app.description : null
|
|
2601
|
-
});
|
|
2602
|
-
}
|
|
2603
|
-
const refresh = typeof data.refresh_after === "number" && Number.isFinite(data.refresh_after) ? data.refresh_after : DEFAULT_REFRESH_SECONDS;
|
|
2604
|
-
return { status: "ready", apps, refreshAfter: Math.max(1, Math.min(DEFAULT_REFRESH_SECONDS, refresh)) };
|
|
2605
|
-
}
|
|
2606
|
-
function authorizeHref(authorizeUrl, location) {
|
|
2607
|
-
if (authorizeUrl === null) return null;
|
|
2608
|
-
try {
|
|
2609
|
-
const url = new URL(authorizeUrl, location.origin);
|
|
2610
|
-
if (url.origin !== location.origin) return null;
|
|
2611
|
-
url.searchParams.set("return_to", location.pathname + location.search);
|
|
2612
|
-
return url.pathname + url.search;
|
|
2613
|
-
} catch {
|
|
2614
|
-
return null;
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
function CboxAppCatalog({ endpoint, currentAppKey, icons, className }) {
|
|
2595
|
+
defineCboxAppSwitcher();
|
|
2596
|
+
function CboxAppCatalog({ endpoint, currentAppKey, theme, className }) {
|
|
2618
2597
|
const { t } = useCboxLocalization();
|
|
2619
|
-
const
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
cache: "no-store",
|
|
2633
|
-
headers: { Accept: "application/json", "X-Requested-With": "XMLHttpRequest" },
|
|
2634
|
-
signal: request.signal
|
|
2635
|
-
});
|
|
2636
|
-
const body = await response.json().catch(() => null);
|
|
2637
|
-
if (request.signal.aborted) return;
|
|
2638
|
-
const next = parseAppCatalog(response.ok, body);
|
|
2639
|
-
expires.current = next.status === "ready" ? Date.now() + next.refreshAfter * 1e3 : 0;
|
|
2640
|
-
setState(next);
|
|
2641
|
-
} catch {
|
|
2642
|
-
if (!request.signal.aborted) {
|
|
2643
|
-
expires.current = 0;
|
|
2644
|
-
setState({ status: "unavailable" });
|
|
2645
|
-
}
|
|
2646
|
-
} finally {
|
|
2647
|
-
if (flight.current === request) flight.current = null;
|
|
2648
|
-
}
|
|
2649
|
-
}, [endpoint]);
|
|
2650
|
-
const refresh = useCallback(() => {
|
|
2651
|
-
if (document.visibilityState === "visible" && Date.now() >= expires.current) void load();
|
|
2652
|
-
}, [load]);
|
|
2653
|
-
useEffect(() => {
|
|
2654
|
-
if (!open) return;
|
|
2655
|
-
refresh();
|
|
2656
|
-
const outside = (event) => {
|
|
2657
|
-
if (container.current !== null && !container.current.contains(event.target)) setOpen(false);
|
|
2658
|
-
};
|
|
2659
|
-
const key = (event) => {
|
|
2660
|
-
if (event.key === "Escape") setOpen(false);
|
|
2661
|
-
};
|
|
2662
|
-
window.addEventListener("pointerdown", outside);
|
|
2663
|
-
window.addEventListener("keydown", key);
|
|
2664
|
-
window.addEventListener("focus", refresh);
|
|
2665
|
-
document.addEventListener("visibilitychange", refresh);
|
|
2666
|
-
return () => {
|
|
2667
|
-
window.removeEventListener("pointerdown", outside);
|
|
2668
|
-
window.removeEventListener("keydown", key);
|
|
2669
|
-
window.removeEventListener("focus", refresh);
|
|
2670
|
-
document.removeEventListener("visibilitychange", refresh);
|
|
2671
|
-
};
|
|
2672
|
-
}, [open, refresh]);
|
|
2673
|
-
useEffect(() => {
|
|
2674
|
-
if (!open || state.status !== "ready") return;
|
|
2675
|
-
const timer = window.setTimeout(refresh, Math.max(50, expires.current - Date.now()));
|
|
2676
|
-
return () => window.clearTimeout(timer);
|
|
2677
|
-
}, [open, state, refresh]);
|
|
2678
|
-
useEffect(() => () => flight.current?.abort(), []);
|
|
2679
|
-
useEffect(() => {
|
|
2680
|
-
expires.current = 0;
|
|
2681
|
-
setState({ status: "idle" });
|
|
2682
|
-
}, [endpoint]);
|
|
2683
|
-
const reconnect = state.status === "authorization_required" && typeof window !== "undefined" ? authorizeHref(state.authorizeUrl, window.location) : null;
|
|
2684
|
-
return /* @__PURE__ */ jsxs("div", { ref: container, className: cn("relative", className), children: [
|
|
2685
|
-
/* @__PURE__ */ jsx(
|
|
2686
|
-
"button",
|
|
2687
|
-
{
|
|
2688
|
-
type: "button",
|
|
2689
|
-
"aria-label": t("Switch app"),
|
|
2690
|
-
title: t("Switch app"),
|
|
2691
|
-
"aria-haspopup": "dialog",
|
|
2692
|
-
"aria-expanded": open,
|
|
2693
|
-
disabled: endpoint === null,
|
|
2694
|
-
onClick: () => setOpen((value) => !value),
|
|
2695
|
-
className: cn(
|
|
2696
|
-
"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground disabled:cursor-default disabled:opacity-60 disabled:hover:bg-transparent",
|
|
2697
|
-
open && "bg-secondary text-foreground"
|
|
2698
|
-
),
|
|
2699
|
-
children: /* @__PURE__ */ jsx(Grid2, {})
|
|
2700
|
-
}
|
|
2701
|
-
),
|
|
2702
|
-
open ? /* @__PURE__ */ jsxs("div", { role: "dialog", "aria-label": t("Switch app"), className: "absolute right-0 top-full z-50 mt-1.5 w-[min(18.25rem,calc(100vw-1rem))] overflow-hidden rounded-lg border border-border bg-popover p-3 shadow-lg", children: [
|
|
2703
|
-
/* @__PURE__ */ jsx("h2", { className: "mb-2 text-sm font-semibold text-foreground", children: t("Switch app") }),
|
|
2704
|
-
/* @__PURE__ */ jsxs("div", { "aria-live": "polite", children: [
|
|
2705
|
-
(state.status === "idle" || state.status === "loading") && /* @__PURE__ */ jsx("p", { className: "px-1 py-2 text-sm text-muted-foreground", children: t("Loading apps\u2026") }),
|
|
2706
|
-
state.status === "unavailable" && /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-1 py-2 text-sm", children: [
|
|
2707
|
-
/* @__PURE__ */ jsx("p", { role: "alert", className: "text-muted-foreground", children: t("Apps could not be loaded.") }),
|
|
2708
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void load(), className: "font-medium text-foreground underline", children: t("Try again") })
|
|
2709
|
-
] }),
|
|
2710
|
-
state.status === "authorization_required" && /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-1 py-2 text-sm", children: [
|
|
2711
|
-
/* @__PURE__ */ jsx("p", { role: "alert", className: "text-muted-foreground", children: t("Apps could not be loaded.") }),
|
|
2712
|
-
reconnect !== null ? /* @__PURE__ */ jsx("a", { href: reconnect, className: "font-medium text-foreground underline", children: t("Reconnect to Cbox ID") }) : /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void load(), className: "font-medium text-foreground underline", children: t("Try again") })
|
|
2713
|
-
] }),
|
|
2714
|
-
state.status === "ready" && (state.apps.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-1 py-2 text-sm text-muted-foreground", children: t("No apps available") }) : /* @__PURE__ */ jsx("nav", { "aria-label": t("Switch app"), className: "grid grid-cols-3 gap-1", children: state.apps.map((app) => {
|
|
2715
|
-
const current = app.key === currentAppKey;
|
|
2716
|
-
return /* @__PURE__ */ jsxs(
|
|
2717
|
-
"a",
|
|
2718
|
-
{
|
|
2719
|
-
href: app.launch_url,
|
|
2720
|
-
"aria-current": current ? "true" : void 0,
|
|
2721
|
-
title: app.description ?? app.name,
|
|
2722
|
-
onClick: () => setOpen(false),
|
|
2723
|
-
className: cn("relative flex min-h-[60px] min-w-0 flex-col items-center justify-center gap-1.5 rounded-md p-2 text-center text-[13px] font-medium leading-tight text-foreground hover:bg-secondary", current && "bg-accent-soft"),
|
|
2724
|
-
children: [
|
|
2725
|
-
/* @__PURE__ */ jsx(AppMark, { app, icon: icons?.[app.key] }),
|
|
2726
|
-
/* @__PURE__ */ jsx("span", { className: "max-w-full break-words", children: app.name.replace(/^Cbox\s*·\s*/i, "") }),
|
|
2727
|
-
current && /* @__PURE__ */ jsx(Check2, {})
|
|
2728
|
-
]
|
|
2729
|
-
},
|
|
2730
|
-
app.key
|
|
2731
|
-
);
|
|
2732
|
-
}) }))
|
|
2733
|
-
] })
|
|
2734
|
-
] }) : null
|
|
2735
|
-
] });
|
|
2736
|
-
}
|
|
2737
|
-
function AppMark({ app, icon }) {
|
|
2738
|
-
const [failed, setFailed] = useState(false);
|
|
2739
|
-
if (icon !== void 0) {
|
|
2740
|
-
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "flex h-6 w-6 items-center justify-center", children: icon });
|
|
2741
|
-
}
|
|
2742
|
-
if (typeof app.icon_url === "string" && app.icon_url !== "" && !failed) {
|
|
2743
|
-
return /* @__PURE__ */ jsx("img", { src: app.icon_url, alt: "", className: "h-6 w-6 rounded object-contain", loading: "lazy", onError: () => setFailed(true) });
|
|
2744
|
-
}
|
|
2745
|
-
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "grid h-6 w-6 place-items-center rounded bg-secondary text-[11px] font-semibold text-foreground", children: app.name.slice(0, 2) });
|
|
2746
|
-
}
|
|
2747
|
-
function Grid2() {
|
|
2748
|
-
return /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "currentColor", "aria-hidden": true, children: [3, 9, 15].flatMap((y) => [3, 9, 15].map((x) => /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: "1.65" }, `${x}-${y}`))) });
|
|
2749
|
-
}
|
|
2750
|
-
function Check2() {
|
|
2751
|
-
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", className: "absolute right-2 top-1.5 h-3 w-3 text-accent", children: /* @__PURE__ */ jsx("path", { d: "m5 12 4 4L19 6" }) });
|
|
2598
|
+
const labels = JSON.stringify({
|
|
2599
|
+
title: t("Switch app"),
|
|
2600
|
+
loading: t("Loading apps\u2026"),
|
|
2601
|
+
empty: t("No apps available"),
|
|
2602
|
+
unavailable: t("Apps could not be loaded.")
|
|
2603
|
+
});
|
|
2604
|
+
return createElement("cbox-app-switcher", {
|
|
2605
|
+
endpoint: endpoint ?? "",
|
|
2606
|
+
current: currentAppKey,
|
|
2607
|
+
labels,
|
|
2608
|
+
theme,
|
|
2609
|
+
className
|
|
2610
|
+
});
|
|
2752
2611
|
}
|
|
2753
2612
|
function Combobox(props) {
|
|
2754
2613
|
const { t } = useCboxLocalization();
|
|
@@ -3053,7 +2912,7 @@ function ComboboxGroupRows({
|
|
|
3053
2912
|
/* @__PURE__ */ jsx("span", { className: "truncate text-[13px] font-medium text-foreground", children: opt.label }),
|
|
3054
2913
|
opt.secondary !== void 0 ? /* @__PURE__ */ jsx("span", { className: "text-mono truncate text-[10px] text-muted-foreground", children: opt.secondary }) : null
|
|
3055
2914
|
] }),
|
|
3056
|
-
isActive ? /* @__PURE__ */ jsx(
|
|
2915
|
+
isActive ? /* @__PURE__ */ jsx(Check2, {}) : null
|
|
3057
2916
|
] });
|
|
3058
2917
|
const className = cn(
|
|
3059
2918
|
"group block w-full rounded-sm transition-colors text-left",
|
|
@@ -3145,7 +3004,7 @@ function ComboboxAvatarChip({
|
|
|
3145
3004
|
avatar,
|
|
3146
3005
|
fallbackLabel
|
|
3147
3006
|
}) {
|
|
3148
|
-
const
|
|
3007
|
+
const initials2 = avatar.initials ?? deriveInitials3(fallbackLabel);
|
|
3149
3008
|
const style = avatar.src === void 0 && avatar.accent !== void 0 ? { backgroundColor: avatar.accent, color: "#fff" } : void 0;
|
|
3150
3009
|
if (avatar.src !== void 0) {
|
|
3151
3010
|
return /* @__PURE__ */ jsx(
|
|
@@ -3166,7 +3025,7 @@ function ComboboxAvatarChip({
|
|
|
3166
3025
|
"flex h-5 w-5 shrink-0 items-center justify-center rounded-sm text-[9px] font-semibold tracking-tight",
|
|
3167
3026
|
avatar.accent === void 0 && "bg-info-soft text-info"
|
|
3168
3027
|
),
|
|
3169
|
-
children:
|
|
3028
|
+
children: initials2
|
|
3170
3029
|
}
|
|
3171
3030
|
);
|
|
3172
3031
|
}
|
|
@@ -3235,7 +3094,7 @@ function Chevron4({ open }) {
|
|
|
3235
3094
|
}
|
|
3236
3095
|
);
|
|
3237
3096
|
}
|
|
3238
|
-
function
|
|
3097
|
+
function Check2() {
|
|
3239
3098
|
return /* @__PURE__ */ jsx(
|
|
3240
3099
|
"svg",
|
|
3241
3100
|
{
|
|
@@ -4011,6 +3870,6 @@ function Sparkline({ values, color = "var(--chart-1)", width = 90, height = 20 }
|
|
|
4011
3870
|
] });
|
|
4012
3871
|
}
|
|
4013
3872
|
|
|
4014
|
-
export { AppContent, AppLauncher, AppShell, AppSwitcher, CHART_PALETTE, CboxAppCatalog, CboxAppShell, CboxAppSidebar, CboxBrand, CboxIdProvider, CboxLocalizationProvider, CboxMobileNavDrawer, CboxOrgContextBar, CboxSurfaces, CboxWorkspaceShell, Combobox, ContextAvatarChip, ContextBar, DataPanel, EmptyState, Heading, KeyValue, KeyValueList, NotificationsBell, OrgSwitcher, PageHeader, PageShell, PageTabs, PanelBody, RowLink, SearchTrigger, SectionHeader, Sparkline, StatTile, StatusPill, TopBar, UserMenu, activeNavArea, activeNavItem,
|
|
3873
|
+
export { AppContent, AppLauncher, AppShell, AppSwitcher, CHART_PALETTE, CboxAppCatalog, CboxAppIcon, CboxAppShell, CboxAppSidebar, CboxBrand, CboxIdProvider, CboxLocalizationProvider, CboxMobileNavDrawer, CboxOrgContextBar, CboxServiceMark, CboxSurfaces, CboxWorkspaceShell, Combobox, ContextAvatarChip, ContextBar, DataPanel, EmptyState, Heading, KeyValue, KeyValueList, NotificationsBell, OrgSwitcher, PageHeader, PageShell, PageTabs, PanelBody, RowLink, SearchTrigger, SectionHeader, Sparkline, StatTile, StatusPill, TopBar, UserMenu, activeNavArea, activeNavItem, buildUrlSearch, defineUrlSchema, interpolate, navMatchLength, parseUrlSearch, urlBoolean, urlEnum, urlNumber, urlString, urlStringArray, useCboxId, useCboxIdOptional, useCboxLocalization, useCboxSurfaces, useCboxSurfacesOptional, useKnownAppCatalog };
|
|
4015
3874
|
//# sourceMappingURL=index.js.map
|
|
4016
3875
|
//# sourceMappingURL=index.js.map
|