@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 +23 -14
- package/dist/index.js +26 -4
- package/dist/manager.js +294 -178
- package/package.json +1 -1
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
104
|
-
var MONO = "
|
|
105
|
-
var
|
|
106
|
-
padding: "
|
|
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.
|
|
110
|
-
color: "var(--
|
|
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
|
-
|
|
114
|
-
flexDirection: "column",
|
|
115
|
-
gap: "16px"
|
|
136
|
+
boxSizing: "border-box"
|
|
116
137
|
};
|
|
117
|
-
var
|
|
138
|
+
var topRow = {
|
|
118
139
|
display: "flex",
|
|
119
140
|
alignItems: "flex-start",
|
|
120
141
|
justifyContent: "space-between",
|
|
121
|
-
gap: "
|
|
142
|
+
gap: "16px",
|
|
143
|
+
marginBottom: "14px"
|
|
122
144
|
};
|
|
123
|
-
var
|
|
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: "
|
|
150
|
+
fontSize: "17px",
|
|
132
151
|
fontWeight: 700,
|
|
133
|
-
|
|
152
|
+
letterSpacing: "-0.02em",
|
|
134
153
|
margin: 0,
|
|
135
|
-
lineHeight: 1.
|
|
136
|
-
|
|
154
|
+
lineHeight: 1.25,
|
|
155
|
+
color: "var(--sb-color-text, #1a1d21)"
|
|
137
156
|
};
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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: "
|
|
173
|
+
gap: "6px",
|
|
174
|
+
justifyContent: "flex-end"
|
|
165
175
|
};
|
|
166
|
-
var
|
|
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
|
|
183
|
-
|
|
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
|
|
188
|
+
var sectionLabel = {
|
|
189
189
|
fontSize: "10px",
|
|
190
190
|
fontWeight: 700,
|
|
191
191
|
textTransform: "uppercase",
|
|
192
|
-
letterSpacing: "0.
|
|
193
|
-
color: "var(--
|
|
194
|
-
marginBottom: "
|
|
192
|
+
letterSpacing: "0.06em",
|
|
193
|
+
color: "var(--sb-color-text-muted, #6b7280)",
|
|
194
|
+
marginBottom: "8px"
|
|
195
195
|
};
|
|
196
|
-
var
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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(--
|
|
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
|
-
|
|
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
|
|
222
|
+
var embedFooter = {
|
|
236
223
|
display: "flex",
|
|
237
224
|
justifyContent: "flex-end",
|
|
238
225
|
padding: "8px 12px",
|
|
239
|
-
borderTop: "1px solid var(--
|
|
240
|
-
backgroundColor: "var(--
|
|
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
|
|
229
|
+
var link = {
|
|
243
230
|
fontSize: "11px",
|
|
244
231
|
fontWeight: 600,
|
|
245
|
-
color: "var(--
|
|
232
|
+
color: "var(--sb-color-accent, #1a73e8)",
|
|
246
233
|
textDecoration: "none"
|
|
247
234
|
};
|
|
248
|
-
var
|
|
235
|
+
var codeToolbar = {
|
|
249
236
|
display: "flex",
|
|
250
|
-
|
|
251
|
-
|
|
237
|
+
justifyContent: "flex-end",
|
|
238
|
+
marginBottom: "6px"
|
|
252
239
|
};
|
|
253
|
-
var
|
|
240
|
+
var copyBtn = {
|
|
254
241
|
fontSize: "11px",
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
borderRadius: "8px",
|
|
254
|
+
lineHeight: 1.55,
|
|
255
|
+
margin: 0,
|
|
279
256
|
padding: "12px 14px",
|
|
257
|
+
borderRadius: "8px",
|
|
280
258
|
overflow: "auto",
|
|
281
|
-
|
|
259
|
+
maxHeight: "min(55vh, 520px)",
|
|
282
260
|
whiteSpace: "pre",
|
|
283
|
-
|
|
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: "
|
|
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(--
|
|
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(--
|
|
312
|
-
padding: "2px
|
|
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
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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: {
|
|
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
|
-
|
|
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
|
|
414
|
-
if (
|
|
415
|
-
bestScore =
|
|
435
|
+
const sc = score(entry, tokens);
|
|
436
|
+
if (sc > bestScore) {
|
|
437
|
+
bestScore = sc;
|
|
416
438
|
best = entry;
|
|
417
439
|
tie = false;
|
|
418
|
-
} else if (
|
|
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(
|
|
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
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
}
|
|
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 }, "
|
|
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, {
|
|
586
|
+
return React.createElement(NoMatchState, {
|
|
587
|
+
componentHint: result.componentHint
|
|
588
|
+
});
|
|
513
589
|
}
|
|
514
590
|
const entry = result.entry;
|
|
515
|
-
const
|
|
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
|
|
521
|
-
const
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
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:
|
|
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:
|
|
615
|
+
style: link
|
|
548
616
|
},
|
|
549
617
|
"Open in Figma Dev Mode \u2192"
|
|
550
|
-
)))
|
|
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(
|
|
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.
|
|
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",
|