@weasel-js/forge 1.7.0 → 1.7.2
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 +2 -2
- package/dist/{FrameController-HEcTM04H.d.ts → FrameController-RdGggdGA.d.ts} +10 -0
- package/dist/{chunk-LLGBNJAZ.js → chunk-JNJGIUYU.js} +2 -2
- package/dist/chunk-JNJGIUYU.js.map +1 -0
- package/dist/{chunk-DDDCZ6XW.js → chunk-KIFCYY4F.js} +3 -3
- package/dist/{chunk-DDDCZ6XW.js.map → chunk-KIFCYY4F.js.map} +1 -1
- package/dist/{chunk-ERRLEH6S.js → chunk-NYBMOSSR.js} +3 -3
- package/dist/{chunk-ERRLEH6S.js.map → chunk-NYBMOSSR.js.map} +1 -1
- package/dist/{chunk-7GQI2PDH.js → chunk-SEK6EKHO.js} +35 -35
- package/dist/chunk-SEK6EKHO.js.map +1 -0
- package/dist/{chunk-2GXKNXTJ.js → chunk-Y3WZ2EWR.js} +2 -2
- package/dist/chunk-Y3WZ2EWR.js.map +1 -0
- package/dist/{config-pDbcbGco.d.ts → config-BJIgUhiI.d.ts} +2 -1
- package/dist/frame/index.d.ts +5 -2
- package/dist/frame/index.js +3 -3
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -2
- package/dist/shell/index.css +0 -3
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +12 -2
- package/dist/shell/index.js +22 -23
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +4 -4
- package/dist/test/index.js.map +1 -1
- package/dist/vite/index.d.ts +7 -1
- package/dist/vite/index.js +23 -14
- package/dist/vite/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-2GXKNXTJ.js.map +0 -1
- package/dist/chunk-7GQI2PDH.js.map +0 -1
- package/dist/chunk-LLGBNJAZ.js.map +0 -1
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ with a `viewport` renders as a fixed-size box the trial pans and zooms.
|
|
|
19
19
|
A story that needs a document of its own says so, with the reason:
|
|
20
20
|
|
|
21
21
|
```tsx
|
|
22
|
-
export const Interactive = story({ isolate: '
|
|
23
|
-
// CSF: parameters: { forge: { isolate: '
|
|
22
|
+
export const Interactive = story({ isolate: 'asserts placement against the window edge', render: … });
|
|
23
|
+
// CSF: parameters: { forge: { isolate: 'asserts placement against the window edge' } }
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
It then renders in an iframe, as every story once did. The frame path is kept
|
|
@@ -186,6 +186,8 @@ type FromFrame = {
|
|
|
186
186
|
seq?: number;
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
+
/** What a story's `render` and its decorators receive: the trial's config and state, the globals in force, and the
|
|
190
|
+
* story's own title and name. */
|
|
189
191
|
interface StoryContext<C = unknown, S = unknown> {
|
|
190
192
|
config: C;
|
|
191
193
|
setConfig: (path: string, value: unknown) => void;
|
|
@@ -195,12 +197,15 @@ interface StoryContext<C = unknown, S = unknown> {
|
|
|
195
197
|
title: string;
|
|
196
198
|
name: string;
|
|
197
199
|
}
|
|
200
|
+
/** What a story's `play` receives. `canvasElement` is the element the story rendered into. */
|
|
198
201
|
interface PlayContext<C = unknown> {
|
|
199
202
|
canvasElement: HTMLElement;
|
|
200
203
|
config: C;
|
|
201
204
|
globals: Globals;
|
|
202
205
|
}
|
|
206
|
+
/** Wraps a story: `story()` renders what it wraps, and the decorator returns that inside whatever it adds. */
|
|
203
207
|
type Decorator = (story: () => ReactNode, ctx: StoryContext) => ReactNode;
|
|
208
|
+
/** What `meta()` takes: settings every story in the file shares. */
|
|
204
209
|
interface MetaSpec {
|
|
205
210
|
title?: string;
|
|
206
211
|
decorators?: Decorator[];
|
|
@@ -236,6 +241,7 @@ interface IndexContext {
|
|
|
236
241
|
/** Shows story `id` in this page's trial in its place. */
|
|
237
242
|
open: (id: string) => void;
|
|
238
243
|
}
|
|
244
|
+
/** Props for `IndexContext.Story`. */
|
|
239
245
|
interface IndexStoryProps {
|
|
240
246
|
story: LoadedStory;
|
|
241
247
|
/** Merged over the story's defaults; nested groups merge rather than replace. */
|
|
@@ -243,7 +249,9 @@ interface IndexStoryProps {
|
|
|
243
249
|
/** Shown under the story. */
|
|
244
250
|
label?: string;
|
|
245
251
|
}
|
|
252
|
+
/** A custom index page for a component, given as `MetaSpec.index`. */
|
|
246
253
|
type IndexRender = (ctx: IndexContext) => ReactNode;
|
|
254
|
+
/** What `story()` takes. `config` declares the story's controls; `state`, given, seeds its state from the config. */
|
|
247
255
|
interface StorySpec<C = Record<string, never>, S = undefined> {
|
|
248
256
|
name?: string;
|
|
249
257
|
config?: ConfigSchema<C>;
|
|
@@ -316,6 +324,7 @@ interface GlobalsTarget {
|
|
|
316
324
|
style: (css: string) => void;
|
|
317
325
|
}
|
|
318
326
|
|
|
327
|
+
/** The frame config: what `defineFrameConfig` returns and the `frameConfig` module default-exports. */
|
|
319
328
|
interface FrameSetup {
|
|
320
329
|
/** Wraps every story, outermost; receives the globals. From the frame config (`frameConfig`). */
|
|
321
330
|
decorators?: Decorator[];
|
|
@@ -335,6 +344,7 @@ interface FrameSetup {
|
|
|
335
344
|
*/
|
|
336
345
|
prepare?: (story: LoadedStory) => void | Promise<void>;
|
|
337
346
|
}
|
|
347
|
+
/** Inputs to `startFrame`: the story, the channel to the shell, and the element to render into. */
|
|
338
348
|
interface StartFrameOptions {
|
|
339
349
|
story: LoadedStory;
|
|
340
350
|
channel: Channel<ToFrame, FromFrame>;
|
|
@@ -73,5 +73,5 @@ function withGlobals(schema, declarations) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
export { FOLLOW_APP, GLOBALS_KEY, effectiveGlobals, followApp, isGlobalsPath, labGlobals, labOptions, storyConfig, withGlobals };
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
77
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-JNJGIUYU.js.map
|
|
77
|
+
//# sourceMappingURL=chunk-JNJGIUYU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shell/globals.ts"],"names":["from"],"mappings":"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","file":"chunk-JNJGIUYU.js","sourcesContent":["import type { LabMode } from '@weasel-js/labkit';\nimport { type ConfigSchema, f } from '@weasel-js/labkit/config';\nimport type { Globals } from '../protocol/messages';\n\n/** One global the workshop's toolbar sets for every story, and a trial may pin for its own. */\nexport interface GlobalDeclaration {\n label: string;\n options: readonly { value: string; label: string }[];\n default: string;\n /** Another global's key: the toolbar shows this one in a popover beside that one rather than in the bar itself. */\n under?: string;\n /**\n * Whether the toolbar offers `value` given the lab's other values; every option shows when absent. `globals` is\n * resolved without any declaration's `shows`, so one `shows` cannot depend on another's outcome.\n */\n shows?: (value: string, globals: Globals) => boolean;\n /**\n * What this global reads from the lab's own chrome. Given, the lab's value may be `App` (`FOLLOW_APP`), offered\n * first, and while it is the global follows that chrome control, as the header's mode switch sets it. A trial's\n * pin follows the lab or names a value; it cannot follow the app on its own.\n */\n follows?: (chrome: LabChrome) => string;\n}\n\n/** The lab chrome's own settings a global can follow. */\nexport interface LabChrome {\n mode: LabMode;\n}\n\n/** The shell config's `globals`: each declaration by the key stories read it under. */\nexport type GlobalDeclarations = Readonly<Record<string, GlobalDeclaration>>;\n\n/** The config group every story schema gains, holding the trial's pins. A story never sees it. */\nexport const GLOBALS_KEY = '$globals';\n/** A pin's value when the trial follows the lab. */\nexport const FOLLOW_LAB = 'lab';\n/** A lab value, for a declaration that `follows` the app, meaning whatever the app's chrome is set to. */\nexport const FOLLOW_APP = 'app';\n\nconst APP_OPTION = { value: FOLLOW_APP, label: 'App' } as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport const isGlobalsPath = (path: string): boolean => path === GLOBALS_KEY || path.startsWith(`${GLOBALS_KEY}.`);\n\n/** The options the toolbar offers for `declaration` at `globals`. */\nexport function shownOptions(declaration: GlobalDeclaration, globals: Globals): GlobalDeclaration['options'] {\n const { shows } = declaration;\n return shows ? declaration.options.filter((option) => shows(option.value, globals)) : declaration.options;\n}\n\n/** The options the lab's own control offers: `shownOptions`, after `App` where the declaration follows the app. */\nexport function labOptions(declaration: GlobalDeclaration, globals: Globals): GlobalDeclaration['options'] {\n const shown = shownOptions(declaration, globals);\n return declaration.follows ? [APP_OPTION, ...shown] : shown;\n}\n\n/** `values` with each `App` replaced by what its declaration reads from `chrome`; `values` itself when none is. */\nexport function followApp(declarations: GlobalDeclarations, values: Globals, chrome: LabChrome): Globals {\n const followed = Object.entries(declarations).flatMap(([key, { follows }]) =>\n follows && values[key] === FOLLOW_APP ? [[key, follows(chrome)] as const] : [],\n );\n return followed.length === 0 ? values : { ...values, ...Object.fromEntries(followed) };\n}\n\n/**\n * The lab's values from what was stored: declared keys only. A value no option offers falls back to the default, and\n * one its declaration's `shows` hides falls back to the shown option nearest it in `options`, the earlier on a tie.\n */\nexport function labGlobals(declarations: GlobalDeclarations, stored: unknown): Globals {\n const from = isRecord(stored) ? stored : {};\n const offered: Globals = Object.fromEntries(\n Object.entries(declarations).map(([key, declaration]) => {\n const value = from[key];\n const known =\n declaration.options.some((option) => option.value === value) || (declaration.follows && value === FOLLOW_APP);\n return [key, known ? value : declaration.default];\n }),\n );\n return Object.fromEntries(\n Object.entries(declarations).map(([key, declaration]) => {\n const shown = shownOptions(declaration, offered);\n const value = offered[key];\n if (value === FOLLOW_APP && declaration.follows) return [key, value];\n if (!declaration.shows || shown.length === 0 || shown.some((option) => option.value === value)) return [key, value];\n const at = (v: unknown) => declaration.options.findIndex((option) => option.value === v);\n const from = at(value);\n const nearest = shown.reduce((best, option) =>\n Math.abs(at(option.value) - from) < Math.abs(at(best.value) - from) ? option : best,\n );\n return [key, nearest.value];\n }),\n );\n}\n\n/** The lab's values, overridden by the pins in a trial's config that do not follow the lab. */\nexport function effectiveGlobals(lab: Globals, pins: unknown): Globals {\n if (!isRecord(pins)) return lab;\n const pinned = Object.entries(pins).filter(([key, value]) => key in lab && value !== FOLLOW_LAB);\n return pinned.length === 0 ? lab : { ...lab, ...Object.fromEntries(pinned) };\n}\n\n/**\n * The config a story receives: the trial's, without its pins. Returns `previous` when every other entry is the same,\n * so a change to a pin alone is not a change to the story's config.\n */\nexport function storyConfig(config: unknown, previous?: unknown): unknown {\n if (!isRecord(config) || !(GLOBALS_KEY in config)) return config;\n const rest = Object.fromEntries(Object.entries(config).filter(([key]) => key !== GLOBALS_KEY));\n if (isRecord(previous)) {\n const keys = Object.keys(rest);\n if (keys.length === Object.keys(previous).length && keys.every((key) => rest[key] === previous[key])) return previous;\n }\n return rest;\n}\n\n/** `schema` with a `$globals` group appended: one leaf per declaration, following the lab until pinned. */\nexport function withGlobals(schema: ConfigSchema<unknown>, declarations: GlobalDeclarations): ConfigSchema<unknown> {\n const entries = Object.entries(declarations);\n if (entries.length === 0) return schema;\n const leaves = Object.fromEntries(\n entries.map(([key, declaration]) => [\n key,\n f.enum(FOLLOW_LAB, [{ value: FOLLOW_LAB, label: 'Lab' }, ...declaration.options]).label(declaration.label),\n ]),\n );\n // An empty group name contributes rows without a heading of its own, under the section's.\n const group = f.group(leaves).label('').section('Globals', { layout: 'inline', pack: 'pairs' });\n return f.schema({ ...schema.nodes, [GLOBALS_KEY]: group }) as ConfigSchema<unknown>;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StoryHost } from './chunk-
|
|
1
|
+
import { StoryHost } from './chunk-NYBMOSSR.js';
|
|
2
2
|
import { sanitize } from './chunk-HRGPFQBW.js';
|
|
3
3
|
import { PROTOCOL_VERSION, isPlainObject } from './chunk-YKN3IAEX.js';
|
|
4
4
|
import { f, isConfigBranch, resolveConfigSchema, schemaNodeAtPath, titleCase } from '@weasel-js/labkit/config';
|
|
@@ -401,5 +401,5 @@ function IndexPage({ env, render }) {
|
|
|
401
401
|
}
|
|
402
402
|
|
|
403
403
|
export { IndexPage, LibraryBadge, answerSchema, describeSchema, indexEntries, indexId, isIndexId, libraryOf, openChannel, schemaFromDescription };
|
|
404
|
-
//# sourceMappingURL=chunk-
|
|
405
|
-
//# sourceMappingURL=chunk-
|
|
404
|
+
//# sourceMappingURL=chunk-KIFCYY4F.js.map
|
|
405
|
+
//# sourceMappingURL=chunk-KIFCYY4F.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocol/schema.ts","../src/protocol/channel.ts","../src/story/indexPages.ts","../src/story/library.ts","../src/frame/index/LibraryBadge.tsx","../src/frame/index/variants.ts","../src/frame/index/IndexPage.tsx"],"names":["isConfigBranch","jsx","Badge"],"mappings":"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","file":"chunk-DDDCZ6XW.js","sourcesContent":["import {\n f,\n isConfigBranch,\n resolveConfigSchema,\n schemaNodeAtPath,\n type Annotations,\n type BranchAnnotations,\n type ConfigBranch,\n type ConfigEntry,\n type ConfigNode,\n type ConfigSchema,\n type ConfigShape,\n type NodeOptions,\n} from '@weasel-js/labkit/config';\n\nexport interface SectionDescription {\n label: string;\n collapsed?: boolean;\n}\n\nexport type DescribedEntry =\n | {\n branch: true;\n annotations: BranchAnnotations;\n section?: SectionDescription;\n conditional: boolean;\n children: DescribedShape;\n }\n | {\n branch: false;\n kind: string | null;\n default: unknown;\n annotations: Annotations;\n section?: SectionDescription;\n conditional: boolean;\n validated: boolean;\n /** The node draws its own row with `.render`, which stays in the frame. */\n customControl: boolean;\n };\n\nexport type DescribedShape = { [key: string]: DescribedEntry };\n\n/** A story's `f.schema` as structured-clone data. */\nexport interface SchemaDescription {\n nodes: DescribedShape;\n}\n\n/** Answers the workshop has for the rebuilt schema's predicates. */\nexport interface SchemaAnswers {\n hidden(path: string, config: unknown): boolean;\n errors(path: string, config: unknown): string[];\n}\n\nconst joinPath = (at: string, key: string): string => (at === '' ? key : `${at}.${key}`);\n\nfunction describeShape(shape: ConfigShape): DescribedShape {\n const out: DescribedShape = {};\n for (const [key, entry] of Object.entries(shape)) {\n const { section, showIf } = entry.options;\n const common = {\n annotations: { ...entry.annotations },\n ...(section === undefined ? {} : { section: { ...section } }),\n conditional: showIf !== undefined,\n };\n out[key] = isConfigBranch(entry)\n ? { branch: true, ...common, children: describeShape(entry.children) }\n : {\n branch: false,\n kind: entry.kind,\n default: entry.default,\n ...common,\n validated: entry.options.validate !== undefined,\n customControl: entry.options.render !== undefined,\n };\n }\n return out;\n}\n\nexport function describeSchema(schema: ConfigSchema<unknown>): SchemaDescription {\n return { nodes: describeShape(schema.nodes) };\n}\n\nfunction rebuildShape(shape: DescribedShape, at: string, answers: SchemaAnswers): ConfigShape {\n const out: Record<string, ConfigEntry> = {};\n for (const [key, entry] of Object.entries(shape)) {\n const path = joinPath(at, key);\n const options: NodeOptions = {\n ...(entry.section === undefined ? {} : { section: entry.section }),\n ...(entry.conditional ? { showIf: (config) => !answers.hidden(path, config) } : {}),\n };\n if (entry.branch) {\n const branch: ConfigBranch = {\n children: rebuildShape(entry.children, path, answers),\n annotations: entry.annotations,\n options,\n };\n out[key] = branch;\n } else {\n const node: ConfigNode = {\n kind: entry.kind,\n default: entry.default,\n annotations: entry.annotations,\n options: entry.validated ? { ...options, validate: (_leaf, config) => answers.errors(path, config) } : options,\n };\n out[key] = node;\n }\n }\n return out;\n}\n\nexport function schemaFromDescription(\n description: SchemaDescription,\n answers: SchemaAnswers,\n): ConfigSchema<unknown> {\n return f.schema(rebuildShape(description.nodes, '', answers)) as ConfigSchema<unknown>;\n}\n\n/** Evaluate a schema's own predicates for one config — the frame's half of `answers`. */\nexport function answerSchema(\n schema: ConfigSchema<unknown>,\n config: unknown,\n): { hidden: string[]; errors: Record<string, string[]> } {\n const hidden: string[] = [];\n const errors: Record<string, string[]> = {};\n const record = config as Record<string, unknown>;\n let group: ReturnType<typeof resolveConfigSchema>['group'] | undefined;\n\n const walk = (shape: ConfigShape, at: string): void => {\n for (const [key, entry] of Object.entries(shape)) {\n const path = joinPath(at, key);\n if (entry.options.showIf && !entry.options.showIf(record)) hidden.push(path);\n if (isConfigBranch(entry)) {\n walk(entry.children, path);\n continue;\n }\n const { validate } = entry.options;\n if (!validate) continue;\n group ??= resolveConfigSchema(schema).group;\n const leaf = schemaNodeAtPath(group, path);\n if (!leaf || 'children' in leaf) continue;\n const found = validate(leaf, record);\n if (found.length > 0) errors[path] = found;\n }\n };\n walk(schema.nodes, '');\n return { hidden, errors };\n}\n","import { type Envelope, PROTOCOL_VERSION } from './messages';\n\nexport interface PortLike {\n postMessage(message: unknown): void;\n addEventListener(type: 'message', fn: (event: MessageEvent) => void): void;\n removeEventListener(type: 'message', fn: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\nexport interface Channel<In, Out> {\n send(msg: Out): void;\n on(fn: (msg: In) => void): () => void;\n close(): void;\n}\n\nexport type Mismatch = { reason: 'not-an-envelope' } | { reason: 'version'; version: unknown };\n\nexport interface ChannelOptions {\n onMismatch?: (mismatch: Mismatch) => void;\n}\n\nexport function openChannel<In, Out>(port: PortLike, options: ChannelOptions = {}): Channel<In, Out> {\n const listeners = new Set<(msg: In) => void>();\n const onMessage = (event: MessageEvent) => {\n const data: unknown = event.data;\n if (typeof data !== 'object' || data === null || !('msg' in data)) {\n options.onMismatch?.({ reason: 'not-an-envelope' });\n return;\n }\n const envelope = data as Partial<Envelope<In>>;\n if (envelope.v !== PROTOCOL_VERSION) {\n options.onMismatch?.({ reason: 'version', version: envelope.v });\n return;\n }\n for (const fn of listeners) fn(envelope.msg as In);\n };\n port.addEventListener('message', onMessage);\n port.start?.();\n return {\n send: (msg) => port.postMessage({ v: PROTOCOL_VERSION, msg } satisfies Envelope<Out>),\n on: (fn) => {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n close: () => {\n port.removeEventListener('message', onMessage);\n listeners.clear();\n port.close();\n },\n };\n}\n","import { sanitize } from './ids';\nimport type { IndexEntry } from './types';\n\nconst SUFFIX = ':index';\n\n/** The name an index page goes by in the sidebar and in its trial's title. */\nexport const INDEX_NAME = 'Index';\n\n/** The id of `title`'s index page. A colon never survives `sanitize`, so no story id can collide with it. */\nexport function indexId(title: string): string {\n return `${sanitize(title)}${SUFFIX}`;\n}\n\nexport function isIndexId(id: string): boolean {\n return id.endsWith(SUFFIX);\n}\n\n/**\n * One index-page entry per title in `stories`, in the order titles first appear. It routes and runs like a story:\n * its `file` is the title's first story file, its descriptions are the title's own, and its tags are those every story\n * of the title carries.\n */\nexport function indexEntries(stories: readonly IndexEntry[]): IndexEntry[] {\n const byTitle = new Map<string, IndexEntry>();\n for (const entry of stories) {\n const page = byTitle.get(entry.title);\n if (page) {\n if (page.tags) {\n const common = page.tags.filter((tag) => entry.tags?.includes(tag));\n if (common.length > 0) page.tags = common;\n else delete page.tags;\n }\n continue;\n }\n byTitle.set(entry.title, {\n id: indexId(entry.title),\n title: entry.title,\n name: INDEX_NAME,\n exportName: '',\n file: entry.file,\n ...(entry.componentDescription === undefined ? {} : { componentDescription: entry.componentDescription }),\n ...(entry.componentName === undefined ? {} : { componentName: entry.componentName }),\n ...(entry.tags === undefined ? {} : { tags: entry.tags }),\n });\n }\n return [...byTitle.values()];\n}\n","/**\n * Which library a story file belongs to, by the package it lives in rather\n * than by its title's first segment. The title prefix is authored per story\n * and disagrees with itself — `packages/ui` alone declares both `Primitives/`\n * and `ui/` — so the path is the answer that cannot drift.\n */\nconst LIBRARIES: readonly (readonly [marker: string, label: string])[] = [\n ['/packages/ui/', 'ui'],\n ['/packages/labkit/', 'labkit'],\n ['/packages/forge/', 'forge'],\n ['/apps/draw/', 'draw'],\n ['/apps/forge/', 'forge'],\n];\n\n/** `entry`'s library, falling back to its title's first segment for a file\n * under none of the known packages. */\nexport function libraryOf(entry: { file: string; title: string }): string {\n const file = entry.file.replaceAll('\\\\', '/');\n for (const [marker, label] of LIBRARIES) {\n if (file.includes(marker)) return label;\n }\n return entry.title.split('/')[0] ?? entry.title;\n}\n","// The component's own entry, not the barrel: the barrel would bring every weasel-ui component into each frame.\nimport { Badge } from '@weasel-js/ui/components/Badge';\n\n/** `swatch` mixed toward the foreground, further in light mode: a bright swatch needs more of the dark foreground to\n * hold 4.5:1 as small text on its own tint, and a dark swatch less of the light one. */\nconst tone = (swatch: string, light: number, dark: number): string =>\n `light-dark(color-mix(in oklab, var(--wzl-swatch-${swatch}), var(--wzl-fg) ${light}%), ` +\n `color-mix(in oklab, var(--wzl-swatch-${swatch}), var(--wzl-fg) ${dark}%))`;\n\n/** Each package's peer tone. */\nconst LIBRARY_TONES: Readonly<Record<string, string>> = {\n ui: tone('amber', 55, 40),\n labkit: tone('teal', 55, 45),\n forge: tone('blue', 55, 35),\n draw: tone('rose', 55, 35),\n};\n\n/** A component's package, as a badge toned per package. */\nexport function LibraryBadge({ library, className }: { library: string; className?: string }) {\n return (\n <Badge status=\"muted\" tone={LIBRARY_TONES[library]} variant=\"subtle\" size=\"sm\" {...(className ? { className } : {})}>\n {library}\n </Badge>\n );\n}\n","import { type ConfigSchema, type ConfigShape, isConfigBranch, titleCase } from '@weasel-js/labkit/config';\nimport { isPlainObject } from '../../csf/isPlainObject';\n\nexport interface VariantValue {\n value: unknown;\n label: string;\n}\n\n/** One control a story is shown varying along, with every other control at its default. */\nexport interface VariantRow {\n /** Dotted, as `setConfig` takes it. */\n path: string;\n label: string;\n values: VariantValue[];\n}\n\n/** Above this many choices a row stops being something to scan. */\nexport const MAX_ENUM_OPTIONS = 8;\nexport const MAX_ROWS = 6;\n\nconst labelOf = (key: string, name: string | undefined): string => name ?? titleCase(key);\n\n/**\n * The boolean and enum controls of `schema` a story can be shown varying along, in schema order: skipped are\n * controls that draw their own row, controls hidden at the defaults, and enums with more than\n * `MAX_ENUM_OPTIONS` choices. At most `MAX_ROWS`.\n */\nexport function variantRows(schema: ConfigSchema<unknown>): VariantRow[] {\n const defaults = schema.defaults() as Record<string, unknown>;\n const rows: VariantRow[] = [];\n const walk = (shape: ConfigShape, at: string): void => {\n for (const [key, entry] of Object.entries(shape)) {\n if (rows.length >= MAX_ROWS) return;\n const path = at === '' ? key : `${at}.${key}`;\n if (entry.options.showIf && !entry.options.showIf(defaults)) continue;\n if (isConfigBranch(entry)) {\n walk(entry.children, path);\n continue;\n }\n if (entry.annotations.hidden || entry.options.render) continue;\n const label = labelOf(key, entry.annotations.name);\n if (entry.kind === 'boolean') {\n rows.push({ path, label, values: [false, true].map((value) => ({ value, label: String(value) })) });\n } else if (entry.kind === 'enum') {\n const options = entry.annotations.options ?? [];\n if (options.length < 2 || options.length > MAX_ENUM_OPTIONS) continue;\n rows.push({ path, label, values: options.map((o) => ({ value: o.value, label: o.label })) });\n }\n }\n };\n walk(schema.nodes, '');\n return rows;\n}\n\n/** `over` merged into `base`: nested plain objects merge, anything else replaces. */\nexport function mergeConfig(base: unknown, over: unknown): unknown {\n if (!isPlainObject(base) || !isPlainObject(over)) return over === undefined ? base : over;\n const out: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(over)) out[key] = mergeConfig(base[key], value);\n return out;\n}\n\n/** `config` with `value` at dotted `path`, copying each object along the way. */\nexport function withValueAt(config: unknown, path: string, value: unknown): unknown {\n const [head, ...rest] = path.split('.');\n if (head === undefined) return value;\n const record = isPlainObject(config) ? config : {};\n return { ...record, [head]: rest.length === 0 ? value : withValueAt(record[head], rest.join('.'), value) };\n}\n","// The components' own entries, not the barrel: the barrel would bring every weasel-ui component into each frame.\nimport { Badge } from '@weasel-js/ui/components/Badge';\nimport { Button } from '@weasel-js/ui/components/Button';\nimport {\n createContext,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { Globals } from '../../protocol/messages';\nimport { indexId } from '../../story/indexPages';\nimport type { ComponentDeps, Decorator, IndexContext, IndexStoryProps, LoadedStory, StoryContext } from '../../story/types';\nimport { StoryHost } from '../StoryHost';\nimport { mergeConfig, variantRows, withValueAt } from './variants';\nimport './index.css';\nimport { LibraryBadge } from './LibraryBadge';\n\n/** What every cell on an index page shares with the frame that hosts it. */\nexport interface IndexEnv {\n title: string;\n /** The package the component ships in. */\n library?: string;\n description?: string;\n stories: readonly LoadedStory[];\n /** Per story id, the JSDoc above its export. */\n descriptions: Readonly<Record<string, string>>;\n /** A catalog or showcase rather than one component: every story of it is tagged `gallery`. */\n gallery?: boolean;\n /** The ids of the stories tagged `gallery`. */\n galleries?: readonly string[];\n /** The component's place in the component graph; absent until the graph arrives, and for a gallery. */\n dependencies?: ComponentDeps;\n globals: Globals;\n /** The frame config's, outermost. */\n decorators: readonly Decorator[];\n open: (id: string) => void;\n onError: (error: unknown) => void;\n}\n\nexport const IndexEnvContext = createContext<IndexEnv | null>(null);\n\nfunction useEnv(): IndexEnv {\n const env = useContext(IndexEnvContext);\n if (!env) throw new Error('An index page part rendered outside its index page');\n return env;\n}\n\n/** How far past the viewport a cell stays mounted. */\nconst NEAR_MARGIN = '100%';\n\n/** Whether `ref`'s element is near the viewport; true where the browser cannot say. */\nfunction useNearViewport(ref: RefObject<Element | null>): boolean {\n const [near, setNear] = useState(typeof IntersectionObserver === 'undefined');\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof IntersectionObserver === 'undefined') return;\n const observer = new IntersectionObserver((entries) => {\n const last = entries.at(-1);\n if (last) setNear(last.isIntersecting);\n }, { rootMargin: NEAR_MARGIN });\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref]);\n return near;\n}\n\n/**\n * One story at its defaults with `config` over them. It keeps its own config and state, so it stays interactive, and\n * it mounts only while near the viewport, so a page of canvas stories stays under the browser's WebGL context cap.\n */\nexport function IndexStory({ story, config: over, label }: IndexStoryProps) {\n const env = useEnv();\n const [config, setConfig] = useState(() => mergeConfig(story.config.defaults(), over));\n const [state, setState] = useState<unknown>(() => story.initialState?.(config) ?? null);\n const cell = useRef<HTMLElement>(null);\n const near = useNearViewport(cell);\n // Held while unmounted, so scrolling past a cell does not move everything after it.\n const [height, setHeight] = useState<number | null>(null);\n useEffect(() => {\n const el = cell.current;\n if (!near || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setHeight(el.getBoundingClientRect().height));\n observer.observe(el);\n return () => observer.disconnect();\n }, [near]);\n const ctx: StoryContext = {\n config,\n setConfig: (path, value) => setConfig((prev: unknown) => withValueAt(prev, path, value)),\n state,\n setState: (next) =>\n setState((prev: unknown) => (typeof next === 'function' ? (next as (p: unknown) => unknown)(prev) : next)),\n globals: env.globals,\n title: story.title,\n name: story.name,\n };\n return (\n <figure\n ref={cell}\n className={`fg-index-cell fg-index-cell--${story.layout}`}\n style={!near && height !== null ? { minHeight: height } : undefined}\n >\n <div className=\"fg-index-cell__stage\">\n {near ? (\n <StoryHost story={story} ctx={ctx} decorators={env.decorators} resetKey={0} onError={env.onError} />\n ) : null}\n </div>\n {label === undefined ? null : <figcaption className=\"fg-index-cell__label\">{label}</figcaption>}\n </figure>\n );\n}\n\n/** `story` once per value of each boolean and enum control, every other control at its default. */\nexport function IndexVariants({ story }: { story: LoadedStory }) {\n const rows = useMemo(() => variantRows(story.config), [story]);\n const defaults = useMemo(() => story.config.defaults(), [story]);\n if (rows.length === 0) return null;\n return (\n <div className=\"fg-index-variants\">\n {rows.map((row) => (\n <section key={row.path} className=\"fg-index-variants__row\" aria-label={row.label}>\n <h4 className=\"fg-index-variants__label\">{row.label}</h4>\n <div className=\"fg-index-variants__cells\">\n {row.values.map((v) => (\n <IndexStory\n key={String(v.value)}\n story={story}\n config={withValueAt(defaults, row.path, v.value) as Record<string, unknown>}\n label={v.label}\n />\n ))}\n </div>\n </section>\n ))}\n </div>\n );\n}\n\nfunction GalleryBadge() {\n return (\n <Badge status=\"accent\" variant=\"subtle\" size=\"sm\">\n Gallery\n </Badge>\n );\n}\n\nfunction DependencyList({ label, titles, empty }: { label: string; titles: readonly string[]; empty: string }) {\n const env = useEnv();\n const labelId = useId();\n const follow = (event: MouseEvent, id: string) => {\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n event.preventDefault();\n env.open(id);\n };\n return (\n <div className=\"fg-index-deps__row\">\n <dt id={labelId} className=\"fg-index-deps__label\">\n {label}\n </dt>\n <dd className=\"fg-index-deps__value\">\n {titles.length === 0 ? (\n <span className=\"fg-index-deps__empty\">{empty}</span>\n ) : (\n <ul className=\"fg-index-deps__list\" aria-labelledby={labelId}>\n {titles.map((title) => {\n const cut = title.lastIndexOf('/') + 1;\n const id = indexId(title);\n return (\n <li key={title}>\n <a className=\"fg-index-deps__link\" href={`#/${encodeURIComponent(id)}`} onClick={(event) => follow(event, id)}>\n <span className=\"fg-index-deps__prefix\">{title.slice(0, cut)}</span>\n {title.slice(cut)}\n </a>\n </li>\n );\n })}\n </ul>\n )}\n </dd>\n </div>\n );\n}\n\n/** The listed components this one uses and those that use it, read from source. Nothing for a gallery. */\nexport function IndexDependencies() {\n const { gallery, dependencies } = useEnv();\n if (gallery || !dependencies) return null;\n if (dependencies.source === null) {\n return (\n <p className=\"fg-index-deps__none\">\n forge found no source file for this component, so it lists none of its dependencies. It looks for the\n import the meta’s <code>component</code> names, or else the one the title’s last segment names.\n </p>\n );\n }\n return (\n <dl className=\"fg-index-deps\" aria-label=\"Dependencies\">\n <DependencyList label=\"Uses\" titles={dependencies.uses} empty=\"No listed component.\" />\n <DependencyList label=\"Used by\" titles={dependencies.usedBy} empty=\"No listed component uses it.\" />\n </dl>\n );\n}\n\nfunction StorySection({ story, variants }: { story: LoadedStory; variants: boolean }) {\n const env = useEnv();\n const headingId = useId();\n const description = env.descriptions[story.id];\n const gallery = !env.gallery && env.galleries?.includes(story.id);\n return (\n <section className=\"fg-index-story\" aria-labelledby={headingId}>\n <header className=\"fg-index-story__head\">\n <h2 id={headingId} className=\"fg-index-story__name\">\n {story.name}\n </h2>\n {gallery ? <GalleryBadge /> : null}\n <Button variant=\"secondary\" size=\"sm\" onClick={() => env.open(story.id)}>\n Open\n </Button>\n </header>\n {description ? <p className=\"fg-index-story__description\">{description}</p> : null}\n <IndexStory story={story} />\n {variants ? <IndexVariants story={story} /> : null}\n </section>\n );\n}\n\n/** Which of `stories` show their variants: the first of each set of controls. Stories of one CSF file share their\n * meta's controls, and the same rows under every story would only repeat. */\nfunction firstOfEachControlSet(stories: readonly LoadedStory[]): Set<string> {\n const seen = new Set<string>();\n const shown = new Set<string>();\n for (const story of stories) {\n const key = JSON.stringify(variantRows(story.config));\n if (seen.has(key)) continue;\n seen.add(key);\n shown.add(story.id);\n }\n return shown;\n}\n\n/** The generated page: the component's title and description, then each story, with the variants of the first of\n * each set of controls. */\nexport function DefaultIndex() {\n const env = useEnv();\n const withVariants = useMemo(() => firstOfEachControlSet(env.stories), [env.stories]);\n const segments = env.title.split('/');\n const name = segments.pop();\n const { library } = env;\n if (library !== undefined && segments[0] === library) segments.shift();\n return (\n <article className=\"fg-index\">\n <header className=\"fg-index__head\">\n {segments.length > 0 || library !== undefined ? (\n <p className=\"fg-index__path\">\n {library !== undefined ? <LibraryBadge library={library} className=\"fg-index__library\" /> : null}\n {segments.join(' / ')}\n </p>\n ) : null}\n <div className=\"fg-index__title-row\">\n <h1 className=\"fg-index__title\">{name}</h1>\n {env.gallery ? <GalleryBadge /> : null}\n </div>\n {env.description ? <p className=\"fg-index__description\">{env.description}</p> : null}\n <IndexDependencies />\n </header>\n {env.stories.map((story) => (\n <StorySection key={story.id} story={story} variants={withVariants.has(story.id)} />\n ))}\n </article>\n );\n}\n\n/** What a component's own index page is handed. */\nexport function indexContext(env: IndexEnv): IndexContext {\n return {\n title: env.title,\n ...(env.description === undefined ? {} : { description: env.description }),\n stories: env.stories,\n globals: env.globals,\n Story: IndexStory,\n Variants: IndexVariants,\n DefaultIndex,\n Dependencies: IndexDependencies,\n gallery: env.gallery ?? false,\n open: env.open,\n };\n}\n\n/** The page itself: the component's own, or the generated one. */\nexport function IndexPage({ env, render }: { env: IndexEnv; render: ((ctx: IndexContext) => ReactNode) | null }) {\n return (\n <IndexEnvContext.Provider value={env}>{render ? render(indexContext(env)) : <DefaultIndex />}</IndexEnvContext.Provider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/protocol/schema.ts","../src/protocol/channel.ts","../src/story/indexPages.ts","../src/story/library.ts","../src/frame/index/LibraryBadge.tsx","../src/frame/index/variants.ts","../src/frame/index/IndexPage.tsx"],"names":["isConfigBranch","jsx","Badge"],"mappings":"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","file":"chunk-KIFCYY4F.js","sourcesContent":["import {\n f,\n isConfigBranch,\n resolveConfigSchema,\n schemaNodeAtPath,\n type Annotations,\n type BranchAnnotations,\n type ConfigBranch,\n type ConfigEntry,\n type ConfigNode,\n type ConfigSchema,\n type ConfigShape,\n type NodeOptions,\n} from '@weasel-js/labkit/config';\n\nexport interface SectionDescription {\n label: string;\n collapsed?: boolean;\n}\n\nexport type DescribedEntry =\n | {\n branch: true;\n annotations: BranchAnnotations;\n section?: SectionDescription;\n conditional: boolean;\n children: DescribedShape;\n }\n | {\n branch: false;\n kind: string | null;\n default: unknown;\n annotations: Annotations;\n section?: SectionDescription;\n conditional: boolean;\n validated: boolean;\n /** The node draws its own row with `.render`, which stays in the frame. */\n customControl: boolean;\n };\n\nexport type DescribedShape = { [key: string]: DescribedEntry };\n\n/** A story's `f.schema` as structured-clone data. */\nexport interface SchemaDescription {\n nodes: DescribedShape;\n}\n\n/** Answers the workshop has for the rebuilt schema's predicates. */\nexport interface SchemaAnswers {\n hidden(path: string, config: unknown): boolean;\n errors(path: string, config: unknown): string[];\n}\n\nconst joinPath = (at: string, key: string): string => (at === '' ? key : `${at}.${key}`);\n\nfunction describeShape(shape: ConfigShape): DescribedShape {\n const out: DescribedShape = {};\n for (const [key, entry] of Object.entries(shape)) {\n const { section, showIf } = entry.options;\n const common = {\n annotations: { ...entry.annotations },\n ...(section === undefined ? {} : { section: { ...section } }),\n conditional: showIf !== undefined,\n };\n out[key] = isConfigBranch(entry)\n ? { branch: true, ...common, children: describeShape(entry.children) }\n : {\n branch: false,\n kind: entry.kind,\n default: entry.default,\n ...common,\n validated: entry.options.validate !== undefined,\n customControl: entry.options.render !== undefined,\n };\n }\n return out;\n}\n\nexport function describeSchema(schema: ConfigSchema<unknown>): SchemaDescription {\n return { nodes: describeShape(schema.nodes) };\n}\n\nfunction rebuildShape(shape: DescribedShape, at: string, answers: SchemaAnswers): ConfigShape {\n const out: Record<string, ConfigEntry> = {};\n for (const [key, entry] of Object.entries(shape)) {\n const path = joinPath(at, key);\n const options: NodeOptions = {\n ...(entry.section === undefined ? {} : { section: entry.section }),\n ...(entry.conditional ? { showIf: (config) => !answers.hidden(path, config) } : {}),\n };\n if (entry.branch) {\n const branch: ConfigBranch = {\n children: rebuildShape(entry.children, path, answers),\n annotations: entry.annotations,\n options,\n };\n out[key] = branch;\n } else {\n const node: ConfigNode = {\n kind: entry.kind,\n default: entry.default,\n annotations: entry.annotations,\n options: entry.validated ? { ...options, validate: (_leaf, config) => answers.errors(path, config) } : options,\n };\n out[key] = node;\n }\n }\n return out;\n}\n\nexport function schemaFromDescription(\n description: SchemaDescription,\n answers: SchemaAnswers,\n): ConfigSchema<unknown> {\n return f.schema(rebuildShape(description.nodes, '', answers)) as ConfigSchema<unknown>;\n}\n\n/** Evaluate a schema's own predicates for one config — the frame's half of `answers`. */\nexport function answerSchema(\n schema: ConfigSchema<unknown>,\n config: unknown,\n): { hidden: string[]; errors: Record<string, string[]> } {\n const hidden: string[] = [];\n const errors: Record<string, string[]> = {};\n const record = config as Record<string, unknown>;\n let group: ReturnType<typeof resolveConfigSchema>['group'] | undefined;\n\n const walk = (shape: ConfigShape, at: string): void => {\n for (const [key, entry] of Object.entries(shape)) {\n const path = joinPath(at, key);\n if (entry.options.showIf && !entry.options.showIf(record)) hidden.push(path);\n if (isConfigBranch(entry)) {\n walk(entry.children, path);\n continue;\n }\n const { validate } = entry.options;\n if (!validate) continue;\n group ??= resolveConfigSchema(schema).group;\n const leaf = schemaNodeAtPath(group, path);\n if (!leaf || 'children' in leaf) continue;\n const found = validate(leaf, record);\n if (found.length > 0) errors[path] = found;\n }\n };\n walk(schema.nodes, '');\n return { hidden, errors };\n}\n","import { type Envelope, PROTOCOL_VERSION } from './messages';\n\nexport interface PortLike {\n postMessage(message: unknown): void;\n addEventListener(type: 'message', fn: (event: MessageEvent) => void): void;\n removeEventListener(type: 'message', fn: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\nexport interface Channel<In, Out> {\n send(msg: Out): void;\n on(fn: (msg: In) => void): () => void;\n close(): void;\n}\n\nexport type Mismatch = { reason: 'not-an-envelope' } | { reason: 'version'; version: unknown };\n\nexport interface ChannelOptions {\n onMismatch?: (mismatch: Mismatch) => void;\n}\n\nexport function openChannel<In, Out>(port: PortLike, options: ChannelOptions = {}): Channel<In, Out> {\n const listeners = new Set<(msg: In) => void>();\n const onMessage = (event: MessageEvent) => {\n const data: unknown = event.data;\n if (typeof data !== 'object' || data === null || !('msg' in data)) {\n options.onMismatch?.({ reason: 'not-an-envelope' });\n return;\n }\n const envelope = data as Partial<Envelope<In>>;\n if (envelope.v !== PROTOCOL_VERSION) {\n options.onMismatch?.({ reason: 'version', version: envelope.v });\n return;\n }\n for (const fn of listeners) fn(envelope.msg as In);\n };\n port.addEventListener('message', onMessage);\n port.start?.();\n return {\n send: (msg) => port.postMessage({ v: PROTOCOL_VERSION, msg } satisfies Envelope<Out>),\n on: (fn) => {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n close: () => {\n port.removeEventListener('message', onMessage);\n listeners.clear();\n port.close();\n },\n };\n}\n","import { sanitize } from './ids';\nimport type { IndexEntry } from './types';\n\nconst SUFFIX = ':index';\n\n/** The name an index page goes by in the sidebar and in its trial's title. */\nexport const INDEX_NAME = 'Index';\n\n/** The id of `title`'s index page. A colon never survives `sanitize`, so no story id can collide with it. */\nexport function indexId(title: string): string {\n return `${sanitize(title)}${SUFFIX}`;\n}\n\nexport function isIndexId(id: string): boolean {\n return id.endsWith(SUFFIX);\n}\n\n/**\n * One index-page entry per title in `stories`, in the order titles first appear. It routes and runs like a story:\n * its `file` is the title's first story file, its descriptions are the title's own, and its tags are those every story\n * of the title carries.\n */\nexport function indexEntries(stories: readonly IndexEntry[]): IndexEntry[] {\n const byTitle = new Map<string, IndexEntry>();\n for (const entry of stories) {\n const page = byTitle.get(entry.title);\n if (page) {\n if (page.tags) {\n const common = page.tags.filter((tag) => entry.tags?.includes(tag));\n if (common.length > 0) page.tags = common;\n else delete page.tags;\n }\n continue;\n }\n byTitle.set(entry.title, {\n id: indexId(entry.title),\n title: entry.title,\n name: INDEX_NAME,\n exportName: '',\n file: entry.file,\n ...(entry.componentDescription === undefined ? {} : { componentDescription: entry.componentDescription }),\n ...(entry.componentName === undefined ? {} : { componentName: entry.componentName }),\n ...(entry.tags === undefined ? {} : { tags: entry.tags }),\n });\n }\n return [...byTitle.values()];\n}\n","/**\n * Which library a story file belongs to, by the package it lives in rather\n * than by its title's first segment. The title prefix is authored per story\n * and disagrees with itself — `packages/ui` alone declares both `Primitives/`\n * and `ui/` — so the path is the answer that cannot drift.\n */\nconst LIBRARIES: readonly (readonly [marker: string, label: string])[] = [\n ['/packages/ui/', 'ui'],\n ['/packages/labkit/', 'labkit'],\n ['/packages/forge/', 'forge'],\n ['/apps/draw/', 'draw'],\n ['/apps/forge/', 'forge'],\n];\n\n/** `entry`'s library, falling back to its title's first segment for a file\n * under none of the known packages. */\nexport function libraryOf(entry: { file: string; title: string }): string {\n const file = entry.file.replaceAll('\\\\', '/');\n for (const [marker, label] of LIBRARIES) {\n if (file.includes(marker)) return label;\n }\n return entry.title.split('/')[0] ?? entry.title;\n}\n","// The component's own entry, not the barrel: the barrel would bring every weasel-ui component into each frame.\nimport { Badge } from '@weasel-js/ui/components/Badge';\n\n/** `swatch` mixed toward the foreground, further in light mode: a bright swatch needs more of the dark foreground to\n * hold 4.5:1 as small text on its own tint, and a dark swatch less of the light one. */\nconst tone = (swatch: string, light: number, dark: number): string =>\n `light-dark(color-mix(in oklab, var(--wzl-swatch-${swatch}), var(--wzl-fg) ${light}%), ` +\n `color-mix(in oklab, var(--wzl-swatch-${swatch}), var(--wzl-fg) ${dark}%))`;\n\n/** Each package's peer tone. */\nconst LIBRARY_TONES: Readonly<Record<string, string>> = {\n ui: tone('amber', 55, 40),\n labkit: tone('teal', 55, 45),\n forge: tone('blue', 55, 35),\n draw: tone('rose', 55, 35),\n};\n\n/** A component's package, as a badge toned per package. */\nexport function LibraryBadge({ library, className }: { library: string; className?: string }) {\n return (\n <Badge status=\"muted\" tone={LIBRARY_TONES[library]} variant=\"subtle\" size=\"sm\" {...(className ? { className } : {})}>\n {library}\n </Badge>\n );\n}\n","import { type ConfigSchema, type ConfigShape, isConfigBranch, titleCase } from '@weasel-js/labkit/config';\nimport { isPlainObject } from '../../csf/isPlainObject';\n\nexport interface VariantValue {\n value: unknown;\n label: string;\n}\n\n/** One control a story is shown varying along, with every other control at its default. */\nexport interface VariantRow {\n /** Dotted, as `setConfig` takes it. */\n path: string;\n label: string;\n values: VariantValue[];\n}\n\n/** Above this many choices a row stops being something to scan. */\nexport const MAX_ENUM_OPTIONS = 8;\nexport const MAX_ROWS = 6;\n\nconst labelOf = (key: string, name: string | undefined): string => name ?? titleCase(key);\n\n/**\n * The boolean and enum controls of `schema` a story can be shown varying along, in schema order: skipped are\n * controls that draw their own row, controls hidden at the defaults, and enums with more than\n * `MAX_ENUM_OPTIONS` choices. At most `MAX_ROWS`.\n */\nexport function variantRows(schema: ConfigSchema<unknown>): VariantRow[] {\n const defaults = schema.defaults() as Record<string, unknown>;\n const rows: VariantRow[] = [];\n const walk = (shape: ConfigShape, at: string): void => {\n for (const [key, entry] of Object.entries(shape)) {\n if (rows.length >= MAX_ROWS) return;\n const path = at === '' ? key : `${at}.${key}`;\n if (entry.options.showIf && !entry.options.showIf(defaults)) continue;\n if (isConfigBranch(entry)) {\n walk(entry.children, path);\n continue;\n }\n if (entry.annotations.hidden || entry.options.render) continue;\n const label = labelOf(key, entry.annotations.name);\n if (entry.kind === 'boolean') {\n rows.push({ path, label, values: [false, true].map((value) => ({ value, label: String(value) })) });\n } else if (entry.kind === 'enum') {\n const options = entry.annotations.options ?? [];\n if (options.length < 2 || options.length > MAX_ENUM_OPTIONS) continue;\n rows.push({ path, label, values: options.map((o) => ({ value: o.value, label: o.label })) });\n }\n }\n };\n walk(schema.nodes, '');\n return rows;\n}\n\n/** `over` merged into `base`: nested plain objects merge, anything else replaces. */\nexport function mergeConfig(base: unknown, over: unknown): unknown {\n if (!isPlainObject(base) || !isPlainObject(over)) return over === undefined ? base : over;\n const out: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(over)) out[key] = mergeConfig(base[key], value);\n return out;\n}\n\n/** `config` with `value` at dotted `path`, copying each object along the way. */\nexport function withValueAt(config: unknown, path: string, value: unknown): unknown {\n const [head, ...rest] = path.split('.');\n if (head === undefined) return value;\n const record = isPlainObject(config) ? config : {};\n return { ...record, [head]: rest.length === 0 ? value : withValueAt(record[head], rest.join('.'), value) };\n}\n","// The components' own entries, not the barrel: the barrel would bring every weasel-ui component into each frame.\nimport { Badge } from '@weasel-js/ui/components/Badge';\nimport { Button } from '@weasel-js/ui/components/Button';\nimport {\n createContext,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { Globals } from '../../protocol/messages';\nimport { indexId } from '../../story/indexPages';\nimport type { ComponentDeps, Decorator, IndexContext, IndexStoryProps, LoadedStory, StoryContext } from '../../story/types';\nimport { StoryHost } from '../StoryHost';\nimport { mergeConfig, variantRows, withValueAt } from './variants';\nimport './index.css';\nimport { LibraryBadge } from './LibraryBadge';\n\n/** What every cell on an index page shares with the frame that hosts it. */\nexport interface IndexEnv {\n title: string;\n /** The package the component ships in. */\n library?: string;\n description?: string;\n stories: readonly LoadedStory[];\n /** Per story id, the JSDoc above its export. */\n descriptions: Readonly<Record<string, string>>;\n /** A catalog or showcase rather than one component: every story of it is tagged `gallery`. */\n gallery?: boolean;\n /** The ids of the stories tagged `gallery`. */\n galleries?: readonly string[];\n /** The component's place in the component graph; absent until the graph arrives, and for a gallery. */\n dependencies?: ComponentDeps;\n globals: Globals;\n /** The frame config's, outermost. */\n decorators: readonly Decorator[];\n open: (id: string) => void;\n onError: (error: unknown) => void;\n}\n\nexport const IndexEnvContext = createContext<IndexEnv | null>(null);\n\nfunction useEnv(): IndexEnv {\n const env = useContext(IndexEnvContext);\n if (!env) throw new Error('An index page part rendered outside its index page');\n return env;\n}\n\n/** How far past the viewport a cell stays mounted. */\nconst NEAR_MARGIN = '100%';\n\n/** Whether `ref`'s element is near the viewport; true where the browser cannot say. */\nfunction useNearViewport(ref: RefObject<Element | null>): boolean {\n const [near, setNear] = useState(typeof IntersectionObserver === 'undefined');\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof IntersectionObserver === 'undefined') return;\n const observer = new IntersectionObserver((entries) => {\n const last = entries.at(-1);\n if (last) setNear(last.isIntersecting);\n }, { rootMargin: NEAR_MARGIN });\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref]);\n return near;\n}\n\n/**\n * One story at its defaults with `config` over them. It keeps its own config and state, so it stays interactive, and\n * it mounts only while near the viewport, so a page of canvas stories stays under the browser's WebGL context cap.\n */\nexport function IndexStory({ story, config: over, label }: IndexStoryProps) {\n const env = useEnv();\n const [config, setConfig] = useState(() => mergeConfig(story.config.defaults(), over));\n const [state, setState] = useState<unknown>(() => story.initialState?.(config) ?? null);\n const cell = useRef<HTMLElement>(null);\n const near = useNearViewport(cell);\n // Held while unmounted, so scrolling past a cell does not move everything after it.\n const [height, setHeight] = useState<number | null>(null);\n useEffect(() => {\n const el = cell.current;\n if (!near || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setHeight(el.getBoundingClientRect().height));\n observer.observe(el);\n return () => observer.disconnect();\n }, [near]);\n const ctx: StoryContext = {\n config,\n setConfig: (path, value) => setConfig((prev: unknown) => withValueAt(prev, path, value)),\n state,\n setState: (next) =>\n setState((prev: unknown) => (typeof next === 'function' ? (next as (p: unknown) => unknown)(prev) : next)),\n globals: env.globals,\n title: story.title,\n name: story.name,\n };\n return (\n <figure\n ref={cell}\n className={`fg-index-cell fg-index-cell--${story.layout}`}\n style={!near && height !== null ? { minHeight: height } : undefined}\n >\n <div className=\"fg-index-cell__stage\">\n {near ? (\n <StoryHost story={story} ctx={ctx} decorators={env.decorators} resetKey={0} onError={env.onError} />\n ) : null}\n </div>\n {label === undefined ? null : <figcaption className=\"fg-index-cell__label\">{label}</figcaption>}\n </figure>\n );\n}\n\n/** `story` once per value of each boolean and enum control, every other control at its default. */\nexport function IndexVariants({ story }: { story: LoadedStory }) {\n const rows = useMemo(() => variantRows(story.config), [story]);\n const defaults = useMemo(() => story.config.defaults(), [story]);\n if (rows.length === 0) return null;\n return (\n <div className=\"fg-index-variants\">\n {rows.map((row) => (\n <section key={row.path} className=\"fg-index-variants__row\" aria-label={row.label}>\n <h4 className=\"fg-index-variants__label\">{row.label}</h4>\n <div className=\"fg-index-variants__cells\">\n {row.values.map((v) => (\n <IndexStory\n key={String(v.value)}\n story={story}\n config={withValueAt(defaults, row.path, v.value) as Record<string, unknown>}\n label={v.label}\n />\n ))}\n </div>\n </section>\n ))}\n </div>\n );\n}\n\nfunction GalleryBadge() {\n return (\n <Badge status=\"accent\" variant=\"subtle\" size=\"sm\">\n Gallery\n </Badge>\n );\n}\n\nfunction DependencyList({ label, titles, empty }: { label: string; titles: readonly string[]; empty: string }) {\n const env = useEnv();\n const labelId = useId();\n const follow = (event: MouseEvent, id: string) => {\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n event.preventDefault();\n env.open(id);\n };\n return (\n <div className=\"fg-index-deps__row\">\n <dt id={labelId} className=\"fg-index-deps__label\">\n {label}\n </dt>\n <dd className=\"fg-index-deps__value\">\n {titles.length === 0 ? (\n <span className=\"fg-index-deps__empty\">{empty}</span>\n ) : (\n <ul className=\"fg-index-deps__list\" aria-labelledby={labelId}>\n {titles.map((title) => {\n const cut = title.lastIndexOf('/') + 1;\n const id = indexId(title);\n return (\n <li key={title}>\n <a className=\"fg-index-deps__link\" href={`#/${encodeURIComponent(id)}`} onClick={(event) => follow(event, id)}>\n <span className=\"fg-index-deps__prefix\">{title.slice(0, cut)}</span>\n {title.slice(cut)}\n </a>\n </li>\n );\n })}\n </ul>\n )}\n </dd>\n </div>\n );\n}\n\n/** The listed components this one uses and those that use it, read from source. Nothing for a gallery. */\nexport function IndexDependencies() {\n const { gallery, dependencies } = useEnv();\n if (gallery || !dependencies) return null;\n if (dependencies.source === null) {\n return (\n <p className=\"fg-index-deps__none\">\n forge found no source file for this component, so it lists none of its dependencies. It looks for the\n import the meta’s <code>component</code> names, or else the one the title’s last segment names.\n </p>\n );\n }\n return (\n <dl className=\"fg-index-deps\" aria-label=\"Dependencies\">\n <DependencyList label=\"Uses\" titles={dependencies.uses} empty=\"No listed component.\" />\n <DependencyList label=\"Used by\" titles={dependencies.usedBy} empty=\"No listed component uses it.\" />\n </dl>\n );\n}\n\nfunction StorySection({ story, variants }: { story: LoadedStory; variants: boolean }) {\n const env = useEnv();\n const headingId = useId();\n const description = env.descriptions[story.id];\n const gallery = !env.gallery && env.galleries?.includes(story.id);\n return (\n <section className=\"fg-index-story\" aria-labelledby={headingId}>\n <header className=\"fg-index-story__head\">\n <h2 id={headingId} className=\"fg-index-story__name\">\n {story.name}\n </h2>\n {gallery ? <GalleryBadge /> : null}\n <Button variant=\"secondary\" size=\"sm\" onClick={() => env.open(story.id)}>\n Open\n </Button>\n </header>\n {description ? <p className=\"fg-index-story__description\">{description}</p> : null}\n <IndexStory story={story} />\n {variants ? <IndexVariants story={story} /> : null}\n </section>\n );\n}\n\n/** Which of `stories` show their variants: the first of each set of controls. Stories of one CSF file share their\n * meta's controls, and the same rows under every story would only repeat. */\nfunction firstOfEachControlSet(stories: readonly LoadedStory[]): Set<string> {\n const seen = new Set<string>();\n const shown = new Set<string>();\n for (const story of stories) {\n const key = JSON.stringify(variantRows(story.config));\n if (seen.has(key)) continue;\n seen.add(key);\n shown.add(story.id);\n }\n return shown;\n}\n\n/** The generated page: the component's title and description, then each story, with the variants of the first of\n * each set of controls. */\nexport function DefaultIndex() {\n const env = useEnv();\n const withVariants = useMemo(() => firstOfEachControlSet(env.stories), [env.stories]);\n const segments = env.title.split('/');\n const name = segments.pop();\n const { library } = env;\n if (library !== undefined && segments[0] === library) segments.shift();\n return (\n <article className=\"fg-index\">\n <header className=\"fg-index__head\">\n {segments.length > 0 || library !== undefined ? (\n <p className=\"fg-index__path\">\n {library !== undefined ? <LibraryBadge library={library} className=\"fg-index__library\" /> : null}\n {segments.join(' / ')}\n </p>\n ) : null}\n <div className=\"fg-index__title-row\">\n <h1 className=\"fg-index__title\">{name}</h1>\n {env.gallery ? <GalleryBadge /> : null}\n </div>\n {env.description ? <p className=\"fg-index__description\">{env.description}</p> : null}\n <IndexDependencies />\n </header>\n {env.stories.map((story) => (\n <StorySection key={story.id} story={story} variants={withVariants.has(story.id)} />\n ))}\n </article>\n );\n}\n\n/** What a component's own index page is handed. */\nexport function indexContext(env: IndexEnv): IndexContext {\n return {\n title: env.title,\n ...(env.description === undefined ? {} : { description: env.description }),\n stories: env.stories,\n globals: env.globals,\n Story: IndexStory,\n Variants: IndexVariants,\n DefaultIndex,\n Dependencies: IndexDependencies,\n gallery: env.gallery ?? false,\n open: env.open,\n };\n}\n\n/** The page itself: the component's own, or the generated one. */\nexport function IndexPage({ env, render }: { env: IndexEnv; render: ((ctx: IndexContext) => ReactNode) | null }) {\n return (\n <IndexEnvContext.Provider value={env}>{render ? render(indexContext(env)) : <DefaultIndex />}</IndexEnvContext.Provider>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNative } from './chunk-
|
|
1
|
+
import { isNative } from './chunk-Y3WZ2EWR.js';
|
|
2
2
|
import { storyNameFromExport, storyId } from './chunk-HRGPFQBW.js';
|
|
3
3
|
import { isPlainObject, portSafePart, appliedLocal, withUnsent, coverOf, ArgsContext } from './chunk-YKN3IAEX.js';
|
|
4
4
|
import { createContext, Component, createElement, useContext, useState, useEffect } from 'react';
|
|
@@ -495,5 +495,5 @@ function indexRenderOf(mod) {
|
|
|
495
495
|
}
|
|
496
496
|
|
|
497
497
|
export { StoryHost, captureElement, createGlobalsTarget, createOverrides, indexRenderOf, loadStories, resolveCssVar, runAxe, scanCssVars };
|
|
498
|
-
//# sourceMappingURL=chunk-
|
|
499
|
-
//# sourceMappingURL=chunk-
|
|
498
|
+
//# sourceMappingURL=chunk-NYBMOSSR.js.map
|
|
499
|
+
//# sourceMappingURL=chunk-NYBMOSSR.js.map
|