@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.js
CHANGED
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
// src/DevInspector.tsx
|
|
2
2
|
import { useState, useEffect, useRef, useCallback } from "react";
|
|
3
|
-
import { ArrowDown, ArrowLeft, ArrowUp, ChevronDown, CircleHelp, Component as ComponentIcon, Library as LibraryIcon, Minus, Plus, RotateCcw, Trash2, X } from "lucide-react";
|
|
3
|
+
import { ArrowDown, ArrowLeft, ArrowUp, Check, ChevronDown, CircleHelp, Component as ComponentIcon, Library as LibraryIcon, Minus, Plus, RotateCcw, Trash2, Upload, WandSparkles, X } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
// src/DevInspectorProvider.tsx
|
|
6
6
|
import { createContext, useContext } from "react";
|
|
7
7
|
|
|
8
|
+
// src/tokens/typography.json
|
|
9
|
+
var typography_default = {
|
|
10
|
+
title: {
|
|
11
|
+
fontSize: "15px",
|
|
12
|
+
fontWeight: "700",
|
|
13
|
+
lineHeight: "1.4",
|
|
14
|
+
color: "#111827"
|
|
15
|
+
},
|
|
16
|
+
sectionLabel: {
|
|
17
|
+
fontSize: "12px",
|
|
18
|
+
fontWeight: "700",
|
|
19
|
+
lineHeight: "1.4",
|
|
20
|
+
color: "#374151"
|
|
21
|
+
},
|
|
22
|
+
body: {
|
|
23
|
+
fontSize: "12px",
|
|
24
|
+
fontWeight: "400",
|
|
25
|
+
lineHeight: "1.5",
|
|
26
|
+
color: "#6b7280"
|
|
27
|
+
},
|
|
28
|
+
meta: {
|
|
29
|
+
fontSize: "11px",
|
|
30
|
+
fontWeight: "600",
|
|
31
|
+
lineHeight: "1.35",
|
|
32
|
+
color: "#94a3b8"
|
|
33
|
+
},
|
|
34
|
+
tinyBadge: {
|
|
35
|
+
fontSize: "10px",
|
|
36
|
+
fontWeight: "700",
|
|
37
|
+
lineHeight: "1.2",
|
|
38
|
+
color: "#64748b"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
8
42
|
// src/config.ts
|
|
9
43
|
var FALLBACK_TYPOGRAPHY_STYLES = [
|
|
10
44
|
{
|
|
@@ -104,6 +138,7 @@ var FALLBACK_SHADOW_TOKENS = [
|
|
|
104
138
|
var FALLBACK_TOKENS = {
|
|
105
139
|
colorPalette: [],
|
|
106
140
|
tokenLabels: {},
|
|
141
|
+
inspectorTypography: typography_default,
|
|
107
142
|
radiusPresets: [
|
|
108
143
|
{ label: "\u65E0", sub: "", value: "0px", token: "" },
|
|
109
144
|
{ label: "S", sub: "4px", value: "4px", token: "" },
|
|
@@ -274,12 +309,22 @@ function handleArrowKeyStep(event, onStep, onEnter) {
|
|
|
274
309
|
}
|
|
275
310
|
if (event.key === "Enter") onEnter?.();
|
|
276
311
|
}
|
|
312
|
+
function renderSubmitLabel(submitMsg) {
|
|
313
|
+
if (submitMsg === "\u5DF2\u590D\u5236") {
|
|
314
|
+
return /* @__PURE__ */ jsxs("span", { className: "di-btn-save-content", children: [
|
|
315
|
+
/* @__PURE__ */ jsx2(Check, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" }),
|
|
316
|
+
/* @__PURE__ */ jsx2("span", { children: "\u5DF2\u590D\u5236" })
|
|
317
|
+
] });
|
|
318
|
+
}
|
|
319
|
+
return submitMsg || "\u53D1\u9001\u7ED9AI";
|
|
320
|
+
}
|
|
277
321
|
var COLOR_PROPS = [
|
|
278
322
|
{ label: "\u80CC\u666F\u8272", prop: "background-color" }
|
|
279
323
|
];
|
|
280
324
|
function getColorLabel(val, colorPalette) {
|
|
325
|
+
const normalizedVal = resolveColorValue(val);
|
|
281
326
|
for (const g of colorPalette) {
|
|
282
|
-
const found = g.colors.find((c) => c.val ===
|
|
327
|
+
const found = g.colors.find((c) => resolveColorValue(c.val) === normalizedVal);
|
|
283
328
|
if (found) return `${g.group}\xB7${found.label}`;
|
|
284
329
|
}
|
|
285
330
|
return null;
|
|
@@ -489,10 +534,26 @@ function isTextEntryTarget(target) {
|
|
|
489
534
|
function normalizeColor(val) {
|
|
490
535
|
const raw = val.trim();
|
|
491
536
|
if (raw === "transparent" || /^rgba\(\s*0,\s*0,\s*0,\s*0\s*\)$/i.test(raw)) return "transparent";
|
|
492
|
-
const m =
|
|
537
|
+
const m = raw.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/);
|
|
493
538
|
if (m) return "#" + [m[1], m[2], m[3]].map((n) => parseInt(n).toString(16).padStart(2, "0")).join("");
|
|
539
|
+
if (/^#[0-9a-f]{3,8}$/i.test(raw)) return raw.toLowerCase();
|
|
494
540
|
return raw;
|
|
495
541
|
}
|
|
542
|
+
function resolveColorValue(val) {
|
|
543
|
+
const normalized = normalizeColor(val || "");
|
|
544
|
+
if (!normalized || normalized === "transparent") return normalized || "transparent";
|
|
545
|
+
if (/^#[0-9a-f]{6}$/i.test(normalized)) return normalized;
|
|
546
|
+
if (typeof document === "undefined" || !document.body) return normalized;
|
|
547
|
+
const probe = document.createElement("div");
|
|
548
|
+
probe.style.color = normalized;
|
|
549
|
+
probe.style.position = "fixed";
|
|
550
|
+
probe.style.opacity = "0";
|
|
551
|
+
probe.style.pointerEvents = "none";
|
|
552
|
+
document.body.appendChild(probe);
|
|
553
|
+
const computed = normalizeColor(getComputedStyle(probe).color.trim());
|
|
554
|
+
probe.remove();
|
|
555
|
+
return computed || normalized;
|
|
556
|
+
}
|
|
496
557
|
function isTransparentColor(val) {
|
|
497
558
|
return normalizeColor(val || "transparent") === "transparent";
|
|
498
559
|
}
|
|
@@ -635,7 +696,7 @@ function getComponentClasses(el) {
|
|
|
635
696
|
if (primitiveClasses.length) return primitiveClasses;
|
|
636
697
|
const classes = getClasses(el);
|
|
637
698
|
const cardBaseClass = classes.find(
|
|
638
|
-
(className) =>
|
|
699
|
+
(className) => isCardRootClass(className) && !className.includes("--")
|
|
639
700
|
);
|
|
640
701
|
if (cardBaseClass) return [cardBaseClass];
|
|
641
702
|
const badgeBaseClass = classes.find(
|
|
@@ -694,6 +755,7 @@ var TEXT_ONLY_TAGS = /* @__PURE__ */ new Set([
|
|
|
694
755
|
var TEXT_SEMANTIC_CLASS_RE = /(^|[-_])(caption|copy|desc|description|eyebrow|heading|label|subtitle|text|title)([-_]|$)/i;
|
|
695
756
|
var STRUCTURAL_CONTAINER_CLASS_RE = /(^|[-_])(area|block|card|container|content|group|grid|item|layout|list|panel|row|section|shell|stack|zone)([-_]|$)/i;
|
|
696
757
|
var PAGE_SHELL_CLASS_RE = /(^|[-_])(app|page|root|screen|shell|workspace)([-_]|$)/i;
|
|
758
|
+
var CARD_ROOT_CLASS_NAMES = /* @__PURE__ */ new Set(["task-card"]);
|
|
697
759
|
var TEXT_GROUP_EXCLUDED_SELECTOR = [
|
|
698
760
|
"button",
|
|
699
761
|
"input",
|
|
@@ -724,6 +786,12 @@ function hasTextSemanticClass(el) {
|
|
|
724
786
|
(className) => !isStateClass(className) && !/^lucide(-|$)/.test(className) && TEXT_SEMANTIC_CLASS_RE.test(className)
|
|
725
787
|
);
|
|
726
788
|
}
|
|
789
|
+
function getRegisteredComponentType(el) {
|
|
790
|
+
return (el.getAttribute("data-component") || "").trim();
|
|
791
|
+
}
|
|
792
|
+
function isCardRootClass(className) {
|
|
793
|
+
return CARD_ROOT_CLASS_NAMES.has(className) || /(^|[-_])card($|--)/i.test(className);
|
|
794
|
+
}
|
|
727
795
|
function hasStructuralContainerClass(el) {
|
|
728
796
|
return getClasses(el).some(
|
|
729
797
|
(className) => !isStateClass(className) && STRUCTURAL_CONTAINER_CLASS_RE.test(className)
|
|
@@ -859,6 +927,17 @@ function getInspectorComponentMeta(el) {
|
|
|
859
927
|
const tag = el.tagName.toLowerCase();
|
|
860
928
|
const classes = getClasses(el);
|
|
861
929
|
const componentClasses = getComponentClasses(el);
|
|
930
|
+
const registeredComponentType = getRegisteredComponentType(el);
|
|
931
|
+
if (registeredComponentType) {
|
|
932
|
+
const type = registeredComponentType;
|
|
933
|
+
return {
|
|
934
|
+
name: componentClasses[0] ?? type,
|
|
935
|
+
type,
|
|
936
|
+
layer: "Component",
|
|
937
|
+
variant: inferVariantFromClasses(classes),
|
|
938
|
+
state: inferStateFromElement(el, classes)
|
|
939
|
+
};
|
|
940
|
+
}
|
|
862
941
|
if (tag === "svg" && classes.includes("lucide")) {
|
|
863
942
|
const iconClass = classes.find((className) => /^lucide-/.test(className));
|
|
864
943
|
return {
|
|
@@ -879,9 +958,9 @@ function getInspectorComponentMeta(el) {
|
|
|
879
958
|
state: inferStateFromElement(el, classes)
|
|
880
959
|
};
|
|
881
960
|
}
|
|
882
|
-
if (
|
|
961
|
+
if (classes.some(isCardRootClass)) {
|
|
883
962
|
return {
|
|
884
|
-
name: componentClasses.find((className) =>
|
|
963
|
+
name: componentClasses.find((className) => isCardRootClass(className)) ?? componentClasses[0] ?? "card",
|
|
885
964
|
type: "Card",
|
|
886
965
|
layer: "Component",
|
|
887
966
|
variant: inferCardVariant(classes),
|
|
@@ -1509,6 +1588,14 @@ function canPersistSelector(el, scope) {
|
|
|
1509
1588
|
function isInsidePanel(el) {
|
|
1510
1589
|
return el.closest(".di-panel") !== null || el.closest(".di-trigger") !== null || el.closest(".di-label") !== null;
|
|
1511
1590
|
}
|
|
1591
|
+
function resolveSelectionTarget(raw) {
|
|
1592
|
+
let cursor = raw;
|
|
1593
|
+
while (cursor && cursor !== document.body && cursor !== document.documentElement) {
|
|
1594
|
+
if (getInspectorComponentMeta(cursor)) return cursor;
|
|
1595
|
+
cursor = cursor.parentElement;
|
|
1596
|
+
}
|
|
1597
|
+
return raw;
|
|
1598
|
+
}
|
|
1512
1599
|
function scanTokenMap() {
|
|
1513
1600
|
const map = {};
|
|
1514
1601
|
try {
|
|
@@ -1539,6 +1626,12 @@ function getComputedColor(el, prop) {
|
|
|
1539
1626
|
function getComputedRadius(el) {
|
|
1540
1627
|
return getComputedStyle(el).getPropertyValue("border-radius").trim();
|
|
1541
1628
|
}
|
|
1629
|
+
function getComputedPadding(el) {
|
|
1630
|
+
const cs = getComputedStyle(el);
|
|
1631
|
+
const t = cs.paddingTop, r = cs.paddingRight, b = cs.paddingBottom, l = cs.paddingLeft;
|
|
1632
|
+
if (t === r && r === b && b === l) return t;
|
|
1633
|
+
return `${t} ${r} ${b} ${l}`;
|
|
1634
|
+
}
|
|
1542
1635
|
function parseTranslate(val) {
|
|
1543
1636
|
const raw = (val || "none").trim();
|
|
1544
1637
|
if (!raw || raw === "none") return { x: 0, y: 0 };
|
|
@@ -1982,6 +2075,93 @@ function getTextContent(el) {
|
|
|
1982
2075
|
const text = Array.from(el.childNodes).filter((n) => n.nodeType === Node.TEXT_NODE).map((n) => n.textContent ?? "").join("").trim();
|
|
1983
2076
|
return text.length > 0 ? el.textContent?.trim() ?? null : null;
|
|
1984
2077
|
}
|
|
2078
|
+
function MatchBadge({
|
|
2079
|
+
label,
|
|
2080
|
+
tooltip,
|
|
2081
|
+
tone
|
|
2082
|
+
}) {
|
|
2083
|
+
return /* @__PURE__ */ jsx2(
|
|
2084
|
+
"span",
|
|
2085
|
+
{
|
|
2086
|
+
className: `di-match-badge di-match-badge--${tone}`,
|
|
2087
|
+
title: tooltip,
|
|
2088
|
+
"data-tooltip": tooltip,
|
|
2089
|
+
tabIndex: 0,
|
|
2090
|
+
children: label
|
|
2091
|
+
}
|
|
2092
|
+
);
|
|
2093
|
+
}
|
|
2094
|
+
function getComputedMargin(el) {
|
|
2095
|
+
const cs = getComputedStyle(el);
|
|
2096
|
+
const t = cs.marginTop, r = cs.marginRight, b = cs.marginBottom, l = cs.marginLeft;
|
|
2097
|
+
if (t === r && r === b && b === l) return t;
|
|
2098
|
+
return `${t} ${r} ${b} ${l}`;
|
|
2099
|
+
}
|
|
2100
|
+
function formatReadableColor(value) {
|
|
2101
|
+
if (!value || isTransparentColor(value)) return "\u900F\u660E";
|
|
2102
|
+
return formatColorDisplay(resolveColorValue(value));
|
|
2103
|
+
}
|
|
2104
|
+
function getComponentElementStyleSummary(el) {
|
|
2105
|
+
const cs = getComputedStyle(el);
|
|
2106
|
+
const parts = [];
|
|
2107
|
+
const text = getTextContent(el);
|
|
2108
|
+
const tag = el.tagName.toLowerCase();
|
|
2109
|
+
const borderWidth = getNumericCssValue(cs.borderTopWidth);
|
|
2110
|
+
const radius = cs.borderRadius.trim();
|
|
2111
|
+
const bg = cs.backgroundColor.trim();
|
|
2112
|
+
const color = cs.color.trim();
|
|
2113
|
+
if (text || /^(p|span|a|button|label|h1|h2|h3|h4|h5|h6|li|strong|em)$/i.test(tag)) {
|
|
2114
|
+
parts.push(`\u5B57 ${formatLengthControlValue(cs.fontSize)}`);
|
|
2115
|
+
parts.push(`\u91CD ${cs.fontWeight}`);
|
|
2116
|
+
parts.push(`\u8272 ${formatReadableColor(color)}`);
|
|
2117
|
+
}
|
|
2118
|
+
if (!isTransparentColor(bg)) {
|
|
2119
|
+
parts.push(`\u80CC\u666F ${formatReadableColor(bg)}`);
|
|
2120
|
+
}
|
|
2121
|
+
if (borderWidth > 0 && !isTransparentColor(cs.borderTopColor)) {
|
|
2122
|
+
parts.push(`\u63CF\u8FB9 ${formatLengthControlValue(cs.borderTopWidth)} ${formatReadableColor(cs.borderTopColor)}`);
|
|
2123
|
+
}
|
|
2124
|
+
if (!isZeroLengthValue(radius)) {
|
|
2125
|
+
parts.push(`\u5706\u89D2 ${formatLengthControlValue(radius)}`);
|
|
2126
|
+
}
|
|
2127
|
+
return parts.join(" / ") || "\u65E0\u660E\u663E\u6837\u5F0F";
|
|
2128
|
+
}
|
|
2129
|
+
function getComponentElementSpacingSummary(el) {
|
|
2130
|
+
const cs = getComputedStyle(el);
|
|
2131
|
+
const parts = [];
|
|
2132
|
+
const paddingSummary = getSpaceSummary("padding", getComputedPadding(el));
|
|
2133
|
+
const marginSummary = getSpaceSummary("margin", getComputedMargin(el));
|
|
2134
|
+
const gapSummary = canControlElementGap(el) ? getSpaceSummary("gap", cs.gap.trim()) : "";
|
|
2135
|
+
if (paddingSummary) parts.push(`\u5185\u8FB9\u8DDD ${paddingSummary}`);
|
|
2136
|
+
if (marginSummary) parts.push(`\u5916\u8FB9\u8DDD ${marginSummary}`);
|
|
2137
|
+
if (gapSummary) parts.push(`\u5143\u7D20\u95F4\u8DDD ${gapSummary.replace(/^gap\s*/i, "")}`);
|
|
2138
|
+
return parts.join(" / ") || "\u65E0\u989D\u5916\u95F4\u8DDD";
|
|
2139
|
+
}
|
|
2140
|
+
function getComponentElementStyleStatus(el, tokenMap, colorPalette, tokenLabels, typographyTokens) {
|
|
2141
|
+
const cs = getComputedStyle(el);
|
|
2142
|
+
const colorInfo = getDisplayLabel(normalizeColor(cs.color), tokenMap, colorPalette, tokenLabels);
|
|
2143
|
+
const backgroundInfo = getDisplayLabel(normalizeColor(cs.backgroundColor), tokenMap, colorPalette, tokenLabels);
|
|
2144
|
+
const borderInfo = getDisplayLabel(normalizeColor(cs.borderTopColor), tokenMap, colorPalette, tokenLabels);
|
|
2145
|
+
const typographyMatched = Boolean(getTypographyToken(cs.fontSize.trim(), cs.fontWeight.trim(), normalizeColor(cs.color), typographyTokens));
|
|
2146
|
+
if (typographyMatched) return "token";
|
|
2147
|
+
if (!colorInfo.isHardcoded || !backgroundInfo.isHardcoded || !borderInfo.isHardcoded) return "token";
|
|
2148
|
+
return "raw";
|
|
2149
|
+
}
|
|
2150
|
+
function getComponentElementSpacingStatus(el, spaceSteps) {
|
|
2151
|
+
const cs = getComputedStyle(el);
|
|
2152
|
+
const paddingValue = getComputedPadding(el);
|
|
2153
|
+
const marginValue = getComputedMargin(el);
|
|
2154
|
+
const gapValue = cs.gap.trim();
|
|
2155
|
+
const paddingSummary = getSpaceSummary("padding", paddingValue);
|
|
2156
|
+
const marginSummary = getSpaceSummary("margin", marginValue);
|
|
2157
|
+
const gapSummary = canControlElementGap(el) ? getSpaceSummary("gap", gapValue) : "";
|
|
2158
|
+
const hasSpacing = Boolean(paddingSummary || marginSummary || gapSummary);
|
|
2159
|
+
if (!hasSpacing) return null;
|
|
2160
|
+
const paddingMatched = !paddingSummary || Boolean(getSpaceStepMatch("padding", paddingValue, spaceSteps));
|
|
2161
|
+
const marginMatched = !marginSummary || Boolean(getSpaceStepMatch("margin", marginValue, spaceSteps));
|
|
2162
|
+
const gapMatched = !gapSummary || Boolean(getSpaceStepMatch("gap", gapValue, spaceSteps));
|
|
2163
|
+
return paddingMatched && marginMatched && gapMatched ? "token" : "raw";
|
|
2164
|
+
}
|
|
1985
2165
|
var TOKEN_TYPES = [
|
|
1986
2166
|
{ key: "bg", label: "\u80CC\u666F\u8272", code: "bg" },
|
|
1987
2167
|
{ key: "text", label: "\u6587\u5B57\u8272", code: "text" },
|
|
@@ -2005,9 +2185,15 @@ var TOKEN_STATES = [
|
|
|
2005
2185
|
{ key: "warning", label: "\u8B66\u544A\u6001", code: "warning" }
|
|
2006
2186
|
];
|
|
2007
2187
|
function ColorDropdown({ value, onChange, onClose, onAddToken, pos, colorPalette }) {
|
|
2008
|
-
const
|
|
2188
|
+
const resolvedValue = resolveColorValue(value);
|
|
2189
|
+
const initHex = /^#[0-9a-f]{6}$/i.test(resolvedValue) ? resolvedValue : "#6b7280";
|
|
2190
|
+
const initAlpha = (() => {
|
|
2191
|
+
const rgbaMatch = value.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)$/i);
|
|
2192
|
+
if (!rgbaMatch) return 100;
|
|
2193
|
+
return Math.max(0, Math.min(100, Math.round(parseFloat(rgbaMatch[4]) * 100)));
|
|
2194
|
+
})();
|
|
2009
2195
|
const [hexInput, setHexInput] = useState(initHex);
|
|
2010
|
-
const [alpha, setAlpha] = useState(
|
|
2196
|
+
const [alpha, setAlpha] = useState(initAlpha);
|
|
2011
2197
|
const customColorInputRef = useRef(null);
|
|
2012
2198
|
function buildColor(hex, a) {
|
|
2013
2199
|
const m = hex.match(/^#([0-9a-f]{6})$/i);
|
|
@@ -2277,10 +2463,11 @@ function AddTokenModal({ value, cssProp, elementClasses, onClose, onConfirm, col
|
|
|
2277
2463
|
}
|
|
2278
2464
|
function getDisplayLabel(val, tokenMap, colorPalette, tokenLabels) {
|
|
2279
2465
|
if (isTransparentColor(val)) return { label: "\u65E0", sub: "", isHardcoded: true };
|
|
2280
|
-
const
|
|
2281
|
-
const
|
|
2466
|
+
const resolvedVal = resolveColorValue(val);
|
|
2467
|
+
const displayVal = formatColorDisplay(resolvedVal);
|
|
2468
|
+
const paletteLabel = getColorLabel(resolvedVal, colorPalette);
|
|
2282
2469
|
if (paletteLabel) return { label: paletteLabel, sub: displayVal, isHardcoded: false };
|
|
2283
|
-
const token = tokenMap[val];
|
|
2470
|
+
const token = tokenMap[val] ?? tokenMap[resolvedVal];
|
|
2284
2471
|
if (token) return { label: tokenLabels[token] ?? token.replace("--", ""), sub: displayVal, isHardcoded: false };
|
|
2285
2472
|
return { label: displayVal, sub: "", isHardcoded: true };
|
|
2286
2473
|
}
|
|
@@ -2563,6 +2750,7 @@ function InspectorPanel({
|
|
|
2563
2750
|
const {
|
|
2564
2751
|
colorPalette,
|
|
2565
2752
|
tokenLabels,
|
|
2753
|
+
inspectorTypography,
|
|
2566
2754
|
radiusPresets,
|
|
2567
2755
|
spaceSteps,
|
|
2568
2756
|
borderWidthSteps,
|
|
@@ -2577,6 +2765,28 @@ function InspectorPanel({
|
|
|
2577
2765
|
{ cssVar: "", value: "none", label: "\u65E0", usage: "\u4E0D\u4F7F\u7528\u9634\u5F71" },
|
|
2578
2766
|
...shadowTokens
|
|
2579
2767
|
];
|
|
2768
|
+
const inspectorTypographyVars = {
|
|
2769
|
+
"--di-text-title-size": inspectorTypography.title.fontSize,
|
|
2770
|
+
"--di-text-title-weight": inspectorTypography.title.fontWeight,
|
|
2771
|
+
"--di-text-title-line-height": inspectorTypography.title.lineHeight,
|
|
2772
|
+
"--di-text-title-color": inspectorTypography.title.color,
|
|
2773
|
+
"--di-text-label-size": inspectorTypography.sectionLabel.fontSize,
|
|
2774
|
+
"--di-text-label-weight": inspectorTypography.sectionLabel.fontWeight,
|
|
2775
|
+
"--di-text-label-line-height": inspectorTypography.sectionLabel.lineHeight,
|
|
2776
|
+
"--di-text-label-color": inspectorTypography.sectionLabel.color,
|
|
2777
|
+
"--di-text-body-size": inspectorTypography.body.fontSize,
|
|
2778
|
+
"--di-text-body-weight": inspectorTypography.body.fontWeight,
|
|
2779
|
+
"--di-text-body-line-height": inspectorTypography.body.lineHeight,
|
|
2780
|
+
"--di-text-body-color": inspectorTypography.body.color,
|
|
2781
|
+
"--di-text-meta-size": inspectorTypography.meta.fontSize,
|
|
2782
|
+
"--di-text-meta-weight": inspectorTypography.meta.fontWeight,
|
|
2783
|
+
"--di-text-meta-line-height": inspectorTypography.meta.lineHeight,
|
|
2784
|
+
"--di-text-meta-color": inspectorTypography.meta.color,
|
|
2785
|
+
"--di-text-tiny-badge-size": inspectorTypography.tinyBadge.fontSize,
|
|
2786
|
+
"--di-text-tiny-badge-weight": inspectorTypography.tinyBadge.fontWeight,
|
|
2787
|
+
"--di-text-tiny-badge-line-height": inspectorTypography.tinyBadge.lineHeight,
|
|
2788
|
+
"--di-text-tiny-badge-color": inspectorTypography.tinyBadge.color
|
|
2789
|
+
};
|
|
2580
2790
|
const [isEditing, setIsEditing] = useState(false);
|
|
2581
2791
|
const panelElRef = useRef(null);
|
|
2582
2792
|
const [selected, setSelected] = useState(targetEl);
|
|
@@ -2676,6 +2886,9 @@ function InspectorPanel({
|
|
|
2676
2886
|
const [cardVariantVal, setCardVariantVal] = useState("default");
|
|
2677
2887
|
const [cardVariantClassVal, setCardVariantClassVal] = useState("");
|
|
2678
2888
|
const [pendingCardVariant, setPendingCardVariant] = useState("");
|
|
2889
|
+
const [componentInfoOpen, setComponentInfoOpen] = useState(false);
|
|
2890
|
+
const [annotationOpen, setAnnotationOpen] = useState(false);
|
|
2891
|
+
const [annotationText, setAnnotationText] = useState("");
|
|
2679
2892
|
const [componentMakerSourceMode, setComponentMakerSourceMode] = useState("new");
|
|
2680
2893
|
const [componentMakerAction, setComponentMakerAction] = useState("create-current");
|
|
2681
2894
|
const [componentSpecDraft, setComponentSpecDraft] = useState(EMPTY_COMPONENT_SPEC_DRAFT);
|
|
@@ -2710,6 +2923,8 @@ function InspectorPanel({
|
|
|
2710
2923
|
const [selectedLibraryComponentVariantId, setSelectedLibraryComponentVariantId] = useState("");
|
|
2711
2924
|
const [libraryTokenForm, setLibraryTokenForm] = useState(null);
|
|
2712
2925
|
const [libraryComponentForm, setLibraryComponentForm] = useState(null);
|
|
2926
|
+
const [libraryComponentImportOpen, setLibraryComponentImportOpen] = useState(false);
|
|
2927
|
+
const [libraryComponentImportMsg, setLibraryComponentImportMsg] = useState("");
|
|
2713
2928
|
const [libraryCustomTokens, setLibraryCustomTokens] = useState([]);
|
|
2714
2929
|
const [libraryTokenOverrides, setLibraryTokenOverrides] = useState({});
|
|
2715
2930
|
const [libraryDeletedTokenIds, setLibraryDeletedTokenIds] = useState({});
|
|
@@ -2726,6 +2941,9 @@ function InspectorPanel({
|
|
|
2726
2941
|
useEffect(() => {
|
|
2727
2942
|
localDraftsRef.current = localDrafts;
|
|
2728
2943
|
}, [localDrafts]);
|
|
2944
|
+
useEffect(() => {
|
|
2945
|
+
setComponentInfoOpen(false);
|
|
2946
|
+
}, [selected]);
|
|
2729
2947
|
const formatStyleIntentSummary = useCallback((r) => ({
|
|
2730
2948
|
pendingCount: r.pendingCount ?? 0,
|
|
2731
2949
|
latestPending: r.latestPending ? {
|
|
@@ -2774,6 +2992,50 @@ function InspectorPanel({
|
|
|
2774
2992
|
return next;
|
|
2775
2993
|
});
|
|
2776
2994
|
}
|
|
2995
|
+
function getAnnotationTargetInfo(el) {
|
|
2996
|
+
const componentMeta2 = getInspectorComponentMeta(el);
|
|
2997
|
+
const selector = getSelectorForScope(el, "current");
|
|
2998
|
+
return {
|
|
2999
|
+
key: `current:${selector}`,
|
|
3000
|
+
selector,
|
|
3001
|
+
targetLabel: getTargetDisplayLabel(el, componentMeta2),
|
|
3002
|
+
scopeLabel: "\u5F53\u524D\u5143\u7D20"
|
|
3003
|
+
};
|
|
3004
|
+
}
|
|
3005
|
+
function getAnnotationChange(changes = []) {
|
|
3006
|
+
return changes.find((change) => change.prop === "annotation:intent");
|
|
3007
|
+
}
|
|
3008
|
+
function updateAnnotationDraft(nextText) {
|
|
3009
|
+
const el = selectedRef.current;
|
|
3010
|
+
if (!el) return;
|
|
3011
|
+
const text = nextText.trim();
|
|
3012
|
+
const info = getAnnotationTargetInfo(el);
|
|
3013
|
+
setLocalDrafts((prev) => {
|
|
3014
|
+
const existing = prev[info.key];
|
|
3015
|
+
const remainingChanges = existing?.changes.filter((change2) => change2.prop !== "annotation:intent") ?? [];
|
|
3016
|
+
if (!text) {
|
|
3017
|
+
if (!existing) return prev;
|
|
3018
|
+
const next = { ...prev };
|
|
3019
|
+
if (remainingChanges.length === 0) {
|
|
3020
|
+
delete next[info.key];
|
|
3021
|
+
} else {
|
|
3022
|
+
next[info.key] = { ...existing, changes: remainingChanges, updatedAt: Date.now() };
|
|
3023
|
+
}
|
|
3024
|
+
return next;
|
|
3025
|
+
}
|
|
3026
|
+
const change = {
|
|
3027
|
+
prop: "annotation:intent",
|
|
3028
|
+
from: "AI\u8BC6\u522B",
|
|
3029
|
+
val: text
|
|
3030
|
+
};
|
|
3031
|
+
const nextEntry = {
|
|
3032
|
+
...info,
|
|
3033
|
+
changes: [...remainingChanges, change],
|
|
3034
|
+
updatedAt: Date.now()
|
|
3035
|
+
};
|
|
3036
|
+
return { ...prev, [info.key]: nextEntry };
|
|
3037
|
+
});
|
|
3038
|
+
}
|
|
2777
3039
|
const selectEl = useCallback((el) => {
|
|
2778
3040
|
selectedRef.current = el;
|
|
2779
3041
|
const rect = el.getBoundingClientRect();
|
|
@@ -2782,6 +3044,8 @@ function InspectorPanel({
|
|
|
2782
3044
|
const elCs = getComputedStyle(el);
|
|
2783
3045
|
const selectedComponentMeta = getInspectorComponentMeta(el);
|
|
2784
3046
|
const selectedCapability = getComponentCapability(selectedComponentMeta);
|
|
3047
|
+
const annotationDraft = localDraftsRef.current[getAnnotationTargetInfo(el).key];
|
|
3048
|
+
setAnnotationText(getAnnotationChange(annotationDraft?.changes)?.val ?? "");
|
|
2785
3049
|
const isButtonComponent = selectedCapability?.type === "Button";
|
|
2786
3050
|
const isIconComponent = selectedCapability?.type === "Icon";
|
|
2787
3051
|
const isBadgeComponent = selectedCapability?.type === "Badge";
|
|
@@ -3244,6 +3508,15 @@ function InspectorPanel({
|
|
|
3244
3508
|
setPendingBadgeStatus(status);
|
|
3245
3509
|
setBadgeStatusOnTargets(targets, status);
|
|
3246
3510
|
}
|
|
3511
|
+
function updateBadgeStatusOnElement(element, status) {
|
|
3512
|
+
const currentStatus = inferBadgeStatus(getClasses(element));
|
|
3513
|
+
const currentClass = getBadgeStatusClass(element);
|
|
3514
|
+
if (status === currentStatus) {
|
|
3515
|
+
setBadgeStatusOnTargets([element], currentStatus, currentClass);
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
setBadgeStatusOnTargets([element], status);
|
|
3519
|
+
}
|
|
3247
3520
|
function updateCardVariant(variant) {
|
|
3248
3521
|
const targets = getComponentTargets();
|
|
3249
3522
|
if (variant === cardVariantVal) {
|
|
@@ -4097,6 +4370,7 @@ function InspectorPanel({
|
|
|
4097
4370
|
}
|
|
4098
4371
|
function copyPluginPrompt(prompt, successMsg) {
|
|
4099
4372
|
if (!prompt) return;
|
|
4373
|
+
debugAiPrompt(prompt, "plugin");
|
|
4100
4374
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4101
4375
|
setPluginMsg(copied ? successMsg : "\u590D\u5236\u5931\u8D25");
|
|
4102
4376
|
setTimeout(() => setPluginMsg(""), copied ? 2200 : 1800);
|
|
@@ -4434,6 +4708,7 @@ function InspectorPanel({
|
|
|
4434
4708
|
return `${item.label} / ${item.type} / ${item.categoryLabel} / ${item.summary || "\u672A\u767B\u8BB0\u80FD\u529B"} / ${item.selector || "\u672A\u767B\u8BB0 selector"} / ${item.status}`;
|
|
4435
4709
|
}
|
|
4436
4710
|
function openLibraryComponentCreate() {
|
|
4711
|
+
setLibraryComponentImportOpen(false);
|
|
4437
4712
|
setLibraryComponentForm({
|
|
4438
4713
|
mode: "create",
|
|
4439
4714
|
category: libraryComponentCategory === "all" ? "custom" : libraryComponentCategory,
|
|
@@ -4445,6 +4720,7 @@ function InspectorPanel({
|
|
|
4445
4720
|
});
|
|
4446
4721
|
}
|
|
4447
4722
|
function openLibraryComponentEdit(item) {
|
|
4723
|
+
setLibraryComponentImportOpen(false);
|
|
4448
4724
|
setSelectedLibraryComponentId(item.id);
|
|
4449
4725
|
setLibraryComponentForm({
|
|
4450
4726
|
mode: "update",
|
|
@@ -4457,6 +4733,103 @@ function InspectorPanel({
|
|
|
4457
4733
|
status: item.status.includes("\u8349\u7A3F") ? item.status : "\u7F16\u8F91\u8349\u7A3F"
|
|
4458
4734
|
});
|
|
4459
4735
|
}
|
|
4736
|
+
function normalizeComponentImportDraft(raw) {
|
|
4737
|
+
const type = String(raw.type || "").trim() || "Custom";
|
|
4738
|
+
const category = raw.category || getLibraryComponentCategory(type);
|
|
4739
|
+
const variantText = Array.isArray(raw.variants) && raw.variants.length ? `\u53D8\u4F53\uFF1A${raw.variants.join(" / ")}` : "";
|
|
4740
|
+
const sizeText = Array.isArray(raw.sizes) && raw.sizes.length ? `\u5C3A\u5BF8\uFF1A${raw.sizes.join(" / ")}` : "";
|
|
4741
|
+
const tokenText = Array.isArray(raw.tokenRefs) && raw.tokenRefs.length ? `Token\uFF1A${raw.tokenRefs.join(" / ")}` : "";
|
|
4742
|
+
return {
|
|
4743
|
+
mode: "create",
|
|
4744
|
+
category,
|
|
4745
|
+
type,
|
|
4746
|
+
label: String(raw.label || LIBRARY_COMPONENT_LABELS[type] || type).trim(),
|
|
4747
|
+
summary: String(raw.summary || [variantText, sizeText, tokenText].filter(Boolean).join("\uFF1B") || "\u5BFC\u5165\u7EC4\u4EF6\u8349\u7A3F").trim(),
|
|
4748
|
+
selector: String(raw.selector || `.${type.toLowerCase()}`).trim(),
|
|
4749
|
+
status: String(raw.status || "\u5BFC\u5165\u8349\u7A3F").trim()
|
|
4750
|
+
};
|
|
4751
|
+
}
|
|
4752
|
+
function submitImportedLibraryComponents(drafts) {
|
|
4753
|
+
const normalized = drafts.map(normalizeComponentImportDraft);
|
|
4754
|
+
const nextItems = normalized.map((form, index) => ({
|
|
4755
|
+
id: `draft-component-import:${Date.now()}:${index}:${form.type}`,
|
|
4756
|
+
category: form.category,
|
|
4757
|
+
categoryLabel: getLibraryComponentCategoryLabel(form.category),
|
|
4758
|
+
type: form.type,
|
|
4759
|
+
label: form.label,
|
|
4760
|
+
summary: form.summary,
|
|
4761
|
+
selector: form.selector,
|
|
4762
|
+
status: form.status,
|
|
4763
|
+
source: "draft"
|
|
4764
|
+
}));
|
|
4765
|
+
if (!nextItems.length) {
|
|
4766
|
+
setLibraryComponentImportMsg("\u6CA1\u6709\u8BC6\u522B\u5230\u7EC4\u4EF6");
|
|
4767
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4768
|
+
return;
|
|
4769
|
+
}
|
|
4770
|
+
setLibraryCustomComponents((prev) => [...nextItems, ...prev]);
|
|
4771
|
+
setSelectedLibraryComponentId(nextItems[0].id);
|
|
4772
|
+
nextItems.forEach((item) => {
|
|
4773
|
+
recordLibraryCrudChange({
|
|
4774
|
+
resource: "component",
|
|
4775
|
+
action: "create",
|
|
4776
|
+
name: item.type,
|
|
4777
|
+
from: "\u672A\u767B\u8BB0",
|
|
4778
|
+
val: formatLibraryComponentSummary(item)
|
|
4779
|
+
});
|
|
4780
|
+
});
|
|
4781
|
+
setLibraryComponentImportMsg(`\u5DF2\u5BFC\u5165 ${nextItems.length} \u4E2A\u7EC4\u4EF6\u8349\u7A3F`);
|
|
4782
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 2200);
|
|
4783
|
+
}
|
|
4784
|
+
async function handleComponentImportFile(file) {
|
|
4785
|
+
if (!file) return;
|
|
4786
|
+
try {
|
|
4787
|
+
const content = await file.text();
|
|
4788
|
+
const parsed = JSON.parse(content);
|
|
4789
|
+
const drafts = Array.isArray(parsed) ? parsed : parsed.components ?? [];
|
|
4790
|
+
submitImportedLibraryComponents(drafts);
|
|
4791
|
+
} catch {
|
|
4792
|
+
setLibraryComponentImportMsg("JSON \u89E3\u6790\u5931\u8D25");
|
|
4793
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
function copyComponentLibraryImportPrompt() {
|
|
4797
|
+
const prompt = [
|
|
4798
|
+
"\u8BF7\u4E3A\u5F53\u524D\u9879\u76EE\u751F\u6210 DevInspector \u7EC4\u4EF6\u5E93\u63A5\u5165\u8349\u7A3F\u3002",
|
|
4799
|
+
"",
|
|
4800
|
+
"\u76EE\u6807\uFF1A",
|
|
4801
|
+
"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",
|
|
4802
|
+
"2. \u4F18\u5148\u4F7F\u7528 data-component / registry / \u7A33\u5B9A class\uFF1B\u4E0D\u786E\u5B9A\u9879\u6807\u4E3A\u201C\u5F85\u786E\u8BA4\u201D\u3002",
|
|
4803
|
+
"3. \u8F93\u51FA componentPreviews registry \u6216\u4E0B\u9762\u8FD9\u79CD JSON \u8349\u7A3F\u3002",
|
|
4804
|
+
"",
|
|
4805
|
+
"JSON \u683C\u5F0F\uFF1A",
|
|
4806
|
+
"{",
|
|
4807
|
+
' "components": [',
|
|
4808
|
+
" {",
|
|
4809
|
+
' "type": "Button",',
|
|
4810
|
+
' "label": "\u6309\u94AE",',
|
|
4811
|
+
' "category": "action",',
|
|
4812
|
+
' "summary": "\u4E3B\u6309\u94AE\u3001\u6B21\u6309\u94AE\u3001\u5F31\u6309\u94AE",',
|
|
4813
|
+
' "selector": ".button, [data-component=\\"Button\\"]",',
|
|
4814
|
+
' "variants": ["primary", "secondary", "ghost"],',
|
|
4815
|
+
' "sizes": ["s", "m", "l"],',
|
|
4816
|
+
' "tokenRefs": ["--color-brand-primary"],',
|
|
4817
|
+
' "status": "\u5F85\u786E\u8BA4"',
|
|
4818
|
+
" }",
|
|
4819
|
+
" ]",
|
|
4820
|
+
"}",
|
|
4821
|
+
"",
|
|
4822
|
+
"\u7EA6\u675F\uFF1A\u8BF7\u4FEE\u6539\u6E90\u7801\u5C42\u63A5\u5165\uFF0C\u4E0D\u8981\u76F4\u63A5\u6539 dist \u4EA7\u7269\u3002"
|
|
4823
|
+
].join("\n");
|
|
4824
|
+
debugAiPrompt(prompt, "plugin");
|
|
4825
|
+
copyTextToClipboard(prompt).then((copied) => {
|
|
4826
|
+
setLibraryComponentImportMsg(copied ? "\u63A5\u5165\u63D0\u793A\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4827
|
+
setTimeout(() => setLibraryComponentImportMsg(""), copied ? 2200 : 1800);
|
|
4828
|
+
}).catch(() => {
|
|
4829
|
+
setLibraryComponentImportMsg("\u590D\u5236\u5931\u8D25");
|
|
4830
|
+
setTimeout(() => setLibraryComponentImportMsg(""), 1800);
|
|
4831
|
+
});
|
|
4832
|
+
}
|
|
4460
4833
|
function submitLibraryComponentForm() {
|
|
4461
4834
|
if (!libraryComponentForm) return;
|
|
4462
4835
|
const category = libraryComponentForm.category || getLibraryComponentCategory(libraryComponentForm.type);
|
|
@@ -4512,47 +4885,79 @@ function InspectorPanel({
|
|
|
4512
4885
|
});
|
|
4513
4886
|
}
|
|
4514
4887
|
function buildAiTaskPrompt(params) {
|
|
4515
|
-
const changes = params.changes
|
|
4516
|
-
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";
|
|
4888
|
+
const changes = formatPromptChanges(params.changes);
|
|
4517
4889
|
return [
|
|
4518
|
-
"DevInspector \u6837\u5F0F\u4EFB\u52A1",
|
|
4519
4890
|
`\u9875\u9762\uFF1A${params.pageLabel}`,
|
|
4520
|
-
|
|
4891
|
+
"\u5F85\u5904\u7406\u5BF9\u8C61\uFF1A1",
|
|
4892
|
+
`1. \u5143\u7D20\uFF1A${params.targetLabel}`,
|
|
4521
4893
|
`\u8303\u56F4\uFF1A${params.scopeLabel}`,
|
|
4522
4894
|
`\u9009\u62E9\u5668\uFF1A${params.selector}`,
|
|
4895
|
+
`\u7C7B\u578B\uFF1A${getPromptChangeTypes(params.changes).join(" / ") || "none"}`,
|
|
4523
4896
|
"\u6539\u52A8\uFF1A",
|
|
4524
|
-
changes || "\u65E0\
|
|
4897
|
+
changes || "1. \u65E0\u6539\u52A8",
|
|
4525
4898
|
...params.note ? ["\u8865\u5145\uFF1A", params.note] : [],
|
|
4526
|
-
"\u5B9A\u4F4D\
|
|
4527
|
-
latestHint,
|
|
4528
|
-
"\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"
|
|
4899
|
+
"\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"
|
|
4529
4900
|
].join("\n");
|
|
4530
4901
|
}
|
|
4531
4902
|
function buildAiDraftBasketPrompt(drafts) {
|
|
4532
4903
|
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:")));
|
|
4533
4904
|
const hasLibraryChange = drafts.some((draft) => draft.changes.some((change) => change.prop.startsWith("library-")));
|
|
4905
|
+
const mode = hasLibraryChange ? "library-crud" : hasComponentSpec ? "component-spec" : "style-update";
|
|
4534
4906
|
const sections = drafts.sort((a, b) => a.updatedAt - b.updatedAt).map((draft, index) => {
|
|
4535
|
-
const changes = draft.changes
|
|
4907
|
+
const changes = formatPromptChanges(draft.changes);
|
|
4536
4908
|
return [
|
|
4537
4909
|
`${index + 1}. \u5143\u7D20\uFF1A${draft.targetLabel}`,
|
|
4538
4910
|
`\u8303\u56F4\uFF1A${draft.scopeLabel}`,
|
|
4539
4911
|
`\u9009\u62E9\u5668\uFF1A${draft.selector}`,
|
|
4912
|
+
`\u7C7B\u578B\uFF1A${getPromptChangeTypes(draft.changes).join(" / ") || "none"}`,
|
|
4540
4913
|
"\u6539\u52A8\uFF1A",
|
|
4541
|
-
changes || "\u65E0\
|
|
4914
|
+
changes || "1. \u65E0\u6539\u52A8"
|
|
4542
4915
|
].join("\n");
|
|
4543
4916
|
}).join("\n\n");
|
|
4544
|
-
const
|
|
4545
|
-
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";
|
|
4917
|
+
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";
|
|
4546
4918
|
return [
|
|
4547
|
-
title,
|
|
4548
4919
|
`\u9875\u9762\uFF1A${document.title || "\u5F53\u524D\u9875\u9762"}\uFF08${window.location.href}\uFF09`,
|
|
4549
4920
|
`\u5F85\u5904\u7406\u5BF9\u8C61\uFF1A${drafts.length}`,
|
|
4550
4921
|
sections,
|
|
4551
4922
|
...note ? ["\u8865\u5145\uFF1A", note] : [],
|
|
4552
|
-
|
|
4553
|
-
locationHint
|
|
4923
|
+
aiHint
|
|
4554
4924
|
].join("\n");
|
|
4555
4925
|
}
|
|
4926
|
+
function getPromptChangeType(prop) {
|
|
4927
|
+
if (prop.startsWith("annotation:")) return "annotation";
|
|
4928
|
+
if (prop === "component-spec") return "component-spec";
|
|
4929
|
+
if (prop.startsWith("component-new-variant:")) return "component-new-variant";
|
|
4930
|
+
if (prop.startsWith("component-variant-group:")) return "component-variant-group";
|
|
4931
|
+
if (prop.startsWith("library-token:create")) return "library-token-create";
|
|
4932
|
+
if (prop.startsWith("library-token:update")) return "library-token-update";
|
|
4933
|
+
if (prop.startsWith("library-token:delete")) return "library-token-delete";
|
|
4934
|
+
if (prop.startsWith("library-component:create")) return "library-component-create";
|
|
4935
|
+
if (prop.startsWith("library-component:update")) return "library-component-update";
|
|
4936
|
+
if (prop.startsWith("library-component:delete")) return "library-component-delete";
|
|
4937
|
+
return "style";
|
|
4938
|
+
}
|
|
4939
|
+
function getPromptChangeTypes(changes) {
|
|
4940
|
+
return Array.from(new Set(changes.map((change) => getPromptChangeType(change.prop))));
|
|
4941
|
+
}
|
|
4942
|
+
function formatPromptChanges(changes) {
|
|
4943
|
+
return changes.map((change, index) => {
|
|
4944
|
+
const type = getPromptChangeType(change.prop);
|
|
4945
|
+
if (type === "annotation") {
|
|
4946
|
+
return [
|
|
4947
|
+
`${index + 1}. \u6807\u6CE8\uFF1A${change.val || "\u7A7A"}`
|
|
4948
|
+
].join("\n");
|
|
4949
|
+
}
|
|
4950
|
+
return [
|
|
4951
|
+
`${index + 1}. ${getChangeLabel(change.prop)}\uFF1A${formatStoredChangeRecordValue(change.prop, change.from) || "\u7A7A"} \u2192 ${formatStoredChangeRecordValue(change.prop, change.val) || "\u7A7A"}`
|
|
4952
|
+
].join("\n");
|
|
4953
|
+
}).join("\n");
|
|
4954
|
+
}
|
|
4955
|
+
function debugAiPrompt(prompt, source) {
|
|
4956
|
+
window.__DEV_INSPECTOR_LAST_PROMPT__ = prompt;
|
|
4957
|
+
console.groupCollapsed(`[DevInspector] AI prompt (${source})`);
|
|
4958
|
+
console.log(prompt);
|
|
4959
|
+
console.groupEnd();
|
|
4960
|
+
}
|
|
4556
4961
|
function handleSubmitToAi() {
|
|
4557
4962
|
const draftEntries = Object.values(localDraftsRef.current);
|
|
4558
4963
|
if (draftEntries.length > 0) {
|
|
@@ -4580,8 +4985,9 @@ function InspectorPanel({
|
|
|
4580
4985
|
changes,
|
|
4581
4986
|
note
|
|
4582
4987
|
});
|
|
4988
|
+
debugAiPrompt(prompt, "single");
|
|
4583
4989
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4584
|
-
setSubmitMsg(copied ? "\
|
|
4990
|
+
setSubmitMsg(copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4585
4991
|
setTimeout(() => setSubmitMsg(""), copied ? 2200 : 1800);
|
|
4586
4992
|
}).catch(() => {
|
|
4587
4993
|
setSubmitMsg("\u590D\u5236\u5931\u8D25");
|
|
@@ -4590,8 +4996,9 @@ function InspectorPanel({
|
|
|
4590
4996
|
}
|
|
4591
4997
|
function copyDraftEntriesToAi(draftEntries) {
|
|
4592
4998
|
const prompt = buildAiDraftBasketPrompt(draftEntries);
|
|
4999
|
+
debugAiPrompt(prompt, "draft-basket");
|
|
4593
5000
|
copyTextToClipboard(prompt).then((copied) => {
|
|
4594
|
-
setSubmitMsg(copied ? "\
|
|
5001
|
+
setSubmitMsg(copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u5931\u8D25");
|
|
4595
5002
|
setTimeout(() => setSubmitMsg(""), copied ? 2200 : 1800);
|
|
4596
5003
|
}).catch(() => {
|
|
4597
5004
|
setSubmitMsg("\u590D\u5236\u5931\u8D25");
|
|
@@ -4773,6 +5180,9 @@ function InspectorPanel({
|
|
|
4773
5180
|
});
|
|
4774
5181
|
});
|
|
4775
5182
|
function getChangeLabel(prop) {
|
|
5183
|
+
if (prop.startsWith("annotation:")) {
|
|
5184
|
+
return "\u6807\u6CE8 \xB7 AI\u8BC6\u522B";
|
|
5185
|
+
}
|
|
4776
5186
|
if (prop.startsWith("library-token:") || prop.startsWith("library-component:")) {
|
|
4777
5187
|
const [resource = "", action = "", name = "\u672A\u547D\u540D"] = prop.split(":");
|
|
4778
5188
|
const resourceLabel = resource === "library-token" ? "Token" : "\u7EC4\u4EF6\u89C4\u683C";
|
|
@@ -4902,6 +5312,7 @@ function InspectorPanel({
|
|
|
4902
5312
|
function resetDraftChangeOnPage(draft, change) {
|
|
4903
5313
|
const isCurrentDraft = selectedRef.current ? getDraftTargetInfo(selectedRef.current).key === draft.key : false;
|
|
4904
5314
|
if (isCurrentDraft) clearPendingForProp(change.prop);
|
|
5315
|
+
if (change.prop.startsWith("annotation:")) return;
|
|
4905
5316
|
if (change.prop.startsWith("library-")) return;
|
|
4906
5317
|
if (change.prop === "component-spec" || change.prop.startsWith("component-new-variant:")) return;
|
|
4907
5318
|
const targets = getDraftSelectorTargets(draft.selector);
|
|
@@ -5218,6 +5629,29 @@ function InspectorPanel({
|
|
|
5218
5629
|
const activeBadgeStatus = pendingBadgeStatus || badgeStatusVal;
|
|
5219
5630
|
const activeCardVariant = pendingCardVariant || cardVariantVal;
|
|
5220
5631
|
const componentSizeOptions = getComponentSizeControlOptions(componentCapability);
|
|
5632
|
+
const componentPrimaryText = pendingComponentText ?? componentTextDraft ?? componentTextVal ?? componentEditableSlots.map((slot) => componentTextSlotDrafts[slot.key] || componentTextSlotVals[slot.key] || "").find(Boolean) ?? textContent ?? "";
|
|
5633
|
+
const componentElementInfos = componentMeta ? (() => {
|
|
5634
|
+
const items = [];
|
|
5635
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5636
|
+
const pushItem = (label, element) => {
|
|
5637
|
+
if (!element || seen.has(element)) return;
|
|
5638
|
+
seen.add(element);
|
|
5639
|
+
items.push({
|
|
5640
|
+
key: `${label}:${getSelectorForScope(element, "current")}`,
|
|
5641
|
+
label,
|
|
5642
|
+
selector: getSelectorForScope(element, "current"),
|
|
5643
|
+
text: (element.textContent ?? "").trim() || "\u7A7A",
|
|
5644
|
+
style: getComponentElementStyleSummary(element),
|
|
5645
|
+
spacing: getComponentElementSpacingSummary(element),
|
|
5646
|
+
styleStatus: getComponentElementStyleStatus(element, tokenMap, colorPalette, tokenLabels, typographyTokens),
|
|
5647
|
+
spacingStatus: getComponentElementSpacingStatus(element, spaceSteps)
|
|
5648
|
+
});
|
|
5649
|
+
};
|
|
5650
|
+
pushItem("\u7EC4\u4EF6\u5916\u5C42", selected);
|
|
5651
|
+
componentEditableSlots.forEach((slot) => pushItem(slot.label, getComponentSlotElement(selected, slot)));
|
|
5652
|
+
componentChildSlots.forEach((slot) => pushItem(slot.label, getComponentSlotElement(selected, slot)));
|
|
5653
|
+
return items;
|
|
5654
|
+
})() : [];
|
|
5221
5655
|
const showElementStyleSections = !componentMeta;
|
|
5222
5656
|
const localDraftEntries = Object.values(localDrafts).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
5223
5657
|
const localDraftChangeCount = localDraftEntries.reduce((sum, entry) => sum + entry.changes.length, 0);
|
|
@@ -5604,7 +6038,7 @@ function InspectorPanel({
|
|
|
5604
6038
|
ref: panelElRef,
|
|
5605
6039
|
className: `di-panel${componentCreateOpen || libraryOpen ? " di-panel--drawer-open" : ""}${libraryWorkbenchOpen ? " di-panel--workbench-open" : ""}`,
|
|
5606
6040
|
"data-di-panel-role": "primary",
|
|
5607
|
-
style: { top: panelPos.top, left: panelPos.left },
|
|
6041
|
+
style: { top: panelPos.top, left: panelPos.left, ...inspectorTypographyVars },
|
|
5608
6042
|
children: [
|
|
5609
6043
|
/* @__PURE__ */ jsxs("div", { className: "di-head", onMouseDown: onDragStart, children: [
|
|
5610
6044
|
/* @__PURE__ */ jsxs("div", { className: "di-head-left", children: [
|
|
@@ -6025,7 +6459,24 @@ function InspectorPanel({
|
|
|
6025
6459
|
" \u4E2A\u89C4\u683C"
|
|
6026
6460
|
] })
|
|
6027
6461
|
] }),
|
|
6028
|
-
/* @__PURE__ */
|
|
6462
|
+
/* @__PURE__ */ jsxs("div", { className: "di-library-toolbar-actions", children: [
|
|
6463
|
+
/* @__PURE__ */ jsxs(
|
|
6464
|
+
"button",
|
|
6465
|
+
{
|
|
6466
|
+
type: "button",
|
|
6467
|
+
className: "di-library-workbench-soft-btn",
|
|
6468
|
+
onClick: () => {
|
|
6469
|
+
setLibraryComponentImportOpen(true);
|
|
6470
|
+
setLibraryComponentForm(null);
|
|
6471
|
+
},
|
|
6472
|
+
children: [
|
|
6473
|
+
/* @__PURE__ */ jsx2(Upload, { size: 13, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6474
|
+
"\u5BFC\u5165\u7EC4\u4EF6\u5E93"
|
|
6475
|
+
]
|
|
6476
|
+
}
|
|
6477
|
+
),
|
|
6478
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "di-btn-save", onClick: openLibraryComponentCreate, children: "+ \u7EC4\u4EF6\u89C4\u683C" })
|
|
6479
|
+
] })
|
|
6029
6480
|
] }),
|
|
6030
6481
|
/* @__PURE__ */ jsxs("div", { className: "di-library-component-preview-grid", role: "list", "aria-label": "\u7EC4\u4EF6\u771F\u5B9E\u9884\u89C8", children: [
|
|
6031
6482
|
filteredLibraryComponentItems.map((item) => {
|
|
@@ -6097,7 +6548,7 @@ function InspectorPanel({
|
|
|
6097
6548
|
className: "di-btn-save",
|
|
6098
6549
|
disabled: localDraftChangeCount === 0,
|
|
6099
6550
|
onClick: handleSubmitToAi,
|
|
6100
|
-
children: submitMsg
|
|
6551
|
+
children: renderSubmitLabel(submitMsg)
|
|
6101
6552
|
}
|
|
6102
6553
|
)
|
|
6103
6554
|
] }),
|
|
@@ -6290,7 +6741,67 @@ function InspectorPanel({
|
|
|
6290
6741
|
/* @__PURE__ */ jsx2("button", { type: "button", onClick: () => focusLibraryTokenUsage(selectedLibraryToken), children: "\u5B9A\u4F4D\u4F7F\u7528" }),
|
|
6291
6742
|
/* @__PURE__ */ jsx2("button", { type: "button", onClick: () => openLibraryTokenEdit(selectedLibraryToken), children: "\u7F16\u8F91" })
|
|
6292
6743
|
] })
|
|
6293
|
-
] }) : /* @__PURE__ */ jsx2("div", { className: "di-library-workbench-empty", children: "\u9009\u62E9\u4E00\u4E2A token \u67E5\u770B\u8BE6\u60C5" }) : libraryTab === "components" ?
|
|
6744
|
+
] }) : /* @__PURE__ */ jsx2("div", { className: "di-library-workbench-empty", children: "\u9009\u62E9\u4E00\u4E2A token \u67E5\u770B\u8BE6\u60C5" }) : libraryTab === "components" ? libraryComponentImportOpen ? /* @__PURE__ */ jsxs("div", { className: "di-library-import-panel", children: [
|
|
6745
|
+
/* @__PURE__ */ jsxs("div", { className: "di-library-edit-head", children: [
|
|
6746
|
+
/* @__PURE__ */ jsx2("strong", { children: "\u5BFC\u5165\u7EC4\u4EF6\u5E93" }),
|
|
6747
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "di-head-icon-btn", onClick: () => setLibraryComponentImportOpen(false), "aria-label": "\u5173\u95ED\u5BFC\u5165\u7EC4\u4EF6\u5E93", children: /* @__PURE__ */ jsx2(X, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }) })
|
|
6748
|
+
] }),
|
|
6749
|
+
/* @__PURE__ */ jsxs("div", { className: "di-library-import-steps", children: [
|
|
6750
|
+
/* @__PURE__ */ jsx2("span", { children: "\u9009\u4E00\u79CD\u65B9\u5F0F" }),
|
|
6751
|
+
/* @__PURE__ */ jsx2("span", { children: "\u751F\u6210\u63A5\u5165\u8349\u7A3F" }),
|
|
6752
|
+
/* @__PURE__ */ jsx2("span", { children: "\u53D1\u9001\u7ED9 AI \u843D\u5730" })
|
|
6753
|
+
] }),
|
|
6754
|
+
/* @__PURE__ */ jsxs("div", { className: "di-library-import-option di-library-import-option--primary", children: [
|
|
6755
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
6756
|
+
/* @__PURE__ */ jsx2(WandSparkles, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6757
|
+
/* @__PURE__ */ jsx2("strong", { children: "\u8BA9 AI \u5E2E\u4F60\u6574\u7406" }),
|
|
6758
|
+
/* @__PURE__ */ jsx2("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" })
|
|
6759
|
+
] }),
|
|
6760
|
+
/* @__PURE__ */ jsx2("button", { type: "button", onClick: copyComponentLibraryImportPrompt, children: "\u590D\u5236\u63D0\u793A" })
|
|
6761
|
+
] }),
|
|
6762
|
+
/* @__PURE__ */ jsxs("label", { className: "di-library-import-option", children: [
|
|
6763
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
6764
|
+
/* @__PURE__ */ jsx2(Upload, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6765
|
+
/* @__PURE__ */ jsx2("strong", { children: "\u5DF2\u6709\u7EC4\u4EF6\u6E05\u5355" }),
|
|
6766
|
+
/* @__PURE__ */ jsx2("span", { children: "\u4E0A\u4F20 JSON \u540E\u5148\u53D8\u6210\u8349\u7A3F\uFF0C\u4E0D\u4F1A\u76F4\u63A5\u6539\u6E90\u7801\u3002" })
|
|
6767
|
+
] }),
|
|
6768
|
+
/* @__PURE__ */ jsx2(
|
|
6769
|
+
"input",
|
|
6770
|
+
{
|
|
6771
|
+
type: "file",
|
|
6772
|
+
accept: "application/json,.json",
|
|
6773
|
+
onChange: (event) => {
|
|
6774
|
+
void handleComponentImportFile(event.currentTarget.files?.[0] ?? null);
|
|
6775
|
+
event.currentTarget.value = "";
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
)
|
|
6779
|
+
] }),
|
|
6780
|
+
/* @__PURE__ */ jsxs("div", { className: "di-library-import-option", children: [
|
|
6781
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
6782
|
+
/* @__PURE__ */ jsx2(ComponentIcon, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }),
|
|
6783
|
+
/* @__PURE__ */ jsx2("strong", { children: "\u5148\u52A0\u4E00\u4E2A\u8BD5\u8BD5" }),
|
|
6784
|
+
/* @__PURE__ */ jsx2("span", { children: "\u53EA\u767B\u8BB0\u4E00\u4E2A\u7EC4\u4EF6\uFF0C\u6BD4\u5982 Button \u6216 Card\u3002" })
|
|
6785
|
+
] }),
|
|
6786
|
+
/* @__PURE__ */ jsx2("button", { type: "button", onClick: openLibraryComponentCreate, children: "\u6DFB\u52A0\u7EC4\u4EF6" })
|
|
6787
|
+
] }),
|
|
6788
|
+
/* @__PURE__ */ jsxs("details", { className: "di-library-import-format", children: [
|
|
6789
|
+
/* @__PURE__ */ jsx2("summary", { children: "\u67E5\u770B JSON \u683C\u5F0F" }),
|
|
6790
|
+
/* @__PURE__ */ jsx2("pre", { children: `{
|
|
6791
|
+
"components": [
|
|
6792
|
+
{
|
|
6793
|
+
"type": "Button",
|
|
6794
|
+
"label": "\u6309\u94AE",
|
|
6795
|
+
"category": "action",
|
|
6796
|
+
"selector": ".button",
|
|
6797
|
+
"variants": ["primary", "secondary"],
|
|
6798
|
+
"tokenRefs": ["--color-brand-primary"]
|
|
6799
|
+
}
|
|
6800
|
+
]
|
|
6801
|
+
}` })
|
|
6802
|
+
] }),
|
|
6803
|
+
libraryComponentImportMsg ? /* @__PURE__ */ jsx2("div", { className: "di-library-import-msg", children: libraryComponentImportMsg }) : null
|
|
6804
|
+
] }) : libraryComponentForm ? /* @__PURE__ */ jsxs("div", { className: "di-library-edit-panel", children: [
|
|
6294
6805
|
/* @__PURE__ */ jsxs("div", { className: "di-library-edit-head", children: [
|
|
6295
6806
|
/* @__PURE__ */ jsx2("strong", { children: libraryComponentForm.mode === "create" ? "\u65B0\u589E\u7EC4\u4EF6\u89C4\u683C" : "\u7F16\u8F91\u7EC4\u4EF6\u89C4\u683C" }),
|
|
6296
6807
|
/* @__PURE__ */ jsx2("button", { type: "button", className: "di-head-icon-btn", onClick: () => setLibraryComponentForm(null), "aria-label": "\u5173\u95ED\u7EC4\u4EF6\u89C4\u683C\u8868\u5355", children: /* @__PURE__ */ jsx2(X, { size: 15, strokeWidth: 2.2, "aria-hidden": "true" }) })
|
|
@@ -6416,7 +6927,7 @@ function InspectorPanel({
|
|
|
6416
6927
|
/* @__PURE__ */ jsx2("dd", { children: "\u53EA\u751F\u6210 AI \u4EFB\u52A1\uFF0C\u4E0D\u76F4\u63A5\u5199\u6E90\u7801" })
|
|
6417
6928
|
] })
|
|
6418
6929
|
] }),
|
|
6419
|
-
/* @__PURE__ */ jsx2("div", { className: "di-library-detail-actions", children: /* @__PURE__ */ jsx2("button", { type: "button", onClick: handleSubmitToAi, disabled: localDraftChangeCount === 0, children: submitMsg
|
|
6930
|
+
/* @__PURE__ */ jsx2("div", { className: "di-library-detail-actions", children: /* @__PURE__ */ jsx2("button", { type: "button", onClick: handleSubmitToAi, disabled: localDraftChangeCount === 0, children: renderSubmitLabel(submitMsg) }) })
|
|
6420
6931
|
] }) : /* @__PURE__ */ jsxs("div", { className: "di-library-detail-card", children: [
|
|
6421
6932
|
/* @__PURE__ */ jsx2("div", { className: "di-library-detail-kicker", children: "Usage" }),
|
|
6422
6933
|
/* @__PURE__ */ jsx2("h3", { children: "\u4F7F\u7528\u6CBB\u7406" }),
|
|
@@ -6448,7 +6959,7 @@ function InspectorPanel({
|
|
|
6448
6959
|
className: "di-btn-save",
|
|
6449
6960
|
disabled: localDraftChangeCount === 0,
|
|
6450
6961
|
onClick: handleSubmitToAi,
|
|
6451
|
-
children: submitMsg
|
|
6962
|
+
children: renderSubmitLabel(submitMsg)
|
|
6452
6963
|
}
|
|
6453
6964
|
)
|
|
6454
6965
|
] })
|
|
@@ -7019,18 +7530,74 @@ function InspectorPanel({
|
|
|
7019
7530
|
componentMeta && /* @__PURE__ */ jsxs("div", { className: "di-section", children: [
|
|
7020
7531
|
/* @__PURE__ */ jsx2("div", { className: "di-section-title", children: "\u7EC4\u4EF6" }),
|
|
7021
7532
|
/* @__PURE__ */ jsxs("div", { className: "di-component-card", children: [
|
|
7022
|
-
/* @__PURE__ */
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7533
|
+
/* @__PURE__ */ jsxs("div", { className: "di-component-head", children: [
|
|
7534
|
+
/* @__PURE__ */ jsx2("div", { className: "di-component-main", children: /* @__PURE__ */ jsxs("div", { className: "di-component-title-row", children: [
|
|
7535
|
+
/* @__PURE__ */ jsx2("span", { className: "di-component-name", children: componentDisplayName }),
|
|
7536
|
+
/* @__PURE__ */ jsx2(
|
|
7537
|
+
MatchBadge,
|
|
7538
|
+
{
|
|
7539
|
+
label: componentCapability ? "\u5DF2\u5339\u914D" : "\u5F85\u8865\u5145",
|
|
7540
|
+
tone: componentCapability ? "matched" : "pending",
|
|
7541
|
+
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"
|
|
7542
|
+
}
|
|
7543
|
+
)
|
|
7544
|
+
] }) }),
|
|
7545
|
+
/* @__PURE__ */ jsxs(
|
|
7546
|
+
"button",
|
|
7547
|
+
{
|
|
7548
|
+
type: "button",
|
|
7549
|
+
className: `di-component-meta-toggle${componentInfoOpen ? " di-component-meta-toggle--on" : ""}`,
|
|
7550
|
+
onClick: () => setComponentInfoOpen((open) => !open),
|
|
7551
|
+
"aria-expanded": componentInfoOpen,
|
|
7552
|
+
"aria-label": componentInfoOpen ? "\u6536\u8D77\u5143\u7D20\u4FE1\u606F" : "\u67E5\u770B\u5143\u7D20\u4FE1\u606F",
|
|
7553
|
+
title: componentInfoOpen ? "\u6536\u8D77\u5143\u7D20\u4FE1\u606F" : "\u67E5\u770B\u5143\u7D20\u4FE1\u606F",
|
|
7554
|
+
children: [
|
|
7555
|
+
/* @__PURE__ */ jsx2("span", { children: "\u5143\u7D20\u4FE1\u606F" }),
|
|
7556
|
+
/* @__PURE__ */ jsx2(ChevronDown, { size: 14, strokeWidth: 2.2, "aria-hidden": "true" })
|
|
7557
|
+
]
|
|
7558
|
+
}
|
|
7559
|
+
)
|
|
7560
|
+
] }),
|
|
7561
|
+
/* @__PURE__ */ jsx2("div", { className: "di-component-meta-block", children: componentInfoOpen && /* @__PURE__ */ jsx2("div", { className: "di-component-info-panel", children: componentElementInfos.length > 0 && /* @__PURE__ */ jsx2("div", { className: "di-component-info-elements", children: /* @__PURE__ */ jsx2("div", { className: "di-component-info-element-list", children: componentElementInfos.map((item) => /* @__PURE__ */ jsxs("section", { className: "di-component-info-element-card", children: [
|
|
7562
|
+
/* @__PURE__ */ jsxs("div", { className: "di-component-info-element-head", children: [
|
|
7563
|
+
/* @__PURE__ */ jsx2("span", { className: "di-component-info-element-label", children: item.label }),
|
|
7564
|
+
/* @__PURE__ */ jsx2("span", { className: "di-component-info-element-selector", title: item.selector, children: item.selector })
|
|
7028
7565
|
] }),
|
|
7029
|
-
/* @__PURE__ */ jsxs("
|
|
7030
|
-
"
|
|
7031
|
-
|
|
7566
|
+
/* @__PURE__ */ jsxs("dl", { className: "di-component-info-element-meta", children: [
|
|
7567
|
+
/* @__PURE__ */ jsxs("div", { className: "di-component-info-row", children: [
|
|
7568
|
+
/* @__PURE__ */ jsx2("dt", { children: "\u5185\u5BB9" }),
|
|
7569
|
+
/* @__PURE__ */ jsx2("dd", { title: item.text, children: item.text })
|
|
7570
|
+
] }),
|
|
7571
|
+
/* @__PURE__ */ jsxs("div", { className: "di-component-info-row", children: [
|
|
7572
|
+
/* @__PURE__ */ jsx2("dt", { children: "\u6837\u5F0F" }),
|
|
7573
|
+
/* @__PURE__ */ jsx2("dd", { title: item.style, children: /* @__PURE__ */ jsxs("span", { className: "di-component-info-inline", children: [
|
|
7574
|
+
/* @__PURE__ */ jsx2("span", { children: item.style }),
|
|
7575
|
+
/* @__PURE__ */ jsx2(
|
|
7576
|
+
MatchBadge,
|
|
7577
|
+
{
|
|
7578
|
+
label: item.styleStatus === "token" ? "Token" : "\u771F\u5B9E\u503C",
|
|
7579
|
+
tone: item.styleStatus,
|
|
7580
|
+
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"
|
|
7581
|
+
}
|
|
7582
|
+
)
|
|
7583
|
+
] }) })
|
|
7584
|
+
] }),
|
|
7585
|
+
/* @__PURE__ */ jsxs("div", { className: "di-component-info-row", children: [
|
|
7586
|
+
/* @__PURE__ */ jsx2("dt", { children: "\u95F4\u8DDD" }),
|
|
7587
|
+
/* @__PURE__ */ jsx2("dd", { title: item.spacing, children: /* @__PURE__ */ jsxs("span", { className: "di-component-info-inline", children: [
|
|
7588
|
+
/* @__PURE__ */ jsx2("span", { children: item.spacing }),
|
|
7589
|
+
item.spacingStatus && /* @__PURE__ */ jsx2(
|
|
7590
|
+
MatchBadge,
|
|
7591
|
+
{
|
|
7592
|
+
label: item.spacingStatus === "token" ? "Token" : "\u771F\u5B9E\u503C",
|
|
7593
|
+
tone: item.spacingStatus,
|
|
7594
|
+
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"
|
|
7595
|
+
}
|
|
7596
|
+
)
|
|
7597
|
+
] }) })
|
|
7598
|
+
] })
|
|
7032
7599
|
] })
|
|
7033
|
-
] }),
|
|
7600
|
+
] }, item.key)) }) }) }) }),
|
|
7034
7601
|
componentCapability && /* @__PURE__ */ jsxs("div", { className: "di-component-fields", children: [
|
|
7035
7602
|
componentEditableSlots.map((slot) => /* @__PURE__ */ jsxs("label", { className: "di-component-field di-component-field--text", children: [
|
|
7036
7603
|
/* @__PURE__ */ jsx2("span", { children: slot.label }),
|
|
@@ -7047,24 +7614,38 @@ function InspectorPanel({
|
|
|
7047
7614
|
/* @__PURE__ */ jsx2("span", { children: visibleChildSlots.length === 1 ? visibleChildSlots[0].slot.label : "\u53EF\u9009\u9879" }),
|
|
7048
7615
|
/* @__PURE__ */ jsx2("div", { className: "di-component-child-list", children: visibleChildSlots.map(({ slot, value, element }) => {
|
|
7049
7616
|
const childMeta = element ? getInspectorComponentMeta(element) : null;
|
|
7617
|
+
const childCapability = getComponentCapability(childMeta);
|
|
7050
7618
|
const childName = childMeta ? getComponentDisplayName(childMeta) : slot.label;
|
|
7051
7619
|
const childValue = value || childMeta?.variant || childName;
|
|
7052
7620
|
const showChildLabel = visibleChildSlots.length > 1;
|
|
7621
|
+
const childBadgeStatus = element && childCapability?.statusKind === "badge" ? inferBadgeStatus(getClasses(element)) : null;
|
|
7053
7622
|
return /* @__PURE__ */ jsxs("div", { className: `di-component-child-item${showChildLabel ? " di-component-child-item--with-label" : ""}`, children: [
|
|
7054
7623
|
showChildLabel && /* @__PURE__ */ jsx2("span", { className: "di-component-child-label", children: slot.label }),
|
|
7055
|
-
/* @__PURE__ */ jsx2("
|
|
7056
|
-
/* @__PURE__ */ jsx2(
|
|
7624
|
+
element && childCapability?.statusKind === "badge" ? /* @__PURE__ */ jsx2("div", { className: "di-component-child-variant-grid", role: "group", "aria-label": `${childName} \u72B6\u6001`, children: BADGE_STATUS_OPTIONS.map((option) => /* @__PURE__ */ jsx2(
|
|
7057
7625
|
"button",
|
|
7058
7626
|
{
|
|
7059
7627
|
type: "button",
|
|
7060
|
-
className: "di-component-child-
|
|
7061
|
-
onClick: () =>
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7628
|
+
className: `di-component-child-variant-tile${childBadgeStatus === option.key ? " di-component-child-variant-tile--on" : ""}`,
|
|
7629
|
+
onClick: () => updateBadgeStatusOnElement(element, option.key),
|
|
7630
|
+
title: `${childName} \xB7 ${option.label}`,
|
|
7631
|
+
children: option.label
|
|
7632
|
+
},
|
|
7633
|
+
option.key
|
|
7634
|
+
)) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7635
|
+
/* @__PURE__ */ jsx2("span", { className: "di-component-child-value", children: childValue }),
|
|
7636
|
+
/* @__PURE__ */ jsx2(
|
|
7637
|
+
"button",
|
|
7638
|
+
{
|
|
7639
|
+
type: "button",
|
|
7640
|
+
className: "di-component-child-select",
|
|
7641
|
+
onClick: () => {
|
|
7642
|
+
if (element) selectEl(element);
|
|
7643
|
+
},
|
|
7644
|
+
title: `\u9009\u62E9 ${childName}`,
|
|
7645
|
+
children: "\u9009\u62E9"
|
|
7646
|
+
}
|
|
7647
|
+
)
|
|
7648
|
+
] })
|
|
7068
7649
|
] }, slot.key);
|
|
7069
7650
|
}) })
|
|
7070
7651
|
] }),
|
|
@@ -7120,11 +7701,11 @@ function InspectorPanel({
|
|
|
7120
7701
|
] }),
|
|
7121
7702
|
componentCapability.statusKind === "badge" && /* @__PURE__ */ jsxs("div", { className: "di-component-field", children: [
|
|
7122
7703
|
/* @__PURE__ */ jsx2("span", { children: "\u72B6\u6001" }),
|
|
7123
|
-
/* @__PURE__ */ jsx2("div", { className: "di-component-
|
|
7704
|
+
/* @__PURE__ */ jsx2("div", { className: "di-component-variant-grid", role: "group", "aria-label": "\u6807\u7B7E\u72B6\u6001", children: BADGE_STATUS_OPTIONS.map((option) => /* @__PURE__ */ jsx2(
|
|
7124
7705
|
"button",
|
|
7125
7706
|
{
|
|
7126
7707
|
type: "button",
|
|
7127
|
-
className: `di-component-
|
|
7708
|
+
className: `di-component-variant-tile${activeBadgeStatus === option.key ? " di-component-variant-tile--on" : ""}`,
|
|
7128
7709
|
onClick: () => updateBadgeStatus(option.key),
|
|
7129
7710
|
children: option.label
|
|
7130
7711
|
},
|
|
@@ -8273,6 +8854,43 @@ function InspectorPanel({
|
|
|
8273
8854
|
] })
|
|
8274
8855
|
] })
|
|
8275
8856
|
] }),
|
|
8857
|
+
/* @__PURE__ */ jsxs("div", { className: "di-section di-annotation-section", children: [
|
|
8858
|
+
/* @__PURE__ */ jsxs("div", { className: `di-section-title-row di-section-title-row--action${annotationOpen ? "" : " di-section-title-row--empty"}`, children: [
|
|
8859
|
+
/* @__PURE__ */ jsxs("div", { className: "di-section-title-group", children: [
|
|
8860
|
+
/* @__PURE__ */ jsx2("div", { className: "di-section-title", children: "\u6807\u6CE8" }),
|
|
8861
|
+
localDraftEntries.some((entry) => entry.changes.some((change) => change.prop.startsWith("annotation:"))) && /* @__PURE__ */ jsx2("span", { className: "di-annotation-count", children: "\u5DF2\u8BB0\u5F55" })
|
|
8862
|
+
] }),
|
|
8863
|
+
/* @__PURE__ */ jsx2(
|
|
8864
|
+
"button",
|
|
8865
|
+
{
|
|
8866
|
+
type: "button",
|
|
8867
|
+
className: "di-section-icon-action",
|
|
8868
|
+
onClick: () => setAnnotationOpen((open) => !open),
|
|
8869
|
+
title: annotationOpen ? "\u6536\u8D77\u6807\u6CE8" : "\u6DFB\u52A0\u6807\u6CE8",
|
|
8870
|
+
"aria-label": annotationOpen ? "\u6536\u8D77\u6807\u6CE8" : "\u6DFB\u52A0\u6807\u6CE8",
|
|
8871
|
+
children: annotationOpen ? /* @__PURE__ */ jsx2(Minus, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" }) : /* @__PURE__ */ jsx2(Plus, { size: 14, strokeWidth: 2.4, "aria-hidden": "true" })
|
|
8872
|
+
}
|
|
8873
|
+
)
|
|
8874
|
+
] }),
|
|
8875
|
+
annotationOpen && /* @__PURE__ */ jsx2("div", { className: "di-annotation-card", children: /* @__PURE__ */ jsx2("label", { className: "di-annotation-row di-annotation-row--text", children: /* @__PURE__ */ jsx2(
|
|
8876
|
+
"textarea",
|
|
8877
|
+
{
|
|
8878
|
+
className: "di-annotation-textarea",
|
|
8879
|
+
value: annotationText,
|
|
8880
|
+
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",
|
|
8881
|
+
rows: 2,
|
|
8882
|
+
onChange: (event) => {
|
|
8883
|
+
const nextText = event.currentTarget.value;
|
|
8884
|
+
setAnnotationText(nextText);
|
|
8885
|
+
updateAnnotationDraft(nextText);
|
|
8886
|
+
resizeTextareaToContent(event.currentTarget);
|
|
8887
|
+
},
|
|
8888
|
+
ref: (node) => {
|
|
8889
|
+
if (node) resizeTextareaToContent(node);
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8892
|
+
) }) })
|
|
8893
|
+
] }),
|
|
8276
8894
|
/* @__PURE__ */ jsxs("div", { className: "di-section", children: [
|
|
8277
8895
|
/* @__PURE__ */ jsxs("div", { className: "di-section-title", children: [
|
|
8278
8896
|
"\u672C\u6B21\u4FEE\u6539\u5185\u5BB9 ",
|
|
@@ -8422,7 +9040,7 @@ ${pending.map(([p, v]) => ` ${p}: ${v};`).join("\n")}
|
|
|
8422
9040
|
disabled: !hasPending,
|
|
8423
9041
|
style: !hasPending ? { opacity: 0.4, cursor: "not-allowed" } : {},
|
|
8424
9042
|
title: "\u590D\u5236\u4E00\u6BB5\u53EF\u76F4\u63A5\u53D1\u7ED9 AI \u7684\u4EFB\u52A1\u6587\u672C",
|
|
8425
|
-
children: submitMsg
|
|
9043
|
+
children: renderSubmitLabel(submitMsg)
|
|
8426
9044
|
}
|
|
8427
9045
|
)
|
|
8428
9046
|
] });
|
|
@@ -8458,115 +9076,6 @@ ${pending.map(([p, v]) => ` ${p}: ${v};`).join("\n")}
|
|
|
8458
9076
|
)
|
|
8459
9077
|
] });
|
|
8460
9078
|
}
|
|
8461
|
-
var CODE_FILES = [
|
|
8462
|
-
{ name: "src/", desc: "React \u7EC4\u4EF6\u3001\u9875\u9762\u3001\u6837\u5F0F\u6E90\u7801\uFF08\u4E0D\u542B\u8C03\u8BD5\u5DE5\u5177\uFF09" },
|
|
8463
|
-
{ name: "index.html", desc: "\u5E94\u7528\u5165\u53E3 HTML" },
|
|
8464
|
-
{ name: "package.json", desc: "\u4F9D\u8D56\u5305\u4E0E\u811A\u672C\u914D\u7F6E" },
|
|
8465
|
-
{ name: "tsconfig.json", desc: "TypeScript \u7F16\u8BD1\u914D\u7F6E" },
|
|
8466
|
-
{ name: "vite.config.ts", desc: "\u6784\u5EFA\u5DE5\u5177\u914D\u7F6E" }
|
|
8467
|
-
];
|
|
8468
|
-
var PRODUCT_FILES = [
|
|
8469
|
-
{ name: "docs/PRODUCT_PLAN.md", desc: "\u4EA7\u54C1\u89C4\u5212\u4E0E\u8DEF\u7EBF\u56FE" },
|
|
8470
|
-
{ name: "docs/PROJECT.md", desc: "\u9879\u76EE\u80CC\u666F\u4E0E\u76EE\u6807\u6982\u8FF0" },
|
|
8471
|
-
{ name: "docs/DECISIONS.md", desc: "\u5173\u952E\u4EA7\u54C1\u51B3\u7B56\u8BB0\u5F55" },
|
|
8472
|
-
{ name: "docs/CHANGELOG.md", desc: "\u529F\u80FD\u8FED\u4EE3\u53D8\u66F4\u65E5\u5FD7" },
|
|
8473
|
-
{ name: "docs/CODE_STRUCTURE.md", desc: "\u524D\u7AEF\u76EE\u5F55\u7ED3\u6784\u8BF4\u660E" },
|
|
8474
|
-
{ name: "docs/DESIGN_STANDARDS.md", desc: "\u8BBE\u8BA1\u89C4\u8303\u603B\u89C8" }
|
|
8475
|
-
];
|
|
8476
|
-
var DESIGN_FILES = [
|
|
8477
|
-
{ name: "docs/design/OVERVIEW.md", desc: "\u8BBE\u8BA1\u7CFB\u7EDF\u603B\u89C8" },
|
|
8478
|
-
{ name: "docs/design/tokens.md", desc: "Design Token \u4F7F\u7528\u8BF4\u660E" },
|
|
8479
|
-
{ name: "docs/design/layout.md", desc: "\u9875\u9762\u5E03\u5C40\u89C4\u8303" },
|
|
8480
|
-
{ name: "docs/design/component-index.md", desc: "\u7EC4\u4EF6\u6E05\u5355\u7D22\u5F15" },
|
|
8481
|
-
{ name: "docs/design/business-components.md", desc: "\u4E1A\u52A1\u7EC4\u4EF6\u8BF4\u660E" }
|
|
8482
|
-
];
|
|
8483
|
-
function FileList({ files }) {
|
|
8484
|
-
return /* @__PURE__ */ jsx2("ul", { className: "di-dl-file-list", children: files.map((f) => /* @__PURE__ */ jsxs("li", { children: [
|
|
8485
|
-
/* @__PURE__ */ jsx2("span", { className: "di-dl-file-name", children: f.name }),
|
|
8486
|
-
/* @__PURE__ */ jsx2("span", { className: "di-dl-file-desc", children: f.desc })
|
|
8487
|
-
] }, f.name)) });
|
|
8488
|
-
}
|
|
8489
|
-
function DownloadButton() {
|
|
8490
|
-
const { endpoints } = useDevInspectorConfig();
|
|
8491
|
-
const [open, setOpen] = useState(false);
|
|
8492
|
-
const [status, setStatus] = useState("idle");
|
|
8493
|
-
const [filePath, setFilePath] = useState("");
|
|
8494
|
-
const [details, setDetails] = useState({ code: false, product: false, design: false });
|
|
8495
|
-
const [opts, setOpts] = useState({ code: true, product: false, design: false });
|
|
8496
|
-
function toggle(k) {
|
|
8497
|
-
setOpts((prev) => ({ ...prev, [k]: !prev[k] }));
|
|
8498
|
-
}
|
|
8499
|
-
function toggleDetail(k) {
|
|
8500
|
-
setDetails((prev) => ({ ...prev, [k]: !prev[k] }));
|
|
8501
|
-
}
|
|
8502
|
-
function handleOpen() {
|
|
8503
|
-
setOpen((v) => !v);
|
|
8504
|
-
if (open) setStatus("idle");
|
|
8505
|
-
}
|
|
8506
|
-
async function download() {
|
|
8507
|
-
if (!opts.code && !opts.product && !opts.design) return;
|
|
8508
|
-
setStatus("packing");
|
|
8509
|
-
try {
|
|
8510
|
-
const params = new URLSearchParams({
|
|
8511
|
-
code: opts.code ? "1" : "0",
|
|
8512
|
-
product: opts.product ? "1" : "0",
|
|
8513
|
-
design: opts.design ? "1" : "0"
|
|
8514
|
-
});
|
|
8515
|
-
const res = await fetch(`${endpoints.handoff}?${params}`);
|
|
8516
|
-
const json = await res.json();
|
|
8517
|
-
if (!json.ok) throw new Error(json.error);
|
|
8518
|
-
setFilePath(json.path);
|
|
8519
|
-
setStatus("done");
|
|
8520
|
-
} catch {
|
|
8521
|
-
setStatus("error");
|
|
8522
|
-
}
|
|
8523
|
-
}
|
|
8524
|
-
async function revealInFinder() {
|
|
8525
|
-
await fetch(`${endpoints.reveal}?path=${encodeURIComponent(filePath)}`);
|
|
8526
|
-
}
|
|
8527
|
-
const sections = [
|
|
8528
|
-
{ key: "code", label: "\u524D\u7AEF\u4EE3\u7801", files: CODE_FILES },
|
|
8529
|
-
{ key: "product", label: "\u4EA7\u54C1\u6587\u6863", files: PRODUCT_FILES },
|
|
8530
|
-
{ key: "design", label: "\u8BBE\u8BA1\u6587\u6863", files: DESIGN_FILES }
|
|
8531
|
-
];
|
|
8532
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8533
|
-
/* @__PURE__ */ jsx2("button", { className: "di-dl-btn", onClick: handleOpen, children: "\u4E0B\u8F7D" }),
|
|
8534
|
-
open && /* @__PURE__ */ jsxs("div", { className: "di-dl-modal", children: [
|
|
8535
|
-
/* @__PURE__ */ jsx2("div", { className: "di-dl-title", children: "\u9009\u62E9\u4E0B\u8F7D\u5185\u5BB9" }),
|
|
8536
|
-
status === "packing" && /* @__PURE__ */ jsxs("div", { className: "di-dl-status", children: [
|
|
8537
|
-
/* @__PURE__ */ jsx2("span", { className: "di-dl-spinner" }),
|
|
8538
|
-
"\u6B63\u5728\u6253\u5305\uFF0C\u8BF7\u7A0D\u5019\u2026"
|
|
8539
|
-
] }),
|
|
8540
|
-
status === "done" && /* @__PURE__ */ jsxs("div", { className: "di-dl-done", children: [
|
|
8541
|
-
/* @__PURE__ */ jsx2("div", { className: "di-dl-done-check", children: "\u2713 \u5DF2\u4FDD\u5B58\u81F3\u684C\u9762" }),
|
|
8542
|
-
/* @__PURE__ */ jsx2("div", { className: "di-dl-done-path", children: filePath.replace(/.*\//, "") }),
|
|
8543
|
-
/* @__PURE__ */ jsx2("button", { className: "di-dl-reveal-btn", onClick: revealInFinder, children: "\u5728 Finder \u4E2D\u663E\u793A" })
|
|
8544
|
-
] }),
|
|
8545
|
-
status === "error" && /* @__PURE__ */ jsx2("div", { className: "di-dl-status di-dl-status--error", children: "\u6253\u5305\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0" }),
|
|
8546
|
-
(status === "idle" || status === "error") && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8547
|
-
sections.map(({ key, label, files }) => /* @__PURE__ */ jsxs("div", { children: [
|
|
8548
|
-
/* @__PURE__ */ jsxs("div", { className: "di-dl-row", children: [
|
|
8549
|
-
/* @__PURE__ */ jsxs("label", { className: "di-dl-check-label", children: [
|
|
8550
|
-
/* @__PURE__ */ jsx2("input", { type: "checkbox", checked: opts[key], onChange: () => toggle(key) }),
|
|
8551
|
-
label
|
|
8552
|
-
] }),
|
|
8553
|
-
/* @__PURE__ */ jsx2("button", { className: "di-dl-detail-btn", onClick: () => toggleDetail(key), children: details[key] ? "\u6536\u8D77" : "\u8BE6\u60C5" })
|
|
8554
|
-
] }),
|
|
8555
|
-
details[key] && /* @__PURE__ */ jsx2(FileList, { files })
|
|
8556
|
-
] }, key)),
|
|
8557
|
-
/* @__PURE__ */ jsx2(
|
|
8558
|
-
"button",
|
|
8559
|
-
{
|
|
8560
|
-
className: "di-dl-confirm",
|
|
8561
|
-
onClick: download,
|
|
8562
|
-
disabled: !opts.code && !opts.product && !opts.design,
|
|
8563
|
-
children: "\u4E0B\u8F7D"
|
|
8564
|
-
}
|
|
8565
|
-
)
|
|
8566
|
-
] })
|
|
8567
|
-
] })
|
|
8568
|
-
] });
|
|
8569
|
-
}
|
|
8570
9079
|
function DevInspector() {
|
|
8571
9080
|
const [active, setActive] = useState(false);
|
|
8572
9081
|
const [tokenMap, setTokenMap] = useState({});
|
|
@@ -8596,26 +9105,29 @@ function DevInspector() {
|
|
|
8596
9105
|
useEffect(() => {
|
|
8597
9106
|
const onOver = (e) => {
|
|
8598
9107
|
if (!active || modalOpenRef.current) return;
|
|
8599
|
-
const
|
|
8600
|
-
if (!
|
|
8601
|
-
if (isInsidePanel(
|
|
8602
|
-
|
|
9108
|
+
const raw = e.target;
|
|
9109
|
+
if (!raw?.classList) return;
|
|
9110
|
+
if (isInsidePanel(raw)) {
|
|
9111
|
+
raw.classList.remove("di-hover");
|
|
8603
9112
|
return;
|
|
8604
9113
|
}
|
|
8605
|
-
|
|
9114
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
9115
|
+
resolveSelectionTarget(raw).classList.add("di-hover");
|
|
8606
9116
|
};
|
|
8607
|
-
const onOut = (
|
|
8608
|
-
|
|
9117
|
+
const onOut = () => {
|
|
9118
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
8609
9119
|
};
|
|
8610
9120
|
const onClick = (e) => {
|
|
8611
9121
|
if (!active || modalOpenRef.current) return;
|
|
8612
|
-
const
|
|
8613
|
-
if (
|
|
9122
|
+
const raw = e.target;
|
|
9123
|
+
if (!raw?.classList) return;
|
|
9124
|
+
if (isInsidePanel(raw)) return;
|
|
8614
9125
|
e.preventDefault();
|
|
8615
9126
|
e.stopPropagation();
|
|
8616
|
-
|
|
9127
|
+
const target = resolveSelectionTarget(raw);
|
|
9128
|
+
document.querySelectorAll(".di-hover").forEach((item) => item.classList.remove("di-hover"));
|
|
8617
9129
|
setPanels(
|
|
8618
|
-
(prev) => prev.length === 0 ? [{ id: "main", el }] : prev.map((p, i) => i === 0 ? { ...p, el } : p)
|
|
9130
|
+
(prev) => prev.length === 0 ? [{ id: "main", el: target }] : prev.map((p, i) => i === 0 ? { ...p, el: target } : p)
|
|
8619
9131
|
);
|
|
8620
9132
|
};
|
|
8621
9133
|
document.addEventListener("mouseover", onOver, true);
|
|
@@ -8656,7 +9168,6 @@ function DevInspector() {
|
|
|
8656
9168
|
const primaryEl = panels[0]?.el;
|
|
8657
9169
|
const triggerTooltip = active ? `\u9000\u51FA\u7F16\u8F91\uFF08${EXIT_SHORTCUT_LABEL}\uFF09` : `\u8FDB\u5165\u7F16\u8F91\uFF08${EDIT_SHORTCUT_LABEL}\uFF09`;
|
|
8658
9170
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8659
|
-
/* @__PURE__ */ jsx2(DownloadButton, {}),
|
|
8660
9171
|
/* @__PURE__ */ jsx2(
|
|
8661
9172
|
"button",
|
|
8662
9173
|
{
|