@cboxdk/cbox-ui 0.8.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/app-switcher/catalog.ts","../src/app-switcher/theme.ts","../src/app-switcher/styles.ts","../src/app-switcher/elements.ts"],"names":["sheet","stop"],"mappings":"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","file":"chunk-AJCYF7SS.js","sourcesContent":["/**\n * The app catalog contract every Cbox app serves, and the copy of it this browser keeps.\n * Framework-free: the `<cbox-app-switcher>` element and the React components both read it.\n *\n * Every app's icon comes from Cbox ID's catalog: one light and one dark upload per app\n * (`icon_url`, `icon_dark_url`). No app keeps a local copy of the marks.\n */\n\n/** One app as the host's catalog endpoint lists it. */\nexport type CboxCatalogApp = {\n key: string;\n name: string;\n launch_url: string;\n /** Cbox ID's uploaded icon for light surfaces. */\n icon_url?: string | null;\n /** Cbox ID's uploaded icon for dark surfaces. */\n icon_dark_url?: string | null;\n description?: string | null;\n};\n\nexport type CboxAppCatalogState =\n | { status: 'idle' | 'loading' }\n | { status: 'ready'; apps: CboxCatalogApp[]; refreshAfter: number }\n /**\n * The person has to sign in again. `signinUrl` is the new contract (the host's `401\n * { signin_url }`), `authorizeUrl` the legacy one (`{ authorize_url }`).\n */\n | { status: 'signin_required'; signinUrl: string | null; authorizeUrl: string | null }\n | { status: 'unavailable' };\n\n/** One app as this browser keeps it between pages. */\nexport type CboxKnownApp = { key: string; name: string; icon_url: string | null; icon_dark_url: string | null; launch_url?: string };\n\nexport const DEFAULT_REFRESH_SECONDS = 60;\nexport const KEPT_CATALOG_KEY = 'cbox-app-catalog';\nexport const CATALOG_EVENT = 'cbox-app-catalog';\n\n/**\n * Interpret the catalog endpoint's answer:\n *\n * - `200 { apps: [{ key, name, launch_url, icon_url?, icon_dark_url?, description? }], refresh_after?: seconds }`\n * - `401`/`403 { signin_url }`: the person signs in again there. The legacy `{ authorize_url }`\n * and `{ state: 'authorization_required' }` mean the same.\n * - anything else: unavailable right now.\n *\n * Only `http(s)` launch URLs are kept: the tiles are links the person will click.\n */\nexport function parseAppCatalog(ok: boolean, body: unknown): CboxAppCatalogState {\n const data = typeof body === 'object' && body !== null ? (body as Record<string, unknown>) : {};\n if (!ok) {\n const signin = typeof data.signin_url === 'string' && data.signin_url !== '' ? data.signin_url : null;\n const authorize = typeof data.authorize_url === 'string' && data.authorize_url !== '' ? data.authorize_url : null;\n if (signin !== null || authorize !== null || data.state === 'authorization_required') {\n return { status: 'signin_required', signinUrl: signin, authorizeUrl: authorize };\n }\n\n return { status: 'unavailable' };\n }\n if (!Array.isArray(data.apps)) {\n return { status: 'unavailable' };\n }\n const apps: CboxCatalogApp[] = [];\n for (const entry of data.apps as unknown[]) {\n if (typeof entry !== 'object' || entry === null) continue;\n const app = entry as Record<string, unknown>;\n if (typeof app.key !== 'string' || typeof app.name !== 'string' || typeof app.launch_url !== 'string') continue;\n if (!/^https?:\\/\\//i.test(app.launch_url)) continue;\n apps.push({\n key: app.key,\n name: app.name,\n launch_url: app.launch_url,\n icon_url: typeof app.icon_url === 'string' ? app.icon_url : null,\n icon_dark_url: typeof app.icon_dark_url === 'string' ? app.icon_dark_url : null,\n description: typeof app.description === 'string' ? app.description : null,\n });\n }\n const refresh = typeof data.refresh_after === 'number' && Number.isFinite(data.refresh_after) ? data.refresh_after : DEFAULT_REFRESH_SECONDS;\n\n return { status: 'ready', apps, refreshAfter: Math.max(1, Math.min(DEFAULT_REFRESH_SECONDS, refresh)) };\n}\n\ntype Here = { origin: string; pathname: string; search: string };\n\n/** The legacy authorize link with `return_to` set to where the person is, on this origin only. */\nexport function authorizeHref(authorizeUrl: string | null, location: Here): string | null {\n if (authorizeUrl === null) return null;\n try {\n const url = new URL(authorizeUrl, location.origin);\n if (url.origin !== location.origin) return null;\n url.searchParams.set('return_to', location.pathname + location.search);\n\n return url.pathname + url.search;\n } catch {\n return null;\n }\n}\n\n/**\n * Where to send the person when the catalog says they must sign in again: the host's\n * `signin_url` when it is on this origin (the app's own sign-in; never another site), else the legacy authorize\n * link with `return_to`. `null` when neither is usable.\n */\nexport function signInTarget(state: { signinUrl: string | null; authorizeUrl: string | null }, location: Here): string | null {\n if (state.signinUrl !== null) {\n try {\n const url = new URL(state.signinUrl, location.origin);\n if (url.origin === location.origin) return url.href;\n } catch {\n // Fall through to the legacy link.\n }\n }\n const legacy = authorizeHref(state.authorizeUrl, location);\n\n return legacy === null ? null : new URL(legacy, location.origin).href;\n}\n\n/** Only `https:` icon URLs are rendered: the icons are hosted by Cbox ID. */\nexport function secureIconUrl(url: unknown): string | null {\n if (typeof url !== 'string' || url === '') return null;\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'https:' ? parsed.href : null;\n } catch {\n return null;\n }\n}\n\n/** The app's name without the `Cbox · ` prefix, as the tiles show it. */\nexport function displayName(name: string): string {\n return name.replace(/^Cbox\\s*·\\s*/i, '');\n}\n\n/** The two letters that stand in for an app without an icon. */\nexport function initials(name: string): string {\n return displayName(name).slice(0, 2);\n}\n\nconst EMPTY: CboxKnownApp[] = [];\nlet cache: { raw: string | null; apps: CboxKnownApp[] } = { raw: null, apps: EMPTY };\n\nfunction storage(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage;\n } catch {\n return null;\n }\n}\n\n/** The last catalog this browser kept (`localStorage` key `cbox-app-catalog`); empty without one. */\nexport function readKnownAppCatalog(): CboxKnownApp[] {\n let raw: string | null = null;\n try {\n raw = storage()?.getItem(KEPT_CATALOG_KEY) ?? null;\n } catch {\n raw = null;\n }\n if (raw === cache.raw) return cache.apps;\n let apps: CboxKnownApp[] = EMPTY;\n try {\n const value: unknown = raw === null ? [] : JSON.parse(raw);\n if (Array.isArray(value)) {\n apps = value.flatMap((entry: unknown) => {\n if (typeof entry !== 'object' || entry === null) return [];\n const app = entry as Record<string, unknown>;\n if (typeof app.key !== 'string' || typeof app.name !== 'string') return [];\n const known: CboxKnownApp = { key: app.key, name: app.name, icon_url: secureIconUrl(app.icon_url), icon_dark_url: secureIconUrl(app.icon_dark_url) };\n if (typeof app.launch_url === 'string' && /^https?:\\/\\//i.test(app.launch_url)) known.launch_url = app.launch_url;\n return [known];\n });\n }\n } catch {\n apps = EMPTY;\n }\n cache = { raw, apps };\n\n return apps;\n}\n\n/** Keep the catalog the person just loaded, and tell every mark on this page to repaint. */\nexport function rememberAppCatalog(apps: ReadonlyArray<{ key: string; name: string; launch_url?: string | null; icon_url?: string | null; icon_dark_url?: string | null }>): void {\n const kept = apps.map(({ key, name, launch_url, icon_url, icon_dark_url }) => {\n const app: CboxKnownApp = { key, name, icon_url: icon_url ?? null, icon_dark_url: icon_dark_url ?? null };\n if (typeof launch_url === 'string' && launch_url !== '') app.launch_url = launch_url;\n return app;\n });\n try {\n storage()?.setItem(KEPT_CATALOG_KEY, JSON.stringify(kept));\n } catch {\n // A private window or blocked storage: the marks wait for the next live answer.\n }\n if (typeof document !== 'undefined') document.dispatchEvent(new CustomEvent(CATALOG_EVENT));\n}\n\n/** Call `change` whenever the kept catalog changes, on this page or in another tab. */\nexport function subscribeKnownAppCatalog(change: () => void): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => undefined;\n const storageChange = (event: StorageEvent) => { if (event.key === KEPT_CATALOG_KEY) change(); };\n document.addEventListener(CATALOG_EVENT, change);\n window.addEventListener('storage', storageChange);\n return () => {\n document.removeEventListener(CATALOG_EVENT, change);\n window.removeEventListener('storage', storageChange);\n };\n}\n","/**\n * Which theme the host page shows, read the way every Cbox app marks it:\n *\n * - `.dark` or `[data-theme=\"dark\"]` on the root element: dark;\n * - `.light` or `[data-theme=\"light\"]` on the root element: light;\n * - neither: the system's `prefers-color-scheme`, unless the element says `theme=\"class\"`\n * (a host whose tokens only turn dark under `.dark`, so no marker means light).\n *\n * `theme=\"light\"` or `theme=\"dark\"` on the element pins it.\n */\nexport type CboxThemeMode = 'auto' | 'class' | 'light' | 'dark';\n\nexport function themeMode(value: string | null): CboxThemeMode {\n return value === 'class' || value === 'light' || value === 'dark' ? value : 'auto';\n}\n\nexport function isDark(mode: CboxThemeMode = 'auto'): boolean {\n if (mode === 'light' || mode === 'dark') return mode === 'dark';\n if (typeof document === 'undefined') return false;\n const root = document.documentElement;\n const marked = root.getAttribute('data-theme');\n if (root.classList.contains('dark') || marked === 'dark') return true;\n if (root.classList.contains('light') || marked === 'light') return false;\n if (mode === 'class') return false;\n\n return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n}\n\nconst listeners = new Set<() => void>();\nlet stop: (() => void) | null = null;\n\nfunction notify(): void {\n for (const listener of [...listeners]) listener();\n}\n\n/** Call `change` when the root's theme marker or the system scheme changes. One observer serves every element. */\nexport function subscribeTheme(change: () => void): () => void {\n listeners.add(change);\n if (stop === null && typeof document !== 'undefined') {\n const observer = typeof MutationObserver === 'function' ? new MutationObserver(notify) : null;\n observer?.observe(document.documentElement, { attributes: true, attributeFilter: ['class', 'data-theme'] });\n const media = typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia('(prefers-color-scheme: dark)') : null;\n media?.addEventListener?.('change', notify);\n stop = () => {\n observer?.disconnect();\n media?.removeEventListener?.('change', notify);\n };\n }\n\n return () => {\n listeners.delete(change);\n if (listeners.size === 0 && stop !== null) {\n stop();\n stop = null;\n }\n };\n}\n","/**\n * The elements' own styles. They live in each element's shadow root, so no host stylesheet\n * reaches them (no reset, no `button` rule, no `img` rule, no missing preflight), and they\n * never reach the host page. The only thing taken from the host is its Cbox colour tokens,\n * which inherit into the shadow root as custom properties; every token has a fallback, so an\n * app without them still draws the same control.\n */\nconst FONT = \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', ui-sans-serif, system-ui, Arial, sans-serif\";\n\nconst PALETTE = `\n.root {\n --fg: var(--foreground, #1f1d1a);\n --muted-fg: var(--muted-foreground, #6b665e);\n --surface: var(--popover, #ffffff);\n --line: var(--border, #e6e3dd);\n --hover: var(--secondary, #f2f0ec);\n --tile: var(--muted, #f2f0ec);\n --current: var(--accent-soft, #eef2ff);\n --accent: var(--accent-strong, var(--primary, #2f5bd3));\n --focus: var(--ring, #2f5bd3);\n --shadow: var(--shadow-popover, 0 10px 30px -8px rgb(0 0 0 / 0.18), 0 2px 6px rgb(0 0 0 / 0.06));\n}\n.root.dark {\n --fg: var(--foreground, #f3f2ef);\n --muted-fg: var(--muted-foreground, #a29d94);\n --surface: var(--popover, #24221f);\n --line: var(--border, #3a3733);\n --hover: var(--secondary, #312e2a);\n --tile: var(--muted, #312e2a);\n --current: var(--accent-soft, #26304a);\n --accent: var(--accent-strong, var(--primary, #8aa6ff));\n --focus: var(--ring, #8aa6ff);\n --shadow: var(--shadow-popover, 0 10px 30px -8px rgb(0 0 0 / 0.6), 0 2px 6px rgb(0 0 0 / 0.3));\n}`;\n\nconst ICON = `\n.icon { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; width: var(--size, 24px); height: var(--size, 24px); }\n.icon img { display: block; width: 100%; height: 100%; max-width: none; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; object-fit: contain; }\n.icon img.on-dark { display: none; }\n.root.dark .icon img.on-light { display: none; }\n.root.dark .icon img.on-dark { display: block; }\n.icon.initials { border-radius: 6px; background: var(--tile); color: var(--fg); font: 600 10px/1 ${FONT}; letter-spacing: 0; text-transform: none; }`;\n\nexport const SWITCHER_CSS = `\n:host { all: initial; display: inline-flex; flex: none; vertical-align: middle; }\n:host([hidden]) { display: none; }\n*, *::before, *::after { box-sizing: border-box; }\n${PALETTE}\n.root { display: inline-flex; color: var(--fg); font: 400 13px/1.4 ${FONT}; }\n.trigger {\n all: unset; box-sizing: border-box; display: inline-grid; place-items: center;\n width: 32px; height: 32px; border-radius: 8px; color: var(--fg); background: transparent; cursor: pointer;\n transition: background-color 150ms cubic-bezier(.4, 0, .2, 1);\n}\n.trigger svg { display: block; width: 18px; height: 18px; fill: currentColor; }\n.trigger:hover, .trigger[aria-expanded='true'] { background: var(--hover); }\n.trigger:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }\n.trigger:disabled { cursor: default; opacity: .6; background: transparent; }\n.panel {\n position: fixed; inset: auto; top: 0; left: 0; margin: 0; z-index: 2147483000;\n width: min(292px, calc(100vw - 16px)); max-height: calc(100vh - 16px); overflow-y: auto;\n padding: 12px; border: 1px solid var(--line); border-radius: 12px;\n background: var(--surface); color: var(--fg); box-shadow: var(--shadow);\n font: 400 13px/1.4 ${FONT}; text-align: left; outline: none;\n}\n.panel[hidden] { display: none; }\n.panel h2 { margin: 0 4px 8px; padding: 0; color: var(--fg); font: 600 14px/1.4 ${FONT}; letter-spacing: 0; text-transform: none; }\n.grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; margin: 0; padding: 0; }\n.tile {\n position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;\n min-width: 0; min-height: 60px; padding: 8px 4px; border-radius: 8px;\n color: var(--fg); background: transparent; font: 500 13px/1.25 ${FONT}; text-align: center; text-decoration: none; overflow-wrap: anywhere;\n}\n.tile:hover { background: var(--hover); }\n.tile[aria-current='true'] { background: var(--current); }\n.tile:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }\n.tile .label { max-width: 100%; }\n.check { position: absolute; top: 5px; right: 8px; width: 12px; height: 12px; color: var(--accent); }\n.check svg { display: block; width: 12px; height: 12px; }\n.message { margin: 0; padding: 8px 4px; color: var(--muted-fg); font: 400 13px/1.4 ${FONT}; }\n${ICON}\n@media (prefers-reduced-motion: reduce) { .trigger { transition: none; } }`;\n\nexport const MARK_CSS = `\n:host { all: initial; display: inline-flex; flex: none; align-items: center; justify-content: center; vertical-align: middle; }\n:host([hidden]) { display: none; }\n${PALETTE}\n.root { display: inline-flex; --size: var(--cbox-service-mark-size, 24px); }\n${ICON}`;\n\nconst sheets = new Map<string, CSSStyleSheet | null>();\n\n/**\n * Attach `css` to a shadow root. A constructed stylesheet is shared by every element and is not\n * subject to the page's `style-src` CSP; a `<style>` element is the fallback for engines without one.\n */\nexport function adopt(root: ShadowRoot, css: string): void {\n if (!sheets.has(css)) {\n let sheet: CSSStyleSheet | null = null;\n try {\n if ('adoptedStyleSheets' in Document.prototype && typeof CSSStyleSheet === 'function') {\n sheet = new CSSStyleSheet();\n sheet.replaceSync(css);\n }\n } catch {\n sheet = null;\n }\n sheets.set(css, sheet);\n }\n const sheet = sheets.get(css);\n if (sheet) {\n root.adoptedStyleSheets = [sheet];\n return;\n }\n const style = document.createElement('style');\n style.textContent = css;\n root.append(style);\n}\n","import {\n displayName,\n initials,\n parseAppCatalog,\n readKnownAppCatalog,\n rememberAppCatalog,\n secureIconUrl,\n signInTarget,\n subscribeKnownAppCatalog,\n type CboxCatalogApp,\n type CboxKnownApp,\n} from './catalog';\nimport { isDark, subscribeTheme, themeMode } from './theme';\nimport { adopt, MARK_CSS, SWITCHER_CSS } from './styles';\n\n/** The words the control shows. Pass a translation as the `labels` attribute (JSON). */\nexport type CboxAppSwitcherLabels = { title: string; loading: string; empty: string; unavailable: string };\n\nexport const DEFAULT_LABELS: CboxAppSwitcherLabels = {\n title: 'Switch app',\n loading: 'Loading apps…',\n empty: 'No apps available',\n unavailable: 'Apps could not be loaded.',\n};\n\n/**\n * Fired on `<cbox-app-switcher>` (bubbling, composed, cancelable) just before it sends the\n * person to sign in again; `detail.url` is where. `preventDefault()` keeps the page where it is.\n */\nexport const SIGNIN_EVENT = 'cbox-app-switcher:signin';\n\nconst SIGNIN_GUARD = 'cbox-app-switcher-signin';\n/** Sent to the same sign-in URL this recently and still refused: stop, so it never loops. */\nconst LOOP_WINDOW_MS = 30_000;\nconst REFRESH_INTERVAL_MS = 60_000;\nconst SVG = 'http://www.w3.org/2000/svg';\n\ntype View =\n | { kind: 'loading' }\n | { kind: 'empty' }\n | { kind: 'unavailable' }\n | { kind: 'apps'; apps: ReadonlyArray<CboxKnownApp | CboxCatalogApp>; live: boolean; failed: boolean };\n\nfunction svg(viewBox: string, build: (node: SVGSVGElement) => void, attributes: Record<string, string> = {}): SVGSVGElement {\n const node = document.createElementNS(SVG, 'svg');\n node.setAttribute('viewBox', viewBox);\n node.setAttribute('aria-hidden', 'true');\n node.setAttribute('focusable', 'false');\n for (const [name, value] of Object.entries(attributes)) node.setAttribute(name, value);\n build(node);\n return node;\n}\n\nfunction gridIcon(): SVGSVGElement {\n return svg('0 0 18 18', node => {\n for (const y of [3, 9, 15]) {\n for (const x of [3, 9, 15]) {\n const dot = document.createElementNS(SVG, 'circle');\n dot.setAttribute('cx', String(x));\n dot.setAttribute('cy', String(y));\n dot.setAttribute('r', '1.65');\n node.append(dot);\n }\n }\n });\n}\n\nfunction checkIcon(): SVGSVGElement {\n return svg('0 0 24 24', node => {\n const path = document.createElementNS(SVG, 'path');\n path.setAttribute('d', 'm5 12 4 4L19 6');\n node.append(path);\n }, { fill: 'none', stroke: 'currentColor', 'stroke-width': '1.8' });\n}\n\n/**\n * One app's icon: both catalog uploads (the shadow stylesheet shows the one for the theme), or\n * its initials when it has no `https:` icon or the icon fails to load. A service mark shows\n * nothing instead of initials.\n */\nfunction appIcon(app: { name: string; icon_url?: string | null; icon_dark_url?: string | null }, missing: 'initials' | 'nothing'): HTMLSpanElement {\n const box = document.createElement('span');\n box.className = 'icon';\n box.setAttribute('aria-hidden', 'true');\n const fallback = () => {\n box.replaceChildren();\n if (missing === 'initials') {\n box.classList.add('initials');\n box.textContent = initials(app.name);\n }\n };\n const light = secureIconUrl(app.icon_url);\n const dark = secureIconUrl(app.icon_dark_url);\n if (light === null) {\n fallback();\n return box;\n }\n for (const [url, variant] of [[light, dark === null ? 'single' : 'on-light'], [dark, 'on-dark']] as const) {\n if (url === null) continue;\n const image = document.createElement('img');\n image.alt = '';\n image.decoding = 'async';\n image.className = variant;\n image.addEventListener('error', fallback, { once: true });\n image.src = url;\n box.append(image);\n }\n return box;\n}\n\nfunction readLabels(value: string | null): CboxAppSwitcherLabels {\n try {\n const parsed: unknown = JSON.parse(value ?? '{}');\n if (typeof parsed !== 'object' || parsed === null) return DEFAULT_LABELS;\n const labels = { ...DEFAULT_LABELS };\n for (const key of Object.keys(DEFAULT_LABELS) as Array<keyof CboxAppSwitcherLabels>) {\n const text = (parsed as Record<string, unknown>)[key];\n if (typeof text === 'string' && text !== '') labels[key] = text;\n }\n return labels;\n } catch {\n return DEFAULT_LABELS;\n }\n}\n\nfunction recentlySentTo(url: string): boolean {\n try {\n const kept: unknown = JSON.parse(window.sessionStorage.getItem(SIGNIN_GUARD) ?? 'null');\n if (typeof kept !== 'object' || kept === null) return false;\n const { url: sent, at } = kept as { url?: unknown; at?: unknown };\n return sent === url && typeof at === 'number' && Date.now() - at < LOOP_WINDOW_MS;\n } catch {\n return false;\n }\n}\n\nfunction markSentTo(url: string | null): void {\n try {\n if (url === null) window.sessionStorage.removeItem(SIGNIN_GUARD);\n else window.sessionStorage.setItem(SIGNIN_GUARD, JSON.stringify({ url, at: Date.now() }));\n } catch {\n // Blocked storage: the guard is best effort.\n }\n}\n\n/** Navigate the top window (the element may sit in a same-app iframe), else this one. */\nfunction navigateTop(url: string): void {\n try {\n if (window.top !== null && window.top !== window) {\n window.top.location.href = url;\n return;\n }\n } catch {\n // A cross-origin parent that refuses: navigate this frame instead.\n }\n window.location.href = url;\n}\n\nlet uid = 0;\n\n// Private state uses names no attribute shares (`endpoint`, `current`, `labels`, `theme`,\n// `service`): React 19 sets a custom element's property instead of its attribute when the\n// element has one by that name, and these elements read attributes only.\nfunction defineSwitcher(): CustomElementConstructor {\n return class CboxAppSwitcherElement extends HTMLElement {\n static observedAttributes = ['endpoint', 'current', 'labels', 'theme'];\n\n private readonly frame: HTMLDivElement;\n private readonly button: HTMLButtonElement;\n private readonly panel: HTMLDivElement;\n private readonly heading: HTMLHeadingElement;\n private readonly body: HTMLDivElement;\n private readonly native: boolean;\n private copy: CboxAppSwitcherLabels = DEFAULT_LABELS;\n private view: View = { kind: 'loading' };\n private flight: AbortController | null = null;\n private expires = 0;\n private failures = 0;\n private retry: ReturnType<typeof setTimeout> | undefined;\n private ticker: ReturnType<typeof setInterval> | undefined;\n private signin: string | null = null;\n private mounted = false;\n private restoreFocus = false;\n private stopTheme: (() => void) | null = null;\n\n private readonly syncTheme = () => { this.frame.classList.toggle('dark', isDark(themeMode(this.getAttribute('theme')))); };\n private readonly refresh = () => { if (document.visibilityState !== 'hidden' && Date.now() >= this.expires) void this.load(); };\n private readonly place = () => { if (this.isOpen()) this.position(); };\n private readonly outside = (event: Event) => { if (!event.composedPath().includes(this)) this.close(); };\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: 'open' });\n adopt(shadow, SWITCHER_CSS);\n const id = `cbox-app-switcher-${++uid}`;\n\n this.frame = document.createElement('div');\n this.frame.className = 'root';\n\n this.button = document.createElement('button');\n this.button.type = 'button';\n this.button.className = 'trigger';\n this.button.setAttribute('aria-haspopup', 'dialog');\n this.button.setAttribute('aria-expanded', 'false');\n this.button.setAttribute('aria-controls', `${id}-panel`);\n this.button.append(gridIcon());\n\n this.panel = document.createElement('div');\n this.panel.id = `${id}-panel`;\n this.panel.className = 'panel';\n this.panel.tabIndex = -1;\n this.panel.setAttribute('role', 'dialog');\n this.panel.setAttribute('aria-labelledby', `${id}-title`);\n this.native = typeof this.panel.togglePopover === 'function';\n if (this.native) {\n this.panel.popover = 'auto';\n // The button is the popover's invoker, so light dismiss never reopens it on the same click.\n const invoker: HTMLButtonElement = this.button;\n if ('popoverTargetElement' in invoker) invoker.popoverTargetElement = this.panel;\n else (invoker as HTMLElement).setAttribute('popovertarget', this.panel.id);\n this.panel.addEventListener('toggle', event => { this.toggled((event as ToggleEvent).newState === 'open'); });\n } else {\n this.panel.hidden = true;\n this.button.addEventListener('click', () => { if (this.isOpen()) this.close(); else this.open(); });\n }\n\n this.heading = document.createElement('h2');\n this.heading.id = `${id}-title`;\n this.body = document.createElement('div');\n this.body.setAttribute('aria-live', 'polite');\n this.panel.append(this.heading, this.body);\n this.panel.addEventListener('keydown', event => { this.key(event); });\n\n this.frame.append(this.button, this.panel);\n shadow.append(this.frame);\n }\n\n connectedCallback(): void {\n if (this.mounted) return;\n this.mounted = true;\n this.applyLabels();\n this.applyEndpoint();\n this.syncTheme();\n this.stopTheme = subscribeTheme(this.syncTheme);\n this.paintKept();\n this.ticker = setInterval(this.refresh, REFRESH_INTERVAL_MS);\n window.addEventListener('focus', this.refresh);\n document.addEventListener('visibilitychange', this.refresh);\n window.addEventListener('resize', this.place);\n window.addEventListener('scroll', this.place, true);\n this.refresh();\n }\n\n disconnectedCallback(): void {\n this.mounted = false;\n this.flight?.abort();\n this.flight = null;\n clearInterval(this.ticker);\n clearTimeout(this.retry);\n this.retry = undefined;\n this.stopTheme?.();\n this.stopTheme = null;\n window.removeEventListener('focus', this.refresh);\n document.removeEventListener('visibilitychange', this.refresh);\n window.removeEventListener('resize', this.place);\n window.removeEventListener('scroll', this.place, true);\n document.removeEventListener('pointerdown', this.outside, true);\n }\n\n attributeChangedCallback(name: string, before: string | null, after: string | null): void {\n if (!this.mounted || before === after) return;\n if (name === 'labels') { this.applyLabels(); this.render(); }\n if (name === 'current') this.render();\n if (name === 'theme') this.syncTheme();\n if (name === 'endpoint') {\n this.flight?.abort();\n this.flight = null;\n clearTimeout(this.retry);\n this.retry = undefined;\n this.expires = 0;\n this.failures = 0;\n this.signin = null;\n this.view = { kind: 'loading' };\n this.applyEndpoint();\n this.paintKept();\n this.refresh();\n }\n }\n\n private applyLabels(): void {\n this.copy = readLabels(this.getAttribute('labels'));\n this.button.title = this.copy.title;\n this.button.setAttribute('aria-label', this.copy.title);\n this.heading.textContent = this.copy.title;\n }\n\n private applyEndpoint(): void {\n this.button.disabled = !this.getAttribute('endpoint');\n if (this.button.disabled) this.close();\n }\n\n /** The last catalog this browser kept paints the grid at once; the live answer replaces it. */\n private paintKept(): void {\n if (this.view.kind === 'apps' && this.view.live) return;\n const kept = readKnownAppCatalog().filter(app => typeof app.launch_url === 'string');\n this.view = kept.length > 0 ? { kind: 'apps', apps: kept, live: false, failed: false } : { kind: 'loading' };\n this.render();\n }\n\n private isOpen(): boolean {\n if (!this.native) return !this.panel.hidden;\n try {\n return this.panel.matches(':popover-open');\n } catch {\n return false;\n }\n }\n\n private open(): void {\n if (this.button.disabled || this.isOpen()) return;\n if (this.native) { this.panel.showPopover(); return; }\n this.panel.hidden = false;\n document.addEventListener('pointerdown', this.outside, true);\n this.toggled(true);\n }\n\n private close(): void {\n if (!this.isOpen()) return;\n if (this.native) { this.panel.hidePopover(); return; }\n this.panel.hidden = true;\n document.removeEventListener('pointerdown', this.outside, true);\n this.toggled(false);\n }\n\n private toggled(open: boolean): void {\n this.button.setAttribute('aria-expanded', String(open));\n if (!open) {\n if (this.restoreFocus && this.isConnected) this.button.focus();\n this.restoreFocus = false;\n return;\n }\n this.position();\n if (this.signin !== null) { this.goSignIn(this.signin); return; }\n this.focusFirst();\n this.refresh();\n }\n\n private position(): void {\n const box = this.button.getBoundingClientRect();\n const width = Math.min(292, window.innerWidth - 16);\n this.panel.style.width = `${width}px`;\n this.panel.style.left = `${Math.max(8, Math.min(box.right - width, window.innerWidth - width - 8))}px`;\n this.panel.style.top = `${box.bottom + 6}px`;\n this.panel.style.maxHeight = `${Math.max(60, window.innerHeight - box.bottom - 14)}px`;\n }\n\n private tiles(): HTMLAnchorElement[] {\n return [...this.body.querySelectorAll<HTMLAnchorElement>('a[href]')];\n }\n\n private focusFirst(): void {\n (this.tiles()[0] ?? this.panel).focus();\n }\n\n private key(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n this.restoreFocus = true;\n if (!this.native) { event.preventDefault(); this.close(); }\n return;\n }\n const tiles = this.tiles();\n const active = this.shadowRoot?.activeElement ?? null;\n if (event.key === 'Tab') {\n const first = tiles[0];\n const last = tiles.at(-1);\n if (first === undefined || last === undefined) { event.preventDefault(); return; }\n if (event.shiftKey && (active === first || active === this.panel)) { event.preventDefault(); last.focus(); }\n else if (!event.shiftKey && (active === last || active === this.panel)) { event.preventDefault(); first.focus(); }\n return;\n }\n const at = tiles.indexOf(active as HTMLAnchorElement);\n const step: Record<string, number> = { ArrowRight: 1, ArrowLeft: -1, ArrowDown: 3, ArrowUp: -3 };\n let next: number | null = null;\n if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = tiles.length - 1;\n else if (event.key in step) next = at === -1 ? 0 : Math.max(0, Math.min(tiles.length - 1, at + (step[event.key] ?? 0)));\n if (next === null || tiles.length === 0) return;\n event.preventDefault();\n tiles[next]?.focus();\n }\n\n private render(): void {\n const view = this.view;\n if (view.kind !== 'apps') {\n const text = view.kind === 'empty' ? this.copy.empty : view.kind === 'unavailable' ? this.copy.unavailable : this.copy.loading;\n const message = document.createElement('p');\n message.className = 'message';\n message.textContent = text;\n if (view.kind === 'unavailable') message.setAttribute('role', 'status');\n this.body.replaceChildren(message);\n return;\n }\n const hadFocus = this.shadowRoot?.activeElement instanceof HTMLAnchorElement;\n const nav = document.createElement('nav');\n nav.className = 'grid';\n nav.setAttribute('aria-label', this.copy.title);\n const current = this.getAttribute('current');\n for (const app of view.apps) {\n if (typeof app.launch_url !== 'string') continue;\n const tile = document.createElement('a');\n tile.className = 'tile';\n tile.href = app.launch_url;\n const description = 'description' in app && typeof app.description === 'string' ? app.description : null;\n tile.title = description ?? displayName(app.name);\n const label = document.createElement('span');\n label.className = 'label';\n label.textContent = displayName(app.name);\n tile.append(appIcon(app, 'initials'), label);\n if (app.key === current) {\n tile.setAttribute('aria-current', 'true');\n const check = document.createElement('span');\n check.className = 'check';\n check.append(checkIcon());\n tile.append(check);\n }\n tile.addEventListener('click', () => { this.close(); });\n nav.append(tile);\n }\n const parts: Node[] = [];\n if (view.failed) {\n const message = document.createElement('p');\n message.className = 'message';\n message.setAttribute('role', 'status');\n message.textContent = this.copy.unavailable;\n parts.push(message);\n }\n parts.push(nav);\n this.body.replaceChildren(...parts);\n if (hadFocus || (this.isOpen() && this.shadowRoot?.activeElement === this.panel)) this.focusFirst();\n }\n\n private async load(): Promise<void> {\n const endpoint = this.getAttribute('endpoint');\n if (!endpoint || this.flight !== null) return;\n let source: URL;\n try {\n source = new URL(endpoint, window.location.href);\n } catch {\n this.fail(false);\n return;\n }\n // The endpoint is the host's own proxy, under the person's session.\n if (source.origin !== window.location.origin) { this.fail(false); return; }\n const request = new AbortController();\n this.flight = request;\n try {\n const response = await fetch(source.href, {\n credentials: 'same-origin',\n cache: 'no-store',\n redirect: 'error',\n headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },\n signal: request.signal,\n });\n const body: unknown = await response.json().catch(() => null);\n if (request.signal.aborted || !this.isConnected) return;\n const state = parseAppCatalog(response.ok, body);\n if (state.status === 'ready') {\n this.failures = 0;\n clearTimeout(this.retry);\n this.retry = undefined;\n this.signin = null;\n markSentTo(null);\n this.expires = Date.now() + state.refreshAfter * 1000;\n this.view = state.apps.length > 0 ? { kind: 'apps', apps: state.apps, live: true, failed: false } : { kind: 'empty' };\n rememberAppCatalog(state.apps);\n this.render();\n return;\n }\n const target = state.status === 'signin_required' ? signInTarget(state, window.location) : null;\n if (target === null) { this.fail(true); return; }\n this.signin = target;\n this.expires = 0;\n if (this.isOpen()) this.goSignIn(target);\n } catch {\n if (!request.signal.aborted) this.fail(true);\n } finally {\n if (this.flight === request) this.flight = null;\n }\n }\n\n /** Quietly say the apps could not be loaded, keep any grid, and try again by itself. */\n private fail(again: boolean): void {\n this.expires = 0;\n this.view = this.view.kind === 'apps' ? { ...this.view, failed: true } : { kind: 'unavailable' };\n this.render();\n if (!again) return;\n this.failures += 1;\n clearTimeout(this.retry);\n const delay = Math.min(REFRESH_INTERVAL_MS, 2000 * 2 ** (this.failures - 1));\n this.retry = setTimeout(() => { this.retry = undefined; this.refresh(); }, delay);\n }\n\n /** The person has to sign in again: go there, no question asked (but never in a loop). */\n private goSignIn(url: string): void {\n if (recentlySentTo(url)) {\n this.signin = null;\n this.fail(true);\n return;\n }\n const event = new CustomEvent(SIGNIN_EVENT, { detail: { url }, bubbles: true, composed: true, cancelable: true });\n if (!this.dispatchEvent(event)) return;\n markSentTo(url);\n navigateTop(url);\n }\n };\n}\n\nfunction defineServiceMark(): CustomElementConstructor {\n return class CboxServiceMarkElement extends HTMLElement {\n static observedAttributes = ['service', 'theme'];\n\n private readonly frame: HTMLSpanElement;\n private stops: Array<() => void> = [];\n private readonly paint = () => {\n const app = readKnownAppCatalog().find(entry => entry.key === this.getAttribute('service'));\n this.frame.replaceChildren(...(app !== undefined && secureIconUrl(app.icon_url) !== null ? [appIcon(app, 'nothing')] : []));\n };\n private readonly syncTheme = () => { this.frame.classList.toggle('dark', isDark(themeMode(this.getAttribute('theme')))); };\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: 'open' });\n adopt(shadow, MARK_CSS);\n this.frame = document.createElement('span');\n this.frame.className = 'root';\n shadow.append(this.frame);\n }\n\n connectedCallback(): void {\n this.stops.forEach(stop => stop());\n this.stops = [subscribeKnownAppCatalog(this.paint), subscribeTheme(this.syncTheme)];\n this.syncTheme();\n this.paint();\n }\n\n disconnectedCallback(): void {\n this.stops.forEach(stop => stop());\n this.stops = [];\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.isConnected) return;\n if (name === 'theme') this.syncTheme();\n else this.paint();\n }\n };\n}\n\n/** Define `<cbox-app-switcher>` and `<cbox-service-mark>` once. A no-op outside a browser. */\nexport function defineCboxAppSwitcher(): void {\n if (typeof window === 'undefined' || typeof customElements === 'undefined') return;\n if (customElements.get('cbox-service-mark') === undefined) customElements.define('cbox-service-mark', defineServiceMark());\n if (customElements.get('cbox-app-switcher') === undefined) customElements.define('cbox-app-switcher', defineSwitcher());\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
2
3
  import { ReactNode, ComponentProps, ComponentType } from 'react';
4
+ import { C as CboxThemeMode, a as CboxKnownApp } from './catalog-BroZWvws.js';
5
+ export { b as CboxAppCatalogState, c as CboxCatalogApp, d as authorizeHref, p as parseAppCatalog, r as readKnownAppCatalog, e as rememberAppCatalog, s as secureIconUrl, f as signInTarget } from './catalog-BroZWvws.js';
3
6
  import { LucideIcon } from 'lucide-react';
4
7
  import { ClassValue } from 'clsx';
5
8
  export { T as TimePoint, n as niceTicks, t as timeTicks } from './scale-BaaY5qJs.js';
@@ -503,29 +506,6 @@ type AppLauncherProps = {
503
506
  */
504
507
  declare function AppLauncher({ className, onLockedAppClick }: AppLauncherProps): react_jsx_runtime.JSX.Element | null;
505
508
 
506
- /** One app as the host's catalog endpoint lists it. */
507
- type CboxCatalogApp = {
508
- key: string;
509
- name: string;
510
- launch_url: string;
511
- /** Cbox ID's uploaded icon for light surfaces. */
512
- icon_url?: string | null;
513
- /** Cbox ID's uploaded icon for dark surfaces. */
514
- icon_dark_url?: string | null;
515
- description?: string | null;
516
- };
517
- type CboxAppCatalogState = {
518
- status: 'idle' | 'loading';
519
- } | {
520
- status: 'ready';
521
- apps: CboxCatalogApp[];
522
- refreshAfter: number;
523
- } | {
524
- status: 'authorization_required';
525
- authorizeUrl: string | null;
526
- } | {
527
- status: 'unavailable';
528
- };
529
509
  type CboxAppCatalogProps = {
530
510
  /**
531
511
  * Same-origin URL the host serves the person's app catalog from (a proxy of Cbox ID's
@@ -533,59 +513,31 @@ type CboxAppCatalogProps = {
533
513
  * chrome keeps its shape on pages without an organization.
534
514
  */
535
515
  endpoint: string | null;
536
- /** The app key of this app; its tile is marked current and does not navigate. */
516
+ /** The app key of this app; its tile is marked current. */
537
517
  currentAppKey: string;
518
+ /**
519
+ * How the theme is read. Default `auto`: `.dark`/`[data-theme]` on the root, else the
520
+ * system scheme. `class` for a host whose tokens only turn dark under `.dark`.
521
+ */
522
+ theme?: CboxThemeMode;
538
523
  className?: string;
539
524
  };
540
525
  /**
541
- * Interpret the catalog endpoint's answer. The contract every Cbox app serves:
542
- *
543
- * - `200 { apps: [{ key, name, launch_url, icon_url?, icon_dark_url?, description? }], refresh_after?: seconds }`
544
- * - `401`/`403 { authorize_url?: string }` or `{ state: 'authorization_required' }`: the
545
- * person has to (re)connect their catalog grant; `authorize_url` is where.
546
- * - anything else: unavailable right now.
547
- *
548
- * Only `http(s)` launch URLs are kept: the tiles are links the person will click.
549
- */
550
- declare function parseAppCatalog(ok: boolean, body: unknown): CboxAppCatalogState;
551
- /** The authorize link with `return_to` set to where the person is, when it is on this origin. */
552
- declare function authorizeHref(authorizeUrl: string | null, location: {
553
- origin: string;
554
- pathname: string;
555
- search: string;
556
- }): string | null;
557
- /**
558
- * The Switch-app control: a grid of the Cbox apps this person can open, read live from the
559
- * host's catalog endpoint. The host owns the endpoint and the grant; this renders the answer,
560
- * refreshes it when it expires while the panel is open, and offers the way back to Cbox ID
561
- * when the grant is missing. Each tile shows the app's icon from the catalog (light and dark),
562
- * and the answer is kept so `CboxServiceMark` paints the app's own mark from it.
526
+ * The Switch-app control. It renders `<cbox-app-switcher>` from `@cboxdk/cbox-ui/app-switcher`,
527
+ * the same element every Blade app uses, so React and Blade apps draw one identical control:
528
+ * the live catalog from the host's endpoint, Cbox ID's light and dark icons, a quiet retry when
529
+ * the catalog cannot be loaded, and straight to sign-in when the host answers `401 { signin_url }`.
563
530
  */
564
- declare function CboxAppCatalog({ endpoint, currentAppKey, className }: CboxAppCatalogProps): react_jsx_runtime.JSX.Element;
531
+ declare function CboxAppCatalog({ endpoint, currentAppKey, theme, className }: CboxAppCatalogProps): react.ReactElement<{
532
+ endpoint: string;
533
+ current: string;
534
+ labels: string;
535
+ theme: CboxThemeMode | undefined;
536
+ className: string | undefined;
537
+ }, string | react.JSXElementConstructor<any>>;
565
538
 
566
- /**
567
- * Every Cbox app's icon comes from Cbox ID's catalog: one light and one dark upload per app
568
- * (`icon_url`, `icon_dark_url`). There is no local copy of the marks in this package or in an
569
- * app. The last catalog the browser saw is kept here so an app's own mark and the switcher
570
- * paint at once on the next page; the live answer replaces it when it arrives.
571
- */
572
- type CboxKnownApp = {
573
- key: string;
574
- name: string;
575
- icon_url: string | null;
576
- icon_dark_url: string | null;
577
- };
578
- /** Keep the catalog the person just loaded, so every mark on this origin repaints from it. */
579
- declare function rememberAppCatalog(apps: ReadonlyArray<{
580
- key: string;
581
- name: string;
582
- icon_url?: string | null;
583
- icon_dark_url?: string | null;
584
- }>): void;
585
539
  /** The last catalog this browser kept; empty on the server and before the first answer. */
586
540
  declare function useKnownAppCatalog(): CboxKnownApp[];
587
- /** Only `https:` icon URLs are rendered: the icons are hosted by Cbox ID. */
588
- declare function secureIconUrl(url: unknown): string | null;
589
541
  type CboxAppIconProps = {
590
542
  /** The app's name; its first two letters stand in when it has no icon. */
591
543
  name: string;
@@ -1580,4 +1532,4 @@ declare function Sparkline({ values, color, width, height }: {
1580
1532
  height?: number;
1581
1533
  }): react_jsx_runtime.JSX.Element | null;
1582
1534
 
1583
- export { AppContent, AppLauncher, AppShell, AppSwitcher, CHART_PALETTE, CboxAppCatalog, type CboxAppCatalogProps, type CboxAppCatalogState, CboxAppIcon, type CboxAppIconProps, type CboxAppKey, type CboxAppLink, CboxAppShell, type CboxAppShellProps, CboxAppSidebar, type CboxAppSidebarProps, CboxBrand, type CboxBrandProps, type CboxCatalogApp, type CboxIdContextValue, CboxIdProvider, type CboxKnownApp, CboxLocalizationProvider, CboxMobileNavDrawer, type CboxMobileNavDrawerProps, type CboxNavArea, type CboxNavItem, type CboxNavSection, type CboxNotificationPreviewItem, type CboxNotificationsState, CboxOrgContextBar, type CboxOrgContextBarProps, type CboxOrganization, CboxServiceMark, type CboxServiceMarkProps, CboxSurfaces, type CboxSurfacesProps, type CboxTranslationValues, type CboxTranslator, type CboxUser, CboxWorkspaceShell, type CboxWorkspaceShellProps, Combobox, type ComboboxAvatar, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type ContextAvatar, ContextAvatarChip, ContextBar, type ContextCrumb, type ContextItem, DataPanel, EmptyState, Heading, type InboxState, type InferUrlState, KeyValue, KeyValueList, type LinkComponent, NotificationsBell, OrgSwitcher, PageHeader, PageShell, type PageTabSpec, PageTabs, type PageTabsProps, type PageWidth, PanelBody, type RealtimeState, type RealtimeStatus, RowLink, type RowLinkProps, SearchTrigger, SectionHeader, Sparkline, StatTile, StatusPill, type SurfaceArgs, type SurfaceConfig, type SurfaceController, type SurfaceId, TopBar, type Transport, type UrlField, type UrlSchema, UserMenu, activeNavArea, activeNavItem, authorizeHref, buildUrlSearch, cn, defineUrlSchema, interpolate, navMatchLength, parseAppCatalog, parseUrlSearch, rememberAppCatalog, secureIconUrl, urlBoolean, urlEnum, urlNumber, urlString, urlStringArray, useCboxId, useCboxIdOptional, useCboxLocalization, useCboxSurfaces, useCboxSurfacesOptional, useKnownAppCatalog };
1535
+ export { AppContent, AppLauncher, AppShell, AppSwitcher, CHART_PALETTE, CboxAppCatalog, type CboxAppCatalogProps, CboxAppIcon, type CboxAppIconProps, type CboxAppKey, type CboxAppLink, CboxAppShell, type CboxAppShellProps, CboxAppSidebar, type CboxAppSidebarProps, CboxBrand, type CboxBrandProps, type CboxIdContextValue, CboxIdProvider, CboxKnownApp, CboxLocalizationProvider, CboxMobileNavDrawer, type CboxMobileNavDrawerProps, type CboxNavArea, type CboxNavItem, type CboxNavSection, type CboxNotificationPreviewItem, type CboxNotificationsState, CboxOrgContextBar, type CboxOrgContextBarProps, type CboxOrganization, CboxServiceMark, type CboxServiceMarkProps, CboxSurfaces, type CboxSurfacesProps, type CboxTranslationValues, type CboxTranslator, type CboxUser, CboxWorkspaceShell, type CboxWorkspaceShellProps, Combobox, type ComboboxAvatar, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type ContextAvatar, ContextAvatarChip, ContextBar, type ContextCrumb, type ContextItem, DataPanel, EmptyState, Heading, type InboxState, type InferUrlState, KeyValue, KeyValueList, type LinkComponent, NotificationsBell, OrgSwitcher, PageHeader, PageShell, type PageTabSpec, PageTabs, type PageTabsProps, type PageWidth, PanelBody, type RealtimeState, type RealtimeStatus, RowLink, type RowLinkProps, SearchTrigger, SectionHeader, Sparkline, StatTile, StatusPill, type SurfaceArgs, type SurfaceConfig, type SurfaceController, type SurfaceId, TopBar, type Transport, type UrlField, type UrlSchema, UserMenu, activeNavArea, activeNavItem, buildUrlSearch, cn, defineUrlSchema, interpolate, navMatchLength, parseUrlSearch, urlBoolean, urlEnum, urlNumber, urlString, urlStringArray, useCboxId, useCboxIdOptional, useCboxLocalization, useCboxSurfaces, useCboxSurfacesOptional, useKnownAppCatalog };
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { cn } from './chunk-OFTNLF7H.js';
2
2
  export { cn, niceTicks, timeTicks } from './chunk-OFTNLF7H.js';
3
- import { createContext, useContext, useMemo, useSyncExternalStore, useState, useEffect, useRef, useCallback, useId } from 'react';
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';
4
6
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
5
7
  import { X, Menu, PanelLeftOpen, PanelLeftClose, PinOff, Pin } from 'lucide-react';
6
8
 
@@ -60,76 +62,9 @@ function useCboxLocalization() {
60
62
  function defaultDate(value) {
61
63
  return new Date(value).toLocaleString();
62
64
  }
63
- var KEPT = "cbox-app-catalog";
64
- var EVENT = "cbox-app-catalog";
65
65
  var EMPTY = [];
66
- var cache = { raw: null, apps: EMPTY };
67
- function storage() {
68
- try {
69
- return typeof window === "undefined" ? null : window.localStorage;
70
- } catch {
71
- return null;
72
- }
73
- }
74
- function readKnownAppCatalog() {
75
- let raw = null;
76
- try {
77
- raw = storage()?.getItem(KEPT) ?? null;
78
- } catch {
79
- raw = null;
80
- }
81
- if (raw === cache.raw) return cache.apps;
82
- let apps = EMPTY;
83
- try {
84
- const value = raw === null ? [] : JSON.parse(raw);
85
- if (Array.isArray(value)) {
86
- apps = value.flatMap((entry) => {
87
- if (typeof entry !== "object" || entry === null) return [];
88
- const app = entry;
89
- if (typeof app.key !== "string" || typeof app.name !== "string") return [];
90
- return [{ key: app.key, name: app.name, icon_url: secureIconUrl(app.icon_url), icon_dark_url: secureIconUrl(app.icon_dark_url) }];
91
- });
92
- }
93
- } catch {
94
- apps = EMPTY;
95
- }
96
- cache = { raw, apps };
97
- return apps;
98
- }
99
- function subscribe(change) {
100
- if (typeof window === "undefined") return () => void 0;
101
- const storageChange = (event) => {
102
- if (event.key === KEPT) change();
103
- };
104
- document.addEventListener(EVENT, change);
105
- window.addEventListener("storage", storageChange);
106
- return () => {
107
- document.removeEventListener(EVENT, change);
108
- window.removeEventListener("storage", storageChange);
109
- };
110
- }
111
- function rememberAppCatalog(apps) {
112
- const kept = apps.map(({ key, name, icon_url, icon_dark_url }) => ({ key, name, icon_url: icon_url ?? null, icon_dark_url: icon_dark_url ?? null }));
113
- try {
114
- storage()?.setItem(KEPT, JSON.stringify(kept));
115
- } catch {
116
- }
117
- if (typeof document !== "undefined") document.dispatchEvent(new CustomEvent(EVENT));
118
- }
119
66
  function useKnownAppCatalog() {
120
- return useSyncExternalStore(subscribe, readKnownAppCatalog, () => EMPTY);
121
- }
122
- function secureIconUrl(url) {
123
- if (typeof url !== "string" || url === "") return null;
124
- try {
125
- const parsed = new URL(url);
126
- return parsed.protocol === "https:" ? parsed.href : null;
127
- } catch {
128
- return null;
129
- }
130
- }
131
- function initials(name) {
132
- return name.replace(/^Cbox\s*·\s*/i, "").slice(0, 2);
67
+ return useSyncExternalStore(subscribeKnownAppCatalog, readKnownAppCatalog, () => EMPTY);
133
68
  }
134
69
  function CboxAppIcon({ name, iconUrl, iconDarkUrl, className = "h-6 w-6", fallback }) {
135
70
  const light = secureIconUrl(iconUrl);
@@ -2657,174 +2592,22 @@ function Lock2() {
2657
2592
  }
2658
2593
  );
2659
2594
  }
2660
- var DEFAULT_REFRESH_SECONDS = 60;
2661
- function parseAppCatalog(ok, body) {
2662
- const data = typeof body === "object" && body !== null ? body : {};
2663
- if (!ok) {
2664
- const authorize = typeof data.authorize_url === "string" ? data.authorize_url : null;
2665
- if (authorize !== null || data.state === "authorization_required") {
2666
- return { status: "authorization_required", authorizeUrl: authorize };
2667
- }
2668
- return { status: "unavailable" };
2669
- }
2670
- if (!Array.isArray(data.apps)) {
2671
- return { status: "unavailable" };
2672
- }
2673
- const apps = [];
2674
- for (const entry of data.apps) {
2675
- if (typeof entry !== "object" || entry === null) continue;
2676
- const app = entry;
2677
- if (typeof app.key !== "string" || typeof app.name !== "string" || typeof app.launch_url !== "string") continue;
2678
- if (!/^https?:\/\//.test(app.launch_url)) continue;
2679
- apps.push({
2680
- key: app.key,
2681
- name: app.name,
2682
- launch_url: app.launch_url,
2683
- icon_url: typeof app.icon_url === "string" ? app.icon_url : null,
2684
- icon_dark_url: typeof app.icon_dark_url === "string" ? app.icon_dark_url : null,
2685
- description: typeof app.description === "string" ? app.description : null
2686
- });
2687
- }
2688
- const refresh = typeof data.refresh_after === "number" && Number.isFinite(data.refresh_after) ? data.refresh_after : DEFAULT_REFRESH_SECONDS;
2689
- return { status: "ready", apps, refreshAfter: Math.max(1, Math.min(DEFAULT_REFRESH_SECONDS, refresh)) };
2690
- }
2691
- function authorizeHref(authorizeUrl, location) {
2692
- if (authorizeUrl === null) return null;
2693
- try {
2694
- const url = new URL(authorizeUrl, location.origin);
2695
- if (url.origin !== location.origin) return null;
2696
- url.searchParams.set("return_to", location.pathname + location.search);
2697
- return url.pathname + url.search;
2698
- } catch {
2699
- return null;
2700
- }
2701
- }
2702
- function CboxAppCatalog({ endpoint, currentAppKey, className }) {
2595
+ defineCboxAppSwitcher();
2596
+ function CboxAppCatalog({ endpoint, currentAppKey, theme, className }) {
2703
2597
  const { t } = useCboxLocalization();
2704
- const [open, setOpen] = useState(false);
2705
- const [state, setState] = useState({ status: "idle" });
2706
- const container = useRef(null);
2707
- const flight = useRef(null);
2708
- const expires = useRef(0);
2709
- const load = useCallback(async () => {
2710
- if (endpoint === null || flight.current !== null) return;
2711
- const request = new AbortController();
2712
- flight.current = request;
2713
- setState((current) => current.status === "ready" ? current : { status: "loading" });
2714
- try {
2715
- const response = await fetch(endpoint, {
2716
- credentials: "same-origin",
2717
- cache: "no-store",
2718
- headers: { Accept: "application/json", "X-Requested-With": "XMLHttpRequest" },
2719
- signal: request.signal
2720
- });
2721
- const body = await response.json().catch(() => null);
2722
- if (request.signal.aborted) return;
2723
- const next = parseAppCatalog(response.ok, body);
2724
- expires.current = next.status === "ready" ? Date.now() + next.refreshAfter * 1e3 : 0;
2725
- setState(next);
2726
- if (next.status === "ready") rememberAppCatalog(next.apps);
2727
- } catch {
2728
- if (!request.signal.aborted) {
2729
- expires.current = 0;
2730
- setState({ status: "unavailable" });
2731
- }
2732
- } finally {
2733
- if (flight.current === request) flight.current = null;
2734
- }
2735
- }, [endpoint]);
2736
- const refresh = useCallback(() => {
2737
- if (document.visibilityState === "visible" && Date.now() >= expires.current) void load();
2738
- }, [load]);
2739
- useEffect(() => {
2740
- if (!open) return;
2741
- refresh();
2742
- const outside = (event) => {
2743
- if (container.current !== null && !container.current.contains(event.target)) setOpen(false);
2744
- };
2745
- const key = (event) => {
2746
- if (event.key === "Escape") setOpen(false);
2747
- };
2748
- window.addEventListener("pointerdown", outside);
2749
- window.addEventListener("keydown", key);
2750
- window.addEventListener("focus", refresh);
2751
- document.addEventListener("visibilitychange", refresh);
2752
- return () => {
2753
- window.removeEventListener("pointerdown", outside);
2754
- window.removeEventListener("keydown", key);
2755
- window.removeEventListener("focus", refresh);
2756
- document.removeEventListener("visibilitychange", refresh);
2757
- };
2758
- }, [open, refresh]);
2759
- useEffect(() => {
2760
- if (!open || state.status !== "ready") return;
2761
- const timer = window.setTimeout(refresh, Math.max(50, expires.current - Date.now()));
2762
- return () => window.clearTimeout(timer);
2763
- }, [open, state, refresh]);
2764
- useEffect(() => () => flight.current?.abort(), []);
2765
- useEffect(() => {
2766
- expires.current = 0;
2767
- setState({ status: "idle" });
2768
- }, [endpoint]);
2769
- const reconnect = state.status === "authorization_required" && typeof window !== "undefined" ? authorizeHref(state.authorizeUrl, window.location) : null;
2770
- return /* @__PURE__ */ jsxs("div", { ref: container, className: cn("relative", className), children: [
2771
- /* @__PURE__ */ jsx(
2772
- "button",
2773
- {
2774
- type: "button",
2775
- "aria-label": t("Switch app"),
2776
- title: t("Switch app"),
2777
- "aria-haspopup": "dialog",
2778
- "aria-expanded": open,
2779
- disabled: endpoint === null,
2780
- onClick: () => setOpen((value) => !value),
2781
- className: cn(
2782
- "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",
2783
- open && "bg-secondary text-foreground"
2784
- ),
2785
- children: /* @__PURE__ */ jsx(Grid2, {})
2786
- }
2787
- ),
2788
- 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: [
2789
- /* @__PURE__ */ jsx("h2", { className: "mb-2 text-sm font-semibold text-foreground", children: t("Switch app") }),
2790
- /* @__PURE__ */ jsxs("div", { "aria-live": "polite", children: [
2791
- (state.status === "idle" || state.status === "loading") && /* @__PURE__ */ jsx("p", { className: "px-1 py-2 text-sm text-muted-foreground", children: t("Loading apps\u2026") }),
2792
- state.status === "unavailable" && /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-1 py-2 text-sm", children: [
2793
- /* @__PURE__ */ jsx("p", { role: "alert", className: "text-muted-foreground", children: t("Apps could not be loaded.") }),
2794
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void load(), className: "font-medium text-foreground underline", children: t("Try again") })
2795
- ] }),
2796
- state.status === "authorization_required" && /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-1 py-2 text-sm", children: [
2797
- /* @__PURE__ */ jsx("p", { role: "alert", className: "text-muted-foreground", children: t("Apps could not be loaded.") }),
2798
- 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") })
2799
- ] }),
2800
- 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) => {
2801
- const current = app.key === currentAppKey;
2802
- return /* @__PURE__ */ jsxs(
2803
- "a",
2804
- {
2805
- href: app.launch_url,
2806
- "aria-current": current ? "true" : void 0,
2807
- title: app.description ?? app.name,
2808
- onClick: () => setOpen(false),
2809
- 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"),
2810
- children: [
2811
- /* @__PURE__ */ jsx(CboxAppIcon, { name: app.name, iconUrl: app.icon_url, iconDarkUrl: app.icon_dark_url }),
2812
- /* @__PURE__ */ jsx("span", { className: "max-w-full break-words", children: app.name.replace(/^Cbox\s*·\s*/i, "") }),
2813
- current && /* @__PURE__ */ jsx(Check2, {})
2814
- ]
2815
- },
2816
- app.key
2817
- );
2818
- }) }))
2819
- ] })
2820
- ] }) : null
2821
- ] });
2822
- }
2823
- function Grid2() {
2824
- 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}`))) });
2825
- }
2826
- function Check2() {
2827
- 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
+ });
2828
2611
  }
2829
2612
  function Combobox(props) {
2830
2613
  const { t } = useCboxLocalization();
@@ -3129,7 +2912,7 @@ function ComboboxGroupRows({
3129
2912
  /* @__PURE__ */ jsx("span", { className: "truncate text-[13px] font-medium text-foreground", children: opt.label }),
3130
2913
  opt.secondary !== void 0 ? /* @__PURE__ */ jsx("span", { className: "text-mono truncate text-[10px] text-muted-foreground", children: opt.secondary }) : null
3131
2914
  ] }),
3132
- isActive ? /* @__PURE__ */ jsx(Check3, {}) : null
2915
+ isActive ? /* @__PURE__ */ jsx(Check2, {}) : null
3133
2916
  ] });
3134
2917
  const className = cn(
3135
2918
  "group block w-full rounded-sm transition-colors text-left",
@@ -3311,7 +3094,7 @@ function Chevron4({ open }) {
3311
3094
  }
3312
3095
  );
3313
3096
  }
3314
- function Check3() {
3097
+ function Check2() {
3315
3098
  return /* @__PURE__ */ jsx(
3316
3099
  "svg",
3317
3100
  {
@@ -4087,6 +3870,6 @@ function Sparkline({ values, color = "var(--chart-1)", width = 90, height = 20 }
4087
3870
  ] });
4088
3871
  }
4089
3872
 
4090
- 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, authorizeHref, buildUrlSearch, defineUrlSchema, interpolate, navMatchLength, parseAppCatalog, parseUrlSearch, rememberAppCatalog, secureIconUrl, urlBoolean, urlEnum, urlNumber, urlString, urlStringArray, useCboxId, useCboxIdOptional, useCboxLocalization, useCboxSurfaces, useCboxSurfacesOptional, useKnownAppCatalog };
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 };
4091
3874
  //# sourceMappingURL=index.js.map
4092
3875
  //# sourceMappingURL=index.js.map