diff --git a/docs/prototype/code-reader/openpencil/exports/react-state-login.png b/docs/prototype/code-reader/openpencil/exports/react-state-login.png new file mode 100644 index 0000000..4ee166d Binary files /dev/null and b/docs/prototype/code-reader/openpencil/exports/react-state-login.png differ diff --git a/docs/prototype/code-reader/openpencil/exports/react-state-variants.png b/docs/prototype/code-reader/openpencil/exports/react-state-variants.png new file mode 100644 index 0000000..93a92d0 Binary files /dev/null and b/docs/prototype/code-reader/openpencil/exports/react-state-variants.png differ diff --git a/docs/prototype/code-reader/openpencil/react-hooks.js b/docs/prototype/code-reader/openpencil/react-hooks.js index f589060..e10cece 100644 --- a/docs/prototype/code-reader/openpencil/react-hooks.js +++ b/docs/prototype/code-reader/openpencil/react-hooks.js @@ -4,77 +4,10 @@ // 左边的钩子图标、描边所有钩子一样,淡底按来源分,React 自带的钩子左边再并排一个作用图标; // 卡片不分析钩子里写了什么,返回值里有函数的,右上角的调用树按钮查它在哪调用。 // 样例源码 `src/chat/Panel.tsx` 是手写的,两张画板共用:一张画第 1–21 行,一张画第 23–60 行;钩子来自 React、第三方库、项目自己各有一处。 -// 颜色、窗口和卡片画法取自同目录 react.js(VS Code Dark Modern,卡片淡底 7%、描边 35%),函数小框取自同目录 rust-chain.js; -// 卡片里的译文照 vscode/src/codeReader/translators/typescriptZh.ts 的中文直译,渲染大纲的说法照 vscode/src/codeReader/rules/react.ts。 -// OpenPencil 自动折行量不准,长文字按估出的宽度手动断行,文字框都按内容长。 - -const C = { - editor: "#1f1f1f", - side: "#181818", - border: "#2b2b2b", - borderStrong: "#3c3c3c", - fg: "#cccccc", - fgStrong: "#e8e8e8", - desc: "#9d9d9d", - dim: "#6e7681", - activityIdle: "#868686", - activityOn: "#d7d7d7", - focus: "#0078d4", - selection: "#04395e", - input: "#313131", - inputBorder: "#454545", - field: "#111111", - toggleOn: "#37373d", - guide: "#404040", - punct: "#d4d4d4", - keyword: "#c586c0", - storage: "#569cd6", - variable: "#9cdcfe", - fn: "#dcdcaa", - type: "#4ec9b0", - string: "#ce9178", - number: "#b5cea8", - constant: "#4fc1ff", - nativeTag: "#808080", - component: "#61dafb", - branch: "#ce9178", - ret: "#89d185", - loop: "#8f9cff", - folder: "#8b9ba8", - tsx: "#519aba", -}; - -// 编辑器的括号配对着色(Dark Modern 的 editorBracketHighlight.foreground1–3),按嵌套层数轮换 -const BRACKETS = ["#ffd700", "#da70d6", "#179fff"]; - -// 定义处的卡片种类:上下文是这次新加的,别的同 react.js;函数同 build.js。钩子的定义和调用都用 HOOK 的样式 -const K = { - import: { label: "导入", color: "#c586c0", icon: "import" }, - fn: { label: "函数", color: "#dcdcaa", icon: "square-function" }, - context: { label: "上下文", color: "#4ec9b0", icon: "share-2" }, - component: { label: "React 组件", color: "#61dafb", icon: "atom" }, - handler: { label: "事件处理函数", color: "#dcdcaa", icon: "mouse-pointer-click" }, - render: { label: "渲染输出", color: "#89d185", icon: "layout-template" }, -}; - -const MONO = "Menlo"; -const UI = "PingFang SC"; - -// 窗口:活动栏 48、侧栏、编辑器(左边源码、1px 分隔、右边预览) -const WIN_W = 1700; -const SIDE_W = 250; -const CODE_W = 600; -const PREVIEW_W = WIN_W - 48 - SIDE_W - CODE_W - 1; -const PREVIEW_PAD = 20; -const BOARD_GAP = 80; -// Menlo 13px 一个字符宽,源码缩进按它算 -const MONO_CHAR = 7.83; +// 画法在同目录 react-shared.js,接在它后面跑:`cat react-shared.js react-hooks.js | op design - --script`。 // ─── 样例源码 ──────────────────────────────────────────────────────────────── -const FILE = "Panel.tsx"; -const CRUMBS = ["src", "chat", FILE]; - const SOURCE = [ "import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition } from 'react'", "import { useRouter } from 'next/navigation'", @@ -148,646 +81,17 @@ const TREE = [ { kind: "file", name: "App.tsx", depth: 1 }, ]; -// ─── 颜色、宽度 ────────────────────────────────────────────────────────────── - -function solid(color) { - return [{ type: "solid", color }]; -} - -function rgb(hex) { - const h = hex.replace("#", ""); - return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16)); -} - -/** `color` 按 `t` 盖在 `base` 上(`color-mix(in srgb, color t, base)`)。 */ -function mix(color, base, t) { - const a = rgb(color); - const b = rgb(base); - return "#" + a.map((v, i) => Math.round(v * t + b[i] * (1 - t)).toString(16).padStart(2, "0")).join(""); -} - -const WIDE = /[⺀-鿿 -〿＀-￯“”‘’…—·×→]/; - -function charWidth(ch, size, mono) { - if (WIDE.test(ch)) - return size; - if (mono) - return size * 0.61; - if (/[A-Z0-9]/.test(ch)) - return size * 0.68; - if (/[ilj.,:;'|!()[\] ]/.test(ch)) - return size * 0.34; - return size * 0.58; -} - -/** 估一段字的宽度,宁大勿小:估小了字会伸出框外。 */ -function widthOf(s, size, mono) { - let w = 0; - for (const ch of s) w += charWidth(ch, size, mono); - return w * 1.04; -} - -// ─── 译文着色 ──────────────────────────────────────────────────────────────── - -// 「当 … 时」「对 … 的每一项」是渲染大纲的关键字(react.ts 的 when、eachItem) -const ZH_KEYWORD = new Set(["如果", "否则", "返回", "当", "时", "对", "的每一项", "则", "新建", "调用", "常量", "变量", "函数"]); -const ZH_OPERATOR = new Set(["全等", "不全等", "等于", "不等于", "并且", "或者", "不成立"]); -const ZH_LITERAL = new Set(["空", "真", "假", "未定义", "空数组", "空对象"]); -const ZH_TYPE = new Set(["字符串", "数值", "布尔", "任意", "未知", "永不", "无", "对象"]); -const TOKEN = /"(?:[^"\\]|\\.)*"|`[^`]*`|'[^']*'|[A-Za-z_$][\w$]*|\d+(?:\.\d+)?|[一-鿿]+|\s+|[\s\S]/g; - -function seg(text, fill, extra) { - return Object.assign({ text, fill }, extra || {}); -} - -function merge(list) { - const out = []; - for (const s of list) { - const last = out[out.length - 1]; - if (last && last.fill === s.fill && !last.u && !s.u && last.w === s.w) - last.text += s.text; - else - out.push(Object.assign({}, s)); - } - return out; -} - -function identColor(tok, rest) { - if (/^\s*(\?\.)?(<[^()]*>)?\(/.test(rest)) - return C.fn; - if (/^[A-Z][A-Z0-9_]+$/.test(tok)) - return C.constant; - if (/^[A-Z]/.test(tok)) - return C.type; - return C.variable; -} - -/** 一段中文直译:照抄的名字按词性着色,翻出来的关键字、运算符、字面量、内置类型各用各的颜色。 */ -function cx(src) { - const out = []; - let at = 0; - for (const tok of src.match(TOKEN) || []) { - at += tok.length; - let color = C.fg; - if (/^["'`]/.test(tok)) - color = C.string; - else if (/^\d/.test(tok)) - color = C.number; - else if (/^[一-鿿]/.test(tok)) - color = ZH_KEYWORD.has(tok) ? C.keyword : ZH_OPERATOR.has(tok) ? C.storage : ZH_LITERAL.has(tok) ? C.number : ZH_TYPE.has(tok) ? C.type : C.desc; - else if (/^[A-Za-z_$]/.test(tok)) - color = identColor(tok, src.slice(at)); - out.push(seg(tok, color)); - } - return merge(out); -} - -/** 一段同色的字。 */ -function px(text, color) { - return [seg(text, color || C.fg)]; -} - -/** 能点过去的名字(跳到那张卡片):带下划线。 */ -function link(text, color) { - return seg(text, color, { u: true }); -} - -// ─── 源码着色 ──────────────────────────────────────────────────────────────── - -const TSX_TOKEN = /'[^']*'|"[^"]*"|=>|\.\.\.|\?\.|&&|<\/|\/>|[A-Za-z_$][\w$]*|\d+(?:\.\d+)?|\s+|[\s\S]/g; -const TSX_STORAGE = new Set(["const", "let", "var", "function", "new", "typeof", "true", "false", "null", "undefined", "this"]); -const TSX_CONTROL = new Set(["import", "export", "from", "return", "if", "else", "switch", "case", "default", "await"]); -const TSX_PRIMITIVE = new Set(["string", "number", "boolean", "void", "any", "unknown"]); - -/** - * 整份源码按 VS Code Dark Modern 着色,返回每行的着色段(不含行首缩进)。 - * 括号按整份文件的嵌套层数配色;标识符后面紧跟的 `<` 是泛型,别处的 `<名字` 是 JSX 标签,标签里的名字是属性。 - */ -function highlight(lines) { - let depth = 0; - let generic = 0; - let tag = null; - return lines.map((line) => { - const src = line.replace(/^ +/, ""); - const out = []; - let at = 0; - let prev = ""; - let prevSolid = ""; - for (const tok of src.match(TSX_TOKEN) || []) { - at += tok.length; - const rest = src.slice(at); - let color = C.punct; - if (/^\s+$/.test(tok)) { - out.push(seg(tok, C.punct)); - prev = tok; - continue; - } - if (/^['"]/.test(tok)) - color = C.string; - else if (/^\d/.test(tok)) - color = C.number; - else if (tok === "=>") - color = C.storage; - else if ("([{".includes(tok)) { - color = BRACKETS[depth % 3]; - depth++; - if (tag && tok === "{") - tag.braces++; - } - else if (")]}".includes(tok)) { - depth = Math.max(0, depth - 1); - color = BRACKETS[depth % 3]; - if (tag && tok === "}") - tag.braces--; - } - else if (tok === "<") { - if (/^[A-Za-z_$][\w$]*$/.test(prev)) - generic++; - else if (/^[A-Za-z]/.test(rest)) { - color = C.nativeTag; - tag = { name: true, braces: 0 }; - } - } - else if (tok === "" && tag && tag.braces === 0) { - color = C.nativeTag; - tag = null; - } - else if (tok === ">") { - if (generic > 0) - generic--; - else if (tag && tag.braces === 0) { - color = C.nativeTag; - tag = null; - } - } - else if (/^[A-Za-z_$]/.test(tok)) { - if (tag && tag.braces === 0) { - color = tag.name ? (/^[A-Z]/.test(tok) ? C.type : C.storage) : C.variable; - tag.name = false; - } - else if (prevSolid === "." || prevSolid === "?.") - color = /^\s*\(/.test(rest) ? C.fn : C.variable; - else if (TSX_STORAGE.has(tok)) - color = C.storage; - else if (TSX_CONTROL.has(tok)) - color = C.keyword; - else if (TSX_PRIMITIVE.has(tok)) - color = C.type; - else - color = identColor(tok, rest); - } - out.push(seg(tok, color)); - prev = tok; - prevSolid = tok; - } - return { indent: line.length - src.length, segs: merge(out) }; - }); -} - -const CODE = highlight(SOURCE); - -// ─── 断行 ──────────────────────────────────────────────────────────────────── - -const CLOSING = /^[))\]】,,.。、;;::!!??」』”]/; -const OPENING = /[(([【「『“]$/; -const WIDE_CHAR = /^[⺀-鿿 -〿＀-￯“”]$/; -const TOKENS = /\n|[^\S\n]+|[⺀-鿿 -〿＀-￯“”]|[^\s⺀-鿿 -〿＀-￯“”]+/g; - -/** - * 按估出的宽度把一串着色的字断成几行(行间用 `\n` 接起来,交给一个文字框)。 - * 代码只在空格处断;正文在空格处和汉字之间断,收尾标点跟着前一个字、开头标点跟着后一个字;能点的名字整段不断。 - */ -function wrap(segs, maxW, size, mono) { - const units = []; - let cur = null; - const open = () => { - cur = { parts: [], trail: [] }; - units.push(cur); - }; - const add = (list, text, style) => { - const last = list[list.length - 1]; - if (last && last.style === style) - last.text += text; - else - list.push({ text, style }); - }; - const lastText = () => { - const last = cur && cur.parts[cur.parts.length - 1]; - return last ? last.text : ""; - }; - for (const style of segs) { - const tokens = style.u ? [style.text] : style.text.match(TOKENS) || []; - for (const tok of tokens) { - if (tok === "\n") { - units.push({ br: true }); - cur = null; - continue; - } - if (/^\s+$/.test(tok)) { - if (cur) - add(cur.trail, tok, style); - continue; - } - const wide = !mono && WIDE_CHAR.test(tok); - const joins = cur && cur.trail.length === 0 && (CLOSING.test(tok) || OPENING.test(lastText()) || !(wide || cur.wide)); - if (!joins) - open(); - add(cur.parts, tok, style); - cur.wide = wide; - } - } - const measure = (list) => list.reduce((sum, p) => sum + widthOf(p.text, size, mono), 0); - const lines = [[]]; - let w = 0; - const emit = (text, style) => add(lines[lines.length - 1], text, style); - const newLine = () => { - const line = lines[lines.length - 1]; - const tail = line[line.length - 1]; - if (tail) - tail.text = tail.text.replace(/\s+$/, ""); - lines.push([]); - w = 0; - }; - for (const unit of units) { - if (unit.br) { - newLine(); - continue; - } - const uw = measure(unit.parts); - if (w > 0 && w + uw > maxW) - newLine(); - for (const part of unit.parts) emit(part.text, part.style); - w += uw; - for (const part of unit.trail) emit(part.text, part.style); - w += measure(unit.trail); - } - return lines.map((line) => { - const tail = line[line.length - 1]; - if (tail) - tail.text = tail.text.replace(/\s+$/, ""); - return line - .filter((p) => p.text) - .map((p) => Object.assign({}, p.style, { text: p.text })); - }); -} - -function joinLines(lines) { - const out = []; - lines.forEach((line, i) => { - if (i > 0) - out.push(seg("\n", C.fg)); - for (const s of line) out.push(s); - }); - return merge(out); -} - -// ─── 节点 ──────────────────────────────────────────────────────────────────── - -/** - * 文字:`content` 是字符串或着色的段;给了 `maxW` 就按它断行。宽、高都跟着字长,不靠 OpenPencil 折行。 - * 给了 `fixedW` 时宽度定死:几个字符的多色文字按内容长会被导出时挤小。 - * o: size、color、weight、mono、lh(行高 px)、maxW、fixedW、name - */ -function text(parent, content, o) { - const opt = o || {}; - const size = opt.size || 13; - const mono = Boolean(opt.mono); - let segs = typeof content === "string" ? px(content, opt.color || C.fg) : content; - if (opt.maxW) - segs = joinLines(wrap(segs, opt.maxW, size, mono)); - if (!segs.some((s) => s.text.trim())) - return null; - const plain = segs.length === 1 && !segs[0].u && !segs[0].w; - const node = { - type: "text", - name: opt.name || segs.map((s) => s.text).join("").replace(/\n/g, " ").slice(0, 40), - fontFamily: mono ? MONO : UI, - fontSize: size, - fontWeight: opt.weight || 400, - lineHeight: (opt.lh || 20) / size, - width: "fit_content", - height: "fit_content", - textGrowth: "auto", - }; - if (opt.fixedW) { - node.width = opt.fixedW; - node.textGrowth = "fixed-width"; - } - if (plain) { - node.content = segs[0].text; - node.fill = solid(segs[0].fill); - } - else { - node.content = segs.map((s) => { - const piece = { text: s.text, fill: s.fill }; - if (s.u) - piece.underline = true; - if (s.w) - piece.fontWeight = s.w; - return piece; - }); - node.fill = solid(C.fg); - } - return I(parent, node); -} - -function icon(parent, name, color, size) { - return I(parent, { type: "icon_font", name, iconFontName: name, width: size, height: size, fill: solid(color) }); -} - -function box(parent, name, o) { - const opt = o || {}; - const node = { - type: "frame", - name, - layout: opt.layout || "horizontal", - width: opt.width || "fill_container", - height: opt.height || "fit_content", - gap: opt.gap == null ? 0 : opt.gap, - clipContent: Boolean(opt.clip), - }; - if (opt.x != null) { - node.x = opt.x; - node.y = opt.y || 0; - } - if (opt.padding != null) - node.padding = opt.padding; - if (opt.align) - node.alignItems = opt.align; - if (opt.justify) - node.justifyContent = opt.justify; - if (opt.fill) - node.fill = solid(opt.fill); - if (opt.radius != null) - node.cornerRadius = opt.radius; - if (opt.stroke) - node.stroke = { thickness: 1, fill: solid(opt.stroke) }; - return I(parent, node); -} - -function row(parent, name, o) { - return box(parent, name, Object.assign({ layout: "horizontal", align: "center" }, o || {})); -} - -function col(parent, name, o) { - return box(parent, name, Object.assign({ layout: "vertical" }, o || {})); -} - -function spacer(parent, name, width, height) { - return I(parent, { type: "frame", name, width, height }); -} - -/** 小标签(具名导出、useReducer、元素……):给定颜色的淡底、描边。 */ -function tag(parent, label, color, bg) { - const pill = row(parent, "Tag / " + label, { - width: "fit_content", - height: 18, - padding: [0, 5], - radius: 4, - fill: mix(color, bg, 0.14), - stroke: mix(color, bg, 0.45), - }); - text(pill, label, { size: 11, color, lh: 16, weight: 500 }); - return pill; -} - -function tagWidth(label) { - return widthOf(label, 11, false) + 12; -} - -/** 渲染大纲里的小框:条件「当 … 时」、列表「对 … 的每一项」。 */ -function group(parent, segs, color, bg) { - const pill = row(parent, "Group", { - width: "fit_content", - height: 20, - padding: [0, 5], - radius: 4, - fill: mix(color, bg, 0.14), - stroke: mix(color, bg, 0.45), - }); - text(pill, segs, { size: 12.5, mono: true, lh: 18 }); - return pill; -} - -// ─── 卡片 ──────────────────────────────────────────────────────────────────── - -/** - * 卡片右上角:问 AI、编辑;给了 `calls` 再加调用树,同 webview 的 BlockTools:图标后面跟调用次数的小圆标 - * (徽标底色、字色取 Dark Modern 的 badge)。返回这一排的宽度。 - */ -function tools(parent, calls) { - const bar = row(parent, "Tools", { width: "fit_content", height: 20, gap: 2 }); - for (const name of ["sparkles", "pencil"]) { - const button = row(bar, name, { width: 22, height: 20, justify: "center", radius: 4 }); - icon(button, name, C.desc, 14); - } - if (!calls) - return 22 * 2 + 2; - const tree = row(bar, "git-branch", { width: "fit_content", height: 20, padding: [0, 4], gap: 1, radius: 4 }); - icon(tree, "git-branch", C.desc, 14); - const badge = row(tree, "Count", { width: 14, height: 14, justify: "center", radius: 7, fill: "#616161" }); - text(badge, String(calls), { size: 9, weight: 700, color: "#f8f8f8", lh: 14 }); - return 22 * 2 + 2 + 2 + (4 + 14 + 1 + 14 + 4); -} - -/** - * 卡片左边的一个概念图标:20px 见方,图标 16px。`bubble` 时画出它悬停的提示气泡,样子同 webview 的 data-tooltip - * (悬停浮层的底色、边框、11px 字)。气泡画在图标下方隔 6px,右边和图标右边对齐,不伸出这一格,图标那一列才不被撑宽: - * OpenPencil 里前面的兄弟节点画在上层,往上伸的气泡会被上一张卡片盖住。 - */ -function conceptIcon(parent, item) { - if (!item.bubble) { - const cell = row(parent, "Concept / " + item.tip, { width: 20, height: 20, justify: "center" }); - icon(cell, item.name, item.color, 16); - return; - } - const cell = box(parent, "Concept / " + item.tip, { layout: "none", width: 20, height: 20 }); - I(cell, { type: "icon_font", name: item.name, iconFontName: item.name, x: 2, y: 2, width: 16, height: 16, fill: solid(item.color) }); - const bw = Math.ceil(widthOf(item.tip, 11, false)) + 16; - const tip = I(cell, { - type: "frame", - name: "Tooltip", - x: Math.min(Math.round(10 - bw / 2), 20 - bw), - y: 20 + 6, - width: bw, - height: 22, - layout: "horizontal", - alignItems: "center", - justifyContent: "center", - cornerRadius: 4, - fill: solid("#202020"), - stroke: { thickness: 1, fill: solid("#454545") }, - effects: [{ type: "shadow", offsetX: 0, offsetY: 2, blur: 8, spread: 0, color: "rgba(0,0,0,0.36)" }], - }); - text(tip, item.tip, { size: 11, color: C.fg, lh: 14 }); -} - -/** - * 一张卡片:折叠箭头(有子块才有:`open` 展开、`closed` 收起)、概念图标、内容、右上角两个按钮。 - * 概念图标默认是种类图标一个,给了 `icons` 就并排画这几个(`{name, color, tip, bubble?}`)。 - * 淡底默认用种类色,给了 `tint` 用它(钩子卡片按来源分底色)。给了 `calls` 右上角多一个调用树按钮。 - * `w` 是卡片外宽;返回内容区和内容区的宽度,属性行、表格按它断行。 - */ -function card(parent, kind, w, o) { - const opt = o || {}; - const bg = mix(opt.tint || kind.color, C.editor, 0.07); - const node = box(parent, kind.label + (opt.name ? " / " + opt.name : ""), { - layout: "horizontal", - gap: 10, - padding: [8, 10, 8, 8], - radius: 8, - align: "start", - fill: bg, - stroke: mix(kind.color, C.editor, 0.35), - }); - const fold = row(node, "Fold", { width: 14, height: 20, justify: "center" }); - if (opt.fold) - icon(fold, opt.fold === "open" ? "chevron-down" : "chevron-right", C.desc, 14); - const icons = opt.icons || [{ name: kind.icon, color: kind.color, tip: kind.label }]; - const concepts = row(node, "Concepts", { width: "fit_content", height: 20, gap: 2 }); - for (const item of icons) conceptIcon(concepts, item); - const content = col(node, "Content", { gap: 3 }); - const toolsW = tools(node, opt.calls); - const iconsW = icons.length * 20 + (icons.length - 1) * 2; - return { node, content, w: w - 18 - 14 - iconsW - toolsW - 30, bg, labelW: opt.labelW || 76 }; -} - -/** 属性表的一行:左边说明色的标签,右边值。`value` 是着色的段、字符串,或自己画的函数 `(frame, width)`。 */ -function prop(ctx, label, value, o) { - const opt = o || {}; - const line = row(ctx.content, "Prop / " + label, { gap: 12, align: "start" }); - const key = row(line, "Key", { width: ctx.labelW, height: 20, gap: 4 }); - if (opt.fold) - icon(key, opt.fold === "open" ? "chevron-down" : "chevron-right", C.desc, 14); - text(key, label, { size: 12.5, color: C.desc, lh: 20 }); - const valueW = ctx.w - ctx.labelW - 12; - if (typeof value === "function") { - const frame = col(line, "Value", { gap: 2 }); - value(frame, valueW); - return line; - } - const segs = typeof value === "string" ? px(value, opt.color || C.fg) : value; - text(line, segs, { size: opt.size || 13, mono: opt.mono !== false, maxW: valueW, weight: opt.weight }); - return line; -} - -/** 名称一行:名字加粗,后面跟小标签 `[文字, 颜色]`。 */ -function nameProp(ctx, name, color, tags, label) { - const line = row(ctx.content, "Prop / " + (label || "名称"), { gap: 12, align: "start" }); - const key = row(line, "Key", { width: ctx.labelW, height: 20 }); - text(key, label || "名称", { size: 12.5, color: C.desc, lh: 20 }); - const value = row(line, "Value", { gap: 6, height: 20 }); - text(value, name, { mono: true, weight: 600, color }); - for (const [tagLabel, tagColor] of tags || []) tag(value, tagLabel, tagColor, ctx.bg); - return line; -} - -/** - * 表格:`cols` 是 `{name, color?, mono?}`,最后一列分剩下的;格子是着色的段、字符串(按列色)或带 `draw` 的对象。 - * 列宽按整列的内容估,表头浅底,行和列之间一条分隔线。 - */ -function table(ctx, cols, rows) { - const tableW = ctx.w - 5; - const cellText = (cell) => typeof cell === "string" ? cell : Array.isArray(cell) ? cell.map((s) => s.text).join("") : (cell.est || ""); - const natural = cols.map((c, i) => { - let wMax = widthOf(c.name, 12, false); - for (const r of rows) wMax = Math.max(wMax, widthOf(cellText(r[i]), 12.5, c.mono !== false) + (r[i] && r[i].extra ? r[i].extra : 0)); - return Math.ceil(wMax + 18); - }); - const last = cols.length - 1; - const avail = tableW - 2 - last; - const widths = natural.slice(); - widths[last] = avail - widths.slice(0, last).reduce((a, b) => a + b, 0); - const outer = col(ctx.content, "Table wrap", { padding: [2, 0, 2, 5] }); - const grid = col(outer, "Table", { radius: 4, stroke: C.borderStrong, clip: true }); - const headBg = mix("#ffffff", ctx.bg, 0.05); - const drawRow = (cells, header) => { - if (!header) - I(grid, { type: "rectangle", name: "Divider", width: "fill_container", height: 1, fill: solid(C.borderStrong) }); - const line = row(grid, header ? "Header" : "Row", { align: "start", fill: header ? headBg : null }); - cells.forEach((cell, i) => { - if (i > 0) - I(line, { type: "rectangle", name: "Sep", width: 1, height: "fill_container", fill: solid(C.borderStrong) }); - const inner = widths[i] - 16; - const frame = col(line, cols[i].name, { width: widths[i], padding: [2, 8], gap: 3 }); - if (header) { - text(frame, cell, { size: 12, color: C.desc, lh: 20 }); - return; - } - if (cell && cell.draw) { - cell.draw(frame, inner); - return; - } - const segs = typeof cell === "string" ? px(cell, cols[i].color || C.fg) : cell; - text(frame, segs, { size: 12.5, mono: cols[i].mono !== false, maxW: inner, lh: 20 }); - }); - }; - drawRow(cols.map((c) => c.name), true); - for (const r of rows) drawRow(r, false); -} - -// ─── 渲染大纲 ──────────────────────────────────────────────────────────────── - -/** 大纲一行里的几样东西:元素名、属性、文字、条件小框。 */ -const el = (name) => ({ kind: "el", name }); -const at = (name, value) => ({ kind: "attr", name, value }); -const words = (segs) => ({ kind: "words", segs }); -const cond = (segs, color) => ({ kind: "group", segs, color: color || C.branch }); - -function drawPiece(parent, p, bg) { - if (p.kind === "el") - return text(parent, [seg(`<${p.name}>`, /^[A-Z]/.test(p.name) ? C.component : C.nativeTag)], { mono: true }); - if (p.kind === "attr") { - const segs = [seg(p.name, C.variable), seg("=", C.fg)].concat(p.value); - const plain = segs.map((s) => s.text).join(""); - return text(parent, segs, { mono: true, fixedW: plain.length < 6 ? Math.ceil(widthOf(plain, 13, true)) + 2 : null }); - } - if (p.kind === "words") - return text(parent, p.segs, { mono: true }); - return group(parent, p.segs, p.color, bg); -} - -/** 大纲:一行一个元素,下一层缩进、左边一条竖线;带下一层的行前面有折叠箭头。 */ -function outline(parent, items, bg) { - const list = col(parent, "Outline", { gap: 2 }); - for (const item of items) { - const line = row(list, "Item", { gap: 4, align: "start" }); - const fold = row(line, "Fold", { width: 14, height: 20, justify: "center" }); - if (item.kids) - icon(fold, "chevron-down", C.desc, 14); - const holder = row(line, "Line", { gap: 8, height: 20 }); - for (const p of item.line) drawPiece(holder, p, bg); - if (item.kids) { - const sub = row(list, "Sub", { gap: 10, align: "start", padding: [0, 0, 0, 5] }); - I(sub, { type: "rectangle", name: "Guide", width: 1, height: "fill_container", fill: solid(C.guide) }); - const inner = col(sub, "Kids", { gap: 2 }); - outline(inner, item.kids, bg); - } - } - return list; -} +const PANEL = sampleFile({ + project: "web", + file: "Panel.tsx", + crumbs: ["src", "chat", "Panel.tsx"], + tree: TREE, + count: 6, + source: SOURCE, +}); // ─── 卡片内容:第 1–21 行 ──────────────────────────────────────────────────── -const EXPORTED = ["具名导出", C.keyword]; - -/** 导入收起时只剩一行:来源和导入项个数。 */ -function importCard(from, count) { - return (parent, w) => { - const ctx = card(parent, K.import, w, { name: from, fold: "closed" }); - const line = row(ctx.content, "Summary", { gap: 6, height: 20 }); - text(line, "来源", { size: 12.5, color: C.desc }); - text(line, from, { mono: true, color: C.string }); - text(line, "·", { color: C.dim }); - text(line, "导入项", { size: 12.5, color: C.desc }); - text(line, count + " 个", { size: 12.5, color: C.desc }); - }; -} - function contextCard(parent, w) { const ctx = card(parent, K.context, w, { name: "ThemeContext" }); nameProp(ctx, "ThemeContext", K.context.color); @@ -818,87 +122,6 @@ function hookCard(parent, w) { table(ctx, [{ name: "名称", color: C.variable }, { name: "是什么", mono: false }], [["messages", [link("状态 messages", HOOK.color)]]]); } -// ─── 钩子调用:一种卡片 ────────────────────────────────────────────────────── - -// 所有钩子卡片左边第一个图标、描边都一样;淡底按钩子从哪来分:React 自带、第三方库、项目里自己写的 -const HOOK = { label: "钩子", color: "#b180d7", icon: "fishing-hook" }; -const ORIGIN = { react: "#61dafb", library: "#e5c07b", own: "#89d185" }; - -// React 自带钩子的作用,同 React 类型定义里钩子的分组:卡片左边第二个图标,悬停显示名字。 -// 颜色借 Dark Modern 的语法色,和钩子紫分得开:状态同变量、引用同常量、性能同数字、上下文同类型、并发同字符串 -const ROLE = { - state: { label: "状态", icon: "toggle-right", color: "#9cdcfe" }, - effect: { label: "副作用", icon: "zap", color: "#e5c07b" }, - ref: { label: "引用", icon: "anchor", color: "#4fc1ff" }, - perf: { label: "性能", icon: "sigma", color: "#b5cea8" }, - context: { label: "上下文", icon: "share-2", color: "#4ec9b0" }, - concurrent: { label: "并发", icon: "hourglass", color: "#ce9178" }, -}; - -// 所有钩子卡片同一个标签列宽,和最长的标签「类型参数」对齐 -const HOOK_LABEL_W = 76; - -/** 依赖项的三种读法:某个值变化时、空数组的仅挂载时、没写依赖的每次渲染后。 */ -const changed = (name) => [seg(name, C.variable), seg(" 变化时", C.keyword)]; -const ON_MOUNT = [seg("仅挂载时", C.keyword)]; -const NO_DEPS = [seg("没写,", C.desc), seg("每次渲染后", C.keyword)]; - -/** 函数参数收成的小框:朝右的折叠箭头,写「函数 (参数) · N 句」,没参数时不写括号;同调用链原型的闭包小框。 */ -function fnBox(params, count) { - const segs = [seg("函数", C.desc)] - .concat(params ? [seg(" (", C.fg)].concat(params, [seg(")", C.fg)]) : []) - .concat([seg(" · " + count + " 句", C.desc)]); - return { - est: segs.map((s) => s.text).join(""), - draw: (frame) => { - const pill = row(frame, "Fold box", { - width: "fit_content", - height: 20, - padding: [0, 6, 0, 3], - gap: 3, - radius: 4, - fill: C.input, - stroke: C.borderStrong, - }); - icon(pill, "chevron-right", C.desc, 13); - text(pill, segs, { mono: true, size: 12.5, lh: 18 }); - }, - }; -} - -/** - * 钩子调用的卡片,所有钩子共用一种,只有钩子 / 类型参数 / 参数 / 返回四行,照钩子签名排,没有的行不显示。 - * 左边第一个图标、描边所有钩子一样,淡底按来源取:React 自带的(给 `role`)左边再并排一个作用图标; - * 第三方库的(`lib`)、自己写的(`own`)只有钩子图标,自己写的钩子名能点到定义。 - * `roleTip` 换掉作用图标的悬停文字,`bubble` 画出悬停时的提示气泡。`fold` 表示有函数参数,函数体子块收起。 - * `params` 每项是「参数 | 值」;`returns` 每项是「名称 | 是什么」,给了 `namesOnly` 只列名称。格子同 [table]。 - * 返回值里有函数时给 `calls`:右上角多一个调用树按钮,数字是这个函数在样例里被调用几次。 - */ -function hookCall(parent, w, h) { - const tint = h.own ? ORIGIN.own : h.lib ? ORIGIN.library : ORIGIN.react; - const icons = [{ name: HOOK.icon, color: HOOK.color, tip: HOOK.label }]; - if (h.role) - icons.push({ name: h.role.icon, color: h.role.color, tip: h.roleTip || h.role.label, bubble: h.bubble }); - const ctx = card(parent, HOOK, w, { name: h.name + " · " + h.target, fold: h.fold ? "closed" : null, labelW: HOOK_LABEL_W, tint, icons, calls: h.calls }); - const line = row(ctx.content, "Prop / 钩子", { gap: 12, align: "start" }); - const key = row(line, "Key", { width: ctx.labelW, height: 20 }); - text(key, "钩子", { size: 12.5, color: C.desc, lh: 20 }); - text(line, [seg(h.name, C.fn, h.own ? { w: 600, u: true } : { w: 600 })], { mono: true }); - if (h.typeArg) - prop(ctx, "类型参数", cx(h.typeArg)); - if (h.params) { - prop(ctx, "参数", px(`${h.params.length} 个`, C.desc), { mono: false, fold: "open" }); - table(ctx, [{ name: "参数", color: C.variable }, { name: "值" }], h.params); - } - if (h.returns) { - prop(ctx, "返回", px(`${h.returns.length} 个`, C.desc), { mono: false, fold: "open" }); - if (h.namesOnly) - table(ctx, [{ name: "名称", color: C.variable }], h.returns.map((name) => [name])); - else - table(ctx, [{ name: "名称", color: C.variable }, { name: "是什么", mono: false }], h.returns); - } -} - // ─── 钩子调用:样例里的每一处 ──────────────────────────────────────────────── /** 第 14 行:自定义钩子里的 `useState`,作用图标画出悬停气泡。 */ @@ -1066,39 +289,13 @@ function layoutEffectHook(parent, w) { // ─── 卡片内容:第 23–60 行 ─────────────────────────────────────────────────── -const CALLBACK = "回调"; -const PROP_COLS = [ - { name: "名称", color: C.variable }, - { name: "类型", color: C.type }, - { name: "默认值" }, - { name: "必填", mono: false }, -]; - -/** 构造参数表的一行:名称(回调带小标签)| 类型 | 默认值 | 必填。 */ -function propRow(ctx, name, type, def, required) { - const callback = /=>/.test(type); - const nameCell = { - est: name, - extra: callback ? tagWidth(CALLBACK) + 6 : 0, - draw: (frame) => { - const line = row(frame, "Name", { gap: 6, height: 20, width: "fit_content" }); - text(line, name, { size: 12.5, mono: true, color: C.variable }); - if (callback) - tag(line, CALLBACK, C.component, ctx.bg); - }, - }; - return [nameCell, cx(type), def === "—" ? px("—", C.desc) : cx(def), px(required, required === "—" ? C.desc : C.storage)]; -} - -function panelCard(parent, w) { - const ctx = card(parent, K.component, w, { name: "Panel", fold: "open" }); - nameProp(ctx, "Panel", C.component, [EXPORTED]); - prop(ctx, "构造参数", [seg("2 个", C.desc), seg(" · 类型 ", C.desc), link("Props", C.type)], { fold: "open" }); - table(ctx, PROP_COLS, [ - propRow(ctx, "id", "字符串", "—", "是"), - propRow(ctx, "onClose", "() => 无", "—", "是"), - ]); -} +const PANEL_CARD = componentCard({ + name: "Panel", + fold: "open", + tags: [EXPORTED], + from: "Props", + props: [["id", "字符串", "—", "是"], ["onClose", "() => 无", "—", "是"]], +}); function handleClickCard(parent, w) { const ctx = card(parent, K.handler, w, { name: "handleClick", fold: "closed" }); @@ -1123,172 +320,9 @@ const PANEL_OUTLINE = [ }, ]; -function renderCard(parent, w) { - const ctx = card(parent, K.render, w, { name: "Panel" }); - outline(ctx.content, PANEL_OUTLINE, ctx.bg); -} - -// ─── 编辑器和预览对齐 ──────────────────────────────────────────────────────── - -/** - * 一段源码配一张卡片:左边是第 `from`–`to` 行,右边是这段的卡片,两边顶端对齐,较矮的一边下面留空。 - * 卡片内容比卡片顶端低 8px,源码也往下让 8px,第一行字和卡片第一行属性在同一高度。 - * `depth` 是子块的层数,每层左边一条竖线;`last` 是这一层的最后一张,竖线到卡片底边为止,源码比卡片长也不往下伸。 - */ -function band(parent, b) { - const line = row(parent, "Lines " + b.from + "–" + b.to, { align: "start" }); - const code = col(line, "Code", { width: CODE_W, height: "fill_container", padding: [8, 0, 0, 0], clip: true }); - for (let n = b.from; n <= b.to; n++) { - const src = CODE[n - 1]; - const holder = row(code, "Line " + n, { height: 20 }); - const number = row(holder, "Number", { width: 44, height: 20, justify: "end" }); - text(number, String(n), { mono: true, color: C.dim }); - spacer(holder, "Margin", 26 + src.indent * MONO_CHAR, 20); - text(holder, src.segs, { mono: true }); - } - I(line, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); - const depth = b.depth || 0; - const right = col(line, "Preview", { height: "fill_container", padding: [0, PREVIEW_PAD, b.last ? 8 : 0, PREVIEW_PAD] }); - const level = row(right, "Level", { height: b.last ? "fit_content" : "fill_container", gap: 8, align: "start" }); - for (let d = 0; d < depth; d++) { - const guide = col(level, "Guide", { width: 12, height: "fill_container", align: "center" }); - I(guide, { type: "rectangle", name: "Line", width: 1, height: "fill_container", fill: solid(C.guide) }); - } - if (b.draw) { - const cards = col(level, "Cards", { padding: [0, 0, b.last ? 0 : 8, 0] }); - b.draw(cards, PREVIEW_W - PREVIEW_PAD * 2 - depth * 20); - } -} - -// ─── VS Code 窗口 ──────────────────────────────────────────────────────────── - -function activity(parent) { - const bar = col(parent, "Activity bar", { width: 48, fill: C.side }); - const icons = ["files", "search", "git-branch", "play", "monitor", "blocks", "rocket", "book-open-text"]; - for (const name of icons) { - const on = name === "book-open-text"; - const cell = row(bar, "Item / " + name, { width: 48, height: 42, justify: on ? "start" : "center", gap: on ? 10 : 0 }); - if (on) - I(cell, { type: "rectangle", name: "Active bar", width: 2, height: 42, fill: solid(C.focus) }); - icon(cell, name, on ? C.activityOn : C.activityIdle, 22); - } -} - -function sidebar(parent, selected) { - const side = col(parent, "Sidebar", { width: SIDE_W, fill: C.side }); - const header = row(side, "Header", { height: 34, padding: [0, 12, 0, 16], justify: "space_between" }); - text(header, "代码阅读", { size: 11 }); - const actions = row(header, "Actions", { width: "fit_content", gap: 10 }); - for (const name of ["git-pull-request", "file-plus", "refresh-cw"]) icon(actions, name, C.fg, 14); - const list = col(side, "Tree", { padding: [4, 0, 8, 0] }); - for (const item of TREE) { - const line = row(list, item.name, { - height: 26, - gap: 6, - padding: [0, 8, 0, 10 + item.depth * 14], - fill: item.name === selected ? C.selection : null, - }); - if (item.kind === "folder") { - icon(line, item.open ? "chevron-down" : "chevron-right", C.fg, 14); - icon(line, "folder", C.folder, 15); - } - else { - spacer(line, "Twisty", 14, 14); - icon(line, "atom", C.tsx, 14); - } - text(line, item.name, { color: item.name === selected ? C.fgStrong : C.fg }); - } -} - -/** 一组编辑器的标签栏:右边那组(代码阅读预览)有焦点,标签顶上一条聚焦色,右边是编辑 / 预览切换。 */ -function editorTitle(parent, focused) { - const bar = row(parent, "Editor title", { height: 36, justify: "space_between", fill: C.side }); - const tab = col(bar, "Tab", { width: 140, height: "fill_container", fill: C.editor }); - I(tab, { type: "rectangle", name: "Active", width: "fill_container", height: 2, fill: solid(focused ? C.focus : C.editor) }); - const label = row(tab, "Tab label", { height: "fill_container", padding: [0, 12], gap: 6 }); - icon(label, "atom", C.tsx, 14); - text(label, FILE, { color: focused ? C.fgStrong : C.fg }); - if (!focused) - return; - const mode = row(bar, "Mode", { width: "fit_content", padding: [2, 2], gap: 2, radius: 5, fill: C.field, stroke: C.borderStrong }); - const edit = row(mode, "Seg / 编辑", { width: "fit_content", padding: [2, 8], gap: 4, radius: 3 }); - icon(edit, "pencil", C.desc, 13); - text(edit, "编辑", { size: 12, color: C.desc }); - const preview = row(mode, "Seg / 预览", { width: "fit_content", padding: [2, 8], gap: 4, radius: 3, fill: C.toggleOn }); - icon(preview, "eye", C.fgStrong, 13); - text(preview, "预览", { size: 12, color: C.fgStrong }); - spacer(bar, "Pad", 8, 8); -} - -function crumb(parent) { - const line = row(parent, "Breadcrumb", { padding: [6, 16], gap: 6 }); - CRUMBS.forEach((part, index) => { - if (index) - text(line, "/", { size: 12, color: C.dim }); - text(line, part, { size: 12, color: index === CRUMBS.length - 1 ? C.fg : C.desc }); - }); -} - -function filters(parent, chips, count) { - const bar = row(parent, "Filter", { height: 36, padding: [0, 16], gap: 8 }); - text(bar, "筛选", { size: 12, color: C.desc }); - for (const chip of chips) { - const item = row(bar, "Chip / " + chip, { width: "fit_content", height: 24, padding: [0, 8], gap: 4, radius: 4, fill: C.input }); - text(item, chip, { size: 12 }); - icon(item, "chevron-down", C.desc, 12); - } - spacer(bar, "Spacer", "fill_container", 8); - text(bar, count + " 块", { size: 12, color: C.desc }); -} - -/** 两组编辑器的头:左边源码的标签栏、面包屑,下面让出筛选栏那么高;右边预览的标签栏、面包屑、筛选栏。 */ -function groupHeads(parent) { - const line = row(parent, "Group heads", { align: "start" }); - const left = col(line, "Editor group 1", { width: CODE_W }); - editorTitle(left, false); - crumb(left); - spacer(left, "Filter room", "fill_container", 36); - I(line, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); - const right = col(line, "Editor group 2", {}); - editorTitle(right, true); - crumb(right); - filters(right, ["种类", "访问级别"], 6); -} - -function status(parent) { - const bar = row(parent, "Status", { height: 26, padding: [0, 12], justify: "space_between", fill: C.side }); - const branch = row(bar, "Branch", { width: "fit_content", gap: 4 }); - icon(branch, "git-branch", C.fg, 13); - text(branch, "master", { size: 12 }); - const right = row(bar, "Right", { width: "fit_content", gap: 16 }); - text(right, "代码阅读", { size: 12 }); - text(right, "TypeScript JSX", { size: 12 }); -} - -/** VS Code 窗口:标题栏、活动栏、侧栏、编辑器(左源码、右预览,一段段对齐)、状态栏。 */ -function windowOf(name, x, bands) { - const win = col(null, name, { x, width: WIN_W, fill: C.side }); - const title = row(win, "Title bar", { height: 36, padding: [0, 12], justify: "space_between" }); - const lights = row(title, "Lights", { width: "fit_content", gap: 8 }); - for (const color of ["#ff5f57", "#febc2e", "#28c840"]) I(lights, { type: "ellipse", width: 12, height: 12, fill: solid(color) }); - text(title, "web — " + FILE, { size: 12, color: C.desc }); - spacer(title, "Balance", 52, 12); - const body = row(win, "Body", { align: "start", fill: C.side }); - activity(body); - sidebar(body, FILE); - const editor = col(body, "Editor", { fill: C.editor }); - groupHeads(editor); - for (const b of bands) band(editor, b); - const end = row(editor, "End", { height: 28 }); - spacer(end, "Code", CODE_W, 28); - I(end, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); - status(win); - return win; -} - // ─── 画板 ──────────────────────────────────────────────────────────────────── -windowOf("Prototype / React 钩子 · 自定义钩子与上下文", 0, [ +windowOf("Prototype / React 钩子 · 自定义钩子与上下文", 0, PANEL, [ { from: 1, to: 1, draw: importCard("'react'", 10) }, { from: 2, to: 3, draw: importCard("'next/navigation'", 1) }, { from: 4, to: 5, draw: contextCard }, @@ -1299,8 +333,8 @@ windowOf("Prototype / React 钩子 · 自定义钩子与上下文", 0, [ { from: 20, to: 21 }, ]); -windowOf("Prototype / React 钩子 · 组件 Panel", WIN_W + BOARD_GAP, [ - { from: 23, to: 23, draw: panelCard }, +windowOf("Prototype / React 钩子 · 组件 Panel", WIN_W + BOARD_GAP, PANEL, [ + { from: 23, to: 23, draw: PANEL_CARD }, { from: 24, to: 24, depth: 1, draw: routerHook }, { from: 25, to: 25, depth: 1, draw: themeHook }, { from: 26, to: 26, depth: 1, draw: sessionHook }, @@ -1315,6 +349,6 @@ windowOf("Prototype / React 钩子 · 组件 Panel", WIN_W + BOARD_GAP, [ { from: 44, to: 46, depth: 1, draw: renderEffectHook }, { from: 47, to: 49, depth: 1, draw: layoutEffectHook }, { from: 50, to: 52, depth: 1, draw: handleClickCard }, - { from: 53, to: 59, depth: 1, last: true, draw: renderCard }, + { from: 53, to: 59, depth: 1, last: true, draw: renderCard(PANEL_OUTLINE, "Panel") }, { from: 60, to: 60 }, ]); diff --git a/docs/prototype/code-reader/openpencil/react-shared.js b/docs/prototype/code-reader/openpencil/react-shared.js new file mode 100644 index 0000000..d69ef32 --- /dev/null +++ b/docs/prototype/code-reader/openpencil/react-shared.js @@ -0,0 +1,1106 @@ +// 代码阅读 React 原型共用的画法:颜色、文字、源码着色、卡片、表格、渲染大纲、钩子卡片、组件卡片、VS Code 窗口, +// 以及左边编辑器、右边预览一段段对齐的排法。OpenPencil 的脚本只认 I(),不能 import, +// 各原型脚本接在这份后面一起跑:`cat react-shared.js react-hooks.js | op design - --script`。 +// 颜色取 VS Code Dark Modern 和 webview 的 codeReader.css(卡片淡底 7%、描边 35%),窗口、卡片画法同 react.js,函数小框同 rust-chain.js; +// 译文照 vscode/src/codeReader/translators/typescriptZh.ts 的中文直译,渲染大纲的说法照 vscode/src/codeReader/rules/react.ts。 +// OpenPencil 自动折行量不准,长文字按估出的宽度手动断行,文字框都按内容长。 + +const C = { + editor: "#1f1f1f", + side: "#181818", + border: "#2b2b2b", + borderStrong: "#3c3c3c", + fg: "#cccccc", + fgStrong: "#e8e8e8", + desc: "#9d9d9d", + dim: "#6e7681", + activityIdle: "#868686", + activityOn: "#d7d7d7", + focus: "#0078d4", + selection: "#04395e", + input: "#313131", + inputBorder: "#454545", + field: "#111111", + toggleOn: "#37373d", + guide: "#404040", + punct: "#d4d4d4", + comment: "#6a9955", + keyword: "#c586c0", + storage: "#569cd6", + variable: "#9cdcfe", + fn: "#dcdcaa", + type: "#4ec9b0", + string: "#ce9178", + number: "#b5cea8", + constant: "#4fc1ff", + nativeTag: "#808080", + component: "#61dafb", + branch: "#ce9178", + ret: "#89d185", + loop: "#8f9cff", + folder: "#8b9ba8", + tsx: "#519aba", +}; + +// 编辑器的括号配对着色(Dark Modern 的 editorBracketHighlight.foreground1–3),按嵌套层数轮换 +const BRACKETS = ["#ffd700", "#da70d6", "#179fff"]; + +// 定义处的卡片种类:上下文是这次新加的,别的同 react.js;函数同 build.js。钩子的定义和调用都用 HOOK 的样式 +const K = { + import: { label: "导入", color: "#c586c0", icon: "import" }, + fn: { label: "函数", color: "#dcdcaa", icon: "square-function" }, + context: { label: "上下文", color: "#4ec9b0", icon: "share-2" }, + component: { label: "React 组件", color: "#61dafb", icon: "atom" }, + handler: { label: "事件处理函数", color: "#dcdcaa", icon: "mouse-pointer-click" }, + render: { label: "渲染输出", color: "#89d185", icon: "layout-template" }, +}; + +const MONO = "Menlo"; +const UI = "PingFang SC"; + +// 窗口:活动栏 48、侧栏、编辑器(左边源码、1px 分隔、右边预览) +const WIN_W = 1700; +const SIDE_W = 250; +const CODE_W = 600; +const PREVIEW_W = WIN_W - 48 - SIDE_W - CODE_W - 1; +const PREVIEW_PAD = 20; +const BOARD_GAP = 80; +// Menlo 13px 一个字符宽,源码缩进按它算 +const MONO_CHAR = 7.83; + +// ─── 颜色、宽度 ────────────────────────────────────────────────────────────── + +function solid(color) { + return [{ type: "solid", color }]; +} + +function rgb(hex) { + const h = hex.replace("#", ""); + return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16)); +} + +/** `color` 按 `t` 盖在 `base` 上(`color-mix(in srgb, color t, base)`)。 */ +function mix(color, base, t) { + const a = rgb(color); + const b = rgb(base); + return "#" + a.map((v, i) => Math.round(v * t + b[i] * (1 - t)).toString(16).padStart(2, "0")).join(""); +} + +const WIDE = /[⺀-鿿 -〿＀-￯“”‘’…—·×→]/; + +function charWidth(ch, size, mono) { + if (WIDE.test(ch)) + return size; + if (mono) + return size * 0.61; + if (/[A-Z0-9]/.test(ch)) + return size * 0.68; + if (/[ilj.,:;'|!()[\] ]/.test(ch)) + return size * 0.34; + return size * 0.58; +} + +/** 估一段字的宽度,宁大勿小:估小了字会伸出框外。 */ +function widthOf(s, size, mono) { + let w = 0; + for (const ch of s) w += charWidth(ch, size, mono); + return w * 1.04; +} + +// ─── 译文着色 ──────────────────────────────────────────────────────────────── + +// 「当 … 时」「对 … 的每一项」是渲染大纲的关键字(react.ts 的 when、eachItem) +const ZH_KEYWORD = new Set(["如果", "否则", "返回", "当", "时", "对", "的每一项", "则", "新建", "调用", "常量", "变量", "函数"]); +const ZH_OPERATOR = new Set(["全等", "不全等", "等于", "不等于", "并且", "或者", "不成立"]); +const ZH_LITERAL = new Set(["空", "真", "假", "未定义", "空数组", "空对象"]); +const ZH_TYPE = new Set(["字符串", "数值", "布尔", "任意", "未知", "永不", "无", "对象"]); +const TOKEN = /"(?:[^"\\]|\\.)*"|`[^`]*`|'[^']*'|[A-Za-z_$][\w$]*|\d+(?:\.\d+)?|[一-鿿]+|\s+|[\s\S]/g; + +function seg(text, fill, extra) { + return Object.assign({ text, fill }, extra || {}); +} + +function merge(list) { + const out = []; + for (const s of list) { + const last = out[out.length - 1]; + if (last && last.fill === s.fill && !last.u && !s.u && last.w === s.w) + last.text += s.text; + else + out.push(Object.assign({}, s)); + } + return out; +} + +function identColor(tok, rest) { + if (/^\s*(\?\.)?(<[^()]*>)?\(/.test(rest)) + return C.fn; + if (/^[A-Z][A-Z0-9_]+$/.test(tok)) + return C.constant; + if (/^[A-Z]/.test(tok)) + return C.type; + return C.variable; +} + +/** 一段中文直译:照抄的名字按词性着色,翻出来的关键字、运算符、字面量、内置类型各用各的颜色。 */ +function cx(src) { + const out = []; + let at = 0; + for (const tok of src.match(TOKEN) || []) { + at += tok.length; + let color = C.fg; + if (/^["'`]/.test(tok)) + color = C.string; + else if (/^\d/.test(tok)) + color = C.number; + else if (/^[一-鿿]/.test(tok)) + color = ZH_KEYWORD.has(tok) ? C.keyword : ZH_OPERATOR.has(tok) ? C.storage : ZH_LITERAL.has(tok) ? C.number : ZH_TYPE.has(tok) ? C.type : C.desc; + else if (/^[A-Za-z_$]/.test(tok)) + color = identColor(tok, src.slice(at)); + out.push(seg(tok, color)); + } + return merge(out); +} + +/** 一段同色的字。 */ +function px(text, color) { + return [seg(text, color || C.fg)]; +} + +/** 能点过去的名字(跳到那张卡片):带下划线。 */ +function link(text, color) { + return seg(text, color, { u: true }); +} + +// ─── 源码着色 ──────────────────────────────────────────────────────────────── + +const TSX_TOKEN = /'[^']*'|"[^"]*"|=>|\.\.\.|\?\.|&&|<\/|\/>|[A-Za-z_$][\w$]*|\d+(?:\.\d+)?|\s+|[\s\S]/g; +const TSX_STORAGE = new Set(["const", "let", "var", "function", "new", "typeof", "true", "false", "null", "undefined", "this"]); +const TSX_CONTROL = new Set(["import", "export", "from", "return", "if", "else", "switch", "case", "default", "await"]); +const TSX_PRIMITIVE = new Set(["string", "number", "boolean", "void", "any", "unknown"]); + +/** + * 整份源码按 VS Code Dark Modern 着色,返回每行的着色段(不含行首缩进)。 + * 括号按整份文件的嵌套层数配色;标识符后面紧跟的 `<` 是泛型,别处的 `<名字` 是 JSX 标签,标签里的名字是属性。 + * 注释整段用注释色,块注释可以跨行;`type` 后面跟名字或 `{` 时是关键字(`import type`),跟冒号时是普通的键名; + * `from` 只在 import / export 那一行是关键字,别处是变量。 + */ +function highlight(lines) { + let depth = 0; + let generic = 0; + let tag = null; + let inComment = false; + return lines.map((line) => { + const src = line.replace(/^ +/, ""); + const indent = line.length - src.length; + if (inComment || /^\/[*/]/.test(src)) { + if (!/^\/\//.test(src)) + inComment = !/\*\/\s*$/.test(src); + return { indent, segs: [seg(src, C.comment)] }; + } + const out = []; + let at = 0; + let prev = ""; + let prevSolid = ""; + for (const tok of src.match(TSX_TOKEN) || []) { + at += tok.length; + const rest = src.slice(at); + let color = C.punct; + if (/^\s+$/.test(tok)) { + out.push(seg(tok, C.punct)); + prev = tok; + continue; + } + if (/^['"]/.test(tok)) + color = C.string; + else if (/^\d/.test(tok)) + color = C.number; + else if (tok === "=>") + color = C.storage; + else if ("([{".includes(tok)) { + color = BRACKETS[depth % 3]; + depth++; + if (tag && tok === "{") + tag.braces++; + } + else if (")]}".includes(tok)) { + depth = Math.max(0, depth - 1); + color = BRACKETS[depth % 3]; + if (tag && tok === "}") + tag.braces--; + } + else if (tok === "<") { + if (/^[A-Za-z_$][\w$]*$/.test(prev)) + generic++; + else if (/^[A-Za-z]/.test(rest)) { + color = C.nativeTag; + tag = { name: true, braces: 0 }; + } + } + else if (tok === "" && tag && tag.braces === 0) { + color = C.nativeTag; + tag = null; + } + else if (tok === ">") { + if (generic > 0) + generic--; + else if (tag && tag.braces === 0) { + color = C.nativeTag; + tag = null; + } + } + else if (/^[A-Za-z_$]/.test(tok)) { + if (tag && tag.braces === 0) { + color = tag.name ? (/^[A-Z]/.test(tok) ? C.type : C.storage) : C.variable; + tag.name = false; + } + else if (prevSolid === "." || prevSolid === "?.") + color = /^\s*\(/.test(rest) ? C.fn : C.variable; + else if (TSX_STORAGE.has(tok) || (tok === "type" && /^\s+[{A-Za-z_$]/.test(rest))) + color = C.storage; + else if (TSX_CONTROL.has(tok) && (tok !== "from" || /^(import|export)\b/.test(src))) + color = C.keyword; + else if (TSX_PRIMITIVE.has(tok)) + color = C.type; + else + color = identColor(tok, rest); + } + out.push(seg(tok, color)); + prev = tok; + prevSolid = tok; + } + return { indent, segs: merge(out) }; + }); +} + +// ─── 断行 ──────────────────────────────────────────────────────────────────── + +const CLOSING = /^[))\]】,,.。、;;::!!??」』”]/; +const OPENING = /[(([【「『“]$/; +const WIDE_CHAR = /^[⺀-鿿 -〿＀-￯“”]$/; +const TOKENS = /\n|[^\S\n]+|[⺀-鿿 -〿＀-￯“”]|[^\s⺀-鿿 -〿＀-￯“”]+/g; + +/** + * 按估出的宽度把一串着色的字断成几行(行间用 `\n` 接起来,交给一个文字框)。 + * 代码只在空格处断;正文在空格处和汉字之间断,收尾标点跟着前一个字、开头标点跟着后一个字;能点的名字整段不断。 + */ +function wrap(segs, maxW, size, mono) { + const units = []; + let cur = null; + const open = () => { + cur = { parts: [], trail: [] }; + units.push(cur); + }; + const add = (list, text, style) => { + const last = list[list.length - 1]; + if (last && last.style === style) + last.text += text; + else + list.push({ text, style }); + }; + const lastText = () => { + const last = cur && cur.parts[cur.parts.length - 1]; + return last ? last.text : ""; + }; + for (const style of segs) { + const tokens = style.u ? [style.text] : style.text.match(TOKENS) || []; + for (const tok of tokens) { + if (tok === "\n") { + units.push({ br: true }); + cur = null; + continue; + } + if (/^\s+$/.test(tok)) { + if (cur) + add(cur.trail, tok, style); + continue; + } + const wide = !mono && WIDE_CHAR.test(tok); + const joins = cur && cur.trail.length === 0 && (CLOSING.test(tok) || OPENING.test(lastText()) || !(wide || cur.wide)); + if (!joins) + open(); + add(cur.parts, tok, style); + cur.wide = wide; + } + } + const measure = (list) => list.reduce((sum, p) => sum + widthOf(p.text, size, mono), 0); + const lines = [[]]; + let w = 0; + const emit = (text, style) => add(lines[lines.length - 1], text, style); + const newLine = () => { + const line = lines[lines.length - 1]; + const tail = line[line.length - 1]; + if (tail) + tail.text = tail.text.replace(/\s+$/, ""); + lines.push([]); + w = 0; + }; + for (const unit of units) { + if (unit.br) { + newLine(); + continue; + } + const uw = measure(unit.parts); + if (w > 0 && w + uw > maxW) + newLine(); + for (const part of unit.parts) emit(part.text, part.style); + w += uw; + for (const part of unit.trail) emit(part.text, part.style); + w += measure(unit.trail); + } + return lines.map((line) => { + const tail = line[line.length - 1]; + if (tail) + tail.text = tail.text.replace(/\s+$/, ""); + return line + .filter((p) => p.text) + .map((p) => Object.assign({}, p.style, { text: p.text })); + }); +} + +function joinLines(lines) { + const out = []; + lines.forEach((line, i) => { + if (i > 0) + out.push(seg("\n", C.fg)); + for (const s of line) out.push(s); + }); + return merge(out); +} + +// ─── 节点 ──────────────────────────────────────────────────────────────────── + +/** + * 文字:`content` 是字符串或着色的段;给了 `maxW` 就按它断行。宽、高都跟着字长,不靠 OpenPencil 折行。 + * 给了 `fixedW` 时宽度定死:几个字符的多色文字按内容长会被导出时挤小。 + * o: size、color、weight、mono、lh(行高 px)、maxW、fixedW、name + */ +function text(parent, content, o) { + const opt = o || {}; + const size = opt.size || 13; + const mono = Boolean(opt.mono); + let segs = typeof content === "string" ? px(content, opt.color || C.fg) : content; + if (opt.maxW) + segs = joinLines(wrap(segs, opt.maxW, size, mono)); + if (!segs.some((s) => s.text.trim())) + return null; + const plain = segs.length === 1 && !segs[0].u && !segs[0].w; + const node = { + type: "text", + name: opt.name || segs.map((s) => s.text).join("").replace(/\n/g, " ").slice(0, 40), + fontFamily: mono ? MONO : UI, + fontSize: size, + fontWeight: opt.weight || 400, + lineHeight: (opt.lh || 20) / size, + width: "fit_content", + height: "fit_content", + textGrowth: "auto", + }; + if (opt.fixedW) { + node.width = opt.fixedW; + node.textGrowth = "fixed-width"; + } + if (plain) { + node.content = segs[0].text; + node.fill = solid(segs[0].fill); + } + else { + node.content = segs.map((s) => { + const piece = { text: s.text, fill: s.fill }; + if (s.u) + piece.underline = true; + if (s.w) + piece.fontWeight = s.w; + return piece; + }); + node.fill = solid(C.fg); + } + return I(parent, node); +} + +function icon(parent, name, color, size) { + return I(parent, { type: "icon_font", name, iconFontName: name, width: size, height: size, fill: solid(color) }); +} + +function box(parent, name, o) { + const opt = o || {}; + const node = { + type: "frame", + name, + layout: opt.layout || "horizontal", + width: opt.width || "fill_container", + height: opt.height || "fit_content", + gap: opt.gap == null ? 0 : opt.gap, + clipContent: Boolean(opt.clip), + }; + if (opt.x != null) { + node.x = opt.x; + node.y = opt.y || 0; + } + if (opt.padding != null) + node.padding = opt.padding; + if (opt.align) + node.alignItems = opt.align; + if (opt.justify) + node.justifyContent = opt.justify; + if (opt.fill) + node.fill = solid(opt.fill); + if (opt.radius != null) + node.cornerRadius = opt.radius; + if (opt.stroke) + node.stroke = { thickness: 1, fill: solid(opt.stroke) }; + return I(parent, node); +} + +function row(parent, name, o) { + return box(parent, name, Object.assign({ layout: "horizontal", align: "center" }, o || {})); +} + +function col(parent, name, o) { + return box(parent, name, Object.assign({ layout: "vertical" }, o || {})); +} + +function spacer(parent, name, width, height) { + return I(parent, { type: "frame", name, width, height }); +} + +/** 小标签(具名导出、useReducer、元素……):给定颜色的淡底、描边。 */ +function tag(parent, label, color, bg) { + const pill = row(parent, "Tag / " + label, { + width: "fit_content", + height: 18, + padding: [0, 5], + radius: 4, + fill: mix(color, bg, 0.14), + stroke: mix(color, bg, 0.45), + }); + text(pill, label, { size: 11, color, lh: 16, weight: 500 }); + return pill; +} + +function tagWidth(label) { + return widthOf(label, 11, false) + 12; +} + +/** 渲染大纲里的小框:条件「当 … 时」、列表「对 … 的每一项」。 */ +function group(parent, segs, color, bg) { + const pill = row(parent, "Group", { + width: "fit_content", + height: 20, + padding: [0, 5], + radius: 4, + fill: mix(color, bg, 0.14), + stroke: mix(color, bg, 0.45), + }); + text(pill, segs, { size: 12.5, mono: true, lh: 18 }); + return pill; +} + +// ─── 卡片 ──────────────────────────────────────────────────────────────────── + +/** + * 卡片右上角:问 AI、编辑;给了 `calls` 再加调用树,同 webview 的 BlockTools:调用次数大于 0 时图标后面跟一个小圆标 + * (徽标底色、字色取 Dark Modern 的 badge),是 0 时只有图标。返回这一排的宽度。 + */ +function tools(parent, calls) { + const bar = row(parent, "Tools", { width: "fit_content", height: 20, gap: 2 }); + for (const name of ["sparkles", "pencil"]) { + const button = row(bar, name, { width: 22, height: 20, justify: "center", radius: 4 }); + icon(button, name, C.desc, 14); + } + if (calls == null) + return 22 * 2 + 2; + if (calls === 0) { + const tree = row(bar, "git-branch", { width: 22, height: 20, justify: "center", radius: 4 }); + icon(tree, "git-branch", C.desc, 14); + return 22 * 3 + 2 * 2; + } + const tree = row(bar, "git-branch", { width: "fit_content", height: 20, padding: [0, 4], gap: 1, radius: 4 }); + icon(tree, "git-branch", C.desc, 14); + const badge = row(tree, "Count", { width: 14, height: 14, justify: "center", radius: 7, fill: "#616161" }); + text(badge, String(calls), { size: 9, weight: 700, color: "#f8f8f8", lh: 14 }); + return 22 * 2 + 2 + 2 + (4 + 14 + 1 + 14 + 4); +} + +/** 悬停提示气泡,样子同 webview 的 data-tooltip:悬停浮层的底色、边框、11px 字。`x`、`y` 是它在父节点里的位置。 */ +function tooltip(parent, label, x, y) { + const bw = Math.ceil(widthOf(label, 11, false)) + 16; + const tip = I(parent, { + type: "frame", + name: "Tooltip", + x: Math.round(x), + y: Math.round(y), + width: bw, + height: 22, + layout: "horizontal", + alignItems: "center", + justifyContent: "center", + cornerRadius: 4, + fill: solid("#202020"), + stroke: { thickness: 1, fill: solid("#454545") }, + effects: [{ type: "shadow", offsetX: 0, offsetY: 2, blur: 8, spread: 0, color: "rgba(0,0,0,0.36)" }], + }); + text(tip, label, { size: 11, color: C.fg, lh: 14 }); + return bw; +} + +/** 气泡的宽度,按 [tooltip] 的内边距算。 */ +function tooltipWidth(label) { + return Math.ceil(widthOf(label, 11, false)) + 16; +} + +/** + * 卡片左边的一个概念图标:20px 见方,图标 16px。`bubble` 时画出它悬停的气泡:在图标下方隔 6px,右边和图标右边对齐。 + * OpenPencil 里前面的兄弟节点画在上层,图标在内容区前面,气泡才不被内容盖住;自由摆放的框会被伸到右边、下边的子节点撑大, + * 所以气泡不伸出这一格的右边。 + */ +function conceptIcon(parent, item) { + if (!item.bubble) { + const cell = row(parent, "Concept / " + item.tip, { width: 20, height: 20, justify: "center" }); + icon(cell, item.name, item.color, 16); + return; + } + const cell = box(parent, "Concept / " + item.tip, { layout: "none", width: 20, height: 20 }); + I(cell, { type: "icon_font", name: item.name, iconFontName: item.name, x: 2, y: 2, width: 16, height: 16, fill: solid(item.color) }); + const bw = tooltipWidth(item.tip); + tooltip(cell, item.tip, Math.min(Math.round(10 - bw / 2), 20 - bw), 20 + 6); +} + +/** + * 一张卡片:折叠箭头(有子块才有:`open` 展开、`closed` 收起)、概念图标、内容、右上角两个按钮。 + * 概念图标默认是种类图标一个,给了 `icons` 就并排画这几个(`{name, color, tip, bubble?}`)。 + * 淡底默认用种类色,给了 `tint` 用它(钩子卡片按来源分底色)。给了 `calls` 右上角多一个调用树按钮。 + * 放进自由摆放的框里时给 `x`、`y`,宽度定成 `w`。 + * `w` 是卡片外宽;返回内容区和内容区的宽度,属性行、表格按它断行。 + */ +function card(parent, kind, w, o) { + const opt = o || {}; + const bg = mix(opt.tint || kind.color, C.editor, 0.07); + const node = box(parent, kind.label + (opt.name ? " / " + opt.name : ""), { + x: opt.x, + y: opt.y, + width: opt.x != null ? w : null, + layout: "horizontal", + gap: 10, + padding: [8, 10, 8, 8], + radius: 8, + align: "start", + fill: bg, + stroke: mix(kind.color, C.editor, 0.35), + }); + const fold = row(node, "Fold", { width: 14, height: 20, justify: "center" }); + if (opt.fold) + icon(fold, opt.fold === "open" ? "chevron-down" : "chevron-right", C.desc, 14); + const icons = opt.icons || [{ name: kind.icon, color: kind.color, tip: kind.label }]; + const iconsW = icons.length * 20 + (icons.length - 1) * 2; + const concepts = row(node, "Concepts", { width: iconsW, height: 20, gap: 2 }); + for (const item of icons) conceptIcon(concepts, item); + const content = col(node, "Content", { gap: 3 }); + const toolsW = tools(node, opt.calls); + return { node, content, w: w - 18 - 14 - iconsW - toolsW - 30, bg, labelW: opt.labelW || 76 }; +} + +/** 属性表的一行:左边说明色的标签,右边值。`value` 是着色的段、字符串,或自己画的函数 `(frame, width)`。 */ +function prop(ctx, label, value, o) { + const opt = o || {}; + const line = row(ctx.content, "Prop / " + label, { gap: 12, align: "start" }); + const key = row(line, "Key", { width: ctx.labelW, height: 20, gap: 4 }); + if (opt.fold) + icon(key, opt.fold === "open" ? "chevron-down" : "chevron-right", C.desc, 14); + text(key, label, { size: 12.5, color: C.desc, lh: 20 }); + const valueW = ctx.w - ctx.labelW - 12; + if (typeof value === "function") { + const frame = col(line, "Value", { gap: 2 }); + value(frame, valueW); + return line; + } + const segs = typeof value === "string" ? px(value, opt.color || C.fg) : value; + text(line, segs, { size: opt.size || 13, mono: opt.mono !== false, maxW: valueW, weight: opt.weight }); + return line; +} + +/** 名称一行:名字加粗,后面跟小标签 `[文字, 颜色]`。 */ +function nameProp(ctx, name, color, tags, label) { + const line = row(ctx.content, "Prop / " + (label || "名称"), { gap: 12, align: "start" }); + const key = row(line, "Key", { width: ctx.labelW, height: 20 }); + text(key, label || "名称", { size: 12.5, color: C.desc, lh: 20 }); + const value = row(line, "Value", { gap: 6, height: 20 }); + text(value, name, { mono: true, weight: 600, color }); + for (const [tagLabel, tagColor] of tags || []) tag(value, tagLabel, tagColor, ctx.bg); + return line; +} + +/** + * 表格:`cols` 是 `{name, color?, mono?}`,最后一列分剩下的;格子是着色的段、字符串(按列色)或带 `draw` 的对象。 + * 列宽按整列的内容估,表头浅底,行和列之间一条分隔线。 + */ +function table(ctx, cols, rows) { + const tableW = ctx.w - 5; + const cellText = (cell) => typeof cell === "string" ? cell : Array.isArray(cell) ? cell.map((s) => s.text).join("") : (cell.est || ""); + const natural = cols.map((c, i) => { + let wMax = widthOf(c.name, 12, false); + for (const r of rows) wMax = Math.max(wMax, widthOf(cellText(r[i]), 12.5, c.mono !== false) + (r[i] && r[i].extra ? r[i].extra : 0)); + return Math.ceil(wMax + 18); + }); + const last = cols.length - 1; + const avail = tableW - 2 - last; + const widths = natural.slice(); + widths[last] = avail - widths.slice(0, last).reduce((a, b) => a + b, 0); + const outer = col(ctx.content, "Table wrap", { padding: [2, 0, 2, 5] }); + const grid = col(outer, "Table", { radius: 4, stroke: C.borderStrong, clip: true }); + const headBg = mix("#ffffff", ctx.bg, 0.05); + const drawRow = (cells, header) => { + if (!header) + I(grid, { type: "rectangle", name: "Divider", width: "fill_container", height: 1, fill: solid(C.borderStrong) }); + const line = row(grid, header ? "Header" : "Row", { align: "start", fill: header ? headBg : null }); + cells.forEach((cell, i) => { + if (i > 0) + I(line, { type: "rectangle", name: "Sep", width: 1, height: "fill_container", fill: solid(C.borderStrong) }); + const inner = widths[i] - 16; + const frame = col(line, cols[i].name, { width: widths[i], padding: [2, 8], gap: 3 }); + if (header) { + text(frame, cell, { size: 12, color: C.desc, lh: 20 }); + return; + } + if (cell && cell.draw) { + cell.draw(frame, inner); + return; + } + const segs = typeof cell === "string" ? px(cell, cols[i].color || C.fg) : cell; + text(frame, segs, { size: 12.5, mono: cols[i].mono !== false, maxW: inner, lh: 20 }); + }); + }; + drawRow(cols.map((c) => c.name), true); + for (const r of rows) drawRow(r, false); +} + +// ─── 渲染大纲 ──────────────────────────────────────────────────────────────── + +/** 大纲一行里的几样东西:元素名、className 收成的小框、属性、文字、条件小框。 */ +const el = (name) => ({ kind: "el", name }); +const cls = (label) => ({ kind: "cls", label }); +const at = (name, value) => ({ kind: "attr", name, value }); +const words = (segs) => ({ kind: "words", segs }); +const cond = (segs, color) => ({ kind: "group", segs, color: color || C.branch }); + +/** className 收成的「样式 N 个类」小框。 */ +function classes(parent, label) { + const pill = row(parent, "Classes", { width: "fit_content", height: 20, padding: [0, 5], radius: 4, fill: C.input, stroke: C.inputBorder }); + text(pill, label, { size: 11, color: C.desc, lh: 18 }); + return pill; +} + +function pieceText(p) { + if (p.kind === "el") + return `<${p.name}>`; + if (p.kind === "attr") + return p.name + "=" + p.value.map((s) => s.text).join(""); + return p.segs.map((s) => s.text).join(""); +} + +function pieceWidth(p) { + if (p.kind === "cls") + return widthOf(p.label, 11, false) + 12; + if (p.kind === "group") + return widthOf(pieceText(p), 12.5, true) + 12; + return widthOf(pieceText(p), 13, true); +} + +/** 画大纲里的一样东西;属性一样就比一行还长时(回调写在属性值里)按 `maxW` 断行。 */ +function drawPiece(parent, p, bg, maxW) { + if (p.kind === "el") + return text(parent, [seg(`<${p.name}>`, /^[A-Z]/.test(p.name) ? C.component : C.nativeTag)], { mono: true }); + if (p.kind === "cls") + return classes(parent, p.label); + if (p.kind === "attr") { + const segs = [seg(p.name, C.variable), seg("=", C.fg)].concat(p.value); + const plain = pieceText(p); + if (pieceWidth(p) > maxW) + return text(parent, segs, { mono: true, maxW }); + return text(parent, segs, { mono: true, fixedW: plain.length < 6 ? Math.ceil(widthOf(plain, 13, true)) + 2 : null }); + } + if (p.kind === "words") + return text(parent, p.segs, { mono: true }); + return group(parent, p.segs, p.color, bg); +} + +/** + * 大纲:一行一个元素,下一层缩进、左边一条竖线;带下一层的行前面有折叠箭头。 + * 一个元素的几样东西一行放不下就往下排,接着的行缩进 16px。`w` 是大纲的宽度。 + */ +function outline(parent, items, w, bg) { + const list = col(parent, "Outline", { gap: 2 }); + for (const item of items) { + const line = row(list, "Item", { gap: 4, align: "start" }); + const fold = row(line, "Fold", { width: 14, height: 20, justify: "center" }); + if (item.kids) + icon(fold, "chevron-down", C.desc, 14); + const maxW = w - 18; + const lines = [[]]; + let lw = 0; + for (const p of item.line) { + const pw = Math.min(pieceWidth(p), maxW - 16); + if (lw > 0 && lw + 8 + pw > maxW) { + lines.push([]); + lw = 16; + } + lines[lines.length - 1].push(p); + lw += (lines[lines.length - 1].length > 1 ? 8 : 0) + pw; + } + if (lines.length === 1) { + const holder = row(line, "Line", { gap: 8, height: 20 }); + for (const p of item.line) drawPiece(holder, p, bg, maxW); + } + else { + const body = col(line, "Lines", { gap: 2 }); + lines.forEach((pieces, i) => { + const holder = row(body, "Line", { gap: 8, align: "start", padding: [0, 0, 0, i === 0 ? 0 : 16] }); + for (const p of pieces) drawPiece(holder, p, bg, maxW - 16); + }); + } + if (item.kids) { + const sub = row(list, "Sub", { gap: 10, align: "start", padding: [0, 0, 0, 5] }); + I(sub, { type: "rectangle", name: "Guide", width: 1, height: "fill_container", fill: solid(C.guide) }); + const inner = col(sub, "Kids", { gap: 2 }); + outline(inner, item.kids, w - 16, bg); + } + } + return list; +} + +/** 渲染输出卡片:组件返回的 JSX 画成大纲。 */ +function renderCard(items, name) { + return (parent, w) => { + const ctx = card(parent, K.render, w, { name }); + outline(ctx.content, items, ctx.w, ctx.bg); + }; +} + +// ─── 定义处的卡片 ───────────────────────────────────────────────────────────── + +const EXPORTED = ["具名导出", C.keyword]; +const DEFAULT_EXPORT = ["默认导出", C.keyword]; +const CLIENT = ["客户端组件", C.component]; + +/** 导入收起时只剩一行:来源和导入项个数,`import type` 再写「仅类型」。 */ +function importCard(from, count, typeOnly) { + return (parent, w) => { + const ctx = card(parent, K.import, w, { name: from, fold: "closed" }); + const line = row(ctx.content, "Summary", { gap: 6, height: 20 }); + text(line, "来源", { size: 12.5, color: C.desc }); + text(line, from, { mono: true, color: C.string }); + text(line, "·", { color: C.dim }); + text(line, "导入项", { size: 12.5, color: C.desc }); + text(line, count + " 个", { size: 12.5, color: C.desc }); + if (typeOnly) { + text(line, "·", { color: C.dim }); + text(line, "仅类型", { size: 12.5, color: C.desc }); + } + }; +} + +// ─── 钩子调用:一种卡片 ────────────────────────────────────────────────────── + +// 所有钩子卡片左边第一个图标、描边都一样;淡底按钩子从哪来分:React 自带、第三方库、项目里自己写的 +const HOOK = { label: "钩子", color: "#b180d7", icon: "fishing-hook" }; +const ORIGIN = { react: "#61dafb", library: "#e5c07b", own: "#89d185" }; + +// React 自带钩子的作用,同 React 类型定义里钩子的分组:卡片左边第二个图标,悬停显示名字。 +// 颜色借 Dark Modern 的语法色,和钩子紫分得开:状态同变量、引用同常量、性能同数字、上下文同类型、并发同字符串 +const ROLE = { + state: { label: "状态", icon: "toggle-right", color: "#9cdcfe" }, + effect: { label: "副作用", icon: "zap", color: "#e5c07b" }, + ref: { label: "引用", icon: "anchor", color: "#4fc1ff" }, + perf: { label: "性能", icon: "sigma", color: "#b5cea8" }, + context: { label: "上下文", icon: "share-2", color: "#4ec9b0" }, + concurrent: { label: "并发", icon: "hourglass", color: "#ce9178" }, +}; + +// 所有钩子卡片同一个标签列宽,和最长的标签「类型参数」对齐 +const HOOK_LABEL_W = 76; + +/** 依赖项的三种读法:某个值变化时、空数组的仅挂载时、没写依赖的每次渲染后。 */ +const changed = (name) => [seg(name, C.variable), seg(" 变化时", C.keyword)]; +const ON_MOUNT = [seg("仅挂载时", C.keyword)]; +const NO_DEPS = [seg("没写,", C.desc), seg("每次渲染后", C.keyword)]; + +/** 函数参数收成的小框:朝右的折叠箭头,写「函数 (参数) · N 句」,没参数时不写括号;同调用链原型的闭包小框。 */ +function fnBox(params, count) { + const segs = [seg("函数", C.desc)] + .concat(params ? [seg(" (", C.fg)].concat(params, [seg(")", C.fg)]) : []) + .concat([seg(" · " + count + " 句", C.desc)]); + return { + est: segs.map((s) => s.text).join(""), + draw: (frame) => { + const pill = row(frame, "Fold box", { + width: "fit_content", + height: 20, + padding: [0, 6, 0, 3], + gap: 3, + radius: 4, + fill: C.input, + stroke: C.borderStrong, + }); + icon(pill, "chevron-right", C.desc, 13); + text(pill, segs, { mono: true, size: 12.5, lh: 18 }); + }, + }; +} + +/** + * 钩子调用的卡片,所有钩子共用一种,只有钩子 / 类型参数 / 参数 / 返回四行,照钩子签名排,没有的行不显示。 + * 左边第一个图标、描边所有钩子一样,淡底按来源取:React 自带的(给 `role`)左边再并排一个作用图标; + * 第三方库的(`lib`)、自己写的(`own`)只有钩子图标,自己写的钩子名能点到定义。 + * `roleTip` 换掉作用图标的悬停文字,`bubble` 画出悬停时的提示气泡。`fold` 表示有函数参数,函数体子块收起。 + * `params` 每项是「参数 | 值」;`returns` 每项是「名称 | 是什么」,给了 `namesOnly` 只列名称。格子同 [table]。 + * 返回值里有函数时给 `calls`:右上角多一个调用树按钮,数字是这个函数在样例里被调用几次。 + */ +function hookCall(parent, w, h) { + const tint = h.own ? ORIGIN.own : h.lib ? ORIGIN.library : ORIGIN.react; + const icons = [{ name: HOOK.icon, color: HOOK.color, tip: HOOK.label }]; + if (h.role) + icons.push({ name: h.role.icon, color: h.role.color, tip: h.roleTip || h.role.label, bubble: h.bubble }); + const ctx = card(parent, HOOK, w, { name: h.name + " · " + h.target, fold: h.fold ? "closed" : null, labelW: HOOK_LABEL_W, tint, icons, calls: h.calls }); + const line = row(ctx.content, "Prop / 钩子", { gap: 12, align: "start" }); + const key = row(line, "Key", { width: ctx.labelW, height: 20 }); + text(key, "钩子", { size: 12.5, color: C.desc, lh: 20 }); + text(line, [seg(h.name, C.fn, h.own ? { w: 600, u: true } : { w: 600 })], { mono: true }); + if (h.typeArg) + prop(ctx, "类型参数", cx(h.typeArg)); + if (h.params) { + prop(ctx, "参数", px(`${h.params.length} 个`, C.desc), { mono: false, fold: "open" }); + table(ctx, [{ name: "参数", color: C.variable }, { name: "值" }], h.params); + } + if (h.returns) { + prop(ctx, "返回", px(`${h.returns.length} 个`, C.desc), { mono: false, fold: "open" }); + if (h.namesOnly) + table(ctx, [{ name: "名称", color: C.variable }], h.returns.map((name) => [name])); + else + table(ctx, [{ name: "名称", color: C.variable }, { name: "是什么", mono: false }], h.returns); + } +} + +const CALLBACK = "回调"; +const PROP_COLS = [ + { name: "名称", color: C.variable }, + { name: "类型", color: C.type }, + { name: "默认值" }, + { name: "必填", mono: false }, +]; + +/** 构造参数表的一行:名称(回调带小标签)| 类型 | 默认值 | 必填。 */ +function propRow(ctx, name, type, def, required) { + const callback = /=>/.test(type); + const nameCell = { + est: name, + extra: callback ? tagWidth(CALLBACK) + 6 : 0, + draw: (frame) => { + const line = row(frame, "Name", { gap: 6, height: 20, width: "fit_content" }); + text(line, name, { size: 12.5, mono: true, color: C.variable }); + if (callback) + tag(line, CALLBACK, C.component, ctx.bg); + }, + }; + return [nameCell, cx(type), def === "—" ? px("—", C.desc) : cx(def), px(required, required === "—" ? C.desc : C.storage)]; +} + +/** 说明(组件上面的 JSDoc,Markdown 段落,注释色),几段之间空 6px。 */ +function docProp(ctx, paragraphs) { + prop(ctx, "说明", (frame, w) => { + const body = col(frame, "Doc", { gap: 6 }); + for (const p of paragraphs) text(body, p, { color: C.comment, maxW: w, size: 13 }); + }); +} + +/** + * React 组件卡片:名称(组件色,后面跟导出方式、客户端组件这些小标签)/ 说明(有才写)/ 构造参数。 + * `props` 每项是 `[名称, 类型, 默认值, 必填]`,一个都没有时构造参数写「无」;属性类型是一个名字时给 `from`。 + */ +function componentCard(o) { + return (parent, w) => { + const ctx = card(parent, K.component, w, { name: o.name, fold: o.fold }); + nameProp(ctx, o.name, C.component, o.tags); + if (o.doc) + docProp(ctx, o.doc); + if (o.props.length === 0) { + prop(ctx, "构造参数", px("无", C.desc), { mono: false }); + return; + } + prop(ctx, "构造参数", [seg(`${o.props.length} 个`, C.desc)].concat(o.from ? [seg(" · 类型 ", C.desc), link(o.from, C.type)] : []), { fold: "open" }); + table(ctx, PROP_COLS, o.props.map((r) => propRow(ctx, r[0], r[1], r[2], r[3]))); + }; +} + +// ─── 编辑器和预览对齐 ──────────────────────────────────────────────────────── + +/** + * 一份样例文件:`project` 写在标题栏,`file`、`crumbs`(面包屑)、`tree`(侧栏的文件树),`count` 是筛选栏的块数, + * `source` 是源码,一行一个字符串。返回的 `code` 是着色好的各行。 + */ +function sampleFile(o) { + return Object.assign({}, o, { code: highlight(o.source) }); +} + +/** + * 一段源码配一张卡片:左边是 `doc` 的第 `from`–`to` 行,右边是这段的卡片,两边顶端对齐,较矮的一边下面留空。 + * 卡片内容比卡片顶端低 8px,源码也往下让 8px,第一行字和卡片第一行属性在同一高度。 + * `depth` 是子块的层数,每层左边一条竖线;`last` 是这一层的最后一张,竖线到卡片底边为止,源码比卡片长也不往下伸。 + */ +function band(parent, doc, b) { + const line = row(parent, "Lines " + b.from + "–" + b.to, { align: "start" }); + const code = col(line, "Code", { width: CODE_W, height: "fill_container", padding: [8, 0, 0, 0], clip: true }); + for (let n = b.from; n <= b.to; n++) { + const src = doc.code[n - 1]; + const holder = row(code, "Line " + n, { height: 20 }); + const number = row(holder, "Number", { width: 44, height: 20, justify: "end" }); + text(number, String(n), { mono: true, color: C.dim }); + spacer(holder, "Margin", 26 + src.indent * MONO_CHAR, 20); + text(holder, src.segs, { mono: true }); + } + I(line, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); + const depth = b.depth || 0; + const right = col(line, "Preview", { height: "fill_container", padding: [0, PREVIEW_PAD, b.last ? 8 : 0, PREVIEW_PAD] }); + const level = row(right, "Level", { height: b.last ? "fit_content" : "fill_container", gap: 8, align: "start" }); + for (let d = 0; d < depth; d++) { + const guide = col(level, "Guide", { width: 12, height: "fill_container", align: "center" }); + I(guide, { type: "rectangle", name: "Line", width: 1, height: "fill_container", fill: solid(C.guide) }); + } + if (b.draw) { + const cards = col(level, "Cards", { padding: [0, 0, b.last ? 0 : 8, 0] }); + b.draw(cards, PREVIEW_W - PREVIEW_PAD * 2 - depth * 20); + } +} + +// ─── VS Code 窗口 ──────────────────────────────────────────────────────────── + +function activity(parent) { + const bar = col(parent, "Activity bar", { width: 48, fill: C.side }); + const icons = ["files", "search", "git-branch", "play", "monitor", "blocks", "rocket", "book-open-text"]; + for (const name of icons) { + const on = name === "book-open-text"; + const cell = row(bar, "Item / " + name, { width: 48, height: 42, justify: on ? "start" : "center", gap: on ? 10 : 0 }); + if (on) + I(cell, { type: "rectangle", name: "Active bar", width: 2, height: 42, fill: solid(C.focus) }); + icon(cell, name, on ? C.activityOn : C.activityIdle, 22); + } +} + +function sidebar(parent, doc) { + const selected = doc.file; + const side = col(parent, "Sidebar", { width: SIDE_W, fill: C.side }); + const header = row(side, "Header", { height: 34, padding: [0, 12, 0, 16], justify: "space_between" }); + text(header, "代码阅读", { size: 11 }); + const actions = row(header, "Actions", { width: "fit_content", gap: 10 }); + for (const name of ["git-pull-request", "file-plus", "refresh-cw"]) icon(actions, name, C.fg, 14); + const list = col(side, "Tree", { padding: [4, 0, 8, 0] }); + for (const item of doc.tree) { + const line = row(list, item.name, { + height: 26, + gap: 6, + padding: [0, 8, 0, 10 + item.depth * 14], + fill: item.name === selected ? C.selection : null, + }); + if (item.kind === "folder") { + icon(line, item.open ? "chevron-down" : "chevron-right", C.fg, 14); + icon(line, "folder", C.folder, 15); + } + else { + spacer(line, "Twisty", 14, 14); + icon(line, "atom", C.tsx, 14); + } + text(line, item.name, { color: item.name === selected ? C.fgStrong : C.fg }); + } +} + +/** 一组编辑器的标签栏:右边那组(代码阅读预览)有焦点,标签顶上一条聚焦色,右边是编辑 / 预览切换。 */ +function editorTitle(parent, doc, focused) { + const bar = row(parent, "Editor title", { height: 36, justify: "space_between", fill: C.side }); + const tab = col(bar, "Tab", { width: 140, height: "fill_container", fill: C.editor }); + I(tab, { type: "rectangle", name: "Active", width: "fill_container", height: 2, fill: solid(focused ? C.focus : C.editor) }); + const label = row(tab, "Tab label", { height: "fill_container", padding: [0, 12], gap: 6 }); + icon(label, "atom", C.tsx, 14); + text(label, doc.file, { color: focused ? C.fgStrong : C.fg }); + if (!focused) + return; + const mode = row(bar, "Mode", { width: "fit_content", padding: [2, 2], gap: 2, radius: 5, fill: C.field, stroke: C.borderStrong }); + const edit = row(mode, "Seg / 编辑", { width: "fit_content", padding: [2, 8], gap: 4, radius: 3 }); + icon(edit, "pencil", C.desc, 13); + text(edit, "编辑", { size: 12, color: C.desc }); + const preview = row(mode, "Seg / 预览", { width: "fit_content", padding: [2, 8], gap: 4, radius: 3, fill: C.toggleOn }); + icon(preview, "eye", C.fgStrong, 13); + text(preview, "预览", { size: 12, color: C.fgStrong }); + spacer(bar, "Pad", 8, 8); +} + +function crumb(parent, doc) { + const line = row(parent, "Breadcrumb", { padding: [6, 16], gap: 6 }); + doc.crumbs.forEach((part, index) => { + if (index) + text(line, "/", { size: 12, color: C.dim }); + text(line, part, { size: 12, color: index === doc.crumbs.length - 1 ? C.fg : C.desc }); + }); +} + +function filters(parent, chips, count) { + const bar = row(parent, "Filter", { height: 36, padding: [0, 16], gap: 8 }); + text(bar, "筛选", { size: 12, color: C.desc }); + for (const chip of chips) { + const item = row(bar, "Chip / " + chip, { width: "fit_content", height: 24, padding: [0, 8], gap: 4, radius: 4, fill: C.input }); + text(item, chip, { size: 12 }); + icon(item, "chevron-down", C.desc, 12); + } + spacer(bar, "Spacer", "fill_container", 8); + text(bar, count + " 块", { size: 12, color: C.desc }); +} + +/** 两组编辑器的头:左边源码的标签栏、面包屑,下面让出筛选栏那么高;右边预览的标签栏、面包屑、筛选栏。 */ +function groupHeads(parent, doc) { + const line = row(parent, "Group heads", { align: "start" }); + const left = col(line, "Editor group 1", { width: CODE_W }); + editorTitle(left, doc, false); + crumb(left, doc); + spacer(left, "Filter room", "fill_container", 36); + I(line, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); + const right = col(line, "Editor group 2", {}); + editorTitle(right, doc, true); + crumb(right, doc); + filters(right, ["种类", "访问级别"], doc.count); +} + +function status(parent) { + const bar = row(parent, "Status", { height: 26, padding: [0, 12], justify: "space_between", fill: C.side }); + const branch = row(bar, "Branch", { width: "fit_content", gap: 4 }); + icon(branch, "git-branch", C.fg, 13); + text(branch, "master", { size: 12 }); + const right = row(bar, "Right", { width: "fit_content", gap: 16 }); + text(right, "代码阅读", { size: 12 }); + text(right, "TypeScript JSX", { size: 12 }); +} + +/** + * VS Code 窗口:标题栏、活动栏、侧栏、编辑器(左源码、右预览,一段段对齐)、状态栏。 + * `bands` 每项是 `{from, to, depth?, last?, draw?}`,见 [band]。 + */ +function windowOf(name, x, doc, bands) { + const win = col(null, name, { x, width: WIN_W, fill: C.side }); + const title = row(win, "Title bar", { height: 36, padding: [0, 12], justify: "space_between" }); + const lights = row(title, "Lights", { width: "fit_content", gap: 8 }); + for (const color of ["#ff5f57", "#febc2e", "#28c840"]) I(lights, { type: "ellipse", width: 12, height: 12, fill: solid(color) }); + text(title, doc.project + " — " + doc.file, { size: 12, color: C.desc }); + spacer(title, "Balance", 52, 12); + const body = row(win, "Body", { align: "start", fill: C.side }); + activity(body); + sidebar(body, doc); + const editor = col(body, "Editor", { fill: C.editor }); + groupHeads(editor, doc); + for (const b of bands) band(editor, doc, b); + const end = row(editor, "End", { height: 28 }); + spacer(end, "Code", CODE_W, 28); + I(end, { type: "rectangle", name: "Sash", width: 1, height: "fill_container", fill: solid(C.border) }); + status(win); + return win; +} diff --git a/docs/prototype/code-reader/openpencil/react-state.js b/docs/prototype/code-reader/openpencil/react-state.js new file mode 100644 index 0000000..cd465a6 --- /dev/null +++ b/docs/prototype/code-reader/openpencil/react-state.js @@ -0,0 +1,250 @@ +// 代码阅读 React 状态卡片:useState 不再写成「钩子 useState」,而是一张「状态」卡片,讲清楚五件事: +// 它是普通变量也是 React 状态(左边变量、状态两个图标);它是数组解构(名称照源码写出解构,展开是每一项); +// 它来自 React 内置的 useState(悬停说明);状态类型;默认值。修改函数在哪调用,用右上角的调用树查。 +// 画板一照抄 luffy-agent-platform 的 frontend/client-nextjs/src/app/desktop/login/page.tsx 第 1–37 行, +// 画板二是手写的三行,讲没标类型、函数形式的默认值、只取当前值三种写法。 +// 窗口、对齐、别的卡片的画法在同目录 react-shared.js,接在它后面跑:`cat react-shared.js react-state.js | op design - --script`。 + +// ─── 样例源码 ──────────────────────────────────────────────────────────────── + +const LOGIN = sampleFile({ + project: "client-nextjs", + file: "page.tsx", + crumbs: ["src", "app", "desktop", "login", "page.tsx"], + tree: [ + { kind: "folder", name: "app", open: true, depth: 0 }, + { kind: "folder", name: "desktop", open: true, depth: 1 }, + { kind: "folder", name: "login", open: true, depth: 2 }, + { kind: "file", name: "page.test.tsx", depth: 3 }, + { kind: "file", name: "page.tsx", depth: 3 }, + { kind: "file", name: "layout.test.tsx", depth: 2 }, + { kind: "file", name: "layout.tsx", depth: 2 }, + { kind: "folder", name: "desktop-lab", open: false, depth: 1 }, + { kind: "folder", name: "home", open: false, depth: 1 }, + ], + count: 7, + source: [ + "\"use client\";", + "", + "import { useState } from \"react\";", + "import { useRouter, useSearchParams } from \"next/navigation\";", + "", + "import { LoginPanel } from \"@/components/auth/login/LoginPanel\";", + "import type { LoginTab, PasswordView } from \"@/components/auth/login/types\";", + "import { DESKTOP_ENTRY } from \"@/lib/desktop-shell\";", + "import { isSafeReturnTo } from \"@/lib/safe-redirect\";", + "", + "/**", + " * 桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。", + " *", + " * ![桌面登录](docs/prototype/desktop-login/openpencil/exports/desktop-login.png)", + " */", + "const DesktopLoginPage = () => {", + " const router = useRouter();", + " const from = useSearchParams().get(\"from\");", + " const [activeTab, setActiveTab] = useState(\"sms\");", + " const [passwordView, setPasswordView] = useState(\"login\");", + "", + " return (", + "
", + "
", + " router.replace(from && isSafeReturnTo(from) ? from : DESKTOP_ENTRY)}", + " />", + "
", + "
", + " );", + "};", + "", + "export default DesktopLoginPage;", + ], +}); + +const VARIANTS = sampleFile({ + project: "web", + file: "examples.tsx", + crumbs: ["src", "examples.tsx"], + tree: [ + { kind: "folder", name: "src", open: true, depth: 0 }, + { kind: "file", name: "examples.tsx", depth: 1 }, + ], + count: 3, + source: [ + "const [open, setOpen] = useState(false)", + "const [items, setItems] = useState(() => loadItems())", + "const [count] = useState(0)", + ], +}); + +// ─── 状态卡片 ──────────────────────────────────────────────────────────────── + +// 种类「状态」:描边、淡底、两个图标都用变量色;左边先是变量卡片的图标,再是状态图标,悬停才出名字 +const STATE = { label: "状态", color: "#9cdcfe", icon: "variable" }; +const FROM_TIP = "React 内置钩子"; + +/** + * 「来自」那一行悬停时的气泡在卡片里的位置:在 `useState` 几个字正上方居中、隔 6px。 + * 内容区从卡片内边距(上 8、左 8)、折叠箭头一列(14)、两个图标(42)各隔 10px 往后排; + * 「来自」前面是名称一行和解构表(表头一行、每项一行,各带 1px 分隔线、上下各 2px 留白)。 + */ +function fromBubble(labelW, items) { + const tableH = 2 + 24 + items * (24 + 1) + 2; + const rowTop = 8 + 20 + 3 + tableH + 3; + const valueX = 8 + 14 + 10 + 42 + 10 + labelW + 12; + const center = valueX + widthOf("useState", 13, true) / 1.04 / 2; + return { x: center - tooltipWidth(FROM_TIP) / 2, y: rowTop - 6 - 22 }; +} + +/** + * 一处 useState:名称照源码写出解构(后面灰字「数组解构」,展开是「第几项 | 名称 | 是什么」)/ 来自 / 状态类型 / 默认值。 + * `names` 是解构出的名字,第二个是修改函数;有修改函数时右上角有调用树,`calls` 是它被调用几次。 + * `type` 是状态类型(没写时「未标注」),`initial` 是默认值的着色段。 + * `bubble` 画出「来自」的悬停气泡:卡片和气泡放进一个自由摆放的框,气泡在前,才画在卡片上层。 + */ +function stateCard(s) { + return (parent, w) => { + const icons = [ + { name: "variable", color: STATE.color, tip: "变量" }, + { name: "toggle-right", color: STATE.color, tip: "React 状态" }, + ]; + let holder = parent; + let place = {}; + if (s.bubble) { + holder = box(parent, "Hover / 来自", { layout: "none", width: w, height: "fit_content" }); + const spot = fromBubble(76, s.names.length); + tooltip(holder, FROM_TIP, spot.x, spot.y); + place = { x: 0, y: 0 }; + } + const ctx = card(holder, STATE, w, Object.assign({ name: s.names[0], icons, calls: s.names.length > 1 ? s.calls : null }, place)); + prop(ctx, "名称", (frame) => { + const line = row(frame, "Destructure", { gap: 8, height: 20, width: "fit_content" }); + const parts = [seg("[", C.fg)]; + s.names.forEach((name, i) => { + if (i > 0) + parts.push(seg(", ", C.fg)); + parts.push(seg(name, i === 0 ? C.variable : C.fn, { w: 600 })); + }); + parts.push(seg("]", C.fg)); + text(line, parts, { mono: true }); + text(line, "数组解构", { size: 12.5, color: C.desc }); + }, { fold: "open" }); + table(ctx, [{ name: "第几项", mono: false }, { name: "名称", color: C.variable }, { name: "是什么", mono: false }], + s.names.map((name, i) => [indexCell(i + 1), px(name, i === 0 ? C.variable : C.fn), i === 0 ? "当前值" : "修改函数"])); + prop(ctx, "来自", px("useState", C.fn)); + prop(ctx, "状态类型", s.type || px("未标注", C.desc), { mono: Boolean(s.type) }); + prop(ctx, "默认值", s.initial); + }; +} + +/** 「第几项」一格:只有一个数字,宽度定死,按内容长会被导出时挤小。 */ +function indexCell(n) { + return { est: String(n), draw: (frame) => text(frame, String(n), { size: 12.5, color: C.desc, lh: 20, fixedW: 12 }) }; +} + +// ─── 画板一:登录页 ────────────────────────────────────────────────────────── + +const LOGIN_PAGE = componentCard({ + name: "DesktopLoginPage", + fold: "open", + tags: [DEFAULT_EXPORT, CLIENT], + doc: ["桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。"], + props: [], +}); + +function routerHook(parent, w) { + hookCall(parent, w, { + lib: "next/navigation", + name: "useRouter", + target: "router", + returns: [["router", "路由器,用于页面跳转"]], + }); +} + +function searchParamsHook(parent, w) { + hookCall(parent, w, { + lib: "next/navigation", + name: "useSearchParams", + target: "from", + returns: [["from", [seg("URL 查询参数里 ", C.fg), seg("\"from\"", C.string), seg(" 的值", C.fg)]]], + }); +} + +const ACTIVE_TAB = stateCard({ + names: ["activeTab", "setActiveTab"], + calls: 1, + type: [link("LoginTab", C.type)], + initial: px("\"sms\"", C.string), + bubble: true, +}); + +const PASSWORD_VIEW = stateCard({ + names: ["passwordView", "setPasswordView"], + calls: 1, + type: [link("PasswordView", C.type)], + initial: px("\"login\"", C.string), +}); + +// DesktopLoginPage 返回的 JSX:className 收成「样式 N 个类」,回调照译 +const LOGIN_OUTLINE = [ + { + line: [el("main"), cls("样式 4 个类")], + kids: [ + { + line: [el("div"), cls("样式 5 个类")], + kids: [ + { + line: [ + el("LoginPanel"), + at("activeTab", [link("activeTab", C.variable)]), + at("onTabChange", [link("setActiveTab", C.fn)]), + at("passwordView", [link("passwordView", C.variable)]), + at("onPasswordView", [link("setPasswordView", C.fn)]), + at("onSuccess", cx("() => router.replace(如果 from 并且 isSafeReturnTo(from) 则 from 否则 DESKTOP_ENTRY)")), + ], + }, + ], + }, + ], + }, +]; + +windowOf("Prototype / React 状态 · 登录页", 0, LOGIN, [ + { from: 1, to: 2 }, + { from: 3, to: 3, draw: importCard("\"react\"", 1) }, + { from: 4, to: 5, draw: importCard("\"next/navigation\"", 2) }, + { from: 6, to: 6, draw: importCard("\"@/components/auth/login/LoginPanel\"", 1) }, + { from: 7, to: 7, draw: importCard("\"@/components/auth/login/types\"", 2, true) }, + { from: 8, to: 8, draw: importCard("\"@/lib/desktop-shell\"", 1) }, + { from: 9, to: 10, draw: importCard("\"@/lib/safe-redirect\"", 1) }, + { from: 11, to: 16, draw: LOGIN_PAGE }, + { from: 17, to: 17, depth: 1, draw: routerHook }, + { from: 18, to: 18, depth: 1, draw: searchParamsHook }, + { from: 19, to: 19, depth: 1, draw: ACTIVE_TAB }, + { from: 20, to: 21, depth: 1, draw: PASSWORD_VIEW }, + { from: 22, to: 34, depth: 1, last: true, draw: renderCard(LOGIN_OUTLINE, "DesktopLoginPage") }, + { from: 35, to: 37 }, +]); + +// ─── 画板二:其他写法 ──────────────────────────────────────────────────────── + +windowOf("Prototype / React 状态 · 其他写法", WIN_W + BOARD_GAP, VARIANTS, [ + { + from: 1, + to: 1, + draw: stateCard({ names: ["open", "setOpen"], calls: 0, initial: cx("假") }), + }, + { + from: 2, + to: 2, + draw: stateCard({ names: ["items", "setItems"], calls: 0, type: [link("Item", C.type), seg("[]", C.fg)], initial: [seg("首次渲染时调用 ", C.fg)].concat(cx("loadItems()")) }), + }, + { + from: 3, + to: 3, + draw: stateCard({ names: ["count"], initial: cx("0") }), + }, +]); diff --git a/docs/prototype/code-reader/openpencil/react-state.op b/docs/prototype/code-reader/openpencil/react-state.op new file mode 100644 index 0000000..c27e02c --- /dev/null +++ b/docs/prototype/code-reader/openpencil/react-state.op @@ -0,0 +1,19184 @@ +{ + "version": "0.8.4", + "name": "OpenPencil CLI Session", + "children": [ + { + "type": "frame", + "id": "n1", + "name": "Prototype / React 状态 · 登录页", + "x": 0.0, + "y": 0.0, + "width": 1700.0, + "height": 62.0, + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n2", + "name": "Title bar", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n3", + "name": "Lights", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "ellipse", + "id": "n4", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#ff5f57" + } + ] + }, + { + "type": "ellipse", + "id": "n5", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#febc2e" + } + ] + }, + { + "type": "ellipse", + "id": "n6", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#28c840" + } + ] + } + ] + }, + { + "type": "text", + "id": "n7", + "name": "client-nextjs — page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "client-nextjs — page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n8", + "name": "Balance", + "width": 52.0, + "height": 12.0, + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n9", + "name": "Body", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n10", + "name": "Activity bar", + "width": 48.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n11", + "name": "Item / files", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n12", + "name": "files", + "iconFontName": "files", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n13", + "name": "Item / search", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n14", + "name": "search", + "iconFontName": "search", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n15", + "name": "Item / git-branch", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n16", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n17", + "name": "Item / play", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n18", + "name": "play", + "iconFontName": "play", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n19", + "name": "Item / monitor", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n20", + "name": "monitor", + "iconFontName": "monitor", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n21", + "name": "Item / blocks", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n22", + "name": "blocks", + "iconFontName": "blocks", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n23", + "name": "Item / rocket", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n24", + "name": "rocket", + "iconFontName": "rocket", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n25", + "name": "Item / book-open-text", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 10.0, + "justifyContent": "start", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n26", + "name": "Active bar", + "width": 2.0, + "height": 42.0, + "fill": [ + { + "type": "solid", + "color": "#0078d4" + } + ], + "children": [] + }, + { + "type": "icon_font", + "id": "n27", + "name": "book-open-text", + "iconFontName": "book-open-text", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#d7d7d7" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n28", + "name": "Sidebar", + "width": 250.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n29", + "name": "Header", + "width": "fill_container", + "height": 34.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0, + 0.0, + 16.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n30", + "name": "代码阅读", + "width": "fit_content", + "height": "fit_content", + "content": "代码阅读", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 400, + "lineHeight": 1.818181818181818, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "frame", + "id": "n31", + "name": "Actions", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n32", + "name": "git-pull-request", + "iconFontName": "git-pull-request", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n33", + "name": "file-plus", + "iconFontName": "file-plus", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n34", + "name": "refresh-cw", + "iconFontName": "refresh-cw", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n35", + "name": "Tree", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 4.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n36", + "name": "app", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 10.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n37", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n38", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n39", + "name": "app", + "width": "fit_content", + "height": "fit_content", + "content": "app", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n40", + "name": "desktop", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 24.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n41", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n42", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n43", + "name": "desktop", + "width": "fit_content", + "height": "fit_content", + "content": "desktop", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n44", + "name": "login", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 38.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n45", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n46", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n47", + "name": "login", + "width": "fit_content", + "height": "fit_content", + "content": "login", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n48", + "name": "page.test.tsx", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 52.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n49", + "name": "Twisty", + "width": 14.0, + "height": 14.0, + "children": [] + }, + { + "type": "icon_font", + "id": "n50", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n51", + "name": "page.test.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.test.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n52", + "name": "page.tsx", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 52.0 + ], + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#04395e" + } + ], + "children": [ + { + "type": "frame", + "id": "n53", + "name": "Twisty", + "width": 14.0, + "height": 14.0, + "children": [] + }, + { + "type": "icon_font", + "id": "n54", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n55", + "name": "page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n56", + "name": "layout.test.tsx", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 38.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n57", + "name": "Twisty", + "width": 14.0, + "height": 14.0, + "children": [] + }, + { + "type": "icon_font", + "id": "n58", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n59", + "name": "layout.test.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "layout.test.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n60", + "name": "layout.tsx", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 38.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n61", + "name": "Twisty", + "width": 14.0, + "height": 14.0, + "children": [] + }, + { + "type": "icon_font", + "id": "n62", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n63", + "name": "layout.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "layout.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n64", + "name": "desktop-lab", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 24.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n65", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n66", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n67", + "name": "desktop-lab", + "width": "fit_content", + "height": "fit_content", + "content": "desktop-lab", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n68", + "name": "home", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 24.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n69", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n70", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n71", + "name": "home", + "width": "fit_content", + "height": "fit_content", + "content": "home", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n72", + "name": "Editor", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "frame", + "id": "n73", + "name": "Group heads", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n74", + "name": "Editor group 1", + "width": 600.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n75", + "name": "Editor title", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n76", + "name": "Tab", + "width": 140.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "rectangle", + "id": "n77", + "name": "Active", + "width": "fill_container", + "height": 2.0, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n78", + "name": "Tab label", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 12.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n79", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n80", + "name": "page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n81", + "name": "Breadcrumb", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 6.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n82", + "name": "src", + "width": "fit_content", + "height": "fit_content", + "content": "src", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n83", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n84", + "name": "app", + "width": "fit_content", + "height": "fit_content", + "content": "app", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n85", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n86", + "name": "desktop", + "width": "fit_content", + "height": "fit_content", + "content": "desktop", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n87", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n88", + "name": "login", + "width": "fit_content", + "height": "fit_content", + "content": "login", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n89", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n90", + "name": "page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n91", + "name": "Filter room", + "width": "fill_container", + "height": 36.0, + "children": [] + } + ] + }, + { + "type": "rectangle", + "id": "n92", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n93", + "name": "Editor group 2", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n94", + "name": "Editor title", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n95", + "name": "Tab", + "width": 140.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "rectangle", + "id": "n96", + "name": "Active", + "width": "fill_container", + "height": 2.0, + "fill": [ + { + "type": "solid", + "color": "#0078d4" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n97", + "name": "Tab label", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 12.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n98", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n99", + "name": "page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n100", + "name": "Mode", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 2.0, + "padding": [ + 2.0, + 2.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 5.0, + "fill": [ + { + "type": "solid", + "color": "#111111" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n101", + "name": "Seg / 编辑", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 2.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 3.0, + "children": [ + { + "type": "icon_font", + "id": "n102", + "name": "pencil", + "iconFontName": "pencil", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n103", + "name": "编辑", + "width": "fit_content", + "height": "fit_content", + "content": "编辑", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n104", + "name": "Seg / 预览", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 2.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 3.0, + "fill": [ + { + "type": "solid", + "color": "#37373d" + } + ], + "children": [ + { + "type": "icon_font", + "id": "n105", + "name": "eye", + "iconFontName": "eye", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + }, + { + "type": "text", + "id": "n106", + "name": "预览", + "width": "fit_content", + "height": "fit_content", + "content": "预览", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n107", + "name": "Pad", + "width": 8.0, + "height": 8.0, + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n108", + "name": "Breadcrumb", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 6.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n109", + "name": "src", + "width": "fit_content", + "height": "fit_content", + "content": "src", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n110", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n111", + "name": "app", + "width": "fit_content", + "height": "fit_content", + "content": "app", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n112", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n113", + "name": "desktop", + "width": "fit_content", + "height": "fit_content", + "content": "desktop", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n114", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n115", + "name": "login", + "width": "fit_content", + "height": "fit_content", + "content": "login", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n116", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n117", + "name": "page.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "page.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n118", + "name": "Filter", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 8.0, + "padding": [ + 0.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n119", + "name": "筛选", + "width": "fit_content", + "height": "fit_content", + "content": "筛选", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n120", + "name": "Chip / 种类", + "width": "fit_content", + "height": 24.0, + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 0.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "children": [ + { + "type": "text", + "id": "n121", + "name": "种类", + "width": "fit_content", + "height": "fit_content", + "content": "种类", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n122", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n123", + "name": "Chip / 访问级别", + "width": "fit_content", + "height": 24.0, + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 0.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "children": [ + { + "type": "text", + "id": "n124", + "name": "访问级别", + "width": "fit_content", + "height": "fit_content", + "content": "访问级别", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n125", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n126", + "name": "Spacer", + "width": "fill_container", + "height": 8.0, + "children": [] + }, + { + "type": "text", + "id": "n127", + "name": "7 块", + "width": "fit_content", + "height": "fit_content", + "content": "7 块", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n128", + "name": "Lines 1–2", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n129", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n130", + "name": "Line 1", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n131", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n132", + "name": "1", + "width": "fit_content", + "height": "fit_content", + "content": "1", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n133", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n134", + "name": "\"use client\";", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "\"use client\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n135", + "name": "Line 2", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n136", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n137", + "name": "2", + "width": "fit_content", + "height": "fit_content", + "content": "2", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n138", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n139", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n140", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n141", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n142", + "name": "Lines 3–3", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n143", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n144", + "name": "Line 3", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n145", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n146", + "name": "3", + "width": "fit_content", + "height": "fit_content", + "content": "3", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n147", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n148", + "name": "import { useState } from \"react\";", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "useState", + "fill": "#9cdcfe" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"react\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n149", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n150", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n151", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n152", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n153", + "name": "导入 / \"react\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n154", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n155", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n156", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n157", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n158", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n159", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n160", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n161", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n162", + "name": "\"react\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"react\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n163", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n164", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n165", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n166", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n167", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n168", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n169", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n170", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n171", + "name": "Lines 4–5", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n172", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n173", + "name": "Line 4", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n174", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n175", + "name": "4", + "width": "fit_content", + "height": "fit_content", + "content": "4", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n176", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n177", + "name": "import { useRouter, useSearchParams } fr", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "useRouter", + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#d4d4d4" + }, + { + "text": "useSearchParams", + "fill": "#9cdcfe" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"next/navigation\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n178", + "name": "Line 5", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n179", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n180", + "name": "5", + "width": "fit_content", + "height": "fit_content", + "content": "5", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n181", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n182", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n183", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n184", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n185", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n186", + "name": "导入 / \"next/navigation\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n187", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n188", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n189", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n190", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n191", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n192", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n193", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n194", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n195", + "name": "\"next/navigation\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"next/navigation\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n196", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n197", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n198", + "name": "2 个", + "width": "fit_content", + "height": "fit_content", + "content": "2 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n199", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n200", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n201", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n202", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n203", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n204", + "name": "Lines 6–6", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n205", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n206", + "name": "Line 6", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n207", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n208", + "name": "6", + "width": "fit_content", + "height": "fit_content", + "content": "6", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n209", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n210", + "name": "import { LoginPanel } from \"@/components", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "LoginPanel", + "fill": "#4ec9b0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"@/components/auth/login/LoginPanel\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n211", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n212", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n213", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n214", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n215", + "name": "导入 / \"@/components/auth/login/LoginPanel\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n216", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n217", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n218", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n219", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n220", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n221", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n222", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n223", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n224", + "name": "\"@/components/auth/login/LoginPanel\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"@/components/auth/login/LoginPanel\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n225", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n226", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n227", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n228", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n229", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n230", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n231", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n232", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n233", + "name": "Lines 7–7", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n234", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n235", + "name": "Line 7", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n236", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n237", + "name": "7", + "width": "fit_content", + "height": "fit_content", + "content": "7", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n238", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n239", + "name": "import type { LoginTab, PasswordView } f", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "type", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "LoginTab", + "fill": "#4ec9b0" + }, + { + "text": ", ", + "fill": "#d4d4d4" + }, + { + "text": "PasswordView", + "fill": "#4ec9b0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"@/components/auth/login/types\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n240", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n241", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n242", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n243", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n244", + "name": "导入 / \"@/components/auth/login/types\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n245", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n246", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n247", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n248", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n249", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n250", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n251", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n252", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n253", + "name": "\"@/components/auth/login/types\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"@/components/auth/login/types\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n254", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n255", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n256", + "name": "2 个", + "width": "fit_content", + "height": "fit_content", + "content": "2 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n257", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n258", + "name": "仅类型", + "width": "fit_content", + "height": "fit_content", + "content": "仅类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n259", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n260", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n261", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n262", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n263", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n264", + "name": "Lines 8–8", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n265", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n266", + "name": "Line 8", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n267", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n268", + "name": "8", + "width": "fit_content", + "height": "fit_content", + "content": "8", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n269", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n270", + "name": "import { DESKTOP_ENTRY } from \"@/lib/des", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "DESKTOP_ENTRY", + "fill": "#4fc1ff" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"@/lib/desktop-shell\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n271", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n272", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n273", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n274", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n275", + "name": "导入 / \"@/lib/desktop-shell\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n276", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n277", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n278", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n279", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n280", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n281", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n282", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n283", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n284", + "name": "\"@/lib/desktop-shell\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"@/lib/desktop-shell\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n285", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n286", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n287", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n288", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n289", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n290", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n291", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n292", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n293", + "name": "Lines 9–10", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n294", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n295", + "name": "Line 9", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n296", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n297", + "name": "9", + "width": "fit_content", + "height": "fit_content", + "content": "9", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n298", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n299", + "name": "import { isSafeReturnTo } from \"@/lib/sa", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "import", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "isSafeReturnTo", + "fill": "#9cdcfe" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "\"@/lib/safe-redirect\"", + "fill": "#ce9178" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n300", + "name": "Line 10", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n301", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n302", + "name": "10", + "width": "fit_content", + "height": "fit_content", + "content": "10", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n303", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n304", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n305", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n306", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n307", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n308", + "name": "导入 / \"@/lib/safe-redirect\"", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2b262a" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#594357" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n309", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n310", + "name": "chevron-right", + "iconFontName": "chevron-right", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n311", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n312", + "name": "Concept / 导入", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n313", + "name": "import", + "iconFontName": "import", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n314", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n315", + "name": "Summary", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n316", + "name": "来源", + "width": "fit_content", + "height": "fit_content", + "content": "来源", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n317", + "name": "\"@/lib/safe-redirect\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"@/lib/safe-redirect\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + }, + { + "type": "text", + "id": "n318", + "name": "·", + "width": "fit_content", + "height": "fit_content", + "content": "·", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n319", + "name": "导入项", + "width": "fit_content", + "height": "fit_content", + "content": "导入项", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n320", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n321", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n322", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n323", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n324", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n325", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n326", + "name": "Lines 11–16", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n327", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n328", + "name": "Line 11", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n329", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n330", + "name": "11", + "width": "fit_content", + "height": "fit_content", + "content": "11", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n331", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n332", + "name": "/**", + "width": "fit_content", + "height": "fit_content", + "content": "/**", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n333", + "name": "Line 12", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n334", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n335", + "name": "12", + "width": "fit_content", + "height": "fit_content", + "content": "12", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n336", + "name": "Margin", + "width": 33.83, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n337", + "name": "* 桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。", + "width": "fit_content", + "height": "fit_content", + "content": "* 桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n338", + "name": "Line 13", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n339", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n340", + "name": "13", + "width": "fit_content", + "height": "fit_content", + "content": "13", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n341", + "name": "Margin", + "width": 33.83, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n342", + "name": "*", + "width": "fit_content", + "height": "fit_content", + "content": "*", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n343", + "name": "Line 14", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n344", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n345", + "name": "14", + "width": "fit_content", + "height": "fit_content", + "content": "14", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n346", + "name": "Margin", + "width": 33.83, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n347", + "name": "* ![桌面登录](docs/prototype/desktop-login/o", + "width": "fit_content", + "height": "fit_content", + "content": "* ![桌面登录](docs/prototype/desktop-login/openpencil/exports/desktop-login.png)", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n348", + "name": "Line 15", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n349", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n350", + "name": "15", + "width": "fit_content", + "height": "fit_content", + "content": "15", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n351", + "name": "Margin", + "width": 33.83, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n352", + "name": "*/", + "width": "fit_content", + "height": "fit_content", + "content": "*/", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n353", + "name": "Line 16", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n354", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n355", + "name": "16", + "width": "fit_content", + "height": "fit_content", + "content": "16", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n356", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n357", + "name": "const DesktopLoginPage = () => {", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "DesktopLoginPage", + "fill": "#4ec9b0" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "()", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "=>", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#ffd700" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n358", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n359", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n360", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n361", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n362", + "name": "React 组件 / DesktopLoginPage", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#242c2e" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#36606c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n363", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n364", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n365", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n366", + "name": "Concept / React 组件", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n367", + "name": "atom", + "iconFontName": "atom", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#61dafb" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n368", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n369", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n370", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n371", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n372", + "name": "Value", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 6.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n373", + "name": "DesktopLoginPage", + "width": "fit_content", + "height": "fit_content", + "content": "DesktopLoginPage", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 600, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#61dafb" + } + ] + }, + { + "type": "frame", + "id": "n374", + "name": "Tag / 默认导出", + "width": "fit_content", + "height": 18.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 5.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#3b3942" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#6c5570" + } + ] + }, + "children": [ + { + "type": "text", + "id": "n375", + "name": "默认导出", + "width": "fit_content", + "height": "fit_content", + "content": "默认导出", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 500, + "lineHeight": 1.4545454545454546, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#c586c0" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n376", + "name": "Tag / 客户端组件", + "width": "fit_content", + "height": 18.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 5.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#2d444b" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3f7a8a" + } + ] + }, + "children": [ + { + "type": "text", + "id": "n377", + "name": "客户端组件", + "width": "fit_content", + "height": "fit_content", + "content": "客户端组件", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 500, + "lineHeight": 1.4545454545454546, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#61dafb" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n378", + "name": "Prop / 说明", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n379", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n380", + "name": "说明", + "width": "fit_content", + "height": "fit_content", + "content": "说明", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n381", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n382", + "name": "Doc", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 6.0, + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n383", + "name": "桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。", + "width": "fit_content", + "height": "fit_content", + "content": "桌面壳的唯一登录面:没有首页、没有弹窗、没有关闭。", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6a9955" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n384", + "name": "Prop / 构造参数", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n385", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n386", + "name": "构造参数", + "width": "fit_content", + "height": "fit_content", + "content": "构造参数", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n387", + "name": "无", + "width": "fit_content", + "height": "fit_content", + "content": "无", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n388", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n389", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n390", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n391", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n392", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n393", + "name": "Lines 17–17", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n394", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n395", + "name": "Line 17", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n396", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n397", + "name": "17", + "width": "fit_content", + "height": "fit_content", + "content": "17", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n398", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n399", + "name": "const router = useRouter();", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "router", + "fill": "#9cdcfe" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useRouter", + "fill": "#dcdcaa" + }, + { + "text": "()", + "fill": "#da70d6" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n400", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n401", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n402", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n403", + "name": "Guide", + "width": 12.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n404", + "name": "Line", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n405", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n406", + "name": "钩子 / useRouter · router", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2d2a25" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#52415f" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n407", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n408", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n409", + "name": "Concept / 钩子", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n410", + "name": "fishing-hook", + "iconFontName": "fishing-hook", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#b180d7" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n411", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n412", + "name": "Prop / 钩子", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n413", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n414", + "name": "钩子", + "width": "fit_content", + "height": "fit_content", + "content": "钩子", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n415", + "name": "useRouter", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "useRouter", + "fontWeight": 600, + "fill": "#dcdcaa" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n416", + "name": "Prop / 返回", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n417", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n418", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n419", + "name": "返回", + "width": "fit_content", + "height": "fit_content", + "content": "返回", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n420", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n421", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n422", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n423", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#383530" + } + ], + "children": [ + { + "type": "frame", + "id": "n424", + "name": "名称", + "width": 66.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n425", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n426", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n427", + "name": "是什么", + "width": 539.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n428", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n429", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n430", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n431", + "name": "名称", + "width": 66.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n432", + "name": "router", + "width": "fit_content", + "height": "fit_content", + "content": "router", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n433", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n434", + "name": "是什么", + "width": 539.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n435", + "name": "路由器,用于页面跳转", + "width": "fit_content", + "height": "fit_content", + "content": "路由器,用于页面跳转", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n436", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n437", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n438", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n439", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n440", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n441", + "name": "Lines 18–18", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n442", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n443", + "name": "Line 18", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n444", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n445", + "name": "18", + "width": "fit_content", + "height": "fit_content", + "content": "18", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n446", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n447", + "name": "const from = useSearchParams().get(\"from", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useSearchParams", + "fill": "#dcdcaa" + }, + { + "text": "()", + "fill": "#da70d6" + }, + { + "text": ".", + "fill": "#d4d4d4" + }, + { + "text": "get", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#da70d6" + }, + { + "text": "\"from\"", + "fill": "#ce9178" + }, + { + "text": ")", + "fill": "#da70d6" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n448", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n449", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n450", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n451", + "name": "Guide", + "width": 12.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n452", + "name": "Line", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n453", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n454", + "name": "钩子 / useSearchParams · from", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#2d2a25" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#52415f" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n455", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n456", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n457", + "name": "Concept / 钩子", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n458", + "name": "fishing-hook", + "iconFontName": "fishing-hook", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#b180d7" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n459", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n460", + "name": "Prop / 钩子", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n461", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n462", + "name": "钩子", + "width": "fit_content", + "height": "fit_content", + "content": "钩子", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n463", + "name": "useSearchParams", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "useSearchParams", + "fontWeight": 600, + "fill": "#dcdcaa" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n464", + "name": "Prop / 返回", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n465", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n466", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n467", + "name": "返回", + "width": "fit_content", + "height": "fit_content", + "content": "返回", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n468", + "name": "1 个", + "width": "fit_content", + "height": "fit_content", + "content": "1 个", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n469", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n470", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n471", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#383530" + } + ], + "children": [ + { + "type": "frame", + "id": "n472", + "name": "名称", + "width": 50.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n473", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n474", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n475", + "name": "是什么", + "width": 555.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n476", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n477", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n478", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n479", + "name": "名称", + "width": 50.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n480", + "name": "from", + "width": "fit_content", + "height": "fit_content", + "content": "from", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n481", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n482", + "name": "是什么", + "width": 555.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n483", + "name": "URL 查询参数里 \"from\" 的值", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "URL 查询参数里 ", + "fill": "#cccccc" + }, + { + "text": "\"from\"", + "fill": "#ce9178" + }, + { + "text": " 的值", + "fill": "#cccccc" + } + ], + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n484", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n485", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n486", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n487", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n488", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n489", + "name": "Lines 19–19", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n490", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n491", + "name": "Line 19", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n492", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n493", + "name": "19", + "width": "fit_content", + "height": "fit_content", + "content": "19", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n494", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n495", + "name": "const [activeTab, setActiveTab] = useSta", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "[", + "fill": "#da70d6" + }, + { + "text": "activeTab", + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#d4d4d4" + }, + { + "text": "setActiveTab", + "fill": "#9cdcfe" + }, + { + "text": "]", + "fill": "#da70d6" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useState", + "fill": "#dcdcaa" + }, + { + "text": "<", + "fill": "#d4d4d4" + }, + { + "text": "LoginTab", + "fill": "#4ec9b0" + }, + { + "text": ">", + "fill": "#d4d4d4" + }, + { + "text": "(", + "fill": "#da70d6" + }, + { + "text": "\"sms\"", + "fill": "#ce9178" + }, + { + "text": ")", + "fill": "#da70d6" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n496", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n497", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n498", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n499", + "name": "Guide", + "width": 12.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n500", + "name": "Line", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n501", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n502", + "name": "Hover / 来自", + "width": 741.0, + "height": "fit_content", + "layout": "none", + "gap": 0.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n503", + "name": "Tooltip", + "x": 154.0, + "y": 84.0, + "width": 100.0, + "height": 22.0, + "layout": "horizontal", + "justifyContent": "center", + "alignItems": "center", + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#202020" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#454545" + } + ] + }, + "effects": [ + { + "type": "shadow", + "offsetX": 0.0, + "offsetY": 2.0, + "blur": 8.0, + "spread": 0.0, + "color": "rgba(0,0,0,0.36)" + } + ], + "children": [ + { + "type": "text", + "id": "n504", + "name": "React 内置钩子", + "width": "fit_content", + "height": "fit_content", + "content": "React 内置钩子", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 400, + "lineHeight": 1.2727272727272727, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n505", + "name": "状态 / activeTab", + "x": 0.0, + "y": 0.0, + "width": 741.0, + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#282c2f" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#4b616d" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n506", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n507", + "name": "Concepts", + "width": 42.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n508", + "name": "Concept / 变量", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n509", + "name": "variable", + "iconFontName": "variable", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n510", + "name": "Concept / React 状态", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n511", + "name": "toggle-right", + "iconFontName": "toggle-right", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n512", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n513", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n514", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n515", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n516", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n517", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n518", + "name": "Destructure", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n519", + "name": "[activeTab, setActiveTab]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "[", + "fill": "#cccccc" + }, + { + "text": "activeTab", + "fontWeight": 600, + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#cccccc" + }, + { + "text": "setActiveTab", + "fontWeight": 600, + "fill": "#dcdcaa" + }, + { + "text": "]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n520", + "name": "数组解构", + "width": "fit_content", + "height": "fit_content", + "content": "数组解构", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n521", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n522", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n523", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#333739" + } + ], + "children": [ + { + "type": "frame", + "id": "n524", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n525", + "name": "第几项", + "width": "fit_content", + "height": "fit_content", + "content": "第几项", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n526", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n527", + "name": "名称", + "width": 114.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n528", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n529", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n530", + "name": "是什么", + "width": 373.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n531", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n532", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n533", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n534", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n535", + "name": "1", + "width": 12.0, + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n536", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n537", + "name": "名称", + "width": 114.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n538", + "name": "activeTab", + "width": "fit_content", + "height": "fit_content", + "content": "activeTab", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n539", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n540", + "name": "是什么", + "width": 373.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n541", + "name": "当前值", + "width": "fit_content", + "height": "fit_content", + "content": "当前值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n542", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n543", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n544", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n545", + "name": "2", + "width": 12.0, + "height": "fit_content", + "content": "2", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n546", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n547", + "name": "名称", + "width": 114.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n548", + "name": "setActiveTab", + "width": "fit_content", + "height": "fit_content", + "content": "setActiveTab", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n549", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n550", + "name": "是什么", + "width": 373.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n551", + "name": "修改函数", + "width": "fit_content", + "height": "fit_content", + "content": "修改函数", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n552", + "name": "Prop / 来自", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n553", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n554", + "name": "来自", + "width": "fit_content", + "height": "fit_content", + "content": "来自", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n555", + "name": "useState", + "width": "fit_content", + "height": "fit_content", + "content": "useState", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n556", + "name": "Prop / 状态类型", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n557", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n558", + "name": "状态类型", + "width": "fit_content", + "height": "fit_content", + "content": "状态类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n559", + "name": "LoginTab", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "LoginTab", + "fill": "#4ec9b0", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n560", + "name": "Prop / 默认值", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n561", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n562", + "name": "默认值", + "width": "fit_content", + "height": "fit_content", + "content": "默认值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n563", + "name": "\"sms\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"sms\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n564", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n565", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n566", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n567", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n568", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n569", + "name": "git-branch", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 1.0, + "padding": [ + 0.0, + 4.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n570", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n571", + "name": "Count", + "width": 14.0, + "height": 14.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 7.0, + "fill": [ + { + "type": "solid", + "color": "#616161" + } + ], + "children": [ + { + "type": "text", + "id": "n572", + "name": "1", + "width": "fit_content", + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 9.0, + "fontWeight": 700, + "lineHeight": 1.5555555555555556, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#f8f8f8" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n573", + "name": "Lines 20–21", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n574", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n575", + "name": "Line 20", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n576", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n577", + "name": "20", + "width": "fit_content", + "height": "fit_content", + "content": "20", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n578", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n579", + "name": "const [passwordView, setPasswordView] = ", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "[", + "fill": "#da70d6" + }, + { + "text": "passwordView", + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#d4d4d4" + }, + { + "text": "setPasswordView", + "fill": "#9cdcfe" + }, + { + "text": "]", + "fill": "#da70d6" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useState", + "fill": "#dcdcaa" + }, + { + "text": "<", + "fill": "#d4d4d4" + }, + { + "text": "PasswordView", + "fill": "#4ec9b0" + }, + { + "text": ">", + "fill": "#d4d4d4" + }, + { + "text": "(", + "fill": "#da70d6" + }, + { + "text": "\"login\"", + "fill": "#ce9178" + }, + { + "text": ")", + "fill": "#da70d6" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n580", + "name": "Line 21", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n581", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n582", + "name": "21", + "width": "fit_content", + "height": "fit_content", + "content": "21", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n583", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n584", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n585", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n586", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n587", + "name": "Guide", + "width": 12.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n588", + "name": "Line", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n589", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n590", + "name": "状态 / passwordView", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#282c2f" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#4b616d" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n591", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n592", + "name": "Concepts", + "width": 42.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n593", + "name": "Concept / 变量", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n594", + "name": "variable", + "iconFontName": "variable", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n595", + "name": "Concept / React 状态", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n596", + "name": "toggle-right", + "iconFontName": "toggle-right", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n597", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n598", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n599", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n600", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n601", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n602", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n603", + "name": "Destructure", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n604", + "name": "[passwordView, setPasswordView]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "[", + "fill": "#cccccc" + }, + { + "text": "passwordView", + "fontWeight": 600, + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#cccccc" + }, + { + "text": "setPasswordView", + "fontWeight": 600, + "fill": "#dcdcaa" + }, + { + "text": "]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n605", + "name": "数组解构", + "width": "fit_content", + "height": "fit_content", + "content": "数组解构", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n606", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n607", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n608", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#333739" + } + ], + "children": [ + { + "type": "frame", + "id": "n609", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n610", + "name": "第几项", + "width": "fit_content", + "height": "fit_content", + "content": "第几项", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n611", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n612", + "name": "名称", + "width": 137.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n613", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n614", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n615", + "name": "是什么", + "width": 350.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n616", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n617", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n618", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n619", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n620", + "name": "1", + "width": 12.0, + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n621", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n622", + "name": "名称", + "width": 137.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n623", + "name": "passwordView", + "width": "fit_content", + "height": "fit_content", + "content": "passwordView", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n624", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n625", + "name": "是什么", + "width": 350.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n626", + "name": "当前值", + "width": "fit_content", + "height": "fit_content", + "content": "当前值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n627", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n628", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n629", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n630", + "name": "2", + "width": 12.0, + "height": "fit_content", + "content": "2", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n631", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n632", + "name": "名称", + "width": 137.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n633", + "name": "setPasswordView", + "width": "fit_content", + "height": "fit_content", + "content": "setPasswordView", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n634", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n635", + "name": "是什么", + "width": 350.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n636", + "name": "修改函数", + "width": "fit_content", + "height": "fit_content", + "content": "修改函数", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n637", + "name": "Prop / 来自", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n638", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n639", + "name": "来自", + "width": "fit_content", + "height": "fit_content", + "content": "来自", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n640", + "name": "useState", + "width": "fit_content", + "height": "fit_content", + "content": "useState", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n641", + "name": "Prop / 状态类型", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n642", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n643", + "name": "状态类型", + "width": "fit_content", + "height": "fit_content", + "content": "状态类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n644", + "name": "PasswordView", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "PasswordView", + "fill": "#4ec9b0", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n645", + "name": "Prop / 默认值", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n646", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n647", + "name": "默认值", + "width": "fit_content", + "height": "fit_content", + "content": "默认值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n648", + "name": "\"login\"", + "width": "fit_content", + "height": "fit_content", + "content": "\"login\"", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#ce9178" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n649", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n650", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n651", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n652", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n653", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n654", + "name": "git-branch", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 1.0, + "padding": [ + 0.0, + 4.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n655", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n656", + "name": "Count", + "width": 14.0, + "height": 14.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 7.0, + "fill": [ + { + "type": "solid", + "color": "#616161" + } + ], + "children": [ + { + "type": "text", + "id": "n657", + "name": "1", + "width": "fit_content", + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 9.0, + "fontWeight": 700, + "lineHeight": 1.5555555555555556, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#f8f8f8" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n658", + "name": "Lines 22–34", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n659", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n660", + "name": "Line 22", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n661", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n662", + "name": "22", + "width": "fit_content", + "height": "fit_content", + "content": "22", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n663", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n664", + "name": "return (", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "return", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "(", + "fill": "#da70d6" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n665", + "name": "Line 23", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n666", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n667", + "name": "23", + "width": "fit_content", + "height": "fit_content", + "content": "23", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n668", + "name": "Margin", + "width": 57.32, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n669", + "name": "
", + "fill": "#808080" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n670", + "name": "Line 24", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n671", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n672", + "name": "24", + "width": "fit_content", + "height": "fit_content", + "content": "24", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n673", + "name": "Margin", + "width": 72.98, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n674", + "name": "
", + "fill": "#808080" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n675", + "name": "Line 25", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n676", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n677", + "name": "25", + "width": "fit_content", + "height": "fit_content", + "content": "25", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n678", + "name": "Margin", + "width": 88.64, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n679", + "name": " router.replace(from && ", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "onSuccess", + "fill": "#9cdcfe" + }, + { + "text": "=", + "fill": "#d4d4d4" + }, + { + "text": "{", + "fill": "#179fff" + }, + { + "text": "()", + "fill": "#ffd700" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "=>", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "router", + "fill": "#9cdcfe" + }, + { + "text": ".", + "fill": "#d4d4d4" + }, + { + "text": "replace", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#ffd700" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": " && ", + "fill": "#d4d4d4" + }, + { + "text": "isSafeReturnTo", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#da70d6" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": ")", + "fill": "#da70d6" + }, + { + "text": " ? ", + "fill": "#d4d4d4" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": " : ", + "fill": "#d4d4d4" + }, + { + "text": "DESKTOP_ENTRY", + "fill": "#4fc1ff" + }, + { + "text": ")", + "fill": "#ffd700" + }, + { + "text": "}", + "fill": "#179fff" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n705", + "name": "Line 31", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n706", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n707", + "name": "31", + "width": "fit_content", + "height": "fit_content", + "content": "31", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n708", + "name": "Margin", + "width": 88.64, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n709", + "name": "/>", + "width": "fit_content", + "height": "fit_content", + "content": "/>", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#808080" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n710", + "name": "Line 32", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n711", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n712", + "name": "32", + "width": "fit_content", + "height": "fit_content", + "content": "32", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n713", + "name": "Margin", + "width": 72.98, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n714", + "name": "
", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "", + "fill": "#808080" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n715", + "name": "Line 33", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n716", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n717", + "name": "33", + "width": "fit_content", + "height": "fit_content", + "content": "33", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n718", + "name": "Margin", + "width": 57.32, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n719", + "name": "
", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "", + "fill": "#808080" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n720", + "name": "Line 34", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n721", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n722", + "name": "34", + "width": "fit_content", + "height": "fit_content", + "content": "34", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n723", + "name": "Margin", + "width": 41.66, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n724", + "name": ");", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": ")", + "fill": "#da70d6" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n725", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n726", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 8.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n727", + "name": "Level", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n728", + "name": "Guide", + "width": 12.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n729", + "name": "Line", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n730", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n731", + "name": "渲染输出 / DesktopLoginPage", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#262b26" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#445d43" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n732", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n733", + "name": "Concepts", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n734", + "name": "Concept / 渲染输出", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n735", + "name": "layout-template", + "iconFontName": "layout-template", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#89d185" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n736", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n737", + "name": "Outline", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n738", + "name": "Item", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n739", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n740", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n741", + "name": "Line", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n742", + "name": "
", + "width": "fit_content", + "height": "fit_content", + "content": "
", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#808080" + } + ] + }, + { + "type": "frame", + "id": "n743", + "name": "Classes", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 5.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#454545" + } + ] + }, + "children": [ + { + "type": "text", + "id": "n744", + "name": "样式 4 个类", + "width": "fit_content", + "height": "fit_content", + "content": "样式 4 个类", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 400, + "lineHeight": 1.6363636363636365, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n745", + "name": "Sub", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 5.0 + ], + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n746", + "name": "Guide", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n747", + "name": "Kids", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n748", + "name": "Outline", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n749", + "name": "Item", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n750", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n751", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n752", + "name": "Line", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n753", + "name": "
", + "width": "fit_content", + "height": "fit_content", + "content": "
", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#808080" + } + ] + }, + { + "type": "frame", + "id": "n754", + "name": "Classes", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 5.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#454545" + } + ] + }, + "children": [ + { + "type": "text", + "id": "n755", + "name": "样式 5 个类", + "width": "fit_content", + "height": "fit_content", + "content": "样式 5 个类", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 400, + "lineHeight": 1.6363636363636365, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n756", + "name": "Sub", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 5.0 + ], + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n757", + "name": "Guide", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#404040" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n758", + "name": "Kids", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n759", + "name": "Outline", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n760", + "name": "Item", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n761", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n762", + "name": "Lines", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n763", + "name": "Line", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n764", + "name": "", + "width": "fit_content", + "height": "fit_content", + "content": "", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#61dafb" + } + ] + }, + { + "type": "text", + "id": "n765", + "name": "activeTab=activeTab", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "activeTab", + "fill": "#9cdcfe" + }, + { + "text": "=", + "fill": "#cccccc" + }, + { + "text": "activeTab", + "fill": "#9cdcfe", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n766", + "name": "onTabChange=setActiveTab", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "onTabChange", + "fill": "#9cdcfe" + }, + { + "text": "=", + "fill": "#cccccc" + }, + { + "text": "setActiveTab", + "fill": "#dcdcaa", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n767", + "name": "Line", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 16.0 + ], + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n768", + "name": "passwordView=passwordView", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "passwordView", + "fill": "#9cdcfe" + }, + { + "text": "=", + "fill": "#cccccc" + }, + { + "text": "passwordView", + "fill": "#9cdcfe", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n769", + "name": "onPasswordView=setPasswordView", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "onPasswordView", + "fill": "#9cdcfe" + }, + { + "text": "=", + "fill": "#cccccc" + }, + { + "text": "setPasswordView", + "fill": "#dcdcaa", + "underline": true + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n770", + "name": "Line", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "padding": [ + 0.0, + 0.0, + 0.0, + 16.0 + ], + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n771", + "name": "onSuccess=() => router.replace(如果 from 并", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "onSuccess", + "fill": "#9cdcfe" + }, + { + "text": "=() => ", + "fill": "#cccccc" + }, + { + "text": "router", + "fill": "#9cdcfe" + }, + { + "text": ".", + "fill": "#cccccc" + }, + { + "text": "replace", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#cccccc" + }, + { + "text": "如果", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "并且", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "isSafeReturnTo", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#cccccc" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": ")\n", + "fill": "#cccccc" + }, + { + "text": "则", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "from", + "fill": "#9cdcfe" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "否则", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#cccccc" + }, + { + "text": "DESKTOP_ENTRY", + "fill": "#4fc1ff" + }, + { + "text": ")", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n772", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n773", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n774", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n775", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n776", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n777", + "name": "Lines 35–37", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n778", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n779", + "name": "Line 35", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n780", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n781", + "name": "35", + "width": "fit_content", + "height": "fit_content", + "content": "35", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n782", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n783", + "name": "};", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "}", + "fill": "#ffd700" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n784", + "name": "Line 36", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n785", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n786", + "name": "36", + "width": "fit_content", + "height": "fit_content", + "content": "36", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n787", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n788", + "name": "Line 37", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n789", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n790", + "name": "37", + "width": "fit_content", + "height": "fit_content", + "content": "37", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n791", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n792", + "name": "export default DesktopLoginPage;", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "export", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "default", + "fill": "#c586c0" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "DesktopLoginPage", + "fill": "#4ec9b0" + }, + { + "text": ";", + "fill": "#d4d4d4" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n793", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n794", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n795", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n796", + "name": "End", + "width": "fill_container", + "height": 28.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n797", + "name": "Code", + "width": 600.0, + "height": 28.0, + "children": [] + }, + { + "type": "rectangle", + "id": "n798", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n799", + "name": "Status", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n800", + "name": "Branch", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n801", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n802", + "name": "master", + "width": "fit_content", + "height": "fit_content", + "content": "master", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n803", + "name": "Right", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 16.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n804", + "name": "代码阅读", + "width": "fit_content", + "height": "fit_content", + "content": "代码阅读", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n805", + "name": "TypeScript JSX", + "width": "fit_content", + "height": "fit_content", + "content": "TypeScript JSX", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n806", + "name": "Prototype / React 状态 · 其他写法", + "x": 1780.0, + "y": 0.0, + "width": 1700.0, + "height": 62.0, + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n807", + "name": "Title bar", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n808", + "name": "Lights", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "ellipse", + "id": "n809", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#ff5f57" + } + ] + }, + { + "type": "ellipse", + "id": "n810", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#febc2e" + } + ] + }, + { + "type": "ellipse", + "id": "n811", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#28c840" + } + ] + } + ] + }, + { + "type": "text", + "id": "n812", + "name": "web — examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "web — examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n813", + "name": "Balance", + "width": 52.0, + "height": 12.0, + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n814", + "name": "Body", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n815", + "name": "Activity bar", + "width": 48.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n816", + "name": "Item / files", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n817", + "name": "files", + "iconFontName": "files", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n818", + "name": "Item / search", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n819", + "name": "search", + "iconFontName": "search", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n820", + "name": "Item / git-branch", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n821", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n822", + "name": "Item / play", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n823", + "name": "play", + "iconFontName": "play", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n824", + "name": "Item / monitor", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n825", + "name": "monitor", + "iconFontName": "monitor", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n826", + "name": "Item / blocks", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n827", + "name": "blocks", + "iconFontName": "blocks", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n828", + "name": "Item / rocket", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n829", + "name": "rocket", + "iconFontName": "rocket", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#868686" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n830", + "name": "Item / book-open-text", + "width": 48.0, + "height": 42.0, + "layout": "horizontal", + "gap": 10.0, + "justifyContent": "start", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "rectangle", + "id": "n831", + "name": "Active bar", + "width": 2.0, + "height": 42.0, + "fill": [ + { + "type": "solid", + "color": "#0078d4" + } + ], + "children": [] + }, + { + "type": "icon_font", + "id": "n832", + "name": "book-open-text", + "iconFontName": "book-open-text", + "width": 22.0, + "height": 22.0, + "fill": [ + { + "type": "solid", + "color": "#d7d7d7" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n833", + "name": "Sidebar", + "width": 250.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n834", + "name": "Header", + "width": "fill_container", + "height": 34.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0, + 0.0, + 16.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n835", + "name": "代码阅读", + "width": "fit_content", + "height": "fit_content", + "content": "代码阅读", + "fontFamily": "PingFang SC", + "fontSize": 11.0, + "fontWeight": 400, + "lineHeight": 1.818181818181818, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "frame", + "id": "n836", + "name": "Actions", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n837", + "name": "git-pull-request", + "iconFontName": "git-pull-request", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n838", + "name": "file-plus", + "iconFontName": "file-plus", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n839", + "name": "refresh-cw", + "iconFontName": "refresh-cw", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n840", + "name": "Tree", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 4.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n841", + "name": "src", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 10.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n842", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n843", + "name": "folder", + "iconFontName": "folder", + "width": 15.0, + "height": 15.0, + "fill": [ + { + "type": "solid", + "color": "#8b9ba8" + } + ] + }, + { + "type": "text", + "id": "n844", + "name": "src", + "width": "fit_content", + "height": "fit_content", + "content": "src", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n845", + "name": "examples.tsx", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 8.0, + 0.0, + 24.0 + ], + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#04395e" + } + ], + "children": [ + { + "type": "frame", + "id": "n846", + "name": "Twisty", + "width": 14.0, + "height": 14.0, + "children": [] + }, + { + "type": "icon_font", + "id": "n847", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n848", + "name": "examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n849", + "name": "Editor", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "frame", + "id": "n850", + "name": "Group heads", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n851", + "name": "Editor group 1", + "width": 600.0, + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n852", + "name": "Editor title", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n853", + "name": "Tab", + "width": 140.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "rectangle", + "id": "n854", + "name": "Active", + "width": "fill_container", + "height": 2.0, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n855", + "name": "Tab label", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 12.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n856", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n857", + "name": "examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n858", + "name": "Breadcrumb", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 6.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n859", + "name": "src", + "width": "fit_content", + "height": "fit_content", + "content": "src", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n860", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n861", + "name": "examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n862", + "name": "Filter room", + "width": "fill_container", + "height": 36.0, + "children": [] + } + ] + }, + { + "type": "rectangle", + "id": "n863", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n864", + "name": "Editor group 2", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n865", + "name": "Editor title", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n866", + "name": "Tab", + "width": 140.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#1f1f1f" + } + ], + "children": [ + { + "type": "rectangle", + "id": "n867", + "name": "Active", + "width": "fill_container", + "height": 2.0, + "fill": [ + { + "type": "solid", + "color": "#0078d4" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n868", + "name": "Tab label", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 0.0, + 12.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n869", + "name": "atom", + "iconFontName": "atom", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#519aba" + } + ] + }, + { + "type": "text", + "id": "n870", + "name": "examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n871", + "name": "Mode", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 2.0, + "padding": [ + 2.0, + 2.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 5.0, + "fill": [ + { + "type": "solid", + "color": "#111111" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n872", + "name": "Seg / 编辑", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 2.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 3.0, + "children": [ + { + "type": "icon_font", + "id": "n873", + "name": "pencil", + "iconFontName": "pencil", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n874", + "name": "编辑", + "width": "fit_content", + "height": "fit_content", + "content": "编辑", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n875", + "name": "Seg / 预览", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 2.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 3.0, + "fill": [ + { + "type": "solid", + "color": "#37373d" + } + ], + "children": [ + { + "type": "icon_font", + "id": "n876", + "name": "eye", + "iconFontName": "eye", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + }, + { + "type": "text", + "id": "n877", + "name": "预览", + "width": "fit_content", + "height": "fit_content", + "content": "预览", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#e8e8e8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n878", + "name": "Pad", + "width": 8.0, + "height": 8.0, + "children": [] + } + ] + }, + { + "type": "frame", + "id": "n879", + "name": "Breadcrumb", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 6.0, + "padding": [ + 6.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n880", + "name": "src", + "width": "fit_content", + "height": "fit_content", + "content": "src", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n881", + "name": "/", + "width": "fit_content", + "height": "fit_content", + "content": "/", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + }, + { + "type": "text", + "id": "n882", + "name": "examples.tsx", + "width": "fit_content", + "height": "fit_content", + "content": "examples.tsx", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n883", + "name": "Filter", + "width": "fill_container", + "height": 36.0, + "layout": "horizontal", + "gap": 8.0, + "padding": [ + 0.0, + 16.0 + ], + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n884", + "name": "筛选", + "width": "fit_content", + "height": "fit_content", + "content": "筛选", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "frame", + "id": "n885", + "name": "Chip / 种类", + "width": "fit_content", + "height": 24.0, + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 0.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "children": [ + { + "type": "text", + "id": "n886", + "name": "种类", + "width": "fit_content", + "height": "fit_content", + "content": "种类", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n887", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n888", + "name": "Chip / 访问级别", + "width": "fit_content", + "height": 24.0, + "layout": "horizontal", + "gap": 4.0, + "padding": [ + 0.0, + 8.0 + ], + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "fill": [ + { + "type": "solid", + "color": "#313131" + } + ], + "children": [ + { + "type": "text", + "id": "n889", + "name": "访问级别", + "width": "fit_content", + "height": "fit_content", + "content": "访问级别", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "icon_font", + "id": "n890", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 12.0, + "height": 12.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n891", + "name": "Spacer", + "width": "fill_container", + "height": 8.0, + "children": [] + }, + { + "type": "text", + "id": "n892", + "name": "3 块", + "width": "fit_content", + "height": "fit_content", + "content": "3 块", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n893", + "name": "Lines 1–1", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n894", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n895", + "name": "Line 1", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n896", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n897", + "name": "1", + "width": "fit_content", + "height": "fit_content", + "content": "1", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n898", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n899", + "name": "const [open, setOpen] = useState(false)", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "[", + "fill": "#ffd700" + }, + { + "text": "open", + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#d4d4d4" + }, + { + "text": "setOpen", + "fill": "#9cdcfe" + }, + { + "text": "]", + "fill": "#ffd700" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useState", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#ffd700" + }, + { + "text": "false", + "fill": "#569cd6" + }, + { + "text": ")", + "fill": "#ffd700" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n900", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n901", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n902", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n903", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n904", + "name": "状态 / open", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#282c2f" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#4b616d" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n905", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n906", + "name": "Concepts", + "width": 42.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n907", + "name": "Concept / 变量", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n908", + "name": "variable", + "iconFontName": "variable", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n909", + "name": "Concept / React 状态", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n910", + "name": "toggle-right", + "iconFontName": "toggle-right", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n911", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n912", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n913", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n914", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n915", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n916", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n917", + "name": "Destructure", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n918", + "name": "[open, setOpen]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "[", + "fill": "#cccccc" + }, + { + "text": "open", + "fontWeight": 600, + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#cccccc" + }, + { + "text": "setOpen", + "fontWeight": 600, + "fill": "#dcdcaa" + }, + { + "text": "]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n919", + "name": "数组解构", + "width": "fit_content", + "height": "fit_content", + "content": "数组解构", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n920", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n921", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n922", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#333739" + } + ], + "children": [ + { + "type": "frame", + "id": "n923", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n924", + "name": "第几项", + "width": "fit_content", + "height": "fit_content", + "content": "第几项", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n925", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n926", + "name": "名称", + "width": 74.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n927", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n928", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n929", + "name": "是什么", + "width": 448.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n930", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n931", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n932", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n933", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n934", + "name": "1", + "width": 12.0, + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n935", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n936", + "name": "名称", + "width": 74.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n937", + "name": "open", + "width": "fit_content", + "height": "fit_content", + "content": "open", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n938", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n939", + "name": "是什么", + "width": 448.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n940", + "name": "当前值", + "width": "fit_content", + "height": "fit_content", + "content": "当前值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n941", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n942", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n943", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n944", + "name": "2", + "width": 12.0, + "height": "fit_content", + "content": "2", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n945", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n946", + "name": "名称", + "width": 74.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n947", + "name": "setOpen", + "width": "fit_content", + "height": "fit_content", + "content": "setOpen", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n948", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n949", + "name": "是什么", + "width": 448.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n950", + "name": "修改函数", + "width": "fit_content", + "height": "fit_content", + "content": "修改函数", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n951", + "name": "Prop / 来自", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n952", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n953", + "name": "来自", + "width": "fit_content", + "height": "fit_content", + "content": "来自", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n954", + "name": "useState", + "width": "fit_content", + "height": "fit_content", + "content": "useState", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n955", + "name": "Prop / 状态类型", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n956", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n957", + "name": "状态类型", + "width": "fit_content", + "height": "fit_content", + "content": "状态类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n958", + "name": "未标注", + "width": "fit_content", + "height": "fit_content", + "content": "未标注", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n959", + "name": "Prop / 默认值", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n960", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n961", + "name": "默认值", + "width": "fit_content", + "height": "fit_content", + "content": "默认值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n962", + "name": "假", + "width": "fit_content", + "height": "fit_content", + "content": "假", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#b5cea8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n963", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n964", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n965", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n966", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n967", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n968", + "name": "git-branch", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n969", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n970", + "name": "Lines 2–2", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n971", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n972", + "name": "Line 2", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n973", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n974", + "name": "2", + "width": "fit_content", + "height": "fit_content", + "content": "2", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n975", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n976", + "name": "const [items, setItems] = useState", + "fill": "#d4d4d4" + }, + { + "text": "(", + "fill": "#ffd700" + }, + { + "text": "()", + "fill": "#da70d6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "=>", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "loadItems", + "fill": "#dcdcaa" + }, + { + "text": "()", + "fill": "#da70d6" + }, + { + "text": ")", + "fill": "#ffd700" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n977", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n978", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n979", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n980", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n981", + "name": "状态 / items", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#282c2f" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#4b616d" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n982", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n983", + "name": "Concepts", + "width": 42.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n984", + "name": "Concept / 变量", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n985", + "name": "variable", + "iconFontName": "variable", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n986", + "name": "Concept / React 状态", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n987", + "name": "toggle-right", + "iconFontName": "toggle-right", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n988", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n989", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n990", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n991", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n992", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n993", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n994", + "name": "Destructure", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n995", + "name": "[items, setItems]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "[", + "fill": "#cccccc" + }, + { + "text": "items", + "fontWeight": 600, + "fill": "#9cdcfe" + }, + { + "text": ", ", + "fill": "#cccccc" + }, + { + "text": "setItems", + "fontWeight": 600, + "fill": "#dcdcaa" + }, + { + "text": "]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n996", + "name": "数组解构", + "width": "fit_content", + "height": "fit_content", + "content": "数组解构", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n997", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n998", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n999", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#333739" + } + ], + "children": [ + { + "type": "frame", + "id": "n1000", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1001", + "name": "第几项", + "width": "fit_content", + "height": "fit_content", + "content": "第几项", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1002", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1003", + "name": "名称", + "width": 82.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1004", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1005", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1006", + "name": "是什么", + "width": 440.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1007", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1008", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1009", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1010", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1011", + "name": "1", + "width": 12.0, + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1012", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1013", + "name": "名称", + "width": 82.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1014", + "name": "items", + "width": "fit_content", + "height": "fit_content", + "content": "items", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1015", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1016", + "name": "是什么", + "width": 440.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1017", + "name": "当前值", + "width": "fit_content", + "height": "fit_content", + "content": "当前值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1018", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1019", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1020", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1021", + "name": "2", + "width": 12.0, + "height": "fit_content", + "content": "2", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1022", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1023", + "name": "名称", + "width": 82.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1024", + "name": "setItems", + "width": "fit_content", + "height": "fit_content", + "content": "setItems", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1025", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1026", + "name": "是什么", + "width": 440.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1027", + "name": "修改函数", + "width": "fit_content", + "height": "fit_content", + "content": "修改函数", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1028", + "name": "Prop / 来自", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1029", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1030", + "name": "来自", + "width": "fit_content", + "height": "fit_content", + "content": "来自", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1031", + "name": "useState", + "width": "fit_content", + "height": "fit_content", + "content": "useState", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1032", + "name": "Prop / 状态类型", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1033", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1034", + "name": "状态类型", + "width": "fit_content", + "height": "fit_content", + "content": "状态类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1035", + "name": "Item[]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "Item", + "fill": "#4ec9b0", + "underline": true + }, + { + "text": "[]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1036", + "name": "Prop / 默认值", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1037", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1038", + "name": "默认值", + "width": "fit_content", + "height": "fit_content", + "content": "默认值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1039", + "name": "首次渲染时调用 loadItems()", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "首次渲染时调用 ", + "fill": "#cccccc" + }, + { + "text": "loadItems", + "fill": "#dcdcaa" + }, + { + "text": "()", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1040", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1041", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n1042", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1043", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n1044", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1045", + "name": "git-branch", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n1046", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1047", + "name": "Lines 3–3", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1048", + "name": "Code", + "width": 600.0, + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 8.0, + 0.0, + 0.0, + 0.0 + ], + "clipContent": true, + "children": [ + { + "type": "frame", + "id": "n1049", + "name": "Line 3", + "width": "fill_container", + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1050", + "name": "Number", + "width": 44.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "end", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1051", + "name": "3", + "width": "fit_content", + "height": "fit_content", + "content": "3", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#6e7681" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1052", + "name": "Margin", + "width": 26.0, + "height": 20.0, + "children": [] + }, + { + "type": "text", + "id": "n1053", + "name": "const [count] = useState(0)", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "const", + "fill": "#569cd6" + }, + { + "text": " ", + "fill": "#d4d4d4" + }, + { + "text": "[", + "fill": "#ffd700" + }, + { + "text": "count", + "fill": "#9cdcfe" + }, + { + "text": "]", + "fill": "#ffd700" + }, + { + "text": " = ", + "fill": "#d4d4d4" + }, + { + "text": "useState", + "fill": "#dcdcaa" + }, + { + "text": "(", + "fill": "#ffd700" + }, + { + "text": "0", + "fill": "#b5cea8" + }, + { + "text": ")", + "fill": "#ffd700" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1054", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1055", + "name": "Preview", + "width": "fill_container", + "height": "fill_container", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 20.0, + 0.0, + 20.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1056", + "name": "Level", + "width": "fill_container", + "height": "fill_container", + "layout": "horizontal", + "gap": 8.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1057", + "name": "Cards", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 0.0, + 0.0, + 8.0, + 0.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1058", + "name": "状态 / count", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 10.0, + "padding": [ + 8.0, + 10.0, + 8.0, + 8.0 + ], + "alignItems": "start", + "clipContent": false, + "cornerRadius": 8.0, + "fill": [ + { + "type": "solid", + "color": "#282c2f" + } + ], + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#4b616d" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n1059", + "name": "Fold", + "width": 14.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [] + }, + { + "type": "frame", + "id": "n1060", + "name": "Concepts", + "width": 42.0, + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1061", + "name": "Concept / 变量", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n1062", + "name": "variable", + "iconFontName": "variable", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1063", + "name": "Concept / React 状态", + "width": 20.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n1064", + "name": "toggle-right", + "iconFontName": "toggle-right", + "width": 16.0, + "height": 16.0, + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1065", + "name": "Content", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1066", + "name": "Prop / 名称", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1067", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n1068", + "name": "chevron-down", + "iconFontName": "chevron-down", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + }, + { + "type": "text", + "id": "n1069", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1070", + "name": "Value", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 2.0, + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1071", + "name": "Destructure", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 8.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1072", + "name": "[count]", + "width": "fit_content", + "height": "fit_content", + "content": [ + { + "text": "[", + "fill": "#cccccc" + }, + { + "text": "count", + "fontWeight": 600, + "fill": "#9cdcfe" + }, + { + "text": "]", + "fill": "#cccccc" + } + ], + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n1073", + "name": "数组解构", + "width": "fit_content", + "height": "fit_content", + "content": "数组解构", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1074", + "name": "Table wrap", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "padding": [ + 2.0, + 0.0, + 2.0, + 5.0 + ], + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1075", + "name": "Table", + "width": "fill_container", + "height": "fit_content", + "layout": "vertical", + "gap": 0.0, + "clipContent": true, + "cornerRadius": 4.0, + "stroke": { + "thickness": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ] + }, + "children": [ + { + "type": "frame", + "id": "n1076", + "name": "Header", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#333739" + } + ], + "children": [ + { + "type": "frame", + "id": "n1077", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1078", + "name": "第几项", + "width": "fit_content", + "height": "fit_content", + "content": "第几项", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1079", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1080", + "name": "名称", + "width": 58.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1081", + "name": "名称", + "width": "fit_content", + "height": "fit_content", + "content": "名称", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1082", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1083", + "name": "是什么", + "width": 488.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1084", + "name": "是什么", + "width": "fit_content", + "height": "fit_content", + "content": "是什么", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1085", + "name": "Divider", + "width": "fill_container", + "height": 1.0, + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1086", + "name": "Row", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 0.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1087", + "name": "第几项", + "width": 56.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1088", + "name": "1", + "width": 12.0, + "height": "fit_content", + "content": "1", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "fixed-width", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1089", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1090", + "name": "名称", + "width": 58.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1091", + "name": "count", + "width": "fit_content", + "height": "fit_content", + "content": "count", + "fontFamily": "Menlo", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9cdcfe" + } + ] + } + ] + }, + { + "type": "rectangle", + "id": "n1092", + "name": "Sep", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#3c3c3c" + } + ], + "children": [] + }, + { + "type": "frame", + "id": "n1093", + "name": "是什么", + "width": 488.0, + "height": "fit_content", + "layout": "vertical", + "gap": 3.0, + "padding": [ + 2.0, + 8.0 + ], + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1094", + "name": "当前值", + "width": "fit_content", + "height": "fit_content", + "content": "当前值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1095", + "name": "Prop / 来自", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1096", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1097", + "name": "来自", + "width": "fit_content", + "height": "fit_content", + "content": "来自", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1098", + "name": "useState", + "width": "fit_content", + "height": "fit_content", + "content": "useState", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#dcdcaa" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1099", + "name": "Prop / 状态类型", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1100", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1101", + "name": "状态类型", + "width": "fit_content", + "height": "fit_content", + "content": "状态类型", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1102", + "name": "未标注", + "width": "fit_content", + "height": "fit_content", + "content": "未标注", + "fontFamily": "PingFang SC", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1103", + "name": "Prop / 默认值", + "width": "fill_container", + "height": "fit_content", + "layout": "horizontal", + "gap": 12.0, + "alignItems": "start", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1104", + "name": "Key", + "width": 76.0, + "height": 20.0, + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1105", + "name": "默认值", + "width": "fit_content", + "height": "fit_content", + "content": "默认值", + "fontFamily": "PingFang SC", + "fontSize": 12.5, + "fontWeight": 400, + "lineHeight": 1.6, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "text", + "id": "n1106", + "name": "0", + "width": "fit_content", + "height": "fit_content", + "content": "0", + "fontFamily": "Menlo", + "fontSize": 13.0, + "fontWeight": 400, + "lineHeight": 1.5384615384615383, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#b5cea8" + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1107", + "name": "Tools", + "width": "fit_content", + "height": 20.0, + "layout": "horizontal", + "gap": 2.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1108", + "name": "sparkles", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n1109", + "name": "sparkles", + "iconFontName": "sparkles", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1110", + "name": "pencil", + "width": 22.0, + "height": 20.0, + "layout": "horizontal", + "gap": 0.0, + "justifyContent": "center", + "alignItems": "center", + "clipContent": false, + "cornerRadius": 4.0, + "children": [ + { + "type": "icon_font", + "id": "n1111", + "name": "pencil", + "iconFontName": "pencil", + "width": 14.0, + "height": 14.0, + "fill": [ + { + "type": "solid", + "color": "#9d9d9d" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1112", + "name": "End", + "width": "fill_container", + "height": 28.0, + "layout": "horizontal", + "gap": 0.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "frame", + "id": "n1113", + "name": "Code", + "width": 600.0, + "height": 28.0, + "children": [] + }, + { + "type": "rectangle", + "id": "n1114", + "name": "Sash", + "width": 1.0, + "height": "fill_container", + "fill": [ + { + "type": "solid", + "color": "#2b2b2b" + } + ], + "children": [] + } + ] + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1115", + "name": "Status", + "width": "fill_container", + "height": 26.0, + "layout": "horizontal", + "gap": 0.0, + "padding": [ + 0.0, + 12.0 + ], + "justifyContent": "space_between", + "alignItems": "center", + "clipContent": false, + "fill": [ + { + "type": "solid", + "color": "#181818" + } + ], + "children": [ + { + "type": "frame", + "id": "n1116", + "name": "Branch", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 4.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "icon_font", + "id": "n1117", + "name": "git-branch", + "iconFontName": "git-branch", + "width": 13.0, + "height": 13.0, + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n1118", + "name": "master", + "width": "fit_content", + "height": "fit_content", + "content": "master", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + }, + { + "type": "frame", + "id": "n1119", + "name": "Right", + "width": "fit_content", + "height": "fit_content", + "layout": "horizontal", + "gap": 16.0, + "alignItems": "center", + "clipContent": false, + "children": [ + { + "type": "text", + "id": "n1120", + "name": "代码阅读", + "width": "fit_content", + "height": "fit_content", + "content": "代码阅读", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + }, + { + "type": "text", + "id": "n1121", + "name": "TypeScript JSX", + "width": "fit_content", + "height": "fit_content", + "content": "TypeScript JSX", + "fontFamily": "PingFang SC", + "fontSize": 12.0, + "fontWeight": 400, + "lineHeight": 1.6666666666666667, + "textGrowth": "auto", + "fill": [ + { + "type": "solid", + "color": "#cccccc" + } + ] + } + ] + } + ] + } + ] + } + ], + "editorMeta": { + "activePageIndex": 0, + "preserveAuthoredGeometry": false + } +} \ No newline at end of file