@lijinmei-810/dev-inspector 0.2.0 → 0.2.1
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/dev-inspector.css +494 -160
- package/dist/index.cjs +688 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +478 -180
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +689 -178
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,40 @@ var import_lucide_react = require("lucide-react");
|
|
|
37
37
|
// src/DevInspectorProvider.tsx
|
|
38
38
|
var import_react = require("react");
|
|
39
39
|
|
|
40
|
+
// src/tokens/typography.json
|
|
41
|
+
var typography_default = {
|
|
42
|
+
title: {
|
|
43
|
+
fontSize: "15px",
|
|
44
|
+
fontWeight: "700",
|
|
45
|
+
lineHeight: "1.4",
|
|
46
|
+
color: "#111827"
|
|
47
|
+
},
|
|
48
|
+
sectionLabel: {
|
|
49
|
+
fontSize: "12px",
|
|
50
|
+
fontWeight: "700",
|
|
51
|
+
lineHeight: "1.4",
|
|
52
|
+
color: "#374151"
|
|
53
|
+
},
|
|
54
|
+
body: {
|
|
55
|
+
fontSize: "12px",
|
|
56
|
+
fontWeight: "400",
|
|
57
|
+
lineHeight: "1.5",
|
|
58
|
+
color: "#6b7280"
|
|
59
|
+
},
|
|
60
|
+
meta: {
|
|
61
|
+
fontSize: "11px",
|
|
62
|
+
fontWeight: "600",
|
|
63
|
+
lineHeight: "1.35",
|
|
64
|
+
color: "#94a3b8"
|
|
65
|
+
},
|
|
66
|
+
tinyBadge: {
|
|
67
|
+
fontSize: "10px",
|
|
68
|
+
fontWeight: "700",
|
|
69
|
+
lineHeight: "1.2",
|
|
70
|
+
color: "#64748b"
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
40
74
|
// src/config.ts
|
|
41
75
|
var FALLBACK_TYPOGRAPHY_STYLES = [
|
|
42
76
|
{
|
|
@@ -136,6 +170,7 @@ var FALLBACK_SHADOW_TOKENS = [
|
|
|
136
170
|
var FALLBACK_TOKENS = {
|
|
137
171
|
colorPalette: [],
|
|
138
172
|
tokenLabels: {},
|
|
173
|
+
inspectorTypography: typography_default,
|
|
139
174
|
radiusPresets: [
|
|
140
175
|
{ label: "\u65E0", sub: "", value: "0px", token: "" },
|
|
141
176
|
{ label: "S", sub: "4px", value: "4px", token: "" },
|
|
@@ -306,12 +341,22 @@ function handleArrowKeyStep(event, onStep, onEnter) {
|
|
|
306
341
|
}
|
|
307
342
|
if (event.key === "Enter") onEnter?.();
|
|
308
343
|
}
|
|
344
|
+
function renderSubmitLabel(submitMsg) {
|
|
345
|
+
if (submitMsg === "\u5DF2\u590D\u5236") {
|
|
346
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "di-btn-save-content", children: [
|
|
347
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Check, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" }),
|
|
348
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u5DF2\u590D\u5236" })
|
|
349
|
+
] });
|
|
350
|
+
}
|
|
351
|
+
return submitMsg || "\u53D1\u9001\u7ED9AI";
|
|
352
|
+
}
|
|
309
353
|
var COLOR_PROPS = [
|
|
310
354
|
{ label: "\u80CC\u666F\u8272", prop: "background-color" }
|
|
311
355
|
];
|
|
312
356
|
function getColorLabel(val, colorPalette) {
|
|
357
|
+
const normalizedVal = resolveColorValue(val);
|
|
313
358
|
for (const g of colorPalette) {
|
|
314
|
-
const found = g.colors.find((c) => c.val ===
|
|
359
|
+
const found = g.colors.find((c) => resolveColorValue(c.val) === normalizedVal);
|
|
315
360
|
if (found) return `${g.group}\xB7${found.label}`;
|
|
316
361
|
}
|
|
317
362
|
return null;
|
|
@@ -521,10 +566,26 @@ function isTextEntryTarget(target) {
|
|
|
521
566
|
function normalizeColor(val) {
|
|
522
567
|
const raw = val.trim();
|
|
523
568
|
if (raw === "transparent" || /^rgba\(\s*0,\s*0,\s*0,\s*0\s*\)$/i.test(raw)) return "transparent";
|
|
524
|
-
const m =
|
|
569
|
+
const m = raw.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/);
|
|
525
570
|
if (m) return "#" + [m[1], m[2], m[3]].map((n) => parseInt(n).toString(16).padStart(2, "0")).join("");
|
|
571
|
+
if (/^#[0-9a-f]{3,8}$/i.test(raw)) return raw.toLowerCase();
|
|
526
572
|
return raw;
|
|
527
573
|
}
|
|
574
|
+
function resolveColorValue(val) {
|
|
575
|
+
const normalized = normalizeColor(val || "");
|
|
576
|
+
if (!normalized || normalized === "transparent") return normalized || "transparent";
|
|
577
|
+
if (/^#[0-9a-f]{6}$/i.test(normalized)) return normalized;
|
|
578
|
+
if (typeof document === "undefined" || !document.body) return normalized;
|
|
579
|
+
const probe = document.createElement("div");
|
|
580
|
+
probe.style.color = normalized;
|
|
581
|
+
probe.style.position = "fixed";
|
|
582
|
+
probe.style.opacity = "0";
|
|
583
|
+
probe.style.pointerEvents = "none";
|
|
584
|
+
document.body.appendChild(probe);
|
|
585
|
+
const computed = normalizeColor(getComputedStyle(probe).color.trim());
|
|
586
|
+
probe.remove();
|
|
587
|
+
return computed || normalized;
|
|
588
|
+
}
|
|
528
589
|
function isTransparentColor(val) {
|
|
529
590
|
return normalizeColor(val || "transparent") === "transparent";
|
|
530
591
|
}
|
|
@@ -667,7 +728,7 @@ function getComponentClasses(el) {
|
|
|
667
728
|
if (primitiveClasses.length) return primitiveClasses;
|
|
668
729
|
const classes = getClasses(el);
|
|
669
730
|
const cardBaseClass = classes.find(
|
|
670
|
-
(className) =>
|
|
731
|
+
(className) => isCardRootClass(className) && !className.includes("--")
|
|
671
732
|
);
|
|
672
733
|
if (cardBaseClass) return [cardBaseClass];
|
|
673
734
|
const badgeBaseClass = classes.find(
|
|
@@ -726,6 +787,7 @@ var TEXT_ONLY_TAGS = /* @__PURE__ */ new Set([
|
|
|
726
787
|
var TEXT_SEMANTIC_CLASS_RE = /(^|[-_])(caption|copy|desc|description|eyebrow|heading|label|subtitle|text|title)([-_]|$)/i;
|
|
727
788
|
var STRUCTURAL_CONTAINER_CLASS_RE = /(^|[-_])(area|block|card|container|content|group|grid|item|layout|list|panel|row|section|shell|stack|zone)([-_]|$)/i;
|
|
728
789
|
var PAGE_SHELL_CLASS_RE = /(^|[-_])(app|page|root|screen|shell|workspace)([-_]|$)/i;
|
|
790
|
+
var CARD_ROOT_CLASS_NAMES = /* @__PURE__ */ new Set(["task-card"]);
|
|
729
791
|
var TEXT_GROUP_EXCLUDED_SELECTOR = [
|
|
730
792
|
"button",
|
|
731
793
|
"input",
|
|
@@ -756,6 +818,12 @@ function hasTextSemanticClass(el) {
|
|
|
756
818
|
(className) => !isStateClass(className) && !/^lucide(-|$)/.test(className) && TEXT_SEMANTIC_CLASS_RE.test(className)
|
|
757
819
|
);
|
|
758
820
|
}
|
|
821
|
+
function getRegisteredComponentType(el) {
|
|
822
|
+
return (el.getAttribute("data-component") || "").trim();
|
|
823
|
+
}
|
|
824
|
+
function isCardRootClass(className) {
|
|
825
|
+
return CARD_ROOT_CLASS_NAMES.has(className) || /(^|[-_])card($|--)/i.test(className);
|
|
826
|
+
}
|
|
759
827
|
function hasStructuralContainerClass(el) {
|
|
760
828
|
return getClasses(el).some(
|
|
761
829
|
(className) => !isStateClass(className) && STRUCTURAL_CONTAINER_CLASS_RE.test(className)
|
|
@@ -891,6 +959,17 @@ function getInspectorComponentMeta(el) {
|
|
|
891
959
|
const tag = el.tagName.toLowerCase();
|
|
892
960
|
const classes = getClasses(el);
|
|
893
961
|
const componentClasses = getComponentClasses(el);
|
|
962
|
+
const registeredComponentType = getRegisteredComponentType(el);
|
|
963
|
+
if (registeredComponentType) {
|
|
964
|
+
const type = registeredComponentType;
|
|
965
|
+
return {
|
|
966
|
+
name: componentClasses[0] ?? type,
|
|
967
|
+
type,
|
|
968
|
+
layer: "Component",
|
|
969
|
+
variant: inferVariantFromClasses(classes),
|
|
970
|
+
state: inferStateFromElement(el, classes)
|
|
971
|
+
};
|
|
972
|
+
}
|
|
894
973
|
if (tag === "svg" && classes.includes("lucide")) {
|
|
895
974
|
const iconClass = classes.find((className) => /^lucide-/.test(className));
|
|
896
975
|
return {
|
|
@@ -911,9 +990,9 @@ function getInspectorComponentMeta(el) {
|
|
|
911
990
|
state: inferStateFromElement(el, classes)
|
|
912
991
|
};
|
|
913
992
|
}
|
|
914
|
-
if (
|
|
993
|
+
if (classes.some(isCardRootClass)) {
|
|
915
994
|
return {
|
|
916
|
-
name: componentClasses.find((className) =>
|
|
995
|
+
name: componentClasses.find((className) => isCardRootClass(className)) ?? componentClasses[0] ?? "card",
|
|
917
996
|
type: "Card",
|
|
918
997
|
layer: "Component",
|
|
919
998
|
variant: inferCardVariant(classes),
|
|
@@ -1541,6 +1620,14 @@ function canPersistSelector(el, scope) {
|
|
|
1541
1620
|
function isInsidePanel(el) {
|
|
1542
1621
|
return el.closest(".di-panel") !== null || el.closest(".di-trigger") !== null || el.closest(".di-label") !== null;
|
|
1543
1622
|
}
|
|
1623
|
+
function resolveSelectionTarget(raw) {
|
|
1624
|
+
let cursor = raw;
|
|
1625
|
+
while (cursor && cursor !== document.body && cursor !== document.documentElement) {
|
|
1626
|
+
if (getInspectorComponentMeta(cursor)) return cursor;
|
|
1627
|
+
cursor = cursor.parentElement;
|
|
1628
|
+
}
|
|
1629
|
+
return raw;
|
|
1630
|
+
}
|
|
1544
1631
|
function scanTokenMap() {
|
|
1545
1632
|
const map = {};
|
|
1546
1633
|
try {
|
|
@@ -1571,6 +1658,12 @@ function getComputedColor(el, prop) {
|
|
|
1571
1658
|
function getComputedRadius(el) {
|
|
1572
1659
|
return getComputedStyle(el).getPropertyValue("border-radius").trim();
|
|
1573
1660
|
}
|
|
1661
|
+
function getComputedPadding(el) {
|
|
1662
|
+
const cs = getComputedStyle(el);
|
|
1663
|
+
const t = cs.paddingTop, r = cs.paddingRight, b = cs.paddingBottom, l = cs.paddingLeft;
|
|
1664
|
+
if (t === r && r === b && b === l) return t;
|
|
1665
|
+
return `${t} ${r} ${b} ${l}`;
|
|
1666
|
+
}
|
|
1574
1667
|
function parseTranslate(val) {
|
|
1575
1668
|
const raw = (val || "none").trim();
|
|
1576
1669
|
if (!raw || raw === "none") return { x: 0, y: 0 };
|
|
@@ -2014,6 +2107,93 @@ function getTextContent(el) {
|
|
|
2014
2107
|
const text = Array.from(el.childNodes).filter((n) => n.nodeType === Node.TEXT_NODE).map((n) => n.textContent ?? "").join("").trim();
|
|
2015
2108
|
return text.length > 0 ? el.textContent?.trim() ?? null : null;
|
|
2016
2109
|
}
|
|
2110
|
+
function MatchBadge({
|
|
2111
|
+
label,
|
|
2112
|
+
tooltip,
|
|
2113
|
+
tone
|
|
2114
|
+
}) {
|
|
2115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2116
|
+
"span",
|
|
2117
|
+
{
|
|
2118
|
+
className: `di-match-badge di-match-badge--${tone}`,
|
|
2119
|
+
title: tooltip,
|
|
2120
|
+
"data-tooltip": tooltip,
|
|
2121
|
+
tabIndex: 0,
|
|
2122
|
+
children: label
|
|
2123
|
+
}
|
|
2124
|
+
);
|
|
2125
|
+
}
|
|
2126
|
+
function getComputedMargin(el) {
|
|
2127
|
+
const cs = getComputedStyle(el);
|
|
2128
|
+
const t = cs.marginTop, r = cs.marginRight, b = cs.marginBottom, l = cs.marginLeft;
|
|
2129
|
+
if (t === r && r === b && b === l) return t;
|
|
2130
|
+
return `${t} ${r} ${b} ${l}`;
|
|
2131
|
+
}
|
|
2132
|
+
function formatReadableColor(value) {
|
|
2133
|
+
if (!value || isTransparentColor(value)) return "\u900F\u660E";
|
|
2134
|
+
return formatColorDisplay(resolveColorValue(value));
|
|
2135
|
+
}
|
|
2136
|
+
function getComponentElementStyleSummary(el) {
|
|
2137
|
+
const cs = getComputedStyle(el);
|
|
2138
|
+
const parts = [];
|
|
2139
|
+
const text = getTextContent(el);
|
|
2140
|
+
const tag = el.tagName.toLowerCase();
|
|
2141
|
+
const borderWidth = getNumericCssValue(cs.borderTopWidth);
|
|
2142
|
+
const radius = cs.borderRadius.trim();
|
|
2143
|
+
const bg = cs.backgroundColor.trim();
|
|
2144
|
+
const color = cs.color.trim();
|
|
2145
|
+
if (text || /^(p|span|a|button|label|h1|h2|h3|h4|h5|h6|li|strong|em)$/i.test(tag)) {
|
|
2146
|
+
parts.push(`\u5B57 ${formatLengthControlValue(cs.fontSize)}`);
|
|
2147
|
+
parts.push(`\u91CD ${cs.fontWeight}`);
|
|
2148
|
+
parts.push(`\u8272 ${formatReadableColor(color)}`);
|
|
2149
|
+
}
|
|
2150
|
+
if (!isTransparentColor(bg)) {
|
|
2151
|
+
parts.push(`\u80CC\u666F ${formatReadableColor(bg)}`);
|
|
2152
|
+
}
|
|
2153
|
+
if (borderWidth > 0 && !isTransparentColor(cs.borderTopColor)) {
|
|
2154
|
+
parts.push(`\u63CF\u8FB9 ${formatLengthControlValue(cs.borderTopWidth)} ${formatReadableColor(cs.borderTopColor)}`);
|
|
2155
|
+
}
|
|
2156
|
+
if (!isZeroLengthValue(radius)) {
|
|
2157
|
+
parts.push(`\u5706\u89D2 ${formatLengthControlValue(radius)}`);
|
|
2158
|
+
}
|
|
2159
|
+
return parts.join(" / ") || "\u65E0\u660E\u663E\u6837\u5F0F";
|
|
2160
|
+
}
|
|
2161
|
+
function getComponentElementSpacingSummary(el) {
|
|
2162
|
+
const cs = getComputedStyle(el);
|
|
2163
|
+
const parts = [];
|
|
2164
|
+
const paddingSummary = getSpaceSummary("padding", getComputedPadding(el));
|
|
2165
|
+
const marginSummary = getSpaceSummary("margin", getComputedMargin(el));
|
|
2166
|
+
const gapSummary = canControlElementGap(el) ? getSpaceSummary("gap", cs.gap.trim()) : "";
|
|
2167
|
+
if (paddingSummary) parts.push(`\u5185\u8FB9\u8DDD ${paddingSummary}`);
|
|
2168
|
+
if (marginSummary) parts.push(`\u5916\u8FB9\u8DDD ${marginSummary}`);
|
|
2169
|
+
if (gapSummary) parts.push(`\u5143\u7D20\u95F4\u8DDD ${gapSummary.replace(/^gap\s*/i, "")}`);
|
|
2170
|
+
return parts.join(" / ") || "\u65E0\u989D\u5916\u95F4\u8DDD";
|
|
2171
|
+
}
|
|
2172
|
+
function getComponentElementStyleStatus(el, tokenMap, colorPalette, tokenLabels, typographyTokens) {
|
|
2173
|
+
const cs = getComputedStyle(el);
|
|
2174
|
+
const colorInfo = getDisplayLabel(normalizeColor(cs.color), tokenMap, colorPalette, tokenLabels);
|
|
2175
|
+
const backgroundInfo = getDisplayLabel(normalizeColor(cs.backgroundColor), tokenMap, colorPalette, tokenLabels);
|
|
2176
|
+
const borderInfo = getDisplayLabel(normalizeColor(cs.borderTopColor), tokenMap, colorPalette, tokenLabels);
|
|
2177
|
+
const typographyMatched = Boolean(getTypographyToken(cs.fontSize.trim(), cs.fontWeight.trim(), normalizeColor(cs.color), typographyTokens));
|
|
2178
|
+
if (typographyMatched) return "token";
|
|
2179
|
+
if (!colorInfo.isHardcoded || !backgroundInfo.isHardcoded || !borderInfo.isHardcoded) return "token";
|
|
2180
|
+
return "raw";
|
|
2181
|
+
}
|
|
2182
|
+
function getComponentElementSpacingStatus(el, spaceSteps) {
|
|
2183
|
+
const cs = getComputedStyle(el);
|
|
2184
|
+
const paddingValue = getComputedPadding(el);
|
|
2185
|
+
const marginValue = getComputedMargin(el);
|
|
2186
|
+
const gapValue = cs.gap.trim();
|
|
2187
|
+
const paddingSummary = getSpaceSummary("padding", paddingValue);
|
|
2188
|
+
const marginSummary = getSpaceSummary("margin", marginValue);
|
|
2189
|
+
const gapSummary = canControlElementGap(el) ? getSpaceSummary("gap", gapValue) : "";
|
|
2190
|
+
const hasSpacing = Boolean(paddingSummary || marginSummary || gapSummary);
|
|
2191
|
+
if (!hasSpacing) return null;
|
|
2192
|
+
const paddingMatched = !paddingSummary || Boolean(getSpaceStepMatch("padding", paddingValue, spaceSteps));
|
|
2193
|
+
const marginMatched = !marginSummary || Boolean(getSpaceStepMatch("margin", marginValue, spaceSteps));
|
|
2194
|
+
const gapMatched = !gapSummary || Boolean(getSpaceStepMatch("gap", gapValue, spaceSteps));
|
|
2195
|
+
return paddingMatched && marginMatched && gapMatched ? "token" : "raw";
|
|
2196
|
+
}
|
|
2017
2197
|
var TOKEN_TYPES = [
|
|
2018
2198
|
{ key: "bg", label: "\u80CC\u666F\u8272", code: "bg" },
|
|
2019
2199
|
{ key: "text", label: "\u6587\u5B57\u8272", code: "text" },
|
|
@@ -2037,9 +2217,15 @@ var TOKEN_STATES = [
|
|
|
2037
2217
|
{ key: "warning", label: "\u8B66\u544A\u6001", code: "warning" }
|
|
2038
2218
|
];
|
|
2039
2219
|
function ColorDropdown({ value, onChange, onClose, onAddToken, pos, colorPalette }) {
|
|
2040
|
-
const
|
|
2220
|
+
const resolvedValue = resolveColorValue(value);
|
|
2221
|
+
const initHex = /^#[0-9a-f]{6}$/i.test(resolvedValue) ? resolvedValue : "#6b7280";
|
|
2222
|
+
const initAlpha = (() => {
|
|
2223
|
+
const rgbaMatch = value.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)$/i);
|
|
2224
|
+
if (!rgbaMatch) return 100;
|
|
2225
|
+
return Math.max(0, Math.min(100, Math.round(parseFloat(rgbaMatch[4]) * 100)));
|
|
2226
|
+
})();
|
|
2041
2227
|
const [hexInput, setHexInput] = (0, import_react2.useState)(initHex);
|
|
2042
|
-
const [alpha, setAlpha] = (0, import_react2.useState)(
|
|
2228
|
+
const [alpha, setAlpha] = (0, import_react2.useState)(initAlpha);
|
|
2043
2229
|
const customColorInputRef = (0, import_react2.useRef)(null);
|
|
2044
2230
|
function buildColor(hex, a) {
|
|
2045
2231
|
const m = hex.match(/^#([0-9a-f]{6})$/i);
|
|
@@ -2309,10 +2495,11 @@ function AddTokenModal({ value, cssProp, elementClasses, onClose, onConfirm, col
|
|
|
2309
2495
|
}
|
|
2310
2496
|
function getDisplayLabel(val, tokenMap, colorPalette, tokenLabels) {
|
|
2311
2497
|
if (isTransparentColor(val)) return { label: "\u65E0", sub: "", isHardcoded: true };
|
|
2312
|
-
const
|
|
2313
|
-
const
|
|
2498
|
+
const resolvedVal = resolveColorValue(val);
|
|
2499
|
+
const displayVal = formatColorDisplay(resolvedVal);
|
|
2500
|
+
const paletteLabel = getColorLabel(resolvedVal, colorPalette);
|
|
2314
2501
|
if (paletteLabel) return { label: paletteLabel, sub: displayVal, isHardcoded: false };
|
|
2315
|
-
const token = tokenMap[val];
|
|
2502
|
+
const token = tokenMap[val] ?? tokenMap[resolvedVal];
|
|
2316
2503
|
if (token) return { label: tokenLabels[token] ?? token.replace("--", ""), sub: displayVal, isHardcoded: false };
|
|
2317
2504
|
return { label: displayVal, sub: "", isHardcoded: true };
|
|
2318
2505
|
}
|
|
@@ -2595,6 +2782,7 @@ function InspectorPanel({
|
|
|
2595
2782
|
const {
|
|
2596
2783
|
colorPalette,
|
|
2597
2784
|
tokenLabels,
|
|
2785
|
+
inspectorTypography,
|
|
2598
2786
|
radiusPresets,
|
|
2599
2787
|
spaceSteps,
|
|
2600
2788
|
borderWidthSteps,
|
|
@@ -2609,6 +2797,28 @@ function InspectorPanel({
|
|
|
2609
2797
|
{ cssVar: "", value: "none", label: "\u65E0", usage: "\u4E0D\u4F7F\u7528\u9634\u5F71" },
|
|
2610
2798
|
...shadowTokens
|
|
2611
2799
|
];
|
|
2800
|
+
const inspectorTypographyVars = {
|
|
2801
|
+
"--di-text-title-size": inspectorTypography.title.fontSize,
|
|
2802
|
+
"--di-text-title-weight": inspectorTypography.title.fontWeight,
|
|
2803
|
+
"--di-text-title-line-height": inspectorTypography.title.lineHeight,
|
|
2804
|
+
"--di-text-title-color": inspectorTypography.title.color,
|
|
2805
|
+
"--di-text-label-size": inspectorTypography.sectionLabel.fontSize,
|
|
2806
|
+
"--di-text-label-weight": inspectorTypography.sectionLabel.fontWeight,
|
|
2807
|
+
"--di-text-label-line-height": inspectorTypography.sectionLabel.lineHeight,
|
|
2808
|
+
"--di-text-label-color": inspectorTypography.sectionLabel.color,
|
|
2809
|
+
"--di-text-body-size": inspectorTypography.body.fontSize,
|
|
2810
|
+
"--di-text-body-weight": inspectorTypography.body.fontWeight,
|
|
2811
|
+
"--di-text-body-line-height": inspectorTypography.body.lineHeight,
|
|
2812
|
+
"--di-text-body-color": inspectorTypography.body.color,
|
|
2813
|
+
"--di-text-meta-size": inspectorTypography.meta.fontSize,
|
|
2814
|
+
"--di-text-meta-weight": inspectorTypography.meta.fontWeight,
|
|
2815
|
+
"--di-text-meta-line-height": inspectorTypography.meta.lineHeight,
|
|
2816
|
+
"--di-text-meta-color": inspectorTypography.meta.color,
|
|
2817
|
+
"--di-text-tiny-badge-size": inspectorTypography.tinyBadge.fontSize,
|
|
2818
|
+
"--di-text-tiny-badge-weight": inspectorTypography.tinyBadge.fontWeight,
|
|
2819
|
+
"--di-text-tiny-badge-line-height": inspectorTypography.tinyBadge.lineHeight,
|
|
2820
|
+
"--di-text-tiny-badge-color": inspectorTypography.tinyBadge.color
|
|
2821
|
+
};
|
|
2612
2822
|
const [isEditing, setIsEditing] = (0, import_react2.useState)(false);
|
|
2613
2823
|
const panelElRef = (0, import_react2.useRef)(null);
|
|
2614
2824
|
const [selected, setSelected] = (0, import_react2.useState)(targetEl);
|
|
@@ -2708,6 +2918,9 @@ function InspectorPanel({
|
|
|
2708
2918
|
const [cardVariantVal, setCardVariantVal] = (0, import_react2.useState)("default");
|
|
2709
2919
|
const [cardVariantClassVal, setCardVariantClassVal] = (0, import_react2.useState)("");
|
|
2710
2920
|
const [pendingCardVariant, setPendingCardVariant] = (0, import_react2.useState)("");
|
|
2921
|
+
const [componentInfoOpen, setComponentInfoOpen] = (0, import_react2.useState)(false);
|
|
2922
|
+
const [annotationOpen, setAnnotationOpen] = (0, import_react2.useState)(false);
|
|
2923
|
+
const [annotationText, setAnnotationText] = (0, import_react2.useState)("");
|
|
2711
2924
|
const [componentMakerSourceMode, setComponentMakerSourceMode] = (0, import_react2.useState)("new");
|
|
2712
2925
|
const [componentMakerAction, setComponentMakerAction] = (0, import_react2.useState)("create-current");
|
|
2713
2926
|
const [componentSpecDraft, setComponentSpecDraft] = (0, import_react2.useState)(EMPTY_COMPONENT_SPEC_DRAFT);
|
|
@@ -2742,6 +2955,8 @@ function InspectorPanel({
|
|
|
2742
2955
|
const [selectedLibraryComponentVariantId, setSelectedLibraryComponentVariantId] = (0, import_react2.useState)("");
|
|
2743
2956
|
const [libraryTokenForm, setLibraryTokenForm] = (0, import_react2.useState)(null);
|
|
2744
2957
|
const [libraryComponentForm, setLibraryComponentForm] = (0, import_react2.useState)(null);
|
|
2958
|
+
const [libraryComponentImportOpen, setLibraryComponentImportOpen] = (0, import_react2.useState)(false);
|
|
2959
|
+
const [libraryComponentImportMsg, setLibraryComponentImportMsg] = (0, import_react2.useState)("");
|
|
2745
2960
|
const [libraryCustomTokens, setLibraryCustomTokens] = (0, import_react2.useState)([]);
|
|
2746
2961
|
const [libraryTokenOverrides, setLibraryTokenOverrides] = (0, import_react2.useState)({});
|
|
2747
2962
|
const [libraryDeletedTokenIds, setLibraryDeletedTokenIds] = (0, import_react2.useState)({});
|
|
@@ -2758,6 +2973,9 @@ function InspectorPanel({
|
|
|
2758
2973
|
(0, import_react2.useEffect)(() => {
|
|
2759
2974
|
localDraftsRef.current = localDrafts;
|
|
2760
2975
|
}, [localDrafts]);
|
|
2976
|
+
(0, import_react2.useEffect)(() => {
|
|
2977
|
+
setComponentInfoOpen(false);
|
|
2978
|
+
}, [selected]);
|
|
2761
2979
|
const formatStyleIntentSummary = (0, import_react2.useCallback)((r) => ({
|
|
2762
2980
|
pendingCount: r.pendingCount ?? 0,
|
|
2763
2981
|
latestPending: r.latestPending ? {
|
|
@@ -2806,6 +3024,50 @@ function InspectorPanel({
|
|
|
2806
3024
|
return next;
|
|
2807
3025
|
});
|
|
2808
3026
|
}
|
|
3027
|
+
function getAnnotationTargetInfo(el) {
|
|
3028
|
+
const componentMeta2 = getInspectorComponentMeta(el);
|
|
3029
|
+
const selector = getSelectorForScope(el, "current");
|
|
3030
|
+
return {
|
|
3031
|
+
key: `current:${selector}`,
|
|
3032
|
+
selector,
|
|
3033
|
+
targetLabel: getTargetDisplayLabel(el, componentMeta2),
|
|
3034
|
+
scopeLabel: "\u5F53\u524D\u5143\u7D20"
|
|
3035
|
+
};
|
|
3036
|
+
}
|
|
3037
|
+
function getAnnotationChange(changes = []) {
|
|
3038
|
+
return changes.find((change) => change.prop === "annotation:intent");
|
|
3039
|
+
}
|
|
3040
|
+
function updateAnnotationDraft(nextText) {
|
|
3041
|
+
const el = selectedRef.current;
|
|
3042
|
+
if (!el) return;
|
|
3043
|
+
const text = nextText.trim();
|
|
3044
|
+
const info = getAnnotationTargetInfo(el);
|
|
3045
|
+
setLocalDrafts((prev) => {
|
|
3046
|
+
const existing = prev[info.key];
|
|
3047
|
+
const remainingChanges = existing?.changes.filter((change2) => change2.prop !== "annotation:intent") ?? [];
|
|
3048
|
+
if (!text) {
|
|
3049
|
+
if (!existing) return prev;
|
|
3050
|
+
const next = { ...prev };
|
|
3051
|
+
if (remainingChanges.length === 0) {
|
|
3052
|
+
delete next[info.key];
|
|
3053
|
+
} else {
|
|
3054
|
+
next[info.key] = { ...existing, changes: remainingChanges, updatedAt: Date.now() };
|
|
3055
|
+
}
|
|
3056
|
+
return next;
|
|
3057
|
+
}
|
|
3058
|
+
const change = {
|
|
3059
|
+
prop: "annotation:intent",
|
|
3060
|
+
from: "AI\u8BC6\u522B",
|
|
3061
|
+
val: text
|
|
3062
|
+
};
|
|
3063
|
+
const nextEntry = {
|
|
3064
|
+
...info,
|
|
3065
|
+
changes: [...remainingChanges, change],
|
|
3066
|
+
updatedAt: Date.now()
|
|
3067
|
+
};
|
|
3068
|
+
return { ...prev, [info.key]: nextEntry };
|
|
3069
|
+
});
|
|
3070
|
+
}
|
|
2809
3071
|
const selectEl = (0, import_react2.useCallback)((el) => {
|
|
2810
3072
|
selectedRef.current = el;
|
|
2811
3073
|
const rect = el.getBoundingClientRect();
|
|
@@ -2814,6 +3076,8 @@ function InspectorPanel({
|
|
|
2814
3076
|
const elCs = getComputedStyle(el);
|
|
2815
3077
|
const selectedComponentMeta = getInspectorComponentMeta(el);
|
|
2816
3078
|
const selectedCapability = getComponentCapability(selectedComponentMeta);
|
|
3079
|
+
const annotationDraft = localDraftsRef.current[getAnnotationTargetInfo(el).key];
|
|
3080
|
+
setAnnotationText(getAnnotationChange(annotationDraft?.changes)?.val ?? "");
|
|
2817
3081
|
const isButtonComponent = selectedCapability?.type === "Button";
|
|
2818
3082
|
const isIconComponent = selectedCapability?.type === "Icon";
|
|
2819
3083
|
const isBadgeComponent = selectedCapability?.type === "Badge";
|
|
@@ -3276,6 +3540,15 @@ function InspectorPanel({
|
|
|
3276
3540
|
setPendingBadgeStatus(status);
|
|
3277
3541
|
setBadgeStatusOnTargets(targets, status);
|
|
3278
3542
|
}
|
|
3543
|
+
function updateBadgeStatusOnElement(element, status) {
|
|
3544
|
+
const currentStatus = inferBadgeStatus(getClasses(element));
|
|
3545
|
+
const currentClass = getBadgeStatusClass(element);
|
|
3546
|
+
if (status === currentStatus) {
|
|
3547
|
+
setBadgeStatusOnTargets([element], currentStatus, currentClass);
|
|
3548
|
+
return;
|
|
3549
|
+
}
|
|
3550
|
+
setBadgeStatusOnTargets([element], status);
|
|
3551
|
+
}
|
|
3279
3552
|
function updateCardVariant(variant) {
|
|
3280
3553
|
const targets = getComponentTargets();
|
|
3281
3554
|
if (variant === cardVariantVal) {
|
|
@@ -4129,6 +4402,7 @@ function InspectorPanel({
|
|
|
4129
4402
|
}
|
|
4130
4403
|
function copyPluginPrompt(prompt, successMsg) {
|
|
4131
4404
|
if (!prompt) return;
|
|
4405
|
+
debugAiPrompt(prompt, "plugin");
|
|
4132
4406
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4133
4407
|
setPluginMsg(copied ? successMsg : "\u590D\u5236\u5931\u8D25");
|
|
4134
4408
|
setTimeout(() => setPluginMsg(""), copied ? 2200 : 1800);
|
|
@@ -4466,6 +4740,7 @@ function InspectorPanel({
|
|
|
4466
4740
|
return `${item.label} / ${item.type} / ${item.categoryLabel} / ${item.summary || "\u672A\u767B\u8BB0\u80FD\u529B"} / ${item.selector || "\u672A\u767B\u8BB0 selector"} / ${item.status}`;
|
|
4467
4741
|
}
|
|
4468
4742
|
function openLibraryComponentCreate() {
|
|
4743
|
+
setLibraryComponentImportOpen(false);
|
|
4469
4744
|
setLibraryComponentForm({
|
|
4470
4745
|
mode: "create",
|
|
4471
4746
|
category: libraryComponentCategory === "all" ? "custom" : libraryComponentCategory,
|
|
@@ -4477,6 +4752,7 @@ function InspectorPanel({
|
|
|
4477
4752
|
});
|
|
4478
4753
|
}
|
|
4479
4754
|
function openLibraryComponentEdit(item) {
|
|
4755
|
+
setLibraryComponentImportOpen(false);
|
|
4480
4756
|
setSelectedLibraryComponentId(item.id);
|
|
4481
4757
|
setLibraryComponentForm({
|
|
4482
4758
|
mode: "update",
|
|
@@ -4489,6 +4765,103 @@ function InspectorPanel({
|
|
|
4489
4765
|
status: item.status.includes("\u8349\u7A3F") ? item.status : "\u7F16\u8F91\u8349\u7A3F"
|
|
4490
4766
|
});
|
|
4491
4767
|
}
|
|
4768
|
+
function normalizeComponentImportDraft(raw) {
|
|
4769
|
+
const type = String(raw.type || "").trim() || "Custom";
|
|
4770
|
+
const category = raw.category || getLibraryComponentCategory(type);
|
|
4771
|
+
const variantText = Array.isArray(raw.variants) && raw.variants.length ? `\u53D8\u4F53\uFF1A${raw.variants.join(" / ")}` : "";
|
|
4772
|
+
const sizeText = Array.isArray(raw.sizes) && raw.sizes.length ? `\u5C3A\u5BF8\uFF1A${raw.sizes.join(" / ")}` : "";
|
|
4773
|
+
const tokenText = Array.isArray(raw.tokenRefs) && raw.tokenRefs.length ? `Token\uFF1A${raw.tokenRefs.join(" / ")}` : "";
|
|
4774
|
+
return {
|
|
4775
|
+
mode: "create",
|
|
4776
|
+
category,
|
|
4777
|
+
type,
|
|
4778
|
+
label: String(raw.label || LIBRARY_COMPONENT_LABELS[type] || type).trim(),
|
|
4779
|
+
summary: String(raw.summary || [variantText, sizeText, tokenText].filter(Boolean).join("\uFF1B") || "\u5BFC\u5165\u7EC4\u4EF6\u8349\u7A3F").trim(),
|
|
4780
|
+
selector: String(raw.selector || `.${type.toLowerCase()}`).trim(),
|
|
4781
|
+
status: String(raw.status || "\u5BFC\u5165\u8349\u7A3F").trim()
|
|
4782
|
+
};
|
|
4783
|
+
}
|
|
4784
|
+
function submitImportedLibraryComponents(drafts) {
|
|
4785
|
+
const normalized = drafts.map(normalizeComponentImportDraft);
|
|
4786
|
+
const nextItems = normalized.map((form, index) => ({
|
|
4787
|
+
id: `draft-component-import:${Date.now()}:${index}:${form.type}`,
|
|
4788
|
+
category: form.category,
|
|
4789
|
+
categoryLabel: getLibraryComponentCategoryLabel(form.category),
|
|
4790
|
+
type: form.type,
|
|
4791
|
+
label: form.label,
|
|
4792
|
+
summary: form.summary,
|
|
4793
|
+
selector: form.selector,
|
|
4794
|
+
status: form.status,
|
|
4795
|
+
source: "draft"
|
|
4796
|
+
}));
|
|
4797
|
+
if (!nextItems.length) {
|
|
4798
|
+
setLibraryComponentImportMsg("\u6CA1\u6709\u8BC6\u522B\u5230\u7EC4\u4EF6");
|
|
4799
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4800
|
+
return;
|
|
4801
|
+
}
|
|
4802
|
+
setLibraryCustomComponents((prev) => [...nextItems, ...prev]);
|
|
4803
|
+
setSelectedLibraryComponentId(nextItems[0].id);
|
|
4804
|
+
nextItems.forEach((item) => {
|
|
4805
|
+
recordLibraryCrudChange({
|
|
4806
|
+
resource: "component",
|
|
4807
|
+
action: "create",
|
|
4808
|
+
name: item.type,
|
|
4809
|
+
from: "\u672A\u767B\u8BB0",
|
|
4810
|
+
val: formatLibraryComponentSummary(item)
|
|
4811
|
+
});
|
|
4812
|
+
});
|
|
4813
|
+
setLibraryComponentImportMsg(`\u5DF2\u5BFC\u5165 ${nextItems.length} \u4E2A\u7EC4\u4EF6\u8349\u7A3F`);
|
|
4814
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 2200);
|
|
4815
|
+
}
|
|
4816
|
+
async function handleComponentImportFile(file) {
|
|
4817
|
+
if (!file) return;
|
|
4818
|
+
try {
|
|
4819
|
+
const content = await file.text();
|
|
4820
|
+
const parsed = JSON.parse(content);
|
|
4821
|
+
const drafts = Array.isArray(parsed) ? parsed : parsed.components ?? [];
|
|
4822
|
+
submitImportedLibraryComponents(drafts);
|
|
4823
|
+
} catch {
|
|
4824
|
+
setLibraryComponentImportMsg("JSON \u89E3\u6790\u5931\u8D25");
|
|
4825
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4826
|
+
}
|
|
4827
|
+
}
|
|
4828
|
+
function copyComponentLibraryImportPrompt() {
|
|
4829
|
+
const prompt = [
|
|
4830
|
+
"\u8BF7\u4E3A\u5F53\u524D\u9879\u76EE\u751F\u6210 DevInspector \u7EC4\u4EF6\u5E93\u63A5\u5165\u8349\u7A3F\u3002",
|
|
4831
|
+
"",
|
|
4832
|
+
"\u76EE\u6807\uFF1A",
|
|
4833
|
+
"1. \u626B\u63CF\u73B0\u6709\u7EC4\u4EF6\u6E90\u7801\uFF0C\u8BC6\u522B\u7EC4\u4EF6 type\u3001\u4E2D\u6587 label\u3001selector\u3001\u53D8\u4F53\u3001\u5C3A\u5BF8\u548C tokenRefs\u3002",
|
|
4834
|
+
"2. \u4F18\u5148\u4F7F\u7528 data-component / registry / \u7A33\u5B9A class\uFF1B\u4E0D\u786E\u5B9A\u9879\u6807\u4E3A\u201C\u5F85\u786E\u8BA4\u201D\u3002",
|
|
4835
|
+
"3. \u8F93\u51FA componentPreviews registry \u6216\u4E0B\u9762\u8FD9\u79CD JSON \u8349\u7A3F\u3002",
|
|
4836
|
+
"",
|
|
4837
|
+
"JSON \u683C\u5F0F\uFF1A",
|
|
4838
|
+
"{",
|
|
4839
|
+
' "components": [',
|
|
4840
|
+
" {",
|
|
4841
|
+
' "type": "Button",',
|
|
4842
|
+
' "label": "\u6309\u94AE",',
|
|
4843
|
+
' "category": "action",',
|
|
4844
|
+
' "summary": "\u4E3B\u6309\u94AE\u3001\u6B21\u6309\u94AE\u3001\u5F31\u6309\u94AE",',
|
|
4845
|
+
' "selector": ".button, [data-component=\\"Button\\"]",',
|
|
4846
|
+
' "variants": ["primary", "secondary", "ghost"],',
|
|
4847
|
+
' "sizes": ["s", "m", "l"],',
|
|
4848
|
+
' "tokenRefs": ["--color-brand-primary"],',
|
|
4849
|
+
' "status": "\u5F85\u786E\u8BA4"',
|
|
4850
|
+
" }",
|
|
4851
|
+
" ]",
|
|
4852
|
+
"}",
|
|
4853
|
+
"",
|
|
4854
|
+
"\u7EA6\u675F\uFF1A\u8BF7\u4FEE\u6539\u6E90\u7801\u5C42\u63A5\u5165\uFF0C\u4E0D\u8981\u76F4\u63A5\u6539 dist \u4EA7\u7269\u3002"
|
|
4855
|
+
].join("\n");
|
|
4856
|
+
debugAiPrompt(prompt, "plugin");
|
|
4857
|
+
copyTextToClipboard(prompt).then((copied) => {
|
|
4858
|
+
setLibraryComponentImportMsg(copied ? "\u63A5\u5165\u63D0\u793A\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4859
|
+
setTimeout(() => setLibraryComponentImportMsg(""), copied ? 2200 : 1800);
|
|
4860
|
+
}).catch(() => {
|
|
4861
|
+
setLibraryComponentImportMsg("\u590D\u5236\u5931\u8D25");
|
|
4862
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4863
|
+
});
|
|
4864
|
+
}
|
|
4492
4865
|
function submitLibraryComponentForm() {
|
|
4493
4866
|
if (!libraryComponentForm) return;
|
|
4494
4867
|
const category = libraryComponentForm.category || getLibraryComponentCategory(libraryComponentForm.type);
|
|
@@ -4544,47 +4917,79 @@ function InspectorPanel({
|
|
|
4544
4917
|
});
|
|
4545
4918
|
}
|
|
4546
4919
|
function buildAiTaskPrompt(params) {
|
|
4547
|
-
const changes = params.changes
|
|
4548
|
-
const latestHint = params.entryId ? `\u4F18\u5148\u5904\u7406 id = ${params.entryId} \u8FD9\u6761\u8BB0\u5F55\u3002` : "\u8FD9\u6761\u4EFB\u52A1\u6765\u81EA DevInspector \u5F53\u524D\u9009\u4E2D\u5143\u7D20\u3002";
|
|
4920
|
+
const changes = formatPromptChanges(params.changes);
|
|
4549
4921
|
return [
|
|
4550
|
-
"DevInspector \u6837\u5F0F\u4EFB\u52A1",
|
|
4551
4922
|
`\u9875\u9762\uFF1A${params.pageLabel}`,
|
|
4552
|
-
|
|
4923
|
+
"\u5F85\u5904\u7406\u5BF9\u8C61\uFF1A1",
|
|
4924
|
+
`1. \u5143\u7D20\uFF1A${params.targetLabel}`,
|
|
4553
4925
|
`\u8303\u56F4\uFF1A${params.scopeLabel}`,
|
|
4554
4926
|
`\u9009\u62E9\u5668\uFF1A${params.selector}`,
|
|
4927
|
+
`\u7C7B\u578B\uFF1A${getPromptChangeTypes(params.changes).join(" / ") || "none"}`,
|
|
4555
4928
|
"\u6539\u52A8\uFF1A",
|
|
4556
|
-
changes || "\u65E0\
|
|
4929
|
+
changes || "1. \u65E0\u6539\u52A8",
|
|
4557
4930
|
...params.note ? ["\u8865\u5145\uFF1A", params.note] : [],
|
|
4558
|
-
"\u5B9A\u4F4D\
|
|
4559
|
-
latestHint,
|
|
4560
|
-
"\u8BF7\u4F18\u5148\u5B9A\u4F4D\u8BE5\u9009\u62E9\u5668\u5BF9\u5E94\u7684\u7EC4\u4EF6\u6216\u6837\u5F0F\u6E90\u7801\uFF0C\u5224\u65AD\u662F\u5426\u5E94\u56FA\u5316\u4E3A\u6B63\u5F0F\u7EC4\u4EF6\u6837\u5F0F\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002"
|
|
4931
|
+
"\u7ED9AI\uFF1A\u6309\u9009\u62E9\u5668\u5148\u5B9A\u4F4D\u6E90\u7801\uFF0C\u518D\u5224\u65AD\u843D\u4E3A\u7EC4\u4EF6\u6837\u5F0F\u3001token\u3001\u5C40\u90E8\u8986\u76D6\u6216\u5B9E\u73B0\u7EA6\u675F\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002"
|
|
4561
4932
|
].join("\n");
|
|
4562
4933
|
}
|
|
4563
4934
|
function buildAiDraftBasketPrompt(drafts) {
|
|
4564
4935
|
const hasComponentSpec = drafts.some((draft) => draft.changes.some((change) => change.prop === "component-spec" || change.prop.startsWith("component-new-variant:") || change.prop.startsWith("component-variant-group:")));
|
|
4565
4936
|
const hasLibraryChange = drafts.some((draft) => draft.changes.some((change) => change.prop.startsWith("library-")));
|
|
4937
|
+
const mode = hasLibraryChange ? "library-crud" : hasComponentSpec ? "component-spec" : "style-update";
|
|
4566
4938
|
const sections = drafts.sort((a, b) => a.updatedAt - b.updatedAt).map((draft, index) => {
|
|
4567
|
-
const changes = draft.changes
|
|
4939
|
+
const changes = formatPromptChanges(draft.changes);
|
|
4568
4940
|
return [
|
|
4569
4941
|
`${index + 1}. \u5143\u7D20\uFF1A${draft.targetLabel}`,
|
|
4570
4942
|
`\u8303\u56F4\uFF1A${draft.scopeLabel}`,
|
|
4571
4943
|
`\u9009\u62E9\u5668\uFF1A${draft.selector}`,
|
|
4944
|
+
`\u7C7B\u578B\uFF1A${getPromptChangeTypes(draft.changes).join(" / ") || "none"}`,
|
|
4572
4945
|
"\u6539\u52A8\uFF1A",
|
|
4573
|
-
changes || "\u65E0\
|
|
4946
|
+
changes || "1. \u65E0\u6539\u52A8"
|
|
4574
4947
|
].join("\n");
|
|
4575
4948
|
}).join("\n\n");
|
|
4576
|
-
const
|
|
4577
|
-
const locationHint = hasLibraryChange ? "\u8FD9\u4E9B\u5185\u5BB9\u6765\u81EA DevInspector \u8BBE\u8BA1\u5E93\u5DE5\u4F5C\u53F0\uFF1BToken / Component \u7684\u589E\u5220\u6539\u90FD\u662F\u7528\u6237\u786E\u8BA4\u7684\u53D7\u63A7\u8349\u7A3F\uFF0C\u8BF7\u5148\u5B9A\u4F4D\u8BBE\u8BA1 token \u914D\u7F6E\u3001\u7EC4\u4EF6\u80FD\u529B\u8868\u6216\u6E90\u7801\u4E2D\u7684\u6B63\u5F0F\u5B9A\u4E49\uFF0C\u518D\u5224\u65AD\u5982\u4F55\u843D\u5730\uFF1B\u5220\u9664\u64CD\u4F5C\u9700\u5148\u5904\u7406\u4F7F\u7528\u5173\u7CFB\uFF0C\u4E0D\u8981\u624B\u6539 dist\u3002" : hasComponentSpec ? "\u8FD9\u4E9B\u5185\u5BB9\u6765\u81EA DevInspector \u672C\u6B21\u4FEE\u6539\u5185\u5BB9\uFF1B\u7EC4\u4EF6\u89C4\u683C\u548C\u65B0\u53D8\u4F53\u662F\u7528\u6237\u786E\u8BA4\u7684\u8349\u7A3F\uFF0C\u8BF7\u6309\u7EC4\u4EF6\u540D\u3001\u53EF\u7F16\u8F91\u5185\u5BB9\u3001\u53D8\u4F53\u7EF4\u5EA6\u3001\u72B6\u6001\u3001\u5C3A\u5BF8\u548C\u6837\u5F0F\u89C4\u5219\u5B9A\u4F4D\u6E90\u7801\u843D\u5730\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002" : "\u8FD9\u4E9B\u5185\u5BB9\u6765\u81EA DevInspector \u672C\u6B21\u4FEE\u6539\u5185\u5BB9\uFF0C\u8BF7\u6309\u5BF9\u8C61\u9010\u4E00\u5B9A\u4F4D\u6E90\u7801\uFF0C\u5224\u65AD\u662F\u5426\u5E94\u56FA\u5316\u4E3A\u7EC4\u4EF6\u6837\u5F0F\u3001token \u6216\u5C40\u90E8\u8986\u76D6\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002";
|
|
4949
|
+
const aiHint = hasLibraryChange ? "\u7ED9AI\uFF1A\u5148\u5B9A\u4F4D\u6B63\u5F0F token \u914D\u7F6E\u3001\u7EC4\u4EF6\u80FD\u529B\u8868\u6216\u6E90\u7801\u5B9A\u4E49\uFF0C\u518D\u5904\u7406\u589E\u5220\u6539\uFF1B\u5220\u9664\u524D\u5148\u68C0\u67E5\u4F7F\u7528\u5173\u7CFB\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002" : hasComponentSpec ? "\u7ED9AI\uFF1A\u7EC4\u4EF6\u89C4\u683C\u548C\u65B0\u53D8\u4F53\u6309\u5DF2\u786E\u8BA4\u8349\u7A3F\u5904\u7406\uFF1B\u5148\u5B9A\u4F4D\u7EC4\u4EF6\u5B9A\u4E49\u3001\u53EF\u7F16\u8F91\u5185\u5BB9\u3001\u53D8\u4F53\u7EF4\u5EA6\u548C token \u6620\u5C04\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002" : "\u7ED9AI\uFF1A\u6309\u5BF9\u8C61\u9010\u4E00\u5B9A\u4F4D\u6E90\u7801\uFF0C\u518D\u5224\u65AD\u843D\u4E3A\u7EC4\u4EF6\u6837\u5F0F\u3001token\u3001\u5C40\u90E8\u8986\u76D6\u6216\u5B9E\u73B0\u7EA6\u675F\uFF1B\u4E0D\u8981\u624B\u6539 dist\u3002";
|
|
4578
4950
|
return [
|
|
4579
|
-
title,
|
|
4580
4951
|
`\u9875\u9762\uFF1A${document.title || "\u5F53\u524D\u9875\u9762"}\uFF08${window.location.href}\uFF09`,
|
|
4581
4952
|
`\u5F85\u5904\u7406\u5BF9\u8C61\uFF1A${drafts.length}`,
|
|
4582
4953
|
sections,
|
|
4583
4954
|
...note ? ["\u8865\u5145\uFF1A", note] : [],
|
|
4584
|
-
|
|
4585
|
-
locationHint
|
|
4955
|
+
aiHint
|
|
4586
4956
|
].join("\n");
|
|
4587
4957
|
}
|
|
4958
|
+
function getPromptChangeType(prop) {
|
|
4959
|
+
if (prop.startsWith("annotation:")) return "annotation";
|
|
4960
|
+
if (prop === "component-spec") return "component-spec";
|
|
4961
|
+
if (prop.startsWith("component-new-variant:")) return "component-new-variant";
|
|
4962
|
+
if (prop.startsWith("component-variant-group:")) return "component-variant-group";
|
|
4963
|
+
if (prop.startsWith("library-token:create")) return "library-token-create";
|
|
4964
|
+
if (prop.startsWith("library-token:update")) return "library-token-update";
|
|
4965
|
+
if (prop.startsWith("library-token:delete")) return "library-token-delete";
|
|
4966
|
+
if (prop.startsWith("library-component:create")) return "library-component-create";
|
|
4967
|
+
if (prop.startsWith("library-component:update")) return "library-component-update";
|
|
4968
|
+
if (prop.startsWith("library-component:delete")) return "library-component-delete";
|
|
4969
|
+
return "style";
|
|
4970
|
+
}
|
|
4971
|
+
function getPromptChangeTypes(changes) {
|
|
4972
|
+
return Array.from(new Set(changes.map((change) => getPromptChangeType(change.prop))));
|
|
4973
|
+
}
|
|
4974
|
+
function formatPromptChanges(changes) {
|
|
4975
|
+
return changes.map((change, index) => {
|
|
4976
|
+
const type = getPromptChangeType(change.prop);
|
|
4977
|
+
if (type === "annotation") {
|
|
4978
|
+
return [
|
|
4979
|
+
`${index + 1}. \u6807\u6CE8\uFF1A${change.val || "\u7A7A"}`
|
|
4980
|
+
].join("\n");
|
|
4981
|
+
}
|
|
4982
|
+
return [
|
|
4983
|
+
`${index + 1}. ${getChangeLabel(change.prop)}\uFF1A${formatStoredChangeRecordValue(change.prop, change.from) || "\u7A7A"} \u2192 ${formatStoredChangeRecordValue(change.prop, change.val) || "\u7A7A"}`
|
|
4984
|
+
].join("\n");
|
|
4985
|
+
}).join("\n");
|
|
4986
|
+
}
|
|
4987
|
+
function debugAiPrompt(prompt, source) {
|
|
4988
|
+
window.__DEV_INSPECTOR_LAST_PROMPT__ = prompt;
|
|
4989
|
+
console.groupCollapsed(`[DevInspector] AI prompt (${source})`);
|
|
4990
|
+
console.log(prompt);
|
|
4991
|
+
console.groupEnd();
|
|
4992
|
+
}
|
|
4588
4993
|
function handleSubmitToAi() {
|
|
4589
4994
|
const draftEntries = Object.values(localDraftsRef.current);
|
|
4590
4995
|
if (draftEntries.length > 0) {
|
|
@@ -4612,8 +5017,9 @@ function InspectorPanel({
|
|
|
4612
5017
|
changes,
|
|
4613
5018
|
note
|
|
4614
5019
|
});
|
|
5020
|
+
debugAiPrompt(prompt, "single");
|
|
4615
5021
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4616
|
-
setSubmitMsg(copied ? "\
|
|
5022
|
+
setSubmitMsg(copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4617
5023
|
setTimeout(() => setSubmitMsg(""), copied ? 2200 : 1800);
|
|
4618
5024
|
}).catch(() => {
|
|
4619
5025
|
setSubmitMsg("\u590D\u5236\u5931\u8D25");
|
|
@@ -4622,8 +5028,9 @@ function InspectorPanel({
|
|
|
4622
5028
|
}
|
|
4623
5029
|
function copyDraftEntriesToAi(draftEntries) {
|
|
4624
5030
|
const prompt = buildAiDraftBasketPrompt(draftEntries);
|
|
5031
|
+
debugAiPrompt(prompt, "draft-basket");
|
|
4625
5032
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4626
|
-
setSubmitMsg(copied ? "\
|
|
5033
|
+
setSubmitMsg(copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4627
5034
|
setTimeout(() => setSubmitMsg(""), copied ? 2200 : 1800);
|
|
4628
5035
|
}).catch(() => {
|
|
4629
5036
|
setSubmitMsg("\u590D\u5236\u5931\u8D25");
|
|
@@ -4805,6 +5212,9 @@ function InspectorPanel({
|
|
|
4805
5212
|
});
|
|
4806
5213
|
});
|
|
4807
5214
|
function getChangeLabel(prop) {
|
|
5215
|
+
if (prop.startsWith("annotation:")) {
|
|
5216
|
+
return "\u6807\u6CE8 \xB7 AI\u8BC6\u522B";
|
|
5217
|
+
}
|
|
4808
5218
|
if (prop.startsWith("library-token:") || prop.startsWith("library-component:")) {
|
|
4809
5219
|
const [resource = "", action = "", name = "\u672A\u547D\u540D"] = prop.split(":");
|
|
4810
5220
|
const resourceLabel = resource === "library-token" ? "Token" : "\u7EC4\u4EF6\u89C4\u683C";
|
|
@@ -4934,6 +5344,7 @@ function InspectorPanel({
|
|
|
4934
5344
|
function resetDraftChangeOnPage(draft, change) {
|
|
4935
5345
|
const isCurrentDraft = selectedRef.current ? getDraftTargetInfo(selectedRef.current).key === draft.key : false;
|
|
4936
5346
|
if (isCurrentDraft) clearPendingForProp(change.prop);
|
|
5347
|
+
if (change.prop.startsWith("annotation:")) return;
|
|
4937
5348
|
if (change.prop.startsWith("library-")) return;
|
|
4938
5349
|
if (change.prop === "component-spec" || change.prop.startsWith("component-new-variant:")) return;
|
|
4939
5350
|
const targets = getDraftSelectorTargets(draft.selector);
|
|
@@ -5250,6 +5661,29 @@ function InspectorPanel({
|
|
|
5250
5661
|
const activeBadgeStatus = pendingBadgeStatus || badgeStatusVal;
|
|
5251
5662
|
const activeCardVariant = pendingCardVariant || cardVariantVal;
|
|
5252
5663
|
const componentSizeOptions = getComponentSizeControlOptions(componentCapability);
|
|
5664
|
+
const componentPrimaryText = pendingComponentText ?? componentTextDraft ?? componentTextVal ?? componentEditableSlots.map((slot) => componentTextSlotDrafts[slot.key] || componentTextSlotVals[slot.key] || "").find(Boolean) ?? textContent ?? "";
|
|
5665
|
+
const componentElementInfos = componentMeta ? (() => {
|
|
5666
|
+
const items = [];
|
|
5667
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5668
|
+
const pushItem = (label, element) => {
|
|
5669
|
+
if (!element || seen.has(element)) return;
|
|
5670
|
+
seen.add(element);
|
|
5671
|
+
items.push({
|
|
5672
|
+
key: `${label}:${getSelectorForScope(element, "current")}`,
|
|
5673
|
+
label,
|
|
5674
|
+
selector: getSelectorForScope(element, "current"),
|
|
5675
|
+
text: (element.textContent ?? "").trim() || "\u7A7A",
|
|
5676
|
+
style: getComponentElementStyleSummary(element),
|
|
5677
|
+
spacing: getComponentElementSpacingSummary(element),
|
|
5678
|
+
styleStatus: getComponentElementStyleStatus(element, tokenMap, colorPalette, tokenLabels, typographyTokens),
|
|
5679
|
+
spacingStatus: getComponentElementSpacingStatus(element, spaceSteps)
|
|
5680
|
+
});
|
|
5681
|
+
};
|
|
5682
|
+
pushItem("\u7EC4\u4EF6\u5916\u5C42", selected);
|
|
5683
|
+
componentEditableSlots.forEach((slot) => pushItem(slot.label, getComponentSlotElement(selected, slot)));
|
|
5684
|
+
componentChildSlots.forEach((slot) => pushItem(slot.label, getComponentSlotElement(selected, slot)));
|
|
5685
|
+
return items;
|
|
5686
|
+
})() : [];
|
|
5253
5687
|
const showElementStyleSections = !componentMeta;
|
|
5254
5688
|
const localDraftEntries = Object.values(localDrafts).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
5255
5689
|
const localDraftChangeCount = localDraftEntries.reduce((sum, entry) => sum + entry.changes.length, 0);
|
|
@@ -5636,7 +6070,7 @@ function InspectorPanel({
|
|
|
5636
6070
|
ref: panelElRef,
|
|
5637
6071
|
className: `di-panel${componentCreateOpen || libraryOpen ? " di-panel--drawer-open" : ""}${libraryWorkbenchOpen ? " di-panel--workbench-open" : ""}`,
|
|
5638
6072
|
"data-di-panel-role": "primary",
|
|
5639
|
-
style: { top: panelPos.top, left: panelPos.left },
|
|
6073
|
+
style: { top: panelPos.top, left: panelPos.left, ...inspectorTypographyVars },
|
|
5640
6074
|
children: [
|
|
5641
6075
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-head", onMouseDown: onDragStart, children: [
|
|
5642
6076
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-head-left", children: [
|
|
@@ -6057,7 +6491,24 @@ function InspectorPanel({
|
|
|
6057
6491
|
" \u4E2A\u89C4\u683C"
|
|
6058
6492
|
] })
|
|
6059
6493
|
] }),
|
|
6060
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
6494
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-toolbar-actions", children: [
|
|
6495
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
6496
|
+
"button",
|
|
6497
|
+
{
|
|
6498
|
+
type: "button",
|
|
6499
|
+
className: "di-library-workbench-soft-btn",
|
|
6500
|
+
onClick: () => {
|
|
6501
|
+
setLibraryComponentImportOpen(true);
|
|
6502
|
+
setLibraryComponentForm(null);
|
|
6503
|
+
},
|
|
6504
|
+
children: [
|
|
6505
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Upload, { size: 13, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6506
|
+
"\u5BFC\u5165\u7EC4\u4EF6\u5E93"
|
|
6507
|
+
]
|
|
6508
|
+
}
|
|
6509
|
+
),
|
|
6510
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "di-btn-save", onClick: openLibraryComponentCreate, children: "+ \u7EC4\u4EF6\u89C4\u683C" })
|
|
6511
|
+
] })
|
|
6061
6512
|
] }),
|
|
6062
6513
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-component-preview-grid", role: "list", "aria-label": "\u7EC4\u4EF6\u771F\u5B9E\u9884\u89C8", children: [
|
|
6063
6514
|
filteredLibraryComponentItems.map((item) => {
|
|
@@ -6129,7 +6580,7 @@ function InspectorPanel({
|
|
|
6129
6580
|
className: "di-btn-save",
|
|
6130
6581
|
disabled: localDraftChangeCount === 0,
|
|
6131
6582
|
onClick: handleSubmitToAi,
|
|
6132
|
-
children: submitMsg
|
|
6583
|
+
children: renderSubmitLabel(submitMsg)
|
|
6133
6584
|
}
|
|
6134
6585
|
)
|
|
6135
6586
|
] }),
|
|
@@ -6322,7 +6773,67 @@ function InspectorPanel({
|
|
|
6322
6773
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: () => focusLibraryTokenUsage(selectedLibraryToken), children: "\u5B9A\u4F4D\u4F7F\u7528" }),
|
|
6323
6774
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: () => openLibraryTokenEdit(selectedLibraryToken), children: "\u7F16\u8F91" })
|
|
6324
6775
|
] })
|
|
6325
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-workbench-empty", children: "\u9009\u62E9\u4E00\u4E2A token \u67E5\u770B\u8BE6\u60C5" }) : libraryTab === "components" ?
|
|
6776
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-workbench-empty", children: "\u9009\u62E9\u4E00\u4E2A token \u67E5\u770B\u8BE6\u60C5" }) : libraryTab === "components" ? libraryComponentImportOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-import-panel", children: [
|
|
6777
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-edit-head", children: [
|
|
6778
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u5BFC\u5165\u7EC4\u4EF6\u5E93" }),
|
|
6779
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "di-head-icon-btn", onClick: () => setLibraryComponentImportOpen(false), "aria-label": "\u5173\u95ED\u5BFC\u5165\u7EC4\u4EF6\u5E93", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.X, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }) })
|
|
6780
|
+
] }),
|
|
6781
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-import-steps", children: [
|
|
6782
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u9009\u4E00\u79CD\u65B9\u5F0F" }),
|
|
6783
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u751F\u6210\u63A5\u5165\u8349\u7A3F" }),
|
|
6784
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u53D1\u9001\u7ED9 AI \u843D\u5730" })
|
|
6785
|
+
] }),
|
|
6786
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-import-option di-library-import-option--primary", children: [
|
|
6787
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
6788
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.WandSparkles, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6789
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u8BA9 AI \u5E2E\u4F60\u6574\u7406" }),
|
|
6790
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u9002\u5408\u7B2C\u4E00\u6B21\u63A5\u5165\u3002\u4F1A\u590D\u5236\u4E00\u6BB5\u63D0\u793A\uFF0C\u8BA9 AI \u626B\u63CF\u9879\u76EE\u5E76\u751F\u6210\u7EC4\u4EF6\u6E05\u5355\u3002" })
|
|
6791
|
+
] }),
|
|
6792
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: copyComponentLibraryImportPrompt, children: "\u590D\u5236\u63D0\u793A" })
|
|
6793
|
+
] }),
|
|
6794
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "di-library-import-option", children: [
|
|
6795
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
6796
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Upload, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6797
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u5DF2\u6709\u7EC4\u4EF6\u6E05\u5355" }),
|
|
6798
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u4E0A\u4F20 JSON \u540E\u5148\u53D8\u6210\u8349\u7A3F\uFF0C\u4E0D\u4F1A\u76F4\u63A5\u6539\u6E90\u7801\u3002" })
|
|
6799
|
+
] }),
|
|
6800
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
6801
|
+
"input",
|
|
6802
|
+
{
|
|
6803
|
+
type: "file",
|
|
6804
|
+
accept: "application/json,.json",
|
|
6805
|
+
onChange: (event) => {
|
|
6806
|
+
void handleComponentImportFile(event.currentTarget.files?.[0] ?? null);
|
|
6807
|
+
event.currentTarget.value = "";
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
)
|
|
6811
|
+
] }),
|
|
6812
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-import-option", children: [
|
|
6813
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
6814
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Component, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6815
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u5148\u52A0\u4E00\u4E2A\u8BD5\u8BD5" }),
|
|
6816
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u53EA\u767B\u8BB0\u4E00\u4E2A\u7EC4\u4EF6\uFF0C\u6BD4\u5982 Button \u6216 Card\u3002" })
|
|
6817
|
+
] }),
|
|
6818
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: openLibraryComponentCreate, children: "\u6DFB\u52A0\u7EC4\u4EF6" })
|
|
6819
|
+
] }),
|
|
6820
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("details", { className: "di-library-import-format", children: [
|
|
6821
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("summary", { children: "\u67E5\u770B JSON \u683C\u5F0F" }),
|
|
6822
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { children: `{
|
|
6823
|
+
"components": [
|
|
6824
|
+
{
|
|
6825
|
+
"type": "Button",
|
|
6826
|
+
"label": "\u6309\u94AE",
|
|
6827
|
+
"category": "action",
|
|
6828
|
+
"selector": ".button",
|
|
6829
|
+
"variants": ["primary", "secondary"],
|
|
6830
|
+
"tokenRefs": ["--color-brand-primary"]
|
|
6831
|
+
}
|
|
6832
|
+
]
|
|
6833
|
+
}` })
|
|
6834
|
+
] }),
|
|
6835
|
+
libraryComponentImportMsg ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-import-msg", children: libraryComponentImportMsg }) : null
|
|
6836
|
+
] }) : libraryComponentForm ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-edit-panel", children: [
|
|
6326
6837
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-edit-head", children: [
|
|
6327
6838
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: libraryComponentForm.mode === "create" ? "\u65B0\u589E\u7EC4\u4EF6\u89C4\u683C" : "\u7F16\u8F91\u7EC4\u4EF6\u89C4\u683C" }),
|
|
6328
6839
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "di-head-icon-btn", onClick: () => setLibraryComponentForm(null), "aria-label": "\u5173\u95ED\u7EC4\u4EF6\u89C4\u683C\u8868\u5355", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.X, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }) })
|
|
@@ -6448,7 +6959,7 @@ function InspectorPanel({
|
|
|
6448
6959
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { children: "\u53EA\u751F\u6210 AI \u4EFB\u52A1\uFF0C\u4E0D\u76F4\u63A5\u5199\u6E90\u7801" })
|
|
6449
6960
|
] })
|
|
6450
6961
|
] }),
|
|
6451
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-detail-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: handleSubmitToAi, disabled: localDraftChangeCount === 0, children: submitMsg
|
|
6962
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-detail-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: handleSubmitToAi, disabled: localDraftChangeCount === 0, children: renderSubmitLabel(submitMsg) }) })
|
|
6452
6963
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-library-detail-card", children: [
|
|
6453
6964
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-library-detail-kicker", children: "Usage" }),
|
|
6454
6965
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u4F7F\u7528\u6CBB\u7406" }),
|
|
@@ -6480,7 +6991,7 @@ function InspectorPanel({
|
|
|
6480
6991
|
className: "di-btn-save",
|
|
6481
6992
|
disabled: localDraftChangeCount === 0,
|
|
6482
6993
|
onClick: handleSubmitToAi,
|
|
6483
|
-
children: submitMsg
|
|
6994
|
+
children: renderSubmitLabel(submitMsg)
|
|
6484
6995
|
}
|
|
6485
6996
|
)
|
|
6486
6997
|
] })
|
|
@@ -7051,18 +7562,74 @@ function InspectorPanel({
|
|
|
7051
7562
|
componentMeta && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-section", children: [
|
|
7052
7563
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-section-title", children: "\u7EC4\u4EF6" }),
|
|
7053
7564
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-card", children: [
|
|
7054
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7565
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-head", children: [
|
|
7566
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-main", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-title-row", children: [
|
|
7567
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-component-name", children: componentDisplayName }),
|
|
7568
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7569
|
+
MatchBadge,
|
|
7570
|
+
{
|
|
7571
|
+
label: componentCapability ? "\u5DF2\u5339\u914D" : "\u5F85\u8865\u5145",
|
|
7572
|
+
tone: componentCapability ? "matched" : "pending",
|
|
7573
|
+
tooltip: componentCapability ? "\u5DF2\u5339\u914D\u5230\u53EF\u590D\u7528\u89C4\u5219\uFF0C\u53EF\u6309\u7EC4\u4EF6\u65B9\u5F0F\u67E5\u770B\u548C\u5904\u7406\u3002" : "\u5F53\u524D\u8FD8\u6CA1\u6709\u53EF\u590D\u7528\u89C4\u5219\uFF0C\u5148\u6309\u5F53\u524D\u6837\u5F0F\u5904\u7406\uFF0C\u540E\u7EED\u53EF\u8865\u5145\u5230\u8BBE\u8BA1\u5E93\u3002"
|
|
7574
|
+
}
|
|
7575
|
+
)
|
|
7576
|
+
] }) }),
|
|
7577
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
7578
|
+
"button",
|
|
7579
|
+
{
|
|
7580
|
+
type: "button",
|
|
7581
|
+
className: `di-component-meta-toggle${componentInfoOpen ? " di-component-meta-toggle--on" : ""}`,
|
|
7582
|
+
onClick: () => setComponentInfoOpen((open) => !open),
|
|
7583
|
+
"aria-expanded": componentInfoOpen,
|
|
7584
|
+
"aria-label": componentInfoOpen ? "\u6536\u8D77\u5143\u7D20\u4FE1\u606F" : "\u67E5\u770B\u5143\u7D20\u4FE1\u606F",
|
|
7585
|
+
title: componentInfoOpen ? "\u6536\u8D77\u5143\u7D20\u4FE1\u606F" : "\u67E5\u770B\u5143\u7D20\u4FE1\u606F",
|
|
7586
|
+
children: [
|
|
7587
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u5143\u7D20\u4FE1\u606F" }),
|
|
7588
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronDown, { size: 14, strokeWidth: 2.2, "aria-hidden": "true" })
|
|
7589
|
+
]
|
|
7590
|
+
}
|
|
7591
|
+
)
|
|
7592
|
+
] }),
|
|
7593
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-meta-block", children: componentInfoOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-info-panel", children: componentElementInfos.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-info-elements", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-info-element-list", children: componentElementInfos.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "di-component-info-element-card", children: [
|
|
7594
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-info-element-head", children: [
|
|
7595
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-component-info-element-label", children: item.label }),
|
|
7596
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-component-info-element-selector", title: item.selector, children: item.selector })
|
|
7060
7597
|
] }),
|
|
7061
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("
|
|
7062
|
-
"
|
|
7063
|
-
|
|
7598
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dl", { className: "di-component-info-element-meta", children: [
|
|
7599
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-info-row", children: [
|
|
7600
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "\u5185\u5BB9" }),
|
|
7601
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { title: item.text, children: item.text })
|
|
7602
|
+
] }),
|
|
7603
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-info-row", children: [
|
|
7604
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "\u6837\u5F0F" }),
|
|
7605
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { title: item.style, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "di-component-info-inline", children: [
|
|
7606
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: item.style }),
|
|
7607
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7608
|
+
MatchBadge,
|
|
7609
|
+
{
|
|
7610
|
+
label: item.styleStatus === "token" ? "Token" : "\u771F\u5B9E\u503C",
|
|
7611
|
+
tone: item.styleStatus,
|
|
7612
|
+
tooltip: item.styleStatus === "token" ? "\u5F53\u524D\u503C\u5DF2\u6620\u5C04\u5230\u8BBE\u8BA1 token\u3002" : "\u5F53\u524D\u5C55\u793A\u7684\u662F\u9875\u9762\u5B9E\u9645\u6837\u5F0F\u503C\uFF0C\u5C1A\u672A\u6620\u5C04\u5230\u8BBE\u8BA1 token \u6216\u7EC4\u4EF6\u89C4\u5219\u3002"
|
|
7613
|
+
}
|
|
7614
|
+
)
|
|
7615
|
+
] }) })
|
|
7616
|
+
] }),
|
|
7617
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-info-row", children: [
|
|
7618
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "\u95F4\u8DDD" }),
|
|
7619
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { title: item.spacing, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "di-component-info-inline", children: [
|
|
7620
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: item.spacing }),
|
|
7621
|
+
item.spacingStatus && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7622
|
+
MatchBadge,
|
|
7623
|
+
{
|
|
7624
|
+
label: item.spacingStatus === "token" ? "Token" : "\u771F\u5B9E\u503C",
|
|
7625
|
+
tone: item.spacingStatus,
|
|
7626
|
+
tooltip: item.spacingStatus === "token" ? "\u5F53\u524D\u503C\u5DF2\u6620\u5C04\u5230\u8BBE\u8BA1 token\u3002" : "\u5F53\u524D\u5C55\u793A\u7684\u662F\u9875\u9762\u5B9E\u9645\u6837\u5F0F\u503C\uFF0C\u5C1A\u672A\u6620\u5C04\u5230\u8BBE\u8BA1 token \u6216\u7EC4\u4EF6\u89C4\u5219\u3002"
|
|
7627
|
+
}
|
|
7628
|
+
)
|
|
7629
|
+
] }) })
|
|
7630
|
+
] })
|
|
7064
7631
|
] })
|
|
7065
|
-
] }),
|
|
7632
|
+
] }, item.key)) }) }) }) }),
|
|
7066
7633
|
componentCapability && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-fields", children: [
|
|
7067
7634
|
componentEditableSlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "di-component-field di-component-field--text", children: [
|
|
7068
7635
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: slot.label }),
|
|
@@ -7079,24 +7646,38 @@ function InspectorPanel({
|
|
|
7079
7646
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: visibleChildSlots.length === 1 ? visibleChildSlots[0].slot.label : "\u53EF\u9009\u9879" }),
|
|
7080
7647
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-child-list", children: visibleChildSlots.map(({ slot, value, element }) => {
|
|
7081
7648
|
const childMeta = element ? getInspectorComponentMeta(element) : null;
|
|
7649
|
+
const childCapability = getComponentCapability(childMeta);
|
|
7082
7650
|
const childName = childMeta ? getComponentDisplayName(childMeta) : slot.label;
|
|
7083
7651
|
const childValue = value || childMeta?.variant || childName;
|
|
7084
7652
|
const showChildLabel = visibleChildSlots.length > 1;
|
|
7653
|
+
const childBadgeStatus = element && childCapability?.statusKind === "badge" ? inferBadgeStatus(getClasses(element)) : null;
|
|
7085
7654
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `di-component-child-item${showChildLabel ? " di-component-child-item--with-label" : ""}`, children: [
|
|
7086
7655
|
showChildLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-component-child-label", children: slot.label }),
|
|
7087
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("
|
|
7088
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7656
|
+
element && childCapability?.statusKind === "badge" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-child-variant-grid", role: "group", "aria-label": `${childName} \u72B6\u6001`, children: BADGE_STATUS_OPTIONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7089
7657
|
"button",
|
|
7090
7658
|
{
|
|
7091
7659
|
type: "button",
|
|
7092
|
-
className: "di-component-child-
|
|
7093
|
-
onClick: () =>
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7660
|
+
className: `di-component-child-variant-tile${childBadgeStatus === option.key ? " di-component-child-variant-tile--on" : ""}`,
|
|
7661
|
+
onClick: () => updateBadgeStatusOnElement(element, option.key),
|
|
7662
|
+
title: `${childName} \xB7 ${option.label}`,
|
|
7663
|
+
children: option.label
|
|
7664
|
+
},
|
|
7665
|
+
option.key
|
|
7666
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
7667
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-component-child-value", children: childValue }),
|
|
7668
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7669
|
+
"button",
|
|
7670
|
+
{
|
|
7671
|
+
type: "button",
|
|
7672
|
+
className: "di-component-child-select",
|
|
7673
|
+
onClick: () => {
|
|
7674
|
+
if (element) selectEl(element);
|
|
7675
|
+
},
|
|
7676
|
+
title: `\u9009\u62E9 ${childName}`,
|
|
7677
|
+
children: "\u9009\u62E9"
|
|
7678
|
+
}
|
|
7679
|
+
)
|
|
7680
|
+
] })
|
|
7100
7681
|
] }, slot.key);
|
|
7101
7682
|
}) })
|
|
7102
7683
|
] }),
|
|
@@ -7152,11 +7733,11 @@ function InspectorPanel({
|
|
|
7152
7733
|
] }),
|
|
7153
7734
|
componentCapability.statusKind === "badge" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-component-field", children: [
|
|
7154
7735
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u72B6\u6001" }),
|
|
7155
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-
|
|
7736
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-component-variant-grid", role: "group", "aria-label": "\u6807\u7B7E\u72B6\u6001", children: BADGE_STATUS_OPTIONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
7156
7737
|
"button",
|
|
7157
7738
|
{
|
|
7158
7739
|
type: "button",
|
|
7159
|
-
className: `di-component-
|
|
7740
|
+
className: `di-component-variant-tile${activeBadgeStatus === option.key ? " di-component-variant-tile--on" : ""}`,
|
|
7160
7741
|
onClick: () => updateBadgeStatus(option.key),
|
|
7161
7742
|
children: option.label
|
|
7162
7743
|
},
|
|
@@ -8305,6 +8886,43 @@ function InspectorPanel({
|
|
|
8305
8886
|
] })
|
|
8306
8887
|
] })
|
|
8307
8888
|
] }),
|
|
8889
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-section di-annotation-section", children: [
|
|
8890
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `di-section-title-row di-section-title-row--action${annotationOpen ? "" : " di-section-title-row--empty"}`, children: [
|
|
8891
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-section-title-group", children: [
|
|
8892
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-section-title", children: "\u6807\u6CE8" }),
|
|
8893
|
+
localDraftEntries.some((entry) => entry.changes.some((change) => change.prop.startsWith("annotation:"))) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-annotation-count", children: "\u5DF2\u8BB0\u5F55" })
|
|
8894
|
+
] }),
|
|
8895
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
8896
|
+
"button",
|
|
8897
|
+
{
|
|
8898
|
+
type: "button",
|
|
8899
|
+
className: "di-section-icon-action",
|
|
8900
|
+
onClick: () => setAnnotationOpen((open) => !open),
|
|
8901
|
+
title: annotationOpen ? "\u6536\u8D77\u6807\u6CE8" : "\u6DFB\u52A0\u6807\u6CE8",
|
|
8902
|
+
"aria-label": annotationOpen ? "\u6536\u8D77\u6807\u6CE8" : "\u6DFB\u52A0\u6807\u6CE8",
|
|
8903
|
+
children: annotationOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Minus, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Plus, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" })
|
|
8904
|
+
}
|
|
8905
|
+
)
|
|
8906
|
+
] }),
|
|
8907
|
+
annotationOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-annotation-card", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "di-annotation-row di-annotation-row--text", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
8908
|
+
"textarea",
|
|
8909
|
+
{
|
|
8910
|
+
className: "di-annotation-textarea",
|
|
8911
|
+
value: annotationText,
|
|
8912
|
+
placeholder: "\u76F4\u63A5\u5199\u4F60\u7684\u60F3\u6CD5\uFF0C\u4F8B\u5982\uFF1A\u8FD9\u91CC\u8981\u4FDD\u6301\u9AD8\u4EAE\u4F46\u4E0D\u8981\u7528\u5B9E\u5E95\u4E3B\u6309\u94AE\u6837\u5F0F\u3002AI \u4F1A\u5224\u65AD\u8FD9\u662F\u8BBE\u8BA1\u8BF4\u660E\u3001\u4EA7\u54C1\u89C4\u5219\u8FD8\u662F\u5F00\u53D1\u5907\u6CE8\u3002",
|
|
8913
|
+
rows: 2,
|
|
8914
|
+
onChange: (event) => {
|
|
8915
|
+
const nextText = event.currentTarget.value;
|
|
8916
|
+
setAnnotationText(nextText);
|
|
8917
|
+
updateAnnotationDraft(nextText);
|
|
8918
|
+
resizeTextareaToContent(event.currentTarget);
|
|
8919
|
+
},
|
|
8920
|
+
ref: (node) => {
|
|
8921
|
+
if (node) resizeTextareaToContent(node);
|
|
8922
|
+
}
|
|
8923
|
+
}
|
|
8924
|
+
) }) })
|
|
8925
|
+
] }),
|
|
8308
8926
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-section", children: [
|
|
8309
8927
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-section-title", children: [
|
|
8310
8928
|
"\u672C\u6B21\u4FEE\u6539\u5185\u5BB9 ",
|
|
@@ -8454,7 +9072,7 @@ ${pending.map(([p, v]) => ` ${p}: ${v};`).join("\n")}
|
|
|
8454
9072
|
disabled: !hasPending,
|
|
8455
9073
|
style: !hasPending ? { opacity: 0.4, cursor: "not-allowed" } : {},
|
|
8456
9074
|
title: "\u590D\u5236\u4E00\u6BB5\u53EF\u76F4\u63A5\u53D1\u7ED9 AI \u7684\u4EFB\u52A1\u6587\u672C",
|
|
8457
|
-
children: submitMsg
|
|
9075
|
+
children: renderSubmitLabel(submitMsg)
|
|
8458
9076
|
}
|
|
8459
9077
|
)
|
|
8460
9078
|
] });
|
|
@@ -8490,115 +9108,6 @@ ${pending.map(([p, v]) => ` ${p}: ${v};`).join("\n")}
|
|
|
8490
9108
|
)
|
|
8491
9109
|
] });
|
|
8492
9110
|
}
|
|
8493
|
-
var CODE_FILES = [
|
|
8494
|
-
{ name: "src/", desc: "React \u7EC4\u4EF6\u3001\u9875\u9762\u3001\u6837\u5F0F\u6E90\u7801\uFF08\u4E0D\u542B\u8C03\u8BD5\u5DE5\u5177\uFF09" },
|
|
8495
|
-
{ name: "index.html", desc: "\u5E94\u7528\u5165\u53E3 HTML" },
|
|
8496
|
-
{ name: "package.json", desc: "\u4F9D\u8D56\u5305\u4E0E\u811A\u672C\u914D\u7F6E" },
|
|
8497
|
-
{ name: "tsconfig.json", desc: "TypeScript \u7F16\u8BD1\u914D\u7F6E" },
|
|
8498
|
-
{ name: "vite.config.ts", desc: "\u6784\u5EFA\u5DE5\u5177\u914D\u7F6E" }
|
|
8499
|
-
];
|
|
8500
|
-
var PRODUCT_FILES = [
|
|
8501
|
-
{ name: "docs/PRODUCT_PLAN.md", desc: "\u4EA7\u54C1\u89C4\u5212\u4E0E\u8DEF\u7EBF\u56FE" },
|
|
8502
|
-
{ name: "docs/PROJECT.md", desc: "\u9879\u76EE\u80CC\u666F\u4E0E\u76EE\u6807\u6982\u8FF0" },
|
|
8503
|
-
{ name: "docs/DECISIONS.md", desc: "\u5173\u952E\u4EA7\u54C1\u51B3\u7B56\u8BB0\u5F55" },
|
|
8504
|
-
{ name: "docs/CHANGELOG.md", desc: "\u529F\u80FD\u8FED\u4EE3\u53D8\u66F4\u65E5\u5FD7" },
|
|
8505
|
-
{ name: "docs/CODE_STRUCTURE.md", desc: "\u524D\u7AEF\u76EE\u5F55\u7ED3\u6784\u8BF4\u660E" },
|
|
8506
|
-
{ name: "docs/DESIGN_STANDARDS.md", desc: "\u8BBE\u8BA1\u89C4\u8303\u603B\u89C8" }
|
|
8507
|
-
];
|
|
8508
|
-
var DESIGN_FILES = [
|
|
8509
|
-
{ name: "docs/design/OVERVIEW.md", desc: "\u8BBE\u8BA1\u7CFB\u7EDF\u603B\u89C8" },
|
|
8510
|
-
{ name: "docs/design/tokens.md", desc: "Design Token \u4F7F\u7528\u8BF4\u660E" },
|
|
8511
|
-
{ name: "docs/design/layout.md", desc: "\u9875\u9762\u5E03\u5C40\u89C4\u8303" },
|
|
8512
|
-
{ name: "docs/design/component-index.md", desc: "\u7EC4\u4EF6\u6E05\u5355\u7D22\u5F15" },
|
|
8513
|
-
{ name: "docs/design/business-components.md", desc: "\u4E1A\u52A1\u7EC4\u4EF6\u8BF4\u660E" }
|
|
8514
|
-
];
|
|
8515
|
-
function FileList({ files }) {
|
|
8516
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "di-dl-file-list", children: files.map((f) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { children: [
|
|
8517
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-dl-file-name", children: f.name }),
|
|
8518
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-dl-file-desc", children: f.desc })
|
|
8519
|
-
] }, f.name)) });
|
|
8520
|
-
}
|
|
8521
|
-
function DownloadButton() {
|
|
8522
|
-
const { endpoints } = useDevInspectorConfig();
|
|
8523
|
-
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
8524
|
-
const [status, setStatus] = (0, import_react2.useState)("idle");
|
|
8525
|
-
const [filePath, setFilePath] = (0, import_react2.useState)("");
|
|
8526
|
-
const [details, setDetails] = (0, import_react2.useState)({ code: false, product: false, design: false });
|
|
8527
|
-
const [opts, setOpts] = (0, import_react2.useState)({ code: true, product: false, design: false });
|
|
8528
|
-
function toggle(k) {
|
|
8529
|
-
setOpts((prev) => ({ ...prev, [k]: !prev[k] }));
|
|
8530
|
-
}
|
|
8531
|
-
function toggleDetail(k) {
|
|
8532
|
-
setDetails((prev) => ({ ...prev, [k]: !prev[k] }));
|
|
8533
|
-
}
|
|
8534
|
-
function handleOpen() {
|
|
8535
|
-
setOpen((v) => !v);
|
|
8536
|
-
if (open) setStatus("idle");
|
|
8537
|
-
}
|
|
8538
|
-
async function download() {
|
|
8539
|
-
if (!opts.code && !opts.product && !opts.design) return;
|
|
8540
|
-
setStatus("packing");
|
|
8541
|
-
try {
|
|
8542
|
-
const params = new URLSearchParams({
|
|
8543
|
-
code: opts.code ? "1" : "0",
|
|
8544
|
-
product: opts.product ? "1" : "0",
|
|
8545
|
-
design: opts.design ? "1" : "0"
|
|
8546
|
-
});
|
|
8547
|
-
const res = await fetch(`${endpoints.handoff}?${params}`);
|
|
8548
|
-
const json = await res.json();
|
|
8549
|
-
if (!json.ok) throw new Error(json.error);
|
|
8550
|
-
setFilePath(json.path);
|
|
8551
|
-
setStatus("done");
|
|
8552
|
-
} catch {
|
|
8553
|
-
setStatus("error");
|
|
8554
|
-
}
|
|
8555
|
-
}
|
|
8556
|
-
async function revealInFinder() {
|
|
8557
|
-
await fetch(`${endpoints.reveal}?path=${encodeURIComponent(filePath)}`);
|
|
8558
|
-
}
|
|
8559
|
-
const sections = [
|
|
8560
|
-
{ key: "code", label: "\u524D\u7AEF\u4EE3\u7801", files: CODE_FILES },
|
|
8561
|
-
{ key: "product", label: "\u4EA7\u54C1\u6587\u6863", files: PRODUCT_FILES },
|
|
8562
|
-
{ key: "design", label: "\u8BBE\u8BA1\u6587\u6863", files: DESIGN_FILES }
|
|
8563
|
-
];
|
|
8564
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
8565
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "di-dl-btn", onClick: handleOpen, children: "\u4E0B\u8F7D" }),
|
|
8566
|
-
open && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-dl-modal", children: [
|
|
8567
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-dl-title", children: "\u9009\u62E9\u4E0B\u8F7D\u5185\u5BB9" }),
|
|
8568
|
-
status === "packing" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-dl-status", children: [
|
|
8569
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "di-dl-spinner" }),
|
|
8570
|
-
"\u6B63\u5728\u6253\u5305\uFF0C\u8BF7\u7A0D\u5019\u2026"
|
|
8571
|
-
] }),
|
|
8572
|
-
status === "done" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-dl-done", children: [
|
|
8573
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-dl-done-check", children: "\u2713 \u5DF2\u4FDD\u5B58\u81F3\u684C\u9762" }),
|
|
8574
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-dl-done-path", children: filePath.replace(/.*\//, "") }),
|
|
8575
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "di-dl-reveal-btn", onClick: revealInFinder, children: "\u5728 Finder \u4E2D\u663E\u793A" })
|
|
8576
|
-
] }),
|
|
8577
|
-
status === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "di-dl-status di-dl-status--error", children: "\u6253\u5305\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0" }),
|
|
8578
|
-
(status === "idle" || status === "error") && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
8579
|
-
sections.map(({ key, label, files }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
8580
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "di-dl-row", children: [
|
|
8581
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "di-dl-check-label", children: [
|
|
8582
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "checkbox", checked: opts[key], onChange: () => toggle(key) }),
|
|
8583
|
-
label
|
|
8584
|
-
] }),
|
|
8585
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "di-dl-detail-btn", onClick: () => toggleDetail(key), children: details[key] ? "\u6536\u8D77" : "\u8BE6\u60C5" })
|
|
8586
|
-
] }),
|
|
8587
|
-
details[key] && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FileList, { files })
|
|
8588
|
-
] }, key)),
|
|
8589
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
8590
|
-
"button",
|
|
8591
|
-
{
|
|
8592
|
-
className: "di-dl-confirm",
|
|
8593
|
-
onClick: download,
|
|
8594
|
-
disabled: !opts.code && !opts.product && !opts.design,
|
|
8595
|
-
children: "\u4E0B\u8F7D"
|
|
8596
|
-
}
|
|
8597
|
-
)
|
|
8598
|
-
] })
|
|
8599
|
-
] })
|
|
8600
|
-
] });
|
|
8601
|
-
}
|
|
8602
9111
|
function DevInspector() {
|
|
8603
9112
|
const [active, setActive] = (0, import_react2.useState)(false);
|
|
8604
9113
|
const [tokenMap, setTokenMap] = (0, import_react2.useState)({});
|
|
@@ -8628,26 +9137,29 @@ function DevInspector() {
|
|
|
8628
9137
|
(0, import_react2.useEffect)(() => {
|
|
8629
9138
|
const onOver = (e) => {
|
|
8630
9139
|
if (!active || modalOpenRef.current) return;
|
|
8631
|
-
const
|
|
8632
|
-
if (!
|
|
8633
|
-
if (isInsidePanel(
|
|
8634
|
-
|
|
9140
|
+
const raw = e.target;
|
|
9141
|
+
if (!raw?.classList) return;
|
|
9142
|
+
if (isInsidePanel(raw)) {
|
|
9143
|
+
raw.classList.remove("di-hover");
|
|
8635
9144
|
return;
|
|
8636
9145
|
}
|
|
8637
|
-
|
|
9146
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
9147
|
+
resolveSelectionTarget(raw).classList.add("di-hover");
|
|
8638
9148
|
};
|
|
8639
|
-
const onOut = (
|
|
8640
|
-
|
|
9149
|
+
const onOut = () => {
|
|
9150
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
8641
9151
|
};
|
|
8642
9152
|
const onClick = (e) => {
|
|
8643
9153
|
if (!active || modalOpenRef.current) return;
|
|
8644
|
-
const
|
|
8645
|
-
if (
|
|
9154
|
+
const raw = e.target;
|
|
9155
|
+
if (!raw?.classList) return;
|
|
9156
|
+
if (isInsidePanel(raw)) return;
|
|
8646
9157
|
e.preventDefault();
|
|
8647
9158
|
e.stopPropagation();
|
|
8648
|
-
|
|
9159
|
+
const target = resolveSelectionTarget(raw);
|
|
9160
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
8649
9161
|
setPanels(
|
|
8650
|
-
(prev) => prev.length === 0 ? [{ id: "main", el }] : prev.map((p, i) => i === 0 ? { ...p, el } : p)
|
|
9162
|
+
(prev) => prev.length === 0 ? [{ id: "main", el: target }] : prev.map((p, i) => i === 0 ? { ...p, el: target } : p)
|
|
8651
9163
|
);
|
|
8652
9164
|
};
|
|
8653
9165
|
document.addEventListener("mouseover", onOver, true);
|
|
@@ -8688,7 +9200,6 @@ function DevInspector() {
|
|
|
8688
9200
|
const primaryEl = panels[0]?.el;
|
|
8689
9201
|
const triggerTooltip = active ? `\u9000\u51FA\u7F16\u8F91\uFF08${EXIT_SHORTCUT_LABEL}\uFF09` : `\u8FDB\u5165\u7F16\u8F91\uFF08${EDIT_SHORTCUT_LABEL}\uFF09`;
|
|
8690
9202
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
8691
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DownloadButton, {}),
|
|
8692
9203
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
8693
9204
|
"button",
|
|
8694
9205
|
{
|