@vitus-labs/rocketstories 2.0.0 → 2.2.0

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/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ListProps } from "@vitus-labs/elements";
2
- import { RocketComponentType } from "@vitus-labs/rocketstyle";
2
+ import { RocketComponentType, ThemeModeKeys } from "@vitus-labs/rocketstyle";
3
3
  import { ComponentType, FC, ForwardRefExoticComponent, ReactNode } from "react";
4
4
 
5
5
  //#region src/constants/controls.d.ts
@@ -17,8 +17,12 @@ type StoryComponent<P = {}> = FC<P> & Partial<{
17
17
  type ElementType<T extends TObj | unknown = any> = ComponentType<T> | ForwardRefExoticComponent<T>;
18
18
  type RocketType = RocketComponentType & {
19
19
  VITUS_LABS__COMPONENT?: string;
20
- getStaticDimensions: any;
21
- getDefaultAttrs: any;
20
+ getStaticDimensions: (theme: TObj) => {
21
+ dimensions: Record<string, any>;
22
+ useBooleans: boolean;
23
+ multiKeys: Record<string, true>;
24
+ };
25
+ getDefaultAttrs: (props: TObj, theme: TObj, mode: ThemeModeKeys) => TObj;
22
26
  displayName?: string;
23
27
  };
24
28
  type ControlTypes = T_CONTROL_TYPES;
@@ -67,6 +71,16 @@ type Configuration = {
67
71
  }>;
68
72
  controls: Record<string, Control>;
69
73
  decorators: Decorator[];
74
+ /**
75
+ * Theme used at story-construction time when introspecting rocketstyle
76
+ * components (`getStaticDimensions`, `getDefaultAttrs`). The
77
+ * `rocketstories` factory snapshots this from the module-level singleton
78
+ * (`utils/theme.ts`) so each `storyOf(component)` instance is isolated
79
+ * from later `setTheme` mutations or competing `init({ theme })` calls
80
+ * in the same process. Optional in the type to ease direct test
81
+ * construction; consumers via the factory always receive a value.
82
+ */
83
+ theme?: Record<string, unknown>;
70
84
  };
71
85
  type RocketStoryConfiguration = Omit<Configuration, 'component'> & {
72
86
  component: RocketType;
@@ -121,7 +135,7 @@ interface IRocketStories<OA extends TObj = {}, RA extends TObj | unknown = unkno
121
135
  }>) => ReturnType<RenderDimension<OA>> | null;
122
136
  render: (params: RenderStoryOptions<OA>) => ISRS extends true ? ReturnType<RenderRender<OA>> : ReturnType<RenderRender$1<OA>>;
123
137
  list: (params: ListStoryOptions) => ISRS extends true ? ReturnType<RenderList<OA>> : ReturnType<RenderList$1<OA>>;
124
- init: () => {
138
+ init: {
125
139
  component: Configuration['component'];
126
140
  title: Configuration['name'];
127
141
  decorators: Configuration['decorators'];
@@ -135,7 +149,7 @@ interface IRocketStories<OA extends TObj = {}, RA extends TObj | unknown = unkno
135
149
  }
136
150
  //#endregion
137
151
  //#region src/init.d.ts
138
- type InitParams = Partial<Omit<Configuration, 'component' | 'attrs'>> & {
152
+ type InitParams = Partial<Omit<Configuration, 'component' | 'attrs' | 'theme'>> & {
139
153
  theme?: Record<string, unknown>;
140
154
  };
141
155
  /**
@@ -154,7 +168,9 @@ declare const init: Init;
154
168
  * returning an IRocketStories builder with chainable methods for
155
169
  * generating Storybook stories, controls, and dimension showcases.
156
170
  */
157
- type Rocketstories = <C extends Configuration['component']>(component: C, options?: Partial<Omit<Configuration, 'component' | 'attrs'>>) => C extends RocketType ? IRocketStories<ExtractProps<C>, C['$$rocketstyle'], true> : IRocketStories<ExtractProps<C>, unknown, false>;
171
+ type Rocketstories = <C extends Configuration['component']>(component: C, options?: Partial<Omit<Configuration, 'component' | 'attrs' | 'theme'>> & {
172
+ theme?: Record<string, unknown>;
173
+ }) => C extends RocketType ? IRocketStories<ExtractProps<C>, C['$$rocketstyle'], true> : IRocketStories<ExtractProps<C>, unknown, false>;
158
174
  /** @see {@link Rocketstories} */
159
175
  declare const rocketstories: Rocketstories;
160
176
  //#endregion
package/lib/index.js CHANGED
@@ -562,7 +562,8 @@ const story = (WrappedComponent) => ({ component, attrs, controls }) => {
562
562
  * Accepts list configuration (data, itemKey, etc.) and wraps the component
563
563
  * through StoryHoc, rendering it inside a Vitus Labs List element.
564
564
  */
565
- var renderList_default$1 = (list) => story((component) => (props) => /* @__PURE__ */ jsx(List, {
565
+ const LooseList$1 = List;
566
+ var renderList_default$1 = (list) => story((component) => (props) => /* @__PURE__ */ jsx(LooseList$1, {
566
567
  rootElement: false,
567
568
  ...list,
568
569
  itemProps: props,
@@ -766,14 +767,6 @@ const generateMainJSXCode = ({ name, props, dimensions, booleanDimensions }) =>
766
767
  return result;
767
768
  };
768
769
 
769
- //#endregion
770
- //#region src/utils/theme.ts
771
- let theme = {};
772
- const getTheme = () => theme;
773
- const setTheme = (value) => {
774
- theme = value;
775
- };
776
-
777
770
  //#endregion
778
771
  //#region src/stories/rocketstories/renderDimension/context.tsx
779
772
  /**
@@ -829,8 +822,7 @@ const component = ({ itemProps }) => /* @__PURE__ */ jsx(Fragment, { children: p
829
822
  * PseudoList when pseudo-state visualization is enabled). Generates
830
823
  * corresponding JSX code snippets and Storybook controls.
831
824
  */
832
- const renderDimension = (dimension, { name, component: component$3, attrs = {}, controls, storyOptions = {}, ignore = [] }) => {
833
- const theme = getTheme();
825
+ const renderDimension = (dimension, { name, component: component$3, attrs = {}, controls, storyOptions = {}, ignore = [], theme = {} }) => {
834
826
  const statics = component$3.getStaticDimensions(theme);
835
827
  const defaultAttrs = component$3.getDefaultAttrs(attrs, theme, "light");
836
828
  const { dimensions, useBooleans, multiKeys } = statics;
@@ -942,8 +934,7 @@ const extractDefaultBooleanProps = ({ dimensions, multiKeys, useBooleans }) => {
942
934
  * static configuration, auto-generates Storybook controls for dimensions
943
935
  * and known Vitus Labs props, and attaches args/argTypes/parameters to the story.
944
936
  */
945
- const rocketStory = (WrappedComponent) => ({ name, component, attrs, controls }) => {
946
- const theme = getTheme();
937
+ const rocketStory = (WrappedComponent) => ({ name, component, attrs, controls, theme = {} }) => {
947
938
  const statics = component.getStaticDimensions(theme);
948
939
  const defaultAttrs = component.getDefaultAttrs(attrs, theme, "light");
949
940
  const { dimensions, useBooleans, multiKeys } = statics;
@@ -989,7 +980,8 @@ const rocketStory = (WrappedComponent) => ({ name, component, attrs, controls })
989
980
  * Accepts list configuration and wraps the component through RocketStoryHoc,
990
981
  * rendering it inside a Vitus Labs List element with auto-generated controls.
991
982
  */
992
- var renderList_default = (list) => rocketStory((component) => (props) => /* @__PURE__ */ jsx(List, {
983
+ const LooseList = List;
984
+ var renderList_default = (list) => rocketStory((component) => (props) => /* @__PURE__ */ jsx(LooseList, {
993
985
  rootElement: false,
994
986
  itemProps: props,
995
987
  ...list,
@@ -1012,16 +1004,31 @@ var renderRender_default = (render) => rocketStory(() => render);
1012
1004
  //#endregion
1013
1005
  //#region src/rocketstories.tsx
1014
1006
  /**
1015
- * Clones the current configuration, merges in new options,
1016
- * and returns a fresh IRocketStories instance for immutable chaining.
1007
+ * Clones the current configuration, merges in new options, and returns a
1008
+ * fresh IRocketStories instance for immutable chaining.
1009
+ *
1010
+ * Component-swap reset: when `options.component` differs from the current
1011
+ * `defaultOptions.component`, the prior `attrs` are dropped — they were
1012
+ * tailored to the previous component's prop shape, and applying them to a
1013
+ * different component silently leaks invalid props onto the rendered
1014
+ * output. Story-level config (`storyOptions`, `controls`, `decorators`)
1015
+ * is preserved because it's about how stories render, not about the
1016
+ * component's prop shape. Mirrors the same fix in `@vitus-labs/rocketstyle`'s
1017
+ * `cloneAndEnhance` (PR #200).
1018
+ *
1019
+ * Callers who want to preserve attrs across a component swap must
1020
+ * re-chain explicitly:
1021
+ *
1022
+ * stories.replaceComponent(NewComp).attrs(sharedAttrs)
1017
1023
  */
1018
- const cloneAndEhnance = (defaultOptions, options) => {
1024
+ const cloneAndEnhance = (defaultOptions, options) => {
1025
+ const componentChanged = options.component != null && options.component !== defaultOptions.component;
1019
1026
  const result = {
1020
1027
  ...defaultOptions,
1021
1028
  name: defaultOptions.name || options.name,
1022
1029
  prefix: options.prefix || defaultOptions.prefix,
1023
1030
  component: options.component || defaultOptions.component,
1024
- attrs: {
1031
+ attrs: componentChanged ? { ...options.attrs } : {
1025
1032
  ...defaultOptions.attrs,
1026
1033
  ...options.attrs
1027
1034
  },
@@ -1078,21 +1085,29 @@ const createRocketStories = (options) => {
1078
1085
  title: options.name,
1079
1086
  decorators: options.decorators
1080
1087
  },
1081
- storyOptions: (storyOptions) => cloneAndEhnance(options, { storyOptions }),
1082
- controls: (controls) => cloneAndEhnance(options, { controls }),
1083
- config: ({ component, storyOptions, prefix, name, decorators }) => cloneAndEhnance(options, {
1088
+ storyOptions: (storyOptions) => cloneAndEnhance(options, { storyOptions }),
1089
+ controls: (controls) => cloneAndEnhance(options, { controls }),
1090
+ config: ({ component, storyOptions, prefix, name, decorators }) => cloneAndEnhance(options, {
1084
1091
  component,
1085
1092
  storyOptions,
1086
1093
  prefix,
1087
1094
  name,
1088
1095
  decorators
1089
1096
  }),
1090
- attrs: (attrs) => cloneAndEhnance(options, { attrs }),
1091
- replaceComponent: (component) => cloneAndEhnance(options, { component }),
1092
- decorators: (decorators) => cloneAndEhnance(options, { decorators })
1097
+ attrs: (attrs) => cloneAndEnhance(options, { attrs }),
1098
+ replaceComponent: (component) => cloneAndEnhance(options, { component }),
1099
+ decorators: (decorators) => cloneAndEnhance(options, { decorators })
1093
1100
  };
1094
1101
  };
1095
1102
 
1103
+ //#endregion
1104
+ //#region src/utils/theme.ts
1105
+ let theme = {};
1106
+ const getTheme = () => theme;
1107
+ const setTheme = (value) => {
1108
+ theme = value;
1109
+ };
1110
+
1096
1111
  //#endregion
1097
1112
  //#region src/init.ts
1098
1113
  /** @see {@link Init} */
@@ -1101,12 +1116,13 @@ const init = ({ decorators = [], storyOptions = {}, theme, ...rest }) => {
1101
1116
  return (component) => rocketstories(component, {
1102
1117
  decorators,
1103
1118
  storyOptions,
1119
+ theme,
1104
1120
  ...rest
1105
1121
  });
1106
1122
  };
1107
1123
  /** @see {@link Rocketstories} */
1108
1124
  const rocketstories = (component, options = {}) => {
1109
- const { decorators = [], storyOptions = {} } = options;
1125
+ const { decorators = [], storyOptions = {}, theme } = options;
1110
1126
  return createRocketStories({
1111
1127
  component,
1112
1128
  name: component.displayName || component.name,
@@ -1119,7 +1135,8 @@ const rocketstories = (component, options = {}) => {
1119
1135
  ...storyOptions
1120
1136
  },
1121
1137
  decorators,
1122
- controls: {}
1138
+ controls: {},
1139
+ theme: theme ?? getTheme()
1123
1140
  });
1124
1141
  };
1125
1142
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitus-labs/rocketstories",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "license": "MIT",
5
5
  "author": "Vit Bokisch <vit@bokisch.cz>",
6
6
  "maintainers": [
@@ -61,14 +61,13 @@
61
61
  "test:coverage": "vitest run --coverage",
62
62
  "test:watch": "vitest",
63
63
  "cover": "coveralls < .coverage/lcov.info",
64
- "typecheck": "tsc --noEmit",
65
- "version": "node ../../scripts/sync-peer-deps.mjs"
64
+ "typecheck": "tsc --noEmit"
66
65
  },
67
66
  "peerDependencies": {
68
- "@storybook/react": "10.2.8",
69
- "@vitus-labs/core": "2.0.0",
70
- "@vitus-labs/rocketstyle": "2.0.0",
71
- "@vitus-labs/unistyle": "2.0.0",
67
+ "@storybook/react": "^10.3.6",
68
+ "@vitus-labs/core": "workspace:^",
69
+ "@vitus-labs/rocketstyle": "workspace:^",
70
+ "@vitus-labs/unistyle": "workspace:^",
72
71
  "react": ">= 19"
73
72
  },
74
73
  "dependencies": {
@@ -77,9 +76,9 @@
77
76
  "devDependencies": {
78
77
  "@vitus-labs/core": "workspace:*",
79
78
  "@vitus-labs/rocketstyle": "workspace:*",
80
- "@vitus-labs/tools-rolldown": "2.2.0",
81
- "@vitus-labs/tools-storybook": "2.2.0",
82
- "@vitus-labs/tools-typescript": "2.1.0",
79
+ "@vitus-labs/tools-rolldown": "2.3.0",
80
+ "@vitus-labs/tools-storybook": "2.3.0",
81
+ "@vitus-labs/tools-typescript": "2.3.0",
83
82
  "@vitus-labs/unistyle": "workspace:*"
84
83
  }
85
84
  }