@sxl-studio/storybook-addon 1.0.9 → 1.0.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.
package/dist/index.d.ts CHANGED
@@ -2,16 +2,27 @@ declare const ADDON_ID: "sxl-studio";
2
2
  declare const PANEL_ID: "sxl-studio/panel";
3
3
  declare const PARAM_KEY: "sxl";
4
4
 
5
- /** Token assignment status on the Figma component. */
5
+ /** Token row: green "True" or gray "False" (from `tokensReady` in registry). */
6
+ type SxlTokensBool = "true" | "false";
7
+ /** @deprecated Prefer `tokensBool` + readiness badges */
6
8
  type SxlTokenStatus = "assigned" | "partial" | "none";
7
- /** Design readiness stage. */
9
+ /** Design readiness stage (maps to colored badges). */
8
10
  type SxlReadiness = "complete" | "ready-for-dev" | "in-progress" | "backlog";
11
+ type SxlComponentApiProp = {
12
+ name: string;
13
+ kind: string;
14
+ defaultValue?: string | boolean;
15
+ options?: string[];
16
+ };
9
17
  /** Extended metadata for a single Figma component (exported by the plugin). */
10
18
  type SxlRegistryMeta = {
11
19
  variantCount?: number;
12
20
  componentProperties?: string[];
21
+ /** @deprecated */
13
22
  tokenStatus?: SxlTokenStatus;
14
23
  readiness?: SxlReadiness;
24
+ /** Green/gray tokens row */
25
+ tokensBool?: SxlTokensBool;
15
26
  };
16
27
  /** File binding from Code Connect (per-framework). */
17
28
  type SxlFileBinding = {
@@ -38,6 +49,13 @@ type SxlRegistryEntry = {
38
49
  snippetTemplate?: string;
39
50
  /** Per-framework file bindings. */
40
51
  files?: SxlFileBinding[];
52
+ /** Embedded composition JSON (from plugin push). */
53
+ compositionSnapshot?: string;
54
+ compositionName?: string;
55
+ /** Figma component API snapshot */
56
+ componentApi?: {
57
+ properties: SxlComponentApiProp[];
58
+ };
41
59
  meta?: SxlRegistryMeta;
42
60
  };
43
61
  /**
@@ -66,8 +84,9 @@ type SxlStoryParameters = {
66
84
  figmaUrl?: string;
67
85
  /** Direct description (overrides registry). */
68
86
  description?: string;
69
- /** Override token status per-story. */
87
+ /** Override token badge per-story. */
70
88
  tokenStatus?: SxlTokenStatus;
89
+ tokensBool?: SxlTokensBool;
71
90
  /** Override readiness per-story. */
72
91
  readiness?: SxlReadiness;
73
92
  /** Override designEmbed per-story. */
@@ -83,17 +102,7 @@ type SxlStoryParameters = {
83
102
  /**
84
103
  * Converts the plugin's `diff-code-connect.<fileKey>.json` to the addon registry format.
85
104
  * Supports both v1 (`entries[]`) and v2 (`components[]`) schemas transparently.
86
- *
87
- * Usage in `.storybook/preview.ts`:
88
- * ```ts
89
- * import raw from '../diff-code-connect.abc123.json';
90
- * import { fromDiffCodeConnect } from '@sxl-studio/storybook-addon';
91
- *
92
- * export default {
93
- * parameters: { sxl: { registry: fromDiffCodeConnect(raw) } },
94
- * };
95
- * ```
96
105
  */
97
106
  declare function fromDiffCodeConnect(data: unknown): SxlRegistry;
98
107
 
99
- export { ADDON_ID, PANEL_ID, PARAM_KEY, type SxlFileBinding, type SxlReadiness, type SxlRegistry, type SxlRegistryEntry, type SxlRegistryMeta, type SxlStoryParameters, type SxlTokenStatus, fromDiffCodeConnect };
108
+ export { ADDON_ID, PANEL_ID, PARAM_KEY, type SxlComponentApiProp, type SxlFileBinding, type SxlReadiness, type SxlRegistry, type SxlRegistryEntry, type SxlRegistryMeta, type SxlStoryParameters, type SxlTokenStatus, type SxlTokensBool, fromDiffCodeConnect };
package/dist/index.js CHANGED
@@ -20,16 +20,20 @@ function fromDiffCodeConnect(data) {
20
20
  entries
21
21
  };
22
22
  }
23
+ function tokensBoolFromStorybook(sb) {
24
+ if (sb.tokensReady === true) return "true";
25
+ return "false";
26
+ }
23
27
  function convertV2Components(components, fileKey) {
24
28
  return components.filter((c) => c.linked === true).map((c) => {
25
29
  const nodeId = String(c.nodeId ?? "");
26
30
  const sb = c.storybook ?? {};
27
31
  const cc = c.codeConnect ?? {};
28
32
  const figmaUrl = fileKey ? `https://www.figma.com/design/${fileKey}?node-id=${nodeId.replace(":", "-")}` : void 0;
29
- const tokenStatus = sb.tokensReady === true ? "assigned" : void 0;
30
33
  const statusRaw = typeof sb.status === "string" ? sb.status : void 0;
31
34
  const readiness = statusRaw === "complete" || statusRaw === "ready-for-dev" || statusRaw === "in-progress" || statusRaw === "backlog" ? statusRaw : void 0;
32
35
  const files = parseFiles(Array.isArray(cc.files) ? cc.files : []);
36
+ const componentApi = parseComponentApi(sb.componentApi);
33
37
  return {
34
38
  nodeId,
35
39
  displayName: String(c.displayName ?? c.name ?? ""),
@@ -42,13 +46,28 @@ function convertV2Components(components, fileKey) {
42
46
  importPath: typeof cc.importPath === "string" ? cc.importPath : void 0,
43
47
  snippetTemplate: typeof cc.snippetTemplate === "string" ? cc.snippetTemplate : void 0,
44
48
  files: files.length > 0 ? files : void 0,
49
+ compositionSnapshot: typeof sb.compositionSnapshot === "string" ? sb.compositionSnapshot : void 0,
50
+ compositionName: typeof sb.compositionName === "string" ? sb.compositionName : void 0,
51
+ componentApi,
45
52
  meta: {
46
- ...tokenStatus ? { tokenStatus } : {},
53
+ tokensBool: tokensBoolFromStorybook(sb),
47
54
  ...readiness ? { readiness } : {}
48
55
  }
49
56
  };
50
57
  });
51
58
  }
59
+ function parseComponentApi(raw) {
60
+ if (!raw || typeof raw !== "object") return void 0;
61
+ const o = raw;
62
+ if (!Array.isArray(o.properties)) return void 0;
63
+ const properties = o.properties.filter((p) => !!p && typeof p === "object").map((p) => ({
64
+ name: String(p.name ?? ""),
65
+ kind: String(p.kind ?? ""),
66
+ ...p.defaultValue !== void 0 ? { defaultValue: p.defaultValue } : {},
67
+ ...Array.isArray(p.options) ? { options: p.options.map(String) } : {}
68
+ }));
69
+ return properties.length ? { properties } : void 0;
70
+ }
52
71
  function convertV1Entries(rawEntries, fileKey) {
53
72
  return rawEntries.filter((e) => {
54
73
  if (!e || typeof e !== "object") return false;
@@ -59,10 +78,10 @@ function convertV1Entries(rawEntries, fileKey) {
59
78
  const sb = b.storybook ?? {};
60
79
  const nodeId = String(e.nodeId ?? "");
61
80
  const figmaUrl = fileKey ? `https://www.figma.com/design/${fileKey}?node-id=${nodeId.replace(":", "-")}` : void 0;
62
- const tokenStatus = sb.tokensReady === true ? "assigned" : void 0;
63
81
  const statusRaw = typeof sb.status === "string" ? sb.status : void 0;
64
82
  const readiness = statusRaw === "complete" || statusRaw === "ready-for-dev" || statusRaw === "in-progress" || statusRaw === "backlog" ? statusRaw : void 0;
65
83
  const files = parseFiles(Array.isArray(b.files) ? b.files : []);
84
+ const componentApi = parseComponentApi(sb.componentApi);
66
85
  return {
67
86
  nodeId,
68
87
  displayName: String(b.displayName ?? e.nodeName ?? ""),
@@ -75,8 +94,11 @@ function convertV1Entries(rawEntries, fileKey) {
75
94
  importPath: typeof b.importPath === "string" ? b.importPath : void 0,
76
95
  snippetTemplate: typeof b.snippetTemplate === "string" ? b.snippetTemplate : void 0,
77
96
  files: files.length > 0 ? files : void 0,
97
+ compositionSnapshot: typeof sb.compositionSnapshot === "string" ? sb.compositionSnapshot : void 0,
98
+ compositionName: typeof sb.compositionName === "string" ? sb.compositionName : void 0,
99
+ componentApi,
78
100
  meta: {
79
- ...tokenStatus ? { tokenStatus } : {},
101
+ tokensBool: tokensBoolFromStorybook(sb),
80
102
  ...readiness ? { readiness } : {}
81
103
  }
82
104
  };
package/dist/manager.js CHANGED
@@ -8,7 +8,7 @@ var PANEL_ID = `${ADDON_ID}/panel`;
8
8
  var PARAM_KEY = "sxl";
9
9
 
10
10
  // src/components/SxlPanel.tsx
11
- import React from "react";
11
+ import React, { useCallback, useState } from "react";
12
12
  import { useParameter, useStorybookState } from "@storybook/manager-api";
13
13
 
14
14
  // src/convert.ts
@@ -28,16 +28,20 @@ function fromDiffCodeConnect(data) {
28
28
  entries
29
29
  };
30
30
  }
31
+ function tokensBoolFromStorybook(sb) {
32
+ if (sb.tokensReady === true) return "true";
33
+ return "false";
34
+ }
31
35
  function convertV2Components(components, fileKey) {
32
36
  return components.filter((c) => c.linked === true).map((c) => {
33
37
  const nodeId = String(c.nodeId ?? "");
34
38
  const sb = c.storybook ?? {};
35
39
  const cc = c.codeConnect ?? {};
36
40
  const figmaUrl = fileKey ? `https://www.figma.com/design/${fileKey}?node-id=${nodeId.replace(":", "-")}` : void 0;
37
- const tokenStatus = sb.tokensReady === true ? "assigned" : void 0;
38
41
  const statusRaw = typeof sb.status === "string" ? sb.status : void 0;
39
42
  const readiness = statusRaw === "complete" || statusRaw === "ready-for-dev" || statusRaw === "in-progress" || statusRaw === "backlog" ? statusRaw : void 0;
40
43
  const files = parseFiles(Array.isArray(cc.files) ? cc.files : []);
44
+ const componentApi = parseComponentApi(sb.componentApi);
41
45
  return {
42
46
  nodeId,
43
47
  displayName: String(c.displayName ?? c.name ?? ""),
@@ -50,13 +54,28 @@ function convertV2Components(components, fileKey) {
50
54
  importPath: typeof cc.importPath === "string" ? cc.importPath : void 0,
51
55
  snippetTemplate: typeof cc.snippetTemplate === "string" ? cc.snippetTemplate : void 0,
52
56
  files: files.length > 0 ? files : void 0,
57
+ compositionSnapshot: typeof sb.compositionSnapshot === "string" ? sb.compositionSnapshot : void 0,
58
+ compositionName: typeof sb.compositionName === "string" ? sb.compositionName : void 0,
59
+ componentApi,
53
60
  meta: {
54
- ...tokenStatus ? { tokenStatus } : {},
61
+ tokensBool: tokensBoolFromStorybook(sb),
55
62
  ...readiness ? { readiness } : {}
56
63
  }
57
64
  };
58
65
  });
59
66
  }
67
+ function parseComponentApi(raw) {
68
+ if (!raw || typeof raw !== "object") return void 0;
69
+ const o = raw;
70
+ if (!Array.isArray(o.properties)) return void 0;
71
+ const properties = o.properties.filter((p) => !!p && typeof p === "object").map((p) => ({
72
+ name: String(p.name ?? ""),
73
+ kind: String(p.kind ?? ""),
74
+ ...p.defaultValue !== void 0 ? { defaultValue: p.defaultValue } : {},
75
+ ...Array.isArray(p.options) ? { options: p.options.map(String) } : {}
76
+ }));
77
+ return properties.length ? { properties } : void 0;
78
+ }
60
79
  function convertV1Entries(rawEntries, fileKey) {
61
80
  return rawEntries.filter((e) => {
62
81
  if (!e || typeof e !== "object") return false;
@@ -67,10 +86,10 @@ function convertV1Entries(rawEntries, fileKey) {
67
86
  const sb = b.storybook ?? {};
68
87
  const nodeId = String(e.nodeId ?? "");
69
88
  const figmaUrl = fileKey ? `https://www.figma.com/design/${fileKey}?node-id=${nodeId.replace(":", "-")}` : void 0;
70
- const tokenStatus = sb.tokensReady === true ? "assigned" : void 0;
71
89
  const statusRaw = typeof sb.status === "string" ? sb.status : void 0;
72
90
  const readiness = statusRaw === "complete" || statusRaw === "ready-for-dev" || statusRaw === "in-progress" || statusRaw === "backlog" ? statusRaw : void 0;
73
91
  const files = parseFiles(Array.isArray(b.files) ? b.files : []);
92
+ const componentApi = parseComponentApi(sb.componentApi);
74
93
  return {
75
94
  nodeId,
76
95
  displayName: String(b.displayName ?? e.nodeName ?? ""),
@@ -83,8 +102,11 @@ function convertV1Entries(rawEntries, fileKey) {
83
102
  importPath: typeof b.importPath === "string" ? b.importPath : void 0,
84
103
  snippetTemplate: typeof b.snippetTemplate === "string" ? b.snippetTemplate : void 0,
85
104
  files: files.length > 0 ? files : void 0,
105
+ compositionSnapshot: typeof sb.compositionSnapshot === "string" ? sb.compositionSnapshot : void 0,
106
+ compositionName: typeof sb.compositionName === "string" ? sb.compositionName : void 0,
107
+ componentApi,
86
108
  meta: {
87
- ...tokenStatus ? { tokenStatus } : {},
109
+ tokensBool: tokensBoolFromStorybook(sb),
88
110
  ...readiness ? { readiness } : {}
89
111
  }
90
112
  };
@@ -100,187 +122,166 @@ function parseFiles(raw) {
100
122
  }
101
123
 
102
124
  // src/components/styles.ts
103
- var FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
104
- var MONO = "'SF Mono', 'Fira Code', 'Cascadia Code', Menlo, monospace";
105
- var root = {
106
- padding: "20px",
125
+ var FONT = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
126
+ var MONO = '"SF Mono", ui-monospace, "Fira Code", "Cascadia Code", Menlo, monospace';
127
+ var panelRoot = {
128
+ padding: "16px 18px 24px",
107
129
  fontFamily: FONT,
108
130
  fontSize: "13px",
109
- lineHeight: 1.55,
110
- color: "var(--sxl-text, #1a1a2e)",
131
+ lineHeight: 1.5,
132
+ color: "var(--sb-color-text, var(--color-text-default, #2e343f))",
133
+ backgroundColor: "transparent",
111
134
  overflow: "auto",
112
135
  height: "100%",
113
- display: "flex",
114
- flexDirection: "column",
115
- gap: "16px"
136
+ boxSizing: "border-box"
116
137
  };
117
- var header = {
138
+ var topRow = {
118
139
  display: "flex",
119
140
  alignItems: "flex-start",
120
141
  justifyContent: "space-between",
121
- gap: "12px"
142
+ gap: "16px",
143
+ marginBottom: "14px"
122
144
  };
123
- var headerLeft = {
124
- display: "flex",
125
- flexDirection: "column",
126
- gap: "4px",
145
+ var titleBlock = {
127
146
  flex: 1,
128
147
  minWidth: 0
129
148
  };
130
149
  var componentName = {
131
- fontSize: "18px",
150
+ fontSize: "17px",
132
151
  fontWeight: 700,
133
- color: "var(--sxl-text, #1a1a2e)",
152
+ letterSpacing: "-0.02em",
134
153
  margin: 0,
135
- lineHeight: 1.3,
136
- wordBreak: "break-word"
154
+ lineHeight: 1.25,
155
+ color: "var(--sb-color-text, #1a1d21)"
137
156
  };
138
- var updatedAt = {
139
- fontSize: "11px",
140
- color: "var(--sxl-muted, #8e8ea0)",
141
- fontWeight: 400
157
+ var metaCol = {
158
+ display: "flex",
159
+ flexDirection: "column",
160
+ alignItems: "flex-end",
161
+ gap: "8px",
162
+ flexShrink: 0,
163
+ maxWidth: "52%"
142
164
  };
143
- var figmaButton = {
144
- display: "inline-flex",
145
- alignItems: "center",
146
- gap: "6px",
147
- padding: "6px 14px",
148
- borderRadius: "8px",
149
- border: "1px solid var(--sxl-border, #e0e0e8)",
150
- backgroundColor: "var(--sxl-bg, #fff)",
151
- color: "var(--sxl-link, #18a0fb)",
152
- fontSize: "12px",
153
- fontWeight: 600,
154
- fontFamily: FONT,
155
- textDecoration: "none",
156
- cursor: "pointer",
157
- whiteSpace: "nowrap",
158
- transition: "all 120ms ease",
159
- flexShrink: 0
165
+ var dateText = {
166
+ fontSize: "11px",
167
+ fontWeight: 500,
168
+ color: "var(--sb-color-text-muted, var(--sb-text-secondary, #6b7280))"
160
169
  };
161
170
  var badgeRow = {
162
171
  display: "flex",
163
172
  flexWrap: "wrap",
164
- gap: "8px"
173
+ gap: "6px",
174
+ justifyContent: "flex-end"
165
175
  };
166
- var badge = {
176
+ var badgeBase = {
167
177
  display: "inline-flex",
168
178
  alignItems: "center",
169
- gap: "6px",
170
179
  padding: "4px 10px",
171
180
  borderRadius: "6px",
172
181
  fontSize: "11px",
173
182
  fontWeight: 600,
174
- lineHeight: 1
175
- };
176
- var badgeDot = {
177
- width: "7px",
178
- height: "7px",
179
- borderRadius: "50%",
180
- flexShrink: 0
183
+ lineHeight: 1.2
181
184
  };
182
- var card = {
183
- padding: "14px 16px",
184
- borderRadius: "10px",
185
- backgroundColor: "var(--sxl-card-bg, #f8f8fb)",
186
- border: "1px solid var(--sxl-border, #ebebf0)"
185
+ var section = {
186
+ marginBottom: "14px"
187
187
  };
188
- var cardTitle = {
188
+ var sectionLabel = {
189
189
  fontSize: "10px",
190
190
  fontWeight: 700,
191
191
  textTransform: "uppercase",
192
- letterSpacing: "0.8px",
193
- color: "var(--sxl-muted, #8e8ea0)",
194
- marginBottom: "10px"
192
+ letterSpacing: "0.06em",
193
+ color: "var(--sb-color-text-muted, #6b7280)",
194
+ marginBottom: "8px"
195
195
  };
196
- var row = {
197
- display: "flex",
198
- alignItems: "baseline",
199
- gap: "8px",
200
- marginBottom: "6px"
201
- };
202
- var rowLabel = {
203
- fontSize: "12px",
204
- fontWeight: 500,
205
- color: "var(--sxl-label, #6b6b80)",
206
- minWidth: "80px",
207
- flexShrink: 0
208
- };
209
- var rowValue = {
210
- fontSize: "13px",
211
- color: "var(--sxl-text, #1a1a2e)",
212
- wordBreak: "break-word"
213
- };
214
- var mono = {
215
- fontFamily: MONO,
216
- fontSize: "12px"
196
+ var card = {
197
+ padding: "12px 14px",
198
+ borderRadius: "10px",
199
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.08))",
200
+ border: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.08))"
217
201
  };
218
202
  var descriptionText = {
219
203
  fontSize: "13px",
220
- color: "var(--sxl-text, #3a3a4a)",
221
- lineHeight: 1.6,
222
- margin: 0
204
+ lineHeight: 1.55,
205
+ margin: 0,
206
+ color: "var(--sb-color-text, inherit)"
223
207
  };
224
208
  var embedWrap = {
225
209
  borderRadius: "10px",
226
210
  overflow: "hidden",
227
- border: "1px solid var(--sxl-border, #ebebf0)"
211
+ border: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.1))",
212
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.06))"
228
213
  };
229
214
  var iframe = {
230
215
  width: "100%",
231
- height: "380px",
216
+ minHeight: "360px",
217
+ height: "min(50vh, 420px)",
232
218
  border: "none",
233
- display: "block"
219
+ display: "block",
220
+ backgroundColor: "var(--sb-color-bg-panel, #fff)"
234
221
  };
235
- var embedActions = {
222
+ var embedFooter = {
236
223
  display: "flex",
237
224
  justifyContent: "flex-end",
238
225
  padding: "8px 12px",
239
- borderTop: "1px solid var(--sxl-border, #ebebf0)",
240
- backgroundColor: "var(--sxl-card-bg, #f8f8fb)"
226
+ borderTop: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.08))",
227
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.04))"
241
228
  };
242
- var embedLink = {
229
+ var link = {
243
230
  fontSize: "11px",
244
231
  fontWeight: 600,
245
- color: "var(--sxl-link, #18a0fb)",
232
+ color: "var(--sb-color-accent, #1a73e8)",
246
233
  textDecoration: "none"
247
234
  };
248
- var tagList = {
235
+ var codeToolbar = {
249
236
  display: "flex",
250
- flexWrap: "wrap",
251
- gap: "6px"
237
+ justifyContent: "flex-end",
238
+ marginBottom: "6px"
252
239
  };
253
- var tag = {
240
+ var copyBtn = {
254
241
  fontSize: "11px",
255
- fontFamily: MONO,
256
- backgroundColor: "var(--sxl-tag-bg, #eef0ff)",
257
- color: "var(--sxl-tag-text, #3d4a8c)",
258
- padding: "3px 8px",
259
- borderRadius: "5px",
260
- fontWeight: 500
261
- };
262
- var frameworkTag = {
263
- fontSize: "10px",
264
- fontFamily: FONT,
265
- fontWeight: 700,
266
- textTransform: "uppercase",
267
- letterSpacing: "0.4px",
268
- backgroundColor: "var(--sxl-fw-bg, #e8faf0)",
269
- color: "var(--sxl-fw-text, #1a7a4c)",
270
- padding: "2px 7px",
271
- borderRadius: "4px"
242
+ fontWeight: 600,
243
+ padding: "4px 10px",
244
+ borderRadius: "6px",
245
+ border: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.12))",
246
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.08))",
247
+ color: "var(--sb-color-text, inherit)",
248
+ cursor: "pointer",
249
+ fontFamily: FONT
272
250
  };
273
251
  var codeBlock = {
274
252
  fontFamily: MONO,
275
253
  fontSize: "11px",
276
- backgroundColor: "var(--sxl-code-bg, #f3f3f8)",
277
- border: "1px solid var(--sxl-border, #ebebf0)",
278
- borderRadius: "8px",
254
+ lineHeight: 1.55,
255
+ margin: 0,
279
256
  padding: "12px 14px",
257
+ borderRadius: "8px",
280
258
  overflow: "auto",
281
- lineHeight: 1.65,
259
+ maxHeight: "min(55vh, 520px)",
282
260
  whiteSpace: "pre",
283
- margin: 0
261
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.12))",
262
+ border: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.08))",
263
+ color: "var(--sb-color-text, inherit)"
264
+ };
265
+ var apiTable = {
266
+ width: "100%",
267
+ borderCollapse: "collapse",
268
+ fontSize: "12px"
269
+ };
270
+ var apiTh = {
271
+ textAlign: "left",
272
+ padding: "6px 8px",
273
+ borderBottom: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.1))",
274
+ color: "var(--sb-color-text-muted, #6b7280)",
275
+ fontWeight: 600
276
+ };
277
+ var apiTd = {
278
+ padding: "6px 8px",
279
+ borderBottom: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.06))",
280
+ verticalAlign: "top"
281
+ };
282
+ var apiMono = {
283
+ fontFamily: MONO,
284
+ fontSize: "11px"
284
285
  };
285
286
  var emptyContainer = {
286
287
  display: "flex",
@@ -288,42 +289,58 @@ var emptyContainer = {
288
289
  alignItems: "center",
289
290
  justifyContent: "center",
290
291
  height: "100%",
291
- padding: "40px 20px",
292
+ padding: "32px 20px",
292
293
  fontFamily: FONT,
293
- textAlign: "center"
294
+ textAlign: "center",
295
+ color: "var(--sb-color-text, inherit)"
294
296
  };
295
297
  var emptyTitle = {
296
298
  fontSize: "15px",
297
299
  fontWeight: 600,
298
- color: "var(--sxl-text, #3a3a4a)",
299
300
  marginBottom: "8px",
300
301
  marginTop: 0
301
302
  };
302
303
  var emptyHint = {
303
304
  fontSize: "12px",
304
- color: "var(--sxl-muted, #8e8ea0)",
305
+ color: "var(--sb-color-text-muted, #6b7280)",
305
306
  marginBottom: "12px",
306
- marginTop: 0
307
+ marginTop: 0,
308
+ maxWidth: "360px"
307
309
  };
308
310
  var emptyCode = {
309
311
  fontFamily: MONO,
310
312
  fontSize: "11px",
311
- backgroundColor: "var(--sxl-code-bg, #f3f3f8)",
312
- padding: "2px 5px",
313
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.1))",
314
+ padding: "2px 6px",
313
315
  borderRadius: "4px"
314
316
  };
317
+ var figmaBtn = {
318
+ display: "inline-flex",
319
+ alignItems: "center",
320
+ gap: "6px",
321
+ marginTop: "10px",
322
+ padding: "6px 12px",
323
+ borderRadius: "8px",
324
+ border: "1px solid var(--sb-color-border, rgba(0, 0, 0, 0.12))",
325
+ backgroundColor: "var(--sb-color-bg-panel, rgba(128, 128, 128, 0.08))",
326
+ color: "var(--sb-color-accent, #1a73e8)",
327
+ fontSize: "12px",
328
+ fontWeight: 600,
329
+ textDecoration: "none"
330
+ };
331
+ var nodeFoot = {
332
+ fontSize: "10px",
333
+ color: "var(--sb-color-text-muted, #9ca3af)",
334
+ textAlign: "right",
335
+ marginTop: "8px"
336
+ };
315
337
 
316
338
  // src/components/SxlPanel.tsx
317
- var TOKEN_MAP = {
318
- assigned: { label: "Tokens", fg: "#166534", bg: "#dcfce7", dot: "#22c55e" },
319
- partial: { label: "Tokens (partial)", fg: "#92400e", bg: "#fef3c7", dot: "#f59e0b" },
320
- none: { label: "No tokens", fg: "#6b7280", bg: "#f3f4f6", dot: "#9ca3af" }
321
- };
322
- var READINESS_MAP = {
323
- "complete": { label: "Complete", fg: "#166534", bg: "#dcfce7", dot: "#22c55e" },
324
- "ready-for-dev": { label: "Ready for Dev", fg: "#1e40af", bg: "#dbeafe", dot: "#3b82f6" },
325
- "in-progress": { label: "In Progress", fg: "#92400e", bg: "#fef3c7", dot: "#f59e0b" },
326
- "backlog": { label: "Backlog", fg: "#6b7280", bg: "#f3f4f6", dot: "#9ca3af" }
339
+ var READINESS_BADGE = {
340
+ backlog: { label: "Backlog", bg: "#111827", fg: "#f9fafb" },
341
+ "in-progress": { label: "In Progress", bg: "#ea580c", fg: "#ffffff" },
342
+ "ready-for-dev": { label: "Ready for Dev", bg: "#16a34a", fg: "#ffffff" },
343
+ complete: { label: "Completed", bg: "#9ca3af", fg: "#111827" }
327
344
  };
328
345
  function normalizeRegistry(raw) {
329
346
  if (!raw || typeof raw !== "object") return null;
@@ -356,7 +373,10 @@ function resolveEntry(params, ctx) {
356
373
  designEmbed: params.designEmbed ?? !!params.figmaUrl,
357
374
  compositionJson: params.compositionJson,
358
375
  metadata: params.metadata,
359
- meta: { tokenStatus: params.tokenStatus, readiness: params.readiness }
376
+ meta: {
377
+ tokensBool: params.tokensBool,
378
+ readiness: params.readiness
379
+ }
360
380
  }
361
381
  };
362
382
  }
@@ -387,13 +407,15 @@ function resolveEntry(params, ctx) {
387
407
  ...found,
388
408
  meta: {
389
409
  ...found.meta,
390
- tokenStatus: params.tokenStatus ?? found.meta?.tokenStatus,
410
+ tokensBool: params.tokensBool ?? found.meta?.tokensBool,
391
411
  readiness: params.readiness ?? found.meta?.readiness
392
412
  },
393
413
  description: params.description ?? found.description,
394
414
  compositionJson: params.compositionJson ?? found.compositionJson,
395
415
  metadata: params.metadata ?? found.metadata,
396
- designEmbed: params.designEmbed ?? found.designEmbed
416
+ designEmbed: params.designEmbed ?? found.designEmbed,
417
+ compositionSnapshot: found.compositionSnapshot,
418
+ componentApi: found.componentApi
397
419
  }
398
420
  };
399
421
  }
@@ -410,12 +432,12 @@ function matchByStoryContext(entries, ctx) {
410
432
  let bestScore = 0;
411
433
  let tie = false;
412
434
  for (const entry of entries) {
413
- const s = score(entry, tokens);
414
- if (s > bestScore) {
415
- bestScore = s;
435
+ const sc = score(entry, tokens);
436
+ if (sc > bestScore) {
437
+ bestScore = sc;
416
438
  best = entry;
417
439
  tie = false;
418
- } else if (s === bestScore && s > 0) {
440
+ } else if (sc === bestScore && sc > 0) {
419
441
  tie = true;
420
442
  }
421
443
  }
@@ -469,7 +491,7 @@ function buildDevModeUrl(figmaUrl) {
469
491
  function formatDate(iso) {
470
492
  if (!iso) return null;
471
493
  try {
472
- return new Intl.DateTimeFormat("en-US", {
494
+ return new Intl.DateTimeFormat(void 0, {
473
495
  month: "short",
474
496
  day: "numeric",
475
497
  year: "numeric",
@@ -480,12 +502,50 @@ function formatDate(iso) {
480
502
  return iso;
481
503
  }
482
504
  }
483
- var Badge = ({
484
- label,
485
- fg,
486
- bg,
487
- dot
488
- }) => /* @__PURE__ */ React.createElement("span", { style: { ...badge, color: fg, backgroundColor: bg } }, /* @__PURE__ */ React.createElement("span", { style: { ...badgeDot, backgroundColor: dot } }), label);
505
+ function resolveTokensBool(entry, params) {
506
+ const p = params?.tokensBool ?? entry.meta?.tokensBool;
507
+ if (p === "true" || p === "false") return p;
508
+ if (entry.meta?.tokenStatus === "assigned") return "true";
509
+ return "false";
510
+ }
511
+ function formatJsonSnapshot(raw) {
512
+ if (!raw) return "";
513
+ try {
514
+ return JSON.stringify(JSON.parse(raw), null, 2);
515
+ } catch {
516
+ return raw;
517
+ }
518
+ }
519
+ var TokensBadge = ({ value }) => {
520
+ const on = value === "true";
521
+ return /* @__PURE__ */ React.createElement(
522
+ "span",
523
+ {
524
+ style: {
525
+ ...badgeBase,
526
+ backgroundColor: on ? "#dcfce7" : "#e5e7eb",
527
+ color: on ? "#166534" : "#6b7280",
528
+ border: `1px solid ${on ? "#bbf7d0" : "#d1d5db"}`
529
+ }
530
+ },
531
+ "Tokens \u2014 ",
532
+ on ? "True" : "False"
533
+ );
534
+ };
535
+ var ReadinessBadge = ({ readiness }) => {
536
+ const b = READINESS_BADGE[readiness];
537
+ return /* @__PURE__ */ React.createElement(
538
+ "span",
539
+ {
540
+ style: {
541
+ ...badgeBase,
542
+ backgroundColor: b.bg,
543
+ color: b.fg
544
+ }
545
+ },
546
+ b.label
547
+ );
548
+ };
489
549
  var NoRegistryState = () => /* @__PURE__ */ React.createElement("div", { style: emptyContainer }, /* @__PURE__ */ React.createElement("p", { style: emptyTitle }, "SXL Studio not configured"), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, "Import the registry in ", /* @__PURE__ */ React.createElement("code", { style: emptyCode }, ".storybook/preview.ts"), ":"), /* @__PURE__ */ React.createElement("pre", { style: codeBlock }, `import registry from '../diff-code-connect.YOUR_FILE_KEY.json';
490
550
 
491
551
  export default {
@@ -493,7 +553,10 @@ export default {
493
553
  sxl: { registry },
494
554
  },
495
555
  };`));
496
- var NoMatchState = ({ componentHint }) => /* @__PURE__ */ React.createElement("div", { style: emptyContainer }, /* @__PURE__ */ React.createElement("p", { style: emptyTitle }, "No Figma integration for this component"), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, componentHint ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("strong", null, componentHint), " has not been linked in the SXL Studio Figma plugin.") : /* @__PURE__ */ React.createElement(React.Fragment, null, "This story has not been linked to a Figma component.")), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, "To add integration, open the component in Figma, go to ", /* @__PURE__ */ React.createElement("strong", null, "Code \u2192 Storybook Integration"), ", and click ", /* @__PURE__ */ React.createElement("strong", null, "Connect"), "."));
556
+ var NoMatchState = ({ componentHint }) => /* @__PURE__ */ React.createElement("div", { style: emptyContainer }, /* @__PURE__ */ React.createElement("p", { style: emptyTitle }, "No Figma integration for this component"), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, componentHint ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("strong", null, componentHint), " has not been linked in the SXL Studio Figma plugin.") : /* @__PURE__ */ React.createElement(React.Fragment, null, "This story has not been linked to a Figma component.")), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, "In Figma: ", /* @__PURE__ */ React.createElement("strong", null, "Code \u2192 Storybook Integration \u2192 Connect"), "."));
557
+ function ApiTable({ props }) {
558
+ return /* @__PURE__ */ React.createElement("table", { style: apiTable }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", { style: apiTh }, "Name"), /* @__PURE__ */ React.createElement("th", { style: apiTh }, "Kind"), /* @__PURE__ */ React.createElement("th", { style: apiTh }, "Default / options"))), /* @__PURE__ */ React.createElement("tbody", null, props.map((p) => /* @__PURE__ */ React.createElement("tr", { key: p.name + p.kind }, /* @__PURE__ */ React.createElement("td", { style: apiTd }, /* @__PURE__ */ React.createElement("span", { style: apiMono }, p.name)), /* @__PURE__ */ React.createElement("td", { style: apiTd }, p.kind), /* @__PURE__ */ React.createElement("td", { style: { ...apiTd, ...apiMono } }, p.defaultValue !== void 0 ? String(p.defaultValue) : "\u2014", p.options?.length ? ` \xB7 ${p.options.join(", ")}` : "")))));
559
+ }
497
560
  var SxlPanel = () => {
498
561
  const params = useParameter(PARAM_KEY);
499
562
  const state = useStorybookState();
@@ -505,51 +568,104 @@ var SxlPanel = () => {
505
568
  importPath: selected?.importPath ?? ""
506
569
  };
507
570
  const result = resolveEntry(params, ctx);
571
+ const [copyState, setCopyState] = useState("idle");
572
+ const copyJson = useCallback(async (text) => {
573
+ try {
574
+ await navigator.clipboard.writeText(text);
575
+ setCopyState("ok");
576
+ setTimeout(() => setCopyState("idle"), 2e3);
577
+ } catch {
578
+ setCopyState("err");
579
+ setTimeout(() => setCopyState("idle"), 2500);
580
+ }
581
+ }, []);
508
582
  if (result.status === "no-registry") {
509
583
  return React.createElement(NoRegistryState, null);
510
584
  }
511
585
  if (result.status === "no-match") {
512
- return React.createElement(NoMatchState, { componentHint: result.componentHint });
586
+ return React.createElement(NoMatchState, {
587
+ componentHint: result.componentHint
588
+ });
513
589
  }
514
590
  const entry = result.entry;
515
- const tokenStatus = entry.meta?.tokenStatus;
591
+ const tokensBool = resolveTokensBool(entry, params);
516
592
  const readiness = entry.meta?.readiness;
517
- const tokenInfo = tokenStatus ? TOKEN_MAP[tokenStatus] : null;
518
- const readinessInfo = readiness ? READINESS_MAP[readiness] : null;
519
593
  const dateStr = formatDate(entry.updatedAt);
520
- const hasProps = !!entry.meta?.componentProperties?.length;
521
- const hasFiles = !!entry.files?.length;
522
- const hasBadges = !!(tokenInfo || readinessInfo);
523
- return /* @__PURE__ */ React.createElement("div", { style: root }, /* @__PURE__ */ React.createElement("div", { style: header }, /* @__PURE__ */ React.createElement("div", { style: headerLeft }, entry.displayName && /* @__PURE__ */ React.createElement("h2", { style: componentName }, entry.displayName), dateStr && /* @__PURE__ */ React.createElement("span", { style: updatedAt }, "Updated ", dateStr)), entry.figmaUrl && /* @__PURE__ */ React.createElement(
524
- "a",
525
- {
526
- href: buildDevModeUrl(entry.figmaUrl),
527
- target: "_blank",
528
- rel: "noopener noreferrer",
529
- style: figmaButton
530
- },
531
- /* @__PURE__ */ React.createElement(FigmaIcon, null),
532
- "Open in Figma"
533
- )), hasBadges && /* @__PURE__ */ React.createElement("div", { style: badgeRow }, tokenInfo && /* @__PURE__ */ React.createElement(Badge, { ...tokenInfo }), readinessInfo && /* @__PURE__ */ React.createElement(Badge, { ...readinessInfo })), entry.description && /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("div", { style: cardTitle }, "Description"), /* @__PURE__ */ React.createElement("p", { style: descriptionText }, entry.description)), entry.figmaUrl && entry.designEmbed !== false && /* @__PURE__ */ React.createElement("div", { style: embedWrap }, /* @__PURE__ */ React.createElement(
594
+ const showEmbed = !!entry.figmaUrl && entry.designEmbed !== false;
595
+ const showComposition = entry.compositionJson && !!entry.compositionSnapshot && entry.compositionSnapshot.trim().length > 0;
596
+ const apiProps = entry.componentApi?.properties;
597
+ const formattedJson = formatJsonSnapshot(entry.compositionSnapshot);
598
+ return /* @__PURE__ */ React.createElement("div", { style: panelRoot }, /* @__PURE__ */ React.createElement("div", { style: topRow }, /* @__PURE__ */ React.createElement("div", { style: titleBlock }, entry.displayName ? /* @__PURE__ */ React.createElement("h2", { style: componentName }, entry.displayName) : null), /* @__PURE__ */ React.createElement("div", { style: metaCol }, dateStr ? /* @__PURE__ */ React.createElement("div", { style: dateText }, "Updated ", dateStr) : null, /* @__PURE__ */ React.createElement("div", { style: badgeRow }, /* @__PURE__ */ React.createElement(TokensBadge, { value: tokensBool }), readiness ? /* @__PURE__ */ React.createElement(ReadinessBadge, { readiness }) : null))), entry.description ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement("div", { style: sectionLabel }, "Description"), /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("p", { style: descriptionText }, entry.description))) : null, showEmbed ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement("div", { style: sectionLabel }, "Embed"), /* @__PURE__ */ React.createElement("div", { style: embedWrap }, /* @__PURE__ */ React.createElement(
534
599
  "iframe",
535
600
  {
536
- title: "Figma Design",
601
+ title: "Figma embed",
537
602
  src: buildEmbedUrl(entry.figmaUrl),
538
603
  style: iframe,
539
- allowFullScreen: true
604
+ allowFullScreen: true,
605
+ loading: "lazy",
606
+ referrerPolicy: "strict-origin-when-cross-origin",
607
+ sandbox: "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-forms allow-presentation"
540
608
  }
541
- ), /* @__PURE__ */ React.createElement("div", { style: embedActions }, /* @__PURE__ */ React.createElement(
609
+ ), /* @__PURE__ */ React.createElement("div", { style: embedFooter }, /* @__PURE__ */ React.createElement(
542
610
  "a",
543
611
  {
544
612
  href: buildDevModeUrl(entry.figmaUrl),
545
613
  target: "_blank",
546
614
  rel: "noopener noreferrer",
547
- style: embedLink
615
+ style: link
548
616
  },
549
617
  "Open in Figma Dev Mode \u2192"
550
- ))), (hasProps || entry.meta?.variantCount != null) && /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("div", { style: cardTitle }, "API Contract"), hasProps && /* @__PURE__ */ React.createElement("div", { style: row }, /* @__PURE__ */ React.createElement("span", { style: rowLabel }, "Props"), /* @__PURE__ */ React.createElement("span", { style: tagList }, entry.meta.componentProperties.map((p) => /* @__PURE__ */ React.createElement("span", { key: p, style: tag }, p)))), entry.meta?.variantCount != null && /* @__PURE__ */ React.createElement("div", { style: row }, /* @__PURE__ */ React.createElement("span", { style: rowLabel }, "Variants"), /* @__PURE__ */ React.createElement("span", { style: rowValue }, entry.meta.variantCount))), (entry.importPath || hasFiles || entry.snippetTemplate) && /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("div", { style: cardTitle }, "Code Connect"), entry.importPath && /* @__PURE__ */ React.createElement("div", { style: row }, /* @__PURE__ */ React.createElement("span", { style: rowLabel }, "Import"), /* @__PURE__ */ React.createElement("span", { style: { ...rowValue, ...mono } }, entry.importPath)), hasFiles && /* @__PURE__ */ React.createElement("div", { style: row }, /* @__PURE__ */ React.createElement("span", { style: rowLabel }, "Files"), /* @__PURE__ */ React.createElement("span", { style: tagList }, entry.files.map((f) => /* @__PURE__ */ React.createElement("span", { key: f.filePath, style: { display: "inline-flex", alignItems: "center", gap: "4px" } }, /* @__PURE__ */ React.createElement("span", { style: frameworkTag }, f.framework), /* @__PURE__ */ React.createElement("span", { style: { ...rowValue, ...mono, fontSize: "11px" } }, f.filePath))))), entry.snippetTemplate && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { style: { ...cardTitle, marginTop: "10px", marginBottom: "6px" } }, "Snippet Template"), /* @__PURE__ */ React.createElement("pre", { style: codeBlock }, entry.snippetTemplate))), entry.compositionJson && /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: cardTitle }, "Composition JSON"), /* @__PURE__ */ React.createElement(Badge, { label: "Enabled", fg: "#166534", bg: "#dcfce7", dot: "#22c55e" }))), entry.nodeId && /* @__PURE__ */ React.createElement("div", { style: { fontSize: "10px", color: "var(--sxl-muted, #b0b0b8)", textAlign: "right" } }, "Node: ", entry.nodeId));
618
+ )))) : entry.figmaUrl ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement(
619
+ "a",
620
+ {
621
+ href: buildDevModeUrl(entry.figmaUrl),
622
+ target: "_blank",
623
+ rel: "noopener noreferrer",
624
+ style: figmaBtn
625
+ },
626
+ /* @__PURE__ */ React.createElement(FigmaIcon, null),
627
+ " Open in Figma"
628
+ )) : null, entry.compositionJson ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement("div", { style: sectionLabel }, "Composition JSON"), showComposition ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { style: codeToolbar }, /* @__PURE__ */ React.createElement(
629
+ "button",
630
+ {
631
+ type: "button",
632
+ style: copyBtn,
633
+ onClick: () => void copyJson(formattedJson)
634
+ },
635
+ copyState === "ok" ? "Copied" : copyState === "err" ? "Copy failed" : "Copy JSON"
636
+ )), /* @__PURE__ */ React.createElement("pre", { style: codeBlock }, formattedJson)) : /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement("p", { style: { ...descriptionText, margin: 0 } }, "No composition snapshot in the registry yet. In the SXL Studio plugin, enable Composition JSON and select a composition file (or use Generate on the node), then push ", /* @__PURE__ */ React.createElement("code", { style: emptyCode }, "diff-code-connect"), "."))) : null, apiProps && apiProps.length > 0 ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement("div", { style: sectionLabel }, "API"), /* @__PURE__ */ React.createElement("div", { style: card }, /* @__PURE__ */ React.createElement(ApiTable, { props: apiProps }))) : null, entry.importPath || entry.snippetTemplate || entry.files && entry.files.length > 0 ? /* @__PURE__ */ React.createElement("div", { style: section }, /* @__PURE__ */ React.createElement("div", { style: sectionLabel }, "Code Connect"), /* @__PURE__ */ React.createElement("div", { style: card }, entry.importPath ? /* @__PURE__ */ React.createElement("p", { style: { ...descriptionText, margin: "0 0 8px" } }, /* @__PURE__ */ React.createElement("strong", null, "Import:"), " ", /* @__PURE__ */ React.createElement("span", { style: apiMono }, entry.importPath)) : null, entry.files?.map((f) => /* @__PURE__ */ React.createElement("p", { key: f.filePath, style: { ...descriptionText, margin: "4px 0" } }, /* @__PURE__ */ React.createElement("strong", null, f.framework, ":"), " ", /* @__PURE__ */ React.createElement("span", { style: apiMono }, f.filePath))), entry.snippetTemplate ? /* @__PURE__ */ React.createElement("pre", { style: { ...codeBlock, marginTop: "10px" } }, entry.snippetTemplate) : null)) : null, entry.nodeId ? /* @__PURE__ */ React.createElement("div", { style: nodeFoot }, "Node: ", entry.nodeId) : null);
551
637
  };
552
- var FigmaIcon = () => /* @__PURE__ */ React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 38 57", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement("path", { d: "M19 28.5C19 23.2533 23.2533 19 28.5 19C33.7467 19 38 23.2533 38 28.5C38 33.7467 33.7467 38 28.5 38C23.2533 38 19 33.7467 19 28.5Z", fill: "#1ABCFE" }), /* @__PURE__ */ React.createElement("path", { d: "M0 47.5C0 42.2533 4.25329 38 9.5 38H19V47.5C19 52.7467 14.7467 57 9.5 57C4.25329 57 0 52.7467 0 47.5Z", fill: "#0ACF83" }), /* @__PURE__ */ React.createElement("path", { d: "M19 0V19H28.5C33.7467 19 38 14.7467 38 9.5C38 4.25329 33.7467 0 28.5 0H19Z", fill: "#FF7262" }), /* @__PURE__ */ React.createElement("path", { d: "M0 9.5C0 14.7467 4.25329 19 9.5 19H19V0H9.5C4.25329 0 0 4.25329 0 9.5Z", fill: "#F24E1E" }), /* @__PURE__ */ React.createElement("path", { d: "M0 28.5C0 33.7467 4.25329 38 9.5 38H19V19H9.5C4.25329 19 0 23.2533 0 28.5Z", fill: "#A259FF" }));
638
+ var FigmaIcon = () => /* @__PURE__ */ React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 38 57", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement(
639
+ "path",
640
+ {
641
+ d: "M19 28.5C19 23.2533 23.2533 19 28.5 19C33.7467 19 38 23.2533 38 28.5C38 33.7467 33.7467 38 28.5 38C23.2533 38 19 33.7467 19 28.5Z",
642
+ fill: "#1ABCFE"
643
+ }
644
+ ), /* @__PURE__ */ React.createElement(
645
+ "path",
646
+ {
647
+ d: "M0 47.5C0 42.2533 4.25329 38 9.5 38H19V47.5C19 52.7467 14.7467 57 9.5 57C4.25329 57 0 52.7467 0 47.5Z",
648
+ fill: "#0ACF83"
649
+ }
650
+ ), /* @__PURE__ */ React.createElement(
651
+ "path",
652
+ {
653
+ d: "M19 0V19H28.5C33.7467 19 38 14.7467 38 9.5C38 4.25329 33.7467 0 28.5 0H19Z",
654
+ fill: "#FF7262"
655
+ }
656
+ ), /* @__PURE__ */ React.createElement(
657
+ "path",
658
+ {
659
+ d: "M0 9.5C0 14.7467 4.25329 19 9.5 19H19V0H9.5C4.25329 0 0 4.25329 0 9.5Z",
660
+ fill: "#F24E1E"
661
+ }
662
+ ), /* @__PURE__ */ React.createElement(
663
+ "path",
664
+ {
665
+ d: "M0 28.5C0 33.7467 4.25329 38 9.5 38H19V19H9.5C4.25329 19 0 23.2533 0 28.5Z",
666
+ fill: "#A259FF"
667
+ }
668
+ ));
553
669
 
554
670
  // src/manager.tsx
555
671
  var REGISTRY_GUARD_KEY = "__sxlStudioAddonRegistered__";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sxl-studio/storybook-addon",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Storybook addon for SXL Studio — displays Figma Embed, component info and design token status for linked components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",