@cboxdk/cbox-ui 0.9.0 → 0.10.1
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 +183 -78
- package/dist/index.d.ts +468 -537
- package/dist/index.js +3782 -3324
- package/dist/index.js.map +1 -1
- package/package.json +11 -3
- package/tokens/cbox.css +3 -35
- package/tokens/shell.css +362 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import { ReactNode,
|
|
3
|
+
import { ReactNode, ComponentType, AnchorHTMLAttributes, ComponentProps } from 'react';
|
|
4
4
|
import { C as CboxThemeMode, a as CboxKnownApp } from './catalog-BroZWvws.js';
|
|
5
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';
|
|
6
6
|
import { LucideIcon } from 'lucide-react';
|
|
@@ -208,176 +208,489 @@ declare function useCboxId(): CboxIdContextValue;
|
|
|
208
208
|
*/
|
|
209
209
|
declare function useCboxIdOptional(): CboxIdContextValue | null;
|
|
210
210
|
|
|
211
|
-
type
|
|
211
|
+
type CboxTranslationValues = Record<string, string | number>;
|
|
212
|
+
type CboxTranslator = (message: string, values?: CboxTranslationValues) => string;
|
|
213
|
+
declare function interpolate(message: string, values?: CboxTranslationValues): string;
|
|
214
|
+
/** Optional and additive: without a provider existing consumers retain English. */
|
|
215
|
+
declare function CboxLocalizationProvider({ locale, translate, formatDate, children }: {
|
|
216
|
+
locale: string;
|
|
217
|
+
translate: CboxTranslator;
|
|
218
|
+
formatDate?: (value: string) => string;
|
|
212
219
|
children: ReactNode;
|
|
220
|
+
}): react_jsx_runtime.JSX.Element;
|
|
221
|
+
declare function useCboxLocalization(): {
|
|
222
|
+
locale: string;
|
|
223
|
+
t: CboxTranslator;
|
|
224
|
+
formatDate: (value: string) => string;
|
|
213
225
|
};
|
|
226
|
+
|
|
214
227
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
228
|
+
* Help's state lives outside React (§7.1): open or closed, what it shows, the search, the scroll
|
|
229
|
+
* position and the support updates survive an Inertia visit and even a remount of the shell,
|
|
230
|
+
* like a browser side panel. The conversation itself lives in the `<cbox-support>` element, which
|
|
231
|
+
* survives as long as the shell sits in the host's persistent layout.
|
|
218
232
|
*/
|
|
219
|
-
|
|
233
|
+
type HelpArticle = {
|
|
234
|
+
id: string;
|
|
235
|
+
title: string;
|
|
236
|
+
excerpt?: string;
|
|
237
|
+
body?: string;
|
|
238
|
+
url?: string;
|
|
239
|
+
source?: string;
|
|
240
|
+
};
|
|
241
|
+
type SupportUpdate = {
|
|
242
|
+
id: string;
|
|
243
|
+
kind: 'ticket' | 'chat';
|
|
244
|
+
title: string;
|
|
245
|
+
excerpt?: string;
|
|
246
|
+
at?: string;
|
|
247
|
+
unread: boolean;
|
|
248
|
+
url?: string;
|
|
249
|
+
};
|
|
250
|
+
type HelpStatus = 'idle' | 'loading' | 'ready' | 'unavailable';
|
|
251
|
+
type HelpState = {
|
|
252
|
+
open: boolean;
|
|
253
|
+
/** The article shown instead of the home view, or null. */
|
|
254
|
+
article: HelpArticle | null;
|
|
255
|
+
query: string;
|
|
256
|
+
scrollTop: number;
|
|
257
|
+
updates: SupportUpdate[];
|
|
258
|
+
updatesStatus: HelpStatus;
|
|
259
|
+
/** A question waiting for the chat to be ready ("Ask Cbox: …" from the palette). */
|
|
260
|
+
pendingQuestion: string | null;
|
|
261
|
+
/** Whether `open` was taken from the person's saved preference yet. */
|
|
262
|
+
seeded: boolean;
|
|
263
|
+
/**
|
|
264
|
+
* `open` came from the saved preference, not from the person on this page. Help left open
|
|
265
|
+
* shows docked from 1280px; below that it waits until the person opens it, so a phone or a
|
|
266
|
+
* narrow window never lands under the full-screen overlay.
|
|
267
|
+
*/
|
|
268
|
+
restored: boolean;
|
|
269
|
+
/** Which list the support updates came from (URL and organization), so a switch reloads them. */
|
|
270
|
+
updatesKey: string | null;
|
|
271
|
+
};
|
|
272
|
+
type HelpStore = {
|
|
273
|
+
get(): HelpState;
|
|
274
|
+
set(patch: Partial<HelpState> | ((state: HelpState) => Partial<HelpState>)): void;
|
|
275
|
+
subscribe(listener: () => void): () => void;
|
|
276
|
+
};
|
|
277
|
+
declare function createHelpStore(initial?: Partial<HelpState>): HelpStore;
|
|
278
|
+
|
|
279
|
+
type ShellIcon = ComponentType<{
|
|
280
|
+
size?: number;
|
|
281
|
+
strokeWidth?: number;
|
|
282
|
+
className?: string;
|
|
283
|
+
'aria-hidden'?: boolean;
|
|
284
|
+
}>;
|
|
285
|
+
/** Lucide names an app can use for areas, pages and actions without shipping its own map. */
|
|
286
|
+
declare const SHELL_ICONS: Readonly<Record<string, ShellIcon>>;
|
|
220
287
|
|
|
221
288
|
/**
|
|
222
|
-
*
|
|
223
|
-
* scrollable content column (right) side-by-side. Fits the full
|
|
224
|
-
* viewport height; only the content column scrolls.
|
|
289
|
+
* The `shell` Inertia prop: the one data contract every Cbox app shares (spec §11.1).
|
|
225
290
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
291
|
+
* The server (laravel-console-kit) produces it; `<CboxShell>` renders it. It carries only the
|
|
292
|
+
* current selection and URLs. Lists, the app catalog, help and search load in the browser after
|
|
293
|
+
* the page has painted, so building this prop never calls another service (local first, §11.2a).
|
|
228
294
|
*/
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
295
|
+
/** The product key (URL standard §1). Unknown keys are allowed so a new app needs no release here. */
|
|
296
|
+
type AppKey = 'id' | 'billing' | 'telemetry' | 'work' | 'brain' | 'infra' | 'engage' | 'assistant' | 'sites' | 'stache' | 'status' | 'tax' | 'signals' | 'domains' | (string & {});
|
|
297
|
+
/**
|
|
298
|
+
* A labelled link. `href` is the same URL under the name laravel-console-kit 0.2 sends; the
|
|
299
|
+
* shell reads `url` first, then `href`.
|
|
300
|
+
*/
|
|
301
|
+
type Link = {
|
|
234
302
|
label: string;
|
|
303
|
+
url: string;
|
|
304
|
+
href?: string;
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* One page inside an area. `icon` is a Lucide icon name (`"git-branch"`), resolved by the shell.
|
|
308
|
+
* `href` is the same URL under the name laravel-console-kit 0.2 sends; the shell reads `url`
|
|
309
|
+
* first, then `href`.
|
|
310
|
+
*/
|
|
311
|
+
type NavPage = {
|
|
312
|
+
key: string;
|
|
313
|
+
label: string;
|
|
314
|
+
url: string;
|
|
315
|
+
href?: string;
|
|
316
|
+
icon?: string;
|
|
235
317
|
/**
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* (`/org/${slug}/endpoints`) before passing it in — cbox-ui
|
|
239
|
-
* stays unaware of routing conventions.
|
|
318
|
+
* The page is not part of the organization's plan: it shows with a lock and an accessible
|
|
319
|
+
* "(locked)", and `url` leads to the upgrade prompt.
|
|
240
320
|
*/
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
321
|
+
locked?: boolean;
|
|
322
|
+
/** A badge, such as open drafts. Not shown when 0 or absent. */
|
|
323
|
+
count?: number;
|
|
324
|
+
/**
|
|
325
|
+
* A heading inside the area's subnav (Settings → "Organization", "Project"). Pages of one
|
|
326
|
+
* group show together under it, in the order each group first appears.
|
|
327
|
+
*/
|
|
328
|
+
group?: string;
|
|
249
329
|
};
|
|
250
|
-
|
|
330
|
+
/** One area in the rail. The subnav shows its pages when it has more than one. */
|
|
331
|
+
type NavArea = {
|
|
332
|
+
key: string;
|
|
251
333
|
label: string;
|
|
252
|
-
|
|
334
|
+
url: string;
|
|
335
|
+
href?: string;
|
|
336
|
+
icon?: string;
|
|
337
|
+
pages?: NavPage[];
|
|
253
338
|
};
|
|
339
|
+
type ContextTone = 'production' | 'sandbox' | 'neutral';
|
|
254
340
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
341
|
+
* One selectable item of a level: the current one in the prop, and every row a level's
|
|
342
|
+
* `listUrl` returns. Environments are app-defined (§5.1a): `tone`, `label` and `testData` are
|
|
343
|
+
* all optional and the shell never sorts the items.
|
|
258
344
|
*/
|
|
259
|
-
type
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
/** App key for the brand submark (and aria labels). */
|
|
271
|
-
appKey: string;
|
|
272
|
-
/** Optional override for the submark — defaults to `appKey`. */
|
|
273
|
-
brandSubmark?: string | null;
|
|
274
|
-
/** Where brand assets live. Default `/brand`. */
|
|
275
|
-
assetBase?: string;
|
|
276
|
-
/** Where the brand row links to (typically the app's home). */
|
|
277
|
-
brandHref?: string;
|
|
278
|
-
/** Nav sections — top to bottom. */
|
|
279
|
-
sections: CboxNavSection[];
|
|
280
|
-
/** Active path — used to highlight the current row. */
|
|
281
|
-
currentPath: string;
|
|
282
|
-
/** Apps inject their router's Link primitive. */
|
|
283
|
-
LinkComponent: LinkComponent;
|
|
284
|
-
/** Persisted "is the desktop sidebar collapsed?" state. */
|
|
285
|
-
collapsed?: boolean;
|
|
286
|
-
className?: string;
|
|
345
|
+
type ContextItem = {
|
|
346
|
+
id: string;
|
|
347
|
+
name: string;
|
|
348
|
+
/** Chip text. Defaults to the first letters of the name. */
|
|
349
|
+
initials?: string;
|
|
350
|
+
/** The coloured square: production green, sandbox amber, neutral grey. */
|
|
351
|
+
tone?: ContextTone;
|
|
352
|
+
/** Short app-defined label beside the name ("default", "test data"). */
|
|
353
|
+
label?: string;
|
|
354
|
+
/** The sandbox strip shows while the current item has test data. */
|
|
355
|
+
testData?: boolean;
|
|
287
356
|
};
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
* No app should ship its own sidebar component. The chrome is the
|
|
297
|
-
* shape; nav items are the data.
|
|
298
|
-
*/
|
|
299
|
-
declare function CboxAppSidebar({ appKey, brandSubmark, assetBase, brandHref, sections, currentPath, LinkComponent, collapsed, className, }: CboxAppSidebarProps): react_jsx_runtime.JSX.Element;
|
|
300
|
-
|
|
301
|
-
type CboxAppShellProps = {
|
|
302
|
-
/** App key — drives the brand submark + aria labels. */
|
|
303
|
-
appKey: string;
|
|
304
|
-
/** Override the submark text (defaults to appKey). */
|
|
305
|
-
brandSubmark?: string | null;
|
|
306
|
-
/** Asset base for brand pngs. Default `/brand`. */
|
|
307
|
-
assetBase?: string;
|
|
308
|
-
/** Brand row href (typically the app's home). */
|
|
309
|
-
brandHref?: string;
|
|
310
|
-
/** Sidebar nav config. */
|
|
311
|
-
sections: CboxNavSection[];
|
|
312
|
-
/** Active path — used by both sidebar (highlight) and topbar
|
|
313
|
-
* (sidebar-collapse toggle aria state). */
|
|
314
|
-
currentPath: string;
|
|
315
|
-
/** Apps inject their router's Link primitive. */
|
|
316
|
-
LinkComponent: LinkComponent;
|
|
317
|
-
/** Persisted "sidebar collapsed?" state — owned by the host
|
|
318
|
-
* (the cookie hook lives there). */
|
|
319
|
-
sidebarCollapsed?: boolean;
|
|
320
|
-
/** Click handler for the topbar collapse toggle. Hide the
|
|
321
|
-
* toggle entirely by omitting this prop. */
|
|
322
|
-
onToggleSidebar?: () => void;
|
|
357
|
+
type ContextLevel = {
|
|
358
|
+
/** `organization`, `project`, `environment`, or the app's own key (`site`, `space`). */
|
|
359
|
+
key: 'organization' | 'project' | 'environment' | (string & {});
|
|
360
|
+
/** Singular, as the app names it: "Organization", "Site", "Space", "Environment". */
|
|
361
|
+
label: string;
|
|
362
|
+
/** Plural for headings ("Organizations"). Defaults to `label` + "s". */
|
|
363
|
+
labelPlural?: string;
|
|
364
|
+
current: ContextItem;
|
|
323
365
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* pages) leave this off.
|
|
366
|
+
* Lazy JSON list, fetched when a menu opens: `GET listUrl?q=&parent=&cursor=&limit=` answering
|
|
367
|
+
* `{ data: ContextItem[], has_more: boolean, next_cursor: string | null }`.
|
|
327
368
|
*/
|
|
328
|
-
|
|
369
|
+
listUrl: string;
|
|
370
|
+
/** `POST createUrl { name, parent? }` answering `{ id, detailsUrl }`. Absent: no "New …". */
|
|
371
|
+
createUrl?: string;
|
|
372
|
+
/** "View all". */
|
|
373
|
+
allUrl: string;
|
|
329
374
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* chrome stays visually identical across all apps regardless of
|
|
333
|
-
* whether a palette has been wired up yet.
|
|
375
|
+
* Settings page of one item, as a URL template on the wire: `{id}` is replaced with the
|
|
376
|
+
* item's id (`/orgs/{id}/settings`). Absent: no gear.
|
|
334
377
|
*/
|
|
335
|
-
|
|
378
|
+
settingsUrl?: string;
|
|
379
|
+
};
|
|
380
|
+
type PaletteAction = {
|
|
381
|
+
id: string;
|
|
382
|
+
label: string;
|
|
383
|
+
url: string;
|
|
384
|
+
/** `post` for actions that change something. Default `get`. */
|
|
385
|
+
method?: 'get' | 'post';
|
|
386
|
+
icon?: string;
|
|
387
|
+
/** Extra words the palette matches on. */
|
|
388
|
+
keywords?: string[];
|
|
389
|
+
};
|
|
390
|
+
type ShellHelp = {
|
|
391
|
+
/** False: Help still renders, and says it is not available here. */
|
|
392
|
+
enabled: boolean;
|
|
393
|
+
/** The page's help topic key (§7.2.3). */
|
|
394
|
+
topic?: string;
|
|
395
|
+
/** Same-origin route the Assistant SDK's `<cbox-support>` element fetches its session from. */
|
|
396
|
+
sessionUrl?: string;
|
|
397
|
+
/** Where the SDK script is served. Default `/ai-assistant/support.js` (laravel-assistant-client). */
|
|
398
|
+
scriptUrl?: string;
|
|
399
|
+
/** The support portal. Absent or offline: the link is hidden. */
|
|
400
|
+
portalUrl?: string;
|
|
401
|
+
/** `GET` support updates; `POST {updatesUrl}/{id}/read` marks one read. */
|
|
402
|
+
updatesUrl?: string;
|
|
403
|
+
/** `GET ?q=&topic=` docs, help centre and knowledge base search. */
|
|
404
|
+
searchUrl?: string;
|
|
405
|
+
/** Articles for a topic, as a template: `{topic}` is replaced. */
|
|
406
|
+
articlesUrl?: string;
|
|
407
|
+
};
|
|
408
|
+
type ShellNotifications = {
|
|
409
|
+
enabled: false;
|
|
410
|
+
} | {
|
|
411
|
+
enabled: true;
|
|
412
|
+
unread: number;
|
|
413
|
+
url: string;
|
|
414
|
+
};
|
|
415
|
+
type ShellBanner = {
|
|
416
|
+
kind: 'sandbox' | 'impersonation' | 'notice';
|
|
417
|
+
text: string;
|
|
418
|
+
action?: Link;
|
|
419
|
+
};
|
|
420
|
+
type ShellTheme = 'system' | 'light' | 'dark';
|
|
421
|
+
type ShellPreferences = {
|
|
422
|
+
theme: ShellTheme;
|
|
423
|
+
locale: string;
|
|
424
|
+
railPinned: boolean;
|
|
425
|
+
helpOpen: boolean;
|
|
426
|
+
/** The subnav collapsed to its strip (⌘.). */
|
|
427
|
+
subnavCollapsed?: boolean;
|
|
428
|
+
/** Regional format (a BCP 47 locale for dates and numbers), from Cbox ID's preferences. */
|
|
429
|
+
regionalFormat?: string;
|
|
430
|
+
/** IANA time zone, from Cbox ID's preferences. */
|
|
431
|
+
timeZone?: string;
|
|
432
|
+
};
|
|
433
|
+
type ShellOption = {
|
|
434
|
+
code: string;
|
|
435
|
+
label: string;
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* What the account menu (§10) links to. A row whose URL is absent is not shown (laravel-console-kit
|
|
439
|
+
* leaves out what the app has no route for).
|
|
440
|
+
*/
|
|
441
|
+
type ShellAccount = {
|
|
442
|
+
/** Profile and security, in Cbox ID. */
|
|
443
|
+
profileUrl?: string;
|
|
444
|
+
switchAccountUrl?: string;
|
|
445
|
+
signOutUrl?: string;
|
|
446
|
+
/** Default `post`. */
|
|
447
|
+
signOutMethod?: 'get' | 'post';
|
|
448
|
+
/** Languages the app is translated into. */
|
|
449
|
+
languages?: ShellOption[];
|
|
450
|
+
/** Regional formats offered. Defaults to a short list. */
|
|
451
|
+
formats?: ShellOption[];
|
|
452
|
+
/** Line under the name in the account menu. Default "Signed in with Cbox ID". */
|
|
453
|
+
signedInWith?: string;
|
|
454
|
+
};
|
|
455
|
+
type Shell = {
|
|
456
|
+
app: {
|
|
457
|
+
key: AppKey;
|
|
458
|
+
name: string;
|
|
459
|
+
homeUrl: string;
|
|
460
|
+
};
|
|
461
|
+
person: {
|
|
462
|
+
id: string;
|
|
463
|
+
name: string;
|
|
464
|
+
initials: string;
|
|
465
|
+
avatarUrl?: string;
|
|
466
|
+
email?: string;
|
|
467
|
+
};
|
|
468
|
+
/** The page title and route, for "On this page" and the chat's page intent. */
|
|
469
|
+
page?: {
|
|
470
|
+
title: string;
|
|
471
|
+
route?: string;
|
|
472
|
+
};
|
|
473
|
+
nav: {
|
|
474
|
+
areas: NavArea[];
|
|
475
|
+
activeArea: string;
|
|
476
|
+
activePage?: string;
|
|
477
|
+
};
|
|
478
|
+
context: {
|
|
479
|
+
/** 1–3, in order. The first is the organization. */
|
|
480
|
+
levels: ContextLevel[];
|
|
481
|
+
/** `POST` target; the server resolves same-page or list fallback (§5.6). */
|
|
482
|
+
switchUrl: string;
|
|
483
|
+
};
|
|
484
|
+
palette: {
|
|
485
|
+
/** `GET ?q=` → `{ data: [{ id, title, subtitle?, url }] }`, in the current context. */
|
|
486
|
+
searchUrl?: string;
|
|
487
|
+
/** `GET ?q=` → level 2/3 combinations across organizations (§6.1.4). */
|
|
488
|
+
gotoUrl?: string;
|
|
489
|
+
actions: PaletteAction[];
|
|
490
|
+
/** The palette search field's placeholder, e.g. "Search customers, invoices… or pages". Default "Search or ask…". */
|
|
491
|
+
placeholder?: string;
|
|
492
|
+
};
|
|
493
|
+
help: ShellHelp;
|
|
494
|
+
notifications: ShellNotifications;
|
|
495
|
+
apps: {
|
|
496
|
+
/** The host's catalog endpoint (laravel-id-client `CboxId::appCatalogRoutes()`). */
|
|
497
|
+
catalogUrl: string;
|
|
498
|
+
/** "All products ↗". Default https://cbox.dk. */
|
|
499
|
+
productsUrl?: string;
|
|
500
|
+
};
|
|
501
|
+
/** The account menu's links. Absent (laravel-console-kit 0.2.2): the menu has only the preferences. */
|
|
502
|
+
account?: ShellAccount;
|
|
503
|
+
banner?: ShellBanner;
|
|
504
|
+
preferences: ShellPreferences;
|
|
505
|
+
};
|
|
506
|
+
/** How the shell moves the person. An Inertia host passes `router.visit`. */
|
|
507
|
+
type ShellNavigate = (url: string, options?: {
|
|
508
|
+
method?: 'get' | 'post';
|
|
509
|
+
data?: Record<string, unknown>;
|
|
510
|
+
newTab?: boolean;
|
|
511
|
+
}) => void;
|
|
512
|
+
/** Where the shell reports a preference the person changed, for the host to persist. */
|
|
513
|
+
type ShellPreferenceChange = <K extends keyof ShellPreferences>(key: K, value: ShellPreferences[K]) => void;
|
|
514
|
+
|
|
515
|
+
/** A client-side link (Inertia's `Link`). Receives `href`, `className`, `children` and ARIA props. */
|
|
516
|
+
type ShellLinkComponent = ComponentType<AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
517
|
+
href: string;
|
|
518
|
+
children?: ReactNode;
|
|
519
|
+
}>;
|
|
520
|
+
/** Which overlay is open. Only one at a time, so two menus never stack. */
|
|
521
|
+
type ShellOverlay = 'org' | 'context' | 'apps' | 'account' | 'palette' | 'nav-sheet' | 'context-sheet' | null;
|
|
522
|
+
type ShellApi = {
|
|
523
|
+
shell: Shell;
|
|
524
|
+
t: CboxTranslator;
|
|
525
|
+
navigate: ShellNavigate;
|
|
526
|
+
Link: ShellLinkComponent;
|
|
527
|
+
icons: Readonly<Record<string, ShellIcon>>;
|
|
528
|
+
preferences: ShellPreferences;
|
|
529
|
+
setPreference: ShellPreferenceChange;
|
|
530
|
+
overlay: ShellOverlay;
|
|
531
|
+
setOverlay: (overlay: ShellOverlay) => void;
|
|
532
|
+
help: HelpStore;
|
|
533
|
+
/** Open or close Help. */
|
|
534
|
+
toggleHelp: (open?: boolean) => void;
|
|
535
|
+
/** Open Help on an article. */
|
|
536
|
+
openArticle: (article: HelpArticle) => void;
|
|
537
|
+
/** Open Help and send a question to the chat with the page as context. */
|
|
538
|
+
ask: (question: string) => void;
|
|
539
|
+
/** Switch context: `chosen` maps level keys to ids. */
|
|
540
|
+
switchTo: (chosen: Record<string, string>) => void;
|
|
541
|
+
};
|
|
542
|
+
/** Help for a page's own `?` button, or `null` outside the shell. */
|
|
543
|
+
declare function useShellHelp(): Pick<ShellApi, 'toggleHelp' | 'openArticle' | 'ask'> | null;
|
|
544
|
+
|
|
545
|
+
type CboxShellProps = {
|
|
546
|
+
/** The shared `shell` prop. */
|
|
547
|
+
shell: Shell;
|
|
548
|
+
/** The page. */
|
|
549
|
+
children: ReactNode;
|
|
550
|
+
/** How to move the person. Inertia: `(url, o) => router.visit(url, { method: o?.method, data: o?.data })`, plus `window.open` for `newTab`. Default: page loads and form posts. */
|
|
551
|
+
navigate?: ShellNavigate;
|
|
552
|
+
/** Client-side link for nav and settings links (Inertia's `Link`). Default `<a>`. */
|
|
553
|
+
LinkComponent?: ShellLinkComponent;
|
|
554
|
+
/** Extra icons by name, on top of the built-in Lucide set. */
|
|
555
|
+
icons?: Readonly<Record<string, ShellIcon>>;
|
|
336
556
|
/**
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
557
|
+
* Called when the person changes a preference, for the host to persist (a cookie read before
|
|
558
|
+
* first paint, and Cbox ID's preferences for theme, language, format and time zone). Without
|
|
559
|
+
* it the shell writes a `cbox_shell_<key>` cookie.
|
|
340
560
|
*/
|
|
341
|
-
|
|
342
|
-
|
|
561
|
+
onPreferenceChange?: ShellPreferenceChange;
|
|
562
|
+
/** Help's state store. Default: one per page, so it outlives the shell's own remounts. */
|
|
563
|
+
helpStore?: HelpStore;
|
|
564
|
+
/** Where the Cbox wordmark is served. Default `/brand`. */
|
|
565
|
+
brandAssetBase?: string;
|
|
566
|
+
/** `id` of the `<main>` landmark, which the shell's "Skip to content" link targets. Default `main-content`. */
|
|
567
|
+
mainId?: string;
|
|
343
568
|
};
|
|
344
569
|
/**
|
|
345
|
-
*
|
|
346
|
-
*
|
|
570
|
+
* Apply a theme choice to the document the way the tokens read it: `.dark` and `data-theme` on
|
|
571
|
+
* the root, with `system` following the device. The saved choice stays `system`; the device's
|
|
572
|
+
* scheme is never written back (cbox-design, shared preferences).
|
|
573
|
+
*/
|
|
574
|
+
declare function applyTheme(theme: ShellTheme): void;
|
|
575
|
+
/**
|
|
576
|
+
* The inline script a host puts in `<head>` so the theme is right before the first paint
|
|
577
|
+
* (§12.1). `theme` is the person's saved choice from the `shell` prop.
|
|
578
|
+
*/
|
|
579
|
+
declare function themeBootScript(theme: ShellTheme): string;
|
|
580
|
+
/**
|
|
581
|
+
* The one shell for every Cbox app (spec 2026-11-10 shell v1): rail with the account at the
|
|
582
|
+
* bottom, subnav, header with the context selectors, Search, Help, the bell when the app has a
|
|
583
|
+
* source, Switch app; the ⌘K palette; the Help column; and the phone layout.
|
|
347
584
|
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
* compose `<AppShell>`/`<AppContent>`/sidebar/topbar manually —
|
|
351
|
-
* drift is the whole reason this component exists.
|
|
585
|
+
* Render it in the host's persistent layout (Inertia `Page.layout`), so the rail, Help and the
|
|
586
|
+
* chat survive page visits; only `shell` and `children` change.
|
|
352
587
|
*/
|
|
353
|
-
declare function
|
|
588
|
+
declare function CboxShell({ shell, children, navigate, LinkComponent, icons, onPreferenceChange, helpStore, brandAssetBase, mainId }: CboxShellProps): react_jsx_runtime.JSX.Element;
|
|
354
589
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
590
|
+
/** The page intent the chat is given (§7.2.4): route, title and context. */
|
|
591
|
+
type PageIntent = {
|
|
592
|
+
route?: string;
|
|
593
|
+
title?: string;
|
|
594
|
+
context: string;
|
|
595
|
+
url?: string;
|
|
596
|
+
};
|
|
597
|
+
declare function contextTrail(shell: Shell): string;
|
|
598
|
+
declare function pageIntent(shell: Shell): PageIntent;
|
|
599
|
+
|
|
600
|
+
/** One app in the grid (§9). */
|
|
601
|
+
type ShellApp = {
|
|
602
|
+
key: string;
|
|
603
|
+
name: string;
|
|
604
|
+
/** One line: "Identity and sign-in". */
|
|
605
|
+
purpose: string | null;
|
|
606
|
+
/** Fixed per-app hue (0–360); the tile is drawn in it, in light and dark. */
|
|
607
|
+
hue: number;
|
|
608
|
+
iconUrl: string | null;
|
|
609
|
+
iconDarkUrl: string | null;
|
|
610
|
+
/** Where the tile goes: the app, or its admission page when the organization lacks it. */
|
|
611
|
+
url: string;
|
|
612
|
+
/** The organization has this app. False: "More from Cbox", dimmed. */
|
|
613
|
+
inOrganization: boolean;
|
|
614
|
+
};
|
|
615
|
+
/** Each app's fixed hue when the catalog sends none. */
|
|
616
|
+
declare const APP_HUES: Readonly<Record<string, number>>;
|
|
617
|
+
/** A stable hue for an unknown key, so its tile keeps its colour between pages. */
|
|
618
|
+
declare function hueFor(key: string, given?: unknown): number;
|
|
619
|
+
type ShellCatalogState = {
|
|
620
|
+
status: 'loading';
|
|
621
|
+
} | {
|
|
622
|
+
status: 'ready';
|
|
623
|
+
apps: ShellApp[];
|
|
624
|
+
} | {
|
|
625
|
+
status: 'signin_required';
|
|
626
|
+
href: string | null;
|
|
627
|
+
} | {
|
|
628
|
+
status: 'unavailable';
|
|
365
629
|
};
|
|
366
630
|
/**
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
* `
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
631
|
+
* The catalog answer, with the shell's additions (§9.3): `in_organization` (default true),
|
|
632
|
+
* `admission_url` for apps the organization does not have, `purpose` (falls back to
|
|
633
|
+
* `description`) and `hue`. Only http(s) links are kept.
|
|
634
|
+
*/
|
|
635
|
+
declare function parseShellCatalog(ok: boolean, body: unknown, here?: {
|
|
636
|
+
origin: string;
|
|
637
|
+
pathname: string;
|
|
638
|
+
search: string;
|
|
639
|
+
}): ShellCatalogState;
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* The shell's few network shapes and the pure rules around them: list pages, inline create,
|
|
643
|
+
* the switch payload and settings links. Everything here is same-origin and JSON.
|
|
644
|
+
*/
|
|
645
|
+
type ListPage = {
|
|
646
|
+
items: ContextItem[];
|
|
647
|
+
hasMore: boolean;
|
|
648
|
+
nextCursor: string | null;
|
|
649
|
+
};
|
|
650
|
+
/** First letters of the first two words, for a chip. */
|
|
651
|
+
declare function initialsOf(name: string): string;
|
|
652
|
+
/**
|
|
653
|
+
* A list answer. The URL standard's envelope (`{ object: 'list', data, has_more, next_cursor }`)
|
|
654
|
+
* and a bare array are both accepted; rows without an id and a name are dropped.
|
|
655
|
+
*/
|
|
656
|
+
declare function parseListPage(body: unknown): ListPage;
|
|
657
|
+
/** `url` with query parameters added; empty values are left out. Works for relative URLs. */
|
|
658
|
+
declare function withQuery(url: string, params: Record<string, string | undefined | null>): string;
|
|
659
|
+
/** The settings link of one item, from the level's URL template. Null when the level has none. */
|
|
660
|
+
declare function settingsHref(level: Pick<ContextLevel, 'settingsUrl'>, id: string): string | null;
|
|
661
|
+
/**
|
|
662
|
+
* Which environment a project click lands on (§5.4): the one with the current environment's
|
|
663
|
+
* name when the project has it, else its first. Undefined when the project has none.
|
|
664
|
+
*/
|
|
665
|
+
declare function environmentFor(environments: readonly ContextItem[], currentName: string | undefined): ContextItem | undefined;
|
|
666
|
+
/**
|
|
667
|
+
* The switch payload (§5.6): every level above the chosen one keeps its current id, the chosen
|
|
668
|
+
* levels get theirs, and levels below are left to the server (it lands on the last used one).
|
|
669
|
+
* `return_to` is where the person is, so the server can stay on the same page.
|
|
670
|
+
*/
|
|
671
|
+
declare function switchPayload(levels: readonly ContextLevel[], chosen: Record<string, string>, returnTo: string): Record<string, string>;
|
|
672
|
+
|
|
673
|
+
type Props$2 = ComponentProps<'main'> & {
|
|
674
|
+
children: ReactNode;
|
|
675
|
+
};
|
|
676
|
+
/**
|
|
677
|
+
* Scrolling main column inside an <AppShell>. Wears the soft blue-
|
|
678
|
+
* tinted gradient canvas so every Cbox app sits on the same
|
|
679
|
+
* background.
|
|
680
|
+
*/
|
|
681
|
+
declare function AppContent({ children, className, ...props }: Props$2): react_jsx_runtime.JSX.Element;
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Top-level chrome. Hosts the desktop sidebar (left) and the
|
|
685
|
+
* scrollable content column (right) side-by-side. Fits the full
|
|
686
|
+
* viewport height; only the content column scrolls.
|
|
375
687
|
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
* page underneath doesn't scroll on touch.
|
|
688
|
+
* Pair with <AppContent> inside. Per-app sidebars compose alongside
|
|
689
|
+
* — cbox-ui doesn't ship one because the nav items are app-specific.
|
|
379
690
|
*/
|
|
380
|
-
declare function
|
|
691
|
+
declare function AppShell({ children }: {
|
|
692
|
+
children: ReactNode;
|
|
693
|
+
}): react_jsx_runtime.JSX.Element;
|
|
381
694
|
|
|
382
695
|
type CboxBrandProps = {
|
|
383
696
|
/**
|
|
@@ -416,96 +729,6 @@ type CboxBrandProps = {
|
|
|
416
729
|
*/
|
|
417
730
|
declare function CboxBrand({ appKey, submark, assetBase, tone, collapsed, className, }: CboxBrandProps): react_jsx_runtime.JSX.Element;
|
|
418
731
|
|
|
419
|
-
type CboxOrgContextBarProps = {
|
|
420
|
-
/**
|
|
421
|
-
* Apps inject their router's Link primitive — used for the
|
|
422
|
-
* crumb's brand-side anchor. The dropdown's onSelect calls
|
|
423
|
-
* `onNavigate(href)` so apps can either `router.visit(href)`
|
|
424
|
-
* (Inertia) or `<Link>`-style navigate.
|
|
425
|
-
*/
|
|
426
|
-
LinkComponent: LinkComponent;
|
|
427
|
-
/**
|
|
428
|
-
* Called when the user picks a different org from the dropdown.
|
|
429
|
-
* Receives an absolute path with the slug substituted in. Apps
|
|
430
|
-
* trigger their router.
|
|
431
|
-
*
|
|
432
|
-
* Path-rewrite rule (Cbox suite convention):
|
|
433
|
-
* /org/<old-slug>/foo/bar → /org/<new-slug>/foo/bar
|
|
434
|
-
* /something-else → /org/<new-slug>
|
|
435
|
-
*
|
|
436
|
-
* Apps that aren't org-scoped (notifications) typically don't
|
|
437
|
-
* render this component at all — but if they do, switching
|
|
438
|
-
* lands on the new org's `/org/<slug>` root and lets the host
|
|
439
|
-
* sort the rest out.
|
|
440
|
-
*/
|
|
441
|
-
onNavigate: (href: string) => void;
|
|
442
|
-
};
|
|
443
|
-
/**
|
|
444
|
-
* Standard Cbox topbar org switcher. One crumb, one dropdown,
|
|
445
|
-
* URL-driven (no POST, no session pin). Mirrors id's pattern 1:1
|
|
446
|
-
* so the chrome reads identically across the suite — that's the
|
|
447
|
-
* whole reason it's here, not in each app.
|
|
448
|
-
*
|
|
449
|
-
* Apps render this in the `topbarCentre` slot of `CboxAppShell`.
|
|
450
|
-
* Hides itself when there's no current org (eg pre-auth, or
|
|
451
|
-
* non-org-scoped surfaces).
|
|
452
|
-
*/
|
|
453
|
-
declare function CboxOrgContextBar({ LinkComponent, onNavigate, }: CboxOrgContextBarProps): react_jsx_runtime.JSX.Element | null;
|
|
454
|
-
|
|
455
|
-
type Props$6 = {
|
|
456
|
-
/**
|
|
457
|
-
* App branding rendered on the left — typically a small logo +
|
|
458
|
-
* the app name. Rendered inside a fixed-height bar so keep it
|
|
459
|
-
* visually compact (24-32px tall content).
|
|
460
|
-
*/
|
|
461
|
-
brand: ReactNode;
|
|
462
|
-
/** Anything between brand and the right cluster — search, breadcrumbs, etc. */
|
|
463
|
-
centre?: ReactNode;
|
|
464
|
-
/**
|
|
465
|
-
* Override slots if an app needs a different control mix in the
|
|
466
|
-
* right cluster. Default: AppLauncher → NotificationsBell → UserMenu.
|
|
467
|
-
*/
|
|
468
|
-
rightCluster?: ReactNode;
|
|
469
|
-
/**
|
|
470
|
-
* Whether to show the org switcher next to the brand. Hide on
|
|
471
|
-
* non-org-scoped surfaces (eg id account-settings).
|
|
472
|
-
*/
|
|
473
|
-
showOrgSwitcher?: boolean;
|
|
474
|
-
className?: string;
|
|
475
|
-
};
|
|
476
|
-
/**
|
|
477
|
-
* Standard Cbox top bar. Same shell across every app — keeps cross-app
|
|
478
|
-
* navigation (launcher, account, notifications) muscle-memory-stable.
|
|
479
|
-
*/
|
|
480
|
-
declare function TopBar({ brand, centre, rightCluster, showOrgSwitcher, className, }: Props$6): react_jsx_runtime.JSX.Element;
|
|
481
|
-
|
|
482
|
-
type AppLauncherProps = {
|
|
483
|
-
className?: string;
|
|
484
|
-
/**
|
|
485
|
-
* Called when the user clicks an app they're not entitled to. Use
|
|
486
|
-
* this to open an upgrade flow / Stripe checkout / Intercom message.
|
|
487
|
-
* If unset, locked tiles fall through to a static "Add to plan"
|
|
488
|
-
* affordance — the click is a no-op so we never silently ship the
|
|
489
|
-
* user to a broken paywall.
|
|
490
|
-
*/
|
|
491
|
-
onLockedAppClick?: (app: CboxAppLink) => void;
|
|
492
|
-
};
|
|
493
|
-
/**
|
|
494
|
-
* Cross-app launcher — the 9-dot button in the top bar.
|
|
495
|
-
*
|
|
496
|
-
* Renders the Cbox suite as a vertical list with status per app:
|
|
497
|
-
* - entitled apps → full-colour tile, click navigates with ?org=<slug>
|
|
498
|
-
* - locked apps → greyed out + lock badge, opens upgrade flow if the
|
|
499
|
-
* host app provides one (otherwise inert click)
|
|
500
|
-
* - coming-soon → greyed out + "soon" badge, never clickable
|
|
501
|
-
* - the current app → highlighted ring on its monogram tile
|
|
502
|
-
*
|
|
503
|
-
* Row layout (vs. the old 3-col grid) gives us room for descriptions
|
|
504
|
-
* and status badges, which makes the entitlement signal readable at a
|
|
505
|
-
* glance instead of needing a tooltip.
|
|
506
|
-
*/
|
|
507
|
-
declare function AppLauncher({ className, onLockedAppClick }: AppLauncherProps): react_jsx_runtime.JSX.Element | null;
|
|
508
|
-
|
|
509
732
|
type CboxAppCatalogProps = {
|
|
510
733
|
/**
|
|
511
734
|
* Same-origin URL the host serves the person's app catalog from (a proxy of Cbox ID's
|
|
@@ -568,126 +791,6 @@ type CboxServiceMarkProps = {
|
|
|
568
791
|
/** An app's own mark (its rail or brand icon), read from the catalog this browser last kept. */
|
|
569
792
|
declare function CboxServiceMark({ appKey, className, fallback }: CboxServiceMarkProps): react_jsx_runtime.JSX.Element;
|
|
570
793
|
|
|
571
|
-
type AppSwitcherProps = {
|
|
572
|
-
className?: string;
|
|
573
|
-
/**
|
|
574
|
-
* Called when the user clicks an app they're not entitled to. Use
|
|
575
|
-
* this to open an upgrade flow / Stripe checkout / Intercom message.
|
|
576
|
-
* If unset, locked rows fall through to a static "Add to plan"
|
|
577
|
-
* affordance — the click is a no-op so we never silently ship the
|
|
578
|
-
* user to a broken paywall.
|
|
579
|
-
*/
|
|
580
|
-
onLockedAppClick?: (app: CboxAppLink) => void;
|
|
581
|
-
};
|
|
582
|
-
/**
|
|
583
|
-
* Left-cluster app picker — the dropdown button that sits beside OrgSwitcher.
|
|
584
|
-
*
|
|
585
|
-
* Shows the current app's monogram + name as the trigger so both context
|
|
586
|
-
* dimensions (which app, which org) are immediately visible in the left
|
|
587
|
-
* cluster without needing to open anything.
|
|
588
|
-
*
|
|
589
|
-
* The dropdown preserves the full AppLauncher row richness: monogram tile
|
|
590
|
-
* with per-app accent, name, description, and entitlement badges. Entitled
|
|
591
|
-
* apps are grouped first; locked / coming-soon land in an "Available" section.
|
|
592
|
-
*
|
|
593
|
-
* Includes typeahead — auto-focus on open, filters name/description/key as
|
|
594
|
-
* the user types, arrow-key navigation, Enter to activate, Escape to close.
|
|
595
|
-
*
|
|
596
|
-
* Soft-reads via useCboxIdOptional — renders null when no provider is
|
|
597
|
-
* mounted above (admin shells, pre-auth pages).
|
|
598
|
-
*/
|
|
599
|
-
declare function AppSwitcher({ className, onLockedAppClick }: AppSwitcherProps): react_jsx_runtime.JSX.Element | null;
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Bell with unread-count badge + popover preview. Click opens a
|
|
603
|
-
* dropdown with the last 5 items inline (no navigation), each with
|
|
604
|
-
* an inline mark-read action and an optional deep-link to the page
|
|
605
|
-
* that originated the notification. "See all" at the bottom links
|
|
606
|
-
* to the central notifications service inbox — the only navigation
|
|
607
|
-
* away from the host app.
|
|
608
|
-
*
|
|
609
|
-
* Pattern matches Linear / GitHub / Stripe: glance + mark-read
|
|
610
|
-
* without leaving context; cross-app jump only when the user
|
|
611
|
-
* explicitly wants the full list.
|
|
612
|
-
*
|
|
613
|
-
* Renders nothing if the context is missing or notifications
|
|
614
|
-
* aren't configured (eg pre-auth pages).
|
|
615
|
-
*/
|
|
616
|
-
declare function NotificationsBell({ className }: {
|
|
617
|
-
className?: string;
|
|
618
|
-
}): react_jsx_runtime.JSX.Element | null;
|
|
619
|
-
|
|
620
|
-
type Props$5 = {
|
|
621
|
-
/**
|
|
622
|
-
* Optional renderer override for the trigger so apps can match
|
|
623
|
-
* their topbar style (filled button vs ghost vs icon-only).
|
|
624
|
-
*/
|
|
625
|
-
Trigger?: ComponentType<{
|
|
626
|
-
organization: CboxOrganization | null;
|
|
627
|
-
onClick: () => void;
|
|
628
|
-
open: boolean;
|
|
629
|
-
}>;
|
|
630
|
-
className?: string;
|
|
631
|
-
};
|
|
632
|
-
/**
|
|
633
|
-
* Dropdown that surfaces the user's orgs and dispatches the picked
|
|
634
|
-
* one through `onSwitchOrganization`. Reads everything else from
|
|
635
|
-
* CboxIdProvider so the same component works in id, cortex, atlas —
|
|
636
|
-
* no per-app data wiring.
|
|
637
|
-
*
|
|
638
|
-
* Includes typeahead — auto-focus on open, filters by name as the
|
|
639
|
-
* user types, arrow-key navigation, Enter to switch, Escape to close.
|
|
640
|
-
*/
|
|
641
|
-
declare function OrgSwitcher({ Trigger, className }: Props$5): react_jsx_runtime.JSX.Element;
|
|
642
|
-
|
|
643
|
-
type Props$4 = {
|
|
644
|
-
/** Click handler — typically dispatches the app's command-palette
|
|
645
|
-
* open shortcut. Apps that don't have a palette yet pass a no-op
|
|
646
|
-
* so the chrome stays visually consistent across the suite. */
|
|
647
|
-
onOpen?: () => void;
|
|
648
|
-
className?: string;
|
|
649
|
-
label?: string;
|
|
650
|
-
};
|
|
651
|
-
/**
|
|
652
|
-
* Topbar Search trigger — a visual-only command-palette button.
|
|
653
|
-
*
|
|
654
|
-
* Hosted in cbox-ui because every Cbox app's chrome must show the
|
|
655
|
-
* same search affordance in the same spot, with the same width and
|
|
656
|
-
* the same shortcut hint. Drift across apps means users see layout
|
|
657
|
-
* shifts when tabbing between id / webhooks / cortex; that's a UX
|
|
658
|
-
* tax we don't want to charge them.
|
|
659
|
-
*
|
|
660
|
-
* The actual palette stays per-app (commands differ); this primitive
|
|
661
|
-
* just renders the trigger and dispatches `onOpen`.
|
|
662
|
-
*/
|
|
663
|
-
declare function SearchTrigger({ onOpen, className, label }: Props$4): react_jsx_runtime.JSX.Element;
|
|
664
|
-
|
|
665
|
-
type Props$3 = {
|
|
666
|
-
/**
|
|
667
|
-
* App-specific menu items rendered above the standard
|
|
668
|
-
* "Manage account" / "Sign out" set. Use sparingly — the goal
|
|
669
|
-
* is consistency across apps.
|
|
670
|
-
*/
|
|
671
|
-
extras?: ReactNode;
|
|
672
|
-
placement?: 'bottom-end' | 'top-start';
|
|
673
|
-
className?: string;
|
|
674
|
-
/**
|
|
675
|
-
* The router's link for the account and organization rows, when they are pages of this
|
|
676
|
-
* app (an Inertia `Link` keeps the visit client-side). Default: a plain anchor, which is
|
|
677
|
-
* right when the rows deep-link into Cbox ID on another origin.
|
|
678
|
-
*/
|
|
679
|
-
LinkComponent?: LinkComponent;
|
|
680
|
-
};
|
|
681
|
-
/**
|
|
682
|
-
* User-menu dropdown. Always exposes:
|
|
683
|
-
* - Manage account ↗ (deep-link into id)
|
|
684
|
-
* - Team & billing ↗ (deep-link into id, current org scope)
|
|
685
|
-
* - Sign out
|
|
686
|
-
*
|
|
687
|
-
* The arrows signal cross-app navigation — id is canonical.
|
|
688
|
-
*/
|
|
689
|
-
declare function UserMenu({ extras, className, placement, LinkComponent: Link }: Props$3): react_jsx_runtime.JSX.Element;
|
|
690
|
-
|
|
691
794
|
/**
|
|
692
795
|
* Combobox — the canonical select replacement for the Cbox suite.
|
|
693
796
|
*
|
|
@@ -758,7 +861,7 @@ type ComboboxAvatar = {
|
|
|
758
861
|
accent?: string;
|
|
759
862
|
src?: string;
|
|
760
863
|
};
|
|
761
|
-
type LinkComp
|
|
864
|
+
type LinkComp = ComponentType<{
|
|
762
865
|
href: string;
|
|
763
866
|
prefetch?: boolean;
|
|
764
867
|
className?: string;
|
|
@@ -794,7 +897,7 @@ type CommonProps = {
|
|
|
794
897
|
* Framework Link adapter for navigation-mode items + footer link.
|
|
795
898
|
* If unset, navigation falls back to plain `<a>`.
|
|
796
899
|
*/
|
|
797
|
-
LinkComponent?: LinkComp
|
|
900
|
+
LinkComponent?: LinkComp;
|
|
798
901
|
/** ID for the trigger button (associate with a <Label htmlFor>). */
|
|
799
902
|
id?: string;
|
|
800
903
|
/** className for the outer wrapper. */
|
|
@@ -818,111 +921,6 @@ type NavModeProps = CommonProps & {
|
|
|
818
921
|
type ComboboxProps = ValueModeProps | NavModeProps;
|
|
819
922
|
declare function Combobox(props: ComboboxProps): react_jsx_runtime.JSX.Element;
|
|
820
923
|
|
|
821
|
-
/**
|
|
822
|
-
* ContextBar — the topbar breadcrumb-style context selector. One
|
|
823
|
-
* crumb per level of context (org / project / environment / branch /
|
|
824
|
-
* deployment). Each crumb renders as a chip (avatar + label +
|
|
825
|
-
* chevron) and opens a dropdown with the items at that level plus
|
|
826
|
-
* an optional "+ New X" footer.
|
|
827
|
-
*
|
|
828
|
-
* The pattern is the cloud-platform default — Vercel, Render, Forge,
|
|
829
|
-
* GitHub, Stripe, Cortex all use it. Topbar carries identity and
|
|
830
|
-
* context; sidebar carries navigation. The two never overlap.
|
|
831
|
-
*
|
|
832
|
-
* URL-driven by default — clicking a dropdown item navigates via the
|
|
833
|
-
* supplied `LinkComponent`. Apps that need a non-navigational select
|
|
834
|
-
* (post a form, mutate session state) pass `onSelect` instead.
|
|
835
|
-
*
|
|
836
|
-
* Separator between crumbs is a muted slash — same as Forge / Cortex.
|
|
837
|
-
*/
|
|
838
|
-
type ContextAvatar = {
|
|
839
|
-
/** 1–2 character monogram. Defaults to first letter of the label. */
|
|
840
|
-
initials?: string;
|
|
841
|
-
/**
|
|
842
|
-
* Hex / CSS colour applied as the avatar's bg. Falls back to the
|
|
843
|
-
* neutral chip when missing. Per-item override of the default.
|
|
844
|
-
*/
|
|
845
|
-
accent?: string;
|
|
846
|
-
/** Optional avatar image URL — overrides initials when set. */
|
|
847
|
-
src?: string;
|
|
848
|
-
};
|
|
849
|
-
type ContextItem = {
|
|
850
|
-
/** Stable identity for the item (slug, id). */
|
|
851
|
-
id: string;
|
|
852
|
-
/** Primary display label. */
|
|
853
|
-
label: string;
|
|
854
|
-
/** Optional secondary line — slug, role, env name. Mono-tracked. */
|
|
855
|
-
secondary?: string;
|
|
856
|
-
/** Avatar specification. Same shape as the crumb's own avatar. */
|
|
857
|
-
avatar?: ContextAvatar;
|
|
858
|
-
/** Navigation target — clicking the item navigates here. */
|
|
859
|
-
href?: string;
|
|
860
|
-
/** Mark the item as the active selection (gets a check on the right). */
|
|
861
|
-
current?: boolean;
|
|
862
|
-
/**
|
|
863
|
-
* Optional href to a settings page for this item. When set, a
|
|
864
|
-
* cogwheel button appears on the right of the row on hover/focus
|
|
865
|
-
* — clicking it navigates straight to settings without going
|
|
866
|
-
* through the item's normal selection. Cortex-style shortcut.
|
|
867
|
-
*/
|
|
868
|
-
settingsHref?: string;
|
|
869
|
-
/**
|
|
870
|
-
* Aria-label for the optional settings cogwheel. Defaults to
|
|
871
|
-
* `Settings for <label>`. Override when the label alone isn't
|
|
872
|
-
* enough context (eg multiple items with the same name).
|
|
873
|
-
*/
|
|
874
|
-
settingsAriaLabel?: string;
|
|
875
|
-
};
|
|
876
|
-
type ContextCrumb = {
|
|
877
|
-
/** Stable identity for the crumb (used as React key). */
|
|
878
|
-
id: string;
|
|
879
|
-
/** The chip's visible label — typically the active item's name. */
|
|
880
|
-
label: string;
|
|
881
|
-
/** The chip's avatar — typically the active item's avatar. */
|
|
882
|
-
avatar?: ContextAvatar;
|
|
883
|
-
/** Items shown in the dropdown. Empty array = chip with no menu. */
|
|
884
|
-
items: ContextItem[];
|
|
885
|
-
/**
|
|
886
|
-
* Optional footer link below the items — typically "+ New X" or
|
|
887
|
-
* "Manage Y". Renders with a + icon and an accent text colour.
|
|
888
|
-
*/
|
|
889
|
-
footerLink?: {
|
|
890
|
-
label: string;
|
|
891
|
-
href: string;
|
|
892
|
-
};
|
|
893
|
-
/**
|
|
894
|
-
* Override per-item navigation. When set, item clicks call this
|
|
895
|
-
* with the item's id instead of navigating to `item.href`. Useful
|
|
896
|
-
* for posting a form (eg an org switcher that POSTs to a server-side
|
|
897
|
-
* endpoint).
|
|
898
|
-
*/
|
|
899
|
-
onSelect?: (itemId: string) => void;
|
|
900
|
-
/** Optional aria-label for the chip's button (defaults to "Switch <label>"). */
|
|
901
|
-
ariaLabel?: string;
|
|
902
|
-
};
|
|
903
|
-
type LinkComp = ComponentType<{
|
|
904
|
-
href: string;
|
|
905
|
-
prefetch?: boolean;
|
|
906
|
-
className?: string;
|
|
907
|
-
children: ReactNode;
|
|
908
|
-
}>;
|
|
909
|
-
type Props$2 = {
|
|
910
|
-
crumbs: ContextCrumb[];
|
|
911
|
-
/**
|
|
912
|
-
* The framework's link component. Inertia consumers pass the
|
|
913
|
-
* Inertia Link; TanStack Router consumers pass their typed Link.
|
|
914
|
-
* Plain `<a>` is the fallback.
|
|
915
|
-
*/
|
|
916
|
-
LinkComponent?: LinkComp;
|
|
917
|
-
className?: string;
|
|
918
|
-
};
|
|
919
|
-
declare function ContextBar({ crumbs, LinkComponent, className, }: Props$2): react_jsx_runtime.JSX.Element | null;
|
|
920
|
-
declare function ContextAvatarChip({ avatar, fallbackLabel, size, }: {
|
|
921
|
-
avatar: ContextAvatar;
|
|
922
|
-
fallbackLabel: string;
|
|
923
|
-
size?: 'sm' | 'md';
|
|
924
|
-
}): react_jsx_runtime.JSX.Element;
|
|
925
|
-
|
|
926
924
|
/**
|
|
927
925
|
* Generic panel container — soft border, card surface, subtle shadow.
|
|
928
926
|
* The default building block for every section on a page.
|
|
@@ -990,6 +988,13 @@ type Props$1 = {
|
|
|
990
988
|
eyebrow?: ReactNode;
|
|
991
989
|
description?: ReactNode;
|
|
992
990
|
actions?: ReactNode;
|
|
991
|
+
/**
|
|
992
|
+
* Show the `?` beside the title that toggles the shell's Help column (spec §7.1). The page's
|
|
993
|
+
* help topic travels in `shell.help.topic`, set on the server per route (console-kit's
|
|
994
|
+
* `helpTopic`), so Help knows the topic on the first paint and for pages without a header.
|
|
995
|
+
* Ignored outside `CboxShell`.
|
|
996
|
+
*/
|
|
997
|
+
help?: boolean;
|
|
993
998
|
className?: string;
|
|
994
999
|
};
|
|
995
1000
|
/**
|
|
@@ -998,7 +1003,7 @@ type Props$1 = {
|
|
|
998
1003
|
* Cortex-style — no italics, no brackets — so it carries across many
|
|
999
1004
|
* sibling apps cleanly.
|
|
1000
1005
|
*/
|
|
1001
|
-
declare function PageHeader({ title, eyebrow, description, actions, className, }: Props$1): react_jsx_runtime.JSX.Element;
|
|
1006
|
+
declare function PageHeader({ title, eyebrow, description, actions, help, className, }: Props$1): react_jsx_runtime.JSX.Element;
|
|
1002
1007
|
|
|
1003
1008
|
/**
|
|
1004
1009
|
* Width policy for `<PageShell>` — the single horizontal-rhythm
|
|
@@ -1224,25 +1229,17 @@ declare function StatusPill({ children, tone, className, dot, }: StatusPillProps
|
|
|
1224
1229
|
* land.
|
|
1225
1230
|
*
|
|
1226
1231
|
* The criterion for accepting a new surface: "would it be useful
|
|
1227
|
-
* in *every* Cbox app?" Inbox yes.
|
|
1232
|
+
* in *every* Cbox app?" Inbox yes. "Webhook
|
|
1228
1233
|
* delivery details" no — that's a route inside webhooks, not a
|
|
1229
1234
|
* cross-app overlay.
|
|
1230
1235
|
*/
|
|
1231
1236
|
|
|
1232
|
-
|
|
1237
|
+
/** Search and Help are the shell's palette and Help column now; `inbox` stays for apps that use it. */
|
|
1238
|
+
type SurfaceId = 'inbox';
|
|
1233
1239
|
type SurfaceArgs = {
|
|
1234
1240
|
inbox: {
|
|
1235
1241
|
focusUnread?: boolean;
|
|
1236
1242
|
};
|
|
1237
|
-
search: {
|
|
1238
|
-
initialQuery?: string;
|
|
1239
|
-
};
|
|
1240
|
-
activity: {
|
|
1241
|
-
scope?: 'user' | 'org';
|
|
1242
|
-
};
|
|
1243
|
-
help: {
|
|
1244
|
-
topic?: string;
|
|
1245
|
-
};
|
|
1246
1243
|
};
|
|
1247
1244
|
/**
|
|
1248
1245
|
* Auth + transport plumbing the host injects. cbox-ui's surface
|
|
@@ -1258,7 +1255,6 @@ type Transport = {
|
|
|
1258
1255
|
*/
|
|
1259
1256
|
urls: Partial<{
|
|
1260
1257
|
notifications: string;
|
|
1261
|
-
search: string;
|
|
1262
1258
|
audit: string;
|
|
1263
1259
|
realtime: string;
|
|
1264
1260
|
}>;
|
|
@@ -1279,10 +1275,6 @@ type Transport = {
|
|
|
1279
1275
|
csrfToken?: () => string;
|
|
1280
1276
|
};
|
|
1281
1277
|
type SurfaceConfig = Partial<{
|
|
1282
|
-
search: {
|
|
1283
|
-
placeholder?: string;
|
|
1284
|
-
scopes?: string[];
|
|
1285
|
-
};
|
|
1286
1278
|
inbox: {};
|
|
1287
1279
|
}>;
|
|
1288
1280
|
/**
|
|
@@ -1338,7 +1330,7 @@ type CboxSurfacesProps = {
|
|
|
1338
1330
|
|
|
1339
1331
|
/**
|
|
1340
1332
|
* Mount the cbox-ui surface runtime once per app, alongside the
|
|
1341
|
-
* page tree. The host's chrome (bell
|
|
1333
|
+
* page tree. The host's chrome (the bell) reads
|
|
1342
1334
|
* `useCboxSurfaces()` to open surfaces; cbox-ui renders the
|
|
1343
1335
|
* active one as a modal/drawer over the page.
|
|
1344
1336
|
*
|
|
@@ -1355,7 +1347,7 @@ declare function CboxSurfaces({ transport, surfaces, config, children, }: CboxSu
|
|
|
1355
1347
|
declare function useCboxSurfaces(): SurfaceController;
|
|
1356
1348
|
/**
|
|
1357
1349
|
* Optional variant — returns `null` when no `<CboxSurfaces>` host is
|
|
1358
|
-
* mounted. Chrome controls (bell
|
|
1350
|
+
* mounted. Chrome controls (the bell) use this to
|
|
1359
1351
|
* degrade gracefully to cross-app navigation when the host hasn't
|
|
1360
1352
|
* opted into the surface runtime yet.
|
|
1361
1353
|
*/
|
|
@@ -1461,67 +1453,6 @@ declare function parseUrlSearch<S extends UrlSchema>(search: string, schema: S):
|
|
|
1461
1453
|
*/
|
|
1462
1454
|
declare function buildUrlSearch<S extends UrlSchema>(state: InferUrlState<S>, schema: S): string;
|
|
1463
1455
|
|
|
1464
|
-
type CboxTranslationValues = Record<string, string | number>;
|
|
1465
|
-
type CboxTranslator = (message: string, values?: CboxTranslationValues) => string;
|
|
1466
|
-
declare function interpolate(message: string, values?: CboxTranslationValues): string;
|
|
1467
|
-
/** Optional and additive: without a provider existing consumers retain English. */
|
|
1468
|
-
declare function CboxLocalizationProvider({ locale, translate, formatDate, children }: {
|
|
1469
|
-
locale: string;
|
|
1470
|
-
translate: CboxTranslator;
|
|
1471
|
-
formatDate?: (value: string) => string;
|
|
1472
|
-
children: ReactNode;
|
|
1473
|
-
}): react_jsx_runtime.JSX.Element;
|
|
1474
|
-
declare function useCboxLocalization(): {
|
|
1475
|
-
locale: string;
|
|
1476
|
-
t: CboxTranslator;
|
|
1477
|
-
formatDate: (value: string) => string;
|
|
1478
|
-
};
|
|
1479
|
-
|
|
1480
|
-
type CboxNavArea = CboxNavItem & {
|
|
1481
|
-
items?: CboxNavItem[];
|
|
1482
|
-
};
|
|
1483
|
-
type CboxWorkspaceShellProps = {
|
|
1484
|
-
appKey: string;
|
|
1485
|
-
brandSubmark: string;
|
|
1486
|
-
areas: CboxNavArea[];
|
|
1487
|
-
currentPath: string;
|
|
1488
|
-
LinkComponent: LinkComponent;
|
|
1489
|
-
context: ReactNode;
|
|
1490
|
-
tools: ReactNode;
|
|
1491
|
-
account: ReactNode;
|
|
1492
|
-
children: ReactNode;
|
|
1493
|
-
/** Where the brand row links. Default `/`. */
|
|
1494
|
-
brandHref?: string;
|
|
1495
|
-
/** `id` of the `<main>` landmark, so a host's skip link can target it. Default `main-content`. */
|
|
1496
|
-
mainId?: string;
|
|
1497
|
-
/**
|
|
1498
|
-
* Rail pinned open. Pass `pinned` + `onPinnedChange` to control it (the host persists the
|
|
1499
|
-
* preference, in a cookie or Cbox ID), or `defaultPinned` to seed the shell's own state.
|
|
1500
|
-
*/
|
|
1501
|
-
pinned?: boolean;
|
|
1502
|
-
defaultPinned?: boolean;
|
|
1503
|
-
onPinnedChange?: (pinned: boolean) => void;
|
|
1504
|
-
/** Contextual subnav collapsed to its strip. Controlled and uncontrolled as `pinned`. */
|
|
1505
|
-
collapsed?: boolean;
|
|
1506
|
-
defaultCollapsed?: boolean;
|
|
1507
|
-
onCollapsedChange?: (collapsed: boolean) => void;
|
|
1508
|
-
};
|
|
1509
|
-
/**
|
|
1510
|
-
* How well `href` matches `path`: the href's length when the path is the href or beneath it,
|
|
1511
|
-
* -1 otherwise. `/` matches only itself, so a home item never claims every page.
|
|
1512
|
-
*/
|
|
1513
|
-
declare function navMatchLength(path: string, href: string): number;
|
|
1514
|
-
/** The item whose href is the most specific match for `path`, or undefined. */
|
|
1515
|
-
declare function activeNavItem<T extends CboxNavItem>(path: string, items: readonly T[]): T | undefined;
|
|
1516
|
-
/**
|
|
1517
|
-
* The area `path` is in: the one holding the most specific match among its own href and its
|
|
1518
|
-
* items' hrefs. A first-match would put every page beneath an area at `/` (an overview, a
|
|
1519
|
-
* dashboard) under that area and never show another area's subnav.
|
|
1520
|
-
*/
|
|
1521
|
-
declare function activeNavArea<T extends CboxNavArea>(path: string, areas: readonly T[]): T | undefined;
|
|
1522
|
-
/** Two-tier workspace navigation. Route ownership and preference persistence stay with the host. */
|
|
1523
|
-
declare function CboxWorkspaceShell({ appKey, brandSubmark, areas, currentPath, LinkComponent: Link, context, tools, account, children, brandHref, mainId, pinned: pinnedProp, defaultPinned, onPinnedChange, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange }: CboxWorkspaceShellProps): react_jsx_runtime.JSX.Element;
|
|
1524
|
-
|
|
1525
1456
|
/** The chart tokens in order, for series that set their own colour. */
|
|
1526
1457
|
declare const CHART_PALETTE: string[];
|
|
1527
1458
|
/** A row's shape over the window, small: a line with a faint area, zero at the bottom. Decorative. */
|
|
@@ -1532,4 +1463,4 @@ declare function Sparkline({ values, color, width, height }: {
|
|
|
1532
1463
|
height?: number;
|
|
1533
1464
|
}): react_jsx_runtime.JSX.Element | null;
|
|
1534
1465
|
|
|
1535
|
-
export { AppContent,
|
|
1466
|
+
export { APP_HUES, AppContent, type AppKey, AppShell, CHART_PALETTE, CboxAppCatalog, type CboxAppCatalogProps, CboxAppIcon, type CboxAppIconProps, type CboxAppKey, type CboxAppLink, CboxBrand, type CboxBrandProps, type CboxIdContextValue, CboxIdProvider, CboxKnownApp, CboxLocalizationProvider, type CboxNotificationPreviewItem, type CboxNotificationsState, type CboxOrganization, CboxServiceMark, type CboxServiceMarkProps, CboxShell, type CboxShellProps, CboxSurfaces, type CboxSurfacesProps, type CboxTranslationValues, type CboxTranslator, type CboxUser, Combobox, type ComboboxAvatar, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type ContextItem, type ContextLevel, type ContextTone, DataPanel, EmptyState, Heading, type HelpArticle, type HelpState, type HelpStore, type InboxState, type InferUrlState, KeyValue, KeyValueList, type ListPage, type NavArea, type NavPage, PageHeader, type PageIntent, PageShell, type PageTabSpec, PageTabs, type PageTabsProps, type PageWidth, type PaletteAction, PanelBody, type RealtimeState, type RealtimeStatus, RowLink, type RowLinkProps, SHELL_ICONS, SectionHeader, type Shell, type ShellAccount, type Link as ShellActionLink, type ShellApp, type ShellBanner, type ShellCatalogState, type ShellHelp, type ShellIcon, type ShellLinkComponent, type ShellNavigate, type ShellNotifications, type ShellOption, type ShellPreferenceChange, type ShellPreferences, type ShellTheme, Sparkline, StatTile, StatusPill, type SupportUpdate, type SurfaceArgs, type SurfaceConfig, type SurfaceController, type SurfaceId, type Transport, type UrlField, type UrlSchema, applyTheme, buildUrlSearch, cn, contextTrail, createHelpStore, defineUrlSchema, environmentFor, hueFor, initialsOf, interpolate, pageIntent, parseListPage, parseShellCatalog, parseUrlSearch, settingsHref, switchPayload, themeBootScript, urlBoolean, urlEnum, urlNumber, urlString, urlStringArray, useCboxId, useCboxIdOptional, useCboxLocalization, useCboxSurfaces, useCboxSurfacesOptional, useKnownAppCatalog, useShellHelp, withQuery };
|