@marktiderman/genesis-ui 2.12.2 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +1 -0
- package/dist/{chunk-MLZEKXV2.js → chunk-5OFA2CQR.js} +5 -5
- package/dist/{chunk-MLZEKXV2.js.map → chunk-5OFA2CQR.js.map} +1 -1
- package/dist/chunk-D3U5SBLW.js +605 -0
- package/dist/chunk-D3U5SBLW.js.map +1 -0
- package/dist/{chunk-4CQHPWJD.js → chunk-ORCI5SVM.js} +3 -45
- package/dist/chunk-ORCI5SVM.js.map +1 -0
- package/dist/chunk-SURORBV7.js +85 -0
- package/dist/chunk-SURORBV7.js.map +1 -0
- package/dist/chunk-ZHCP2RZP.js +130 -0
- package/dist/chunk-ZHCP2RZP.js.map +1 -0
- package/dist/components/data/index.js +11 -11
- package/dist/components/layout/band.d.ts +92 -0
- package/dist/components/layout/band.js +5 -0
- package/dist/components/layout/band.js.map +1 -0
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/index.js +6 -5
- package/dist/components/patterns/index.js +3 -3
- package/dist/components/patterns/toggle-row.js +1 -1
- package/dist/components/resource/index.d.ts +234 -0
- package/dist/components/resource/index.js +21 -0
- package/dist/components/resource/index.js.map +1 -0
- package/dist/components/resource/rules.d.ts +74 -0
- package/dist/components/resource/rules.js +4 -0
- package/dist/components/resource/rules.js.map +1 -0
- package/dist/components/rich-text/rich-text-editor.js +2 -2
- package/dist/hooks/index.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +82 -54
- package/dist/index.js.map +1 -1
- package/package.json +18 -6
- package/dist/chunk-4CQHPWJD.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/resource/chip.tsx","../src/components/resource/ResourceHeader.tsx","../src/components/resource/ReadinessChip.tsx","../src/components/resource/ResponsesToolbar.tsx","../src/components/resource/HeadlineNumbers.tsx","../src/components/resource/SummaryCard.tsx","../src/components/resource/FollowUpList.tsx","../src/components/resource/ResourceSettingsPage.tsx","../src/components/resource/ShareDialog.tsx"],"names":["jsxs","jsx","Fragment","Check","TriangleAlert","useState"],"mappings":"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","file":"chunk-D3U5SBLW.js","sourcesContent":["import type { ReactNode } from \"react\";\nimport { Badge } from \"../ui/badge\";\nimport { StatusBadge } from \"../patterns/status-badge\";\nimport { cn } from \"../../utils\";\nimport type { ChipTone } from \"./status\";\n\n/** A small status chip in one of the resource workspace's tones (tinted, AA-safe Genesis badges). */\nexport function Chip({\n tone,\n icon,\n children,\n className,\n testID,\n}: {\n tone: ChipTone;\n icon?: ReactNode;\n children: ReactNode;\n className?: string | undefined;\n testID?: string | undefined;\n}) {\n const inner = (\n <>\n {icon ? <span className=\"mr-1 inline-flex [&_svg]:size-3\" aria-hidden>{icon}</span> : null}\n {children}\n </>\n );\n // Badge's destructive variant is a solid fill; the tinted red is StatusBadge's.\n if (tone === \"danger\") {\n return (\n <StatusBadge status=\"offTrack\" className={cn(\"font-normal\", className)} data-testid={testID}>\n {inner}\n </StatusBadge>\n );\n }\n return (\n <Badge variant={tone} className={cn(\"font-normal\", className)} data-testid={testID}>\n {inner}\n </Badge>\n );\n}\n","import type { ReactNode } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"../ui/breadcrumb\";\nimport { Button } from \"../ui/button\";\nimport { Separator } from \"../ui/separator\";\nimport { cn } from \"../../utils\";\nimport { Check, Eye, Loader2, Redo2, Rocket, Share2, TriangleAlert, Undo2 } from \"lucide-react\";\nimport { Chip } from \"./chip\";\nimport { SAVE_STATE_LABEL, type ChipTone, type SaveState } from \"./status\";\n\nexport interface ResourceHeaderProps {\n /** The title, shown once: as the heading and the breadcrumb's last part. */\n title: string;\n /** Shown when the title is empty. Default \"Untitled\". */\n untitled?: string | undefined;\n /**\n * The breadcrumb's parent link, e.g. `<Link to=\"/courses\">Courses</Link>`: one element, so\n * the host's router renders it.\n */\n parent?: ReactNode;\n /** The status chip, e.g. \"Live · version 3\" or \"Draft\" (forms-studio's formStatusChip makes a form's). */\n status?: { label: string; tone: ChipTone } | undefined;\n /** Where saving the draft stands; no chip when absent. */\n saveState?: SaveState | undefined;\n /** Undo and redo buttons, shown when given (for example the builder's history). */\n onUndo?: (() => void) | undefined;\n onRedo?: (() => void) | undefined;\n canUndo?: boolean | undefined;\n canRedo?: boolean | undefined;\n /** A Preview button. */\n onPreview?: (() => void) | undefined;\n /** A Share button (open a share dialog). */\n onShare?: (() => void) | undefined;\n /** The primary button: \"Publish\", or \"Publish changes\" once it is live. */\n publish?:\n | {\n onClick: () => void;\n label?: string | undefined;\n loading?: boolean | undefined;\n disabled?: boolean | undefined;\n }\n | undefined;\n /** Anything else for the right-hand side, before Preview (a Reload button, a menu). */\n actions?: ReactNode;\n className?: string | undefined;\n}\n\nconst SAVE_TONE: Record<SaveState, ChipTone> = {\n saved: \"muted\",\n saving: \"muted\",\n unsaved: \"muted\",\n failed: \"warning\",\n stopped: \"danger\",\n conflict: \"danger\",\n};\n\n/**\n * The header of a page that edits one publishable thing (a form, a course, a lesson, a\n * worksheet): the breadcrumb (\"Courses › name\"), the title once, its status and save-state\n * chips, and on the right undo and redo, Preview, Share and Publish. Every action is the\n * host's; a button shows only when its handler is given.\n */\nexport function ResourceHeader({\n title,\n untitled = \"Untitled\",\n parent,\n status,\n saveState,\n onUndo,\n onRedo,\n canUndo = true,\n canRedo = true,\n onPreview,\n onShare,\n publish,\n actions,\n className,\n}: ResourceHeaderProps) {\n const history = onUndo || onRedo;\n const name = title.trim() || untitled;\n return (\n <header\n data-slot=\"resource-header\"\n className={cn(\"flex flex-col gap-3 md:flex-row md:items-start md:justify-between\", className)}\n >\n <div className=\"min-w-0 flex-1 space-y-1\">\n {parent ? (\n <Breadcrumb>\n <BreadcrumbList className=\"text-xs\">\n {/* The host's own link, as is: BreadcrumbLink would wrap it in a second <a>. */}\n <BreadcrumbItem className=\"[&_a:hover]:text-foreground [&_a]:transition-colors\">{parent}</BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem className=\"min-w-0\">\n <BreadcrumbPage className=\"truncate\">{name}</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n ) : null}\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n <h1 className=\"min-w-0 break-words text-xl font-semibold tracking-tight sm:text-2xl\">{name}</h1>\n {status ? (\n <Chip tone={status.tone} testID=\"resource-status\">\n {status.label}\n </Chip>\n ) : null}\n {saveState ? (\n <span aria-live=\"polite\">\n <Chip\n tone={SAVE_TONE[saveState]}\n testID=\"resource-save-state\"\n icon={\n saveState === \"saved\" ? (\n <Check />\n ) : saveState === \"saving\" ? (\n <Loader2 className=\"animate-spin\" />\n ) : saveState === \"unsaved\" ? null : (\n <TriangleAlert />\n )\n }\n >\n {SAVE_STATE_LABEL[saveState]}\n </Chip>\n </span>\n ) : null}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {history ? (\n <>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Undo\"\n title=\"Undo\"\n disabled={!onUndo || !canUndo}\n onClick={onUndo}\n data-testid=\"resource-undo\"\n >\n <Undo2 className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Redo\"\n title=\"Redo\"\n disabled={!onRedo || !canRedo}\n onClick={onRedo}\n data-testid=\"resource-redo\"\n >\n <Redo2 className=\"size-4\" />\n </Button>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n </>\n ) : null}\n {actions}\n {onPreview ? (\n <Button variant=\"ghost\" startIcon={<Eye className=\"size-4\" />} onClick={onPreview} data-testid=\"resource-preview\">\n Preview\n </Button>\n ) : null}\n {onShare ? (\n <Button variant=\"outline\" startIcon={<Share2 className=\"size-4\" />} onClick={onShare} data-testid=\"resource-share\">\n Share\n </Button>\n ) : null}\n {publish ? (\n <Button\n startIcon={<Rocket className=\"size-4\" />}\n loading={publish.loading}\n disabled={publish.disabled}\n onClick={publish.onClick}\n data-testid=\"resource-publish\"\n >\n {publish.label ?? \"Publish\"}\n </Button>\n ) : null}\n </div>\n </header>\n );\n}\n","import { Check, CircleAlert, TriangleAlert } from \"lucide-react\";\nimport { Chip } from \"./chip\";\nimport { readinessChip, type Readiness, type ReadinessLabels } from \"./status\";\n\n/**\n * \"Ready to publish\", or how many problems to fix: for the trailing slot of a resource\n * page's row of tabs (genesis-ui's `<AppShellSubNavEnd>`). With `onClick` it is a button (open the checks).\n */\nexport function ReadinessChip({\n readiness,\n onClick,\n labels,\n className,\n}: {\n readiness: Readiness;\n /** The chip's words; the defaults are neutral (\"Nothing to publish yet\" when empty). */\n labels?: ReadinessLabels | undefined;\n onClick?: (() => void) | undefined;\n className?: string | undefined;\n}) {\n const { label, tone } = readinessChip(readiness, labels);\n const icon =\n readiness.state === \"ready\" ? <Check /> : readiness.state === \"problems\" ? <CircleAlert /> : readiness.state === \"warnings\" ? <TriangleAlert /> : null;\n const chip = (\n <Chip tone={tone} icon={icon} testID=\"readiness\" className={className}>\n {label}\n </Chip>\n );\n if (!onClick) return chip;\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {chip}\n </button>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { ToggleGroup, ToggleGroupItem } from \"../ui/toggle-group\";\nimport { cn } from \"../../utils\";\n\nexport type ResponsesView = \"summary\" | \"each\";\n\n/**\n * The Responses tab's toolbar: a Summary / Each response switch, the host's filters\n * (forms-studio's ResponsesFilters, or its own) and, on the right, its export actions\n * (open a Sheet, Download CSV). `labels` renames the switch, e.g. \"Each submission\".\n */\nexport function ResponsesToolbar({\n view,\n onViewChange,\n filters,\n actions,\n labels = {},\n className,\n}: {\n view: ResponsesView;\n onViewChange: (view: ResponsesView) => void;\n filters?: ReactNode;\n actions?: ReactNode;\n /** The switch's words. Defaults \"Summary\", \"Each response\" and \"Show responses as\". */\n labels?: { summary?: string | undefined; each?: string | undefined; group?: string | undefined } | undefined;\n className?: string | undefined;\n}) {\n return (\n <div\n data-slot=\"responses-toolbar\"\n className={cn(\"flex flex-col gap-2 lg:flex-row lg:items-start lg:justify-between\", className)}\n >\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <ToggleGroup\n type=\"single\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-9\"\n value={view}\n onValueChange={(v) => v && onViewChange(v as ResponsesView)}\n aria-label={labels.group ?? \"Show responses as\"}\n >\n <ToggleGroupItem value=\"summary\" className=\"h-9 px-3\" data-testid=\"responses-view-summary\">\n {labels.summary ?? \"Summary\"}\n </ToggleGroupItem>\n <ToggleGroupItem value=\"each\" className=\"h-9 px-3\" data-testid=\"responses-view-each\">\n {labels.each ?? \"Each response\"}\n </ToggleGroupItem>\n </ToggleGroup>\n {filters}\n </div>\n {actions ? <div className=\"flex shrink-0 flex-wrap items-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { cn } from \"../../utils\";\n\n/** One headline number: a label, the number, and a short line under it. */\nexport interface HeadlineNumber {\n key: string;\n label: string;\n value: ReactNode;\n detail?: ReactNode;\n /** The detail's colour: good news, bad news, a warning, or plain. Default plain. */\n tone?: \"positive\" | \"negative\" | \"warning\" | \"muted\" | undefined;\n}\n\nconst TONE: Record<NonNullable<HeadlineNumber[\"tone\"]>, string> = {\n positive: \"text-emerald-700 dark:text-emerald-300\",\n negative: \"text-red-700 dark:text-red-300\",\n warning: \"text-amber-800 dark:text-amber-200\",\n muted: \"text-muted-foreground\",\n};\n\n/** A row of headline numbers (KPI cards): two across on a phone, up to four on a wide screen. */\nexport function HeadlineNumbers({\n numbers,\n isLoading = false,\n className,\n}: {\n numbers: readonly HeadlineNumber[];\n isLoading?: boolean | undefined;\n className?: string | undefined;\n}) {\n if (isLoading) {\n return (\n <div className={cn(\"grid grid-cols-2 gap-3 lg:grid-cols-4\", className)}>\n {[0, 1, 2, 3].map((i) => (\n <Skeleton key={i} className=\"h-28 w-full rounded-lg\" />\n ))}\n </div>\n );\n }\n if (!numbers.length) return null;\n return (\n <dl\n data-slot=\"headline-numbers\"\n className={cn(\n \"grid grid-cols-2 gap-3\",\n numbers.length >= 4 ? \"lg:grid-cols-4\" : numbers.length === 3 ? \"lg:grid-cols-3\" : \"\",\n className,\n )}\n >\n {numbers.map((n) => (\n <div\n key={n.key}\n className=\"flex min-w-0 flex-col gap-1 rounded-lg border border-border bg-card p-4 text-card-foreground\"\n data-testid={`headline-${n.key}`}\n >\n <dt className=\"truncate text-sm text-muted-foreground\">{n.label}</dt>\n <dd className=\"text-2xl font-semibold tabular-nums tracking-tight sm:text-3xl\">{n.value}</dd>\n {n.detail ? <dd className={cn(\"text-xs\", TONE[n.tone ?? \"muted\"])}>{n.detail}</dd> : null}\n </div>\n ))}\n </dl>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\n/**\n * One card of a summary column: an icon and a title, a short line on the right (\"24\n * responses · average 4.1\"), then whatever summarises it (bars, quotes, a split bar).\n */\nexport function SummaryCard({\n icon,\n title,\n meta,\n children,\n className,\n testID,\n}: {\n icon?: ReactNode;\n title: string;\n meta?: ReactNode;\n children?: ReactNode;\n className?: string | undefined;\n testID?: string | undefined;\n}) {\n return (\n <section\n aria-label={title}\n data-testid={testID}\n data-slot=\"summary-card\"\n className={cn(\"flex flex-col gap-4 rounded-lg border border-border bg-card p-5 text-card-foreground\", className)}\n >\n <header className=\"flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1\">\n <h3 className=\"flex min-w-0 items-center gap-2 font-semibold\">\n {icon ? (\n <span className=\"shrink-0 text-muted-foreground [&_svg]:size-4\" aria-hidden>\n {icon}\n </span>\n ) : null}\n <span className=\"min-w-0 break-words\">{title}</span>\n </h3>\n {meta ? <span className=\"text-xs text-muted-foreground\">{meta}</span> : null}\n </header>\n {children}\n </section>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { cn } from \"../../utils\";\nimport { CircleCheck, Star, TriangleAlert } from \"lucide-react\";\nimport { Chip } from \"./chip\";\nimport type { ChipTone } from \"./status\";\n\n/** One item in the follow-up list (a response, a submission), as the host describes it. */\nexport interface FollowUpEntry {\n id: string;\n /** Who answered: a name, or \"Anonymous\". */\n name: string;\n /** A tag beside the name, e.g. \"Member\" or \"New lead\". */\n tag?: { label: string; tone?: ChipTone | undefined } | undefined;\n /** One line under the name: \"Today · 6:00 WOD · Leo\". */\n meta?: ReactNode;\n /** What they wrote; null shows `noComment`. */\n comment?: string | null | undefined;\n /** The low score, on its scale. */\n rating?: { value: number; max: number } | null | undefined;\n}\n\n/**\n * Responses that need a follow-up (the host decides which; forms-studio's needsFollowUp is\n * one rule), each with who answered, a tag, the day and context, their comment, its low\n * score and the host's actions (Reply, Mark handled). Handled items are the host's to leave out.\n */\nexport function FollowUpList({\n entries,\n actions,\n title = \"Needs a follow-up\",\n isLoading = false,\n empty = \"Nothing to follow up right now.\",\n noComment = \"No comment\",\n className,\n}: {\n entries: readonly FollowUpEntry[];\n /** Buttons for one entry. */\n actions?: ((entry: FollowUpEntry) => ReactNode) | undefined;\n title?: string | undefined;\n isLoading?: boolean | undefined;\n /** Said when the list is empty. */\n empty?: ReactNode;\n /** Said for an entry without a comment. Default \"No comment\". */\n noComment?: string | undefined;\n className?: string | undefined;\n}) {\n return (\n <section\n aria-label={title}\n data-testid=\"follow-up-list\"\n className={cn(\"flex flex-col gap-3 rounded-lg border border-border bg-card p-4 text-card-foreground\", className)}\n >\n <header className=\"flex items-center justify-between gap-2\">\n <h3 className=\"flex items-center gap-2 font-semibold\">\n <TriangleAlert className=\"size-4 text-amber-800 dark:text-amber-200\" aria-hidden />\n {title}\n </h3>\n {!isLoading ? (\n <span className=\"rounded-md bg-muted px-2 py-0.5 text-xs tabular-nums text-muted-foreground\">\n {entries.length}\n </span>\n ) : null}\n </header>\n {isLoading ? (\n <>\n <Skeleton className=\"h-24 w-full rounded-md\" />\n <Skeleton className=\"h-24 w-full rounded-md\" />\n </>\n ) : entries.length === 0 ? (\n <p className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <CircleCheck className=\"size-4 shrink-0\" aria-hidden />\n {empty}\n </p>\n ) : (\n <ul className=\"flex flex-col gap-3\">\n {entries.map((entry) => {\n const buttons = actions?.(entry);\n return (\n <li\n key={entry.id}\n className=\"flex flex-col gap-1.5 rounded-md border border-border p-3\"\n data-testid={`follow-up-${entry.id}`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <span className=\"break-words font-medium\">{entry.name}</span>\n {entry.tag ? <Chip tone={entry.tag.tone ?? \"muted\"}>{entry.tag.label}</Chip> : null}\n </p>\n {entry.rating ? (\n <span\n className=\"flex shrink-0 items-center gap-0.5 text-sm font-medium tabular-nums text-amber-800 dark:text-amber-200\"\n role=\"img\"\n aria-label={`Rated ${entry.rating.value} out of ${entry.rating.max}`}\n >\n {entry.rating.value}\n <Star className=\"size-3.5 fill-current\" aria-hidden />\n </span>\n ) : null}\n </div>\n {entry.meta ? <p className=\"text-xs text-muted-foreground\">{entry.meta}</p> : null}\n <p className={cn(\"line-clamp-3 break-words text-sm\", !entry.comment && \"text-muted-foreground\")}>\n {entry.comment || noComment}\n </p>\n {buttons ? <div className=\"mt-1 flex flex-wrap gap-2\">{buttons}</div> : null}\n </li>\n );\n })}\n </ul>\n )}\n </section>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\n/**\n * One group of settings as a card: an icon, a title and a sentence, then its rows\n * (genesis-ui `SettingsRow` and `ToggleRow`: a label, a one-sentence description and the\n * control), divided by lines. On a phone a row whose control isn't a switch puts the\n * control under its label, so wide controls (a link, a list of people) still fit.\n */\nexport function SettingsSection({\n id,\n icon,\n title,\n description,\n children,\n className,\n}: {\n /** The jump link's target. */\n id?: string | undefined;\n icon?: ReactNode;\n title: ReactNode;\n description?: ReactNode;\n children?: ReactNode;\n className?: string | undefined;\n}) {\n const headingId = id ? `${id}-title` : undefined;\n return (\n <section\n id={id}\n aria-labelledby={headingId}\n data-slot=\"settings-section\"\n className={cn(\"scroll-mt-6 rounded-lg border border-border bg-card text-card-foreground\", className)}\n >\n <header className=\"flex gap-3 border-b border-border px-5 py-4\">\n {icon ? (\n <span className=\"mt-0.5 text-primary [&_svg]:size-5\" aria-hidden>\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0\">\n <h2 id={headingId} className=\"font-semibold\">\n {title}\n </h2>\n {description ? <p className=\"text-sm text-muted-foreground\">{description}</p> : null}\n </div>\n </header>\n <div\n className={cn(\n \"divide-y divide-border\",\n // Rows: genesis-ui SettingsRow and ToggleRow, padded to the card.\n \"[&>*]:px-5 [&>[data-slot=settings-row]]:py-3.5\",\n \"[&>[data-slot=settings-row]:not(:has([role=switch]))]:max-sm:flex-col\",\n \"[&>[data-slot=settings-row]:not(:has([role=switch]))]:max-sm:items-stretch\",\n \"[&>[data-slot=settings-row]>div:last-child]:max-sm:flex-wrap\",\n )}\n >\n {children}\n </div>\n </section>\n );\n}\n\n/**\n * One section of a ResourceSettingsPage. (Named apart from the layout tier's\n * `SettingsPageSection`, which belongs to the whole-page `SettingsPage`.)\n */\nexport interface ResourceSettingsSection {\n id: string;\n title: string;\n icon?: ReactNode;\n description?: ReactNode;\n /** The rows. Absent: a jump link only, to `#id` elsewhere on the page (or `onSelect`). */\n content?: ReactNode;\n /** For a link-only section whose target has no id: scroll to it yourself. */\n onSelect?: (() => void) | undefined;\n}\n\n/**\n * Every setting of one thing (a form, a course, a worksheet) on one page: jump links on the left (\"On this page\", the one in\n * view marked), the sections as cards on the right. On a phone the links sit above the\n * sections as a row that scrolls sideways.\n *\n * Not genesis-ui's `SettingsPage`: that one is a whole page with its own title, and plain\n * sections; these settings sit under the resource's header, as cards with icons.\n */\nexport function ResourceSettingsPage({\n sections,\n navLabel = \"On this page\",\n className,\n}: {\n sections: readonly ResourceSettingsSection[];\n navLabel?: string | undefined;\n className?: string | undefined;\n}) {\n const [active, setActive] = useState(sections[0]?.id);\n const ids = sections.map((s) => s.id).join(\" \");\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n // The section in view is the last one whose top has passed the upper third of the\n // window (the first one before any has).\n let frame = 0;\n const update = () => {\n frame = 0;\n const line = window.innerHeight / 3;\n let current = sections[0]?.id;\n // One pass: the section past the line, and the last one on the page.\n let last: string | undefined;\n for (const s of sections) {\n const el = document.getElementById(s.id);\n if (!el) continue;\n last = s.id;\n if (el.getBoundingClientRect().top <= line) current = s.id;\n }\n // At the very bottom the last sections can't reach the line: the last one is in view.\n const bottom = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 2;\n if (bottom && last && window.scrollY > 0) current = last;\n setActive(current);\n };\n const onScroll = () => {\n if (!frame) frame = window.requestAnimationFrame(update);\n };\n update();\n window.addEventListener(\"scroll\", onScroll, { passive: true, capture: true });\n return () => {\n window.removeEventListener(\"scroll\", onScroll, { capture: true });\n if (frame) window.cancelAnimationFrame(frame);\n };\n }, [ids]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <div\n data-slot=\"resource-settings-page\"\n className={cn(\"grid grid-cols-[minmax(0,1fr)] gap-6 md:grid-cols-[12rem_minmax(0,1fr)] lg:gap-8\", className)}\n >\n <nav aria-label={navLabel} className=\"min-w-0 md:sticky md:top-4 md:self-start\">\n <p className=\"mb-2 hidden text-xs font-medium uppercase tracking-wide text-muted-foreground md:block\">\n {navLabel}\n </p>\n <ul className=\"-mx-1 flex gap-1 overflow-x-auto px-1 md:mx-0 md:flex-col md:overflow-visible md:px-0\">\n {sections.map((s) => (\n <li key={s.id} className=\"shrink-0\">\n <a\n href={`#${s.id}`}\n aria-current={active === s.id ? \"location\" : undefined}\n onClick={(e) => {\n setActive(s.id);\n if (s.content === undefined && s.onSelect) {\n e.preventDefault();\n s.onSelect();\n }\n }}\n className={cn(\n \"flex items-center gap-2 whitespace-nowrap rounded-md px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-4\",\n active === s.id && \"bg-muted font-medium text-foreground\",\n )}\n >\n {s.icon ? <span aria-hidden>{s.icon}</span> : null}\n {s.title}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n <div className=\"flex min-w-0 flex-col gap-5\">\n {sections\n .filter((s) => s.content !== undefined)\n .map((s) => (\n <SettingsSection key={s.id} id={s.id} icon={s.icon} title={s.title} description={s.description}>\n {s.content}\n </SettingsSection>\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useId, useState, type ReactNode } from \"react\";\nimport { Button } from \"../ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../ui/select\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../ui/tabs\";\nimport { Textarea } from \"../ui/textarea\";\nimport { toast } from \"../ui/sonner\";\nimport { Copy, ExternalLink, Printer } from \"lucide-react\";\nimport { embedSnippet, prefilledUrl, type PrefillChoice } from \"./share\";\n\nconst ANY = \"__any\";\n\nasync function copy(text: string, what: string) {\n try {\n await navigator.clipboard.writeText(text);\n toast.success(`${what} copied.`);\n } catch {\n toast.error(\"Couldn't copy. Select it and copy it instead.\");\n }\n}\n\nfunction CopyField({\n id,\n label,\n value,\n what,\n}: {\n id: string;\n label: string;\n value: string;\n what: string;\n}) {\n return (\n <div className=\"space-y-1.5\">\n <Label htmlFor={id}>{label}</Label>\n <div className=\"flex gap-2\">\n <Input id={id} readOnly value={value} onFocus={(e) => e.target.select()} />\n <Button\n variant=\"outline\"\n startIcon={<Copy className=\"size-4\" />}\n onClick={() => void copy(value, what)}\n >\n Copy\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Sharing one published page (a form, a course, a worksheet), as Google Forms' Send step:\n * its link with Copy, a QR code (and a printable poster when the host has one), an\n * `<iframe>` to embed it on a website, and a builder for prefilled links\n * (`?location=…&staff=…`, or whatever the host offers).\n * Generic: the host passes the link, how to draw a QR code, and the prefill choices.\n */\nexport function ShareDialog({\n open,\n onOpenChange,\n noun = \"page\",\n title = `Share your ${noun}`,\n description = \"Anyone with the link can open it.\",\n url,\n posterUrl,\n renderQr,\n name,\n prefill = [],\n prefillNote,\n defaultTab = \"link\",\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Default \"Share your {noun}\". */\n title?: string | undefined;\n /** Default \"Anyone with the link can open it.\" */\n description?: ReactNode;\n /** The public link; null while it is still loading. */\n url: string | null;\n /** A printable poster for a link (the base link, or a prefilled one), when the host has one. */\n posterUrl?: ((url: string, prefill: Record<string, string>) => string | null) | undefined;\n /** Draws a QR code for a link. */\n renderQr?: ((url: string) => ReactNode) | undefined;\n /** Its name, for the embed's accessible title. */\n name: string;\n /** What it is, in the default title and buttons: \"page\" (default), \"form\", \"course\". */\n noun?: string | undefined;\n /** The search params a prefilled link may set, each with its choices. None hides the builder. */\n prefill?: readonly PrefillChoice[] | undefined;\n /** Said under the prefilled-link builder (what a prefilled link does). */\n prefillNote?: ReactNode;\n /** The tab it opens on (each time it opens). Default \"link\". */\n defaultTab?: \"link\" | \"qr\" | \"embed\" | undefined;\n}) {\n const id = useId();\n const [values, setValues] = useState<Record<string, string>>({});\n const chosen = Object.fromEntries(Object.entries(values).filter(([, v]) => v && v !== ANY));\n const prefilled = url && Object.keys(chosen).length ? prefilledUrl(url, chosen) : null;\n const poster = url ? posterUrl?.(url, {}) : null;\n const prefilledPoster = prefilled && url ? posterUrl?.(url, chosen) : null;\n const usable = prefill.filter((p) => p.options.length > 0);\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[90dvh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n {!url ? (\n <p className=\"text-sm text-muted-foreground\">Loading the link…</p>\n ) : (\n <Tabs defaultValue={defaultTab === \"qr\" && !renderQr ? \"link\" : defaultTab}>\n <TabsList>\n <TabsTrigger value=\"link\">Link</TabsTrigger>\n {renderQr && <TabsTrigger value=\"qr\">QR code</TabsTrigger>}\n <TabsTrigger value=\"embed\">Embed</TabsTrigger>\n </TabsList>\n <TabsContent value=\"link\" className=\"space-y-5 pt-2\">\n <CopyField id={`${id}-link`} label=\"Link\" value={url} what=\"Link\" />\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n startIcon={<ExternalLink className=\"size-4\" />}\n >\n <a href={url} target=\"_blank\" rel=\"noreferrer\">\n Open the {noun}\n </a>\n </Button>\n {usable.length > 0 && (\n <div className=\"space-y-3 border-t border-border pt-4\">\n <div>\n <p className=\"text-sm font-medium\">Prefilled link</p>\n {prefillNote && <p className=\"text-sm text-muted-foreground\">{prefillNote}</p>}\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {usable.map((p) => (\n <Select\n key={p.key}\n value={values[p.key] ?? ANY}\n onValueChange={(v) => setValues((old) => ({ ...old, [p.key]: v }))}\n >\n <SelectTrigger className=\"min-w-40 flex-1\" aria-label={p.label}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ANY}>{p.anyLabel}</SelectItem>\n {p.options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ))}\n </div>\n {prefilled && (\n <>\n <CopyField\n id={`${id}-prefilled`}\n label=\"Prefilled link\"\n value={prefilled}\n what=\"Prefilled link\"\n />\n {prefilledPoster && (\n <Button\n asChild\n variant=\"outline\"\n startIcon={<Printer className=\"size-4\" />}\n >\n <a href={prefilledPoster} target=\"_blank\" rel=\"noreferrer\">\n Print a poster for this link\n </a>\n </Button>\n )}\n </>\n )}\n </div>\n )}\n </TabsContent>\n {renderQr && (\n <TabsContent value=\"qr\" className=\"space-y-4 pt-2\">\n <div className=\"mx-auto w-full max-w-56\">{renderQr(url)}</div>\n <p className=\"text-center text-sm text-muted-foreground\">\n Scan with a phone's camera to open the {noun}.\n </p>\n {poster && (\n <div className=\"flex justify-center\">\n <Button asChild variant=\"outline\" startIcon={<Printer className=\"size-4\" />}>\n <a href={poster} target=\"_blank\" rel=\"noreferrer\">\n Print a QR poster\n </a>\n </Button>\n </div>\n )}\n </TabsContent>\n )}\n <TabsContent value=\"embed\" className=\"space-y-3 pt-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor={`${id}-embed`}>Embed on your website</Label>\n <Textarea\n id={`${id}-embed`}\n readOnly\n rows={4}\n className=\"font-mono text-xs\"\n value={embedSnippet(url, name)}\n onFocus={(e) => e.target.select()}\n />\n </div>\n <Button\n variant=\"outline\"\n startIcon={<Copy className=\"size-4\" />}\n onClick={() => void copy(embedSnippet(url, name), \"Embed code\")}\n >\n Copy embed code\n </Button>\n </TabsContent>\n </Tabs>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n"]}
|
|
@@ -69,49 +69,7 @@ var Stack = React.forwardRef(
|
|
|
69
69
|
)
|
|
70
70
|
);
|
|
71
71
|
Stack.displayName = "Stack";
|
|
72
|
-
var containerVariants = cva("mx-auto w-full", {
|
|
73
|
-
variants: {
|
|
74
|
-
// A deliberately short list. Named widths are a shared decision — five
|
|
75
|
-
// of them means two pages can't be 4px apart for no reason, which is
|
|
76
|
-
// exactly what happens once `max-w-[1180px]` is on the table.
|
|
77
|
-
size: {
|
|
78
|
-
/** Forms, settings, single-column detail. */
|
|
79
|
-
sm: "max-w-3xl",
|
|
80
|
-
/** Standard content pages. */
|
|
81
|
-
md: "max-w-5xl",
|
|
82
|
-
/** Application pages — the default. */
|
|
83
|
-
lg: "max-w-7xl",
|
|
84
|
-
/** Dashboards and wide tables: gutters, no ceiling. */
|
|
85
|
-
full: "max-w-none",
|
|
86
|
-
/** Long-form reading, capped by character count rather than width. */
|
|
87
|
-
prose: "max-w-prose"
|
|
88
|
-
},
|
|
89
|
-
// The three steps are the design system's own page spacing token
|
|
90
|
-
// (`spacing.page` = 1rem / 1.5rem / 2rem) expressed as utilities.
|
|
91
|
-
gutter: {
|
|
92
|
-
true: "px-4 sm:px-6 lg:px-8",
|
|
93
|
-
false: "px-0"
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
defaultVariants: {
|
|
97
|
-
size: "lg",
|
|
98
|
-
gutter: true
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
var Container = React.forwardRef(
|
|
102
|
-
({ className, size, gutter, testID, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
103
|
-
"div",
|
|
104
|
-
{
|
|
105
|
-
ref,
|
|
106
|
-
"data-slot": "container",
|
|
107
|
-
"data-testid": testID,
|
|
108
|
-
className: cn(containerVariants({ size, gutter }), className),
|
|
109
|
-
...props
|
|
110
|
-
}
|
|
111
|
-
)
|
|
112
|
-
);
|
|
113
|
-
Container.displayName = "Container";
|
|
114
72
|
|
|
115
|
-
export {
|
|
116
|
-
//# sourceMappingURL=chunk-
|
|
117
|
-
//# sourceMappingURL=chunk-
|
|
73
|
+
export { Stack, stackVariants };
|
|
74
|
+
//# sourceMappingURL=chunk-ORCI5SVM.js.map
|
|
75
|
+
//# sourceMappingURL=chunk-ORCI5SVM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/stack.tsx"],"names":[],"mappings":";;;;;;AAKA,IAAM,aAAA,GAAgB,IAAI,MAAA,EAAQ;AAAA,EAChC,QAAA,EAAU;AAAA,IACR,SAAA,EAAW;AAAA,MACT,GAAA,EAAK,UAAA;AAAA,MACL,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,GAAA,EAAK,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWL,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,aAAA;AAAA,MACP,MAAA,EAAQ,cAAA;AAAA,MACR,GAAA,EAAK,WAAA;AAAA,MACL,OAAA,EAAS;AAAA,KACX;AAAA,IACA,OAAA,EAAS;AAAA,MACP,KAAA,EAAO,eAAA;AAAA,MACP,MAAA,EAAQ,gBAAA;AAAA,MACR,GAAA,EAAK,aAAA;AAAA,MACL,OAAA,EAAS,iBAAA;AAAA,MACT,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,WAAA;AAAA;AAAA;AAAA;AAAA,MAIN,KAAA,EAAO;AAAA;AACT,GACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAA,EAAiB;AAAA,IACf,SAAA,EAAW,QAAA;AAAA,IACX,GAAA,EAAK,IAAA;AAAA,IACL,IAAA,EAAM;AAAA;AAEV,CAAC;AA6CM,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACzB,CACE,EAAE,SAAA,EAAW,SAAA,EAAW,GAAA,EAAK,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,MAAA,EAAQ,GAAG,KAAA,EAAM,EACpE,GAAA,qBAEA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,OAAA;AAAA,MACV,aAAA,EAAa,MAAA;AAAA,MACb,SAAA,EAAW,EAAA;AAAA,QACT,cAAc,EAAE,SAAA,EAAW,KAAK,KAAA,EAAO,OAAA,EAAS,MAAM,CAAA;AAAA,QACtD;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA;AAGV;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-ORCI5SVM.js","sourcesContent":["import * as React from \"react\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { cn } from \"../../utils\";\nimport { GAP_CLASSES } from \"./spacing\";\n\nconst stackVariants = cva(\"flex\", {\n variants: {\n direction: {\n row: \"flex-row\",\n column: \"flex-col\",\n },\n gap: GAP_CLASSES,\n // Exactly `@marktiderman/genesis-ui-native`'s `FlexAlign` / `FlexJustify`\n // — see `./spacing` for why the two surfaces share one vocabulary.\n // Web flexbox also supports `baseline` and `space-evenly`, and an\n // earlier draft offered both; they are deliberately NOT here, because\n // native's Yoga vocabulary has neither, so a spec written against them\n // could not be applied to the native surface. Since `align`/`justify`\n // emit nothing when unset, `className=\"items-baseline\"` reaches them\n // with no class to fight. Widening is additive and can happen later on\n // BOTH surfaces at once; shipping them here first and withdrawing them\n // to restore parity would be a breaking change.\n align: {\n start: \"items-start\",\n center: \"items-center\",\n end: \"items-end\",\n stretch: \"items-stretch\",\n },\n justify: {\n start: \"justify-start\",\n center: \"justify-center\",\n end: \"justify-end\",\n between: \"justify-between\",\n around: \"justify-around\",\n },\n wrap: {\n true: \"flex-wrap\",\n // Empty, not `flex-nowrap`: nowrap is already flexbox's initial value,\n // so emitting it would only add noise. Same reasoning as the\n // undefaulted `align`/`justify` below.\n false: \"\",\n },\n },\n // `align` and `justify` have NO default on purpose. Defaulting them would\n // emit `items-stretch`/`justify-start` on every Stack ever rendered — the\n // browser's own initial values — which is noise in the DOM and, worse,\n // beats a consumer's `className` at equal specificity for anyone not\n // going through `cn()`. Unset means \"whatever flexbox already does\".\n defaultVariants: {\n direction: \"column\",\n gap: \"md\",\n wrap: false,\n },\n});\n\nexport interface StackProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof stackVariants> {\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/**\n * Stack — one-dimensional flow. The single most-repeated shape in any\n * application: a run of things in a line, evenly spaced.\n *\n * It replaces the `flex flex-col gap-4` / `flex items-center gap-2` strings\n * that otherwise get retyped in every file, and it is the reason `gap`\n * stays on the shared `SpaceToken` scale (see `./spacing`) instead of\n * drifting per page.\n *\n * ```tsx\n * <Stack gap=\"lg\">\n * <Card />\n * <Card />\n * </Stack>\n *\n * <Stack direction=\"row\" align=\"center\" justify=\"between\" gap=\"sm\">\n * <h2>Members</h2>\n * <Button>Invite</Button>\n * </Stack>\n * ```\n *\n * Deliberately NOT here: responsive per-breakpoint directions. A layout\n * that changes axis at a breakpoint is a `Split`, which owns that idea and\n * names the breakpoint explicitly.\n *\n * Note for consumers of both surfaces: `@marktiderman/genesis-ui-native`\n * splits this shape into two components, `Stack` (column) and `Inline`\n * (row). On web they are one component with a `direction` prop, which is\n * the established web idiom. The `gap` / `align` / `justify` vocabulary is\n * identical either way — deliberately, and enforced by a test that reads\n * the native definitions directly — so a spec written once still reads the\n * same on both. That means the web unions are the SHARED vocabulary, not\n * everything web flexbox can do; see the note on `align` below.\n *\n * @stability Beta\n */\nexport const Stack = React.forwardRef<HTMLDivElement, StackProps>(\n (\n { className, direction, gap, align, justify, wrap, testID, ...props },\n ref\n ) => (\n <div\n ref={ref}\n data-slot=\"stack\"\n data-testid={testID}\n className={cn(\n stackVariants({ direction, gap, align, justify, wrap }),\n className\n )}\n {...props}\n />\n )\n);\nStack.displayName = \"Stack\";\n\nexport { stackVariants };\n"]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// src/components/resource/status.ts
|
|
2
|
+
var SAVE_STATE_LABEL = {
|
|
3
|
+
saved: "Changes saved",
|
|
4
|
+
saving: "Saving\u2026",
|
|
5
|
+
unsaved: "Unsaved changes",
|
|
6
|
+
failed: "Couldn't save; trying again",
|
|
7
|
+
stopped: "Couldn't save",
|
|
8
|
+
conflict: "Changed elsewhere; reload"
|
|
9
|
+
};
|
|
10
|
+
function readinessOf(findings, options = {}) {
|
|
11
|
+
const { emptyCode, pending } = options;
|
|
12
|
+
let errors = 0;
|
|
13
|
+
let warnings = 0;
|
|
14
|
+
for (const f of findings) {
|
|
15
|
+
if (emptyCode !== void 0 && f.code === emptyCode) return { state: "empty", count: 0 };
|
|
16
|
+
if (f.level === "error") errors++;
|
|
17
|
+
else if (f.level === "warning") warnings++;
|
|
18
|
+
}
|
|
19
|
+
if (errors) return { state: "problems", count: errors };
|
|
20
|
+
if (pending) return { state: "pending", count: 0 };
|
|
21
|
+
if (warnings) return { state: "warnings", count: warnings };
|
|
22
|
+
return { state: "ready", count: 0 };
|
|
23
|
+
}
|
|
24
|
+
function readinessChip(readiness, labels = {}) {
|
|
25
|
+
switch (readiness.state) {
|
|
26
|
+
case "ready":
|
|
27
|
+
return { label: labels.ready ?? "Ready to publish", tone: "success" };
|
|
28
|
+
case "empty":
|
|
29
|
+
return { label: labels.empty ?? "Nothing to publish yet", tone: "muted" };
|
|
30
|
+
case "pending":
|
|
31
|
+
return { label: labels.pending ?? "In progress", tone: "muted" };
|
|
32
|
+
case "problems":
|
|
33
|
+
return {
|
|
34
|
+
label: labels.problems?.(readiness.count) ?? `${readiness.count} ${readiness.count === 1 ? "problem" : "problems"} to fix`,
|
|
35
|
+
tone: "danger"
|
|
36
|
+
};
|
|
37
|
+
case "warnings":
|
|
38
|
+
return { label: labels.warnings?.(readiness.count) ?? `${readiness.count} to check`, tone: "warning" };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/components/resource/days.ts
|
|
43
|
+
var MONTH_DAY = new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", timeZone: "UTC" });
|
|
44
|
+
var MONTH_DAY_YEAR = new Intl.DateTimeFormat("en-US", {
|
|
45
|
+
month: "short",
|
|
46
|
+
day: "numeric",
|
|
47
|
+
year: "numeric",
|
|
48
|
+
timeZone: "UTC"
|
|
49
|
+
});
|
|
50
|
+
function dayLabel(day, today) {
|
|
51
|
+
const t = Date.parse(`${day}T00:00:00Z`);
|
|
52
|
+
if (Number.isNaN(t)) return day;
|
|
53
|
+
if (today) {
|
|
54
|
+
const diff = Math.round((Date.parse(`${today}T00:00:00Z`) - t) / 864e5);
|
|
55
|
+
if (diff === 0) return "Today";
|
|
56
|
+
if (diff === 1) return "Yesterday";
|
|
57
|
+
if (day.slice(0, 4) !== today.slice(0, 4)) return MONTH_DAY_YEAR.format(t);
|
|
58
|
+
}
|
|
59
|
+
return MONTH_DAY.format(t);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/components/resource/share.ts
|
|
63
|
+
var RELATIVE_BASE = "http://relative.invalid";
|
|
64
|
+
function prefilledUrl(url, values) {
|
|
65
|
+
let absolute = true;
|
|
66
|
+
let u;
|
|
67
|
+
try {
|
|
68
|
+
u = new URL(url);
|
|
69
|
+
} catch {
|
|
70
|
+
absolute = false;
|
|
71
|
+
u = new URL(url, RELATIVE_BASE);
|
|
72
|
+
}
|
|
73
|
+
for (const [k, v] of Object.entries(values)) if (v) u.searchParams.set(k, v);
|
|
74
|
+
if (absolute) return u.toString();
|
|
75
|
+
const path = url.startsWith("/") ? u.pathname : u.pathname.replace(/^\//, "");
|
|
76
|
+
return `${path}${u.search}${u.hash}`;
|
|
77
|
+
}
|
|
78
|
+
var attr = (s) => s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
79
|
+
function embedSnippet(url, title) {
|
|
80
|
+
return `<iframe src="${attr(url)}" title="${attr(title)}" width="100%" height="720" style="border:0;max-width:100%" loading="lazy"></iframe>`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { SAVE_STATE_LABEL, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf };
|
|
84
|
+
//# sourceMappingURL=chunk-SURORBV7.js.map
|
|
85
|
+
//# sourceMappingURL=chunk-SURORBV7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/resource/status.ts","../src/components/resource/days.ts","../src/components/resource/share.ts"],"names":[],"mappings":"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","file":"chunk-SURORBV7.js","sourcesContent":["// Words for a resource page's chips (save state, readiness). Pure: no React, safe on a\n// server. Not about any one kind of resource: forms, courses, lessons and worksheets use\n// the same page pattern.\n\n/** Where the host's draft saving stands. */\nexport type SaveState = \"saved\" | \"saving\" | \"unsaved\" | \"failed\" | \"stopped\" | \"conflict\";\n\nexport const SAVE_STATE_LABEL: Record<SaveState, string> = {\n saved: \"Changes saved\",\n saving: \"Saving…\",\n unsaved: \"Unsaved changes\",\n failed: \"Couldn't save; trying again\",\n stopped: \"Couldn't save\",\n conflict: \"Changed elsewhere; reload\",\n};\n\n/** A chip's colour: the tinted, AA-safe Genesis badge tones. */\nexport type ChipTone = \"success\" | \"warning\" | \"danger\" | \"info\" | \"muted\";\n\n/** Whether something can be published, from an editor's checks. */\nexport interface Readiness {\n state: \"ready\" | \"problems\" | \"warnings\" | \"empty\" | \"pending\";\n /** Problems or warnings to look at (0 when ready, empty or pending). */\n count: number;\n}\n\n/** One of an editor's findings, as readinessOf reads it. */\nexport interface ReadinessFinding {\n level: \"error\" | \"warning\" | \"info\";\n code?: string | undefined;\n}\n\nexport interface ReadinessOptions {\n /** Errors are held back while something new is being written: \"pending\", not \"problems\". */\n pending?: boolean | undefined;\n /**\n * The finding code that means \"nothing to publish yet\" (for example a form builder's\n * `no-questions`): it makes the result \"empty\", not broken. None by default.\n */\n emptyCode?: string | undefined;\n}\n\n/**\n * Readiness from an editor's findings (any list of `{ level, code? }`): errors block\n * publishing, warnings ask for a look. One pass over the findings.\n */\nexport function readinessOf(\n findings: readonly ReadinessFinding[],\n options: ReadinessOptions = {},\n): Readiness {\n const { emptyCode, pending } = options;\n let errors = 0;\n let warnings = 0;\n for (const f of findings) {\n if (emptyCode !== undefined && f.code === emptyCode) return { state: \"empty\", count: 0 };\n if (f.level === \"error\") errors++;\n else if (f.level === \"warning\") warnings++;\n }\n if (errors) return { state: \"problems\", count: errors };\n if (pending) return { state: \"pending\", count: 0 };\n if (warnings) return { state: \"warnings\", count: warnings };\n return { state: \"ready\", count: 0 };\n}\n\n/** The readiness chip's words, each optional; the defaults are resource-neutral. */\nexport interface ReadinessLabels {\n /** Default \"Ready to publish\". */\n ready?: string | undefined;\n /** When there is nothing yet. Default \"Nothing to publish yet\"; a form says \"Add a question\". */\n empty?: string | undefined;\n /** Default \"In progress\". */\n pending?: string | undefined;\n /** Default \"1 problem to fix\" / \"3 problems to fix\". */\n problems?: ((count: number) => string) | undefined;\n /** Default \"2 to check\". */\n warnings?: ((count: number) => string) | undefined;\n}\n\n/** The readiness chip's label and tone. */\nexport function readinessChip(\n readiness: Readiness,\n labels: ReadinessLabels = {},\n): { label: string; tone: ChipTone } {\n switch (readiness.state) {\n case \"ready\":\n return { label: labels.ready ?? \"Ready to publish\", tone: \"success\" };\n case \"empty\":\n return { label: labels.empty ?? \"Nothing to publish yet\", tone: \"muted\" };\n case \"pending\":\n return { label: labels.pending ?? \"In progress\", tone: \"muted\" };\n case \"problems\":\n return {\n label:\n labels.problems?.(readiness.count) ??\n `${readiness.count} ${readiness.count === 1 ? \"problem\" : \"problems\"} to fix`,\n tone: \"danger\",\n };\n case \"warnings\":\n return { label: labels.warnings?.(readiness.count) ?? `${readiness.count} to check`, tone: \"warning\" };\n }\n}\n","// A day (YYYY-MM-DD) in plain words. Pure.\n\nconst MONTH_DAY = new Intl.DateTimeFormat(\"en-US\", { month: \"short\", day: \"numeric\", timeZone: \"UTC\" });\nconst MONTH_DAY_YEAR = new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n timeZone: \"UTC\",\n});\n\n/** A day (YYYY-MM-DD) in words, given today on the same clock: \"Today\", \"Yesterday\", \"Oct 21\", \"Oct 21, 2025\". */\nexport function dayLabel(day: string, today?: string): string {\n const t = Date.parse(`${day}T00:00:00Z`);\n if (Number.isNaN(t)) return day;\n if (today) {\n const diff = Math.round((Date.parse(`${today}T00:00:00Z`) - t) / 86_400_000);\n if (diff === 0) return \"Today\";\n if (diff === 1) return \"Yesterday\";\n if (day.slice(0, 4) !== today.slice(0, 4)) return MONTH_DAY_YEAR.format(t);\n }\n return MONTH_DAY.format(t);\n}\n","// Sharing a published page (ShareDialog): prefilled links and the embed snippet. Pure.\n\n/** One search param a prefilled link may set, and the values staff pick from. */\nexport interface PrefillChoice {\n key: string;\n /** The picker's accessible name, e.g. \"Location\". */\n label: string;\n /** The picker's \"leave it out\" choice, e.g. \"Any location\". */\n anyLabel: string;\n options: readonly { value: string; label: string }[];\n}\n\n// Resolves a relative link without inventing an origin for it.\nconst RELATIVE_BASE = \"http://relative.invalid\";\n\n/**\n * `url` with `values` set as search params (empty values left out), keeping what it has.\n * An absolute link stays absolute; a relative one (`/f/a?x=1`) stays relative, so it never\n * throws while a page is still working out its origin.\n */\nexport function prefilledUrl(url: string, values: Record<string, string | undefined>): string {\n let absolute = true;\n let u: URL;\n try {\n u = new URL(url);\n } catch {\n absolute = false;\n u = new URL(url, RELATIVE_BASE);\n }\n for (const [k, v] of Object.entries(values)) if (v) u.searchParams.set(k, v);\n if (absolute) return u.toString();\n const path = url.startsWith(\"/\") ? u.pathname : u.pathname.replace(/^\\//, \"\");\n return `${path}${u.search}${u.hash}`;\n}\n\nconst attr = (s: string) =>\n s.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n\n/** An `<iframe>` that shows the page on another website, full width. */\nexport function embedSnippet(url: string, title: string): string {\n return `<iframe src=\"${attr(url)}\" title=\"${attr(title)}\" width=\"100%\" height=\"720\" style=\"border:0;max-width:100%\" loading=\"lazy\"></iframe>`;\n}\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { cn } from './chunk-NZ5WBA4R.js';
|
|
2
|
+
import * as React2 from 'react';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var containerVariants = cva("mx-auto w-full", {
|
|
7
|
+
variants: {
|
|
8
|
+
// A deliberately short list. Named widths are a shared decision — five
|
|
9
|
+
// of them means two pages can't be 4px apart for no reason, which is
|
|
10
|
+
// exactly what happens once `max-w-[1180px]` is on the table.
|
|
11
|
+
size: {
|
|
12
|
+
/** Forms, settings, single-column detail. */
|
|
13
|
+
sm: "max-w-3xl",
|
|
14
|
+
/** Standard content pages. */
|
|
15
|
+
md: "max-w-5xl",
|
|
16
|
+
/** Application pages — the default. */
|
|
17
|
+
lg: "max-w-7xl",
|
|
18
|
+
/** Dashboards and wide tables: gutters, no ceiling. */
|
|
19
|
+
full: "max-w-none",
|
|
20
|
+
/** Long-form reading, capped by character count rather than width. */
|
|
21
|
+
prose: "max-w-prose"
|
|
22
|
+
},
|
|
23
|
+
// The three steps are the design system's own page spacing token
|
|
24
|
+
// (`spacing.page` = 1rem / 1.5rem / 2rem) expressed as utilities.
|
|
25
|
+
gutter: {
|
|
26
|
+
true: "px-4 sm:px-6 lg:px-8",
|
|
27
|
+
false: "px-0"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
size: "lg",
|
|
32
|
+
gutter: true
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
var Container = React2.forwardRef(
|
|
36
|
+
({ className, size, gutter, testID, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
37
|
+
"div",
|
|
38
|
+
{
|
|
39
|
+
ref,
|
|
40
|
+
"data-slot": "container",
|
|
41
|
+
"data-testid": testID,
|
|
42
|
+
className: cn(containerVariants({ size, gutter }), className),
|
|
43
|
+
...props
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
Container.displayName = "Container";
|
|
48
|
+
var bandVariants = cva("relative w-full", {
|
|
49
|
+
variants: {
|
|
50
|
+
surface: {
|
|
51
|
+
base: "bg-background text-foreground",
|
|
52
|
+
muted: "bg-muted text-foreground",
|
|
53
|
+
accent: "bg-primary text-primary-foreground",
|
|
54
|
+
inverse: "bg-foreground text-background"
|
|
55
|
+
},
|
|
56
|
+
// Vertical rhythm, mobile first: a band breathes more on a wide screen.
|
|
57
|
+
spacing: {
|
|
58
|
+
none: "py-0",
|
|
59
|
+
sm: "py-8 sm:py-10",
|
|
60
|
+
md: "py-12 sm:py-16 lg:py-20",
|
|
61
|
+
lg: "py-16 sm:py-24 lg:py-32"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
defaultVariants: {
|
|
65
|
+
surface: "base",
|
|
66
|
+
spacing: "md"
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
var Band = React2.forwardRef(
|
|
70
|
+
({ as: Tag = "section", surface, spacing, width = "lg", className, innerClassName, testID, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
71
|
+
Tag,
|
|
72
|
+
{
|
|
73
|
+
ref,
|
|
74
|
+
"data-slot": "band",
|
|
75
|
+
"data-surface": surface ?? "base",
|
|
76
|
+
"data-testid": testID,
|
|
77
|
+
className: cn(bandVariants({ surface, spacing }), className),
|
|
78
|
+
...props,
|
|
79
|
+
children: /* @__PURE__ */ jsx("div", { "data-slot": "band-inner", className: cn(containerVariants({ size: width, gutter: true }), innerClassName), children })
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
Band.displayName = "Band";
|
|
84
|
+
var displayVariants = cva("font-display font-bold tracking-tight text-balance", {
|
|
85
|
+
variants: {
|
|
86
|
+
size: {
|
|
87
|
+
/** A hero headline. */
|
|
88
|
+
xl: "text-4xl leading-[1.1] sm:text-5xl lg:text-6xl",
|
|
89
|
+
/** A section headline. */
|
|
90
|
+
lg: "text-3xl leading-tight sm:text-4xl",
|
|
91
|
+
/** A card or column title in a band. */
|
|
92
|
+
md: "text-2xl leading-snug sm:text-3xl",
|
|
93
|
+
/** A small title, such as a pricing tier's name. */
|
|
94
|
+
sm: "text-xl leading-snug"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
defaultVariants: {
|
|
98
|
+
size: "lg"
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
var Display = React2.forwardRef(
|
|
102
|
+
({ as: Tag = "h2", size, className, testID, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
103
|
+
Tag,
|
|
104
|
+
{
|
|
105
|
+
ref,
|
|
106
|
+
"data-slot": "display",
|
|
107
|
+
"data-testid": testID,
|
|
108
|
+
className: cn(displayVariants({ size }), className),
|
|
109
|
+
...props
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
Display.displayName = "Display";
|
|
114
|
+
var leadVariants = cva("text-lg leading-relaxed sm:text-xl text-pretty", {
|
|
115
|
+
variants: {
|
|
116
|
+
tone: {
|
|
117
|
+
muted: "text-muted-foreground",
|
|
118
|
+
inherit: "text-current"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
defaultVariants: { tone: "muted" }
|
|
122
|
+
});
|
|
123
|
+
var BandLead = React2.forwardRef(
|
|
124
|
+
({ tone, className, testID, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, "data-slot": "band-lead", "data-testid": testID, className: cn(leadVariants({ tone }), className), ...props })
|
|
125
|
+
);
|
|
126
|
+
BandLead.displayName = "BandLead";
|
|
127
|
+
|
|
128
|
+
export { Band, BandLead, Container, Display, bandVariants, containerVariants, displayVariants, leadVariants };
|
|
129
|
+
//# sourceMappingURL=chunk-ZHCP2RZP.js.map
|
|
130
|
+
//# sourceMappingURL=chunk-ZHCP2RZP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/container.tsx","../src/components/layout/band.tsx"],"names":["React","cva","jsx"],"mappings":"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","file":"chunk-ZHCP2RZP.js","sourcesContent":["import * as React from \"react\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { cn } from \"../../utils\";\n\nconst containerVariants = cva(\"mx-auto w-full\", {\n variants: {\n // A deliberately short list. Named widths are a shared decision — five\n // of them means two pages can't be 4px apart for no reason, which is\n // exactly what happens once `max-w-[1180px]` is on the table.\n size: {\n /** Forms, settings, single-column detail. */\n sm: \"max-w-3xl\",\n /** Standard content pages. */\n md: \"max-w-5xl\",\n /** Application pages — the default. */\n lg: \"max-w-7xl\",\n /** Dashboards and wide tables: gutters, no ceiling. */\n full: \"max-w-none\",\n /** Long-form reading, capped by character count rather than width. */\n prose: \"max-w-prose\",\n },\n // The three steps are the design system's own page spacing token\n // (`spacing.page` = 1rem / 1.5rem / 2rem) expressed as utilities.\n gutter: {\n true: \"px-4 sm:px-6 lg:px-8\",\n false: \"px-0\",\n },\n },\n defaultVariants: {\n size: \"lg\",\n gutter: true,\n },\n});\n\nexport interface ContainerProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof containerVariants> {\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/**\n * Container — the page gutter: a centered column with a named maximum\n * width and responsive side padding.\n *\n * ```tsx\n * <Container>\n * <Section title=\"Overview\">{…}</Section>\n * </Container>\n *\n * <Container size=\"sm\">\n * <SettingsForm />\n * </Container>\n *\n * <Container size=\"full\" gutter={false}>\n * <FullBleedMap />\n * </Container>\n * ```\n *\n * `gutter` is a real prop rather than a `className` override because the\n * padding is responsive: passing `px-0` would only cancel the base step\n * and leave `sm:px-6` and `lg:px-8` intact, so the escape hatch that looks\n * like it should work silently doesn't.\n *\n * @stability Beta\n */\nexport const Container = React.forwardRef<HTMLDivElement, ContainerProps>(\n ({ className, size, gutter, testID, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"container\"\n data-testid={testID}\n className={cn(containerVariants({ size, gutter }), className)}\n {...props}\n />\n )\n);\nContainer.displayName = \"Container\";\n\nexport { containerVariants };\n","import * as React from \"react\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { cn } from \"../../utils\";\nimport { containerVariants } from \"./container\";\n\n/**\n * The surfaces a band can sit on. Each pairs a background with the\n * foreground made for it, so text on a band always uses the colour designed\n * against that background:\n *\n * - `base`: the page (`background` / `foreground`).\n * - `muted`: a quiet alternate band (`muted` / `foreground`), for rhythm.\n * - `accent`: the brand's primary (`primary` / `primary-foreground`), for a call to action.\n * - `inverse`: the page's colours swapped (`foreground` / `background`), for a footer or a dark band.\n */\nconst bandVariants = cva(\"relative w-full\", {\n variants: {\n surface: {\n base: \"bg-background text-foreground\",\n muted: \"bg-muted text-foreground\",\n accent: \"bg-primary text-primary-foreground\",\n inverse: \"bg-foreground text-background\",\n },\n // Vertical rhythm, mobile first: a band breathes more on a wide screen.\n spacing: {\n none: \"py-0\",\n sm: \"py-8 sm:py-10\",\n md: \"py-12 sm:py-16 lg:py-20\",\n lg: \"py-16 sm:py-24 lg:py-32\",\n },\n },\n defaultVariants: {\n surface: \"base\",\n spacing: \"md\",\n },\n});\n\nexport interface BandProps\n extends React.HTMLAttributes<HTMLElement>,\n VariantProps<typeof bandVariants> {\n /**\n * The element to render. `section` (default) for a region of the page,\n * `header` / `footer` for the site's banner and footer, `div` for a band\n * that is not a region of its own.\n */\n as?: \"section\" | \"header\" | \"footer\" | \"div\" | \"aside\";\n /** The inner column's width (Container's named widths). Default `lg`. */\n width?: \"sm\" | \"md\" | \"lg\" | \"full\" | \"prose\";\n /** Classes for the inner column, after the width and gutter. */\n innerClassName?: string;\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/**\n * Band: a full-bleed, full-width marketing section. The background runs\n * edge to edge; the content sits in a centered column with the page gutter.\n * It is what a landing page is made of: a hero, a features band, a call to\n * action, a footer.\n *\n * ```tsx\n * <Band surface=\"accent\" spacing=\"lg\" aria-labelledby=\"cta-title\">\n * <Display as=\"h2\" id=\"cta-title\" size=\"lg\">Start today</Display>\n * </Band>\n * ```\n *\n * Unlike `Section` (a titled region inside an app page), a band carries no\n * heading of its own: a marketing page decides its heading levels per page\n * (one `h1`, then `h2`s), so the caller places a `Display` and names the\n * region with `aria-labelledby`. Server-safe: no state, no effects.\n *\n * @stability Beta\n */\nexport const Band = React.forwardRef<HTMLElement, BandProps>(\n ({ as: Tag = \"section\", surface, spacing, width = \"lg\", className, innerClassName, testID, children, ...props }, ref) => (\n <Tag\n ref={ref as React.Ref<HTMLElement & HTMLDivElement>}\n data-slot=\"band\"\n data-surface={surface ?? \"base\"}\n data-testid={testID}\n className={cn(bandVariants({ surface, spacing }), className)}\n {...props}\n >\n <div data-slot=\"band-inner\" className={cn(containerVariants({ size: width, gutter: true }), innerClassName)}>\n {children}\n </div>\n </Tag>\n )\n);\nBand.displayName = \"Band\";\n\n/**\n * The marketing (display) type scale: larger than the app scale and\n * responsive, mobile first, so a headline fits a phone and fills a desktop.\n * Size is independent of the heading level: a page has one `h1` whatever\n * size it is drawn at.\n */\nconst displayVariants = cva(\"font-display font-bold tracking-tight text-balance\", {\n variants: {\n size: {\n /** A hero headline. */\n xl: \"text-4xl leading-[1.1] sm:text-5xl lg:text-6xl\",\n /** A section headline. */\n lg: \"text-3xl leading-tight sm:text-4xl\",\n /** A card or column title in a band. */\n md: \"text-2xl leading-snug sm:text-3xl\",\n /** A small title, such as a pricing tier's name. */\n sm: \"text-xl leading-snug\",\n },\n },\n defaultVariants: {\n size: \"lg\",\n },\n});\n\nexport interface DisplayProps\n extends React.HTMLAttributes<HTMLHeadingElement>,\n VariantProps<typeof displayVariants> {\n /** The heading level: document structure, not a size. Default `h2`. */\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\";\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/**\n * Display: a heading in the marketing type scale (`displayVariants`).\n *\n * ```tsx\n * <Display as=\"h1\" size=\"xl\">Train with people who know your name</Display>\n * ```\n *\n * @stability Beta\n */\nexport const Display = React.forwardRef<HTMLHeadingElement, DisplayProps>(\n ({ as: Tag = \"h2\", size, className, testID, ...props }, ref) => (\n <Tag\n ref={ref}\n data-slot=\"display\"\n data-testid={testID}\n className={cn(displayVariants({ size }), className)}\n {...props}\n />\n )\n);\nDisplay.displayName = \"Display\";\n\n/**\n * Lead copy under a display heading: one size up from body text, in the\n * muted foreground on the page (`tone=\"muted\"`), or the band's own\n * foreground on an accent or inverse band (`tone=\"inherit\"`).\n */\nconst leadVariants = cva(\"text-lg leading-relaxed sm:text-xl text-pretty\", {\n variants: {\n tone: {\n muted: \"text-muted-foreground\",\n inherit: \"text-current\",\n },\n },\n defaultVariants: { tone: \"muted\" },\n});\n\nexport interface BandLeadProps\n extends React.HTMLAttributes<HTMLParagraphElement>,\n VariantProps<typeof leadVariants> {\n testID?: string;\n}\n\n/** @stability Beta */\nexport const BandLead = React.forwardRef<HTMLParagraphElement, BandLeadProps>(\n ({ tone, className, testID, ...props }, ref) => (\n <p ref={ref} data-slot=\"band-lead\" data-testid={testID} className={cn(leadVariants({ tone }), className)} {...props} />\n )\n);\nBandLead.displayName = \"BandLead\";\n\nexport { bandVariants, displayVariants, leadVariants };\n"]}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { AppShell, PageHeader } from '../../chunk-
|
|
2
|
+
import { AppShell, PageHeader } from '../../chunk-5OFA2CQR.js';
|
|
3
3
|
export { ViewSettings, ViewToggle } from '../../chunk-46TZGMFW.js';
|
|
4
4
|
import { slots_exports } from '../../chunk-WALJMVEF.js';
|
|
5
5
|
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '../../chunk-N2ZFNOOT.js';
|
|
6
|
-
import { Textarea } from '../../chunk-YETMISCE.js';
|
|
7
|
-
import { Separator } from '../../chunk-SXSCHWZU.js';
|
|
8
6
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '../../chunk-XCGZPFT7.js';
|
|
9
|
-
import { Skeleton } from '../../chunk-QFM4Z2SS.js';
|
|
10
7
|
import { Progress } from '../../chunk-W5Y3LG5K.js';
|
|
11
|
-
import { Checkbox } from '../../chunk-SEBU6JCK.js';
|
|
12
8
|
import { Card, CardContent, CardHeader, CardTitle } from '../../chunk-FN3FZVUR.js';
|
|
9
|
+
import { Checkbox } from '../../chunk-SEBU6JCK.js';
|
|
10
|
+
import { Textarea } from '../../chunk-YETMISCE.js';
|
|
11
|
+
import { Separator } from '../../chunk-SXSCHWZU.js';
|
|
12
|
+
import { Skeleton } from '../../chunk-QFM4Z2SS.js';
|
|
13
|
+
import { Input } from '../../chunk-QSXVL5UB.js';
|
|
13
14
|
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '../../chunk-4C4ESW6O.js';
|
|
14
15
|
import { PageLoading } from '../../chunk-YRYQXU3G.js';
|
|
15
16
|
import { Spinner } from '../../chunk-OVU3Z2MT.js';
|
|
16
17
|
import { useAnnouncer } from '../../chunk-I4NBE2KL.js';
|
|
17
|
-
import {
|
|
18
|
+
import { FormField, FormLabel, FormError, FormDescription } from '../../chunk-R7QFP6EL.js';
|
|
18
19
|
import '../../chunk-B2GIBUQD.js';
|
|
19
20
|
import { Badge } from '../../chunk-NPNADZHM.js';
|
|
21
|
+
import '../../chunk-G5YKBPBF.js';
|
|
20
22
|
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../chunk-FK42ZGGV.js';
|
|
23
|
+
import { Popover, PopoverTrigger, PopoverContent } from '../../chunk-22XB3Q6H.js';
|
|
21
24
|
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuSeparator, DropdownMenuItem, DropdownMenuLabel } from '../../chunk-QJ6P2DW6.js';
|
|
22
25
|
import { Switch } from '../../chunk-27ELYTGE.js';
|
|
23
|
-
import '../../chunk-
|
|
24
|
-
import { Popover, PopoverTrigger, PopoverContent } from '../../chunk-22XB3Q6H.js';
|
|
26
|
+
import '../../chunk-F47U5KNW.js';
|
|
25
27
|
import { DetailPage } from '../../chunk-AFZ76Q26.js';
|
|
26
28
|
import '../../chunk-D2LIXA2Y.js';
|
|
27
29
|
import '../../chunk-AVFZ4P4B.js';
|
|
28
30
|
import { EmptyState } from '../../chunk-65SPT7EA.js';
|
|
29
31
|
export { EmptyState } from '../../chunk-65SPT7EA.js';
|
|
30
32
|
import { Button } from '../../chunk-NWSCYLPT.js';
|
|
31
|
-
import { FormField, FormLabel, FormError, FormDescription } from '../../chunk-R7QFP6EL.js';
|
|
32
|
-
import '../../chunk-F47U5KNW.js';
|
|
33
33
|
import { showUndoToast, showWriteErrorToast, useResourceTableModel } from '../../chunk-STZVZUYO.js';
|
|
34
34
|
export { showUndoToast, showWriteErrorToast, useResourceTable } from '../../chunk-STZVZUYO.js';
|
|
35
35
|
import { titleCase } from '../../chunk-RKPS7ERS.js';
|
|
@@ -37,9 +37,9 @@ import '../../chunk-DIV4BYXX.js';
|
|
|
37
37
|
export { useSavedViews } from '../../chunk-GCQFVMPI.js';
|
|
38
38
|
import '../../chunk-PKFDGGZV.js';
|
|
39
39
|
import '../../chunk-OZ7ZAYCS.js';
|
|
40
|
-
import '../../chunk-4RAZJ6LL.js';
|
|
41
40
|
export { CommandPalette, useCommandPaletteHotkey } from '../../chunk-CNTWQSUT.js';
|
|
42
41
|
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator } from '../../chunk-SEFK4NZV.js';
|
|
42
|
+
import '../../chunk-4RAZJ6LL.js';
|
|
43
43
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '../../chunk-7XMZVISM.js';
|
|
44
44
|
import { cn } from '../../chunk-NZ5WBA4R.js';
|
|
45
45
|
import { DefaultLink } from '../../chunk-J45FHL7D.js';
|