ember-storybook 0.1.6 → 0.2.1

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.
@@ -1,4 +1,16 @@
1
1
  import type { BlockInfo, BlockParam } from 'ember-docgen';
2
- /** Flatten the params union into plain block params, unwrapping yield hashes. */
2
+ /**
3
+ * Unwrap the params union to plain block params at the yield surface: a
4
+ * yield hash expands to its named entries, but unfolded named types
5
+ * (`nested`) are not descended into. Use for anything reflecting what the
6
+ * block actually receives (e.g. slot bindings).
7
+ */
8
+ export declare function unwrapBlockParamsShallow(params: BlockInfo['params']): BlockParam[];
9
+ /**
10
+ * Unwrap every block param: yield hashes expand to their named entries and
11
+ * unfolded named types descend into all members — the whole param tree. Use
12
+ * wherever every referenced component must be found (subcomponent
13
+ * collection, ref rewriting).
14
+ */
3
15
  export declare function unwrapBlockParams(params: BlockInfo['params']): BlockParam[];
4
16
  //# sourceMappingURL=block-params.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-params.d.ts","sourceRoot":"","sources":["../../../src/client/docs/block-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC;AAM1E,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,UAAU,EAAE,CAE3E"}
1
+ {"version":3,"file":"block-params.d.ts","sourceRoot":"","sources":["../../../src/client/docs/block-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC;AAM1E;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,UAAU,EAAE,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,UAAU,EAAE,CAkB3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../../src/client/docs/blocks/blocks.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAA8B,MAAM,cAAc,CAAC;AAE1E,eAAO,MAAM,SAAS;;;mGAInB,CAAC;AAOJ,eAAO,MAAM,QAAQ;;;yGAIlB,CAAC;AAsKJ,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,iBAAiB,EACjB,IAAI,EACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;2HAiCA;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,iBAAiB,EACjB,IAAI,EACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;sGAOA"}
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../../src/client/docs/blocks/blocks.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAA8B,MAAM,cAAc,CAAC;AAE1E,eAAO,MAAM,SAAS;;;mGAInB,CAAC;AAOJ,eAAO,MAAM,QAAQ;;;yGAIlB,CAAC;AA+NJ,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,iBAAiB,EACjB,IAAI,EACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;2HAiCA;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,iBAAiB,EACjB,IAAI,EACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;sGAOA"}
@@ -1 +1 @@
1
- {"version":3,"file":"subcomponents.d.ts","sourceRoot":"","sources":["../../../../src/client/docs/blocks/subcomponents.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAgDpD,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,IAAI,EACL,EAAE;IACD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;kHAmCA"}
1
+ {"version":3,"file":"subcomponents.d.ts","sourceRoot":"","sources":["../../../../src/client/docs/blocks/subcomponents.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAmDpD,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,IAAI,EACL,EAAE;IACD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;;;kHAmCA"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/client/docs/config.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,wBAAwB,EACxB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAuBlC,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAC/B,OAAO,EAAE,wBAAwB,CAAC,aAAa,CAAC,KAC7C,cAAc,CAAC,EAkCnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAQxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,EAAsB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/client/docs/config.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,wBAAwB,EACxB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAuBlC,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAC/B,OAAO,EAAE,wBAAwB,CAAC,aAAa,CAAC,KAC7C,cAAc,CAAC,EAoCnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAQxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,EAAsB,CAAC"}
@@ -1,3 +1,29 @@
1
1
  import type { ComponentSignature } from 'ember-docgen';
2
+ /**
3
+ * Returns a new argTypes object with entries sorted alphabetically by name,
4
+ * matching Storybook's `alpha` sort order. The input object is not mutated.
5
+ */
6
+ export declare function sortArgTypes(argTypes: Record<string, unknown>): Record<string, unknown>;
2
7
  export declare function buildArgTypes(sig: ComponentSignature): Record<string, unknown>;
8
+ /**
9
+ * Merges signature-derived argTypes with the story-provided argTypes.
10
+ *
11
+ * Signature argTypes are the base; story argTypes enhance them for better
12
+ * rendering (custom `name`, `control`, `options`, ...). For args present in
13
+ * both, story fields win — but only when they carry an actual value, so an
14
+ * explicit `undefined` never masks a signature field. The signature keeps the
15
+ * `table` and `description` the story does not override.
16
+ *
17
+ * The `type` object is deep-merged: a story-provided partial `type` (e.g.
18
+ * `type: 'string'`) keeps the signature's `required` flag unless the story
19
+ * explicitly sets it, while the story's `type.name` still wins.
20
+ */
21
+ export declare function mergeArgTypes(signatureArgTypes: Record<string, unknown>, storyArgTypes: Record<string, unknown>): Record<string, unknown>;
22
+ /**
23
+ * Whether the docs page should render the Args/controls table: either the
24
+ * component signature exposes args, or the meta carries story-provided
25
+ * argTypes (e.g. for a template-only component with story argTypes but no
26
+ * signature args).
27
+ */
28
+ export declare function shouldShowArgsSection(sig: ComponentSignature, metaArgTypes?: Record<string, unknown>): boolean;
3
29
  //# sourceMappingURL=extractArgTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractArgTypes.d.ts","sourceRoot":"","sources":["../../../src/client/docs/extractArgTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAoCpE,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoB9E"}
1
+ {"version":3,"file":"extractArgTypes.d.ts","sourceRoot":"","sources":["../../../src/client/docs/extractArgTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAoCpE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEvF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoB9E;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8BzB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,kBAAkB,EACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/docs/page.ts"],"names":[],"mappings":"AAiFA,MAAM,CAAC,OAAO,UAAU,IAAI,4EAiC3B"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/docs/page.ts"],"names":[],"mappings":"AAuFA,MAAM,CAAC,OAAO,UAAU,IAAI,4EAiC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../../src/client/docs/signature.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAcD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAC3D,IAAI,EAAE,SAAS,GACd,MAAM,GAAG,SAAS,CAgBpB;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,kBAAkB,EAC7B,SAAS,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GACjD,kBAAkB,CAsBpB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,IAAI,EAAE,SAAS,GACd,eAAe,EAAE,CA8CnB"}
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../../src/client/docs/signature.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAcD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAC3D,IAAI,EAAE,SAAS,GACd,MAAM,GAAG,SAAS,CAoBpB;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,kBAAkB,EAC7B,SAAS,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GACjD,kBAAkB,CAsBpB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,IAAI,EAAE,SAAS,GACd,eAAe,EAAE,CAiDnB"}
@@ -0,0 +1,32 @@
1
+ //#region src/client/docs/block-params.ts
2
+ function isBlockParam(param) {
3
+ return Object.hasOwn(param, "name") && Object.hasOwn(param, "type");
4
+ }
5
+ /**
6
+ * Unwrap the params union to plain block params at the yield surface: a
7
+ * yield hash expands to its named entries, but unfolded named types
8
+ * (`nested`) are not descended into. Use for anything reflecting what the
9
+ * block actually receives (e.g. slot bindings).
10
+ */
11
+ function unwrapBlockParamsShallow(params) {
12
+ return params.flatMap((param) => isBlockParam(param) ? [param] : Object.values(param));
13
+ }
14
+ /**
15
+ * Unwrap every block param: yield hashes expand to their named entries and
16
+ * unfolded named types descend into all members — the whole param tree. Use
17
+ * wherever every referenced component must be found (subcomponent
18
+ * collection, ref rewriting).
19
+ */
20
+ function unwrapBlockParams(params) {
21
+ const result = [];
22
+ for (const param of params) if (isBlockParam(param)) {
23
+ result.push(param);
24
+ const nested = param.nested;
25
+ if (nested && nested.length > 0) result.push(...unwrapBlockParams(nested));
26
+ } else result.push(...unwrapBlockParams(Object.values(param)));
27
+ return result;
28
+ }
29
+ //#endregion
30
+ export { unwrapBlockParamsShallow as n, unwrapBlockParams as t };
31
+
32
+ //# sourceMappingURL=block-params-wjiT2Ht6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-params-wjiT2Ht6.mjs","names":["isBlockParam","param","Object","hasOwn","unwrapBlockParamsShallow","params","flatMap","values","unwrapBlockParams","result","push","nested","length"],"sources":["../src/client/docs/block-params.ts"],"sourcesContent":["import type { BlockInfo, BlockParam, HashBlockParam } from 'ember-docgen';\n\nfunction isBlockParam(param: BlockParam | HashBlockParam): param is BlockParam {\n return Object.hasOwn(param, 'name') && Object.hasOwn(param, 'type');\n}\n\n/**\n * Unwrap the params union to plain block params at the yield surface: a\n * yield hash expands to its named entries, but unfolded named types\n * (`nested`) are not descended into. Use for anything reflecting what the\n * block actually receives (e.g. slot bindings).\n */\nexport function unwrapBlockParamsShallow(params: BlockInfo['params']): BlockParam[] {\n return params.flatMap((param) => (isBlockParam(param) ? [param] : Object.values(param)));\n}\n\n/**\n * Unwrap every block param: yield hashes expand to their named entries and\n * unfolded named types descend into all members — the whole param tree. Use\n * wherever every referenced component must be found (subcomponent\n * collection, ref rewriting).\n */\nexport function unwrapBlockParams(params: BlockInfo['params']): BlockParam[] {\n const result: BlockParam[] = [];\n\n for (const param of params) {\n if (isBlockParam(param)) {\n result.push(param);\n\n const nested = param.nested;\n\n if (nested && nested.length > 0) {\n result.push(...unwrapBlockParams(nested));\n }\n } else {\n result.push(...unwrapBlockParams(Object.values(param)));\n }\n }\n\n return result;\n}\n"],"mappings":";AAEA,SAASA,aAAaC,OAAyD;CAC7E,OAAOC,OAAOC,OAAOF,OAAO,MAAM,KAAKC,OAAOC,OAAOF,OAAO,MAAM;AACpE;;;;;;;AAQA,SAAgBG,yBAAyBC,QAA2C;CAClF,OAAOA,OAAOC,SAASL,UAAWD,aAAaC,KAAK,IAAI,CAACA,KAAK,IAAIC,OAAOK,OAAON,KAAK,CAAE;AACzF;;;;;;;AAQA,SAAgBO,kBAAkBH,QAA2C;CAC3E,MAAMI,SAAuB,CAAA;CAE7B,KAAK,MAAMR,SAASI,QAClB,IAAIL,aAAaC,KAAK,GAAG;EACvBQ,OAAOC,KAAKT,KAAK;EAEjB,MAAMU,SAASV,MAAMU;EAErB,IAAIA,UAAUA,OAAOC,SAAS,GAC5BH,OAAOC,KAAK,GAAGF,kBAAkBG,MAAM,CAAC;CAE5C,OACEF,OAAOC,KAAK,GAAGF,kBAAkBN,OAAOK,OAAON,KAAK,CAAC,CAAC;CAI1D,OAAOQ;AACT"}
@@ -1,9 +1,9 @@
1
1
  import { n as isEmberStoryResult } from "../../story-result-CCx6LMia.mjs";
2
- import { t as unwrapBlockParams } from "../../block-params-C68OkWMC.mjs";
2
+ import { n as unwrapBlockParamsShallow, t as unwrapBlockParams } from "../../block-params-wjiT2Ht6.mjs";
3
3
  import { emitTransformCode, useEffect, useRef } from "storybook/preview-api";
4
4
  import { SourceType } from "storybook/internal/docs-tools";
5
5
  import emberData from "virtual:ember-storybook";
6
- import { ArgTypes, Controls, Description, DocsContext, Heading, Primary, Stories, Subheading, Subtitle, Title, useOf } from "@storybook/addon-docs/blocks";
6
+ import { Controls, Description, DocsContext, Heading, Primary, PureArgsTable, Stories, Subheading, Subtitle, Title, useOf } from "@storybook/addon-docs/blocks";
7
7
  import { Fragment, createElement, useContext } from "react";
8
8
  import { NAVIGATE_URL } from "storybook/internal/core-events";
9
9
  import { styled } from "storybook/theming";
@@ -21,6 +21,13 @@ function mapTypeToControl(type) {
21
21
  default: return { type: "object" };
22
22
  }
23
23
  }
24
+ /**
25
+ * Returns a new argTypes object with entries sorted alphabetically by name,
26
+ * matching Storybook's `alpha` sort order. The input object is not mutated.
27
+ */
28
+ function sortArgTypes(argTypes) {
29
+ return Object.fromEntries(Object.entries(argTypes).toSorted(([a], [b]) => a.localeCompare(b)));
30
+ }
24
31
  function buildArgTypes(sig) {
25
32
  const argTypes = {};
26
33
  for (const [name, arg] of Object.entries(sig.args)) argTypes[name] = {
@@ -36,8 +43,63 @@ function buildArgTypes(sig) {
36
43
  defaultValue: arg.defaultValue ? { summary: arg.defaultValue } : void 0
37
44
  }
38
45
  };
39
- return argTypes;
46
+ return sortArgTypes(argTypes);
40
47
  }
48
+ function isObject(value) {
49
+ return typeof value === "object" && value !== null;
50
+ }
51
+ /**
52
+ * Merges signature-derived argTypes with the story-provided argTypes.
53
+ *
54
+ * Signature argTypes are the base; story argTypes enhance them for better
55
+ * rendering (custom `name`, `control`, `options`, ...). For args present in
56
+ * both, story fields win — but only when they carry an actual value, so an
57
+ * explicit `undefined` never masks a signature field. The signature keeps the
58
+ * `table` and `description` the story does not override.
59
+ *
60
+ * The `type` object is deep-merged: a story-provided partial `type` (e.g.
61
+ * `type: 'string'`) keeps the signature's `required` flag unless the story
62
+ * explicitly sets it, while the story's `type.name` still wins.
63
+ */
64
+ function mergeArgTypes(signatureArgTypes, storyArgTypes) {
65
+ const merged = { ...signatureArgTypes };
66
+ for (const [name, storyArg] of Object.entries(storyArgTypes)) {
67
+ if (storyArg === void 0) continue;
68
+ const sigArg = merged[name];
69
+ if (!isObject(sigArg) || !isObject(storyArg)) {
70
+ merged[name] = storyArg;
71
+ continue;
72
+ }
73
+ const storyFields = Object.fromEntries(Object.entries(storyArg).filter(([, value]) => value !== void 0));
74
+ const mergedArg = {
75
+ ...sigArg,
76
+ ...storyFields
77
+ };
78
+ if (isObject(sigArg.type) && isObject(storyFields.type)) mergedArg.type = {
79
+ ...sigArg.type,
80
+ ...storyFields.type
81
+ };
82
+ merged[name] = mergedArg;
83
+ }
84
+ return merged;
85
+ }
86
+ /**
87
+ * Whether the docs page should render the Args/controls table: either the
88
+ * component signature exposes args, or the meta carries story-provided
89
+ * argTypes (e.g. for a template-only component with story argTypes but no
90
+ * signature args).
91
+ */
92
+ function shouldShowArgsSection(sig, metaArgTypes) {
93
+ return Object.keys(sig.args).length > 0 || Object.keys(metaArgTypes ?? {}).length > 0;
94
+ }
95
+ //#endregion
96
+ //#region src/client/docs/signature.ts
97
+ /**
98
+ * Key used for default exports in signature/component maps. Mirrors
99
+ * ember-docgen's `Default` sentinel — duplicated as a literal so client
100
+ * code does not pull ember-docgen's node-only dependencies into the bundle.
101
+ */
102
+ const DEFAULT_EXPORT = "__DEFAULT__";
41
103
  /**
42
104
  * Resolve the human-facing name of a referenced component export.
43
105
  *
@@ -54,8 +116,9 @@ function componentDisplayName(ref, data) {
54
116
  const rawEntry = data[ref.filePath];
55
117
  const componentEntry = hasSignatureMap(rawEntry) ? rawEntry : void 0;
56
118
  if (!componentEntry) return ref.exportName === "__DEFAULT__" ? void 0 : ref.exportName;
57
- if (ref.exportName === "__DEFAULT__") return componentEntry.meta["__DEFAULT__"] ?? void 0;
58
- return componentEntry.meta[ref.exportName] ?? ref.exportName;
119
+ const meta = componentEntry.meta;
120
+ if (ref.exportName === "__DEFAULT__") return meta?.[DEFAULT_EXPORT];
121
+ return meta?.[ref.exportName] ?? ref.exportName;
59
122
  }
60
123
  function applyModifiers(signature, modifiers) {
61
124
  if (!modifiers || modifiers.length === 0) return signature;
@@ -77,7 +140,7 @@ function collectSubcomponents(blocks, data) {
77
140
  for (const block of Object.values(blocks)) for (const param of unwrapBlockParams(block.params)) {
78
141
  if (!param.componentRef) continue;
79
142
  const { filePath, exportName, importPath, modifiers } = param.componentRef;
80
- const name = componentDisplayName(param.componentRef, data) ?? param.name;
143
+ const name = param.componentRef.local ? param.name : componentDisplayName(param.componentRef, data) ?? param.name;
81
144
  if (seen.has(name)) continue;
82
145
  seen.add(name);
83
146
  if (importPath) result.push({
@@ -215,7 +278,10 @@ const SubcomponentLink = styled.a(({ theme }) => ({
215
278
  textDecoration: "none",
216
279
  "&:hover": { textDecoration: "underline" }
217
280
  }));
218
- const Indent = styled.span(() => ({ marginInlineStart: "20px" }));
281
+ const CodeLine = styled.div(({ theme }) => ({
282
+ fontSize: theme.typography.size.s2 - 1,
283
+ lineHeight: "19px"
284
+ }));
219
285
  /**
220
286
  * In-page anchor to a subcomponent section. Mirrors Storybook's own
221
287
  * in-docs navigation (TableOfContents / AnchorInPage): the default anchor
@@ -244,56 +310,98 @@ function SubcomponentAnchor({ name, children }) {
244
310
  }, children);
245
311
  }
246
312
  /** Display name for a block param's type: the referenced component's own
247
- * name when available, otherwise the raw type string. */
313
+ * name when available, the yield key for local components, otherwise the
314
+ * raw type string. */
248
315
  function displayTypeName(param, data) {
316
+ if (param.componentRef?.local) return param.name;
249
317
  return (data ? componentDisplayName(param.componentRef, data) : void 0) ?? param.type;
250
318
  }
251
- function renderType(param, subcomponentNames, data) {
319
+ function isBlockParam(param) {
320
+ return Object.hasOwn(param, "name") && Object.hasOwn(param, "type");
321
+ }
322
+ function isNamedParam(name) {
323
+ return Boolean(name) && !name.startsWith("param");
324
+ }
325
+ /**
326
+ * A `BlockParam` whose type was unfolded from a named non-component type is
327
+ * an object just like an inline yield hash — normalize its members to
328
+ * `[name, param]` entries. `undefined` for scalar params.
329
+ */
330
+ function memberEntriesOf(param) {
331
+ const nested = param.nested;
332
+ if (!nested || nested.length === 0) return void 0;
333
+ return nested.flatMap((entry) => isBlockParam(entry) ? [[entry.name, entry]] : Object.entries(entry));
334
+ }
335
+ function renderTypeValue(param, subcomponentNames, data) {
252
336
  const displayType = displayTypeName(param, data);
253
- if (param.componentRef) return subcomponentNames.has(displayType) ? createElement(SubcomponentAnchor, {
337
+ return subcomponentNames.has(displayType) ? createElement(SubcomponentAnchor, {
254
338
  key: "type",
255
339
  name: displayType
256
340
  }, displayType) : createElement(ParamType, { key: "type" }, displayType);
257
- return createElement(ParamType, { key: "type" }, param.type);
258
- }
259
- function renderParam(param, subcomponentNames, data) {
260
- const type = renderType(param, subcomponentNames, data);
261
- return [
262
- createElement(ParamName, { key: "name" }, param.name),
263
- createElement("span", { key: "colon" }, ": "),
264
- type
265
- ];
266
341
  }
267
- function isBlockParam(param) {
268
- return Object.hasOwn(param, "name") && Object.hasOwn(param, "type");
342
+ function descLine(param, key, depth) {
343
+ if (!param.description) return void 0;
344
+ const style = depth === void 0 ? void 0 : {
345
+ marginBottom: 0,
346
+ marginLeft: depth * 20 + 10
347
+ };
348
+ return createElement(ParamDesc, {
349
+ key,
350
+ style
351
+ }, param.description);
269
352
  }
270
- function renderParams(params, subcomponentNames, data) {
271
- return params.map((param, i) => {
272
- if (!isBlockParam(param)) {
273
- const children = [
274
- createElement("span", { key: "open" }, "- {"),
275
- createElement("br", { key: "br-open" }),
276
- ...Object.entries(param).flatMap(([key, p]) => [createElement(Indent, { key: `indent-${key}` }), renderParam(p, subcomponentNames, data)]),
277
- createElement("br", { key: "br-close" }),
278
- createElement("span", { key: "close" }, "}")
279
- ];
280
- return createElement(Fragment, { key: i }, ...children);
353
+ function codeLine(key, depth, children) {
354
+ return createElement(CodeLine, {
355
+ key,
356
+ style: { paddingInlineStart: depth * 20 }
357
+ }, ...children);
358
+ }
359
+ /**
360
+ * Render an object param JSON-style: an opening brace line (optionally
361
+ * prefixed `name: `), member lines one level deeper, and a closing brace —
362
+ * no dashes, no blank lines between the object's lines. Object members
363
+ * recurse; scalar members render as `name: type`.
364
+ */
365
+ function renderParamBlock(name, entries, subcomponentNames, data, depth, key) {
366
+ const head = name ? [createElement(ParamName, { key: `${key}-n` }, name), ": "] : [];
367
+ const lines = [codeLine(`${key}-o`, depth, [...head, "{"])];
368
+ for (const [i, [memberName, memberParam]] of entries.entries()) {
369
+ const memberKey = `${key}-${i}`;
370
+ const memberEntries = memberEntriesOf(memberParam);
371
+ if (memberEntries) lines.push(...renderParamBlock(memberName, memberEntries, subcomponentNames, data, depth + 1, memberKey));
372
+ else lines.push(codeLine(`${memberKey}-l`, depth + 1, [
373
+ createElement(ParamName, { key: `${memberKey}-n` }, memberName),
374
+ ": ",
375
+ renderTypeValue(memberParam, subcomponentNames, data)
376
+ ]));
377
+ const desc = descLine(memberParam, `${memberKey}-d`, depth + 1);
378
+ if (desc) lines.push(desc);
379
+ }
380
+ lines.push(codeLine(`${key}-x`, depth, ["}"]));
381
+ return lines;
382
+ }
383
+ function renderParams(params, subcomponentNames, data, keyPrefix = "p") {
384
+ return params.flatMap((param, i) => {
385
+ const key = `${keyPrefix}-${i}`;
386
+ if (!isBlockParam(param)) return renderParamBlock(void 0, Object.entries(param), subcomponentNames, data, 0, key);
387
+ const entries = memberEntriesOf(param);
388
+ if (entries) {
389
+ const lines = renderParamBlock(isNamedParam(param.name) ? param.name : void 0, entries, subcomponentNames, data, 0, key);
390
+ const desc = descLine(param, `${key}-d`, 0);
391
+ if (desc) lines.push(desc);
392
+ return lines;
281
393
  }
282
- const isNamed = param.name && !param.name.startsWith("param");
283
- const displayType = displayTypeName(param, data);
284
- const isSubcomponent = subcomponentNames.has(displayType);
285
- const children = [];
286
- const typeChildren = [];
287
- if (isSubcomponent) typeChildren.push(createElement(SubcomponentAnchor, {
288
- key: "type",
289
- name: displayType
290
- }, displayType));
291
- else typeChildren.push(createElement(ParamType, { key: "type" }, displayType));
292
- if (isNamed) children.push(createElement("span", { key: "sep" }, "- "), createElement(ParamName, { key: "name" }, param.name), createElement("span", { key: "colon" }, ": "), ...typeChildren);
293
- else children.push(createElement("span", { key: "sep" }, "- "), ...typeChildren);
394
+ const type = renderTypeValue(param, subcomponentNames, data);
395
+ const children = isNamedParam(param.name) ? [
396
+ "- ",
397
+ createElement(ParamName, { key: "name" }, param.name),
398
+ ": ",
399
+ type
400
+ ] : ["- ", type];
294
401
  const rows = [createElement(ParamRow, { key: "row" }, ...children)];
295
- if (param.description) rows.push(createElement(ParamDesc, { key: "desc" }, param.description));
296
- return createElement(Fragment, { key: i }, ...rows);
402
+ const desc = descLine(param, "desc");
403
+ if (desc) rows.push(desc);
404
+ return createElement(Fragment, { key }, ...rows);
297
405
  });
298
406
  }
299
407
  function BlocksTable({ blocks, subcomponentNames, data }) {
@@ -397,7 +505,7 @@ const SectionLabel = styled.div(({ theme }) => ({
397
505
  function renderSubcomponentSignature(sig, subcomponentNames, data) {
398
506
  const children = [];
399
507
  if (sig.element) children.push(createElement(ElementBlock, { element: sig.element }));
400
- if (Object.keys(sig.args).length > 0) children.push(createElement(SectionLabel, void 0, "Args"), createElement(ArgTypes, { include: Object.keys(sig.args) }));
508
+ if (Object.keys(sig.args).length > 0) children.push(createElement(SectionLabel, void 0, "Args"), createElement(PureArgsTable, { rows: buildArgTypes(sig) }));
401
509
  if (Object.keys(sig.blocks).length > 0) children.push(createElement(SectionLabel, {
402
510
  key: "blocks-label",
403
511
  style: { marginTop: 12 }
@@ -427,10 +535,10 @@ function SubcomponentsArea({ components, data }) {
427
535
  }
428
536
  //#endregion
429
537
  //#region src/client/docs/page.ts
430
- function addSignature(signature, data) {
538
+ function addSignature(signature, data, metaArgTypes) {
431
539
  const children = [];
432
540
  if (signature.element) children.push(createElement(ElementBlock, { element: signature.element }));
433
- if (Object.keys(signature.args).length > 0) children.push(createElement(Subheading, void 0, "Args"), createElement(Controls));
541
+ if (shouldShowArgsSection(signature, metaArgTypes)) children.push(createElement(Subheading, void 0, "Args"), createElement(Controls));
434
542
  if (Object.keys(signature.blocks).length > 0) {
435
543
  const subcomponents = collectSubcomponents(signature.blocks, data);
436
544
  const subcomponentNames = new Set(subcomponents.map((s) => s.name));
@@ -477,7 +585,7 @@ function Page() {
477
585
  createElement(Description),
478
586
  createElement(Primary)
479
587
  ];
480
- if (signature) children.push(...addSignature(signature, data));
588
+ if (signature) children.push(...addSignature(signature, data, resolved.preparedMeta?.argTypes));
481
589
  children.push(createElement(Stories));
482
590
  return createElement(Fragment, void 0, ...children);
483
591
  }
@@ -500,7 +608,7 @@ function toArgument(key, value, argTypes) {
500
608
  }
501
609
  function generateBlockContent(blockInfo) {
502
610
  if (blockInfo.params.length === 0) return "...";
503
- return `{{yield ${unwrapBlockParams(blockInfo.params).map((p) => p.name).join(", ")}}}`;
611
+ return `{{yield ${unwrapBlockParamsShallow(blockInfo.params).map((p) => p.name).join(", ")}}}`;
504
612
  }
505
613
  function generateBlockSourceCode(sig, args, indent) {
506
614
  const blockNames = Object.keys(sig.blocks);
@@ -509,7 +617,7 @@ function generateBlockSourceCode(sig, args, indent) {
509
617
  for (const blockName of blockNames) {
510
618
  const blockInfo = sig.blocks[blockName];
511
619
  if (args[blockName] === void 0 && blockInfo.params.length === 0) continue;
512
- const params = unwrapBlockParams(blockInfo.params).map((p) => p.name).join(" ");
620
+ const params = unwrapBlockParamsShallow(blockInfo.params).map((p) => p.name).join(" ");
513
621
  const slotBindings = params ? ` as |${params}|` : "";
514
622
  const content = generateBlockContent(blockInfo);
515
623
  if (blockName === "default" && !slotBindings) blocks.push(content);
@@ -593,23 +701,17 @@ const argTypesEnhancers = [(context) => {
593
701
  const filePath = context.parameters.fileName;
594
702
  if (filePath && Object.hasOwn(data, filePath)) {
595
703
  const sig = resolveSig(data[filePath]);
596
- if (sig) return {
597
- ...buildArgTypes(sig),
598
- ...context.argTypes
599
- };
600
- return context.argTypes;
704
+ if (sig) return sortArgTypes(mergeArgTypes(buildArgTypes(sig), context.argTypes));
705
+ return sortArgTypes(context.argTypes);
601
706
  }
602
707
  const leaf = titleLeaf(context.title);
603
708
  if (leaf) for (const entry of Object.values(data)) {
604
709
  if (!("meta" in entry)) continue;
605
710
  if (titleLeaf(entry.meta.title) !== leaf) continue;
606
711
  const sig = resolveSig(entry);
607
- if (sig) return {
608
- ...buildArgTypes(sig),
609
- ...context.argTypes
610
- };
712
+ if (sig) return sortArgTypes(mergeArgTypes(buildArgTypes(sig), context.argTypes));
611
713
  }
612
- return context.argTypes;
714
+ return sortArgTypes(context.argTypes);
613
715
  }];
614
716
  const parameters = { docs: {
615
717
  source: {