@sit-onyx/storybook-utils 1.0.0-beta.27 → 1.0.0-beta.29

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sit-onyx/storybook-utils",
3
3
  "description": "Storybook utilities for Vue",
4
- "version": "1.0.0-beta.27",
4
+ "version": "1.0.0-beta.29",
5
5
  "type": "module",
6
6
  "author": "Schwarz IT KG",
7
7
  "license": "Apache-2.0",
@@ -27,7 +27,7 @@
27
27
  "storybook": ">= 8.2.0",
28
28
  "storybook-dark-mode": ">= 4",
29
29
  "@sit-onyx/icons": "^1.0.0-beta.0",
30
- "sit-onyx": "^1.0.0-beta.26"
30
+ "sit-onyx": "^1.0.0-beta.28"
31
31
  },
32
32
  "dependencies": {
33
33
  "deepmerge-ts": "^7.1.0"
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./actions";
2
2
  export * from "./preview";
3
+ export * from "./sbType";
3
4
  export * from "./theme";
4
5
  export * from "./types";
@@ -0,0 +1,38 @@
1
+ import type { SBType } from "storybook/internal/types";
2
+ import { describe, expect, test, vi } from "vitest";
3
+ import { walkTree } from "./sbType";
4
+
5
+ describe("walkTree", () => {
6
+ test.each<{ input: SBType; expected: SBType["name"][] }>([
7
+ { input: { name: "array", value: { name: "number" } }, expected: ["array", "number"] },
8
+ { input: { name: "object", value: { a: { name: "number" } } }, expected: ["object", "number"] },
9
+ { input: { name: "enum", value: ["a"] }, expected: ["enum"] },
10
+ {
11
+ input: { name: "intersection", value: [{ name: "number" }] },
12
+ expected: ["intersection", "number"],
13
+ },
14
+ { input: { name: "union", value: [{ name: "number" }] }, expected: ["union", "number"] },
15
+ { input: { name: "other", value: "a" }, expected: ["other"] },
16
+ ])("should execute cb for $input.name correctly", ({ input, expected }) => {
17
+ const spy = vi.fn<(p: SBType) => void>();
18
+ const result = walkTree(input, spy);
19
+
20
+ expect(result).toBeUndefined();
21
+ expect(spy).toHaveBeenCalledTimes(expected.length);
22
+ const nameCalls = spy.mock.calls.map(([{ name }]) => name);
23
+ expect(nameCalls).toMatchObject(expected);
24
+ });
25
+
26
+ test("should return value if there is any returned", () => {
27
+ const target: SBType = { name: "number", raw: "here" };
28
+ const overshoot: SBType = { name: "boolean", raw: "here" };
29
+ const parent: SBType = { name: "intersection", value: [target, overshoot] };
30
+ const returned = 42;
31
+ const spy = vi.fn((p: SBType) => (p.raw === "here" ? returned : undefined));
32
+ const result = walkTree({ name: "union", value: [parent] }, spy);
33
+
34
+ expect(spy).toHaveBeenCalledTimes(3);
35
+ expect(spy).toHaveBeenLastCalledWith(target, parent);
36
+ expect(result).toBe(returned);
37
+ });
38
+ });
package/src/sbType.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { SBType } from "storybook/internal/types";
2
+
3
+ /**
4
+ * Call a function `cb` for every type node in the storybook type tree.
5
+ * @param inputType the root type
6
+ * @param cb the function that is called for every type. If any non-nullish value is returned by `cb` the execution is stopped and this value is returned.
7
+ * @param parent optional, the parent type. Is only used as input for the `cb` function and provided when recursing.
8
+ * @returns the first non-nullish value that is returned by `cb`
9
+ */
10
+ export const walkTree = <TValue>(
11
+ inputType: SBType,
12
+ cb: (sb: SBType, parent?: SBType) => TValue,
13
+ parent?: SBType,
14
+ ): TValue | undefined => {
15
+ const shouldReturn = cb(inputType, parent);
16
+ if (shouldReturn) {
17
+ return shouldReturn;
18
+ }
19
+
20
+ if (inputType.name === "union" || inputType.name === "intersection") {
21
+ return inputType.value.reduce<TValue | undefined>(
22
+ (prev, it) => prev ?? walkTree(it, cb, inputType),
23
+ undefined,
24
+ );
25
+ }
26
+ if (inputType.name === "array") {
27
+ return walkTree(inputType.value, cb, inputType);
28
+ }
29
+ if (inputType.name === "object") {
30
+ return Object.values(inputType.value).reduce<TValue | undefined>(
31
+ (prev, it) => prev ?? walkTree(it, cb, inputType),
32
+ undefined,
33
+ );
34
+ }
35
+ };