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

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.
Files changed (42) hide show
  1. package/dist/catalog.d.ts +1 -1
  2. package/dist/catalog.d.ts.map +1 -1
  3. package/dist/catalog.js +4 -1
  4. package/dist/catalog.js.map +1 -1
  5. package/dist/config.d.ts +4 -1
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/controls.d.ts +2 -1
  9. package/dist/controls.d.ts.map +1 -1
  10. package/dist/controls.js +9 -5
  11. package/dist/controls.js.map +1 -1
  12. package/dist/explorer-navigator.d.ts.map +1 -1
  13. package/dist/explorer-navigator.js +29 -2
  14. package/dist/explorer-navigator.js.map +1 -1
  15. package/dist/explorer-preview.d.ts.map +1 -1
  16. package/dist/explorer-preview.js +23 -4
  17. package/dist/explorer-preview.js.map +1 -1
  18. package/dist/explorer-view.d.ts +5 -1
  19. package/dist/explorer-view.d.ts.map +1 -1
  20. package/dist/explorer-view.js +17 -7
  21. package/dist/explorer-view.js.map +1 -1
  22. package/dist/explorer.d.ts +4 -0
  23. package/dist/explorer.d.ts.map +1 -1
  24. package/dist/explorer.js +6 -1
  25. package/dist/explorer.js.map +1 -1
  26. package/dist/types.d.ts +8 -2
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/types.js.map +1 -1
  29. package/dist/upstream.d.ts +4 -2
  30. package/dist/upstream.d.ts.map +1 -1
  31. package/dist/upstream.js +3 -1
  32. package/dist/upstream.js.map +1 -1
  33. package/package.json +9 -9
  34. package/src/catalog.ts +13 -10
  35. package/src/config.ts +4 -1
  36. package/src/controls.tsx +12 -6
  37. package/src/explorer-navigator.tsx +45 -4
  38. package/src/explorer-preview.tsx +55 -19
  39. package/src/explorer-view.tsx +40 -11
  40. package/src/explorer.ts +12 -1
  41. package/src/types.ts +19 -7
  42. package/src/upstream.ts +6 -2
@@ -2,21 +2,31 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as Gio from "@gtkx/gi/gio";
3
3
  import { AdwApplication, AdwApplicationWindow, AdwHeaderBar, AdwOverlaySplitView, AdwStatusPage, AdwToolbarView, AdwWindowTitle, } from "@gtkx/jsx/adw";
4
4
  import { quit } from "@gtkx/react";
5
- import { useCallback, useState, useSyncExternalStore } from "react";
5
+ import { useCallback, useEffect, useEffectEvent, useState, useSyncExternalStore } from "react";
6
6
  import { StoryNavigator } from "./explorer-navigator.js";
7
7
  import { StorybookPreview } from "./explorer-preview.js";
8
- const StorybookView = ({ catalog, title = "GTKX Storybook" }) => {
8
+ const storyCount = (count) => (count === 1 ? "1 story" : `${String(count)} stories`);
9
+ const StorybookView = ({ catalog, title = "GTKX Storybook", initialStoryId, onStorySelected, }) => {
9
10
  const subscribe = useCallback((listener) => catalog.subscribe(listener), [catalog]);
10
11
  const getSnapshot = useCallback(() => catalog.getSnapshot(), [catalog]);
11
12
  const snapshot = useSyncExternalStore(subscribe, getSnapshot);
12
- const [selectedId, setSelectedId] = useState();
13
+ const [selectedId, setSelectedId] = useState(initialStoryId);
13
14
  const selected = snapshot.stories.find((entry) => entry.id === selectedId) ?? snapshot.stories[0];
14
- if (selectedId !== selected?.id) {
15
- setSelectedId(selected?.id);
15
+ if (selected !== undefined && selectedId !== selected.id) {
16
+ setSelectedId(selected.id);
16
17
  }
17
- return (_jsx(AdwOverlaySplitView, { minSidebarWidth: 220, maxSidebarWidth: 300, sidebar: _jsx(AdwToolbarView, { topBar: _jsx(AdwHeaderBar, { titleWidget: _jsx(AdwWindowTitle, { title: title, subtitle: `${String(snapshot.stories.length)} stories` }) }), children: _jsx(StoryNavigator, { stories: snapshot.stories, errors: snapshot.errors, selectedId: selected?.id, onSelect: setSelectedId }) }), children: selected ? (_jsx(StorybookPreview, { entry: selected }, selected.id)) : (_jsx(AdwToolbarView, { topBar: _jsx(AdwHeaderBar, {}), children: _jsx(AdwStatusPage, { name: "storybook-empty", title: snapshot.isLoading ? "Loading stories" : "Choose a story", iconName: "applications-development-symbolic", description: "Stories from your project appear in the sidebar." }) })) }));
18
+ const selectedStoryId = selected?.id;
19
+ const reportSelection = useEffectEvent((id) => {
20
+ onStorySelected?.(id);
21
+ });
22
+ useEffect(() => {
23
+ if (selectedStoryId !== undefined) {
24
+ reportSelection(selectedStoryId);
25
+ }
26
+ }, [selectedStoryId]);
27
+ return (_jsx(AdwOverlaySplitView, { minSidebarWidth: 220, maxSidebarWidth: 300, sidebar: _jsx(AdwToolbarView, { top: _jsx(AdwHeaderBar, { titleWidget: _jsx(AdwWindowTitle, { title: title, subtitle: storyCount(snapshot.stories.length) }) }), children: _jsx(StoryNavigator, { stories: snapshot.stories, errors: snapshot.errors, selectedId: selectedStoryId, onSelect: setSelectedId }) }), children: selected ? (_jsx(StorybookPreview, { entry: selected }, selected.id)) : (_jsx(AdwToolbarView, { top: _jsx(AdwHeaderBar, {}), children: _jsx(AdwStatusPage, { name: "storybook-empty", title: snapshot.isLoading ? "Loading stories" : "Choose a story", iconName: "applications-development-symbolic", description: "Stories from your project appear in the sidebar." }) })) }));
18
28
  };
19
29
  /** Renders the Adwaita explorer application with navigation, story previews, controls, and actions. */
20
- const Storybook = ({ catalog, applicationId = "org.gtkx.Storybook", title = "GTKX Storybook", }) => (_jsx(AdwApplication, { applicationId: applicationId, flags: Gio.ApplicationFlags.NON_UNIQUE, children: _jsx(AdwApplicationWindow, { title: title, defaultWidth: 1200, defaultHeight: 800, onCloseRequest: quit, children: _jsx(StorybookView, { catalog: catalog, title: title }) }) }));
30
+ const Storybook = ({ catalog, applicationId = "org.gtkx.Storybook", title = "GTKX Storybook", initialStoryId, onStorySelected, }) => (_jsx(AdwApplication, { applicationId: applicationId, flags: Gio.ApplicationFlags.NON_UNIQUE, children: _jsx(AdwApplicationWindow, { title: title, defaultWidth: 1200, defaultHeight: 800, onCloseRequest: quit, children: _jsx(StorybookView, { catalog: catalog, title: title, initialStoryId: initialStoryId, onStorySelected: onStorySelected }) }) }));
21
31
  export { Storybook };
22
32
  //# sourceMappingURL=explorer-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"explorer-view.js","sourceRoot":"","sources":["../src/explorer-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport * as Gio from \"@gtkx/gi/gio\";\nimport {\n AdwApplication,\n AdwApplicationWindow,\n AdwHeaderBar,\n AdwOverlaySplitView,\n AdwStatusPage,\n AdwToolbarView,\n AdwWindowTitle,\n} from \"@gtkx/jsx/adw\";\nimport { quit } from \"@gtkx/react\";\nimport { useCallback, useState, useSyncExternalStore } from \"react\";\nimport type { StoryCatalog } from \"./catalog.js\";\nimport { StoryNavigator } from \"./explorer-navigator.js\";\nimport { StorybookPreview } from \"./explorer-preview.js\";\n\n/** Configuration for the native Storybook application shell. */\ntype StorybookProps = {\n /** Source catalog whose stories and loading errors appear in the explorer. */\n catalog: StoryCatalog;\n /** Gio application identifier; defaults to org.gtkx.Storybook. */\n applicationId?: string;\n /** Explorer window and sidebar title; defaults to GTKX Storybook. */\n title?: string;\n};\n\ntype StorybookViewProps = Pick<StorybookProps, \"catalog\" | \"title\">;\n\nconst StorybookView = ({ catalog, title = \"GTKX Storybook\" }: StorybookViewProps): ReactNode => {\n const subscribe = useCallback((listener: () => void) => catalog.subscribe(listener), [catalog]);\n const getSnapshot = useCallback(() => catalog.getSnapshot(), [catalog]);\n const snapshot = useSyncExternalStore(subscribe, getSnapshot);\n const [selectedId, setSelectedId] = useState<string>();\n const selected = snapshot.stories.find((entry) => entry.id === selectedId) ?? snapshot.stories[0];\n\n if (selectedId !== selected?.id) {\n setSelectedId(selected?.id);\n }\n\n return (\n <AdwOverlaySplitView\n minSidebarWidth={220}\n maxSidebarWidth={300}\n sidebar={\n <AdwToolbarView\n topBar={\n <AdwHeaderBar\n titleWidget={\n <AdwWindowTitle title={title} subtitle={`${String(snapshot.stories.length)} stories`} />\n }\n />\n }\n >\n <StoryNavigator\n stories={snapshot.stories}\n errors={snapshot.errors}\n selectedId={selected?.id}\n onSelect={setSelectedId}\n />\n </AdwToolbarView>\n }\n >\n {selected ? (\n <StorybookPreview key={selected.id} entry={selected} />\n ) : (\n <AdwToolbarView topBar={<AdwHeaderBar />}>\n <AdwStatusPage\n name=\"storybook-empty\"\n title={snapshot.isLoading ? \"Loading stories\" : \"Choose a story\"}\n iconName=\"applications-development-symbolic\"\n description=\"Stories from your project appear in the sidebar.\"\n />\n </AdwToolbarView>\n )}\n </AdwOverlaySplitView>\n );\n};\n\n/** Renders the Adwaita explorer application with navigation, story previews, controls, and actions. */\nconst Storybook = ({\n catalog,\n applicationId = \"org.gtkx.Storybook\",\n title = \"GTKX Storybook\",\n}: StorybookProps): ReactNode => (\n <AdwApplication applicationId={applicationId} flags={Gio.ApplicationFlags.NON_UNIQUE}>\n <AdwApplicationWindow title={title} defaultWidth={1200} defaultHeight={800} onCloseRequest={quit}>\n <StorybookView catalog={catalog} title={title} />\n </AdwApplicationWindow>\n </AdwApplication>\n);\n\nexport { Storybook };\n"]}
1
+ {"version":3,"file":"explorer-view.js","sourceRoot":"","sources":["../src/explorer-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport * as Gio from \"@gtkx/gi/gio\";\nimport {\n AdwApplication,\n AdwApplicationWindow,\n AdwHeaderBar,\n AdwOverlaySplitView,\n AdwStatusPage,\n AdwToolbarView,\n AdwWindowTitle,\n} from \"@gtkx/jsx/adw\";\nimport { quit } from \"@gtkx/react\";\nimport { useCallback, useEffect, useEffectEvent, useState, useSyncExternalStore } from \"react\";\nimport type { StoryCatalog } from \"./catalog.js\";\nimport { StoryNavigator } from \"./explorer-navigator.js\";\nimport { StorybookPreview } from \"./explorer-preview.js\";\n\n/** Configuration for the native Storybook application shell. */\ntype StorybookProps = {\n /** Source catalog whose stories and loading errors appear in the explorer. */\n catalog: StoryCatalog;\n /** Gio application identifier; defaults to org.gtkx.Storybook. */\n applicationId?: string;\n /** Explorer window and sidebar title; defaults to GTKX Storybook. */\n title?: string;\n /** Story selected once the catalog lists it; the first story is selected otherwise. */\n initialStoryId?: string | undefined;\n /** Called with the identifier of each story the explorer selects. */\n onStorySelected?: ((id: string) => void) | undefined;\n};\n\ntype StorybookViewProps = Pick<StorybookProps, \"catalog\" | \"title\" | \"initialStoryId\" | \"onStorySelected\">;\n\nconst storyCount = (count: number): string => (count === 1 ? \"1 story\" : `${String(count)} stories`);\n\nconst StorybookView = ({\n catalog,\n title = \"GTKX Storybook\",\n initialStoryId,\n onStorySelected,\n}: StorybookViewProps): ReactNode => {\n const subscribe = useCallback((listener: () => void) => catalog.subscribe(listener), [catalog]);\n const getSnapshot = useCallback(() => catalog.getSnapshot(), [catalog]);\n const snapshot = useSyncExternalStore(subscribe, getSnapshot);\n const [selectedId, setSelectedId] = useState(initialStoryId);\n const selected = snapshot.stories.find((entry) => entry.id === selectedId) ?? snapshot.stories[0];\n\n if (selected !== undefined && selectedId !== selected.id) {\n setSelectedId(selected.id);\n }\n\n const selectedStoryId = selected?.id;\n const reportSelection = useEffectEvent((id: string) => {\n onStorySelected?.(id);\n });\n\n useEffect(() => {\n if (selectedStoryId !== undefined) {\n reportSelection(selectedStoryId);\n }\n }, [selectedStoryId]);\n\n return (\n <AdwOverlaySplitView\n minSidebarWidth={220}\n maxSidebarWidth={300}\n sidebar={\n <AdwToolbarView\n top={\n <AdwHeaderBar\n titleWidget={\n <AdwWindowTitle title={title} subtitle={storyCount(snapshot.stories.length)} />\n }\n />\n }\n >\n <StoryNavigator\n stories={snapshot.stories}\n errors={snapshot.errors}\n selectedId={selectedStoryId}\n onSelect={setSelectedId}\n />\n </AdwToolbarView>\n }\n >\n {selected ? (\n <StorybookPreview key={selected.id} entry={selected} />\n ) : (\n <AdwToolbarView top={<AdwHeaderBar />}>\n <AdwStatusPage\n name=\"storybook-empty\"\n title={snapshot.isLoading ? \"Loading stories\" : \"Choose a story\"}\n iconName=\"applications-development-symbolic\"\n description=\"Stories from your project appear in the sidebar.\"\n />\n </AdwToolbarView>\n )}\n </AdwOverlaySplitView>\n );\n};\n\n/** Renders the Adwaita explorer application with navigation, story previews, controls, and actions. */\nconst Storybook = ({\n catalog,\n applicationId = \"org.gtkx.Storybook\",\n title = \"GTKX Storybook\",\n initialStoryId,\n onStorySelected,\n}: StorybookProps): ReactNode => (\n <AdwApplication applicationId={applicationId} flags={Gio.ApplicationFlags.NON_UNIQUE}>\n <AdwApplicationWindow title={title} defaultWidth={1200} defaultHeight={800} onCloseRequest={quit}>\n <StorybookView\n catalog={catalog}\n title={title}\n initialStoryId={initialStoryId}\n onStorySelected={onStorySelected}\n />\n </AdwApplicationWindow>\n </AdwApplication>\n);\n\nexport { Storybook };\n"]}
@@ -13,6 +13,10 @@ type StorybookSession = {
13
13
  declare const startStorybook: (options: {
14
14
  /** Gio application identifier assigned to the explorer application. */
15
15
  applicationId: string;
16
+ /** Story to select once it is loaded, such as the one a restarted explorer was showing. */
17
+ initialStoryId?: string | undefined;
18
+ /** Called with the identifier of each story the explorer selects. */
19
+ onStorySelected?: ((id: string) => void) | undefined;
16
20
  }) => StorybookSession;
17
21
  export { startStorybook };
18
22
  export type { StorybookSession };
@@ -1 +1 @@
1
- {"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,2EAA2E;AAC3E,KAAK,gBAAgB,GAAG;IACpB,kGAAkG;IAClG,aAAa,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,sFAAsF;IACtF,oBAAoB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,8DAA8D;IAC9D,IAAI,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wFAAwF;AACxF,QAAA,MAAM,cAAc,YAAa;IAC7B,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;CACzB,KAAG,gBAcH,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,CAAC;AACjC,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAElG,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,2EAA2E;AAC3E,KAAK,gBAAgB,GAAG;IACpB,kGAAkG;IAClG,aAAa,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,sFAAsF;IACtF,oBAAoB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,8DAA8D;IAC9D,IAAI,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wFAAwF;AACxF,QAAA,MAAM,cAAc,YAAa;IAC7B,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,qEAAqE;IACrE,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACxD,KAAG,gBAqBH,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,CAAC;AACjC,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAElG,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/explorer.js CHANGED
@@ -6,7 +6,12 @@ import { Storybook } from "./explorer-view.js";
6
6
  const startStorybook = (options) => {
7
7
  const catalog = new StoryCatalog();
8
8
  const root = createRoot(undefined, { onUncaughtError: catalog.reportError.bind(catalog) });
9
- root.render(createElement(Storybook, { catalog, applicationId: options.applicationId }));
9
+ root.render(createElement(Storybook, {
10
+ catalog,
11
+ applicationId: options.applicationId,
12
+ initialStoryId: options.initialStoryId,
13
+ onStorySelected: options.onStorySelected,
14
+ }));
10
15
  return {
11
16
  updateStories: (sources, preview) => catalog.load(sources, preview),
12
17
  reportStorybookError: (cause) => {
@@ -1 +1 @@
1
- {"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAY/C,wFAAwF;AACxF,MAAM,cAAc,GAAG,CAAC,OAGvB,EAAoB,EAAE;IACnB,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3F,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAEzF,OAAO;QACH,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;QACnE,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,EAAE,GAAG,EAAE;YACP,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAI1B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["import { createRoot } from \"@gtkx/react\";\nimport { createElement } from \"react\";\nimport type { StorySource } from \"./catalog.js\";\nimport type { Preview } from \"./types.js\";\nimport { StoryCatalog } from \"./catalog.js\";\nimport { Storybook } from \"./explorer-view.js\";\n\n/** Controls a running native Storybook explorer and its source catalog. */\ntype StorybookSession = {\n /** Replaces discovered sources and preview annotations, rejecting if any source fails to load. */\n updateStories: (sources: StorySource[], preview?: Preview) => Promise<void>;\n /** Displays a session failure while keeping successfully loaded stories available. */\n reportStorybookError: (cause: unknown) => void;\n /** Unmounts the explorer and its story windows or dialogs. */\n stop: () => void;\n};\n\n/** Starts a native explorer and returns the handle used to load stories and stop it. */\nconst startStorybook = (options: {\n /** Gio application identifier assigned to the explorer application. */\n applicationId: string;\n}): StorybookSession => {\n const catalog = new StoryCatalog();\n const root = createRoot(undefined, { onUncaughtError: catalog.reportError.bind(catalog) });\n root.render(createElement(Storybook, { catalog, applicationId: options.applicationId }));\n\n return {\n updateStories: (sources, preview) => catalog.load(sources, preview),\n reportStorybookError: (cause) => {\n catalog.reportError(cause);\n },\n stop: () => {\n root.unmount();\n },\n };\n};\n\nexport { startStorybook };\nexport type { StorybookSession };\nexport type { StoryCatalogSnapshot, StoryEntry, StoryLoadError, StorySource } from \"./catalog.js\";\n\nexport { StoryCatalog } from \"./catalog.js\";\n\nexport { Storybook } from \"./explorer-view.js\";\n"]}
1
+ {"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAY/C,wFAAwF;AACxF,MAAM,cAAc,GAAG,CAAC,OAOvB,EAAoB,EAAE;IACnB,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3F,IAAI,CAAC,MAAM,CACP,aAAa,CAAC,SAAS,EAAE;QACrB,OAAO;QACP,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,eAAe,EAAE,OAAO,CAAC,eAAe;KAC3C,CAAC,CACL,CAAC;IAEF,OAAO;QACH,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;QACnE,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,EAAE,GAAG,EAAE;YACP,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAI1B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["import { createRoot } from \"@gtkx/react\";\nimport { createElement } from \"react\";\nimport type { StorySource } from \"./catalog.js\";\nimport type { Preview } from \"./types.js\";\nimport { StoryCatalog } from \"./catalog.js\";\nimport { Storybook } from \"./explorer-view.js\";\n\n/** Controls a running native Storybook explorer and its source catalog. */\ntype StorybookSession = {\n /** Replaces discovered sources and preview annotations, rejecting if any source fails to load. */\n updateStories: (sources: StorySource[], preview?: Preview) => Promise<void>;\n /** Displays a session failure while keeping successfully loaded stories available. */\n reportStorybookError: (cause: unknown) => void;\n /** Unmounts the explorer and its story windows or dialogs. */\n stop: () => void;\n};\n\n/** Starts a native explorer and returns the handle used to load stories and stop it. */\nconst startStorybook = (options: {\n /** Gio application identifier assigned to the explorer application. */\n applicationId: string;\n /** Story to select once it is loaded, such as the one a restarted explorer was showing. */\n initialStoryId?: string | undefined;\n /** Called with the identifier of each story the explorer selects. */\n onStorySelected?: ((id: string) => void) | undefined;\n}): StorybookSession => {\n const catalog = new StoryCatalog();\n const root = createRoot(undefined, { onUncaughtError: catalog.reportError.bind(catalog) });\n root.render(\n createElement(Storybook, {\n catalog,\n applicationId: options.applicationId,\n initialStoryId: options.initialStoryId,\n onStorySelected: options.onStorySelected,\n }),\n );\n\n return {\n updateStories: (sources, preview) => catalog.load(sources, preview),\n reportStorybookError: (cause) => {\n catalog.reportError(cause);\n },\n stop: () => {\n root.unmount();\n },\n };\n};\n\nexport { startStorybook };\nexport type { StorybookSession };\nexport type { StoryCatalogSnapshot, StoryEntry, StoryLoadError, StorySource } from \"./catalog.js\";\n\nexport { StoryCatalog } from \"./catalog.js\";\n\nexport { Storybook } from \"./explorer-view.js\";\n"]}
package/dist/types.d.ts CHANGED
@@ -119,11 +119,17 @@ type StoryModule = {
119
119
  /** Component metadata validated when the module is composed. */
120
120
  default: unknown;
121
121
  };
122
+ /** Whether a story's declared args name only args of the component metadata, as stories typed from the metadata do. */
123
+ type IsMetaArgs<TArgs, TMetaArgs> = [Exclude<keyof TArgs, keyof TMetaArgs>] extends [never] ? true : false;
124
+ /** Args of a story export: the component metadata's args, or the args type the story declares itself. */
125
+ type StoryArgs<TModule extends StoryModule, TStory> = TStory extends StoryAnnotations<infer TArgs extends object> ? IsMetaArgs<TArgs, ArgsFrom<TModule["default"]>> extends true ? TStory extends StoryAnnotations<ArgsFrom<TModule["default"]>> ? ArgsFrom<TModule["default"]> : TArgs : TArgs : never;
122
126
  /** Named module exports whose types match CSF3 stories, excluding module bookkeeping. */
123
127
  type StoryKeys<TModule extends StoryModule> = {
124
- [Key in keyof TModule]: Key extends "default" | "__esModule" | "__namedExportsOrder" ? never : TModule[Key] extends StoryAnnotations<ArgsFrom<TModule["default"]>> ? Key : never;
128
+ [Key in keyof TModule]: Key extends "default" | "__esModule" | "__namedExportsOrder" ? never : [StoryArgs<TModule, TModule[Key]>] extends [never] ? never : Key;
125
129
  }[keyof TModule] & string;
126
130
  /** Composed stories keyed by their original named exports. */
127
- type ComposedStories<TModule extends StoryModule> = Record<StoryKeys<TModule>, ComposedStory<ArgsFrom<TModule["default"]>>>;
131
+ type ComposedStories<TModule extends StoryModule> = {
132
+ [Key in StoryKeys<TModule>]: ComposedStory<StoryArgs<TModule, TModule[Key]>>;
133
+ };
128
134
  export type { Args, ArgTypes, ComponentMeta, ComposedStories, ComposedStory, Decorator, Meta, Preview, StoryAnnotations, StoryContext, StoryContextUpdate, StoryModule, StoryObj, StoryRender, };
129
135
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport type {\n ArgsFromMeta,\n ComponentAnnotations,\n GlobalTypes,\n Renderer,\n StoryAnnotations as StorybookAnnotations,\n ArgTypes as StorybookArgTypes,\n StoryContext as StorybookContext,\n} from \"storybook/internal/types\";\n\n/** Named values supplied to a story, including component props and custom render args. */\ntype Args = Record<string, unknown>;\n\n/** Storybook renderer types for React content rendered as native GTK widgets. */\ntype NativeRenderer<TArgs extends object = Args> = Renderer & {\n /** React component receiving the story's args. */\n component: ComponentType<TArgs>;\n /** React content returned by story rendering. */\n storyResult: ReactNode;\n /** Native widget type representing the preview canvas. */\n canvasElement: Gtk.Widget;\n};\n\n/** Explicit argument metadata used to configure native controls and named actions. */\ntype ArgTypes<TArgs extends object = Args> = Partial<StorybookArgTypes<TArgs>>;\n\n/** Composed story identity, args, and annotations available to render functions and decorators. */\ntype StoryContext<TArgs extends object = Args> = Pick<\n StorybookContext<NativeRenderer<TArgs>, TArgs>,\n \"id\" | \"name\" | \"title\" | \"args\" | \"initialArgs\" | \"argTypes\" | \"viewMode\"\n> & {\n /** Parameters merged from preview, component metadata, and the story. */\n parameters: Args;\n /** Global values after applying preview defaults and metadata or story overrides. */\n globals: Args;\n};\n\n/** Renders native React content from the current story args and composition context. */\ntype StoryRender<TArgs extends object = Args> = (args: TArgs, context: StoryContext<TArgs>) => ReactNode;\n\n/** Values a decorator can override when invoking the decorated story. */\ntype StoryContextUpdate<TArgs extends object = Args> = {\n /** Partial args merged into the current invocation without changing composed defaults. */\n args?: Partial<TArgs>;\n /** Global values overridden for the decorated invocation. */\n globals?: Args;\n};\n\n/** Wraps story content and can override args or globals when invoking the supplied Story function. */\ntype Decorator<TArgs extends object = Args> = (\n Story: (update?: StoryContextUpdate<TArgs>) => ReactNode,\n context: StoryContext<TArgs>,\n) => ReactNode;\n\n/** Shared CSF annotations accepted at preview, component, and story scope. */\ntype Annotations<TArgs extends object> = {\n /** Default args, with more specific annotation scopes taking precedence. */\n args?: Partial<TArgs>;\n /** Explicit argument descriptions, controls, and action registrations. */\n argTypes?: ArgTypes<TArgs>;\n /** Parameters merged across scopes, including native preview and layout settings. */\n parameters?: Args;\n /** Wrappers composed around the story's render function. */\n decorators?: Decorator<TArgs>[];\n /** Custom renderer used in place of the component or a less specific render annotation. */\n render?: StoryRender<TArgs>;\n /** Storybook tags composed with tags from other annotation scopes. */\n tags?: string[];\n};\n\n/** Default export metadata describing a component's stories and their shared annotations. */\ntype ComponentMeta<TArgs extends object> = Annotations<TArgs> &\n Pick<ComponentAnnotations<NativeRenderer<TArgs>, TArgs>, \"title\" | \"id\" | \"includeStories\" | \"excludeStories\"> & {\n /** Component rendered with story args when no custom render annotation applies. */\n component?: ComponentType<TArgs>;\n /** Global overrides shared by this component's stories. */\n globals?: Args;\n };\n\n/** Resolves a component's props or accepts an explicitly supplied args object type. */\ntype ComponentOrProps<T> = T extends ComponentType<infer Props extends object> ? Props : T extends object ? T : Args;\n\n/** Presents combined inferred args as a single object type. */\ntype Simplify<T> = { [Key in keyof T]: T[Key] };\n\n/** Infers story args from component props, render functions, decorators, or declared defaults. */\ntype ArgsFrom<T> = T extends { component?: infer Component; render?: unknown; decorators?: unknown }\n ? Simplify<\n (NonNullable<Component> extends ComponentType<infer Props extends object> ? Props : object) &\n ArgsFromMeta<NativeRenderer, T>\n >\n : T extends { args: infer Defaults extends object }\n ? Defaults\n : Args;\n\n/** CSF3 default export metadata typed from a React component or an explicit args type. */\ntype Meta<T = Args> = ComponentMeta<ComponentOrProps<T>>;\n\n/** Annotations for one CSF3 story object, including its display name and global overrides. */\ntype StoryAnnotations<TArgs extends object> = Annotations<TArgs> & {\n /** Display name overriding the name derived from the story's named export. */\n name?: string;\n /** Global overrides applied specifically to this story. */\n globals?: Args;\n};\n\n/** Extracts args already defaulted by component metadata. */\ntype DefaultArgs<T> = T extends { args: infer Defaults } ? Defaults : Record<never, never>;\n\n/** Makes args with metadata defaults optional while preserving other required args. */\ntype RequiredStoryArgs<T, TArgs extends object> = Omit<TArgs, keyof DefaultArgs<T>> &\n Partial<Pick<TArgs, keyof TArgs & keyof DefaultArgs<T>>>;\n\n/** CSF3 story object inferred from metadata, a React component, or an explicit args type. */\ntype StoryObj<T = Args> = T extends { component?: unknown; render?: unknown; decorators?: unknown; args?: unknown }\n ? StoryAnnotations<ArgsFrom<T>> &\n Pick<\n StorybookAnnotations<NativeRenderer<ArgsFrom<T>>, ArgsFrom<T>, RequiredStoryArgs<T, ArgsFrom<T>>>,\n \"args\"\n >\n : StoryAnnotations<ComponentOrProps<T>>;\n\n/** Project annotations shared by all composed stories. */\ntype Preview = Annotations<Args> & {\n /** Initial global values available in story rendering and decorators. */\n initialGlobals?: Args;\n /** Storybook metadata describing global values; native toolbar controls are not provided. */\n globalTypes?: GlobalTypes;\n};\n\n/** Renderable story with merged annotations; props override its composed default args. */\ntype ComposedStory<TArgs extends object = Args> = ((args: Partial<TArgs>) => ReactNode) & {\n /** Default args merged across preview, component metadata, and story annotations. */\n args: Partial<TArgs>;\n /** Composed argument metadata available to native controls and actions. */\n argTypes: ArgTypes<TArgs>;\n /** Composed parameters available to the renderer and explorer. */\n parameters: Args;\n /** Composed global values available in story context. */\n globals: Args;\n /** Storybook identifier derived from component identity and the story export. */\n id: string;\n /** Story name attached by Storybook's portable composition API. */\n storyName: string;\n /** Tags resulting from composition across annotation scopes. */\n tags: string[];\n};\n\n/** Imported CSF module containing default metadata and named story exports. */\ntype StoryModule = {\n /** Component metadata validated when the module is composed. */\n default: unknown;\n};\n\n/** Named module exports whose types match CSF3 stories, excluding module bookkeeping. */\ntype StoryKeys<TModule extends StoryModule> = {\n [Key in keyof TModule]: Key extends \"default\" | \"__esModule\" | \"__namedExportsOrder\"\n ? never\n : TModule[Key] extends StoryAnnotations<ArgsFrom<TModule[\"default\"]>>\n ? Key\n : never;\n}[keyof TModule] &\n string;\n\n/** Composed stories keyed by their original named exports. */\ntype ComposedStories<TModule extends StoryModule> = Record<\n StoryKeys<TModule>,\n ComposedStory<ArgsFrom<TModule[\"default\"]>>\n>;\n\nexport type {\n Args,\n ArgTypes,\n ComponentMeta,\n ComposedStories,\n ComposedStory,\n Decorator,\n Meta,\n Preview,\n StoryAnnotations,\n StoryContext,\n StoryContextUpdate,\n StoryModule,\n StoryObj,\n StoryRender,\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport type {\n ArgsFromMeta,\n ComponentAnnotations,\n GlobalTypes,\n Renderer,\n StoryAnnotations as StorybookAnnotations,\n ArgTypes as StorybookArgTypes,\n StoryContext as StorybookContext,\n} from \"storybook/internal/types\";\n\n/** Named values supplied to a story, including component props and custom render args. */\ntype Args = Record<string, unknown>;\n\n/** Storybook renderer types for React content rendered as native GTK widgets. */\ntype NativeRenderer<TArgs extends object = Args> = Renderer & {\n /** React component receiving the story's args. */\n component: ComponentType<TArgs>;\n /** React content returned by story rendering. */\n storyResult: ReactNode;\n /** Native widget type representing the preview canvas. */\n canvasElement: Gtk.Widget;\n};\n\n/** Explicit argument metadata used to configure native controls and named actions. */\ntype ArgTypes<TArgs extends object = Args> = Partial<StorybookArgTypes<TArgs>>;\n\n/** Composed story identity, args, and annotations available to render functions and decorators. */\ntype StoryContext<TArgs extends object = Args> = Pick<\n StorybookContext<NativeRenderer<TArgs>, TArgs>,\n \"id\" | \"name\" | \"title\" | \"args\" | \"initialArgs\" | \"argTypes\" | \"viewMode\"\n> & {\n /** Parameters merged from preview, component metadata, and the story. */\n parameters: Args;\n /** Global values after applying preview defaults and metadata or story overrides. */\n globals: Args;\n};\n\n/** Renders native React content from the current story args and composition context. */\ntype StoryRender<TArgs extends object = Args> = (args: TArgs, context: StoryContext<TArgs>) => ReactNode;\n\n/** Values a decorator can override when invoking the decorated story. */\ntype StoryContextUpdate<TArgs extends object = Args> = {\n /** Partial args merged into the current invocation without changing composed defaults. */\n args?: Partial<TArgs>;\n /** Global values overridden for the decorated invocation. */\n globals?: Args;\n};\n\n/** Wraps story content and can override args or globals when invoking the supplied Story function. */\ntype Decorator<TArgs extends object = Args> = (\n Story: (update?: StoryContextUpdate<TArgs>) => ReactNode,\n context: StoryContext<TArgs>,\n) => ReactNode;\n\n/** Shared CSF annotations accepted at preview, component, and story scope. */\ntype Annotations<TArgs extends object> = {\n /** Default args, with more specific annotation scopes taking precedence. */\n args?: Partial<TArgs>;\n /** Explicit argument descriptions, controls, and action registrations. */\n argTypes?: ArgTypes<TArgs>;\n /** Parameters merged across scopes, including native preview and layout settings. */\n parameters?: Args;\n /** Wrappers composed around the story's render function. */\n decorators?: Decorator<TArgs>[];\n /** Custom renderer used in place of the component or a less specific render annotation. */\n render?: StoryRender<TArgs>;\n /** Storybook tags composed with tags from other annotation scopes. */\n tags?: string[];\n};\n\n/** Default export metadata describing a component's stories and their shared annotations. */\ntype ComponentMeta<TArgs extends object> = Annotations<TArgs> &\n Pick<ComponentAnnotations<NativeRenderer<TArgs>, TArgs>, \"title\" | \"id\" | \"includeStories\" | \"excludeStories\"> & {\n /** Component rendered with story args when no custom render annotation applies. */\n component?: ComponentType<TArgs>;\n /** Global overrides shared by this component's stories. */\n globals?: Args;\n };\n\n/** Resolves a component's props or accepts an explicitly supplied args object type. */\ntype ComponentOrProps<T> = T extends ComponentType<infer Props extends object> ? Props : T extends object ? T : Args;\n\n/** Presents combined inferred args as a single object type. */\ntype Simplify<T> = { [Key in keyof T]: T[Key] };\n\n/** Infers story args from component props, render functions, decorators, or declared defaults. */\ntype ArgsFrom<T> = T extends { component?: infer Component; render?: unknown; decorators?: unknown }\n ? Simplify<\n (NonNullable<Component> extends ComponentType<infer Props extends object> ? Props : object) &\n ArgsFromMeta<NativeRenderer, T>\n >\n : T extends { args: infer Defaults extends object }\n ? Defaults\n : Args;\n\n/** CSF3 default export metadata typed from a React component or an explicit args type. */\ntype Meta<T = Args> = ComponentMeta<ComponentOrProps<T>>;\n\n/** Annotations for one CSF3 story object, including its display name and global overrides. */\ntype StoryAnnotations<TArgs extends object> = Annotations<TArgs> & {\n /** Display name overriding the name derived from the story's named export. */\n name?: string;\n /** Global overrides applied specifically to this story. */\n globals?: Args;\n};\n\n/** Extracts args already defaulted by component metadata. */\ntype DefaultArgs<T> = T extends { args: infer Defaults } ? Defaults : Record<never, never>;\n\n/** Makes args with metadata defaults optional while preserving other required args. */\ntype RequiredStoryArgs<T, TArgs extends object> = Omit<TArgs, keyof DefaultArgs<T>> &\n Partial<Pick<TArgs, keyof TArgs & keyof DefaultArgs<T>>>;\n\n/** CSF3 story object inferred from metadata, a React component, or an explicit args type. */\ntype StoryObj<T = Args> = T extends { component?: unknown; render?: unknown; decorators?: unknown; args?: unknown }\n ? StoryAnnotations<ArgsFrom<T>> &\n Pick<\n StorybookAnnotations<NativeRenderer<ArgsFrom<T>>, ArgsFrom<T>, RequiredStoryArgs<T, ArgsFrom<T>>>,\n \"args\"\n >\n : StoryAnnotations<ComponentOrProps<T>>;\n\n/** Project annotations shared by all composed stories. */\ntype Preview = Annotations<Args> & {\n /** Initial global values available in story rendering and decorators. */\n initialGlobals?: Args;\n /** Storybook metadata describing global values; native toolbar controls are not provided. */\n globalTypes?: GlobalTypes;\n};\n\n/** Renderable story with merged annotations; props override its composed default args. */\ntype ComposedStory<TArgs extends object = Args> = ((args: Partial<TArgs>) => ReactNode) & {\n /** Default args merged across preview, component metadata, and story annotations. */\n args: Partial<TArgs>;\n /** Composed argument metadata available to native controls and actions. */\n argTypes: ArgTypes<TArgs>;\n /** Composed parameters available to the renderer and explorer. */\n parameters: Args;\n /** Composed global values available in story context. */\n globals: Args;\n /** Storybook identifier derived from component identity and the story export. */\n id: string;\n /** Story name attached by Storybook's portable composition API. */\n storyName: string;\n /** Tags resulting from composition across annotation scopes. */\n tags: string[];\n};\n\n/** Imported CSF module containing default metadata and named story exports. */\ntype StoryModule = {\n /** Component metadata validated when the module is composed. */\n default: unknown;\n};\n\n/** Whether a story's declared args name only args of the component metadata, as stories typed from the metadata do. */\ntype IsMetaArgs<TArgs, TMetaArgs> = [Exclude<keyof TArgs, keyof TMetaArgs>] extends [never] ? true : false;\n\n/** Args of a story export: the component metadata's args, or the args type the story declares itself. */\ntype StoryArgs<TModule extends StoryModule, TStory> =\n TStory extends StoryAnnotations<infer TArgs extends object>\n ? IsMetaArgs<TArgs, ArgsFrom<TModule[\"default\"]>> extends true\n ? TStory extends StoryAnnotations<ArgsFrom<TModule[\"default\"]>>\n ? ArgsFrom<TModule[\"default\"]>\n : TArgs\n : TArgs\n : never;\n\n/** Named module exports whose types match CSF3 stories, excluding module bookkeeping. */\ntype StoryKeys<TModule extends StoryModule> = {\n [Key in keyof TModule]: Key extends \"default\" | \"__esModule\" | \"__namedExportsOrder\"\n ? never\n : [StoryArgs<TModule, TModule[Key]>] extends [never]\n ? never\n : Key;\n}[keyof TModule] &\n string;\n\n/** Composed stories keyed by their original named exports. */\ntype ComposedStories<TModule extends StoryModule> = {\n [Key in StoryKeys<TModule>]: ComposedStory<StoryArgs<TModule, TModule[Key]>>;\n};\n\nexport type {\n Args,\n ArgTypes,\n ComponentMeta,\n ComposedStories,\n ComposedStory,\n Decorator,\n Meta,\n Preview,\n StoryAnnotations,\n StoryContext,\n StoryContextUpdate,\n StoryModule,\n StoryObj,\n StoryRender,\n};\n"]}
@@ -1,4 +1,5 @@
1
- import type { ComponentMeta, ComposedStory, Preview, StoryAnnotations, StoryRender } from "./types.js";
1
+ import type { InputType } from "storybook/internal/types";
2
+ import type { Args, ComponentMeta, ComposedStory, Preview, StoryAnnotations, StoryRender } from "./types.js";
2
3
  type ComposeStory = <TArgs extends object>(...annotations: [
3
4
  story: StoryAnnotations<TArgs>,
4
5
  meta: ComponentMeta<TArgs>,
@@ -9,6 +10,7 @@ type ComposeStory = <TArgs extends object>(...annotations: [
9
10
  exportName?: string
10
11
  ]) => ComposedStory<TArgs>;
11
12
  declare const composeStoryAnnotations: ComposeStory;
12
- export { composeStoryAnnotations };
13
+ declare const isConditionalArgIncluded: (argType: InputType, args: Args, globals: Args) => boolean;
14
+ export { composeStoryAnnotations, isConditionalArgIncluded };
13
15
  export { isExportStory, storyNameFromExport } from "storybook/internal/csf";
14
16
  //# sourceMappingURL=upstream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvG,KAAK,YAAY,GAAG,CAAC,KAAK,SAAS,MAAM,EACrC,GAAG,WAAW,EAAE;IACZ,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC;IAC9B,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC;IAC1B,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;KAAE;IACxC,UAAU,CAAC,EAAE,MAAM;CACtB,KACA,aAAa,CAAC,KAAK,CAAC,CAAC;AAE1B,QAAA,MAAM,uBAAuB,EAAmB,YAAY,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7G,KAAK,YAAY,GAAG,CAAC,KAAK,SAAS,MAAM,EACrC,GAAG,WAAW,EAAE;IACZ,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC;IAC9B,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC;IAC1B,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;KAAE;IACxC,UAAU,CAAC,EAAE,MAAM;CACtB,KACA,aAAa,CAAC,KAAK,CAAC,CAAC;AAE1B,QAAA,MAAM,uBAAuB,EAAmB,YAAY,CAAC;AAE7D,QAAA,MAAM,wBAAwB,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,KAAK,OAA+B,CAAC;AAEnH,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/upstream.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { includeConditionalArg } from "storybook/internal/csf";
1
2
  import { composeStory } from "storybook/preview-api";
2
3
  const composeStoryAnnotations = composeStory;
3
- export { composeStoryAnnotations };
4
+ const isConditionalArgIncluded = includeConditionalArg;
5
+ export { composeStoryAnnotations, isConditionalArgIncluded };
4
6
  export { isExportStory, storyNameFromExport } from "storybook/internal/csf";
5
7
  //# sourceMappingURL=upstream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upstream.js","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAarD,MAAM,uBAAuB,GAAG,YAA4B,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["import { composeStory } from \"storybook/preview-api\";\nimport type { ComponentMeta, ComposedStory, Preview, StoryAnnotations, StoryRender } from \"./types.js\";\n\ntype ComposeStory = <TArgs extends object>(\n ...annotations: [\n story: StoryAnnotations<TArgs>,\n meta: ComponentMeta<TArgs>,\n preview: Preview,\n renderer: { render: StoryRender<TArgs> },\n exportName?: string,\n ]\n) => ComposedStory<TArgs>;\n\nconst composeStoryAnnotations = composeStory as ComposeStory;\n\nexport { composeStoryAnnotations };\n\nexport { isExportStory, storyNameFromExport } from \"storybook/internal/csf\";\n"]}
1
+ {"version":3,"file":"upstream.js","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAarD,MAAM,uBAAuB,GAAG,YAA4B,CAAC;AAE7D,MAAM,wBAAwB,GAA+D,qBAAqB,CAAC;AAEnH,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["import type { InputType } from \"storybook/internal/types\";\nimport { includeConditionalArg } from \"storybook/internal/csf\";\nimport { composeStory } from \"storybook/preview-api\";\nimport type { Args, ComponentMeta, ComposedStory, Preview, StoryAnnotations, StoryRender } from \"./types.js\";\n\ntype ComposeStory = <TArgs extends object>(\n ...annotations: [\n story: StoryAnnotations<TArgs>,\n meta: ComponentMeta<TArgs>,\n preview: Preview,\n renderer: { render: StoryRender<TArgs> },\n exportName?: string,\n ]\n) => ComposedStory<TArgs>;\n\nconst composeStoryAnnotations = composeStory as ComposeStory;\n\nconst isConditionalArgIncluded: (argType: InputType, args: Args, globals: Args) => boolean = includeConditionalArg;\n\nexport { composeStoryAnnotations, isConditionalArgIncluded };\n\nexport { isExportStory, storyNameFromExport } from \"storybook/internal/csf\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/storybook",
3
- "version": "2.0.0-beta.12",
3
+ "version": "2.0.0-beta.13",
4
4
  "description": "Native component stories for GTKX.",
5
5
  "keywords": [
6
6
  "gtkx",
@@ -56,21 +56,21 @@
56
56
  "node": ">=26.7.0"
57
57
  },
58
58
  "dependencies": {
59
- "@gtkx/components": "2.0.0-beta.12",
60
- "@gtkx/react": "2.0.0-beta.12",
61
- "@gtkx/utils": "2.0.0-beta.12",
62
- "storybook": "10.6.2"
59
+ "@gtkx/components": "^2.0.0-beta.13",
60
+ "@gtkx/react": "^2.0.0-beta.13",
61
+ "@gtkx/utils": "^2.0.0-beta.13",
62
+ "storybook": "10.6.5"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@types/react": "^19.3",
66
66
  "react": "^19.3"
67
67
  },
68
68
  "devDependencies": {
69
- "@gtkx/config": "2.0.0-beta.12",
70
- "@gtkx/testing": "2.0.0-beta.12",
71
- "@gtkx/vitest": "2.0.0-beta.12",
69
+ "@gtkx/config": "2.0.0-beta.13",
70
+ "@gtkx/testing": "2.0.0-beta.13",
71
+ "@gtkx/vitest": "2.0.0-beta.13",
72
72
  "@types/react": "^19.3.0",
73
- "vitest": "5.0.5"
73
+ "vitest": "5.1.0"
74
74
  },
75
75
  "scripts": {
76
76
  "release": "node ../../scripts/release/publish-package.ts"
package/src/catalog.ts CHANGED
@@ -41,7 +41,7 @@ type StoryLoadError = {
41
41
 
42
42
  /** Current explorer contents and loading state exposed to subscribers. */
43
43
  type StoryCatalogSnapshot = {
44
- /** Successfully composed stories with duplicate identifiers excluded. */
44
+ /** Successfully composed stories tagged `dev`, with duplicate identifiers excluded. */
45
45
  stories: StoryEntry[];
46
46
  /** Failures encountered during the latest load or reported by the session. */
47
47
  errors: StoryLoadError[];
@@ -59,6 +59,7 @@ type CachedStories = {
59
59
  type LoadedSource = StoryLoadError | { source: StorySource; cached: CachedStories };
60
60
 
61
61
  const EMPTY_PREVIEW: Preview = {};
62
+ const DEVELOPMENT_TAG = "dev";
62
63
 
63
64
  const isObject = (value: unknown): value is Record<string, unknown> =>
64
65
  value !== null && typeof value === "object" && !Array.isArray(value);
@@ -118,15 +119,17 @@ const composeSource = (source: StorySource, module: unknown, preview: Preview):
118
119
  } as Record<string, StoryAnnotations<Args>> & { default: ComponentMeta<Args> };
119
120
  const stories = composeStories(annotations, preview);
120
121
 
121
- return Object.entries(stories).map(([exportName, story]) => ({
122
- id: story.id,
123
- title,
124
- name: displayName(annotations[exportName], exportName),
125
- exportName,
126
- source: source.id,
127
- story,
128
- controls: explicitControls(story.argTypes, annotations[exportName], annotations.default, preview),
129
- }));
122
+ return Object.entries(stories)
123
+ .filter(([, story]) => story.tags.includes(DEVELOPMENT_TAG))
124
+ .map(([exportName, story]) => ({
125
+ id: story.id,
126
+ title,
127
+ name: displayName(annotations[exportName], exportName),
128
+ exportName,
129
+ source: source.id,
130
+ story,
131
+ controls: explicitControls(story.argTypes, annotations[exportName], annotations.default, preview),
132
+ }));
130
133
  };
131
134
 
132
135
  const withoutDuplicateIds = (entries: StoryEntry[], errors: StoryLoadError[]): StoryEntry[] => {
package/src/config.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  /** Story discovery and preview configuration for the native explorer. */
2
2
  type StorybookConfig = {
3
- /** Project-relative globs; defaults to CSF story files under src. */
3
+ /**
4
+ * Project-relative globs; defaults to CSF story files under src. A glob may reach a sibling workspace
5
+ * package through `..` segments when every file it matches lies inside the workspace root.
6
+ */
4
7
  stories?: string[];
5
8
  /** Additional project-relative globs excluded from discovery. */
6
9
  exclude?: string[];
package/src/controls.tsx CHANGED
@@ -4,8 +4,9 @@ import { markupEscapeText } from "@gtkx/gi/glib";
4
4
  import { AdwActionRow, AdwEntryRow, AdwPreferencesGroup, AdwSpinRow, AdwSwitchRow } from "@gtkx/jsx/adw";
5
5
  import { GtkAdjustment } from "@gtkx/jsx/gtk";
6
6
  import type { Args, ArgTypes } from "./types.js";
7
+ import { isConditionalArgIncluded } from "./upstream.js";
7
8
 
8
- type ControlsProps = { argTypes: ArgTypes; args: Args; onChange: (update: Args) => void };
9
+ type ControlsProps = { argTypes: ArgTypes; args: Args; globals: Args; onChange: (update: Args) => void };
9
10
 
10
11
  const NO_SELECTION_ID = "no-selection";
11
12
  const NO_SELECTION_LABEL = "Choose option...";
@@ -29,8 +30,8 @@ const isWithinBoundsOrAbsent = (value: unknown, min: number, max: number): boole
29
30
 
30
31
  const controlTitle = (name: unknown, argument: string): string => (typeof name === "string" ? name : argument);
31
32
 
32
- const numberDigits = (step: number): number => {
33
- const [coefficient = "", exponent = "0"] = String(step).split("e", 2);
33
+ const numberDigits = (value: number): number => {
34
+ const [coefficient = "", exponent = "0"] = String(value).split("e", 2);
34
35
  const fraction = coefficient.split(".", 2)[1]?.length ?? 0;
35
36
  const digits = Math.max(0, fraction - Number(exponent));
36
37
 
@@ -75,7 +76,7 @@ const NumberControl = ({
75
76
  title={markupEscapeText(title, -1)}
76
77
  sensitive={!isDisabled}
77
78
  value={currentValue}
78
- digits={numberDigits(step)}
79
+ digits={Math.max(numberDigits(step), numberDigits(currentValue))}
79
80
  numeric
80
81
  widthChars={8}
81
82
  adjustment={
@@ -197,13 +198,18 @@ const Control = (props: ControlProps): ReactNode => {
197
198
  }
198
199
  };
199
200
 
200
- const Controls = ({ argTypes, args, onChange }: ControlsProps): ReactNode => (
201
+ const Controls = ({ argTypes, args, globals, onChange }: ControlsProps): ReactNode => (
201
202
  <AdwPreferencesGroup title="Controls">
202
203
  {Object.entries(argTypes).map(([argument, annotation]) => {
203
204
  const control: unknown = annotation?.control;
204
205
  const table = isObject(annotation?.table) ? annotation.table : {};
205
206
 
206
- if (control === undefined || control === false || table.disable === true) {
207
+ if (
208
+ control === undefined ||
209
+ control === false ||
210
+ table.disable === true ||
211
+ !isConditionalArgIncluded(annotation ?? {}, args, globals)
212
+ ) {
207
213
  return null;
208
214
  }
209
215
 
@@ -18,6 +18,48 @@ type GroupProps = Pick<NavigatorProps, "selectedId" | "onSelect"> & {
18
18
  entries: StoryEntry[];
19
19
  };
20
20
 
21
+ type Group = {
22
+ title: string;
23
+ entries: StoryEntry[];
24
+ path: number[];
25
+ };
26
+
27
+ const TITLE_SEPARATOR = "/";
28
+
29
+ const titlePrefixes = (title: string): string[] =>
30
+ title.split(TITLE_SEPARATOR).map((_, index, segments) => segments.slice(0, index + 1).join(TITLE_SEPARATOR));
31
+
32
+ const compareIndexPaths = (left: number[], right: number[]): number => {
33
+ for (const [index, value] of left.entries()) {
34
+ const other = right[index];
35
+
36
+ if (other === undefined) {
37
+ return 1;
38
+ }
39
+
40
+ if (value !== other) {
41
+ return value - other;
42
+ }
43
+ }
44
+
45
+ return left.length - right.length;
46
+ };
47
+
48
+ /**
49
+ * Groups stories by title, keeping titles that share a path prefix together as Storybook's sidebar nests
50
+ * them: the first title under each prefix decides where the prefix appears.
51
+ */
52
+ const groupStoriesByTitle = (stories: StoryEntry[]): Group[] => {
53
+ const firstOccurrence: Map<string, number> = new Map();
54
+ const groups = [...Map.groupBy(stories, (entry) => entry.title)].map(([title, entries], order) => ({
55
+ title,
56
+ entries,
57
+ path: titlePrefixes(title).map((prefix) => firstOccurrence.getOrInsert(prefix, order)),
58
+ }));
59
+
60
+ return groups.toSorted((left, right) => compareIndexPaths(left.path, right.path));
61
+ };
62
+
21
63
  const StoryGroup = ({ title, entries, selectedId, onSelect }: GroupProps): ReactNode => (
22
64
  <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={6}>
23
65
  <GtkLabel label={title} xalign={0} marginStart={18} marginEnd={18} cssClasses={["heading"]} wrap />
@@ -68,9 +110,8 @@ const LoadErrors = ({ errors }: Pick<NavigatorProps, "errors">): ReactNode =>
68
110
  const StoryNavigator = ({ stories, errors, selectedId, onSelect }: NavigatorProps): ReactNode => {
69
111
  const [search, setSearch] = useState("");
70
112
  const query = search.trim().toLocaleLowerCase();
71
- const groups = Map.groupBy(
113
+ const groups = groupStoriesByTitle(
72
114
  stories.filter((entry) => `${entry.title} ${entry.name}`.toLocaleLowerCase().includes(query)),
73
- (entry) => entry.title,
74
115
  );
75
116
 
76
117
  return (
@@ -87,7 +128,7 @@ const StoryNavigator = ({ stories, errors, selectedId, onSelect }: NavigatorProp
87
128
  />
88
129
  <GtkScrolledWindow hscrollbarPolicy={Gtk.PolicyType.NEVER} vexpand>
89
130
  <GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={18} marginBottom={18}>
90
- {[...groups].map(([title, entries]) => (
131
+ {groups.map(({ title, entries }) => (
91
132
  <StoryGroup
92
133
  key={title}
93
134
  title={title}
@@ -96,7 +137,7 @@ const StoryNavigator = ({ stories, errors, selectedId, onSelect }: NavigatorProp
96
137
  onSelect={onSelect}
97
138
  />
98
139
  ))}
99
- {groups.size === 0 && (
140
+ {groups.length === 0 && (
100
141
  <AdwStatusPage
101
142
  name="storybook-no-matches"
102
143
  title={query ? "No matching stories" : "No stories"}
@@ -7,10 +7,11 @@ import { createPortal, rootElement } from "@gtkx/react";
7
7
  import { normalizeError } from "@gtkx/utils";
8
8
  import { Component, useCallback, useMemo, useState } from "react";
9
9
  import type { StoryEntry } from "./catalog.js";
10
- import type { Args, ComposedStory } from "./types.js";
10
+ import type { Args, ArgTypes, ComposedStory } from "./types.js";
11
11
  import { ActionsPanel } from "./actions-panel.js";
12
12
  import { ActionStore, bindActions } from "./actions.js";
13
13
  import { Controls } from "./controls.js";
14
+ import { isConditionalArgIncluded } from "./upstream.js";
14
15
 
15
16
  type PreviewProps = {
16
17
  entry: StoryEntry;
@@ -66,6 +67,36 @@ const previewMode = (story: ComposedStory): "content" | "window" | "dialog" => {
66
67
  return mode;
67
68
  };
68
69
 
70
+ const mapValue = (value: unknown, mapping: Record<string, unknown>): unknown => {
71
+ const key = String(value);
72
+
73
+ return Object.hasOwn(mapping, key) ? mapping[key] : value;
74
+ };
75
+
76
+ const mapArgs = (args: Args, argTypes: ArgTypes): Args =>
77
+ Object.fromEntries(
78
+ Object.entries(args).map(([argument, value]) => {
79
+ const mapping = argTypes[argument]?.mapping;
80
+
81
+ if (mapping === undefined) {
82
+ return [argument, value];
83
+ }
84
+
85
+ return [
86
+ argument,
87
+ Array.isArray(value) ? value.map((item) => mapValue(item, mapping)) : mapValue(value, mapping),
88
+ ];
89
+ }),
90
+ );
91
+
92
+ const includedArgs = (args: Args, argTypes: ArgTypes, globals: Args): Args =>
93
+ Object.fromEntries(
94
+ Object.entries(args).map(([argument, value]) => [
95
+ argument,
96
+ isConditionalArgIncluded(argTypes[argument] ?? {}, args, globals) ? value : undefined,
97
+ ]),
98
+ );
99
+
69
100
  const PreviewContent = ({ story: Story, args }: { story: ComposedStory; args: Args }): ReactNode => {
70
101
  const mode = previewMode(Story);
71
102
 
@@ -86,20 +117,20 @@ const PreviewContent = ({ story: Story, args }: { story: ComposedStory; args: Ar
86
117
  const align = Story.parameters.layout === "centered" ? Gtk.Align.CENTER : Gtk.Align.FILL;
87
118
 
88
119
  return (
89
- <GtkBox
90
- name="storybook-canvas"
91
- orientation={Gtk.Orientation.VERTICAL}
92
- hexpand
93
- vexpand
94
- halign={align}
95
- valign={align}
96
- marginTop={margin}
97
- marginBottom={margin}
98
- marginStart={margin}
99
- marginEnd={margin}
100
- >
101
- <Story {...args} />
102
- </GtkBox>
120
+ <GtkScrolledWindow hexpand vexpand propagateNaturalWidth propagateNaturalHeight>
121
+ <GtkBox
122
+ name="storybook-canvas"
123
+ orientation={Gtk.Orientation.VERTICAL}
124
+ halign={align}
125
+ valign={align}
126
+ marginTop={margin}
127
+ marginBottom={margin}
128
+ marginStart={margin}
129
+ marginEnd={margin}
130
+ >
131
+ <Story {...args} />
132
+ </GtkBox>
133
+ </GtkScrolledWindow>
103
134
  );
104
135
  };
105
136
 
@@ -122,8 +153,13 @@ const usePreviewState = ({ entry }: PreviewProps) => {
122
153
  [state.story, state.generation],
123
154
  );
124
155
  const boundArgs = useMemo(
125
- () => bindActions(state.args, state.story.argTypes, state.actions, onError),
126
- [state.args, state.story.argTypes, state.actions, onError],
156
+ () =>
157
+ includedArgs(
158
+ bindActions(mapArgs(state.args, state.story.argTypes), state.story.argTypes, state.actions, onError),
159
+ state.story.argTypes,
160
+ state.story.globals,
161
+ ),
162
+ [state.args, state.story.argTypes, state.story.globals, state.actions, onError],
127
163
  );
128
164
 
129
165
  if (state.story !== entry.story) {
@@ -165,7 +201,7 @@ const StoryInspector = ({ entry, actions, args, onChange }: InspectorProps): Rea
165
201
  marginStart={12}
166
202
  marginEnd={12}
167
203
  >
168
- <Controls argTypes={entry.controls} args={args} onChange={onChange} />
204
+ <Controls argTypes={entry.controls} args={args} globals={entry.story.globals} onChange={onChange} />
169
205
  <ActionsPanel store={actions} />
170
206
  </GtkBox>
171
207
  </GtkScrolledWindow>
@@ -178,7 +214,7 @@ const StorybookPreview = ({ entry }: PreviewProps): ReactNode => {
178
214
  <AdwToolbarView
179
215
  hexpand
180
216
  vexpand
181
- topBar={
217
+ top={
182
218
  <AdwHeaderBar
183
219
  titleWidget={<AdwWindowTitle title={entry.name} subtitle={entry.title} />}
184
220
  end={<GtkButton label="Reset story" onClicked={reset} />}