@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.
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +4 -1
- package/dist/catalog.js.map +1 -1
- package/dist/config.d.ts +4 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/controls.d.ts +2 -1
- package/dist/controls.d.ts.map +1 -1
- package/dist/controls.js +9 -5
- package/dist/controls.js.map +1 -1
- package/dist/explorer-navigator.d.ts.map +1 -1
- package/dist/explorer-navigator.js +29 -2
- package/dist/explorer-navigator.js.map +1 -1
- package/dist/explorer-preview.d.ts.map +1 -1
- package/dist/explorer-preview.js +23 -4
- package/dist/explorer-preview.js.map +1 -1
- package/dist/explorer-view.d.ts +5 -1
- package/dist/explorer-view.d.ts.map +1 -1
- package/dist/explorer-view.js +17 -7
- package/dist/explorer-view.js.map +1 -1
- package/dist/explorer.d.ts +4 -0
- package/dist/explorer.d.ts.map +1 -1
- package/dist/explorer.js +6 -1
- package/dist/explorer.js.map +1 -1
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/upstream.d.ts +4 -2
- package/dist/upstream.d.ts.map +1 -1
- package/dist/upstream.js +3 -1
- package/dist/upstream.js.map +1 -1
- package/package.json +9 -9
- package/src/catalog.ts +13 -10
- package/src/config.ts +4 -1
- package/src/controls.tsx +12 -6
- package/src/explorer-navigator.tsx +45 -4
- package/src/explorer-preview.tsx +55 -19
- package/src/explorer-view.tsx +40 -11
- package/src/explorer.ts +12 -1
- package/src/types.ts +19 -7
- package/src/upstream.ts +6 -2
package/dist/catalog.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ type StoryLoadError = {
|
|
|
34
34
|
};
|
|
35
35
|
/** Current explorer contents and loading state exposed to subscribers. */
|
|
36
36
|
type StoryCatalogSnapshot = {
|
|
37
|
-
/** Successfully composed stories with duplicate identifiers excluded. */
|
|
37
|
+
/** Successfully composed stories tagged `dev`, with duplicate identifiers excluded. */
|
|
38
38
|
stories: StoryEntry[];
|
|
39
39
|
/** Failures encountered during the latest load or reported by the session. */
|
|
40
40
|
errors: StoryLoadError[];
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,uFAAuF;IACvF,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,8EAA8E;IAC9E,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAgJF,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
|
@@ -2,6 +2,7 @@ import { normalizeError } from "@gtkx/utils";
|
|
|
2
2
|
import { composeStories } from "./compose.js";
|
|
3
3
|
import { storyNameFromExport } from "./upstream.js";
|
|
4
4
|
const EMPTY_PREVIEW = {};
|
|
5
|
+
const DEVELOPMENT_TAG = "dev";
|
|
5
6
|
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
7
|
const explicitControls = (resolved, story, meta, preview) => {
|
|
7
8
|
const controls = {};
|
|
@@ -39,7 +40,9 @@ const composeSource = (source, module, preview) => {
|
|
|
39
40
|
default: { ...module.default, title },
|
|
40
41
|
};
|
|
41
42
|
const stories = composeStories(annotations, preview);
|
|
42
|
-
return Object.entries(stories)
|
|
43
|
+
return Object.entries(stories)
|
|
44
|
+
.filter(([, story]) => story.tags.includes(DEVELOPMENT_TAG))
|
|
45
|
+
.map(([exportName, story]) => ({
|
|
43
46
|
id: story.id,
|
|
44
47
|
title,
|
|
45
48
|
name: displayName(annotations[exportName], exportName),
|
package/dist/catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAyDpD,MAAM,aAAa,GAAY,EAAE,CAAC;AAElC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAClE,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEzE,MAAM,gBAAgB,GAAG,CACrB,QAAkB,EAClB,KAAyC,EACzC,IAAyB,EACzB,OAAgB,EACR,EAAE;IACV,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GACT,KAAK,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO;YACpC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO;YAClC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAE1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,SAAS;QACb,CAAC;QAED,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;IAC3G,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,KAAyC,EAAE,UAAkB,EAAU,EAAE;IAC1F,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC;IAEzB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAE,MAAe,EAAE,OAAgB,EAAgB,EAAE;IAC3F,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,uCAAuC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC;IAEnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,SAAS,CAAC,6BAA6B,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,WAAW,GAAG;QAChB,GAAG,MAAM;QACT,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE;KACqC,CAAC;IAC/E,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAErD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,KAAK;QACL,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;QACtD,UAAU;QACV,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,KAAK;QACL,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC;KACpG,CAAC,CAAC,CAAC;AACR,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,OAAqB,EAAE,MAAwB,EAAgB,EAAE;IAC1F,MAAM,MAAM,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE9C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,uBAAuB,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAE3F,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,MAAsB,EAAE,EAAE;IAC9C,MAAM,KAAK,GAA+B,IAAI,GAAG,EAAE,CAAC;IACpD,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;AAC5E,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,GAA+B,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;AAEtE,MAAM,UAAU,GAAG,KAAK,EACpB,MAAmB,EACnB,OAAgB,EAChB,QAA0C,EACrB,EAAE;IACvB,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GACR,QAAQ,KAAK,SAAS;YACtB,QAAQ,CAAC,MAAM,KAAK,MAAM;YAC1B,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK;YAC/B,QAAQ,CAAC,OAAO,KAAK,OAAO;YACxB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QAEpG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/D,CAAC;AACL,CAAC,CAAC;AAEF,uEAAuE;AACvE,MAAM,YAAY;IACN,QAAQ,GAAyB,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACtE,SAAS,GAAoB,IAAI,GAAG,EAAE,CAAC;IACvC,YAAY,GAAmB,IAAI,OAAO,EAAE,CAAC;IACtD,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAC5B,YAAY,CAA6B;IACzC,QAAQ,GAAG,CAAC,CAAC;IAErB,kFAAkF;IAClF,WAAW,GAAG,GAAyB,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;IAExD,iFAAiF;IACjF,SAAS,GAAG,CAAC,QAAoB,EAAgB,EAAE;QAC/C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE7B,OAAO,GAAG,EAAE;YACR,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC,CAAC;IACN,CAAC,CAAC;IAEM,OAAO,CAAC,QAA8B;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,QAAQ,EAAE,CAAC;QACf,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,OAAsB,EAAE,OAAO,GAAY,aAAa;QAC/D,MAAM,QAAQ,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEzG,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAEpD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,IAAI,cAAc,CAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAChC,kCAAkC,CACrC,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/B,MAAM,OAAO,CAAC;QAClB,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,KAAc;QACtB,IAAI,KAAK,YAAY,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,CAAC,CAAC;QACnF,IAAI,CAAC,YAAY,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC;YACT,GAAG,IAAI,CAAC,QAAQ;YAChB,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC;SACzC,CAAC,CAAC;IACP,CAAC;CACJ;AAED,OAAO,EAAE,YAAY,EAAE,CAAC","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
|
+
{"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 tagged `dev`, 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 = {};\nconst DEVELOPMENT_TAG = \"dev\";\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)\n .filter(([, story]) => story.tags.includes(DEVELOPMENT_TAG))\n .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"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/** Story discovery and preview configuration for the native explorer. */
|
|
2
2
|
type StorybookConfig = {
|
|
3
|
-
/**
|
|
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/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,KAAK,eAAe,GAAG;IACnB
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,KAAK,eAAe,GAAG;IACnB;;;OAGG;IACH,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"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,yFAAyF;AACzF,MAAM,YAAY,GAAG,CAAC,MAAuB,EAAmB,EAAE,CAAC,MAAM,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAwB,CAAC","sourcesContent":["/** Story discovery and preview configuration for the native explorer. */\ntype StorybookConfig = {\n /**\n * Project-relative globs; defaults to CSF story files under src. A glob may reach a sibling workspace\n * package through `..` segments when every file it matches lies inside the workspace root.\n */\n stories?: string[];\n /** Additional project-relative globs excluded from discovery. */\n exclude?: string[];\n /** Project-relative preview module; defaults to a discovered .storybook/preview file. */\n preview?: string;\n};\n\n/** Returns a typed explorer configuration without changing it or resolving its paths. */\nconst defineConfig = (config: StorybookConfig): StorybookConfig => config;\n\nexport { defineConfig, type StorybookConfig };\n"]}
|
package/dist/controls.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import type { Args, ArgTypes } from "./types.js";
|
|
|
3
3
|
type ControlsProps = {
|
|
4
4
|
argTypes: ArgTypes;
|
|
5
5
|
args: Args;
|
|
6
|
+
globals: Args;
|
|
6
7
|
onChange: (update: Args) => void;
|
|
7
8
|
};
|
|
8
|
-
declare const Controls: ({ argTypes, args, onChange }: ControlsProps) => ReactNode;
|
|
9
|
+
declare const Controls: ({ argTypes, args, globals, onChange }: ControlsProps) => ReactNode;
|
|
9
10
|
export { Controls };
|
|
10
11
|
//# sourceMappingURL=controls.d.ts.map
|
package/dist/controls.d.ts.map
CHANGED
|
@@ -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;
|
|
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;AAGjD,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK,IAAI,CAAA;CAAE,CAAC;AAgMzG,QAAA,MAAM,QAAQ,0CAA2C,aAAa,KAAG,SAiCxE,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/controls.js
CHANGED
|
@@ -3,13 +3,14 @@ import { ComboRow } from "@gtkx/components";
|
|
|
3
3
|
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
|
+
import { isConditionalArgIncluded } from "./upstream.js";
|
|
6
7
|
const NO_SELECTION_ID = "no-selection";
|
|
7
8
|
const NO_SELECTION_LABEL = "Choose option...";
|
|
8
9
|
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9
10
|
const isWithinBoundsOrAbsent = (value, min, max) => value === undefined || (typeof value === "number" && Number.isFinite(value) && value >= min && value <= max);
|
|
10
11
|
const controlTitle = (name, argument) => (typeof name === "string" ? name : argument);
|
|
11
|
-
const numberDigits = (
|
|
12
|
-
const [coefficient = "", exponent = "0"] = String(
|
|
12
|
+
const numberDigits = (value) => {
|
|
13
|
+
const [coefficient = "", exponent = "0"] = String(value).split("e", 2);
|
|
13
14
|
const fraction = coefficient.split(".", 2)[1]?.length ?? 0;
|
|
14
15
|
const digits = Math.max(0, fraction - Number(exponent));
|
|
15
16
|
return Math.min(20, digits);
|
|
@@ -31,7 +32,7 @@ const NumberControl = ({ argument, title, value, settings, isDisabled, onChange,
|
|
|
31
32
|
return _jsx(UnsupportedControl, { title: title, description: "Provide a finite number and valid bounds." });
|
|
32
33
|
}
|
|
33
34
|
const currentValue = typeof value === "number" ? value : Math.max(min, Math.min(0, max));
|
|
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) => {
|
|
35
|
+
return (_jsx(AdwSpinRow, { name: `storybook-control-${argument}`, title: markupEscapeText(title, -1), sensitive: !isDisabled, value: currentValue, digits: Math.max(numberDigits(step), numberDigits(currentValue)), 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) => {
|
|
35
36
|
if (!Object.is(next, value)) {
|
|
36
37
|
onChange({ [argument]: next });
|
|
37
38
|
}
|
|
@@ -99,10 +100,13 @@ const Control = (props) => {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
|
-
const Controls = ({ argTypes, args, onChange }) => (_jsx(AdwPreferencesGroup, { title: "Controls", children: Object.entries(argTypes).map(([argument, annotation]) => {
|
|
103
|
+
const Controls = ({ argTypes, args, globals, onChange }) => (_jsx(AdwPreferencesGroup, { title: "Controls", children: Object.entries(argTypes).map(([argument, annotation]) => {
|
|
103
104
|
const control = annotation?.control;
|
|
104
105
|
const table = isObject(annotation?.table) ? annotation.table : {};
|
|
105
|
-
if (control === undefined ||
|
|
106
|
+
if (control === undefined ||
|
|
107
|
+
control === false ||
|
|
108
|
+
table.disable === true ||
|
|
109
|
+
!isConditionalArgIncluded(annotation ?? {}, args, globals)) {
|
|
106
110
|
return null;
|
|
107
111
|
}
|
|
108
112
|
const settings = isObject(control) ? control : {};
|
package/dist/controls.js.map
CHANGED
|
@@ -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\" ||\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
|
+
{"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\";\nimport { isConditionalArgIncluded } from \"./upstream.js\";\n\ntype ControlsProps = { argTypes: ArgTypes; args: Args; globals: 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 = (value: number): number => {\n const [coefficient = \"\", exponent = \"0\"] = String(value).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={Math.max(numberDigits(step), numberDigits(currentValue))}\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, globals, 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 (\n control === undefined ||\n control === false ||\n table.disable === true ||\n !isConditionalArgIncluded(annotation ?? {}, args, globals)\n ) {\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;
|
|
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;AAgGF,QAAA,MAAM,cAAc,8CAA+C,cAAc,KAAG,SA2CnF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -4,6 +4,33 @@ import * as Gtk from "@gtkx/gi/gtk";
|
|
|
4
4
|
import { AdwActionRow, AdwStatusPage } from "@gtkx/jsx/adw";
|
|
5
5
|
import { GtkBox, GtkLabel, GtkListBox, GtkScrolledWindow, GtkSearchEntry } from "@gtkx/jsx/gtk";
|
|
6
6
|
import { useState } from "react";
|
|
7
|
+
const TITLE_SEPARATOR = "/";
|
|
8
|
+
const titlePrefixes = (title) => title.split(TITLE_SEPARATOR).map((_, index, segments) => segments.slice(0, index + 1).join(TITLE_SEPARATOR));
|
|
9
|
+
const compareIndexPaths = (left, right) => {
|
|
10
|
+
for (const [index, value] of left.entries()) {
|
|
11
|
+
const other = right[index];
|
|
12
|
+
if (other === undefined) {
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
if (value !== other) {
|
|
16
|
+
return value - other;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return left.length - right.length;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Groups stories by title, keeping titles that share a path prefix together as Storybook's sidebar nests
|
|
23
|
+
* them: the first title under each prefix decides where the prefix appears.
|
|
24
|
+
*/
|
|
25
|
+
const groupStoriesByTitle = (stories) => {
|
|
26
|
+
const firstOccurrence = new Map();
|
|
27
|
+
const groups = [...Map.groupBy(stories, (entry) => entry.title)].map(([title, entries], order) => ({
|
|
28
|
+
title,
|
|
29
|
+
entries,
|
|
30
|
+
path: titlePrefixes(title).map((prefix) => firstOccurrence.getOrInsert(prefix, order)),
|
|
31
|
+
}));
|
|
32
|
+
return groups.toSorted((left, right) => compareIndexPaths(left.path, right.path));
|
|
33
|
+
};
|
|
7
34
|
const StoryGroup = ({ title, entries, selectedId, onSelect }) => (_jsxs(GtkBox, { orientation: Gtk.Orientation.VERTICAL, spacing: 6, children: [_jsx(GtkLabel, { label: title, xalign: 0, marginStart: 18, marginEnd: 18, cssClasses: ["heading"], wrap: true }), _jsx(GtkListBox, { cssClasses: ["navigation-sidebar"], selectedIndex: entries.findIndex((entry) => entry.id === selectedId), onRowSelected: (row) => {
|
|
8
35
|
const entry = row === null ? undefined : entries[row.getIndex()];
|
|
9
36
|
if (entry) {
|
|
@@ -16,10 +43,10 @@ const LoadErrors = ({ errors }) => errors.length > 0 && (_jsx(GtkBox, { name: "s
|
|
|
16
43
|
const StoryNavigator = ({ stories, errors, selectedId, onSelect }) => {
|
|
17
44
|
const [search, setSearch] = useState("");
|
|
18
45
|
const query = search.trim().toLocaleLowerCase();
|
|
19
|
-
const groups =
|
|
46
|
+
const groups = groupStoriesByTitle(stories.filter((entry) => `${entry.title} ${entry.name}`.toLocaleLowerCase().includes(query)));
|
|
20
47
|
return (_jsxs(GtkBox, { orientation: Gtk.Orientation.VERTICAL, spacing: 12, children: [_jsx(GtkSearchEntry, { name: "storybook-search", placeholderText: "Search stories", text: search, marginStart: 12, marginEnd: 12, onChanged: (entry) => {
|
|
21
48
|
setSearch(entry.getText());
|
|
22
|
-
} }), _jsx(GtkScrolledWindow, { hscrollbarPolicy: Gtk.PolicyType.NEVER, vexpand: true, children: _jsxs(GtkBox, { orientation: Gtk.Orientation.VERTICAL, spacing: 18, marginBottom: 18, children: [
|
|
49
|
+
} }), _jsx(GtkScrolledWindow, { hscrollbarPolicy: Gtk.PolicyType.NEVER, vexpand: true, children: _jsxs(GtkBox, { orientation: Gtk.Orientation.VERTICAL, spacing: 18, marginBottom: 18, children: [groups.map(({ title, entries }) => (_jsx(StoryGroup, { title: title, entries: entries, selectedId: selectedId, onSelect: onSelect }, title))), groups.length === 0 && (_jsx(AdwStatusPage, { name: "storybook-no-matches", title: query ? "No matching stories" : "No stories", iconName: "system-search-symbolic", cssClasses: ["compact"] })), _jsx(LoadErrors, { errors: errors })] }) })] }));
|
|
23
50
|
};
|
|
24
51
|
export { StoryNavigator };
|
|
25
52
|
//# sourceMappingURL=explorer-navigator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-navigator.js","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAejC,MAAM,UAAU,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAc,EAAa,EAAE,CAAC,CACpF,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,aACrD,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,IAAI,SAAG,EACnG,KAAC,UAAU,IACP,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAClC,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,EACpE,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEjE,IAAI,KAAK,EAAE,CAAC;oBACR,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC,YAEA,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACpB,KAAC,YAAY,IAET,IAAI,EAAE,mBAAmB,KAAK,CAAC,EAAE,EAAE,EACnC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EACvC,WAAW,QACX,WAAW,EAAE,GAAG,EAAE;oBACd,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvB,CAAC,IANI,KAAK,CAAC,EAAE,CAOf,CACL,CAAC,GACO,IACR,CACZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,EAAkC,EAAa,EAAE,CACzE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CACjB,KAAC,MAAM,IAAC,IAAI,EAAC,uBAAuB,EAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,YACjF,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CACtC,KAAC,QAAQ,IAEL,KAAK,EAAE,GAAG,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAClD,UAAU,EAAE,CAAC,OAAO,CAAC,EACrB,WAAW,EAAE,EAAE,EACf,SAAS,EAAE,EAAE,EACb,IAAI,QACJ,UAAU,QACV,MAAM,EAAE,CAAC,IAPJ,GAAG,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAQnC,CACL,CAAC,GACG,CACZ,CAAC;AAEN,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAkB,EAAa,EAAE;IAC5F,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CACtB,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAC7F,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CACzB,CAAC;IAEF,OAAO,CACH,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,aACtD,KAAC,cAAc,IACX,IAAI,EAAC,kBAAkB,EACvB,eAAe,EAAC,gBAAgB,EAChC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,EAAE,EACf,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/B,CAAC,GACH,EACF,KAAC,iBAAiB,IAAC,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,kBAC9D,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,aACvE,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CACnC,KAAC,UAAU,IAEP,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,IAJb,KAAK,CAKZ,CACL,CAAC,EACD,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAClB,KAAC,aAAa,IACV,IAAI,EAAC,sBAAsB,EAC3B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,YAAY,EACnD,QAAQ,EAAC,wBAAwB,EACjC,UAAU,EAAE,CAAC,SAAS,CAAC,GACzB,CACL,EACD,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,GAAI,IACzB,GACO,IACf,CACZ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC","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
|
+
{"version":3,"file":"explorer-navigator.js","sourceRoot":"","sources":["../src/explorer-navigator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAqBjC,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,MAAM,aAAa,GAAG,CAAC,KAAa,EAAY,EAAE,CAC9C,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;AAEjH,MAAM,iBAAiB,GAAG,CAAC,IAAc,EAAE,KAAe,EAAU,EAAE;IAClE,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAE3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC,CAAC;QACb,CAAC;QAED,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;YAClB,OAAO,KAAK,GAAG,KAAK,CAAC;QACzB,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;AACtC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,mBAAmB,GAAG,CAAC,OAAqB,EAAW,EAAE;IAC3D,MAAM,eAAe,GAAwB,IAAI,GAAG,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/F,KAAK;QACL,OAAO;QACP,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;KACzF,CAAC,CAAC,CAAC;IAEJ,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAc,EAAa,EAAE,CAAC,CACpF,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,aACrD,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,IAAI,SAAG,EACnG,KAAC,UAAU,IACP,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAClC,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,EACpE,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEjE,IAAI,KAAK,EAAE,CAAC;oBACR,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC,YAEA,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACpB,KAAC,YAAY,IAET,IAAI,EAAE,mBAAmB,KAAK,CAAC,EAAE,EAAE,EACnC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EACvC,WAAW,QACX,WAAW,EAAE,GAAG,EAAE;oBACd,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvB,CAAC,IANI,KAAK,CAAC,EAAE,CAOf,CACL,CAAC,GACO,IACR,CACZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,EAAkC,EAAa,EAAE,CACzE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CACjB,KAAC,MAAM,IAAC,IAAI,EAAC,uBAAuB,EAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,YACjF,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CACtC,KAAC,QAAQ,IAEL,KAAK,EAAE,GAAG,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAClD,UAAU,EAAE,CAAC,OAAO,CAAC,EACrB,WAAW,EAAE,EAAE,EACf,SAAS,EAAE,EAAE,EACb,IAAI,QACJ,UAAU,QACV,MAAM,EAAE,CAAC,IAPJ,GAAG,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAQnC,CACL,CAAC,GACG,CACZ,CAAC;AAEN,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAkB,EAAa,EAAE;IAC5F,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,mBAAmB,CAC9B,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAChG,CAAC;IAEF,OAAO,CACH,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,aACtD,KAAC,cAAc,IACX,IAAI,EAAC,kBAAkB,EACvB,eAAe,EAAC,gBAAgB,EAChC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,EAAE,EACf,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/B,CAAC,GACH,EACF,KAAC,iBAAiB,IAAC,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,kBAC9D,MAAC,MAAM,IAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,aACvE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAChC,KAAC,UAAU,IAEP,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,IAJb,KAAK,CAKZ,CACL,CAAC,EACD,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CACpB,KAAC,aAAa,IACV,IAAI,EAAC,sBAAsB,EAC3B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,YAAY,EACnD,QAAQ,EAAC,wBAAwB,EACjC,UAAU,EAAE,CAAC,SAAS,CAAC,GACzB,CACL,EACD,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,GAAI,IACzB,GACO,IACf,CACZ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC","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\ntype Group = {\n title: string;\n entries: StoryEntry[];\n path: number[];\n};\n\nconst TITLE_SEPARATOR = \"/\";\n\nconst titlePrefixes = (title: string): string[] =>\n title.split(TITLE_SEPARATOR).map((_, index, segments) => segments.slice(0, index + 1).join(TITLE_SEPARATOR));\n\nconst compareIndexPaths = (left: number[], right: number[]): number => {\n for (const [index, value] of left.entries()) {\n const other = right[index];\n\n if (other === undefined) {\n return 1;\n }\n\n if (value !== other) {\n return value - other;\n }\n }\n\n return left.length - right.length;\n};\n\n/**\n * Groups stories by title, keeping titles that share a path prefix together as Storybook's sidebar nests\n * them: the first title under each prefix decides where the prefix appears.\n */\nconst groupStoriesByTitle = (stories: StoryEntry[]): Group[] => {\n const firstOccurrence: Map<string, number> = new Map();\n const groups = [...Map.groupBy(stories, (entry) => entry.title)].map(([title, entries], order) => ({\n title,\n entries,\n path: titlePrefixes(title).map((prefix) => firstOccurrence.getOrInsert(prefix, order)),\n }));\n\n return groups.toSorted((left, right) => compareIndexPaths(left.path, right.path));\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 = groupStoriesByTitle(\n stories.filter((entry) => `${entry.title} ${entry.name}`.toLocaleLowerCase().includes(query)),\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.length === 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;AAQvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,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;AAO/C,KAAK,YAAY,GAAG;IAChB,KAAK,EAAE,UAAU,CAAC;CACrB,CAAC;AAgMF,QAAA,MAAM,gBAAgB,cAAe,YAAY,KAAG,SAoCnD,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/explorer-preview.js
CHANGED
|
@@ -9,6 +9,7 @@ import { Component, useCallback, useMemo, useState } from "react";
|
|
|
9
9
|
import { ActionsPanel } from "./actions-panel.js";
|
|
10
10
|
import { ActionStore, bindActions } from "./actions.js";
|
|
11
11
|
import { Controls } from "./controls.js";
|
|
12
|
+
import { isConditionalArgIncluded } from "./upstream.js";
|
|
12
13
|
class PreviewBoundary extends Component {
|
|
13
14
|
static getDerivedStateFromProps(props, state) {
|
|
14
15
|
return props.args === state.args ? null : { error: null, args: props.args };
|
|
@@ -30,6 +31,24 @@ const previewMode = (story) => {
|
|
|
30
31
|
}
|
|
31
32
|
return mode;
|
|
32
33
|
};
|
|
34
|
+
const mapValue = (value, mapping) => {
|
|
35
|
+
const key = String(value);
|
|
36
|
+
return Object.hasOwn(mapping, key) ? mapping[key] : value;
|
|
37
|
+
};
|
|
38
|
+
const mapArgs = (args, argTypes) => Object.fromEntries(Object.entries(args).map(([argument, value]) => {
|
|
39
|
+
const mapping = argTypes[argument]?.mapping;
|
|
40
|
+
if (mapping === undefined) {
|
|
41
|
+
return [argument, value];
|
|
42
|
+
}
|
|
43
|
+
return [
|
|
44
|
+
argument,
|
|
45
|
+
Array.isArray(value) ? value.map((item) => mapValue(item, mapping)) : mapValue(value, mapping),
|
|
46
|
+
];
|
|
47
|
+
}));
|
|
48
|
+
const includedArgs = (args, argTypes, globals) => Object.fromEntries(Object.entries(args).map(([argument, value]) => [
|
|
49
|
+
argument,
|
|
50
|
+
isConditionalArgIncluded(argTypes[argument] ?? {}, args, globals) ? value : undefined,
|
|
51
|
+
]));
|
|
33
52
|
const PreviewContent = ({ story: Story, args }) => {
|
|
34
53
|
const mode = previewMode(Story);
|
|
35
54
|
if (mode !== "content") {
|
|
@@ -37,7 +56,7 @@ const PreviewContent = ({ story: Story, args }) => {
|
|
|
37
56
|
}
|
|
38
57
|
const margin = Story.parameters.layout === "fullscreen" ? 0 : 24;
|
|
39
58
|
const align = Story.parameters.layout === "centered" ? Gtk.Align.CENTER : Gtk.Align.FILL;
|
|
40
|
-
return (_jsx(GtkBox, { name: "storybook-canvas", orientation: Gtk.Orientation.VERTICAL,
|
|
59
|
+
return (_jsx(GtkScrolledWindow, { hexpand: true, vexpand: true, propagateNaturalWidth: true, propagateNaturalHeight: true, children: _jsx(GtkBox, { name: "storybook-canvas", orientation: Gtk.Orientation.VERTICAL, halign: align, valign: align, marginTop: margin, marginBottom: margin, marginStart: margin, marginEnd: margin, children: _jsx(Story, { ...args }) }) }));
|
|
41
60
|
};
|
|
42
61
|
const usePreviewState = ({ entry }) => {
|
|
43
62
|
const [state, setState] = useState(() => ({
|
|
@@ -52,7 +71,7 @@ const usePreviewState = ({ entry }) => {
|
|
|
52
71
|
? { ...current, error }
|
|
53
72
|
: current);
|
|
54
73
|
}, [state.story, state.generation]);
|
|
55
|
-
const boundArgs = useMemo(() => bindActions(state.args, state.story.argTypes, state.actions, onError), [state.args, state.story.argTypes, state.actions, onError]);
|
|
74
|
+
const boundArgs = useMemo(() => includedArgs(bindActions(mapArgs(state.args, state.story.argTypes), state.story.argTypes, state.actions, onError), state.story.argTypes, state.story.globals), [state.args, state.story.argTypes, state.story.globals, state.actions, onError]);
|
|
56
75
|
if (state.story !== entry.story) {
|
|
57
76
|
setState({
|
|
58
77
|
story: entry.story,
|
|
@@ -76,10 +95,10 @@ const usePreviewState = ({ entry }) => {
|
|
|
76
95
|
};
|
|
77
96
|
return { state, boundArgs, reset, onChange };
|
|
78
97
|
};
|
|
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 })] }) }));
|
|
98
|
+
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, globals: entry.story.globals, onChange: onChange }), _jsx(ActionsPanel, { store: actions })] }) }));
|
|
80
99
|
const StorybookPreview = ({ entry }) => {
|
|
81
100
|
const { state, boundArgs, reset, onChange } = usePreviewState({ entry });
|
|
82
|
-
return (_jsx(AdwToolbarView, { hexpand: true, vexpand: true,
|
|
101
|
+
return (_jsx(AdwToolbarView, { hexpand: true, vexpand: true, top: _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
102
|
"\n\nReset the preview or select another story to continue." })) }, state.generation) }), _jsx(StoryInspector, { entry: entry, actions: state.actions, args: state.args, onChange: onChange })] }) }));
|
|
84
103
|
};
|
|
85
104
|
export { StorybookPreview };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-preview.js","sourceRoot":"","sources":["../src/explorer-preview.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 { AdwHeaderBar, AdwStatusPage, AdwToolbarView, AdwWindowTitle } from \"@gtkx/jsx/adw\";\nimport { GtkBox, GtkButton, GtkScrolledWindow } from \"@gtkx/jsx/gtk\";\nimport { createPortal, rootElement } from \"@gtkx/react\";\nimport { normalizeError } from \"@gtkx/utils\";\nimport { Component, useCallback, useMemo, useState } from \"react\";\nimport type { StoryEntry } from \"./catalog.js\";\nimport type { Args, ComposedStory } from \"./types.js\";\nimport { ActionsPanel } from \"./actions-panel.js\";\nimport { ActionStore, bindActions } from \"./actions.js\";\nimport { Controls } from \"./controls.js\";\n\ntype PreviewProps = {\n entry: StoryEntry;\n};\n\ntype PreviewState = {\n story: ComposedStory;\n args: Args;\n generation: number;\n error: Error | null;\n actions: ActionStore;\n};\n\ntype BoundaryProps = { children: ReactNode; args: Args };\ntype BoundaryState = { error: Error | null; args: Args };\n\nclass PreviewBoundary extends Component<BoundaryProps, BoundaryState> {\n static getDerivedStateFromProps(props: BoundaryProps, state: BoundaryState): BoundaryState | null {\n return props.args === state.args ? null : { error: null, args: props.args };\n }\n\n static getDerivedStateFromError(error: unknown): Pick<BoundaryState, \"error\"> {\n return { error: normalizeError(error) };\n }\n\n override state: BoundaryState = { error: null, args: this.props.args };\n\n override render(): ReactNode {\n return this.state.error === null ? (\n this.props.children\n ) : (\n <AdwStatusPage\n name=\"storybook-preview-error\"\n title=\"Preview failed\"\n iconName=\"dialog-error-symbolic\"\n description={\n markupEscapeText(this.state.error.message.slice(0, 500), -1) +\n \"\\n\\nAdjust controls, reset the preview, or select another story to continue.\"\n }\n />\n );\n }\n}\n\nconst previewMode = (story: ComposedStory): \"content\" | \"window\" | \"dialog\" => {\n const gtkx = story.parameters.gtkx;\n const mode = typeof gtkx === \"object\" && gtkx !== null && \"preview\" in gtkx ? gtkx.preview : \"content\";\n\n if (mode !== \"content\" && mode !== \"window\" && mode !== \"dialog\") {\n throw new Error(\"Unsupported GTKX story preview mode\");\n }\n\n return mode;\n};\n\nconst PreviewContent = ({ story: Story, args }: { story: ComposedStory; args: Args }): ReactNode => {\n const mode = previewMode(Story);\n\n if (mode !== \"content\") {\n return (\n <>\n <AdwStatusPage\n title={mode === \"window\" ? \"Window preview\" : \"Dialog preview\"}\n iconName=\"window-new-symbolic\"\n description=\"The story owns its presentation. Reset to open it again.\"\n />\n {createPortal(<Story {...args} />, rootElement)}\n </>\n );\n }\n\n const margin = Story.parameters.layout === \"fullscreen\" ? 0 : 24;\n const align = Story.parameters.layout === \"centered\" ? Gtk.Align.CENTER : Gtk.Align.FILL;\n\n return (\n <GtkBox\n name=\"storybook-canvas\"\n orientation={Gtk.Orientation.VERTICAL}\n hexpand\n vexpand\n halign={align}\n valign={align}\n marginTop={margin}\n marginBottom={margin}\n marginStart={margin}\n marginEnd={margin}\n >\n <Story {...args} />\n </GtkBox>\n );\n};\n\nconst usePreviewState = ({ entry }: PreviewProps) => {\n const [state, setState] = useState<PreviewState>(() => ({\n story: entry.story,\n args: { ...entry.story.args },\n generation: 0,\n error: null,\n actions: new ActionStore(),\n }));\n const onError = useCallback(\n (error: Error) => {\n setState((current) =>\n current.story === state.story && current.generation === state.generation\n ? { ...current, error }\n : current,\n );\n },\n [state.story, state.generation],\n );\n const boundArgs = useMemo(\n () => bindActions(state.args, state.story.argTypes, state.actions, onError),\n [state.args, state.story.argTypes, state.actions, onError],\n );\n\n if (state.story !== entry.story) {\n setState({\n story: entry.story,\n args: { ...entry.story.args },\n generation: state.generation + 1,\n error: null,\n actions: new ActionStore(),\n });\n }\n\n const reset = (): void => {\n setState((current) => ({\n story: entry.story,\n args: { ...entry.story.args },\n generation: current.generation + 1,\n error: null,\n actions: new ActionStore(),\n }));\n };\n\n const onChange = (args: Args): void => {\n setState((current) => ({ ...current, args: { ...current.args, ...args } }));\n };\n\n return { state, boundArgs, reset, onChange };\n};\n\ntype InspectorProps = PreviewProps & { actions: ActionStore; args: Args; onChange: (args: Args) => void };\n\nconst StoryInspector = ({ entry, actions, args, onChange }: InspectorProps): ReactNode => (\n <GtkScrolledWindow name=\"storybook-inspector\" widthRequest={280} hscrollbarPolicy={Gtk.PolicyType.NEVER} vexpand>\n <GtkBox\n orientation={Gtk.Orientation.VERTICAL}\n spacing={24}\n marginTop={18}\n marginBottom={18}\n marginStart={12}\n marginEnd={12}\n >\n <Controls argTypes={entry.controls} args={args} onChange={onChange} />\n <ActionsPanel store={actions} />\n </GtkBox>\n </GtkScrolledWindow>\n);\n\nconst StorybookPreview = ({ entry }: PreviewProps): ReactNode => {\n const { state, boundArgs, reset, onChange } = usePreviewState({ entry });\n\n return (\n <AdwToolbarView\n hexpand\n vexpand\n topBar={\n <AdwHeaderBar\n titleWidget={<AdwWindowTitle title={entry.name} subtitle={entry.title} />}\n end={<GtkButton label=\"Reset story\" onClicked={reset} />}\n />\n }\n >\n <GtkBox>\n <GtkBox orientation={Gtk.Orientation.VERTICAL} hexpand vexpand>\n <PreviewBoundary key={state.generation} args={state.args}>\n {state.error === null ? (\n <PreviewContent story={entry.story} args={boundArgs} />\n ) : (\n <AdwStatusPage\n name=\"storybook-preview-error\"\n title=\"Story action failed\"\n iconName=\"dialog-error-symbolic\"\n description={\n markupEscapeText(state.error.message.slice(0, 500), -1) +\n \"\\n\\nReset the preview or select another story to continue.\"\n }\n />\n )}\n </PreviewBoundary>\n </GtkBox>\n <StoryInspector entry={entry} actions={state.actions} args={state.args} onChange={onChange} />\n </GtkBox>\n </AdwToolbarView>\n );\n};\n\nexport { StorybookPreview };\n"]}
|
|
1
|
+
{"version":3,"file":"explorer-preview.js","sourceRoot":"","sources":["../src/explorer-preview.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 { AdwHeaderBar, AdwStatusPage, AdwToolbarView, AdwWindowTitle } from \"@gtkx/jsx/adw\";\nimport { GtkBox, GtkButton, GtkScrolledWindow } from \"@gtkx/jsx/gtk\";\nimport { createPortal, rootElement } from \"@gtkx/react\";\nimport { normalizeError } from \"@gtkx/utils\";\nimport { Component, useCallback, useMemo, useState } from \"react\";\nimport type { StoryEntry } from \"./catalog.js\";\nimport type { Args, ArgTypes, ComposedStory } from \"./types.js\";\nimport { ActionsPanel } from \"./actions-panel.js\";\nimport { ActionStore, bindActions } from \"./actions.js\";\nimport { Controls } from \"./controls.js\";\nimport { isConditionalArgIncluded } from \"./upstream.js\";\n\ntype PreviewProps = {\n entry: StoryEntry;\n};\n\ntype PreviewState = {\n story: ComposedStory;\n args: Args;\n generation: number;\n error: Error | null;\n actions: ActionStore;\n};\n\ntype BoundaryProps = { children: ReactNode; args: Args };\ntype BoundaryState = { error: Error | null; args: Args };\n\nclass PreviewBoundary extends Component<BoundaryProps, BoundaryState> {\n static getDerivedStateFromProps(props: BoundaryProps, state: BoundaryState): BoundaryState | null {\n return props.args === state.args ? null : { error: null, args: props.args };\n }\n\n static getDerivedStateFromError(error: unknown): Pick<BoundaryState, \"error\"> {\n return { error: normalizeError(error) };\n }\n\n override state: BoundaryState = { error: null, args: this.props.args };\n\n override render(): ReactNode {\n return this.state.error === null ? (\n this.props.children\n ) : (\n <AdwStatusPage\n name=\"storybook-preview-error\"\n title=\"Preview failed\"\n iconName=\"dialog-error-symbolic\"\n description={\n markupEscapeText(this.state.error.message.slice(0, 500), -1) +\n \"\\n\\nAdjust controls, reset the preview, or select another story to continue.\"\n }\n />\n );\n }\n}\n\nconst previewMode = (story: ComposedStory): \"content\" | \"window\" | \"dialog\" => {\n const gtkx = story.parameters.gtkx;\n const mode = typeof gtkx === \"object\" && gtkx !== null && \"preview\" in gtkx ? gtkx.preview : \"content\";\n\n if (mode !== \"content\" && mode !== \"window\" && mode !== \"dialog\") {\n throw new Error(\"Unsupported GTKX story preview mode\");\n }\n\n return mode;\n};\n\nconst mapValue = (value: unknown, mapping: Record<string, unknown>): unknown => {\n const key = String(value);\n\n return Object.hasOwn(mapping, key) ? mapping[key] : value;\n};\n\nconst mapArgs = (args: Args, argTypes: ArgTypes): Args =>\n Object.fromEntries(\n Object.entries(args).map(([argument, value]) => {\n const mapping = argTypes[argument]?.mapping;\n\n if (mapping === undefined) {\n return [argument, value];\n }\n\n return [\n argument,\n Array.isArray(value) ? value.map((item) => mapValue(item, mapping)) : mapValue(value, mapping),\n ];\n }),\n );\n\nconst includedArgs = (args: Args, argTypes: ArgTypes, globals: Args): Args =>\n Object.fromEntries(\n Object.entries(args).map(([argument, value]) => [\n argument,\n isConditionalArgIncluded(argTypes[argument] ?? {}, args, globals) ? value : undefined,\n ]),\n );\n\nconst PreviewContent = ({ story: Story, args }: { story: ComposedStory; args: Args }): ReactNode => {\n const mode = previewMode(Story);\n\n if (mode !== \"content\") {\n return (\n <>\n <AdwStatusPage\n title={mode === \"window\" ? \"Window preview\" : \"Dialog preview\"}\n iconName=\"window-new-symbolic\"\n description=\"The story owns its presentation. Reset to open it again.\"\n />\n {createPortal(<Story {...args} />, rootElement)}\n </>\n );\n }\n\n const margin = Story.parameters.layout === \"fullscreen\" ? 0 : 24;\n const align = Story.parameters.layout === \"centered\" ? Gtk.Align.CENTER : Gtk.Align.FILL;\n\n return (\n <GtkScrolledWindow hexpand vexpand propagateNaturalWidth propagateNaturalHeight>\n <GtkBox\n name=\"storybook-canvas\"\n orientation={Gtk.Orientation.VERTICAL}\n halign={align}\n valign={align}\n marginTop={margin}\n marginBottom={margin}\n marginStart={margin}\n marginEnd={margin}\n >\n <Story {...args} />\n </GtkBox>\n </GtkScrolledWindow>\n );\n};\n\nconst usePreviewState = ({ entry }: PreviewProps) => {\n const [state, setState] = useState<PreviewState>(() => ({\n story: entry.story,\n args: { ...entry.story.args },\n generation: 0,\n error: null,\n actions: new ActionStore(),\n }));\n const onError = useCallback(\n (error: Error) => {\n setState((current) =>\n current.story === state.story && current.generation === state.generation\n ? { ...current, error }\n : current,\n );\n },\n [state.story, state.generation],\n );\n const boundArgs = useMemo(\n () =>\n includedArgs(\n bindActions(mapArgs(state.args, state.story.argTypes), state.story.argTypes, state.actions, onError),\n state.story.argTypes,\n state.story.globals,\n ),\n [state.args, state.story.argTypes, state.story.globals, state.actions, onError],\n );\n\n if (state.story !== entry.story) {\n setState({\n story: entry.story,\n args: { ...entry.story.args },\n generation: state.generation + 1,\n error: null,\n actions: new ActionStore(),\n });\n }\n\n const reset = (): void => {\n setState((current) => ({\n story: entry.story,\n args: { ...entry.story.args },\n generation: current.generation + 1,\n error: null,\n actions: new ActionStore(),\n }));\n };\n\n const onChange = (args: Args): void => {\n setState((current) => ({ ...current, args: { ...current.args, ...args } }));\n };\n\n return { state, boundArgs, reset, onChange };\n};\n\ntype InspectorProps = PreviewProps & { actions: ActionStore; args: Args; onChange: (args: Args) => void };\n\nconst StoryInspector = ({ entry, actions, args, onChange }: InspectorProps): ReactNode => (\n <GtkScrolledWindow name=\"storybook-inspector\" widthRequest={280} hscrollbarPolicy={Gtk.PolicyType.NEVER} vexpand>\n <GtkBox\n orientation={Gtk.Orientation.VERTICAL}\n spacing={24}\n marginTop={18}\n marginBottom={18}\n marginStart={12}\n marginEnd={12}\n >\n <Controls argTypes={entry.controls} args={args} globals={entry.story.globals} onChange={onChange} />\n <ActionsPanel store={actions} />\n </GtkBox>\n </GtkScrolledWindow>\n);\n\nconst StorybookPreview = ({ entry }: PreviewProps): ReactNode => {\n const { state, boundArgs, reset, onChange } = usePreviewState({ entry });\n\n return (\n <AdwToolbarView\n hexpand\n vexpand\n top={\n <AdwHeaderBar\n titleWidget={<AdwWindowTitle title={entry.name} subtitle={entry.title} />}\n end={<GtkButton label=\"Reset story\" onClicked={reset} />}\n />\n }\n >\n <GtkBox>\n <GtkBox orientation={Gtk.Orientation.VERTICAL} hexpand vexpand>\n <PreviewBoundary key={state.generation} args={state.args}>\n {state.error === null ? (\n <PreviewContent story={entry.story} args={boundArgs} />\n ) : (\n <AdwStatusPage\n name=\"storybook-preview-error\"\n title=\"Story action failed\"\n iconName=\"dialog-error-symbolic\"\n description={\n markupEscapeText(state.error.message.slice(0, 500), -1) +\n \"\\n\\nReset the preview or select another story to continue.\"\n }\n />\n )}\n </PreviewBoundary>\n </GtkBox>\n <StoryInspector entry={entry} actions={state.actions} args={state.args} onChange={onChange} />\n </GtkBox>\n </AdwToolbarView>\n );\n};\n\nexport { StorybookPreview };\n"]}
|
package/dist/explorer-view.d.ts
CHANGED
|
@@ -8,8 +8,12 @@ type StorybookProps = {
|
|
|
8
8
|
applicationId?: string;
|
|
9
9
|
/** Explorer window and sidebar title; defaults to GTKX Storybook. */
|
|
10
10
|
title?: string;
|
|
11
|
+
/** Story selected once the catalog lists it; the first story is selected otherwise. */
|
|
12
|
+
initialStoryId?: string | undefined;
|
|
13
|
+
/** Called with the identifier of each story the explorer selects. */
|
|
14
|
+
onStorySelected?: ((id: string) => void) | undefined;
|
|
11
15
|
};
|
|
12
16
|
/** Renders the Adwaita explorer application with navigation, story previews, controls, and actions. */
|
|
13
|
-
declare const Storybook: ({ catalog, applicationId, title, }: StorybookProps) => ReactNode;
|
|
17
|
+
declare const Storybook: ({ catalog, applicationId, title, initialStoryId, onStorySelected, }: StorybookProps) => ReactNode;
|
|
14
18
|
export { Storybook };
|
|
15
19
|
//# sourceMappingURL=explorer-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-view.d.ts","sourceRoot":"","sources":["../src/explorer-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,gEAAgE;AAChE,KAAK,cAAc,GAAG;IAClB,8EAA8E;IAC9E,OAAO,EAAE,YAAY,CAAC;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"explorer-view.d.ts","sourceRoot":"","sources":["../src/explorer-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,gEAAgE;AAChE,KAAK,cAAc,GAAG;IAClB,8EAA8E;IAC9E,OAAO,EAAE,YAAY,CAAC;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,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,CAAC;AAwEF,uGAAuG;AACvG,QAAA,MAAM,SAAS,wEAMZ,cAAc,KAAG,SAWnB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|