@sxl-studio/storybook-addon 1.0.6 → 1.0.7
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 +24 -1
- package/dist/index.js +11 -0
- package/dist/manager.js +245 -139
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,13 @@ type SxlRegistryMeta = {
|
|
|
13
13
|
tokenStatus?: SxlTokenStatus;
|
|
14
14
|
readiness?: SxlReadiness;
|
|
15
15
|
};
|
|
16
|
+
/** File binding from Code Connect (per-framework). */
|
|
17
|
+
type SxlFileBinding = {
|
|
18
|
+
framework: string;
|
|
19
|
+
filePath: string;
|
|
20
|
+
componentName?: string;
|
|
21
|
+
importPath?: string;
|
|
22
|
+
};
|
|
16
23
|
/** One component entry inside the registry. */
|
|
17
24
|
type SxlRegistryEntry = {
|
|
18
25
|
nodeId: string;
|
|
@@ -23,6 +30,14 @@ type SxlRegistryEntry = {
|
|
|
23
30
|
designEmbed?: boolean;
|
|
24
31
|
compositionJson?: boolean;
|
|
25
32
|
metadata?: boolean;
|
|
33
|
+
/** ISO timestamp when the entry was last updated. */
|
|
34
|
+
updatedAt?: string;
|
|
35
|
+
/** Primary import path for the component. */
|
|
36
|
+
importPath?: string;
|
|
37
|
+
/** Snippet template for code generation. */
|
|
38
|
+
snippetTemplate?: string;
|
|
39
|
+
/** Per-framework file bindings. */
|
|
40
|
+
files?: SxlFileBinding[];
|
|
26
41
|
meta?: SxlRegistryMeta;
|
|
27
42
|
};
|
|
28
43
|
/**
|
|
@@ -43,6 +58,8 @@ type SxlRegistry = {
|
|
|
43
58
|
type SxlStoryParameters = {
|
|
44
59
|
/** Explicit match by display name from the registry. */
|
|
45
60
|
component?: string;
|
|
61
|
+
/** Alias for `component` (backward compat). */
|
|
62
|
+
componentName?: string;
|
|
46
63
|
/** Explicit match by Figma node ID. */
|
|
47
64
|
figmaNodeId?: string;
|
|
48
65
|
/** Direct Figma design URL (overrides registry lookup). */
|
|
@@ -53,6 +70,12 @@ type SxlStoryParameters = {
|
|
|
53
70
|
tokenStatus?: SxlTokenStatus;
|
|
54
71
|
/** Override readiness per-story. */
|
|
55
72
|
readiness?: SxlReadiness;
|
|
73
|
+
/** Override designEmbed per-story. */
|
|
74
|
+
designEmbed?: boolean;
|
|
75
|
+
/** Override compositionJson per-story. */
|
|
76
|
+
compositionJson?: boolean;
|
|
77
|
+
/** Override metadata per-story. */
|
|
78
|
+
metadata?: boolean;
|
|
56
79
|
/** Registry data (typically set globally in preview.ts). */
|
|
57
80
|
registry?: SxlRegistry;
|
|
58
81
|
};
|
|
@@ -72,4 +95,4 @@ type SxlStoryParameters = {
|
|
|
72
95
|
*/
|
|
73
96
|
declare function fromDiffCodeConnect(data: unknown): SxlRegistry;
|
|
74
97
|
|
|
75
|
-
export { ADDON_ID, PANEL_ID, PARAM_KEY, type SxlReadiness, type SxlRegistry, type SxlRegistryEntry, type SxlRegistryMeta, type SxlStoryParameters, type SxlTokenStatus, fromDiffCodeConnect };
|
|
98
|
+
export { ADDON_ID, PANEL_ID, PARAM_KEY, type SxlFileBinding, type SxlReadiness, type SxlRegistry, type SxlRegistryEntry, type SxlRegistryMeta, type SxlStoryParameters, type SxlTokenStatus, fromDiffCodeConnect };
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,13 @@ function fromDiffCodeConnect(data) {
|
|
|
24
24
|
const tokenStatus = sb.tokensReady === true ? "assigned" : void 0;
|
|
25
25
|
const statusRaw = typeof sb.status === "string" ? sb.status : void 0;
|
|
26
26
|
const readiness = statusRaw === "complete" || statusRaw === "ready-for-dev" || statusRaw === "in-progress" || statusRaw === "backlog" ? statusRaw : void 0;
|
|
27
|
+
const rawFiles = Array.isArray(b.files) ? b.files : [];
|
|
28
|
+
const files = rawFiles.filter((f) => !!f && typeof f === "object").map((f) => ({
|
|
29
|
+
framework: String(f.framework ?? ""),
|
|
30
|
+
filePath: String(f.filePath ?? ""),
|
|
31
|
+
...f.componentName ? { componentName: String(f.componentName) } : {},
|
|
32
|
+
...f.importPath ? { importPath: String(f.importPath) } : {}
|
|
33
|
+
}));
|
|
27
34
|
return {
|
|
28
35
|
nodeId,
|
|
29
36
|
displayName: String(b.displayName ?? e.nodeName ?? ""),
|
|
@@ -32,6 +39,10 @@ function fromDiffCodeConnect(data) {
|
|
|
32
39
|
designEmbed: sb.designEmbed === true,
|
|
33
40
|
compositionJson: sb.compositionJson === true,
|
|
34
41
|
metadata: sb.metadata === true,
|
|
42
|
+
updatedAt: typeof e.updatedAt === "string" ? e.updatedAt : void 0,
|
|
43
|
+
importPath: typeof b.importPath === "string" ? b.importPath : void 0,
|
|
44
|
+
snippetTemplate: typeof b.snippetTemplate === "string" ? b.snippetTemplate : void 0,
|
|
45
|
+
files: files.length > 0 ? files : void 0,
|
|
35
46
|
meta: {
|
|
36
47
|
...tokenStatus ? { tokenStatus } : {},
|
|
37
48
|
...readiness ? { readiness } : {}
|
package/dist/manager.js
CHANGED
|
@@ -12,147 +12,230 @@ import React from "react";
|
|
|
12
12
|
import { useParameter } from "@storybook/manager-api";
|
|
13
13
|
|
|
14
14
|
// src/components/styles.ts
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
padding: "
|
|
19
|
-
fontFamily:
|
|
15
|
+
var FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
|
|
16
|
+
var MONO = "'SF Mono', 'Fira Code', 'Cascadia Code', Menlo, monospace";
|
|
17
|
+
var root = {
|
|
18
|
+
padding: "20px",
|
|
19
|
+
fontFamily: FONT,
|
|
20
20
|
fontSize: "13px",
|
|
21
|
-
lineHeight: 1.
|
|
22
|
-
color: "var(--sxl-text, #
|
|
21
|
+
lineHeight: 1.55,
|
|
22
|
+
color: "var(--sxl-text, #1a1a2e)",
|
|
23
23
|
overflow: "auto",
|
|
24
|
-
height: "100%"
|
|
24
|
+
height: "100%",
|
|
25
|
+
display: "flex",
|
|
26
|
+
flexDirection: "column",
|
|
27
|
+
gap: "16px"
|
|
25
28
|
};
|
|
26
|
-
var
|
|
27
|
-
marginBottom: "16px",
|
|
28
|
-
borderRadius: "8px",
|
|
29
|
-
overflow: "hidden",
|
|
30
|
-
border: "1px solid var(--sxl-border, #e6e6e6)",
|
|
29
|
+
var header = {
|
|
31
30
|
display: "flex",
|
|
32
|
-
|
|
31
|
+
alignItems: "flex-start",
|
|
32
|
+
justifyContent: "space-between",
|
|
33
|
+
gap: "12px"
|
|
33
34
|
};
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
var headerLeft = {
|
|
36
|
+
display: "flex",
|
|
37
|
+
flexDirection: "column",
|
|
38
|
+
gap: "4px",
|
|
39
|
+
flex: 1,
|
|
40
|
+
minWidth: 0
|
|
38
41
|
};
|
|
39
|
-
var
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
var componentName = {
|
|
43
|
+
fontSize: "18px",
|
|
44
|
+
fontWeight: 700,
|
|
45
|
+
color: "var(--sxl-text, #1a1a2e)",
|
|
46
|
+
margin: 0,
|
|
47
|
+
lineHeight: 1.3,
|
|
48
|
+
wordBreak: "break-word"
|
|
49
|
+
};
|
|
50
|
+
var updatedAt = {
|
|
51
|
+
fontSize: "11px",
|
|
52
|
+
color: "var(--sxl-muted, #8e8ea0)",
|
|
53
|
+
fontWeight: 400
|
|
54
|
+
};
|
|
55
|
+
var figmaButton = {
|
|
56
|
+
display: "inline-flex",
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
gap: "6px",
|
|
59
|
+
padding: "6px 14px",
|
|
60
|
+
borderRadius: "8px",
|
|
61
|
+
border: "1px solid var(--sxl-border, #e0e0e8)",
|
|
62
|
+
backgroundColor: "var(--sxl-bg, #fff)",
|
|
63
|
+
color: "var(--sxl-link, #18a0fb)",
|
|
64
|
+
fontSize: "12px",
|
|
65
|
+
fontWeight: 600,
|
|
66
|
+
fontFamily: FONT,
|
|
67
|
+
textDecoration: "none",
|
|
68
|
+
cursor: "pointer",
|
|
69
|
+
whiteSpace: "nowrap",
|
|
70
|
+
transition: "all 120ms ease",
|
|
71
|
+
flexShrink: 0
|
|
72
|
+
};
|
|
73
|
+
var badgeRow = {
|
|
74
|
+
display: "flex",
|
|
75
|
+
flexWrap: "wrap",
|
|
76
|
+
gap: "8px"
|
|
45
77
|
};
|
|
46
|
-
var
|
|
78
|
+
var badge = {
|
|
79
|
+
display: "inline-flex",
|
|
80
|
+
alignItems: "center",
|
|
81
|
+
gap: "6px",
|
|
82
|
+
padding: "4px 10px",
|
|
83
|
+
borderRadius: "6px",
|
|
47
84
|
fontSize: "11px",
|
|
48
85
|
fontWeight: 600,
|
|
86
|
+
lineHeight: 1
|
|
87
|
+
};
|
|
88
|
+
var badgeDot = {
|
|
89
|
+
width: "7px",
|
|
90
|
+
height: "7px",
|
|
91
|
+
borderRadius: "50%",
|
|
92
|
+
flexShrink: 0
|
|
93
|
+
};
|
|
94
|
+
var card = {
|
|
95
|
+
padding: "14px 16px",
|
|
96
|
+
borderRadius: "10px",
|
|
97
|
+
backgroundColor: "var(--sxl-card-bg, #f8f8fb)",
|
|
98
|
+
border: "1px solid var(--sxl-border, #ebebf0)"
|
|
99
|
+
};
|
|
100
|
+
var cardTitle = {
|
|
101
|
+
fontSize: "10px",
|
|
102
|
+
fontWeight: 700,
|
|
49
103
|
textTransform: "uppercase",
|
|
50
|
-
letterSpacing: "0.
|
|
51
|
-
color: "var(--sxl-muted, #
|
|
52
|
-
marginBottom: "
|
|
104
|
+
letterSpacing: "0.8px",
|
|
105
|
+
color: "var(--sxl-muted, #8e8ea0)",
|
|
106
|
+
marginBottom: "10px"
|
|
53
107
|
};
|
|
54
|
-
var
|
|
108
|
+
var row = {
|
|
55
109
|
display: "flex",
|
|
56
110
|
alignItems: "baseline",
|
|
57
111
|
gap: "8px",
|
|
58
|
-
marginBottom: "
|
|
112
|
+
marginBottom: "6px"
|
|
59
113
|
};
|
|
60
|
-
var
|
|
114
|
+
var rowLabel = {
|
|
61
115
|
fontSize: "12px",
|
|
62
116
|
fontWeight: 500,
|
|
63
|
-
color: "var(--sxl-label, #
|
|
64
|
-
minWidth: "
|
|
117
|
+
color: "var(--sxl-label, #6b6b80)",
|
|
118
|
+
minWidth: "80px",
|
|
65
119
|
flexShrink: 0
|
|
66
120
|
};
|
|
67
|
-
var
|
|
121
|
+
var rowValue = {
|
|
68
122
|
fontSize: "13px",
|
|
69
|
-
color: "var(--sxl-text, #
|
|
123
|
+
color: "var(--sxl-text, #1a1a2e)",
|
|
70
124
|
wordBreak: "break-word"
|
|
71
125
|
};
|
|
72
126
|
var mono = {
|
|
73
|
-
fontFamily:
|
|
127
|
+
fontFamily: MONO,
|
|
74
128
|
fontSize: "12px"
|
|
75
129
|
};
|
|
76
|
-
var
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
fontWeight: 500
|
|
130
|
+
var descriptionText = {
|
|
131
|
+
fontSize: "13px",
|
|
132
|
+
color: "var(--sxl-text, #3a3a4a)",
|
|
133
|
+
lineHeight: 1.6,
|
|
134
|
+
margin: 0
|
|
82
135
|
};
|
|
83
|
-
var
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
136
|
+
var embedWrap = {
|
|
137
|
+
borderRadius: "10px",
|
|
138
|
+
overflow: "hidden",
|
|
139
|
+
border: "1px solid var(--sxl-border, #ebebf0)"
|
|
140
|
+
};
|
|
141
|
+
var iframe = {
|
|
142
|
+
width: "100%",
|
|
143
|
+
height: "380px",
|
|
144
|
+
border: "none",
|
|
145
|
+
display: "block"
|
|
89
146
|
};
|
|
90
|
-
var
|
|
147
|
+
var embedActions = {
|
|
148
|
+
display: "flex",
|
|
149
|
+
justifyContent: "flex-end",
|
|
150
|
+
padding: "8px 12px",
|
|
151
|
+
borderTop: "1px solid var(--sxl-border, #ebebf0)",
|
|
152
|
+
backgroundColor: "var(--sxl-card-bg, #f8f8fb)"
|
|
153
|
+
};
|
|
154
|
+
var embedLink = {
|
|
155
|
+
fontSize: "11px",
|
|
156
|
+
fontWeight: 600,
|
|
157
|
+
color: "var(--sxl-link, #18a0fb)",
|
|
158
|
+
textDecoration: "none"
|
|
159
|
+
};
|
|
160
|
+
var tagList = {
|
|
91
161
|
display: "flex",
|
|
92
162
|
flexWrap: "wrap",
|
|
93
|
-
gap: "
|
|
163
|
+
gap: "6px"
|
|
94
164
|
};
|
|
95
|
-
var
|
|
165
|
+
var tag = {
|
|
96
166
|
fontSize: "11px",
|
|
97
|
-
fontFamily:
|
|
98
|
-
backgroundColor: "var(--sxl-
|
|
99
|
-
color: "var(--sxl-
|
|
100
|
-
padding: "
|
|
167
|
+
fontFamily: MONO,
|
|
168
|
+
backgroundColor: "var(--sxl-tag-bg, #eef0ff)",
|
|
169
|
+
color: "var(--sxl-tag-text, #3d4a8c)",
|
|
170
|
+
padding: "3px 8px",
|
|
171
|
+
borderRadius: "5px",
|
|
172
|
+
fontWeight: 500
|
|
173
|
+
};
|
|
174
|
+
var frameworkTag = {
|
|
175
|
+
fontSize: "10px",
|
|
176
|
+
fontFamily: FONT,
|
|
177
|
+
fontWeight: 700,
|
|
178
|
+
textTransform: "uppercase",
|
|
179
|
+
letterSpacing: "0.4px",
|
|
180
|
+
backgroundColor: "var(--sxl-fw-bg, #e8faf0)",
|
|
181
|
+
color: "var(--sxl-fw-text, #1a7a4c)",
|
|
182
|
+
padding: "2px 7px",
|
|
101
183
|
borderRadius: "4px"
|
|
102
184
|
};
|
|
103
|
-
var
|
|
104
|
-
|
|
105
|
-
|
|
185
|
+
var codeBlock = {
|
|
186
|
+
fontFamily: MONO,
|
|
187
|
+
fontSize: "11px",
|
|
188
|
+
backgroundColor: "var(--sxl-code-bg, #f3f3f8)",
|
|
189
|
+
border: "1px solid var(--sxl-border, #ebebf0)",
|
|
190
|
+
borderRadius: "8px",
|
|
191
|
+
padding: "12px 14px",
|
|
192
|
+
overflow: "auto",
|
|
193
|
+
lineHeight: 1.65,
|
|
194
|
+
whiteSpace: "pre",
|
|
195
|
+
margin: 0
|
|
196
|
+
};
|
|
197
|
+
var emptyContainer = {
|
|
198
|
+
display: "flex",
|
|
199
|
+
flexDirection: "column",
|
|
200
|
+
alignItems: "center",
|
|
201
|
+
justifyContent: "center",
|
|
202
|
+
height: "100%",
|
|
203
|
+
padding: "40px 20px",
|
|
204
|
+
fontFamily: FONT,
|
|
205
|
+
textAlign: "center"
|
|
106
206
|
};
|
|
107
207
|
var emptyTitle = {
|
|
108
|
-
fontSize: "
|
|
208
|
+
fontSize: "15px",
|
|
109
209
|
fontWeight: 600,
|
|
110
|
-
color: "var(--sxl-
|
|
111
|
-
marginBottom: "
|
|
210
|
+
color: "var(--sxl-text, #3a3a4a)",
|
|
211
|
+
marginBottom: "8px",
|
|
112
212
|
marginTop: 0
|
|
113
213
|
};
|
|
114
214
|
var emptyHint = {
|
|
115
215
|
fontSize: "12px",
|
|
116
|
-
color: "var(--sxl-muted, #
|
|
117
|
-
marginBottom: "8px"
|
|
118
|
-
};
|
|
119
|
-
var code = {
|
|
120
|
-
fontFamily: MONO_STACK,
|
|
121
|
-
fontSize: "11px",
|
|
122
|
-
backgroundColor: "var(--sxl-code-bg, #f0f0f0)",
|
|
123
|
-
padding: "1px 4px",
|
|
124
|
-
borderRadius: "3px"
|
|
125
|
-
};
|
|
126
|
-
var codeBlock = {
|
|
127
|
-
fontFamily: MONO_STACK,
|
|
128
|
-
fontSize: "11px",
|
|
129
|
-
backgroundColor: "var(--sxl-code-bg, #f5f5f5)",
|
|
130
|
-
border: "1px solid var(--sxl-border, #e6e6e6)",
|
|
131
|
-
borderRadius: "6px",
|
|
132
|
-
padding: "12px",
|
|
133
|
-
textAlign: "left",
|
|
134
|
-
overflow: "auto",
|
|
216
|
+
color: "var(--sxl-muted, #8e8ea0)",
|
|
135
217
|
marginBottom: "12px",
|
|
136
|
-
|
|
137
|
-
whiteSpace: "pre"
|
|
218
|
+
marginTop: 0
|
|
138
219
|
};
|
|
139
|
-
var
|
|
220
|
+
var emptyCode = {
|
|
221
|
+
fontFamily: MONO,
|
|
140
222
|
fontSize: "11px",
|
|
141
|
-
|
|
142
|
-
|
|
223
|
+
backgroundColor: "var(--sxl-code-bg, #f3f3f8)",
|
|
224
|
+
padding: "2px 5px",
|
|
225
|
+
borderRadius: "4px"
|
|
143
226
|
};
|
|
144
227
|
|
|
145
228
|
// src/components/SxlPanel.tsx
|
|
146
|
-
var
|
|
147
|
-
assigned: { label: "
|
|
148
|
-
partial: { label: "
|
|
149
|
-
none: { label: "
|
|
229
|
+
var TOKEN_MAP = {
|
|
230
|
+
assigned: { label: "Tokens", fg: "#166534", bg: "#dcfce7", dot: "#22c55e" },
|
|
231
|
+
partial: { label: "Tokens (partial)", fg: "#92400e", bg: "#fef3c7", dot: "#f59e0b" },
|
|
232
|
+
none: { label: "No tokens", fg: "#6b7280", bg: "#f3f4f6", dot: "#9ca3af" }
|
|
150
233
|
};
|
|
151
234
|
var READINESS_MAP = {
|
|
152
|
-
"complete": { label: "Complete",
|
|
153
|
-
"ready-for-dev": { label: "Ready for Dev",
|
|
154
|
-
"in-progress": { label: "In Progress",
|
|
155
|
-
"backlog": { label: "Backlog",
|
|
235
|
+
"complete": { label: "Complete", fg: "#166534", bg: "#dcfce7", dot: "#22c55e" },
|
|
236
|
+
"ready-for-dev": { label: "Ready for Dev", fg: "#1e40af", bg: "#dbeafe", dot: "#3b82f6" },
|
|
237
|
+
"in-progress": { label: "In Progress", fg: "#92400e", bg: "#fef3c7", dot: "#f59e0b" },
|
|
238
|
+
"backlog": { label: "Backlog", fg: "#6b7280", bg: "#f3f4f6", dot: "#9ca3af" }
|
|
156
239
|
};
|
|
157
240
|
function resolveEntry(params) {
|
|
158
241
|
if (!params) return null;
|
|
@@ -160,11 +243,12 @@ function resolveEntry(params) {
|
|
|
160
243
|
if (params.figmaUrl || params.description) {
|
|
161
244
|
return {
|
|
162
245
|
nodeId: params.figmaNodeId ?? "",
|
|
163
|
-
displayName: params.component ?? "",
|
|
246
|
+
displayName: params.component ?? params.componentName ?? "",
|
|
164
247
|
description: params.description,
|
|
165
248
|
figmaUrl: params.figmaUrl,
|
|
166
|
-
designEmbed: !!params.figmaUrl,
|
|
167
|
-
|
|
249
|
+
designEmbed: params.designEmbed ?? !!params.figmaUrl,
|
|
250
|
+
compositionJson: params.compositionJson,
|
|
251
|
+
metadata: params.metadata,
|
|
168
252
|
meta: {
|
|
169
253
|
tokenStatus: params.tokenStatus,
|
|
170
254
|
readiness: params.readiness
|
|
@@ -176,17 +260,15 @@ function resolveEntry(params) {
|
|
|
176
260
|
if (params.figmaNodeId) {
|
|
177
261
|
found = registry.entries.find((e) => e.nodeId === params.figmaNodeId);
|
|
178
262
|
}
|
|
179
|
-
if (!found
|
|
180
|
-
const name = params.component.toLowerCase();
|
|
181
|
-
|
|
263
|
+
if (!found) {
|
|
264
|
+
const name = (params.component ?? params.componentName ?? "").toLowerCase();
|
|
265
|
+
if (name) {
|
|
266
|
+
found = registry.entries.find((e) => e.displayName.toLowerCase() === name);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!found && registry.entries.length === 1) {
|
|
270
|
+
found = registry.entries[0];
|
|
182
271
|
}
|
|
183
|
-
console.info("[SXL Storybook Addon] resolve-entry", {
|
|
184
|
-
hasRegistry: !!registry,
|
|
185
|
-
registryEntries: registry?.entries?.length ?? 0,
|
|
186
|
-
figmaNodeId: params.figmaNodeId ?? null,
|
|
187
|
-
component: params.component ?? null,
|
|
188
|
-
found: found ? { nodeId: found.nodeId, displayName: found.displayName } : null
|
|
189
|
-
});
|
|
190
272
|
if (!found) return null;
|
|
191
273
|
return {
|
|
192
274
|
...found,
|
|
@@ -195,57 +277,80 @@ function resolveEntry(params) {
|
|
|
195
277
|
tokenStatus: params.tokenStatus ?? found.meta?.tokenStatus,
|
|
196
278
|
readiness: params.readiness ?? found.meta?.readiness
|
|
197
279
|
},
|
|
198
|
-
description: params.description ?? found.description
|
|
280
|
+
description: params.description ?? found.description,
|
|
281
|
+
compositionJson: params.compositionJson ?? found.compositionJson,
|
|
282
|
+
metadata: params.metadata ?? found.metadata,
|
|
283
|
+
designEmbed: params.designEmbed ?? found.designEmbed
|
|
199
284
|
};
|
|
200
285
|
}
|
|
201
286
|
function buildEmbedUrl(figmaUrl) {
|
|
202
287
|
if (figmaUrl.includes("figma.com/embed")) return figmaUrl;
|
|
203
288
|
return `https://www.figma.com/embed?embed_host=storybook&url=${encodeURIComponent(figmaUrl)}`;
|
|
204
289
|
}
|
|
205
|
-
function
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
290
|
+
function buildDevModeUrl(figmaUrl) {
|
|
291
|
+
try {
|
|
292
|
+
const u = new URL(figmaUrl.includes("figma.com/embed") ? new URL(figmaUrl).searchParams.get("url") ?? figmaUrl : figmaUrl);
|
|
293
|
+
u.searchParams.set("m", "dev");
|
|
294
|
+
return u.toString();
|
|
295
|
+
} catch {
|
|
296
|
+
return figmaUrl;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function formatDate(iso) {
|
|
300
|
+
if (!iso) return null;
|
|
301
|
+
try {
|
|
302
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
303
|
+
month: "short",
|
|
304
|
+
day: "numeric",
|
|
305
|
+
year: "numeric",
|
|
306
|
+
hour: "2-digit",
|
|
307
|
+
minute: "2-digit"
|
|
308
|
+
}).format(new Date(iso));
|
|
309
|
+
} catch {
|
|
310
|
+
return iso;
|
|
213
311
|
}
|
|
214
|
-
return figmaUrl;
|
|
215
312
|
}
|
|
216
|
-
var
|
|
313
|
+
var Badge = ({
|
|
314
|
+
label,
|
|
315
|
+
fg,
|
|
316
|
+
bg,
|
|
317
|
+
dot
|
|
318
|
+
}) => /* @__PURE__ */ React.createElement("span", { style: { ...badge, color: fg, backgroundColor: bg } }, /* @__PURE__ */ React.createElement("span", { style: { ...badgeDot, backgroundColor: dot } }), label);
|
|
319
|
+
var EmptyState = () => /* @__PURE__ */ React.createElement("div", { style: emptyContainer }, /* @__PURE__ */ React.createElement("p", { style: emptyTitle }, "No SXL data for this story"), /* @__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 raw from '../diff-code-connect.YOUR_KEY.json';
|
|
320
|
+
import { fromDiffCodeConnect } from '@sxl-studio/storybook-addon';
|
|
217
321
|
|
|
218
322
|
export default {
|
|
219
323
|
parameters: {
|
|
220
|
-
sxl: { registry },
|
|
324
|
+
sxl: { registry: fromDiffCodeConnect(raw) },
|
|
221
325
|
},
|
|
222
326
|
};`), /* @__PURE__ */ React.createElement("p", { style: emptyHint }, "Then match a story to a Figma component:"), /* @__PURE__ */ React.createElement("pre", { style: codeBlock }, `export const Default = {
|
|
223
327
|
parameters: {
|
|
224
328
|
sxl: { component: 'ButtonPrimary' },
|
|
225
329
|
},
|
|
226
|
-
};`))
|
|
227
|
-
var StatusRow = ({
|
|
228
|
-
label,
|
|
229
|
-
status,
|
|
230
|
-
color
|
|
231
|
-
}) => /* @__PURE__ */ React.createElement("div", { style: infoRow }, /* @__PURE__ */ React.createElement("span", { style: infoLabel }, label), /* @__PURE__ */ React.createElement("span", { style: statusBadge }, /* @__PURE__ */ React.createElement("span", { style: { ...statusDot, backgroundColor: color } }), status));
|
|
330
|
+
};`));
|
|
232
331
|
var SxlPanel = () => {
|
|
233
332
|
const params = useParameter(PARAM_KEY);
|
|
234
|
-
console.info("[SXL Storybook Addon] panel-params", {
|
|
235
|
-
hasParams: !!params,
|
|
236
|
-
keys: params ? Object.keys(params) : [],
|
|
237
|
-
hasRegistry: !!params?.registry,
|
|
238
|
-
registryEntries: params?.registry?.entries?.length ?? 0
|
|
239
|
-
});
|
|
240
333
|
const entry = resolveEntry(params);
|
|
241
|
-
if (!entry) return
|
|
334
|
+
if (!entry) return React.createElement(EmptyState, null);
|
|
242
335
|
const tokenStatus = entry.meta?.tokenStatus;
|
|
243
336
|
const readiness = entry.meta?.readiness;
|
|
244
|
-
const tokenInfo = tokenStatus ?
|
|
337
|
+
const tokenInfo = tokenStatus ? TOKEN_MAP[tokenStatus] : null;
|
|
245
338
|
const readinessInfo = readiness ? READINESS_MAP[readiness] : null;
|
|
339
|
+
const dateStr = formatDate(entry.updatedAt);
|
|
246
340
|
const hasProps = !!entry.meta?.componentProperties?.length;
|
|
247
|
-
const
|
|
248
|
-
|
|
341
|
+
const hasFiles = !!entry.files?.length;
|
|
342
|
+
const hasBadges = !!(tokenInfo || readinessInfo);
|
|
343
|
+
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(
|
|
344
|
+
"a",
|
|
345
|
+
{
|
|
346
|
+
href: buildDevModeUrl(entry.figmaUrl),
|
|
347
|
+
target: "_blank",
|
|
348
|
+
rel: "noopener noreferrer",
|
|
349
|
+
style: figmaButton
|
|
350
|
+
},
|
|
351
|
+
/* @__PURE__ */ React.createElement(FigmaIcon, null),
|
|
352
|
+
"Open in Figma"
|
|
353
|
+
)), 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(
|
|
249
354
|
"iframe",
|
|
250
355
|
{
|
|
251
356
|
title: "Figma Design",
|
|
@@ -253,17 +358,18 @@ var SxlPanel = () => {
|
|
|
253
358
|
style: iframe,
|
|
254
359
|
allowFullScreen: true
|
|
255
360
|
}
|
|
256
|
-
)
|
|
361
|
+
), /* @__PURE__ */ React.createElement("div", { style: embedActions }, /* @__PURE__ */ React.createElement(
|
|
257
362
|
"a",
|
|
258
363
|
{
|
|
259
|
-
href:
|
|
364
|
+
href: buildDevModeUrl(entry.figmaUrl),
|
|
260
365
|
target: "_blank",
|
|
261
366
|
rel: "noopener noreferrer",
|
|
262
|
-
style:
|
|
367
|
+
style: embedLink
|
|
263
368
|
},
|
|
264
|
-
"Open in Figma \
|
|
265
|
-
))), hasProps && /* @__PURE__ */ React.createElement("div", { style:
|
|
369
|
+
"Open in Figma Dev Mode \u2192"
|
|
370
|
+
))), (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));
|
|
266
371
|
};
|
|
372
|
+
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" }));
|
|
267
373
|
|
|
268
374
|
// src/manager.tsx
|
|
269
375
|
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.
|
|
3
|
+
"version": "1.0.7",
|
|
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",
|