@tpitre/story-ui 4.16.9 → 4.16.11

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 +1 @@
1
- {"version":3,"file":"canvasGenerate.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/canvasGenerate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkB5C,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAwIvE,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAmCrD;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAU/D;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc1D;AAgED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsBvD;AAID,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,+CA0GtE"}
1
+ {"version":3,"file":"canvasGenerate.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/canvasGenerate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkB5C,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AA2IvE,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAmCrD;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAU/D;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc1D;AAgED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsBvD;AAID,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,+CA0GtE"}
@@ -120,15 +120,18 @@ render(<Canvas />);\`;
120
120
 
121
121
  export const Default: StoryObj = {
122
122
  render: () => {
123
- // Always start with the placeholder no localStorage restore.
124
- // Code updates arrive exclusively via postMessage from the parent panel.
125
- // This prevents stale code from a previous session causing errors.
126
- const [code, setCode] = useState(PLACEHOLDER);
123
+ // Read from localStorage on mount for the initial code delivery.
124
+ // The parent panel writes code to localStorage just before mounting
125
+ // the iframe, since postMessage can't work until our listener is ready.
126
+ const [code, setCode] = useState(() => {
127
+ try {
128
+ const saved = localStorage.getItem('${LS_KEY}');
129
+ if (saved && saved.trim()) return saved;
130
+ } catch {}
131
+ return PLACEHOLDER;
132
+ });
127
133
 
128
134
  useEffect(() => {
129
- // Clear any stale code left in localStorage from older versions
130
- try { localStorage.removeItem('${LS_KEY}'); } catch {}
131
-
132
135
  const handler = (e: MessageEvent) => {
133
136
  if (e.origin !== window.location.origin) return;
134
137
  if (e.data?.type === 'VOICE_CANVAS_UPDATE' && typeof e.data.code === 'string') {
@@ -1974,6 +1974,7 @@
1974
1974
  flex-direction: column;
1975
1975
  height: 100%;
1976
1976
  background: hsl(var(--background));
1977
+ color: hsl(var(--foreground));
1977
1978
  position: relative;
1978
1979
  }
1979
1980
 
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceCanvas.d.ts","sourceRoot":"","sources":["../../../../templates/StoryUI/voice/VoiceCanvas.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAwE,MAAM,OAAO,CAAC;AAY7F,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID,eAAO,MAAM,WAAW,4FA6wBtB,CAAC"}
1
+ {"version":3,"file":"VoiceCanvas.d.ts","sourceRoot":"","sources":["../../../../templates/StoryUI/voice/VoiceCanvas.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAwE,MAAM,OAAO,CAAC;AAY7F,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID,eAAO,MAAM,WAAW,4FAsxBtB,CAAC"}
@@ -71,10 +71,18 @@ export const VoiceCanvas = React.forwardRef(function VoiceCanvas({ apiBase, prov
71
71
  const iframeLoadedRef = useRef(false);
72
72
  // ── Code → iframe bridge ─────────────────────────────────────
73
73
  /**
74
- * Push code to the story preview iframe via postMessage.
75
- * No localStorage persistence each session starts clean.
74
+ * Push code to the story preview iframe.
75
+ * Uses both localStorage (for initial load before message listener is ready)
76
+ * and postMessage (for instant updates once the iframe is running).
76
77
  */
77
78
  const sendCodeToIframe = useCallback((code) => {
79
+ // Write to localStorage so the iframe can read it on initial mount —
80
+ // postMessage alone doesn't work for the first generation because the
81
+ // iframe's React component hasn't attached its message listener yet.
82
+ try {
83
+ localStorage.setItem(LS_KEY, code);
84
+ }
85
+ catch { }
78
86
  if (iframeRef.current?.contentWindow && iframeLoadedRef.current) {
79
87
  iframeRef.current.contentWindow.postMessage({ type: 'VOICE_CANVAS_UPDATE', code }, IFRAME_ORIGIN);
80
88
  }
@@ -145,12 +153,20 @@ export const VoiceCanvas = React.forwardRef(function VoiceCanvas({ apiBase, prov
145
153
  setRedoStack([]);
146
154
  }
147
155
  setCurrentCode(newCode);
148
- sendCodeToIframe(newCode);
149
- // First generation mount the iframe
156
+ // First generation — mount the iframe. Write to localStorage
157
+ // BEFORE mounting so the iframe reads the code on initial render.
158
+ // For subsequent generations, sendCodeToIframe uses postMessage.
150
159
  if (!storyReady) {
160
+ try {
161
+ localStorage.setItem(LS_KEY, newCode);
162
+ }
163
+ catch { }
151
164
  setStoryReady(true);
152
165
  setIframeKey(k => k + 1);
153
166
  }
167
+ else {
168
+ sendCodeToIframe(newCode);
169
+ }
154
170
  // Track the first prompt for save title (describes the component),
155
171
  // and the last prompt for display in the status bar.
156
172
  if (!firstPromptRef.current) {
@@ -107,10 +107,15 @@ function VoiceCanvas({
107
107
  // ── Code → iframe bridge ─────────────────────────────────────
108
108
 
109
109
  /**
110
- * Push code to the story preview iframe via postMessage.
111
- * No localStorage persistence each session starts clean.
110
+ * Push code to the story preview iframe.
111
+ * Uses both localStorage (for initial load before message listener is ready)
112
+ * and postMessage (for instant updates once the iframe is running).
112
113
  */
113
114
  const sendCodeToIframe = useCallback((code: string) => {
115
+ // Write to localStorage so the iframe can read it on initial mount —
116
+ // postMessage alone doesn't work for the first generation because the
117
+ // iframe's React component hasn't attached its message listener yet.
118
+ try { localStorage.setItem(LS_KEY, code); } catch {}
114
119
  if (iframeRef.current?.contentWindow && iframeLoadedRef.current) {
115
120
  iframeRef.current.contentWindow.postMessage(
116
121
  { type: 'VOICE_CANVAS_UPDATE', code },
@@ -195,12 +200,16 @@ function VoiceCanvas({
195
200
  }
196
201
 
197
202
  setCurrentCode(newCode);
198
- sendCodeToIframe(newCode);
199
203
 
200
- // First generation — mount the iframe
204
+ // First generation — mount the iframe. Write to localStorage
205
+ // BEFORE mounting so the iframe reads the code on initial render.
206
+ // For subsequent generations, sendCodeToIframe uses postMessage.
201
207
  if (!storyReady) {
208
+ try { localStorage.setItem(LS_KEY, newCode); } catch {}
202
209
  setStoryReady(true);
203
210
  setIframeKey(k => k + 1);
211
+ } else {
212
+ sendCodeToIframe(newCode);
204
213
  }
205
214
 
206
215
  // Track the first prompt for save title (describes the component),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpitre/story-ui",
3
- "version": "4.16.9",
3
+ "version": "4.16.11",
4
4
  "description": "AI-powered Storybook story generator with dynamic component discovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1974,6 +1974,7 @@
1974
1974
  flex-direction: column;
1975
1975
  height: 100%;
1976
1976
  background: hsl(var(--background));
1977
+ color: hsl(var(--foreground));
1977
1978
  position: relative;
1978
1979
  }
1979
1980
 
@@ -107,10 +107,15 @@ function VoiceCanvas({
107
107
  // ── Code → iframe bridge ─────────────────────────────────────
108
108
 
109
109
  /**
110
- * Push code to the story preview iframe via postMessage.
111
- * No localStorage persistence each session starts clean.
110
+ * Push code to the story preview iframe.
111
+ * Uses both localStorage (for initial load before message listener is ready)
112
+ * and postMessage (for instant updates once the iframe is running).
112
113
  */
113
114
  const sendCodeToIframe = useCallback((code: string) => {
115
+ // Write to localStorage so the iframe can read it on initial mount —
116
+ // postMessage alone doesn't work for the first generation because the
117
+ // iframe's React component hasn't attached its message listener yet.
118
+ try { localStorage.setItem(LS_KEY, code); } catch {}
114
119
  if (iframeRef.current?.contentWindow && iframeLoadedRef.current) {
115
120
  iframeRef.current.contentWindow.postMessage(
116
121
  { type: 'VOICE_CANVAS_UPDATE', code },
@@ -195,12 +200,16 @@ function VoiceCanvas({
195
200
  }
196
201
 
197
202
  setCurrentCode(newCode);
198
- sendCodeToIframe(newCode);
199
203
 
200
- // First generation — mount the iframe
204
+ // First generation — mount the iframe. Write to localStorage
205
+ // BEFORE mounting so the iframe reads the code on initial render.
206
+ // For subsequent generations, sendCodeToIframe uses postMessage.
201
207
  if (!storyReady) {
208
+ try { localStorage.setItem(LS_KEY, newCode); } catch {}
202
209
  setStoryReady(true);
203
210
  setIframeKey(k => k + 1);
211
+ } else {
212
+ sendCodeToIframe(newCode);
204
213
  }
205
214
 
206
215
  // Track the first prompt for save title (describes the component),