@gtkx/storybook 2.0.0-beta.11 → 2.0.0-beta.12

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 CHANGED
@@ -1,17 +1,17 @@
1
1
  # @gtkx/storybook
2
2
 
3
- Explore GTKX components as native stories.
3
+ Native component stories for GTKX.
4
4
 
5
- Write Component Story Format stories, open them with `gtkx storybook`, and change props through Controls. Actions record interactions, and portable stories can also serve as native integration-test fixtures.
5
+ Write Component Story Format stories, open them with `gtkx storybook`, and change props through Controls. Actions record interactions. Use `composeStories` to render the same stories in native integration tests.
6
6
 
7
- In an existing GTKX 2.0 beta app:
7
+ In an existing GTKX app:
8
8
 
9
9
  ```sh
10
- npm install @gtkx/storybook@beta
10
+ npm install -D @gtkx/storybook@beta
11
11
  ```
12
12
 
13
13
  [Guide](https://gtkx.dev/v2/guide/storybook) · [API reference](https://gtkx.dev/v2/reference/@gtkx/storybook/) · [GTKX](https://gtkx.dev)
14
14
 
15
- GTKX runs on Linux with Node.js and system native libraries. See [Getting Started](https://gtkx.dev/v2/guide/getting-started) for supported versions and installation. This README describes the 2.0 beta.
15
+ GTKX requires Linux, Node.js, and the [native prerequisites](https://gtkx.dev/v2/guide/getting-started).
16
16
 
17
17
  [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
@@ -1 +1 @@
1
- {"version":3,"file":"actions-panel.d.ts","sourceRoot":"","sources":["../src/actions-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,QAAA,MAAM,YAAY,GAAI,WAAW;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,KAAG,SAsBzD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"actions-panel.d.ts","sourceRoot":"","sources":["../src/actions-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,QAAA,MAAM,YAAY,cAAe;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,KAAG,SAsBzD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,WAAW,GAAG;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,qFAAqF;AACrF,KAAK,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AA6CnD;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM,GAAI,MAAM,MAAM,KAAG,cAW9B,CAAC;AAEF,cAAM,WAAW;IACb,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,MAAM,CAAK;IAEnB,WAAW,QAAO,WAAW,EAAE,CAAiB;IAEhD,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAM9C;IAEF,KAAK,QAAO,IAAI,CAEd;IAEF,OAAO,CAAC,OAAO;IAQf,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;CAS7D;AAmFD,QAAA,MAAM,WAAW,GACb,MAAM,IAAI,EACV,UAAU,QAAQ,EAClB,OAAO,WAAW,EAClB,UAAU,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,KACjC,IAiBF,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,WAAW,GAAG;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,qFAAqF;AACrF,KAAK,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AA6CnD;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM,SAAU,MAAM,KAAG,cAW9B,CAAC;AAEF,cAAM,WAAW;IACb,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,MAAM,CAAK;IAEnB,WAAW,QAAO,WAAW,EAAE,CAAiB;IAEhD,SAAS,aAAc,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAM9C;IAEF,KAAK,QAAO,IAAI,CAEd;IAEF,OAAO,CAAC,OAAO;IAQf,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAQzD;CACJ;AAkFD,QAAA,MAAM,WAAW,SAAU,IAAI,YAAY,QAAQ,SAAS,WAAW,YAAY,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,KAAG,IAiB3G,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,CAAC"}
package/dist/actions.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { normalizeError } from "@gtkx/utils";
1
2
  import { AsyncLocalStorage } from "node:async_hooks";
2
3
  import { inspect } from "node:util";
3
4
  const actionNames = new WeakMap();
@@ -98,7 +99,7 @@ const bindCallback = (store, options) => (...values) => {
98
99
  store.record(options.name, values);
99
100
  };
100
101
  const fail = (cause) => {
101
- const error = cause instanceof Error ? cause : new Error(String(cause));
102
+ const error = normalizeError(cause);
102
103
  store.record(options.name, values, error);
103
104
  if (options.onError === undefined) {
104
105
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { inspect } from \"node:util\";\nimport type { Args, ArgTypes } from \"./types.js\";\n\ntype ActionEntry = {\n id: number;\n name: string;\n args: string[];\n error?: string;\n};\n\n/** A named story callback whose arguments can be recorded by the native explorer. */\ntype ActionCallback = (...args: unknown[]) => void;\ntype EventCallback = (...args: unknown[]) => unknown;\n\nconst actionNames: WeakMap<object, string> = new WeakMap();\nconst actionScope: AsyncLocalStorage<ActionStore> = new AsyncLocalStorage();\nconst DEFAULT_HISTORY_LIMIT = 100;\nconst MAX_ARGUMENT_LENGTH = 400;\n\nconst objectLabel = (value: unknown): string | undefined => {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n\n const prototype: unknown = Object.getPrototypeOf(value);\n\n if (prototype === null || typeof prototype !== \"object\" || prototype === Object.prototype) {\n return undefined;\n }\n\n const constructor: unknown = Object.getOwnPropertyDescriptor(prototype, \"constructor\")?.value;\n\n return typeof constructor === \"function\" ? `[${constructor.name}]` : \"[Object]\";\n};\n\nconst formatArgument = (value: unknown): string => {\n try {\n const label = objectLabel(value);\n\n if (label !== undefined) {\n return label;\n }\n\n return inspect(value, {\n depth: 1,\n maxArrayLength: 5,\n maxStringLength: 120,\n customInspect: false,\n getters: false,\n breakLength: Infinity,\n }).slice(0, MAX_ARGUMENT_LENGTH);\n } catch {\n return \"[Unreadable value]\";\n }\n};\n\n/**\n * Creates a named action for a story's callback arguments.\n * The explorer records bounded argument summaries; calls outside its action scope have no effect.\n *\n * @param name Nonempty label displayed in the Actions panel.\n * @returns A callback to supply in story args.\n * @throws If the name is empty or contains only whitespace.\n */\nconst action = (name: string): ActionCallback => {\n if (name.trim().length === 0) {\n throw new TypeError(\"An action needs a name\");\n }\n\n const callback: ActionCallback = (...args) => {\n actionScope.getStore()?.record(name, args);\n };\n actionNames.set(callback, name);\n\n return callback;\n};\n\nclass ActionStore {\n private entries: ActionEntry[] = [];\n private readonly listeners: Set<() => void> = new Set();\n private nextId = 0;\n\n getSnapshot = (): ActionEntry[] => this.entries;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n clear = (): void => {\n this.publish([]);\n };\n\n private publish(entries: ActionEntry[]): void {\n this.entries = entries;\n\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n record(name: string, args: unknown[], error?: Error): void {\n const entry: ActionEntry = {\n id: this.nextId++,\n name,\n args: args.slice(0, 8).map((value) => formatArgument(value)),\n ...(error !== undefined && { error: error.message.slice(0, MAX_ARGUMENT_LENGTH) }),\n };\n this.publish([...this.entries, entry].slice(-DEFAULT_HISTORY_LIMIT));\n }\n}\n\ntype CallbackOptions = { callback?: EventCallback; name: string; onError?: (error: Error) => void };\n\nconst settleCallback = async (\n result: Promise<unknown>,\n succeed: () => void,\n fail: (cause: unknown) => void,\n): Promise<unknown> => {\n try {\n const value = await result;\n succeed();\n\n return value;\n } catch (error) {\n fail(error);\n\n return undefined;\n }\n};\n\nconst bindCallback = (\n store: ActionStore,\n options: CallbackOptions,\n): EventCallback => (...values) => {\n const succeed = (): void => {\n store.record(options.name, values);\n };\n const fail = (cause: unknown): void => {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n store.record(options.name, values, error);\n\n if (options.onError === undefined) {\n throw error;\n }\n\n options.onError(error);\n };\n\n try {\n const result = actionScope.run(store, () => options.callback?.(...values));\n\n if (result instanceof Promise) {\n return settleCallback(result, succeed, fail);\n }\n\n succeed();\n\n return result;\n } catch (error) {\n fail(error);\n\n return;\n }\n};\n\nconst actionName = (value: unknown, configuredName: unknown): string | undefined => {\n if (typeof configuredName === \"string\") {\n return configuredName;\n }\n\n return typeof value === \"function\" ? actionNames.get(value) : undefined;\n};\n\nconst isOriginalCallback = (value: unknown): value is EventCallback =>\n typeof value === \"function\" && !actionNames.has(value);\n\nconst callbackOptions = (\n value: unknown,\n name: string | undefined,\n onError: ((error: Error) => void) | undefined,\n): CallbackOptions | undefined => {\n if (name === undefined) {\n return undefined;\n }\n\n return {\n name,\n ...(isOriginalCallback(value) && { callback: value }),\n ...(onError !== undefined && { onError }),\n };\n};\n\nconst bindActions = (\n args: Args,\n argTypes: ArgTypes,\n store: ActionStore,\n onError?: (error: Error) => void,\n): Args => {\n const bound = { ...args };\n const names = new Set([...Object.keys(args), ...Object.keys(argTypes)]);\n\n for (const argument of names) {\n const value = args[argument];\n const name = actionName(value, argTypes[argument]?.action);\n const options = callbackOptions(value, name, onError);\n\n if (options === undefined) {\n continue;\n }\n\n bound[argument] = bindCallback(store, options);\n }\n\n return bound;\n};\n\nexport { action, ActionStore, bindActions };\nexport type { ActionCallback };\n"]}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeError } from \"@gtkx/utils\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { inspect } from \"node:util\";\nimport type { Args, ArgTypes } from \"./types.js\";\n\ntype ActionEntry = {\n id: number;\n name: string;\n args: string[];\n error?: string;\n};\n\n/** A named story callback whose arguments can be recorded by the native explorer. */\ntype ActionCallback = (...args: unknown[]) => void;\ntype EventCallback = (...args: unknown[]) => unknown;\n\nconst actionNames: WeakMap<object, string> = new WeakMap();\nconst actionScope: AsyncLocalStorage<ActionStore> = new AsyncLocalStorage();\nconst DEFAULT_HISTORY_LIMIT = 100;\nconst MAX_ARGUMENT_LENGTH = 400;\n\nconst objectLabel = (value: unknown): string | undefined => {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n\n const prototype: unknown = Object.getPrototypeOf(value);\n\n if (prototype === null || typeof prototype !== \"object\" || prototype === Object.prototype) {\n return undefined;\n }\n\n const constructor: unknown = Object.getOwnPropertyDescriptor(prototype, \"constructor\")?.value;\n\n return typeof constructor === \"function\" ? `[${constructor.name}]` : \"[Object]\";\n};\n\nconst formatArgument = (value: unknown): string => {\n try {\n const label = objectLabel(value);\n\n if (label !== undefined) {\n return label;\n }\n\n return inspect(value, {\n depth: 1,\n maxArrayLength: 5,\n maxStringLength: 120,\n customInspect: false,\n getters: false,\n breakLength: Infinity,\n }).slice(0, MAX_ARGUMENT_LENGTH);\n } catch {\n return \"[Unreadable value]\";\n }\n};\n\n/**\n * Creates a named action for a story's callback arguments.\n * The explorer records bounded argument summaries; calls outside its action scope have no effect.\n *\n * @param name Nonempty label displayed in the Actions panel.\n * @returns A callback to supply in story args.\n * @throws If the name is empty or contains only whitespace.\n */\nconst action = (name: string): ActionCallback => {\n if (name.trim().length === 0) {\n throw new TypeError(\"An action needs a name\");\n }\n\n const callback: ActionCallback = (...args) => {\n actionScope.getStore()?.record(name, args);\n };\n actionNames.set(callback, name);\n\n return callback;\n};\n\nclass ActionStore {\n private entries: ActionEntry[] = [];\n private readonly listeners: Set<() => void> = new Set();\n private nextId = 0;\n\n getSnapshot = (): ActionEntry[] => this.entries;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n clear = (): void => {\n this.publish([]);\n };\n\n private publish(entries: ActionEntry[]): void {\n this.entries = entries;\n\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n record(name: string, args: unknown[], error?: Error): void {\n const entry: ActionEntry = {\n id: this.nextId++,\n name,\n args: args.slice(0, 8).map((value) => formatArgument(value)),\n ...(error !== undefined && { error: error.message.slice(0, MAX_ARGUMENT_LENGTH) }),\n };\n this.publish([...this.entries, entry].slice(-DEFAULT_HISTORY_LIMIT));\n }\n}\n\ntype CallbackOptions = { callback?: EventCallback; name: string; onError?: (error: Error) => void };\n\nconst settleCallback = async (\n result: Promise<unknown>,\n succeed: () => void,\n fail: (cause: unknown) => void,\n): Promise<unknown> => {\n try {\n const value = await result;\n succeed();\n\n return value;\n } catch (error) {\n fail(error);\n\n return undefined;\n }\n};\n\nconst bindCallback =\n (store: ActionStore, options: CallbackOptions): EventCallback =>\n (...values) => {\n const succeed = (): void => {\n store.record(options.name, values);\n };\n const fail = (cause: unknown): void => {\n const error = normalizeError(cause);\n store.record(options.name, values, error);\n\n if (options.onError === undefined) {\n throw error;\n }\n\n options.onError(error);\n };\n\n try {\n const result = actionScope.run(store, () => options.callback?.(...values));\n\n if (result instanceof Promise) {\n return settleCallback(result, succeed, fail);\n }\n\n succeed();\n\n return result;\n } catch (error) {\n fail(error);\n\n return;\n }\n };\n\nconst actionName = (value: unknown, configuredName: unknown): string | undefined => {\n if (typeof configuredName === \"string\") {\n return configuredName;\n }\n\n return typeof value === \"function\" ? actionNames.get(value) : undefined;\n};\n\nconst isOriginalCallback = (value: unknown): value is EventCallback =>\n typeof value === \"function\" && !actionNames.has(value);\n\nconst callbackOptions = (\n value: unknown,\n name: string | undefined,\n onError: ((error: Error) => void) | undefined,\n): CallbackOptions | undefined => {\n if (name === undefined) {\n return undefined;\n }\n\n return {\n name,\n ...(isOriginalCallback(value) && { callback: value }),\n ...(onError !== undefined && { onError }),\n };\n};\n\nconst bindActions = (args: Args, argTypes: ArgTypes, store: ActionStore, onError?: (error: Error) => void): Args => {\n const bound = { ...args };\n const names = new Set([...Object.keys(args), ...Object.keys(argTypes)]);\n\n for (const argument of names) {\n const value = args[argument];\n const name = actionName(value, argTypes[argument]?.action);\n const options = callbackOptions(value, name, onError);\n\n if (options === undefined) {\n continue;\n }\n\n bound[argument] = bindCallback(store, options);\n }\n\n return bound;\n};\n\nexport { action, ActionStore, bindActions };\nexport type { ActionCallback };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAiB,aAAa,EAAE,OAAO,EAAoB,MAAM,YAAY,CAAC;AAI1G,oEAAoE;AACpE,KAAK,WAAW,GAAG;IACf,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,4EAA4E;AAC5E,KAAK,UAAU,GAAG;IACd,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,EAAE,aAAa,CAAC;IACrB,uEAAuE;IACvE,QAAQ,EAAE,QAAQ,CAAC;CACtB,CAAC;AAEF,mFAAmF;AACnF,KAAK,cAAc,GAAG;IAClB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,0EAA0E;AAC1E,KAAK,oBAAoB,GAAG;IACxB,yEAAyE;IACzE,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,8EAA8E;IAC9E,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AA0IF,uEAAuE;AACvE,cAAM,YAAY;IACd,OAAO,CAAC,QAAQ,CAAuE;IACvF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAK;IAErB,kFAAkF;IAClF,WAAW,QAAO,oBAAoB,CAAkB;IAExD,iFAAiF;IACjF,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAM9C;IAEF,OAAO,CAAC,OAAO;IAQf;;;;OAIG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE,OAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnF;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;CAcpC;AAED,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,QAAQ,EAAiB,aAAa,EAAE,OAAO,EAAoB,MAAM,YAAY,CAAC;AAI1G,oEAAoE;AACpE,KAAK,WAAW,GAAG;IACf,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,4EAA4E;AAC5E,KAAK,UAAU,GAAG;IACd,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,EAAE,aAAa,CAAC;IACrB,uEAAuE;IACvE,QAAQ,EAAE,QAAQ,CAAC;CACtB,CAAC;AAEF,mFAAmF;AACnF,KAAK,cAAc,GAAG;IAClB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,0EAA0E;AAC1E,KAAK,oBAAoB,GAAG;IACxB,yEAAyE;IACzE,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,8EAA8E;IAC9E,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AA6IF,uEAAuE;AACvE,cAAM,YAAY;IACd,OAAO,CAAC,QAAQ,CAAuE;IACvF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAK;IAErB,kFAAkF;IAClF,WAAW,QAAO,oBAAoB,CAAkB;IAExD,iFAAiF;IACjF,SAAS,aAAc,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAM9C;IAEF,OAAO,CAAC,OAAO;IAQf;;;;OAIG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE,OAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBlF;IAED;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAahC;CACJ;AAED,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}
package/dist/catalog.js CHANGED
@@ -1,13 +1,14 @@
1
+ import { normalizeError } from "@gtkx/utils";
1
2
  import { composeStories } from "./compose.js";
2
3
  import { storyNameFromExport } from "./upstream.js";
3
4
  const EMPTY_PREVIEW = {};
4
- const normalizeError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
5
5
  const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6
6
  const explicitControls = (resolved, story, meta, preview) => {
7
7
  const controls = {};
8
8
  for (const [argument, annotation] of Object.entries(resolved)) {
9
9
  const control = story?.argTypes?.[argument]?.control ??
10
- meta.argTypes?.[argument]?.control ?? preview.argTypes?.[argument]?.control;
10
+ meta.argTypes?.[argument]?.control ??
11
+ preview.argTypes?.[argument]?.control;
11
12
  if (control === undefined) {
12
13
  continue;
13
14
  }
@@ -81,8 +82,10 @@ const loadSource = async (source, preview, getCache) => {
81
82
  try {
82
83
  const module = await source.load();
83
84
  const previous = getCache().get(source.id);
84
- const cached = previous !== undefined && previous.module === module &&
85
- previous.title === source.title && previous.preview === preview
85
+ const cached = previous !== undefined &&
86
+ previous.module === module &&
87
+ previous.title === source.title &&
88
+ previous.preview === preview
86
89
  ? previous
87
90
  : { module, title: source.title, preview, entries: composeSource(source, module, preview) };
88
91
  return { source, cached };
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Args, ArgTypes, ComponentMeta, ComposedStory, Preview, StoryAnnotations } from \"./types.js\";\nimport { composeStories } from \"./compose.js\";\nimport { storyNameFromExport } from \"./upstream.js\";\n\n/** A lazily loaded CSF module discovered in a Storybook project. */\ntype StorySource = {\n /** Stable module identifier used for caching and error reporting. */\n id: string;\n /** Fallback story group title when the module does not declare one. */\n title: string;\n /** Imports the module and resolves to its CSF exports. */\n load: () => Promise<unknown>;\n};\n\n/** A composed story and the metadata used to display it in the explorer. */\ntype StoryEntry = {\n /** Storybook identifier used to preserve the selected story across updates. */\n id: string;\n /** Component group title declared by the module or derived from its source. */\n title: string;\n /** Display name declared by the story or derived from its export name. */\n name: string;\n /** Name of the CSF export that defines this story. */\n exportName: string;\n /** Identifier of the module containing this story. */\n source: string;\n /** Renderable story with its metadata, decorators, and default args composed. */\n story: ComposedStory;\n /** Resolved arg types with explicitly configured explorer controls. */\n controls: ArgTypes;\n};\n\n/** A source loading or composition failure displayed alongside healthy stories. */\ntype StoryLoadError = {\n /** Identifier of the failed source, or Storybook for a session failure. */\n source: string;\n /** Normalized error raised while loading or composing the source. */\n error: Error;\n};\n\n/** Current explorer contents and loading state exposed to subscribers. */\ntype StoryCatalogSnapshot = {\n /** Successfully composed stories with duplicate identifiers excluded. */\n stories: StoryEntry[];\n /** Failures encountered during the latest load or reported by the session. */\n errors: StoryLoadError[];\n /** Whether the catalog is waiting for the latest source load to finish. */\n isLoading: boolean;\n};\n\ntype CachedStories = {\n module: unknown;\n title: string;\n preview: Preview;\n entries: StoryEntry[];\n};\n\ntype LoadedSource = StoryLoadError | { source: StorySource; cached: CachedStories };\n\nconst EMPTY_PREVIEW: Preview = {};\n\nconst normalizeError = (cause: unknown): Error => cause instanceof Error ? cause : new Error(String(cause));\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst explicitControls = (\n resolved: ArgTypes,\n story: StoryAnnotations<Args> | undefined,\n meta: ComponentMeta<Args>,\n preview: Preview,\n): ArgTypes => {\n const controls: ArgTypes = {};\n\n for (const [argument, annotation] of Object.entries(resolved)) {\n const control = story?.argTypes?.[argument]?.control ??\n meta.argTypes?.[argument]?.control ?? preview.argTypes?.[argument]?.control;\n\n if (control === undefined) {\n continue;\n }\n\n controls[argument] = { ...annotation, control: control !== false && (annotation?.control ?? control) };\n }\n\n return controls;\n};\n\nconst displayName = (story: StoryAnnotations<Args> | undefined, exportName: string): string => {\n const name = story?.name;\n\n if (name === undefined) {\n return storyNameFromExport(exportName);\n }\n\n if (typeof name !== \"string\") {\n throw new TypeError(\"Expected a story display name\");\n }\n\n return name;\n};\n\nconst composeSource = (source: StorySource, module: unknown, preview: Preview): StoryEntry[] => {\n if (!isObject(module) || !isObject(module.default)) {\n throw new TypeError(`Expected CSF3 component metadata in ${source.id}`);\n }\n\n const title = module.default.title ?? source.title;\n\n if (typeof title !== \"string\" || title.trim().length === 0) {\n throw new TypeError(`Expected a story title in ${source.id}`);\n }\n\n const annotations = {\n ...module,\n default: { ...module.default, title },\n } as Record<string, StoryAnnotations<Args>> & { default: ComponentMeta<Args> };\n const stories = composeStories(annotations, preview);\n\n return Object.entries(stories).map(([exportName, story]) => ({\n id: story.id,\n title,\n name: displayName(annotations[exportName], exportName),\n exportName,\n source: source.id,\n story,\n controls: explicitControls(story.argTypes, annotations[exportName], annotations.default, preview),\n }));\n};\n\nconst withoutDuplicateIds = (entries: StoryEntry[], errors: StoryLoadError[]): StoryEntry[] => {\n const counts: Map<string, number> = new Map();\n\n for (const entry of entries) {\n counts.set(entry.id, (counts.get(entry.id) ?? 0) + 1);\n }\n\n return entries.filter((entry) => {\n if (counts.get(entry.id) === 1) {\n return true;\n }\n\n errors.push({ source: entry.source, error: new Error(`Duplicate story ID: ${entry.id}`) });\n\n return false;\n });\n};\n\nconst collectSources = (loaded: LoadedSource[]) => {\n const cache: Map<string, CachedStories> = new Map();\n const entries: StoryEntry[] = [];\n const errors: StoryLoadError[] = [];\n\n for (const result of loaded) {\n if (\"error\" in result) {\n errors.push(result);\n } else {\n cache.set(result.source.id, result.cached);\n entries.push(...result.cached.entries);\n }\n }\n\n return { cache, stories: withoutDuplicateIds(entries, errors), errors };\n};\n\nconst createSourceCache = (): Map<string, CachedStories> => new Map();\n\nconst loadSource = async (\n source: StorySource,\n preview: Preview,\n getCache: () => Map<string, CachedStories>,\n): Promise<LoadedSource> => {\n try {\n const module = await source.load();\n const previous = getCache().get(source.id);\n const cached = previous !== undefined && previous.module === module &&\n previous.title === source.title && previous.preview === preview\n ? previous\n : { module, title: source.title, preview, entries: composeSource(source, module, preview) };\n\n return { source, cached };\n } catch (error) {\n return { source: source.id, error: normalizeError(error) };\n }\n};\n\n/** Loads CSF modules and publishes subscribable explorer snapshots. */\nclass StoryCatalog {\n private snapshot: StoryCatalogSnapshot = { stories: [], errors: [], isLoading: false };\n private readonly listeners: Set<() => void> = new Set();\n private readonly loadFailures: WeakSet<Error> = new WeakSet();\n private cache = createSourceCache();\n private sessionError: StoryLoadError | undefined;\n private revision = 0;\n\n /** Returns the current snapshot, retaining its identity until the next update. */\n getSnapshot = (): StoryCatalogSnapshot => this.snapshot;\n\n /** Registers a snapshot listener and returns a function that unsubscribes it. */\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private publish(snapshot: StoryCatalogSnapshot): void {\n this.snapshot = snapshot;\n\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n /**\n * Replaces the catalog with stories composed from the supplied sources and preview.\n * Only the latest load publishes results; unchanged module identities reuse composed stories.\n * Rejects with an AggregateError after publishing healthy stories when any source fails.\n */\n async load(sources: StorySource[], preview: Preview = EMPTY_PREVIEW): Promise<void> {\n const revision = ++this.revision;\n this.publish({ ...this.snapshot, isLoading: true });\n const loaded = await Promise.all(sources.map((source) => loadSource(source, preview, () => this.cache)));\n\n if (revision !== this.revision) {\n return;\n }\n\n const { cache, stories, errors } = collectSources(loaded);\n this.cache = cache;\n this.sessionError = undefined;\n this.publish({ stories, errors, isLoading: false });\n\n if (errors.length > 0) {\n const failure = new AggregateError(errors.map(({ error }) => error), \"Some stories could not be loaded\");\n this.loadFailures.add(failure);\n throw failure;\n }\n }\n\n /**\n * Replaces the current session failure while preserving source errors and superseding pending loads.\n * Ignores aggregate failures already published by this catalog's load operation.\n */\n reportError(cause: unknown): void {\n if (cause instanceof Error && this.loadFailures.has(cause)) {\n return;\n }\n\n this.revision++;\n const errors = this.snapshot.errors.filter((entry) => entry !== this.sessionError);\n this.sessionError = { source: \"Storybook\", error: normalizeError(cause) };\n this.publish({\n ...this.snapshot,\n isLoading: false,\n errors: [...errors, this.sessionError],\n });\n }\n}\n\nexport { StoryCatalog };\nexport type { StoryCatalogSnapshot, StoryEntry, StoryLoadError, StorySource };\n"]}
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeError } from \"@gtkx/utils\";\nimport type { Args, ArgTypes, ComponentMeta, ComposedStory, Preview, StoryAnnotations } from \"./types.js\";\nimport { composeStories } from \"./compose.js\";\nimport { storyNameFromExport } from \"./upstream.js\";\n\n/** A lazily loaded CSF module discovered in a Storybook project. */\ntype StorySource = {\n /** Stable module identifier used for caching and error reporting. */\n id: string;\n /** Fallback story group title when the module does not declare one. */\n title: string;\n /** Imports the module and resolves to its CSF exports. */\n load: () => Promise<unknown>;\n};\n\n/** A composed story and the metadata used to display it in the explorer. */\ntype StoryEntry = {\n /** Storybook identifier used to preserve the selected story across updates. */\n id: string;\n /** Component group title declared by the module or derived from its source. */\n title: string;\n /** Display name declared by the story or derived from its export name. */\n name: string;\n /** Name of the CSF export that defines this story. */\n exportName: string;\n /** Identifier of the module containing this story. */\n source: string;\n /** Renderable story with its metadata, decorators, and default args composed. */\n story: ComposedStory;\n /** Resolved arg types with explicitly configured explorer controls. */\n controls: ArgTypes;\n};\n\n/** A source loading or composition failure displayed alongside healthy stories. */\ntype StoryLoadError = {\n /** Identifier of the failed source, or Storybook for a session failure. */\n source: string;\n /** Normalized error raised while loading or composing the source. */\n error: Error;\n};\n\n/** Current explorer contents and loading state exposed to subscribers. */\ntype StoryCatalogSnapshot = {\n /** Successfully composed stories with duplicate identifiers excluded. */\n stories: StoryEntry[];\n /** Failures encountered during the latest load or reported by the session. */\n errors: StoryLoadError[];\n /** Whether the catalog is waiting for the latest source load to finish. */\n isLoading: boolean;\n};\n\ntype CachedStories = {\n module: unknown;\n title: string;\n preview: Preview;\n entries: StoryEntry[];\n};\n\ntype LoadedSource = StoryLoadError | { source: StorySource; cached: CachedStories };\n\nconst EMPTY_PREVIEW: Preview = {};\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst explicitControls = (\n resolved: ArgTypes,\n story: StoryAnnotations<Args> | undefined,\n meta: ComponentMeta<Args>,\n preview: Preview,\n): ArgTypes => {\n const controls: ArgTypes = {};\n\n for (const [argument, annotation] of Object.entries(resolved)) {\n const control =\n story?.argTypes?.[argument]?.control ??\n meta.argTypes?.[argument]?.control ??\n preview.argTypes?.[argument]?.control;\n\n if (control === undefined) {\n continue;\n }\n\n controls[argument] = { ...annotation, control: control !== false && (annotation?.control ?? control) };\n }\n\n return controls;\n};\n\nconst displayName = (story: StoryAnnotations<Args> | undefined, exportName: string): string => {\n const name = story?.name;\n\n if (name === undefined) {\n return storyNameFromExport(exportName);\n }\n\n if (typeof name !== \"string\") {\n throw new TypeError(\"Expected a story display name\");\n }\n\n return name;\n};\n\nconst composeSource = (source: StorySource, module: unknown, preview: Preview): StoryEntry[] => {\n if (!isObject(module) || !isObject(module.default)) {\n throw new TypeError(`Expected CSF3 component metadata in ${source.id}`);\n }\n\n const title = module.default.title ?? source.title;\n\n if (typeof title !== \"string\" || title.trim().length === 0) {\n throw new TypeError(`Expected a story title in ${source.id}`);\n }\n\n const annotations = {\n ...module,\n default: { ...module.default, title },\n } as Record<string, StoryAnnotations<Args>> & { default: ComponentMeta<Args> };\n const stories = composeStories(annotations, preview);\n\n return Object.entries(stories).map(([exportName, story]) => ({\n id: story.id,\n title,\n name: displayName(annotations[exportName], exportName),\n exportName,\n source: source.id,\n story,\n controls: explicitControls(story.argTypes, annotations[exportName], annotations.default, preview),\n }));\n};\n\nconst withoutDuplicateIds = (entries: StoryEntry[], errors: StoryLoadError[]): StoryEntry[] => {\n const counts: Map<string, number> = new Map();\n\n for (const entry of entries) {\n counts.set(entry.id, (counts.get(entry.id) ?? 0) + 1);\n }\n\n return entries.filter((entry) => {\n if (counts.get(entry.id) === 1) {\n return true;\n }\n\n errors.push({ source: entry.source, error: new Error(`Duplicate story ID: ${entry.id}`) });\n\n return false;\n });\n};\n\nconst collectSources = (loaded: LoadedSource[]) => {\n const cache: Map<string, CachedStories> = new Map();\n const entries: StoryEntry[] = [];\n const errors: StoryLoadError[] = [];\n\n for (const result of loaded) {\n if (\"error\" in result) {\n errors.push(result);\n } else {\n cache.set(result.source.id, result.cached);\n entries.push(...result.cached.entries);\n }\n }\n\n return { cache, stories: withoutDuplicateIds(entries, errors), errors };\n};\n\nconst createSourceCache = (): Map<string, CachedStories> => new Map();\n\nconst loadSource = async (\n source: StorySource,\n preview: Preview,\n getCache: () => Map<string, CachedStories>,\n): Promise<LoadedSource> => {\n try {\n const module = await source.load();\n const previous = getCache().get(source.id);\n const cached =\n previous !== undefined &&\n previous.module === module &&\n previous.title === source.title &&\n previous.preview === preview\n ? previous\n : { module, title: source.title, preview, entries: composeSource(source, module, preview) };\n\n return { source, cached };\n } catch (error) {\n return { source: source.id, error: normalizeError(error) };\n }\n};\n\n/** Loads CSF modules and publishes subscribable explorer snapshots. */\nclass StoryCatalog {\n private snapshot: StoryCatalogSnapshot = { stories: [], errors: [], isLoading: false };\n private readonly listeners: Set<() => void> = new Set();\n private readonly loadFailures: WeakSet<Error> = new WeakSet();\n private cache = createSourceCache();\n private sessionError: StoryLoadError | undefined;\n private revision = 0;\n\n /** Returns the current snapshot, retaining its identity until the next update. */\n getSnapshot = (): StoryCatalogSnapshot => this.snapshot;\n\n /** Registers a snapshot listener and returns a function that unsubscribes it. */\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private publish(snapshot: StoryCatalogSnapshot): void {\n this.snapshot = snapshot;\n\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n /**\n * Replaces the catalog with stories composed from the supplied sources and preview.\n * Only the latest load publishes results; unchanged module identities reuse composed stories.\n * Rejects with an AggregateError after publishing healthy stories when any source fails.\n */\n async load(sources: StorySource[], preview: Preview = EMPTY_PREVIEW): Promise<void> {\n const revision = ++this.revision;\n this.publish({ ...this.snapshot, isLoading: true });\n const loaded = await Promise.all(sources.map((source) => loadSource(source, preview, () => this.cache)));\n\n if (revision !== this.revision) {\n return;\n }\n\n const { cache, stories, errors } = collectSources(loaded);\n this.cache = cache;\n this.sessionError = undefined;\n this.publish({ stories, errors, isLoading: false });\n\n if (errors.length > 0) {\n const failure = new AggregateError(\n errors.map(({ error }) => error),\n \"Some stories could not be loaded\",\n );\n this.loadFailures.add(failure);\n throw failure;\n }\n }\n\n /**\n * Replaces the current session failure while preserving source errors and superseding pending loads.\n * Ignores aggregate failures already published by this catalog's load operation.\n */\n reportError(cause: unknown): void {\n if (cause instanceof Error && this.loadFailures.has(cause)) {\n return;\n }\n\n this.revision++;\n const errors = this.snapshot.errors.filter((entry) => entry !== this.sessionError);\n this.sessionError = { source: \"Storybook\", error: normalizeError(cause) };\n this.publish({\n ...this.snapshot,\n isLoading: false,\n errors: [...errors, this.sessionError],\n });\n }\n}\n\nexport { StoryCatalog };\nexport type { StoryCatalogSnapshot, StoryEntry, StoryLoadError, StorySource };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAER,aAAa,EACb,eAAe,EACf,aAAa,EACb,OAAO,EACP,gBAAgB,EAChB,WAAW,EACd,MAAM,YAAY,CAAC;AASpB;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,YAAY,GAAI,KAAK,SAAS,MAAM,EACtC,OAAO,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EACvC,MAAM,aAAa,CAAC,KAAK,CAAC,EAC1B,UAAS,OAAY,EACrB,aAAa,MAAM,KACpB,aAAa,CAAC,KAAK,CAcrB,CAAC;AAEF;;;;;;;;;GASG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,SAAS,WAAW,EAC/C,SAAS,OAAO,EAChB,UAAS,OAAY,KACtB,eAAe,CAAC,OAAO,CAqBzB,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAER,aAAa,EACb,eAAe,EACf,aAAa,EACb,OAAO,EACP,gBAAgB,EAChB,WAAW,EACd,MAAM,YAAY,CAAC;AASpB;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,YAAY,GAAI,KAAK,SAAS,MAAM,SAC/B,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QACjC,aAAa,CAAC,KAAK,CAAC,YACjB,OAAO,eACH,MAAM,KACpB,aAAa,CAAC,KAAK,CAoBrB,CAAC;AAEF;;;;;;;;;GASG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,SAAS,WAAW,WACtC,OAAO,YACP,OAAO,KACjB,eAAe,CAAC,OAAO,CAqBzB,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAUtC,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,aAAa,GAAG,CAAC,KAAc,EAAQ,EAAE;IAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,YAAY,GAAG,CACjB,KAAuC,EACvC,IAA0B,EAC1B,UAAmB,EAAE,EACrB,UAAmB,EACC,EAAE;IACtB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACtE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,uBAAuB,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,OAAO,EAAE;QACxD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClB,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;YACxE,CAAC;YAED,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;KACJ,EAAE,UAAU,CAAC,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,CACnB,OAAgB,EAChB,UAAmB,EAAE,EACG,EAAE;IAC1B,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAA8B,CAAC;IACpD,MAAM,QAAQ,GAAsC,EAAE,CAAC;IAEvD,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,qBAAqB,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;YACvG,SAAS;QACb,CAAC;QAED,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE;YACxC,KAAK,EAAE,YAAY,CAAC,KAA+B,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC;YAC/E,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,IAAI;SACjB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,QAAoC,CAAC;AAChD,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { createElement } from \"react\";\nimport type {\n Args,\n ComponentMeta,\n ComposedStories,\n ComposedStory,\n Preview,\n StoryAnnotations,\n StoryModule,\n} from \"./types.js\";\nimport { composeStoryAnnotations, isExportStory } from \"./upstream.js\";\n\nconst requireObject = (value: unknown): void => {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\"Expected a CSF3 annotation object\");\n }\n};\n\n/**\n * Composes a CSF3 story into a native React component with resolved defaults and decorators.\n * Compose outside render to preserve component identity. Rendering props override the composed args.\n * This function does not create an application, window, or Storybook preview lifecycle.\n *\n * @param story The named story's annotations.\n * @param meta The module's default component metadata.\n * @param preview Shared project annotations, scoped to this composition.\n * @param exportName Export name used for the story identifier and default display name.\n * @returns A renderable component exposing its composed annotations.\n * @throws If an annotation is not an object or no component or render function is available.\n */\nconst composeStory = <TArgs extends object>(\n story: StoryAnnotations<NoInfer<TArgs>>,\n meta: ComponentMeta<TArgs>,\n preview: Preview = {},\n exportName?: string,\n): ComposedStory<TArgs> => {\n if (!story.render && !meta.render && !preview.render && !meta.component) {\n throw new TypeError(\"A story needs a component or render function\");\n }\n\n return composeStoryAnnotations(story, { ...meta }, preview, {\n render: (args) => {\n if (!meta.component) {\n throw new TypeError(\"A story needs a component or render function\");\n }\n\n return createElement(meta.component, args);\n },\n }, exportName);\n};\n\n/**\n * Composes the selected CSF3 exports of a module into native React components.\n * The default export supplies metadata; its includeStories and excludeStories select named exports.\n * Returned keys retain the original export names.\n *\n * @param stories A story module containing default metadata and named story objects.\n * @param preview Shared project annotations, scoped to the returned compositions.\n * @returns Composed components keyed by the selected export names.\n * @throws If metadata or a selected export is invalid, or a selected story has no renderer.\n */\nconst composeStories = <TModule extends StoryModule>(\n stories: TModule,\n preview: Preview = {},\n): ComposedStories<TModule> => {\n requireObject(stories.default);\n\n const meta = stories.default as ComponentMeta<Args>;\n const composed: Partial<ComposedStories<TModule>> = {};\n\n for (const [exportName, story] of Object.entries(stories)) {\n if (exportName === \"default\" || exportName === \"__namedExportsOrder\" || !isExportStory(exportName, meta)) {\n continue;\n }\n\n requireObject(story);\n Object.defineProperty(composed, exportName, {\n value: composeStory(story as StoryAnnotations<Args>, meta, preview, exportName),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n\n return composed as ComposedStories<TModule>;\n};\n\nexport { composeStory, composeStories };\n"]}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAUtC,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,aAAa,GAAG,CAAC,KAAc,EAAQ,EAAE;IAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,YAAY,GAAG,CACjB,KAAuC,EACvC,IAA0B,EAC1B,OAAO,GAAY,EAAE,EACrB,UAAmB,EACC,EAAE;IACtB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACtE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,uBAAuB,CAC1B,KAAK,EACL,EAAE,GAAG,IAAI,EAAE,EACX,OAAO,EACP;QACI,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClB,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;YACxE,CAAC;YAED,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;KACJ,EACD,UAAU,CACb,CAAC;AACN,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,CACnB,OAAgB,EAChB,OAAO,GAAY,EAAE,EACG,EAAE;IAC1B,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAA8B,CAAC;IACpD,MAAM,QAAQ,GAAsC,EAAE,CAAC;IAEvD,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,qBAAqB,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;YACvG,SAAS;QACb,CAAC;QAED,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE;YACxC,KAAK,EAAE,YAAY,CAAC,KAA+B,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC;YAC/E,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,IAAI;SACjB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,QAAoC,CAAC;AAChD,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { createElement } from \"react\";\nimport type {\n Args,\n ComponentMeta,\n ComposedStories,\n ComposedStory,\n Preview,\n StoryAnnotations,\n StoryModule,\n} from \"./types.js\";\nimport { composeStoryAnnotations, isExportStory } from \"./upstream.js\";\n\nconst requireObject = (value: unknown): void => {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\"Expected a CSF3 annotation object\");\n }\n};\n\n/**\n * Composes a CSF3 story into a native React component with resolved defaults and decorators.\n * Compose outside render to preserve component identity. Rendering props override the composed args.\n * This function does not create an application, window, or Storybook preview lifecycle.\n *\n * @param story The named story's annotations.\n * @param meta The module's default component metadata.\n * @param preview Shared project annotations, scoped to this composition.\n * @param exportName Export name used for the story identifier and default display name.\n * @returns A renderable component exposing its composed annotations.\n * @throws If an annotation is not an object or no component or render function is available.\n */\nconst composeStory = <TArgs extends object>(\n story: StoryAnnotations<NoInfer<TArgs>>,\n meta: ComponentMeta<TArgs>,\n preview: Preview = {},\n exportName?: string,\n): ComposedStory<TArgs> => {\n if (!story.render && !meta.render && !preview.render && !meta.component) {\n throw new TypeError(\"A story needs a component or render function\");\n }\n\n return composeStoryAnnotations(\n story,\n { ...meta },\n preview,\n {\n render: (args) => {\n if (!meta.component) {\n throw new TypeError(\"A story needs a component or render function\");\n }\n\n return createElement(meta.component, args);\n },\n },\n exportName,\n );\n};\n\n/**\n * Composes the selected CSF3 exports of a module into native React components.\n * The default export supplies metadata; its includeStories and excludeStories select named exports.\n * Returned keys retain the original export names.\n *\n * @param stories A story module containing default metadata and named story objects.\n * @param preview Shared project annotations, scoped to the returned compositions.\n * @returns Composed components keyed by the selected export names.\n * @throws If metadata or a selected export is invalid, or a selected story has no renderer.\n */\nconst composeStories = <TModule extends StoryModule>(\n stories: TModule,\n preview: Preview = {},\n): ComposedStories<TModule> => {\n requireObject(stories.default);\n\n const meta = stories.default as ComponentMeta<Args>;\n const composed: Partial<ComposedStories<TModule>> = {};\n\n for (const [exportName, story] of Object.entries(stories)) {\n if (exportName === \"default\" || exportName === \"__namedExportsOrder\" || !isExportStory(exportName, meta)) {\n continue;\n }\n\n requireObject(story);\n Object.defineProperty(composed, exportName, {\n value: composeStory(story as StoryAnnotations<Args>, meta, preview, exportName),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n\n return composed as ComposedStories<TModule>;\n};\n\nexport { composeStory, composeStories };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,KAAK,eAAe,GAAG;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,yFAAyF;AACzF,QAAA,MAAM,YAAY,GAAI,QAAQ,eAAe,KAAG,eAAyB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,KAAK,eAAe,GAAG;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,yFAAyF;AACzF,QAAA,MAAM,YAAY,WAAY,eAAe,KAAG,eAAyB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK,IAAI,CAAA;CAAE,CAAC;AA8K1F,QAAA,MAAM,QAAQ,GAAI,8BAA8B,aAAa,KAAG,SA4B/D,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK,IAAI,CAAA;CAAE,CAAC;AAgM1F,QAAA,MAAM,QAAQ,iCAAkC,aAAa,KAAG,SA4B/D,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
package/dist/controls.js CHANGED
@@ -7,7 +7,7 @@ const NO_SELECTION_ID = "no-selection";
7
7
  const NO_SELECTION_LABEL = "Choose option...";
8
8
  const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
9
9
  const isWithinBoundsOrAbsent = (value, min, max) => value === undefined || (typeof value === "number" && Number.isFinite(value) && value >= min && value <= max);
10
- const controlTitle = (name, argument) => typeof name === "string" ? name : argument;
10
+ const controlTitle = (name, argument) => (typeof name === "string" ? name : argument);
11
11
  const numberDigits = (step) => {
12
12
  const [coefficient = "", exponent = "0"] = String(step).split("e", 2);
13
13
  const fraction = coefficient.split(".", 2)[1]?.length ?? 0;
@@ -19,13 +19,19 @@ const NumberControl = ({ argument, title, value, settings, isDisabled, onChange,
19
19
  const min = settings.min ?? -Number.MAX_SAFE_INTEGER;
20
20
  const max = settings.max ?? Number.MAX_SAFE_INTEGER;
21
21
  const step = settings.step ?? 1;
22
- if (typeof min !== "number" || typeof max !== "number" || typeof step !== "number" ||
23
- !Number.isFinite(min) || !Number.isFinite(max) || !Number.isFinite(step) ||
24
- step <= 0 || min > max || !isWithinBoundsOrAbsent(value, min, max)) {
22
+ if (typeof min !== "number" ||
23
+ typeof max !== "number" ||
24
+ typeof step !== "number" ||
25
+ !Number.isFinite(min) ||
26
+ !Number.isFinite(max) ||
27
+ !Number.isFinite(step) ||
28
+ step <= 0 ||
29
+ min > max ||
30
+ !isWithinBoundsOrAbsent(value, min, max)) {
25
31
  return _jsx(UnsupportedControl, { title: title, description: "Provide a finite number and valid bounds." });
26
32
  }
27
33
  const currentValue = typeof value === "number" ? value : Math.max(min, Math.min(0, max));
28
- return (_jsx(AdwSpinRow, { name: `storybook-control-${argument}`, title: markupEscapeText(title, -1), sensitive: !isDisabled, value: currentValue, digits: numberDigits(step), numeric: true, widthChars: 8, adjustment: (_jsx(GtkAdjustment, { lower: min, upper: max, stepIncrement: step, pageIncrement: Math.min(Number.MAX_VALUE, step * 10), value: currentValue })), onNotifyValue: (next) => {
34
+ return (_jsx(AdwSpinRow, { name: `storybook-control-${argument}`, title: markupEscapeText(title, -1), sensitive: !isDisabled, value: currentValue, digits: numberDigits(step), numeric: true, widthChars: 8, adjustment: _jsx(GtkAdjustment, { lower: min, upper: max, stepIncrement: step, pageIncrement: Math.min(Number.MAX_VALUE, step * 10), value: currentValue }), onNotifyValue: (next) => {
29
35
  if (!Object.is(next, value)) {
30
36
  onChange({ [argument]: next });
31
37
  }
@@ -33,16 +39,24 @@ const NumberControl = ({ argument, title, value, settings, isDisabled, onChange,
33
39
  };
34
40
  const SelectControl = (props) => {
35
41
  const { argument, title, value, options, settings, isDisabled, onChange } = props;
36
- if (!Array.isArray(options) || options.length === 0 || options.some((option) => option !== null && typeof option !== "string" && typeof option !== "number" && typeof option !== "boolean")) {
42
+ if (!Array.isArray(options) ||
43
+ options.length === 0 ||
44
+ options.some((option) => option !== null &&
45
+ typeof option !== "string" &&
46
+ typeof option !== "number" &&
47
+ typeof option !== "boolean")) {
37
48
  return _jsx(UnsupportedControl, { title: title, description: "Provide a list of text, number, or boolean options." });
38
49
  }
39
50
  const values = options;
40
51
  const selected = values.findIndex((option) => Object.is(option, value));
41
52
  const labels = isObject(settings.labels) ? settings.labels : {};
42
- const items = [{ id: NO_SELECTION_ID, value: NO_SELECTION_LABEL }, ...values.map((option, index) => {
53
+ const items = [
54
+ { id: NO_SELECTION_ID, value: NO_SELECTION_LABEL },
55
+ ...values.map((option, index) => {
43
56
  const label = labels[String(option)];
44
57
  return { id: String(index), value: typeof label === "string" ? label : String(option) };
45
- })];
58
+ }),
59
+ ];
46
60
  return (_jsx(ComboRow, { name: `storybook-control-${argument}`, title: markupEscapeText(title, -1), sensitive: !isDisabled, items: items, selectedId: selected === -1 ? NO_SELECTION_ID : String(selected), onSelectionChanged: (id) => {
47
61
  if (id === NO_SELECTION_ID) {
48
62
  onChange({ [argument]: undefined });
@@ -1 +1 @@
1
- {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport { ComboRow } from \"@gtkx/components\";\nimport { markupEscapeText } from \"@gtkx/gi/glib\";\nimport { AdwActionRow, AdwEntryRow, AdwPreferencesGroup, AdwSpinRow, AdwSwitchRow } from \"@gtkx/jsx/adw\";\nimport { GtkAdjustment } from \"@gtkx/jsx/gtk\";\nimport type { Args, ArgTypes } from \"./types.js\";\n\ntype ControlsProps = { argTypes: ArgTypes; args: Args; onChange: (update: Args) => void };\n\nconst NO_SELECTION_ID = \"no-selection\";\nconst NO_SELECTION_LABEL = \"Choose option...\";\n\ntype ControlProps = {\n argument: string;\n title: string;\n value: unknown;\n type: string;\n settings: Args;\n options: unknown;\n isDisabled: boolean;\n onChange: (update: Args) => void;\n};\n\nconst isObject = (value: unknown): value is Args =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst isWithinBoundsOrAbsent = (value: unknown, min: number, max: number): boolean =>\n value === undefined || (typeof value === \"number\" && Number.isFinite(value) && value >= min && value <= max);\n\nconst controlTitle = (name: unknown, argument: string): string => typeof name === \"string\" ? name : argument;\n\nconst numberDigits = (step: number): number => {\n const [coefficient = \"\", exponent = \"0\"] = String(step).split(\"e\", 2);\n const fraction = coefficient.split(\".\", 2)[1]?.length ?? 0;\n const digits = Math.max(0, fraction - Number(exponent));\n\n return Math.min(20, digits);\n};\n\nconst UnsupportedControl = ({ title, description }: { title: string; description: string }): ReactNode => (\n <AdwActionRow title={markupEscapeText(title, -1)} subtitle={markupEscapeText(description, -1)} sensitive={false} />\n);\n\nconst NumberControl = ({\n argument,\n title,\n value,\n settings,\n isDisabled,\n onChange,\n}: Omit<ControlProps, \"type\" | \"options\">): ReactNode => {\n const min = settings.min ?? -Number.MAX_SAFE_INTEGER;\n const max = settings.max ?? Number.MAX_SAFE_INTEGER;\n const step = settings.step ?? 1;\n\n if (\n typeof min !== \"number\" || typeof max !== \"number\" || typeof step !== \"number\" ||\n !Number.isFinite(min) || !Number.isFinite(max) || !Number.isFinite(step) ||\n step <= 0 || min > max || !isWithinBoundsOrAbsent(value, min, max)\n ) {\n return <UnsupportedControl title={title} description=\"Provide a finite number and valid bounds.\" />;\n }\n\n const currentValue = typeof value === \"number\" ? value : Math.max(min, Math.min(0, max));\n\n return (\n <AdwSpinRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n value={currentValue}\n digits={numberDigits(step)}\n numeric\n widthChars={8}\n adjustment={(\n <GtkAdjustment\n lower={min}\n upper={max}\n stepIncrement={step}\n pageIncrement={Math.min(Number.MAX_VALUE, step * 10)}\n value={currentValue}\n />\n )}\n onNotifyValue={(next) => {\n if (!Object.is(next, value)) {\n onChange({ [argument]: next });\n }\n }}\n />\n );\n};\n\nconst SelectControl = (props: Omit<ControlProps, \"type\">): ReactNode => {\n const { argument, title, value, options, settings, isDisabled, onChange } = props;\n if (!Array.isArray(options) || options.length === 0 || options.some((option: unknown) =>\n option !== null && typeof option !== \"string\" && typeof option !== \"number\" && typeof option !== \"boolean\")) {\n return <UnsupportedControl title={title} description=\"Provide a list of text, number, or boolean options.\" />;\n }\n\n const values: unknown[] = options;\n const selected = values.findIndex((option) => Object.is(option, value));\n const labels = isObject(settings.labels) ? settings.labels : {};\n const items = [{ id: NO_SELECTION_ID, value: NO_SELECTION_LABEL }, ...values.map((option, index) => {\n const label = labels[String(option)];\n\n return { id: String(index), value: typeof label === \"string\" ? label : String(option) };\n })];\n\n return (\n <ComboRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n items={items}\n selectedId={selected === -1 ? NO_SELECTION_ID : String(selected)}\n onSelectionChanged={(id) => {\n if (id === NO_SELECTION_ID) {\n onChange({ [argument]: undefined });\n\n return;\n }\n\n if (id === null) {\n return;\n }\n\n onChange({ [argument]: values[Number(id)] });\n }}\n />\n );\n};\n\nconst Control = (props: ControlProps): ReactNode => {\n const { argument, title, value, type, isDisabled, onChange } = props;\n\n switch (type) {\n case \"boolean\": {\n return (\n <AdwSwitchRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n active={value === true}\n onNotifyActive={(active) => {\n if (!Object.is(active, value)) {\n onChange({ [argument]: active });\n }\n }}\n />\n );\n }\n case \"text\": {\n return (\n <AdwEntryRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n text={typeof value === \"string\" ? value : \"\"}\n onNotifyText={(text) => {\n if (!Object.is(text, value)) {\n onChange({ [argument]: text });\n }\n }}\n />\n );\n }\n case \"number\":\n case \"range\": {\n return <NumberControl {...props} />;\n }\n case \"select\":\n case \"radio\":\n case \"inline-radio\": {\n return <SelectControl {...props} />;\n }\n default: {\n return <UnsupportedControl title={title} description={`Unsupported control: ${type}`} />;\n }\n }\n};\n\nconst Controls = ({ argTypes, args, onChange }: ControlsProps): ReactNode => (\n <AdwPreferencesGroup title=\"Controls\">\n {Object.entries(argTypes).map(([argument, annotation]) => {\n const control: unknown = annotation?.control;\n const table = isObject(annotation?.table) ? annotation.table : {};\n\n if (control === undefined || control === false || table.disable === true) {\n return null;\n }\n\n const settings = isObject(control) ? control : {};\n const type = typeof control === \"string\" ? control : settings.type;\n\n return (\n <Control\n key={argument}\n argument={argument}\n title={controlTitle(annotation?.name, argument)}\n value={args[argument]}\n type={typeof type === \"string\" ? type : \"unknown\"}\n settings={settings}\n options={annotation?.options}\n isDisabled={settings.disable === true || table.readonly === true}\n onChange={onChange}\n />\n );\n })}\n </AdwPreferencesGroup>\n);\n\nexport { Controls };\n"]}
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport { ComboRow } from \"@gtkx/components\";\nimport { markupEscapeText } from \"@gtkx/gi/glib\";\nimport { AdwActionRow, AdwEntryRow, AdwPreferencesGroup, AdwSpinRow, AdwSwitchRow } from \"@gtkx/jsx/adw\";\nimport { GtkAdjustment } from \"@gtkx/jsx/gtk\";\nimport type { Args, ArgTypes } from \"./types.js\";\n\ntype ControlsProps = { argTypes: ArgTypes; args: Args; onChange: (update: Args) => void };\n\nconst NO_SELECTION_ID = \"no-selection\";\nconst NO_SELECTION_LABEL = \"Choose option...\";\n\ntype ControlProps = {\n argument: string;\n title: string;\n value: unknown;\n type: string;\n settings: Args;\n options: unknown;\n isDisabled: boolean;\n onChange: (update: Args) => void;\n};\n\nconst isObject = (value: unknown): value is Args =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst isWithinBoundsOrAbsent = (value: unknown, min: number, max: number): boolean =>\n value === undefined || (typeof value === \"number\" && Number.isFinite(value) && value >= min && value <= max);\n\nconst controlTitle = (name: unknown, argument: string): string => (typeof name === \"string\" ? name : argument);\n\nconst numberDigits = (step: number): number => {\n const [coefficient = \"\", exponent = \"0\"] = String(step).split(\"e\", 2);\n const fraction = coefficient.split(\".\", 2)[1]?.length ?? 0;\n const digits = Math.max(0, fraction - Number(exponent));\n\n return Math.min(20, digits);\n};\n\nconst UnsupportedControl = ({ title, description }: { title: string; description: string }): ReactNode => (\n <AdwActionRow title={markupEscapeText(title, -1)} subtitle={markupEscapeText(description, -1)} sensitive={false} />\n);\n\nconst NumberControl = ({\n argument,\n title,\n value,\n settings,\n isDisabled,\n onChange,\n}: Omit<ControlProps, \"type\" | \"options\">): ReactNode => {\n const min = settings.min ?? -Number.MAX_SAFE_INTEGER;\n const max = settings.max ?? Number.MAX_SAFE_INTEGER;\n const step = settings.step ?? 1;\n\n if (\n typeof min !== \"number\" ||\n typeof max !== \"number\" ||\n typeof step !== \"number\" ||\n !Number.isFinite(min) ||\n !Number.isFinite(max) ||\n !Number.isFinite(step) ||\n step <= 0 ||\n min > max ||\n !isWithinBoundsOrAbsent(value, min, max)\n ) {\n return <UnsupportedControl title={title} description=\"Provide a finite number and valid bounds.\" />;\n }\n\n const currentValue = typeof value === \"number\" ? value : Math.max(min, Math.min(0, max));\n\n return (\n <AdwSpinRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n value={currentValue}\n digits={numberDigits(step)}\n numeric\n widthChars={8}\n adjustment={\n <GtkAdjustment\n lower={min}\n upper={max}\n stepIncrement={step}\n pageIncrement={Math.min(Number.MAX_VALUE, step * 10)}\n value={currentValue}\n />\n }\n onNotifyValue={(next) => {\n if (!Object.is(next, value)) {\n onChange({ [argument]: next });\n }\n }}\n />\n );\n};\n\nconst SelectControl = (props: Omit<ControlProps, \"type\">): ReactNode => {\n const { argument, title, value, options, settings, isDisabled, onChange } = props;\n if (\n !Array.isArray(options) ||\n options.length === 0 ||\n options.some(\n (option: unknown) =>\n option !== null &&\n typeof option !== \"string\" &&\n typeof option !== \"number\" &&\n typeof option !== \"boolean\",\n )\n ) {\n return <UnsupportedControl title={title} description=\"Provide a list of text, number, or boolean options.\" />;\n }\n\n const values: unknown[] = options;\n const selected = values.findIndex((option) => Object.is(option, value));\n const labels = isObject(settings.labels) ? settings.labels : {};\n const items = [\n { id: NO_SELECTION_ID, value: NO_SELECTION_LABEL },\n ...values.map((option, index) => {\n const label = labels[String(option)];\n\n return { id: String(index), value: typeof label === \"string\" ? label : String(option) };\n }),\n ];\n\n return (\n <ComboRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n items={items}\n selectedId={selected === -1 ? NO_SELECTION_ID : String(selected)}\n onSelectionChanged={(id) => {\n if (id === NO_SELECTION_ID) {\n onChange({ [argument]: undefined });\n\n return;\n }\n\n if (id === null) {\n return;\n }\n\n onChange({ [argument]: values[Number(id)] });\n }}\n />\n );\n};\n\nconst Control = (props: ControlProps): ReactNode => {\n const { argument, title, value, type, isDisabled, onChange } = props;\n\n switch (type) {\n case \"boolean\": {\n return (\n <AdwSwitchRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n active={value === true}\n onNotifyActive={(active) => {\n if (!Object.is(active, value)) {\n onChange({ [argument]: active });\n }\n }}\n />\n );\n }\n case \"text\": {\n return (\n <AdwEntryRow\n name={`storybook-control-${argument}`}\n title={markupEscapeText(title, -1)}\n sensitive={!isDisabled}\n text={typeof value === \"string\" ? value : \"\"}\n onNotifyText={(text) => {\n if (!Object.is(text, value)) {\n onChange({ [argument]: text });\n }\n }}\n />\n );\n }\n case \"number\":\n case \"range\": {\n return <NumberControl {...props} />;\n }\n case \"select\":\n case \"radio\":\n case \"inline-radio\": {\n return <SelectControl {...props} />;\n }\n default: {\n return <UnsupportedControl title={title} description={`Unsupported control: ${type}`} />;\n }\n }\n};\n\nconst Controls = ({ argTypes, args, onChange }: ControlsProps): ReactNode => (\n <AdwPreferencesGroup title=\"Controls\">\n {Object.entries(argTypes).map(([argument, annotation]) => {\n const control: unknown = annotation?.control;\n const table = isObject(annotation?.table) ? annotation.table : {};\n\n if (control === undefined || control === false || table.disable === true) {\n return null;\n }\n\n const settings = isObject(control) ? control : {};\n const type = typeof control === \"string\" ? control : settings.type;\n\n return (\n <Control\n key={argument}\n argument={argument}\n title={controlTitle(annotation?.name, argument)}\n value={args[argument]}\n type={typeof type === \"string\" ? type : \"unknown\"}\n settings={settings}\n options={annotation?.options}\n isDisabled={settings.disable === true || table.readonly === true}\n onChange={onChange}\n />\n );\n })}\n </AdwPreferencesGroup>\n);\n\nexport { Controls };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"explorer-navigator.d.ts","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,KAAK,cAAc,GAAG;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AA4DF,QAAA,MAAM,cAAc,GAAI,2CAA2C,cAAc,KAAG,SA4CnF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"explorer-navigator.d.ts","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,KAAK,cAAc,GAAG;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAsDF,QAAA,MAAM,cAAc,8CAA+C,cAAc,KAAG,SA4CnF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"explorer-navigator.js","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport { markupEscapeText } from \"@gtkx/gi/glib\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { AdwActionRow, AdwStatusPage } from \"@gtkx/jsx/adw\";\nimport { GtkBox, GtkLabel, GtkListBox, GtkScrolledWindow, GtkSearchEntry } from \"@gtkx/jsx/gtk\";\nimport { useState } from \"react\";\nimport type { StoryEntry, StoryLoadError } from \"./catalog.js\";\n\ntype NavigatorProps = {\n stories: StoryEntry[];\n errors: StoryLoadError[];\n selectedId: string | undefined;\n onSelect: (id: string) => void;\n};\n\ntype GroupProps = Pick<NavigatorProps, \"selectedId\" | \"onSelect\"> & {\n title: string;\n entries: StoryEntry[];\n};\n\nconst StoryGroup = ({ title, entries, selectedId, onSelect }: GroupProps): ReactNode => (\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={6}>\n <GtkLabel\n label={title}\n xalign={0}\n marginStart={18}\n marginEnd={18}\n cssClasses={[\"heading\"]}\n wrap\n />\n <GtkListBox\n cssClasses={[\"navigation-sidebar\"]}\n selectedIndex={entries.findIndex((entry) => entry.id === selectedId)}\n onRowSelected={(row) => {\n const entry = row === null ? undefined : entries[row.getIndex()];\n\n if (entry) {\n onSelect(entry.id);\n }\n }}\n >\n {entries.map((entry) => (\n <AdwActionRow\n key={entry.id}\n name={`storybook-story-${entry.id}`}\n title={markupEscapeText(entry.name, -1)}\n activatable\n onActivated={() => {\n onSelect(entry.id);\n }}\n />\n ))}\n </GtkListBox>\n </GtkBox>\n);\n\nconst LoadErrors = ({ errors }: Pick<NavigatorProps, \"errors\">): ReactNode => errors.length > 0 && (\n <GtkBox name=\"storybook-load-errors\" orientation={Gtk.Orientation.VERTICAL} spacing={6}>\n {errors.map(({ source, error }, index) => (\n <GtkLabel\n key={`${source}-${String(index)}`}\n label={`${source}\\n${error.message.slice(0, 500)}`}\n cssClasses={[\"error\"]}\n marginStart={18}\n marginEnd={18}\n wrap\n selectable\n xalign={0}\n />\n ))}\n </GtkBox>\n);\n\nconst StoryNavigator = ({ stories, errors, selectedId, onSelect }: NavigatorProps): ReactNode => {\n const [search, setSearch] = useState(\"\");\n const query = search.trim().toLocaleLowerCase();\n const groups = Map.groupBy(\n stories.filter((entry) => `${entry.title} ${entry.name}`.toLocaleLowerCase().includes(query)),\n (entry) => entry.title,\n );\n\n return (\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12}>\n <GtkSearchEntry\n name=\"storybook-search\"\n placeholderText=\"Search stories\"\n text={search}\n marginStart={12}\n marginEnd={12}\n onChanged={(entry) => {\n setSearch(entry.getText());\n }}\n />\n <GtkScrolledWindow hscrollbarPolicy={Gtk.PolicyType.NEVER} vexpand>\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={18} marginBottom={18}>\n {[...groups].map(([title, entries]) => (\n <StoryGroup\n key={title}\n title={title}\n entries={entries}\n selectedId={selectedId}\n onSelect={onSelect}\n />\n ))}\n {groups.size === 0 && (\n <AdwStatusPage\n name=\"storybook-no-matches\"\n title={query ? \"No matching stories\" : \"No stories\"}\n iconName=\"system-search-symbolic\"\n cssClasses={[\"compact\"]}\n />\n )}\n <LoadErrors errors={errors} />\n </GtkBox>\n </GtkScrolledWindow>\n </GtkBox>\n );\n};\n\nexport { StoryNavigator };\n"]}
1
+ {"version":3,"file":"explorer-navigator.js","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport { markupEscapeText } from \"@gtkx/gi/glib\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { AdwActionRow, AdwStatusPage } from \"@gtkx/jsx/adw\";\nimport { GtkBox, GtkLabel, GtkListBox, GtkScrolledWindow, GtkSearchEntry } from \"@gtkx/jsx/gtk\";\nimport { useState } from \"react\";\nimport type { StoryEntry, StoryLoadError } from \"./catalog.js\";\n\ntype NavigatorProps = {\n stories: StoryEntry[];\n errors: StoryLoadError[];\n selectedId: string | undefined;\n onSelect: (id: string) => void;\n};\n\ntype GroupProps = Pick<NavigatorProps, \"selectedId\" | \"onSelect\"> & {\n title: string;\n entries: StoryEntry[];\n};\n\nconst StoryGroup = ({ title, entries, selectedId, onSelect }: GroupProps): ReactNode => (\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={6}>\n <GtkLabel label={title} xalign={0} marginStart={18} marginEnd={18} cssClasses={[\"heading\"]} wrap />\n <GtkListBox\n cssClasses={[\"navigation-sidebar\"]}\n selectedIndex={entries.findIndex((entry) => entry.id === selectedId)}\n onRowSelected={(row) => {\n const entry = row === null ? undefined : entries[row.getIndex()];\n\n if (entry) {\n onSelect(entry.id);\n }\n }}\n >\n {entries.map((entry) => (\n <AdwActionRow\n key={entry.id}\n name={`storybook-story-${entry.id}`}\n title={markupEscapeText(entry.name, -1)}\n activatable\n onActivated={() => {\n onSelect(entry.id);\n }}\n />\n ))}\n </GtkListBox>\n </GtkBox>\n);\n\nconst LoadErrors = ({ errors }: Pick<NavigatorProps, \"errors\">): ReactNode =>\n errors.length > 0 && (\n <GtkBox name=\"storybook-load-errors\" orientation={Gtk.Orientation.VERTICAL} spacing={6}>\n {errors.map(({ source, error }, index) => (\n <GtkLabel\n key={`${source}-${String(index)}`}\n label={`${source}\\n${error.message.slice(0, 500)}`}\n cssClasses={[\"error\"]}\n marginStart={18}\n marginEnd={18}\n wrap\n selectable\n xalign={0}\n />\n ))}\n </GtkBox>\n );\n\nconst StoryNavigator = ({ stories, errors, selectedId, onSelect }: NavigatorProps): ReactNode => {\n const [search, setSearch] = useState(\"\");\n const query = search.trim().toLocaleLowerCase();\n const groups = Map.groupBy(\n stories.filter((entry) => `${entry.title} ${entry.name}`.toLocaleLowerCase().includes(query)),\n (entry) => entry.title,\n );\n\n return (\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12}>\n <GtkSearchEntry\n name=\"storybook-search\"\n placeholderText=\"Search stories\"\n text={search}\n marginStart={12}\n marginEnd={12}\n onChanged={(entry) => {\n setSearch(entry.getText());\n }}\n />\n <GtkScrolledWindow hscrollbarPolicy={Gtk.PolicyType.NEVER} vexpand>\n <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={18} marginBottom={18}>\n {[...groups].map(([title, entries]) => (\n <StoryGroup\n key={title}\n title={title}\n entries={entries}\n selectedId={selectedId}\n onSelect={onSelect}\n />\n ))}\n {groups.size === 0 && (\n <AdwStatusPage\n name=\"storybook-no-matches\"\n title={query ? \"No matching stories\" : \"No stories\"}\n iconName=\"system-search-symbolic\"\n cssClasses={[\"compact\"]}\n />\n )}\n <LoadErrors errors={errors} />\n </GtkBox>\n </GtkScrolledWindow>\n </GtkBox>\n );\n};\n\nexport { StoryNavigator };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"explorer-preview.d.ts","sourceRoot":"","sources":["../src/explorer-preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,KAAK,YAAY,GAAG;IAChB,KAAK,EAAE,UAAU,CAAC;CACrB,CAAC;AA2JF,QAAA,MAAM,gBAAgB,GAAI,WAAW,YAAY,KAAG,SAkCnD,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"explorer-preview.d.ts","sourceRoot":"","sources":["../src/explorer-preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,KAAK,YAAY,GAAG;IAChB,KAAK,EAAE,UAAU,CAAC;CACrB,CAAC;AA6JF,QAAA,MAAM,gBAAgB,cAAe,YAAY,KAAG,SAoCnD,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,9 +1,10 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { markupEscapeText } from "@gtkx/gi/glib";
3
3
  import * as Gtk from "@gtkx/gi/gtk";
4
4
  import { AdwHeaderBar, AdwStatusPage, AdwToolbarView, AdwWindowTitle } from "@gtkx/jsx/adw";
5
5
  import { GtkBox, GtkButton, GtkScrolledWindow } from "@gtkx/jsx/gtk";
6
6
  import { createPortal, rootElement } from "@gtkx/react";
7
+ import { normalizeError } from "@gtkx/utils";
7
8
  import { Component, useCallback, useMemo, useState } from "react";
8
9
  import { ActionsPanel } from "./actions-panel.js";
9
10
  import { ActionStore, bindActions } from "./actions.js";
@@ -13,14 +14,12 @@ class PreviewBoundary extends Component {
13
14
  return props.args === state.args ? null : { error: null, args: props.args };
14
15
  }
15
16
  static getDerivedStateFromError(error) {
16
- return { error: error instanceof Error ? error : new Error(String(error)) };
17
+ return { error: normalizeError(error) };
17
18
  }
18
19
  state = { error: null, args: this.props.args };
19
20
  render() {
20
- return this.state.error === null
21
- ? this.props.children
22
- : (_jsx(AdwStatusPage, { name: "storybook-preview-error", title: "Preview failed", iconName: "dialog-error-symbolic", description: markupEscapeText(this.state.error.message.slice(0, 500), -1) +
23
- "\n\nAdjust controls, reset the preview, or select another story to continue." }));
21
+ return this.state.error === null ? (this.props.children) : (_jsx(AdwStatusPage, { name: "storybook-preview-error", title: "Preview failed", iconName: "dialog-error-symbolic", description: markupEscapeText(this.state.error.message.slice(0, 500), -1) +
22
+ "\n\nAdjust controls, reset the preview, or select another story to continue." }));
24
23
  }
25
24
  }
26
25
  const previewMode = (story) => {
@@ -80,10 +79,8 @@ const usePreviewState = ({ entry }) => {
80
79
  const StoryInspector = ({ entry, actions, args, onChange }) => (_jsx(GtkScrolledWindow, { name: "storybook-inspector", widthRequest: 280, hscrollbarPolicy: Gtk.PolicyType.NEVER, vexpand: true, children: _jsxs(GtkBox, { orientation: Gtk.Orientation.VERTICAL, spacing: 24, marginTop: 18, marginBottom: 18, marginStart: 12, marginEnd: 12, children: [_jsx(Controls, { argTypes: entry.controls, args: args, onChange: onChange }), _jsx(ActionsPanel, { store: actions })] }) }));
81
80
  const StorybookPreview = ({ entry }) => {
82
81
  const { state, boundArgs, reset, onChange } = usePreviewState({ entry });
83
- return (_jsx(AdwToolbarView, { hexpand: true, vexpand: true, topBar: (_jsx(AdwHeaderBar, { titleWidget: _jsx(AdwWindowTitle, { title: entry.name, subtitle: entry.title }), end: _jsx(GtkButton, { label: "Reset story", onClicked: reset }) })), children: _jsxs(GtkBox, { children: [_jsx(GtkBox, { orientation: Gtk.Orientation.VERTICAL, hexpand: true, vexpand: true, children: _jsx(PreviewBoundary, { args: state.args, children: state.error === null
84
- ? _jsx(PreviewContent, { story: entry.story, args: boundArgs })
85
- : (_jsx(AdwStatusPage, { name: "storybook-preview-error", title: "Story action failed", iconName: "dialog-error-symbolic", description: markupEscapeText(state.error.message.slice(0, 500), -1) +
86
- "\n\nReset the preview or select another story to continue." })) }, state.generation) }), _jsx(StoryInspector, { entry: entry, actions: state.actions, args: state.args, onChange: onChange })] }) }));
82
+ return (_jsx(AdwToolbarView, { hexpand: true, vexpand: true, topBar: _jsx(AdwHeaderBar, { titleWidget: _jsx(AdwWindowTitle, { title: entry.name, subtitle: entry.title }), end: _jsx(GtkButton, { label: "Reset story", onClicked: reset }) }), children: _jsxs(GtkBox, { children: [_jsx(GtkBox, { orientation: Gtk.Orientation.VERTICAL, hexpand: true, vexpand: true, children: _jsx(PreviewBoundary, { args: state.args, children: state.error === null ? (_jsx(PreviewContent, { story: entry.story, args: boundArgs })) : (_jsx(AdwStatusPage, { name: "storybook-preview-error", title: "Story action failed", iconName: "dialog-error-symbolic", description: markupEscapeText(state.error.message.slice(0, 500), -1) +
83
+ "\n\nReset the preview or select another story to continue." })) }, state.generation) }), _jsx(StoryInspector, { entry: entry, actions: state.actions, args: state.args, onChange: onChange })] }) }));
87
84
  };
88
85
  export { StorybookPreview };
89
86
  //# sourceMappingURL=explorer-preview.js.map