dishui 0.0.97 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.release-verified.json +2 -2
- package/dist/ai.js +17 -15
- package/dist/components/Card/Ticket.d.ts +52 -0
- package/dist/components/Card/Ticket2.js +218 -0
- package/dist/components/Card/Ticket2.js.map +1 -0
- package/dist/components/Card/index.d.ts +12 -0
- package/dist/components/Card/index.js +142 -139
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
- package/dist/components/ai/AgentRunCard/index.js +100 -0
- package/dist/components/ai/AgentRunCard/index.js.map +1 -0
- package/dist/components/ai/IssueCard/index.d.ts +39 -0
- package/dist/components/ai/IssueCard/index.js +78 -0
- package/dist/components/ai/IssueCard/index.js.map +1 -0
- package/dist/components/ai/index.d.ts +4 -0
- package/dist/components/pro/Flow/constants.js +3 -3
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowAIContext.d.ts +2 -0
- package/dist/components/pro/Flow/context/FlowAIContext.js +9 -4
- package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.d.ts +3 -2
- package/dist/components/pro/Flow/nodes/MediaContent.js +16 -16
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +25 -23
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.js +3 -3
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/panels/InspectorPanel.js +396 -384
- package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
- package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
- package/dist/components/pro/Kanban/Kanban.js +339 -0
- package/dist/components/pro/Kanban/Kanban.js.map +1 -0
- package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
- package/dist/components/pro/Kanban/Swimlanes.js +60 -0
- package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
- package/dist/components/pro/Kanban/index.d.ts +5 -0
- package/dist/components/pro/Kanban/types.d.ts +103 -0
- package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
- package/dist/components/pro/Kanban/utils.d.ts +13 -0
- package/dist/components/pro/Kanban/utils.js +48 -0
- package/dist/components/pro/Kanban/utils.js.map +1 -0
- package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
- package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
- package/dist/components/pro/RichTextEditor/types.js +11 -0
- package/dist/components/pro/RichTextEditor/types.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +128 -122
- package/dist/kanban.js +5 -0
- package/dist/utils/i18n.js +20 -0
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js +1 -1
- package/dist/utils/menu.js.map +1 -1
- package/package.json +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InspectorPanel.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/InspectorPanel.tsx"],"sourcesContent":["import React, { useMemo, useRef, useState } from 'react';\nimport Input from '../../../Input';\nimport Select from '../../../Select';\nimport Button from '../../../Button';\nimport Label from '../../../Label';\nimport Checkbox from '../../../Checkbox';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useDraggablePanel } from '../hooks/useDraggablePanel';\nimport { useResizablePanel } from '../hooks/useResizablePanel';\nimport { EDGE_LINE_STYLE_OPTIONS, EDGE_MARKER_OPTIONS, BORDER_STYLE_OPTIONS, EDGE_TYPE_OPTIONS, DEFAULT_NODE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\nimport { getAllSvgIcons, getSvgIcon, getSvgIconsByCategory, SVG_ICON_CATEGORIES, buildSvgMarkup, type SvgIconCategory } from '../nodes/svgIcons';\nimport { BORDER_SIDE_NAMES, BORDER_SIDE_TYPES, hasBorderSideOverrides, type BorderSideName } from '../nodes/shapes';\nimport { FLOW_NODE_TYPES, type FlowNode, type FlowEdge, type FlowLine, type FlowShapeType, type FlowBorderSideOverride } from '../types';\nimport { THEME_SYNC_TOKEN, COMMON_COLORS, isThemeToken, themeTokenCssVar, resolveThemeColor, type ThemeColorFieldKind } from '../utils/themeColor';\nimport { DataInspectorSection } from './DataInspectorSection';\nimport { ExpandableTextarea } from './ExpandableTextarea';\nimport {\n ARCHIFY_COMPONENT_ORDER,\n ARCHIFY_COMPONENT_LABELS,\n COMPONENT_STYLES,\n archifyStylePatch,\n} from '../archify';\n\n/**\n * Standalone panel (legacy). Prefer using InspectorPanelContent inside a FlowPanelGroup.\n */\nexport default function InspectorPanel() {\n const { showInspector } = useFlowUI();\n const { panelStyle, handleProps } = useDraggablePanel();\n const { panelWidth, resizeHandleProps } = useResizablePanel('left', 240);\n\n if (!showInspector) return null;\n\n return (\n <div className=\"flow-inspector\" data-flow-panel style={{ ...panelStyle, width: panelWidth }}>\n <div className=\"flow-panel-resize-handle flow-panel-resize-handle--left\" {...resizeHandleProps} />\n <div\n className=\"flow-panel-drag-handle\"\n {...handleProps}\n style={{ fontSize: 11, fontWeight: 600, marginBottom: 8, color: 'color-mix(in oklch, var(--color-base-content) 50%, transparent)', textTransform: 'uppercase', letterSpacing: '0.05em', cursor: 'grab' }}\n >\n Inspector\n </div>\n <div className=\"flow-inspector-content\">\n <InspectorPanelContent />\n </div>\n </div>\n );\n}\n\n/** Reusable content for embedding inside FlowPanelGroup tabs. */\nexport function InspectorPanelContent() {\n const { currentCanvas, selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n\n const selectedNodes = useMemo(\n () => currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id)),\n [currentCanvas.nodes, selection.nodeIds],\n );\n const selectedEdges = useMemo(\n () => currentCanvas.edges.filter(e => selection.edgeIds.has(e.id)),\n [currentCanvas.edges, selection.edgeIds],\n );\n const selectedLines = useMemo(\n () => currentCanvas.lines.filter(l => selection.lineIds.has(l.id)),\n [currentCanvas.lines, selection.lineIds],\n );\n\n const hasSelection = selectedNodes.length > 0 || selectedEdges.length > 0 || selectedLines.length > 0;\n const singleIsGroup = selectedNodes.length === 1 && (selectedNodes[0].type === 'flowGroup' || selectedNodes[0].type === 'geometryGroup' || selectedNodes[0].data.isGroup);\n\n const totalSelected = selectedNodes.length + selectedLines.length;\n\n const handleGroup = (type: 'flowGroup' | 'geometryGroup' = 'flowGroup') => {\n if (totalSelected < 2) return;\n const PAD = 20;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of selectedNodes) {\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + n.width);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n for (const l of selectedLines) {\n for (const p of l.points) {\n minX = Math.min(minX, p.x); minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y);\n }\n }\n const isGeo = type === 'geometryGroup';\n const groupId = generateId('group');\n const groupNode: FlowNode = {\n id: groupId,\n type,\n position: { x: minX - PAD, y: minY - PAD },\n width: maxX - minX + PAD * 2,\n height: maxY - minY + PAD * 2,\n data: {\n ...DEFAULT_NODE_DATA,\n label: isGeo ? 'Geo Group' : 'Group',\n fill: isGeo ? '#fefce8' : '#f0f9ff',\n stroke: '#9ca3af', strokeWidth: 1.5,\n borderStyle: isGeo ? 'dashed' : 'dotted',\n isGroup: true,\n },\n };\n const nIds = selection.nodeIds;\n const lIds = selection.lineIds;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: isGeo\n ? [groupNode, ...canvas.nodes]\n : [groupNode, ...canvas.nodes.map(n => nIds.has(n.id) ? { ...n, parentId: groupId } : n)],\n lines: isGeo\n ? canvas.lines\n : canvas.lines.map(l => lIds.has(l.id) ? { ...l, parentId: groupId } : l),\n }},\n };\n });\n setSelection({ nodeIds: new Set([groupId]), edgeIds: new Set(), lineIds: new Set() });\n };\n\n const handleUngroup = () => {\n const groupIds = new Set<string>();\n const childNodeIds = new Set<string>();\n const childLineIds = new Set<string>();\n for (const n of selectedNodes) {\n if (n.type === 'flowGroup' || n.type === 'geometryGroup' || n.data.isGroup) groupIds.add(n.id);\n }\n if (groupIds.size === 0) return;\n for (const n of currentCanvas.nodes) {\n if (n.parentId && groupIds.has(n.parentId)) childNodeIds.add(n.id);\n }\n for (const l of currentCanvas.lines) {\n if (l.parentId && groupIds.has(l.parentId)) childLineIds.add(l.id);\n }\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !groupIds.has(n.id))\n .map(n => childNodeIds.has(n.id) ? { ...n, parentId: undefined } : n),\n lines: canvas.lines\n .map(l => childLineIds.has(l.id) ? { ...l, parentId: undefined } : l),\n }},\n };\n });\n setSelection({ nodeIds: childNodeIds, edgeIds: new Set(), lineIds: childLineIds });\n };\n\n const changeNodeZIndex = (mode: 'front' | 'back' | 'up' | 'down') => {\n const ids = selection.nodeIds;\n if (ids.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const allZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const maxZ = allZ.length > 0 ? Math.max(...allZ) : 0;\n const minZ = allZ.length > 0 ? Math.min(...allZ) : 0;\n const nodes = canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n const z = n.zIndex ?? 0;\n let newZ = z;\n if (mode === 'front') newZ = maxZ + 1;\n else if (mode === 'back') newZ = minZ - 1;\n else if (mode === 'up') newZ = z + 1;\n else if (mode === 'down') newZ = z - 1;\n return { ...n, zIndex: newZ };\n });\n return { ...prev, canvases: { ...prev.canvases, [currentCanvasId]: { ...canvas, nodes } } };\n });\n };\n\n const changeLineZIndex = (mode: 'front' | 'back' | 'up' | 'down') => {\n const ids = selection.lineIds;\n if (ids.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const allZ = canvas.lines.map(l => l.zIndex ?? 0);\n const maxZ = allZ.length > 0 ? Math.max(...allZ) : 0;\n const minZ = allZ.length > 0 ? Math.min(...allZ) : 0;\n const lines = canvas.lines.map(l => {\n if (!ids.has(l.id)) return l;\n const z = l.zIndex ?? 0;\n let newZ = z;\n if (mode === 'front') newZ = maxZ + 1;\n else if (mode === 'back') newZ = minZ - 1;\n else if (mode === 'up') newZ = z + 1;\n else if (mode === 'down') newZ = z - 1;\n return { ...l, zIndex: newZ };\n });\n return { ...prev, canvases: { ...prev.canvases, [currentCanvasId]: { ...canvas, lines } } };\n });\n };\n\n const updateNodeData = (nodeId: string, key: string, value: any) => {\n updateNodeDataBatch(nodeId, { [key]: value });\n };\n\n const updateNodeDataBatch = (nodeId: string, values: Record<string, any>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n =>\n n.id === nodeId ? { ...n, data: { ...n.data, ...values } } : n,\n ),\n },\n },\n };\n });\n };\n\n const updateNodeDimension = (nodeId: string, key: 'width' | 'height', value: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n =>\n n.id === nodeId ? { ...n, [key]: value } : n,\n ),\n },\n },\n };\n });\n };\n\n const updateEdgeData = (edgeId: string, key: string, value: any) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e =>\n e.id === edgeId ? { ...e, data: { ...e.data, [key]: value } } : e,\n ),\n },\n },\n };\n });\n };\n\n const updateNodeType = (nodeId: string, type: FlowShapeType) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(node => node.id === nodeId ? { ...node, type } : node),\n },\n },\n };\n });\n };\n\n const updateEdgeType = (edgeId: string, type: string) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e =>\n e.id === edgeId ? { ...e, type: type as any } : e,\n ),\n },\n },\n };\n });\n };\n\n const updateLineData = (lineId: string, key: string, value: any) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.map(l =>\n l.id === lineId ? { ...l, [key]: value } : l,\n ),\n },\n },\n };\n });\n };\n\n return (\n <>\n {!hasSelection && (\n <div style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 40%, transparent)', textAlign: 'center', padding: '20px 0' }}>\n Select an element to inspect\n </div>\n )}\n\n {selectedNodes.length === 1 && (\n <NodeInspector\n node={selectedNodes[0]}\n isGroup={singleIsGroup}\n onUpdateData={updateNodeData}\n onUpdateDataBatch={updateNodeDataBatch}\n onUpdateDimension={updateNodeDimension}\n onUpdateType={updateNodeType}\n />\n )}\n {totalSelected > 1 && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Selection</div>\n <div style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 50%, transparent)', marginBottom: 8 }}>\n {selectedNodes.length > 0 && `${selectedNodes.length} node${selectedNodes.length > 1 ? 's' : ''}`}\n {selectedNodes.length > 0 && selectedLines.length > 0 && ', '}\n {selectedLines.length > 0 && `${selectedLines.length} line${selectedLines.length > 1 ? 's' : ''}`}\n {' selected'}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, width: '100%' }}>\n <Button size=\"xs\" onClick={() => handleGroup('flowGroup')} block>\n Group (⌘G)\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => handleGroup('geometryGroup')} block>\n Geo Group (⌘⌥G)\n </Button>\n </div>\n </div>\n )}\n {singleIsGroup && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">\n {selectedNodes[0].type === 'geometryGroup' ? 'Geometry Group' : 'Group'}\n </div>\n <div style={{ fontSize: 11, color: 'color-mix(in oklch, var(--color-base-content) 45%, transparent)', marginBottom: 6 }}>\n {selectedNodes[0].type === 'geometryGroup'\n ? 'Auto-binds spatially contained nodes'\n : 'Explicit membership via add/remove'}\n </div>\n <Button size=\"xs\" variant=\"ghost\" onClick={handleUngroup} block>\n Ungroup (⌘⇧G)\n </Button>\n </div>\n )}\n\n {selectedNodes.length > 0 && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Layer</div>\n <div style={{ display: 'flex', gap: 4 }}>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('front')}>\n <span title=\"Bring to Front (⌘⇧↑)\">⤒</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('up')}>\n <span title=\"Bring Forward (⌘↑)\">↑</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('down')}>\n <span title=\"Send Backward (⌘↓)\">↓</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('back')}>\n <span title=\"Send to Back (⌘⇧↓)\">⤓</span>\n </Button>\n </div>\n </div>\n )}\n\n {selectedEdges.length === 1 && (\n <EdgeInspector\n edge={selectedEdges[0]}\n onUpdateData={updateEdgeData}\n onUpdateType={updateEdgeType}\n />\n )}\n\n {selectedLines.length === 1 && (\n <>\n <LineInspector\n line={selectedLines[0]}\n onUpdateData={updateLineData}\n />\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Layer</div>\n <div style={{ display: 'flex', gap: 4 }}>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('front')}>\n <span title=\"Bring to Front\">⤒</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('up')}>\n <span title=\"Bring Forward\">↑</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('down')}>\n <span title=\"Send Backward\">↓</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('back')}>\n <span title=\"Send to Back\">⤓</span>\n </Button>\n </div>\n </div>\n </>\n )}\n </>\n );\n}\n\n/**\n * A color field for Flow node/edge styling. Layout (left → right):\n * 1. Theme-sync swatch — follows the active theme (per-field role), the\n * default choice for new shapes.\n * 2. Common colors — 黑白赤橙黄绿青蓝紫粉.\n * 3. Custom picker — arbitrary color from the OS color dialog.\n * (Optional) Transparent — for fill/stroke.\n * Every swatch shows a descriptive tooltip on hover.\n */\nfunction ThemeColorField({\n value,\n onChange,\n kind,\n allowTransparent,\n customFallback = '#ffffff',\n}: {\n value: string | undefined;\n onChange: (value: string) => void;\n kind: ThemeColorFieldKind;\n allowTransparent?: boolean;\n customFallback?: string;\n}) {\n const syncToken = THEME_SYNC_TOKEN[kind];\n const syncCssVar = themeTokenCssVar(syncToken) ?? 'var(--color-base-content)';\n\n const rawValue = value ?? '';\n const lowerValue = rawValue.toLowerCase();\n const valueIsToken = isThemeToken(rawValue);\n const isTransparent = rawValue === 'transparent';\n const isCommon = COMMON_COLORS.some((c) => c.value.toLowerCase() === lowerValue);\n const isSync = rawValue === syncToken;\n const isCustom = !!rawValue && !valueIsToken && !isTransparent && !isCommon;\n const pickerValue = isCustom ? rawValue : customFallback;\n\n return (\n <div className=\"flow-color-field\">\n {/* 1. 主题同步色 */}\n <button\n type=\"button\"\n title=\"跟随主题切换\"\n aria-label=\"跟随主题切换\"\n className={`flow-color-swatch flow-color-swatch--sync${isSync ? ' is-active' : ''}`}\n style={{ background: syncCssVar }}\n onClick={() => onChange(syncToken)}\n />\n\n <span className=\"flow-color-divider\" />\n\n {/* 2. 常用颜色 */}\n {COMMON_COLORS.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n title={c.label}\n aria-label={c.label}\n className={`flow-color-swatch${!valueIsToken && !isTransparent && lowerValue === c.value.toLowerCase() ? ' is-active' : ''}`}\n style={{ background: c.value }}\n onClick={() => onChange(c.value)}\n />\n ))}\n\n <span className=\"flow-color-divider\" />\n\n {/* 3. 自定义取色 */}\n <label\n className={`flow-color-swatch flow-color-swatch--custom${isCustom ? ' is-active' : ''}`}\n title=\"自定义颜色\"\n style={isCustom ? { background: rawValue } : undefined}\n >\n <input\n type=\"color\"\n value={pickerValue}\n onChange={(e) => onChange(e.target.value)}\n />\n </label>\n\n {/* 可选:透明 */}\n {allowTransparent && (\n <button\n type=\"button\"\n title=\"透明\"\n aria-label=\"透明\"\n className={`flow-color-swatch flow-color-swatch--transparent${isTransparent ? ' is-active' : ''}`}\n onClick={() => onChange('transparent')}\n />\n )}\n </div>\n );\n}\n\n/** Data-URL preview of a registry icon for picker thumbnails. */\nfunction titleIconThumbUrl(id: string): string {\n const def = getSvgIcon(id);\n const brand = resolveThemeColor(def?.brandColor, '') || '#475569';\n const markup = buildSvgMarkup(id, brand);\n return markup ? `data:image/svg+xml;utf8,${encodeURIComponent(markup)}` : '';\n}\n\n/** Configure the optional glyph rendered beside a shape node's title text:\n * pick from the built-in registry, then side / size / color. */\nfunction TitleIconSection({\n node,\n onUpdateData,\n}: {\n node: FlowNode;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n const [cat, setCat] = useState<SvgIconCategory>('lang');\n const icons = useMemo(() => getSvgIconsByCategory(cat), [cat]);\n const current = node.data.titleIcon ?? '';\n const side = node.data.titleIconSide ?? 'left';\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Title Icon</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Icon</Label>\n <div style={{ display: 'flex', gap: 4, alignItems: 'center', flex: 1, minWidth: 0 }}>\n <Select\n options={SVG_ICON_CATEGORIES.map(c => ({ value: c.id, label: c.label }))}\n value={cat}\n onChange={(v) => setCat(v as SvgIconCategory)}\n style={{ fontSize: 12, flex: 1, minWidth: 0 }}\n />\n <Button\n size=\"xs\"\n variant={current ? 'ghost' : 'primary'}\n square\n onClick={() => onUpdateData(node.id, 'titleIcon', undefined)}\n >\n <span title=\"移除标题图标\">✕</span>\n </Button>\n </div>\n </div>\n {current && !icons.some(ic => ic.id === current) && (\n <div style={{ fontSize: 10, opacity: 0.55, marginBottom: 4 }}>\n 当前图标在其他分类\n </div>\n )}\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(22px, 1fr))',\n gap: 3,\n maxHeight: 92,\n overflowY: 'auto',\n padding: 3,\n border: '1px solid color-mix(in oklch, var(--color-base-content) 14%, transparent)',\n borderRadius: 6,\n marginBottom: 6,\n }}\n >\n {icons.map((ic) => {\n const url = titleIconThumbUrl(ic.id);\n const active = current === ic.id;\n return (\n <button\n key={ic.id}\n type=\"button\"\n title={ic.label}\n aria-label={ic.label}\n onClick={() => onUpdateData(node.id, 'titleIcon', ic.id)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 22,\n height: 22,\n borderRadius: 4,\n cursor: 'pointer',\n padding: 0,\n border: active ? '1.5px solid var(--color-primary)' : '1px solid transparent',\n background: active ? 'color-mix(in oklch, var(--color-primary) 12%, transparent)' : 'transparent',\n }}\n >\n {url && <img src={url} width={16} height={16} alt=\"\" style={{ objectFit: 'contain' }} />}\n </button>\n );\n })}\n </div>\n {current && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Side</Label>\n <Select\n options={[\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n ]}\n value={side}\n onChange={(v) => onUpdateData(node.id, 'titleIconSide', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Size</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.titleIconSize ?? Math.max(8, Math.round(node.data.fontSize * 1.15)))}\n onChange={(e) => onUpdateData(node.id, 'titleIconSize', Math.max(8, Number(e.target.value) || 8))}\n />\n <span className=\"flow-inspector-suffix\" style={{ fontSize: 10, opacity: 0.5 }}>px</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={node.data.titleIconColor\n ?? getSvgIcon(current)?.brandColor\n ?? node.data.labelColor\n ?? node.data.color}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => onUpdateData(node.id, 'titleIconColor', v)}\n />\n </div>\n </>\n )}\n </div>\n );\n}\n\nfunction NodeInspector({\n node,\n isGroup,\n onUpdateData,\n onUpdateDataBatch,\n onUpdateDimension,\n onUpdateType,\n}: {\n node: FlowNode;\n isGroup?: boolean;\n onUpdateData: (id: string, key: string, value: any) => void;\n onUpdateDataBatch: (id: string, values: Record<string, any>) => void;\n onUpdateDimension: (id: string, key: 'width' | 'height', value: number) => void;\n onUpdateType: (id: string, type: FlowShapeType) => void;\n}) {\n return (\n <>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Node</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Input\n size=\"xs\"\n value={node.data.label}\n onChange={(e) => onUpdateData(node.id, 'label', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <Select\n options={FLOW_NODE_TYPES.map(type => ({ value: type, label: type }))}\n value={node.type}\n onChange={(value) => onUpdateType(node.id, value as FlowShapeType)}\n style={{ fontSize: 12 }}\n />\n </div>\n </div>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Size</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">W</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(Math.round(node.width * 100) / 100)}\n onChange={(e) => onUpdateDimension(node.id, 'width', Number(e.target.value) || node.width)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">H</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(Math.round(node.height * 100) / 100)}\n onChange={(e) => onUpdateDimension(node.id, 'height', Number(e.target.value) || node.height)}\n />\n </div>\n </div>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Style</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Fill</Label>\n <ThemeColorField\n value={node.data.fill}\n kind=\"fill\"\n allowTransparent\n customFallback=\"#ffffff\"\n onChange={(v) => onUpdateData(node.id, 'fill', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Stroke</Label>\n <ThemeColorField\n value={node.data.stroke}\n kind=\"stroke\"\n allowTransparent\n customFallback=\"#000000\"\n onChange={(v) => onUpdateData(node.id, 'stroke', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Font</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.fontSize)}\n onChange={(e) => onUpdateData(node.id, 'fontSize', Number(e.target.value) || 14)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={node.data.color}\n kind=\"text\"\n customFallback=\"#111827\"\n onChange={(v) => onUpdateData(node.id, 'color', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Font Color</Label>\n <ThemeColorField\n value={node.data.labelColor ?? node.data.color}\n kind=\"text\"\n customFallback=\"#111827\"\n onChange={(v) => onUpdateData(node.id, 'labelColor', v)}\n />\n </div>\n {node.type !== 'shapeSvg' && node.type !== 'mediaNode' && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Pos</Label>\n <Select\n options={[\n { value: 'center', label: 'center' },\n { value: 'top', label: 'top' },\n { value: 'bottom', label: 'bottom' },\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n { value: 'top-left', label: 'top-left' },\n { value: 'top-right', label: 'top-right' },\n { value: 'bottom-left', label: 'bottom-left' },\n { value: 'bottom-right', label: 'bottom-right' },\n ]}\n value={node.data.textPlacement ?? ((isGroup || node.type === 'animAnchor') ? 'top' : 'center')}\n onChange={(v) => onUpdateData(node.id, 'textPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Off X</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetX ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'labelOffsetX', Number(e.target.value) || 0)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Off Y</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetY ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'labelOffsetY', Number(e.target.value) || 0)}\n />\n </div>\n </>\n )}\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Border</Label>\n <Select\n options={[{ value: 'none', label: 'none' }, ...BORDER_STYLE_OPTIONS.map(s => ({ value: s, label: s }))]}\n value={node.data.borderStyle ?? (isGroup ? (node.type === 'geometryGroup' ? 'dashed' : 'dotted') : 'solid')}\n onChange={(v) => onUpdateData(node.id, 'borderStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n {BORDER_SIDE_TYPES.has(node.type) && (() => {\n const sides = node.data.borderSides ?? {};\n const updateSide = (name: BorderSideName, patch: Partial<FlowBorderSideOverride>) => {\n onUpdateData(node.id, 'borderSides', {\n ...node.data.borderSides,\n [name]: { ...node.data.borderSides?.[name], ...patch },\n });\n };\n const sideLabels: Record<BorderSideName, string> = { top: 'Top', right: 'Right', bottom: 'Bottom', left: 'Left' };\n return (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Sides</Label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, flex: 1 }}>\n <span style={{ fontSize: 10, opacity: 0.55 }}>上下左右独立边框</span>\n {hasBorderSideOverrides(node.data, node.type) && (\n <span title=\"恢复与 Border 设置一致\" style={{ display: 'inline-flex' }}>\n <Button\n size=\"xs\"\n variant=\"ghost\"\n onClick={() => onUpdateData(node.id, 'borderSides', undefined)}\n >\n 重置\n </Button>\n </span>\n )}\n </div>\n </div>\n {BORDER_SIDE_NAMES.map((name) => {\n const override = sides[name];\n return (\n <div key={name} style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>\n <span\n title={`独立设置${sideLabels[name]}边`}\n style={{ fontSize: 10, width: 40, flexShrink: 0, opacity: override ? 0.95 : 0.6 }}\n >\n {sideLabels[name]}\n </span>\n <span title={`显示/隐藏 ${sideLabels[name]} 边`} style={{ display: 'inline-flex' }}>\n <Checkbox\n size=\"sm\"\n checked={override?.visible ?? true}\n onChange={(v) => updateSide(name, { visible: v })}\n />\n </span>\n <ThemeColorField\n value={override?.color ?? node.data.stroke}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => updateSide(name, { color: v })}\n />\n <span title={`${sideLabels[name]} 粗细`} style={{ display: 'inline-flex', width: 52 }}>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(override?.width ?? node.data.strokeWidth)}\n onChange={(e) => updateSide(name, { width: Math.max(0, Number(e.target.value) || 0) })}\n />\n </span>\n </div>\n );\n })}\n </>\n );\n })()}\n {node.type === 'shapeSvg' && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Icon</Label>\n <Select\n options={getAllSvgIcons().map(icon => ({ value: icon.id, label: icon.label }))}\n value={node.data.svgId ?? ''}\n placeholder=\"选择图标\"\n onChange={(value) => {\n const icon = getSvgIcon(String(value));\n onUpdateDataBatch(node.id, {\n svgId: value,\n ...(icon?.brandColor ? { color: icon.brandColor } : {}),\n ...(!node.data.label || node.data.label === 'Text' ? { label: icon?.label ?? String(value) } : {}),\n });\n }}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Box</Label>\n <Checkbox\n size=\"sm\"\n checked={node.data.iconBox ?? false}\n onChange={(v) => onUpdateData(node.id, 'iconBox', v)}\n label=\"显示边框\"\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Select\n options={[\n { value: 'top', label: 'top' },\n { value: 'middle', label: 'middle' },\n { value: 'bottom', label: 'bottom' },\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n ]}\n value={node.data.labelPlacement === ('above' as any)\n ? 'top'\n : node.data.labelPlacement === ('center' as any)\n ? 'middle'\n : node.data.labelPlacement === ('below' as any)\n ? 'bottom'\n : (node.data.labelPlacement ?? 'bottom')}\n onChange={(v) => onUpdateData(node.id, 'labelPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Offset X</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetX ?? 0)}\n onChange={(event) => onUpdateData(node.id, 'labelOffsetX', Number(event.target.value) || 0)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Offset Y</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetY ?? 0)}\n onChange={(event) => onUpdateData(node.id, 'labelOffsetY', Number(event.target.value) || 0)}\n />\n </div>\n </>\n )}\n\n </div>\n {node.type === 'mediaNode' && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Palette (Archify)</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Palette</Label>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {ARCHIFY_COMPONENT_ORDER.map((kind) => (\n <button\n key={kind}\n type=\"button\"\n title={ARCHIFY_COMPONENT_LABELS[kind]}\n aria-label={ARCHIFY_COMPONENT_LABELS[kind]}\n onClick={() => onUpdateDataBatch(node.id, archifyStylePatch(kind))}\n style={{\n width: 18,\n height: 18,\n borderRadius: 4,\n cursor: 'pointer',\n background: COMPONENT_STYLES[kind].fill,\n border: `1.5px solid ${COMPONENT_STYLES[kind].stroke}`,\n }}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n {node.type !== 'mediaNode' && node.type !== 'shapeSvg' && (\n <TitleIconSection node={node} onUpdateData={onUpdateData} />\n )}\n {node.type !== 'mediaNode' && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Card (Archify)</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Subtitle</Label>\n <Input\n size=\"xs\"\n value={node.data.sublabel ?? ''}\n placeholder=\"secondary line\"\n onChange={(e) => onUpdateData(node.id, 'sublabel', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Sub Color</Label>\n <ThemeColorField\n value={node.data.sublabelColor ?? '#94a3b8'}\n kind=\"text\"\n customFallback=\"#94a3b8\"\n onChange={(v) => onUpdateData(node.id, 'sublabelColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag</Label>\n <Input\n size=\"xs\"\n value={node.data.tag ?? ''}\n placeholder=\"corner pill\"\n onChange={(e) => onUpdateData(node.id, 'tag', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag Color</Label>\n <ThemeColorField\n value={node.data.tagColor ?? node.data.stroke}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => onUpdateData(node.id, 'tagColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag Pos</Label>\n <Select\n options={[\n { value: 'top-left', label: 'top-left' },\n { value: 'top-right', label: 'top-right' },\n { value: 'bottom-left', label: 'bottom-left' },\n { value: 'bottom-right', label: 'bottom-right' },\n ]}\n value={node.data.tagPlacement ?? 'top-right'}\n onChange={(v) => onUpdateData(node.id, 'tagPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Palette</Label>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {ARCHIFY_COMPONENT_ORDER.map((kind) => (\n <button\n key={kind}\n type=\"button\"\n title={ARCHIFY_COMPONENT_LABELS[kind]}\n aria-label={ARCHIFY_COMPONENT_LABELS[kind]}\n onClick={() => onUpdateDataBatch(node.id, archifyStylePatch(kind))}\n style={{\n width: 18,\n height: 18,\n borderRadius: 4,\n cursor: 'pointer',\n background: COMPONENT_STYLES[kind].fill,\n border: `1.5px solid ${COMPONENT_STYLES[kind].stroke}`,\n }}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n {node.type === 'mediaNode' && (\n <MediaInspectorSection node={node} onUpdateData={onUpdateData} />\n )}\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Transform</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Rotate</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.rotation ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'rotation', Number(e.target.value) || 0)}\n />\n <span className=\"flow-inspector-suffix\" style={{ fontSize: 10, opacity: 0.5 }}>°</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Flip</Label>\n <Button\n size=\"xs\"\n variant={node.data.flipX ? 'primary' : 'ghost'}\n onClick={() => onUpdateData(node.id, 'flipX', !node.data.flipX)}\n square\n >\n <span title=\"Flip Horizontal\">↔</span>\n </Button>\n <Button\n size=\"xs\"\n variant={node.data.flipY ? 'primary' : 'ghost'}\n onClick={() => onUpdateData(node.id, 'flipY', !node.data.flipY)}\n square\n >\n <span title=\"Flip Vertical\">↕</span>\n </Button>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Quick</Label>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => onUpdateData(node.id, 'rotation', ((node.data.rotation ?? 0) + 90) % 360)}>\n +90°\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => onUpdateData(node.id, 'rotation', ((node.data.rotation ?? 0) - 90 + 360) % 360)}>\n −90°\n </Button>\n </div>\n </div>\n </>\n );\n}\n\nfunction MediaInspectorSection({\n node,\n onUpdateData,\n}: {\n node: FlowNode;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n const kind = node.data.mediaKind ?? 'markdown';\n const ai = node.data.aiConfig;\n const modelFileInputRef = useRef<HTMLInputElement>(null);\n\n const updateAI = (key: string, value: any) => {\n onUpdateData(node.id, 'aiConfig', {\n gateway: '', protocol: 'openai', model: '',\n ...ai,\n [key]: value,\n });\n };\n\n const contentLabels: Record<string, string> = {\n markdown: 'Markdown 源码',\n html: 'HTML 源码',\n mermaid: 'Mermaid 图表',\n math: 'LaTeX 公式',\n };\n\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Media · {kind}</div>\n {kind === 'data' ? (\n <DataInspectorSection node={node} onUpdateData={onUpdateData} />\n ) : kind === 'model3d' ? (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">格式</Label>\n <Select\n options={[\n { value: 'stl', label: 'STL' },\n { value: 'obj', label: 'OBJ' },\n { value: '3mf', label: '3MF' },\n ]}\n value={node.data.modelFormat ?? 'stl'}\n onChange={value => onUpdateData(node.id, 'modelFormat', value)}\n />\n </div>\n <div className=\"flow-inspector-row flow-inspector-multiline\">\n <Label size=\"xs\" className=\"flow-inspector-label\">模型链接</Label>\n <Input\n size=\"xs\"\n value={node.data.mediaContent ?? ''}\n placeholder=\"https://example.com/model.stl\"\n onChange={event => onUpdateData(node.id, 'mediaContent', event.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">本地模型</Label>\n <input\n ref={modelFileInputRef}\n type=\"file\"\n accept=\".stl,.obj,.3mf,model/stl,model/obj,model/3mf,application/vnd.ms-package.3dmanufacturing-3dmodel+xml\"\n hidden\n onChange={event => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (!file) return;\n if (file.size > 10 * 1024 * 1024) {\n window.alert('本地模型不能超过 10 MiB,请改用模型链接。');\n return;\n }\n const extension = file.name.split('.').pop()?.toLowerCase();\n if (extension !== 'stl' && extension !== 'obj' && extension !== '3mf') {\n window.alert('仅支持 STL、OBJ 和 3MF 模型。');\n return;\n }\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result !== 'string') return;\n onUpdateData(node.id, 'modelFormat', extension);\n onUpdateData(node.id, 'mediaContent', reader.result);\n };\n reader.onerror = () => window.alert('读取本地模型失败。');\n reader.readAsDataURL(file);\n }}\n />\n <Button size=\"xs\" variant=\"neutral\" onClick={() => modelFileInputRef.current?.click()}>\n 选择文件\n </Button>\n {node.data.mediaContent?.startsWith('data:') && (\n <span className=\"flow-inspector-file-status\">已嵌入</span>\n )}\n </div>\n <div className=\"flow-inspector-help\">支持 STL、OBJ、3MF;本地文件将以 Base64 嵌入文档,最大 10 MiB。选中节点后可在内部拖拽旋转、滚轮缩放。</div>\n </>\n ) : kind === 'image' ? (\n <>\n <div className=\"flow-inspector-row flow-inspector-multiline\">\n <Label size=\"xs\" className=\"flow-inspector-label\">图片链接</Label>\n <Input\n size=\"xs\"\n value={node.data.mediaContent ?? ''}\n placeholder=\"https://example.com/image.png\"\n onChange={(event) => onUpdateData(node.id, 'mediaContent', event.target.value)}\n />\n </div>\n <div className=\"flow-inspector-help\">支持 HTTP(S) 链接;选中图片节点后可直接粘贴图片并保存为 Base64。</div>\n </>\n ) : kind !== 'ai' ? (\n <ExpandableTextarea\n label={contentLabels[kind] ?? '内容'}\n value={node.data.mediaContent ?? ''}\n onChange={(value) => onUpdateData(node.id, 'mediaContent', value)}\n rows={8}\n />\n ) : (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">协议</Label>\n <Select\n options={[\n { value: 'openai', label: 'OpenAI 兼容' },\n { value: 'anthropic', label: 'Anthropic 兼容' },\n ]}\n value={ai?.protocol ?? 'openai'}\n onChange={(v) => updateAI('protocol', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">接口地址</Label>\n <Input\n size=\"xs\"\n value={ai?.gateway ?? ''}\n placeholder=\"https://api.openai.com/v1/chat/completions\"\n onChange={(e) => updateAI('gateway', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">模型</Label>\n <Input\n size=\"xs\"\n value={ai?.model ?? ''}\n placeholder=\"gpt-4o-mini\"\n onChange={(e) => updateAI('model', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">API Key</Label>\n <Input\n size=\"xs\"\n type=\"password\"\n value={ai?.apiKey ?? ''}\n placeholder=\"sk-...\"\n onChange={(e) => updateAI('apiKey', e.target.value)}\n />\n </div>\n <ExpandableTextarea\n label=\"System Prompt\"\n value={ai?.systemPrompt ?? ''}\n onChange={(value) => updateAI('systemPrompt', value)}\n rows={3}\n />\n <div style={{ fontSize: 10, color: 'color-mix(in oklch, var(--color-base-content) 45%, transparent)', marginTop: 4 }}>\n 密钥会随文档 JSON 一同导出,请谨慎分享。\n </div>\n </>\n )}\n </div>\n );\n}\n\nfunction EdgeInspector({\n edge,\n onUpdateData,\n onUpdateType,\n}: {\n edge: FlowEdge;\n onUpdateData: (id: string, key: string, value: any) => void;\n onUpdateType: (id: string, type: string) => void;\n}) {\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Edge</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <Select\n options={EDGE_TYPE_OPTIONS.map(t => ({ value: t, label: t }))}\n value={edge.type}\n onChange={(v) => onUpdateType(edge.id, v as string)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={edge.data.strokeColor}\n kind=\"line\"\n customFallback=\"#374151\"\n onChange={(v) => onUpdateData(edge.id, 'strokeColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Width</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(edge.data.strokeWidth ?? 2)}\n onChange={(e) => onUpdateData(edge.id, 'strokeWidth', Number(e.target.value) || 2)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Animation</Label>\n <Checkbox\n size=\"sm\"\n checked={edge.data.animated ?? false}\n onChange={(value) => onUpdateData(edge.id, 'animated', value)}\n label=\"预览时播放\"\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Line</Label>\n <Select\n options={EDGE_LINE_STYLE_OPTIONS.map(s => ({ value: s, label: s }))}\n value={edge.data.lineStyle ?? 'solid'}\n onChange={(v) => onUpdateData(edge.id, 'lineStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Start</Label>\n <Select\n options={EDGE_MARKER_OPTIONS.map(m => ({ value: m, label: m }))}\n value={edge.data.markerStart ?? 'none'}\n onChange={(v) => onUpdateData(edge.id, 'markerStart', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">End</Label>\n <Select\n options={EDGE_MARKER_OPTIONS.map(m => ({ value: m, label: m }))}\n value={edge.data.markerEnd ?? 'none'}\n onChange={(v) => onUpdateData(edge.id, 'markerEnd', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Input\n size=\"xs\"\n value={edge.data.labelText ?? ''}\n onChange={(e) => onUpdateData(edge.id, 'labelText', e.target.value)}\n placeholder=\"Edge label\"\n />\n </div>\n </div>\n );\n}\n\nfunction LineInspector({\n line,\n onUpdateData,\n}: {\n line: FlowLine;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Line</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <span style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 60%, transparent)' }}>{line.type}</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={line.strokeColor}\n kind=\"line\"\n customFallback=\"#374151\"\n onChange={(v) => onUpdateData(line.id, 'strokeColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Width</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(line.strokeWidth)}\n onChange={(e) => onUpdateData(line.id, 'strokeWidth', Number(e.target.value) || 2)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Style</Label>\n <Select\n options={EDGE_LINE_STYLE_OPTIONS.map(s => ({ value: s, label: s }))}\n value={line.lineStyle}\n onChange={(v) => onUpdateData(line.id, 'lineStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InspectorPanel.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/InspectorPanel.tsx"],"sourcesContent":["import React, { useMemo, useRef, useState } from 'react';\nimport Input from '../../../Input';\nimport Select from '../../../Select';\nimport Button from '../../../Button';\nimport Label from '../../../Label';\nimport Checkbox from '../../../Checkbox';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowAI } from '../context/FlowAIContext';\nimport { useDraggablePanel } from '../hooks/useDraggablePanel';\nimport { useResizablePanel } from '../hooks/useResizablePanel';\nimport { EDGE_LINE_STYLE_OPTIONS, EDGE_MARKER_OPTIONS, BORDER_STYLE_OPTIONS, EDGE_TYPE_OPTIONS, DEFAULT_NODE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\nimport { getAllSvgIcons, getSvgIcon, getSvgIconsByCategory, SVG_ICON_CATEGORIES, buildSvgMarkup, type SvgIconCategory } from '../nodes/svgIcons';\nimport { BORDER_SIDE_NAMES, BORDER_SIDE_TYPES, hasBorderSideOverrides, type BorderSideName } from '../nodes/shapes';\nimport { FLOW_NODE_TYPES, type FlowNode, type FlowEdge, type FlowLine, type FlowShapeType, type FlowBorderSideOverride, type FlowAIConfig } from '../types';\nimport { THEME_SYNC_TOKEN, COMMON_COLORS, isThemeToken, themeTokenCssVar, resolveThemeColor, type ThemeColorFieldKind } from '../utils/themeColor';\nimport { DataInspectorSection } from './DataInspectorSection';\nimport { ExpandableTextarea } from './ExpandableTextarea';\nimport {\n ARCHIFY_COMPONENT_ORDER,\n ARCHIFY_COMPONENT_LABELS,\n COMPONENT_STYLES,\n archifyStylePatch,\n} from '../archify';\n\n/**\n * Standalone panel (legacy). Prefer using InspectorPanelContent inside a FlowPanelGroup.\n */\nexport default function InspectorPanel() {\n const { showInspector } = useFlowUI();\n const { panelStyle, handleProps } = useDraggablePanel();\n const { panelWidth, resizeHandleProps } = useResizablePanel('left', 240);\n\n if (!showInspector) return null;\n\n return (\n <div className=\"flow-inspector\" data-flow-panel style={{ ...panelStyle, width: panelWidth }}>\n <div className=\"flow-panel-resize-handle flow-panel-resize-handle--left\" {...resizeHandleProps} />\n <div\n className=\"flow-panel-drag-handle\"\n {...handleProps}\n style={{ fontSize: 11, fontWeight: 600, marginBottom: 8, color: 'color-mix(in oklch, var(--color-base-content) 50%, transparent)', textTransform: 'uppercase', letterSpacing: '0.05em', cursor: 'grab' }}\n >\n Inspector\n </div>\n <div className=\"flow-inspector-content\">\n <InspectorPanelContent />\n </div>\n </div>\n );\n}\n\n/** Reusable content for embedding inside FlowPanelGroup tabs. */\nexport function InspectorPanelContent() {\n const { currentCanvas, selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n const { aiConfig, hasSharedConfig } = useFlowAI();\n\n const selectedNodes = useMemo(\n () => currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id)),\n [currentCanvas.nodes, selection.nodeIds],\n );\n const selectedEdges = useMemo(\n () => currentCanvas.edges.filter(e => selection.edgeIds.has(e.id)),\n [currentCanvas.edges, selection.edgeIds],\n );\n const selectedLines = useMemo(\n () => currentCanvas.lines.filter(l => selection.lineIds.has(l.id)),\n [currentCanvas.lines, selection.lineIds],\n );\n\n const hasSelection = selectedNodes.length > 0 || selectedEdges.length > 0 || selectedLines.length > 0;\n const singleIsGroup = selectedNodes.length === 1 && (selectedNodes[0].type === 'flowGroup' || selectedNodes[0].type === 'geometryGroup' || selectedNodes[0].data.isGroup);\n\n const totalSelected = selectedNodes.length + selectedLines.length;\n\n const handleGroup = (type: 'flowGroup' | 'geometryGroup' = 'flowGroup') => {\n if (totalSelected < 2) return;\n const PAD = 20;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of selectedNodes) {\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + n.width);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n for (const l of selectedLines) {\n for (const p of l.points) {\n minX = Math.min(minX, p.x); minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y);\n }\n }\n const isGeo = type === 'geometryGroup';\n const groupId = generateId('group');\n const groupNode: FlowNode = {\n id: groupId,\n type,\n position: { x: minX - PAD, y: minY - PAD },\n width: maxX - minX + PAD * 2,\n height: maxY - minY + PAD * 2,\n data: {\n ...DEFAULT_NODE_DATA,\n label: isGeo ? 'Geo Group' : 'Group',\n fill: isGeo ? '#fefce8' : '#f0f9ff',\n stroke: '#9ca3af', strokeWidth: 1.5,\n borderStyle: isGeo ? 'dashed' : 'dotted',\n isGroup: true,\n },\n };\n const nIds = selection.nodeIds;\n const lIds = selection.lineIds;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: isGeo\n ? [groupNode, ...canvas.nodes]\n : [groupNode, ...canvas.nodes.map(n => nIds.has(n.id) ? { ...n, parentId: groupId } : n)],\n lines: isGeo\n ? canvas.lines\n : canvas.lines.map(l => lIds.has(l.id) ? { ...l, parentId: groupId } : l),\n }},\n };\n });\n setSelection({ nodeIds: new Set([groupId]), edgeIds: new Set(), lineIds: new Set() });\n };\n\n const handleUngroup = () => {\n const groupIds = new Set<string>();\n const childNodeIds = new Set<string>();\n const childLineIds = new Set<string>();\n for (const n of selectedNodes) {\n if (n.type === 'flowGroup' || n.type === 'geometryGroup' || n.data.isGroup) groupIds.add(n.id);\n }\n if (groupIds.size === 0) return;\n for (const n of currentCanvas.nodes) {\n if (n.parentId && groupIds.has(n.parentId)) childNodeIds.add(n.id);\n }\n for (const l of currentCanvas.lines) {\n if (l.parentId && groupIds.has(l.parentId)) childLineIds.add(l.id);\n }\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !groupIds.has(n.id))\n .map(n => childNodeIds.has(n.id) ? { ...n, parentId: undefined } : n),\n lines: canvas.lines\n .map(l => childLineIds.has(l.id) ? { ...l, parentId: undefined } : l),\n }},\n };\n });\n setSelection({ nodeIds: childNodeIds, edgeIds: new Set(), lineIds: childLineIds });\n };\n\n const changeNodeZIndex = (mode: 'front' | 'back' | 'up' | 'down') => {\n const ids = selection.nodeIds;\n if (ids.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const allZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const maxZ = allZ.length > 0 ? Math.max(...allZ) : 0;\n const minZ = allZ.length > 0 ? Math.min(...allZ) : 0;\n const nodes = canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n const z = n.zIndex ?? 0;\n let newZ = z;\n if (mode === 'front') newZ = maxZ + 1;\n else if (mode === 'back') newZ = minZ - 1;\n else if (mode === 'up') newZ = z + 1;\n else if (mode === 'down') newZ = z - 1;\n return { ...n, zIndex: newZ };\n });\n return { ...prev, canvases: { ...prev.canvases, [currentCanvasId]: { ...canvas, nodes } } };\n });\n };\n\n const changeLineZIndex = (mode: 'front' | 'back' | 'up' | 'down') => {\n const ids = selection.lineIds;\n if (ids.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const allZ = canvas.lines.map(l => l.zIndex ?? 0);\n const maxZ = allZ.length > 0 ? Math.max(...allZ) : 0;\n const minZ = allZ.length > 0 ? Math.min(...allZ) : 0;\n const lines = canvas.lines.map(l => {\n if (!ids.has(l.id)) return l;\n const z = l.zIndex ?? 0;\n let newZ = z;\n if (mode === 'front') newZ = maxZ + 1;\n else if (mode === 'back') newZ = minZ - 1;\n else if (mode === 'up') newZ = z + 1;\n else if (mode === 'down') newZ = z - 1;\n return { ...l, zIndex: newZ };\n });\n return { ...prev, canvases: { ...prev.canvases, [currentCanvasId]: { ...canvas, lines } } };\n });\n };\n\n const updateNodeData = (nodeId: string, key: string, value: any) => {\n updateNodeDataBatch(nodeId, { [key]: value });\n };\n\n const updateNodeDataBatch = (nodeId: string, values: Record<string, any>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n =>\n n.id === nodeId ? { ...n, data: { ...n.data, ...values } } : n,\n ),\n },\n },\n };\n });\n };\n\n const updateNodeDimension = (nodeId: string, key: 'width' | 'height', value: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n =>\n n.id === nodeId ? { ...n, [key]: value } : n,\n ),\n },\n },\n };\n });\n };\n\n const updateEdgeData = (edgeId: string, key: string, value: any) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e =>\n e.id === edgeId ? { ...e, data: { ...e.data, [key]: value } } : e,\n ),\n },\n },\n };\n });\n };\n\n const updateNodeType = (nodeId: string, type: FlowShapeType) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(node => node.id === nodeId ? { ...node, type } : node),\n },\n },\n };\n });\n };\n\n const updateEdgeType = (edgeId: string, type: string) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e =>\n e.id === edgeId ? { ...e, type: type as any } : e,\n ),\n },\n },\n };\n });\n };\n\n const updateLineData = (lineId: string, key: string, value: any) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.map(l =>\n l.id === lineId ? { ...l, [key]: value } : l,\n ),\n },\n },\n };\n });\n };\n\n return (\n <>\n {!hasSelection && (\n <div style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 40%, transparent)', textAlign: 'center', padding: '20px 0' }}>\n Select an element to inspect\n </div>\n )}\n\n {selectedNodes.length === 1 && (\n <NodeInspector\n node={selectedNodes[0]}\n isGroup={singleIsGroup}\n onUpdateData={updateNodeData}\n onUpdateDataBatch={updateNodeDataBatch}\n onUpdateDimension={updateNodeDimension}\n onUpdateType={updateNodeType}\n globalAIConfig={aiConfig}\n useSharedAIConfig={hasSharedConfig}\n />\n )}\n {totalSelected > 1 && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Selection</div>\n <div style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 50%, transparent)', marginBottom: 8 }}>\n {selectedNodes.length > 0 && `${selectedNodes.length} node${selectedNodes.length > 1 ? 's' : ''}`}\n {selectedNodes.length > 0 && selectedLines.length > 0 && ', '}\n {selectedLines.length > 0 && `${selectedLines.length} line${selectedLines.length > 1 ? 's' : ''}`}\n {' selected'}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, width: '100%' }}>\n <Button size=\"xs\" onClick={() => handleGroup('flowGroup')} block>\n Group (⌘G)\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => handleGroup('geometryGroup')} block>\n Geo Group (⌘⌥G)\n </Button>\n </div>\n </div>\n )}\n {singleIsGroup && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">\n {selectedNodes[0].type === 'geometryGroup' ? 'Geometry Group' : 'Group'}\n </div>\n <div style={{ fontSize: 11, color: 'color-mix(in oklch, var(--color-base-content) 45%, transparent)', marginBottom: 6 }}>\n {selectedNodes[0].type === 'geometryGroup'\n ? 'Auto-binds spatially contained nodes'\n : 'Explicit membership via add/remove'}\n </div>\n <Button size=\"xs\" variant=\"ghost\" onClick={handleUngroup} block>\n Ungroup (⌘⇧G)\n </Button>\n </div>\n )}\n\n {selectedNodes.length > 0 && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Layer</div>\n <div style={{ display: 'flex', gap: 4 }}>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('front')}>\n <span title=\"Bring to Front (⌘⇧↑)\">⤒</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('up')}>\n <span title=\"Bring Forward (⌘↑)\">↑</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('down')}>\n <span title=\"Send Backward (⌘↓)\">↓</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeNodeZIndex('back')}>\n <span title=\"Send to Back (⌘⇧↓)\">⤓</span>\n </Button>\n </div>\n </div>\n )}\n\n {selectedEdges.length === 1 && (\n <EdgeInspector\n edge={selectedEdges[0]}\n onUpdateData={updateEdgeData}\n onUpdateType={updateEdgeType}\n />\n )}\n\n {selectedLines.length === 1 && (\n <>\n <LineInspector\n line={selectedLines[0]}\n onUpdateData={updateLineData}\n />\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Layer</div>\n <div style={{ display: 'flex', gap: 4 }}>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('front')}>\n <span title=\"Bring to Front\">⤒</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('up')}>\n <span title=\"Bring Forward\">↑</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('down')}>\n <span title=\"Send Backward\">↓</span>\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => changeLineZIndex('back')}>\n <span title=\"Send to Back\">⤓</span>\n </Button>\n </div>\n </div>\n </>\n )}\n </>\n );\n}\n\n/**\n * A color field for Flow node/edge styling. Layout (left → right):\n * 1. Theme-sync swatch — follows the active theme (per-field role), the\n * default choice for new shapes.\n * 2. Common colors — 黑白赤橙黄绿青蓝紫粉.\n * 3. Custom picker — arbitrary color from the OS color dialog.\n * (Optional) Transparent — for fill/stroke.\n * Every swatch shows a descriptive tooltip on hover.\n */\nfunction ThemeColorField({\n value,\n onChange,\n kind,\n allowTransparent,\n customFallback = '#ffffff',\n}: {\n value: string | undefined;\n onChange: (value: string) => void;\n kind: ThemeColorFieldKind;\n allowTransparent?: boolean;\n customFallback?: string;\n}) {\n const syncToken = THEME_SYNC_TOKEN[kind];\n const syncCssVar = themeTokenCssVar(syncToken) ?? 'var(--color-base-content)';\n\n const rawValue = value ?? '';\n const lowerValue = rawValue.toLowerCase();\n const valueIsToken = isThemeToken(rawValue);\n const isTransparent = rawValue === 'transparent';\n const isCommon = COMMON_COLORS.some((c) => c.value.toLowerCase() === lowerValue);\n const isSync = rawValue === syncToken;\n const isCustom = !!rawValue && !valueIsToken && !isTransparent && !isCommon;\n const pickerValue = isCustom ? rawValue : customFallback;\n\n return (\n <div className=\"flow-color-field\">\n {/* 1. 主题同步色 */}\n <button\n type=\"button\"\n title=\"跟随主题切换\"\n aria-label=\"跟随主题切换\"\n className={`flow-color-swatch flow-color-swatch--sync${isSync ? ' is-active' : ''}`}\n style={{ background: syncCssVar }}\n onClick={() => onChange(syncToken)}\n />\n\n <span className=\"flow-color-divider\" />\n\n {/* 2. 常用颜色 */}\n {COMMON_COLORS.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n title={c.label}\n aria-label={c.label}\n className={`flow-color-swatch${!valueIsToken && !isTransparent && lowerValue === c.value.toLowerCase() ? ' is-active' : ''}`}\n style={{ background: c.value }}\n onClick={() => onChange(c.value)}\n />\n ))}\n\n <span className=\"flow-color-divider\" />\n\n {/* 3. 自定义取色 */}\n <label\n className={`flow-color-swatch flow-color-swatch--custom${isCustom ? ' is-active' : ''}`}\n title=\"自定义颜色\"\n style={isCustom ? { background: rawValue } : undefined}\n >\n <input\n type=\"color\"\n value={pickerValue}\n onChange={(e) => onChange(e.target.value)}\n />\n </label>\n\n {/* 可选:透明 */}\n {allowTransparent && (\n <button\n type=\"button\"\n title=\"透明\"\n aria-label=\"透明\"\n className={`flow-color-swatch flow-color-swatch--transparent${isTransparent ? ' is-active' : ''}`}\n onClick={() => onChange('transparent')}\n />\n )}\n </div>\n );\n}\n\n/** Data-URL preview of a registry icon for picker thumbnails. */\nfunction titleIconThumbUrl(id: string): string {\n const def = getSvgIcon(id);\n const brand = resolveThemeColor(def?.brandColor, '') || '#475569';\n const markup = buildSvgMarkup(id, brand);\n return markup ? `data:image/svg+xml;utf8,${encodeURIComponent(markup)}` : '';\n}\n\n/** Configure the optional glyph rendered beside a shape node's title text:\n * pick from the built-in registry, then side / size / color. */\nfunction TitleIconSection({\n node,\n onUpdateData,\n}: {\n node: FlowNode;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n const [cat, setCat] = useState<SvgIconCategory>('lang');\n const icons = useMemo(() => getSvgIconsByCategory(cat), [cat]);\n const current = node.data.titleIcon ?? '';\n const side = node.data.titleIconSide ?? 'left';\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Title Icon</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Icon</Label>\n <div style={{ display: 'flex', gap: 4, alignItems: 'center', flex: 1, minWidth: 0 }}>\n <Select\n options={SVG_ICON_CATEGORIES.map(c => ({ value: c.id, label: c.label }))}\n value={cat}\n onChange={(v) => setCat(v as SvgIconCategory)}\n style={{ fontSize: 12, flex: 1, minWidth: 0 }}\n />\n <Button\n size=\"xs\"\n variant={current ? 'ghost' : 'primary'}\n square\n onClick={() => onUpdateData(node.id, 'titleIcon', undefined)}\n >\n <span title=\"移除标题图标\">✕</span>\n </Button>\n </div>\n </div>\n {current && !icons.some(ic => ic.id === current) && (\n <div style={{ fontSize: 10, opacity: 0.55, marginBottom: 4 }}>\n 当前图标在其他分类\n </div>\n )}\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(22px, 1fr))',\n gap: 3,\n maxHeight: 92,\n overflowY: 'auto',\n padding: 3,\n border: '1px solid color-mix(in oklch, var(--color-base-content) 14%, transparent)',\n borderRadius: 6,\n marginBottom: 6,\n }}\n >\n {icons.map((ic) => {\n const url = titleIconThumbUrl(ic.id);\n const active = current === ic.id;\n return (\n <button\n key={ic.id}\n type=\"button\"\n title={ic.label}\n aria-label={ic.label}\n onClick={() => onUpdateData(node.id, 'titleIcon', ic.id)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 22,\n height: 22,\n borderRadius: 4,\n cursor: 'pointer',\n padding: 0,\n border: active ? '1.5px solid var(--color-primary)' : '1px solid transparent',\n background: active ? 'color-mix(in oklch, var(--color-primary) 12%, transparent)' : 'transparent',\n }}\n >\n {url && <img src={url} width={16} height={16} alt=\"\" style={{ objectFit: 'contain' }} />}\n </button>\n );\n })}\n </div>\n {current && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Side</Label>\n <Select\n options={[\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n ]}\n value={side}\n onChange={(v) => onUpdateData(node.id, 'titleIconSide', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Size</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.titleIconSize ?? Math.max(8, Math.round(node.data.fontSize * 1.15)))}\n onChange={(e) => onUpdateData(node.id, 'titleIconSize', Math.max(8, Number(e.target.value) || 8))}\n />\n <span className=\"flow-inspector-suffix\" style={{ fontSize: 10, opacity: 0.5 }}>px</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={node.data.titleIconColor\n ?? getSvgIcon(current)?.brandColor\n ?? node.data.labelColor\n ?? node.data.color}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => onUpdateData(node.id, 'titleIconColor', v)}\n />\n </div>\n </>\n )}\n </div>\n );\n}\n\nfunction NodeInspector({\n node,\n isGroup,\n onUpdateData,\n onUpdateDataBatch,\n onUpdateDimension,\n onUpdateType,\n globalAIConfig,\n useSharedAIConfig,\n}: {\n node: FlowNode;\n isGroup?: boolean;\n onUpdateData: (id: string, key: string, value: any) => void;\n onUpdateDataBatch: (id: string, values: Record<string, any>) => void;\n onUpdateDimension: (id: string, key: 'width' | 'height', value: number) => void;\n onUpdateType: (id: string, type: FlowShapeType) => void;\n globalAIConfig: FlowAIConfig;\n useSharedAIConfig: boolean;\n}) {\n return (\n <>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Node</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Input\n size=\"xs\"\n value={node.data.label}\n onChange={(e) => onUpdateData(node.id, 'label', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <Select\n options={FLOW_NODE_TYPES.map(type => ({ value: type, label: type }))}\n value={node.type}\n onChange={(value) => onUpdateType(node.id, value as FlowShapeType)}\n style={{ fontSize: 12 }}\n />\n </div>\n </div>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Size</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">W</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(Math.round(node.width * 100) / 100)}\n onChange={(e) => onUpdateDimension(node.id, 'width', Number(e.target.value) || node.width)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">H</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(Math.round(node.height * 100) / 100)}\n onChange={(e) => onUpdateDimension(node.id, 'height', Number(e.target.value) || node.height)}\n />\n </div>\n </div>\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Style</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Fill</Label>\n <ThemeColorField\n value={node.data.fill}\n kind=\"fill\"\n allowTransparent\n customFallback=\"#ffffff\"\n onChange={(v) => onUpdateData(node.id, 'fill', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Stroke</Label>\n <ThemeColorField\n value={node.data.stroke}\n kind=\"stroke\"\n allowTransparent\n customFallback=\"#000000\"\n onChange={(v) => onUpdateData(node.id, 'stroke', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Font</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.fontSize)}\n onChange={(e) => onUpdateData(node.id, 'fontSize', Number(e.target.value) || 14)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={node.data.color}\n kind=\"text\"\n customFallback=\"#111827\"\n onChange={(v) => onUpdateData(node.id, 'color', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Font Color</Label>\n <ThemeColorField\n value={node.data.labelColor ?? node.data.color}\n kind=\"text\"\n customFallback=\"#111827\"\n onChange={(v) => onUpdateData(node.id, 'labelColor', v)}\n />\n </div>\n {node.type !== 'shapeSvg' && node.type !== 'mediaNode' && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Pos</Label>\n <Select\n options={[\n { value: 'center', label: 'center' },\n { value: 'top', label: 'top' },\n { value: 'bottom', label: 'bottom' },\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n { value: 'top-left', label: 'top-left' },\n { value: 'top-right', label: 'top-right' },\n { value: 'bottom-left', label: 'bottom-left' },\n { value: 'bottom-right', label: 'bottom-right' },\n ]}\n value={node.data.textPlacement ?? ((isGroup || node.type === 'animAnchor') ? 'top' : 'center')}\n onChange={(v) => onUpdateData(node.id, 'textPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Off X</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetX ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'labelOffsetX', Number(e.target.value) || 0)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Text Off Y</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetY ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'labelOffsetY', Number(e.target.value) || 0)}\n />\n </div>\n </>\n )}\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Border</Label>\n <Select\n options={[{ value: 'none', label: 'none' }, ...BORDER_STYLE_OPTIONS.map(s => ({ value: s, label: s }))]}\n value={node.data.borderStyle ?? (isGroup ? (node.type === 'geometryGroup' ? 'dashed' : 'dotted') : 'solid')}\n onChange={(v) => onUpdateData(node.id, 'borderStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n {BORDER_SIDE_TYPES.has(node.type) && (() => {\n const sides = node.data.borderSides ?? {};\n const updateSide = (name: BorderSideName, patch: Partial<FlowBorderSideOverride>) => {\n onUpdateData(node.id, 'borderSides', {\n ...node.data.borderSides,\n [name]: { ...node.data.borderSides?.[name], ...patch },\n });\n };\n const sideLabels: Record<BorderSideName, string> = { top: 'Top', right: 'Right', bottom: 'Bottom', left: 'Left' };\n return (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Sides</Label>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, flex: 1 }}>\n <span style={{ fontSize: 10, opacity: 0.55 }}>上下左右独立边框</span>\n {hasBorderSideOverrides(node.data, node.type) && (\n <span title=\"恢复与 Border 设置一致\" style={{ display: 'inline-flex' }}>\n <Button\n size=\"xs\"\n variant=\"ghost\"\n onClick={() => onUpdateData(node.id, 'borderSides', undefined)}\n >\n 重置\n </Button>\n </span>\n )}\n </div>\n </div>\n {BORDER_SIDE_NAMES.map((name) => {\n const override = sides[name];\n return (\n <div key={name} style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>\n <span\n title={`独立设置${sideLabels[name]}边`}\n style={{ fontSize: 10, width: 40, flexShrink: 0, opacity: override ? 0.95 : 0.6 }}\n >\n {sideLabels[name]}\n </span>\n <span title={`显示/隐藏 ${sideLabels[name]} 边`} style={{ display: 'inline-flex' }}>\n <Checkbox\n size=\"sm\"\n checked={override?.visible ?? true}\n onChange={(v) => updateSide(name, { visible: v })}\n />\n </span>\n <ThemeColorField\n value={override?.color ?? node.data.stroke}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => updateSide(name, { color: v })}\n />\n <span title={`${sideLabels[name]} 粗细`} style={{ display: 'inline-flex', width: 52 }}>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(override?.width ?? node.data.strokeWidth)}\n onChange={(e) => updateSide(name, { width: Math.max(0, Number(e.target.value) || 0) })}\n />\n </span>\n </div>\n );\n })}\n </>\n );\n })()}\n {node.type === 'shapeSvg' && (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Icon</Label>\n <Select\n options={getAllSvgIcons().map(icon => ({ value: icon.id, label: icon.label }))}\n value={node.data.svgId ?? ''}\n placeholder=\"选择图标\"\n onChange={(value) => {\n const icon = getSvgIcon(String(value));\n onUpdateDataBatch(node.id, {\n svgId: value,\n ...(icon?.brandColor ? { color: icon.brandColor } : {}),\n ...(!node.data.label || node.data.label === 'Text' ? { label: icon?.label ?? String(value) } : {}),\n });\n }}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Box</Label>\n <Checkbox\n size=\"sm\"\n checked={node.data.iconBox ?? false}\n onChange={(v) => onUpdateData(node.id, 'iconBox', v)}\n label=\"显示边框\"\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Select\n options={[\n { value: 'top', label: 'top' },\n { value: 'middle', label: 'middle' },\n { value: 'bottom', label: 'bottom' },\n { value: 'left', label: 'left' },\n { value: 'right', label: 'right' },\n ]}\n value={node.data.labelPlacement === ('above' as any)\n ? 'top'\n : node.data.labelPlacement === ('center' as any)\n ? 'middle'\n : node.data.labelPlacement === ('below' as any)\n ? 'bottom'\n : (node.data.labelPlacement ?? 'bottom')}\n onChange={(v) => onUpdateData(node.id, 'labelPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Offset X</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetX ?? 0)}\n onChange={(event) => onUpdateData(node.id, 'labelOffsetX', Number(event.target.value) || 0)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Offset Y</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.labelOffsetY ?? 0)}\n onChange={(event) => onUpdateData(node.id, 'labelOffsetY', Number(event.target.value) || 0)}\n />\n </div>\n </>\n )}\n\n </div>\n {node.type === 'mediaNode' && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Palette (Archify)</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Palette</Label>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {ARCHIFY_COMPONENT_ORDER.map((kind) => (\n <button\n key={kind}\n type=\"button\"\n title={ARCHIFY_COMPONENT_LABELS[kind]}\n aria-label={ARCHIFY_COMPONENT_LABELS[kind]}\n onClick={() => onUpdateDataBatch(node.id, archifyStylePatch(kind))}\n style={{\n width: 18,\n height: 18,\n borderRadius: 4,\n cursor: 'pointer',\n background: COMPONENT_STYLES[kind].fill,\n border: `1.5px solid ${COMPONENT_STYLES[kind].stroke}`,\n }}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n {node.type !== 'mediaNode' && node.type !== 'shapeSvg' && (\n <TitleIconSection node={node} onUpdateData={onUpdateData} />\n )}\n {node.type !== 'mediaNode' && (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Card (Archify)</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Subtitle</Label>\n <Input\n size=\"xs\"\n value={node.data.sublabel ?? ''}\n placeholder=\"secondary line\"\n onChange={(e) => onUpdateData(node.id, 'sublabel', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Sub Color</Label>\n <ThemeColorField\n value={node.data.sublabelColor ?? '#94a3b8'}\n kind=\"text\"\n customFallback=\"#94a3b8\"\n onChange={(v) => onUpdateData(node.id, 'sublabelColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag</Label>\n <Input\n size=\"xs\"\n value={node.data.tag ?? ''}\n placeholder=\"corner pill\"\n onChange={(e) => onUpdateData(node.id, 'tag', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag Color</Label>\n <ThemeColorField\n value={node.data.tagColor ?? node.data.stroke}\n kind=\"stroke\"\n customFallback=\"#334155\"\n onChange={(v) => onUpdateData(node.id, 'tagColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Tag Pos</Label>\n <Select\n options={[\n { value: 'top-left', label: 'top-left' },\n { value: 'top-right', label: 'top-right' },\n { value: 'bottom-left', label: 'bottom-left' },\n { value: 'bottom-right', label: 'bottom-right' },\n ]}\n value={node.data.tagPlacement ?? 'top-right'}\n onChange={(v) => onUpdateData(node.id, 'tagPlacement', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Palette</Label>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {ARCHIFY_COMPONENT_ORDER.map((kind) => (\n <button\n key={kind}\n type=\"button\"\n title={ARCHIFY_COMPONENT_LABELS[kind]}\n aria-label={ARCHIFY_COMPONENT_LABELS[kind]}\n onClick={() => onUpdateDataBatch(node.id, archifyStylePatch(kind))}\n style={{\n width: 18,\n height: 18,\n borderRadius: 4,\n cursor: 'pointer',\n background: COMPONENT_STYLES[kind].fill,\n border: `1.5px solid ${COMPONENT_STYLES[kind].stroke}`,\n }}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n {node.type === 'mediaNode' && (\n <MediaInspectorSection node={node} onUpdateData={onUpdateData} globalAIConfig={globalAIConfig} useSharedAIConfig={useSharedAIConfig} />\n )}\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Transform</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Rotate</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(node.data.rotation ?? 0)}\n onChange={(e) => onUpdateData(node.id, 'rotation', Number(e.target.value) || 0)}\n />\n <span className=\"flow-inspector-suffix\" style={{ fontSize: 10, opacity: 0.5 }}>°</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Flip</Label>\n <Button\n size=\"xs\"\n variant={node.data.flipX ? 'primary' : 'ghost'}\n onClick={() => onUpdateData(node.id, 'flipX', !node.data.flipX)}\n square\n >\n <span title=\"Flip Horizontal\">↔</span>\n </Button>\n <Button\n size=\"xs\"\n variant={node.data.flipY ? 'primary' : 'ghost'}\n onClick={() => onUpdateData(node.id, 'flipY', !node.data.flipY)}\n square\n >\n <span title=\"Flip Vertical\">↕</span>\n </Button>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Quick</Label>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => onUpdateData(node.id, 'rotation', ((node.data.rotation ?? 0) + 90) % 360)}>\n +90°\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => onUpdateData(node.id, 'rotation', ((node.data.rotation ?? 0) - 90 + 360) % 360)}>\n −90°\n </Button>\n </div>\n </div>\n </>\n );\n}\n\nfunction MediaInspectorSection({\n node,\n onUpdateData,\n globalAIConfig,\n useSharedAIConfig,\n}: {\n node: FlowNode;\n onUpdateData: (id: string, key: string, value: any) => void;\n globalAIConfig: FlowAIConfig;\n useSharedAIConfig: boolean;\n}) {\n const kind = node.data.mediaKind ?? 'markdown';\n const ai = useSharedAIConfig ? globalAIConfig : node.data.aiConfig;\n const modelFileInputRef = useRef<HTMLInputElement>(null);\n\n const updateAI = (key: string, value: any) => {\n onUpdateData(node.id, 'aiConfig', {\n gateway: '', protocol: 'openai', model: '',\n ...ai,\n [key]: value,\n });\n };\n\n const contentLabels: Record<string, string> = {\n markdown: 'Markdown 源码',\n html: 'HTML 源码',\n mermaid: 'Mermaid 图表',\n math: 'LaTeX 公式',\n };\n\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Media · {kind}</div>\n {kind === 'data' ? (\n <DataInspectorSection node={node} onUpdateData={onUpdateData} />\n ) : kind === 'model3d' ? (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">格式</Label>\n <Select\n options={[\n { value: 'stl', label: 'STL' },\n { value: 'obj', label: 'OBJ' },\n { value: '3mf', label: '3MF' },\n ]}\n value={node.data.modelFormat ?? 'stl'}\n onChange={value => onUpdateData(node.id, 'modelFormat', value)}\n />\n </div>\n <div className=\"flow-inspector-row flow-inspector-multiline\">\n <Label size=\"xs\" className=\"flow-inspector-label\">模型链接</Label>\n <Input\n size=\"xs\"\n value={node.data.mediaContent ?? ''}\n placeholder=\"https://example.com/model.stl\"\n onChange={event => onUpdateData(node.id, 'mediaContent', event.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">本地模型</Label>\n <input\n ref={modelFileInputRef}\n type=\"file\"\n accept=\".stl,.obj,.3mf,model/stl,model/obj,model/3mf,application/vnd.ms-package.3dmanufacturing-3dmodel+xml\"\n hidden\n onChange={event => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (!file) return;\n if (file.size > 10 * 1024 * 1024) {\n window.alert('本地模型不能超过 10 MiB,请改用模型链接。');\n return;\n }\n const extension = file.name.split('.').pop()?.toLowerCase();\n if (extension !== 'stl' && extension !== 'obj' && extension !== '3mf') {\n window.alert('仅支持 STL、OBJ 和 3MF 模型。');\n return;\n }\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result !== 'string') return;\n onUpdateData(node.id, 'modelFormat', extension);\n onUpdateData(node.id, 'mediaContent', reader.result);\n };\n reader.onerror = () => window.alert('读取本地模型失败。');\n reader.readAsDataURL(file);\n }}\n />\n <Button size=\"xs\" variant=\"neutral\" onClick={() => modelFileInputRef.current?.click()}>\n 选择文件\n </Button>\n {node.data.mediaContent?.startsWith('data:') && (\n <span className=\"flow-inspector-file-status\">已嵌入</span>\n )}\n </div>\n <div className=\"flow-inspector-help\">支持 STL、OBJ、3MF;本地文件将以 Base64 嵌入文档,最大 10 MiB。选中节点后可在内部拖拽旋转、滚轮缩放。</div>\n </>\n ) : kind === 'image' ? (\n <>\n <div className=\"flow-inspector-row flow-inspector-multiline\">\n <Label size=\"xs\" className=\"flow-inspector-label\">图片链接</Label>\n <Input\n size=\"xs\"\n value={node.data.mediaContent ?? ''}\n placeholder=\"https://example.com/image.png\"\n onChange={(event) => onUpdateData(node.id, 'mediaContent', event.target.value)}\n />\n </div>\n <div className=\"flow-inspector-help\">支持 HTTP(S) 链接;选中图片节点后可直接粘贴图片并保存为 Base64。</div>\n </>\n ) : kind !== 'ai' ? (\n <ExpandableTextarea\n label={contentLabels[kind] ?? '内容'}\n value={node.data.mediaContent ?? ''}\n onChange={(value) => onUpdateData(node.id, 'mediaContent', value)}\n rows={8}\n />\n ) : useSharedAIConfig ? (\n <div className=\"flow-inspector-help\">\n 此节点自动使用统一 AI 配置{globalAIConfig.model ? `(${globalAIConfig.model})` : ''},请通过 Flow 顶部的 AI 配置入口修改。\n </div>\n ) : (\n <>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">协议</Label>\n <Select\n options={[\n { value: 'openai', label: 'OpenAI 兼容' },\n { value: 'anthropic', label: 'Anthropic 兼容' },\n ]}\n value={ai?.protocol ?? 'openai'}\n onChange={(v) => updateAI('protocol', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">接口地址</Label>\n <Input\n size=\"xs\"\n value={ai?.gateway ?? ''}\n placeholder=\"https://api.openai.com/v1/chat/completions\"\n onChange={(e) => updateAI('gateway', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">模型</Label>\n <Input\n size=\"xs\"\n value={ai?.model ?? ''}\n placeholder=\"gpt-4o-mini\"\n onChange={(e) => updateAI('model', e.target.value)}\n />\n </div>\n <div className=\"flow-inspector-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 4 }}>\n <Label size=\"xs\" className=\"flow-inspector-label\">API Key</Label>\n <Input\n size=\"xs\"\n type=\"password\"\n value={ai?.apiKey ?? ''}\n placeholder=\"sk-...\"\n onChange={(e) => updateAI('apiKey', e.target.value)}\n />\n </div>\n <ExpandableTextarea\n label=\"System Prompt\"\n value={ai?.systemPrompt ?? ''}\n onChange={(value) => updateAI('systemPrompt', value)}\n rows={3}\n />\n <div style={{ fontSize: 10, color: 'color-mix(in oklch, var(--color-base-content) 45%, transparent)', marginTop: 4 }}>\n 密钥会随文档 JSON 一同导出,请谨慎分享。\n </div>\n </>\n )}\n </div>\n );\n}\n\nfunction EdgeInspector({\n edge,\n onUpdateData,\n onUpdateType,\n}: {\n edge: FlowEdge;\n onUpdateData: (id: string, key: string, value: any) => void;\n onUpdateType: (id: string, type: string) => void;\n}) {\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Edge</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <Select\n options={EDGE_TYPE_OPTIONS.map(t => ({ value: t, label: t }))}\n value={edge.type}\n onChange={(v) => onUpdateType(edge.id, v as string)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={edge.data.strokeColor}\n kind=\"line\"\n customFallback=\"#374151\"\n onChange={(v) => onUpdateData(edge.id, 'strokeColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Width</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(edge.data.strokeWidth ?? 2)}\n onChange={(e) => onUpdateData(edge.id, 'strokeWidth', Number(e.target.value) || 2)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Animation</Label>\n <Checkbox\n size=\"sm\"\n checked={edge.data.animated ?? false}\n onChange={(value) => onUpdateData(edge.id, 'animated', value)}\n label=\"预览时播放\"\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Line</Label>\n <Select\n options={EDGE_LINE_STYLE_OPTIONS.map(s => ({ value: s, label: s }))}\n value={edge.data.lineStyle ?? 'solid'}\n onChange={(v) => onUpdateData(edge.id, 'lineStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Start</Label>\n <Select\n options={EDGE_MARKER_OPTIONS.map(m => ({ value: m, label: m }))}\n value={edge.data.markerStart ?? 'none'}\n onChange={(v) => onUpdateData(edge.id, 'markerStart', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">End</Label>\n <Select\n options={EDGE_MARKER_OPTIONS.map(m => ({ value: m, label: m }))}\n value={edge.data.markerEnd ?? 'none'}\n onChange={(v) => onUpdateData(edge.id, 'markerEnd', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Label</Label>\n <Input\n size=\"xs\"\n value={edge.data.labelText ?? ''}\n onChange={(e) => onUpdateData(edge.id, 'labelText', e.target.value)}\n placeholder=\"Edge label\"\n />\n </div>\n </div>\n );\n}\n\nfunction LineInspector({\n line,\n onUpdateData,\n}: {\n line: FlowLine;\n onUpdateData: (id: string, key: string, value: any) => void;\n}) {\n return (\n <div className=\"flow-inspector-section\">\n <div className=\"flow-inspector-section-title\">Line</div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Type</Label>\n <span style={{ fontSize: 12, color: 'color-mix(in oklch, var(--color-base-content) 60%, transparent)' }}>{line.type}</span>\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Color</Label>\n <ThemeColorField\n value={line.strokeColor}\n kind=\"line\"\n customFallback=\"#374151\"\n onChange={(v) => onUpdateData(line.id, 'strokeColor', v)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Width</Label>\n <Input\n size=\"xs\"\n type=\"number\"\n value={String(line.strokeWidth)}\n onChange={(e) => onUpdateData(line.id, 'strokeWidth', Number(e.target.value) || 2)}\n />\n </div>\n <div className=\"flow-inspector-row\">\n <Label size=\"xs\" className=\"flow-inspector-label\">Style</Label>\n <Select\n options={EDGE_LINE_STYLE_OPTIONS.map(s => ({ value: s, label: s }))}\n value={line.lineStyle}\n onChange={(v) => onUpdateData(line.id, 'lineStyle', v)}\n style={{ fontSize: 12 }}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -47,9 +47,9 @@ export declare const THEME_COLOR_TOKENS: ThemeColorToken[];
|
|
|
47
47
|
* The "follow theme" default token for each color field type. Each field syncs
|
|
48
48
|
* to a theme role so shapes stay legible against the canvas:
|
|
49
49
|
* - `fill` -> theme background (base-100)
|
|
50
|
-
* - `stroke` -> theme
|
|
50
|
+
* - `stroke` -> theme hairline (base-300) — a calm, low-contrast outline
|
|
51
51
|
* - `text` -> theme font color (base-content)
|
|
52
|
-
* - `line` -> theme
|
|
52
|
+
* - `line` -> theme hairline (base-300) — lines/edges
|
|
53
53
|
*/
|
|
54
54
|
export type ThemeColorFieldKind = 'fill' | 'stroke' | 'text' | 'line';
|
|
55
55
|
export declare const THEME_SYNC_TOKEN: Record<ThemeColorFieldKind, string>;
|
|
@@ -134,9 +134,9 @@ var u = "theme:", d = [
|
|
|
134
134
|
new Map(d.map((e) => [e.token, e.label]));
|
|
135
135
|
var p = {
|
|
136
136
|
fill: "theme:base-100",
|
|
137
|
-
stroke: "theme:base-
|
|
137
|
+
stroke: "theme:base-300",
|
|
138
138
|
text: "theme:base-content",
|
|
139
|
-
line: "theme:base-
|
|
139
|
+
line: "theme:base-300"
|
|
140
140
|
};
|
|
141
141
|
function m(e) {
|
|
142
142
|
return f.get(e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeColor.js","names":[],"sources":["../../../../../src/components/pro/Flow/utils/themeColor.ts"],"sourcesContent":["/**\n * Resolve a CSS color value (including theme custom properties like\n * `var(--color-base-100)` that may use `oklch(...)`) into a concrete sRGB color\n * for the WebGL canvas.\n *\n * PixiJS needs a numeric/hex color and cannot read CSS variables. Resolution:\n * 1. A hidden probe element inherits the themed scope. Its `color` is set to\n * `color-mix(in srgb, <value> 100%, transparent)`, which forces the\n * browser to convert the color into the sRGB space at computed-value\n * time. `getComputedStyle` then serializes it as a plain `rgb(...)` or\n * `color(srgb ...)` string.\n * 2. That string is parsed directly (no canvas). Canvas rasterization is\n * only a last resort: some engines silently reject CSS Color 4 functions\n * (`oklch()`, `lab()`, `color()`) in `fillStyle`, which previously turned\n * every probed theme color black.\n */\n\nlet _rasterCtx: CanvasRenderingContext2D | null = null;\nfunction getRasterCtx(): CanvasRenderingContext2D | null {\n if (_rasterCtx) return _rasterCtx;\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n _rasterCtx = canvas.getContext('2d', { willReadFrequently: true });\n return _rasterCtx;\n}\n\n/** Rasterize any CSS color string to concrete sRGB bytes. */\nfunction rasterizeColor(cssColor: string): [number, number, number] | null {\n const ctx = getRasterCtx();\n if (!ctx) return null;\n try {\n ctx.clearRect(0, 0, 1, 1);\n ctx.fillStyle = '#000000';\n ctx.fillStyle = cssColor; // ignored if the browser can't parse it\n ctx.fillRect(0, 0, 1, 1);\n const { data } = ctx.getImageData(0, 0, 1, 1);\n return [data[0], data[1], data[2]];\n } catch {\n return null;\n }\n}\n\nfunction byte(v: number): number {\n return Math.max(0, Math.min(255, Math.round(v)));\n}\n\n/**\n * Parse the sRGB strings a browser serializes a computed color to when the\n * color was forced into the sRGB space: `rgb(...)` / `rgba(...)` (0-255\n * channels) or `color(srgb r g b / a)` (0-1 float channels).\n */\nfunction parseSrgbString(value: string): [number, number, number] | null {\n const rgb = /^rgba?\\(\\s*([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)/.exec(value);\n if (rgb) return [byte(+rgb[1]), byte(+rgb[2]), byte(+rgb[3])];\n const fn = /^color\\(\\s*srgb\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)/i.exec(value);\n if (fn) return [byte(+fn[1] * 255), byte(+fn[2] * 255), byte(+fn[3] * 255)];\n return null;\n}\n\n/** Whether the browser computes color-mix() (used to force sRGB output). */\nconst SUPPORTS_COLOR_MIX =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('color', 'color-mix(in srgb, red, blue)');\n\nfunction parseRgb(host: HTMLElement | null, cssValue: string): [number, number, number] | null {\n if (typeof document === 'undefined') return null;\n try {\n const probe = document.createElement('span');\n // Keep out of layout without `display:none` so `color` still resolves.\n probe.style.position = 'absolute';\n probe.style.width = '0';\n probe.style.height = '0';\n probe.style.overflow = 'hidden';\n probe.style.pointerEvents = 'none';\n (host ?? document.body).appendChild(probe);\n // Bail out when the requested custom property is undefined in this scope:\n // var() would invalidate the declaration and the probe would report its\n // inherited text color instead of the theme color.\n const varMatch = /^var\\(\\s*(--[\\w-]+)\\s*\\)$/.exec(cssValue);\n if (varMatch && !getComputedStyle(probe).getPropertyValue(varMatch[1]).trim()) {\n probe.remove();\n return null;\n }\n // Force the resolved color into the sRGB space at computed-value time, so\n // the serialized result is a plain rgb()/color(srgb) string we can parse\n // ourselves. Do NOT rasterize oklch()/lab() via canvas fillStyle here:\n // some engines (e.g. WebKit) silently reject CSS Color 4 functions in\n // canvas, which used to turn every probed theme color black.\n probe.style.color = SUPPORTS_COLOR_MIX\n ? `color-mix(in srgb, ${cssValue} 100%, transparent)`\n : cssValue;\n const resolved = getComputedStyle(probe).color;\n probe.remove();\n return parseSrgbString(resolved) ?? rasterizeColor(resolved);\n } catch {\n return null;\n }\n}\n\n/** Resolve a CSS color to a 0xRRGGBB number (for PixiJS). */\nexport function cssColorToNumber(host: HTMLElement | null, cssValue: string, fallback: number): number {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n}\n\n/** Resolve a CSS color to a `#rrggbb` string (for persisted node data). */\nexport function cssColorToHexString(host: HTMLElement | null, cssValue: string, fallback: string): string {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return '#' + rgb.map((c) => c.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * The colors the Flow canvas derives from the active theme:\n * - `background`: the canvas backdrop, follows the theme's muted background.\n * - `gridDot`: grid dots, derived from the theme foreground color.\n * - `nodeFill`: default fill for new shapes, follows the theme base background.\n */\nexport interface FlowThemeColors {\n background: number;\n gridDot: number;\n nodeFill: string;\n nodeText: string;\n}\n\nexport function resolveFlowThemeColors(host: HTMLElement | null): FlowThemeColors {\n return {\n background: cssColorToNumber(host, 'var(--color-base-200)', 0xf8f9fa),\n gridDot: cssColorToNumber(host, 'var(--color-base-content)', 0xd1d5db),\n nodeFill: cssColorToHexString(host, 'var(--color-base-100)', '#ffffff'),\n nodeText: cssColorToHexString(host, 'var(--color-base-content)', '#111827'),\n };\n}\n\n/* ============================================================================\n * Theme color tokens\n *\n * Node/edge colors may be stored either as a literal color (`#rrggbb`,\n * `transparent`, …) or as a THEME TOKEN of the form `theme:<name>` (e.g.\n * `theme:base-100`). Theme tokens are resolved to the live theme color at\n * render time, so shapes that use them re-color automatically whenever the\n * DishUI theme changes. These tokens are the default colors for new shapes.\n * ========================================================================== */\n\nexport const THEME_COLOR_PREFIX = 'theme:';\n\n/** A selectable theme color, shown as a swatch in the inspector. */\nexport interface ThemeColorToken {\n /** Stored value, e.g. `theme:base-100`. */\n token: string;\n /** CSS custom property backing the token. */\n cssVar: string;\n /** Short label for the inspector tooltip. */\n label: string;\n}\n\n/** The theme colors offered as presets/defaults for Flow color fields. */\nexport const THEME_COLOR_TOKENS: ThemeColorToken[] = [\n { token: 'theme:base-100', cssVar: 'var(--color-base-100)', label: 'Base 100' },\n { token: 'theme:base-200', cssVar: 'var(--color-base-200)', label: 'Base 200' },\n { token: 'theme:base-300', cssVar: 'var(--color-base-300)', label: 'Base 300' },\n { token: 'theme:base-content', cssVar: 'var(--color-base-content)', label: 'Base Content' },\n { token: 'theme:primary', cssVar: 'var(--color-primary)', label: 'Primary' },\n { token: 'theme:secondary', cssVar: 'var(--color-secondary)', label: 'Secondary' },\n { token: 'theme:accent', cssVar: 'var(--color-accent)', label: 'Accent' },\n { token: 'theme:neutral', cssVar: 'var(--color-neutral)', label: 'Neutral' },\n { token: 'theme:info', cssVar: 'var(--color-info)', label: 'Info' },\n { token: 'theme:success', cssVar: 'var(--color-success)', label: 'Success' },\n { token: 'theme:warning', cssVar: 'var(--color-warning)', label: 'Warning' },\n { token: 'theme:error', cssVar: 'var(--color-error)', label: 'Error' },\n];\n\nconst TOKEN_TO_CSSVAR = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.cssVar]));\nconst TOKEN_TO_LABEL = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.label]));\n\n/**\n * The \"follow theme\" default token for each color field type. Each field syncs\n * to a theme role so shapes stay legible against the canvas:\n * - `fill` -> theme background (base-100)\n * - `stroke` -> theme font color (base-content) — a visible outline\n * - `text` -> theme font color (base-content)\n * - `line` -> theme font color (base-content) — lines/edges\n */\nexport type ThemeColorFieldKind = 'fill' | 'stroke' | 'text' | 'line';\n\nexport const THEME_SYNC_TOKEN: Record<ThemeColorFieldKind, string> = {\n fill: 'theme:base-100',\n stroke: 'theme:base-content',\n text: 'theme:base-content',\n line: 'theme:base-content',\n};\n\n/** The CSS var backing a given theme token (for live-updating DOM swatches). */\nexport function themeTokenCssVar(token: string): string | undefined {\n return TOKEN_TO_CSSVAR.get(token);\n}\n\n/** Human label for a theme token (for tooltips). */\nexport function themeTokenLabel(token: string): string | undefined {\n return TOKEN_TO_LABEL.get(token);\n}\n\n/**\n * Common named colors offered after the theme-sync swatch: a compact rainbow\n * plus black/white. Order follows 黑白赤橙黄绿青蓝紫粉 (black, white, red,\n * orange, yellow, green, cyan, blue, purple, pink).\n */\nexport interface NamedColor {\n value: string;\n /** Chinese label shown on hover. */\n label: string;\n}\n\nexport const COMMON_COLORS: NamedColor[] = [\n { value: '#000000', label: '黑' },\n { value: '#ffffff', label: '白' },\n { value: '#ef4444', label: '赤' },\n { value: '#f97316', label: '橙' },\n { value: '#eab308', label: '黄' },\n { value: '#22c55e', label: '绿' },\n { value: '#06b6d4', label: '青' },\n { value: '#3b82f6', label: '蓝' },\n { value: '#8b5cf6', label: '紫' },\n { value: '#ec4899', label: '粉' },\n];\n\n/** True when `value` is a `theme:*` token. */\nexport function isThemeToken(value: string | undefined | null): value is string {\n return typeof value === 'string' && value.startsWith(THEME_COLOR_PREFIX);\n}\n\n// Module-level cache of the currently resolved token -> `#rrggbb` mapping. The\n// render loop resolves tokens against this cache (cheap, synchronous) instead\n// of probing the DOM every frame. `refreshThemePalette` rebuilds it whenever\n// the theme changes.\nconst _palette = new Map<string, string>();\n\n/**\n * Re-resolve every theme token against the given host's themed scope and cache\n * the results. Call on init and whenever the active theme changes.\n */\nexport function refreshThemePalette(host: HTMLElement | null): void {\n for (const { token, cssVar } of THEME_COLOR_TOKENS) {\n _palette.set(token, cssColorToHexString(host, cssVar, '#000000'));\n }\n}\n\n/**\n * Resolve a stored color value to a concrete `#rrggbb`/literal color. Theme\n * tokens are looked up in the cached palette; anything else is returned as-is.\n */\nexport function resolveThemeColor(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return _palette.get(value) ?? fallback;\n return value;\n}\n\n/**\n * Resolve a stored color to a value usable directly in the DOM. Theme tokens\n * map to their CSS variable so the browser tracks theme changes natively.\n */\nexport function resolveThemeColorCss(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return TOKEN_TO_CSSVAR.get(value) ?? fallback;\n return value;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"themeColor.js","names":[],"sources":["../../../../../src/components/pro/Flow/utils/themeColor.ts"],"sourcesContent":["/**\n * Resolve a CSS color value (including theme custom properties like\n * `var(--color-base-100)` that may use `oklch(...)`) into a concrete sRGB color\n * for the WebGL canvas.\n *\n * PixiJS needs a numeric/hex color and cannot read CSS variables. Resolution:\n * 1. A hidden probe element inherits the themed scope. Its `color` is set to\n * `color-mix(in srgb, <value> 100%, transparent)`, which forces the\n * browser to convert the color into the sRGB space at computed-value\n * time. `getComputedStyle` then serializes it as a plain `rgb(...)` or\n * `color(srgb ...)` string.\n * 2. That string is parsed directly (no canvas). Canvas rasterization is\n * only a last resort: some engines silently reject CSS Color 4 functions\n * (`oklch()`, `lab()`, `color()`) in `fillStyle`, which previously turned\n * every probed theme color black.\n */\n\nlet _rasterCtx: CanvasRenderingContext2D | null = null;\nfunction getRasterCtx(): CanvasRenderingContext2D | null {\n if (_rasterCtx) return _rasterCtx;\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n _rasterCtx = canvas.getContext('2d', { willReadFrequently: true });\n return _rasterCtx;\n}\n\n/** Rasterize any CSS color string to concrete sRGB bytes. */\nfunction rasterizeColor(cssColor: string): [number, number, number] | null {\n const ctx = getRasterCtx();\n if (!ctx) return null;\n try {\n ctx.clearRect(0, 0, 1, 1);\n ctx.fillStyle = '#000000';\n ctx.fillStyle = cssColor; // ignored if the browser can't parse it\n ctx.fillRect(0, 0, 1, 1);\n const { data } = ctx.getImageData(0, 0, 1, 1);\n return [data[0], data[1], data[2]];\n } catch {\n return null;\n }\n}\n\nfunction byte(v: number): number {\n return Math.max(0, Math.min(255, Math.round(v)));\n}\n\n/**\n * Parse the sRGB strings a browser serializes a computed color to when the\n * color was forced into the sRGB space: `rgb(...)` / `rgba(...)` (0-255\n * channels) or `color(srgb r g b / a)` (0-1 float channels).\n */\nfunction parseSrgbString(value: string): [number, number, number] | null {\n const rgb = /^rgba?\\(\\s*([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)/.exec(value);\n if (rgb) return [byte(+rgb[1]), byte(+rgb[2]), byte(+rgb[3])];\n const fn = /^color\\(\\s*srgb\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)/i.exec(value);\n if (fn) return [byte(+fn[1] * 255), byte(+fn[2] * 255), byte(+fn[3] * 255)];\n return null;\n}\n\n/** Whether the browser computes color-mix() (used to force sRGB output). */\nconst SUPPORTS_COLOR_MIX =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('color', 'color-mix(in srgb, red, blue)');\n\nfunction parseRgb(host: HTMLElement | null, cssValue: string): [number, number, number] | null {\n if (typeof document === 'undefined') return null;\n try {\n const probe = document.createElement('span');\n // Keep out of layout without `display:none` so `color` still resolves.\n probe.style.position = 'absolute';\n probe.style.width = '0';\n probe.style.height = '0';\n probe.style.overflow = 'hidden';\n probe.style.pointerEvents = 'none';\n (host ?? document.body).appendChild(probe);\n // Bail out when the requested custom property is undefined in this scope:\n // var() would invalidate the declaration and the probe would report its\n // inherited text color instead of the theme color.\n const varMatch = /^var\\(\\s*(--[\\w-]+)\\s*\\)$/.exec(cssValue);\n if (varMatch && !getComputedStyle(probe).getPropertyValue(varMatch[1]).trim()) {\n probe.remove();\n return null;\n }\n // Force the resolved color into the sRGB space at computed-value time, so\n // the serialized result is a plain rgb()/color(srgb) string we can parse\n // ourselves. Do NOT rasterize oklch()/lab() via canvas fillStyle here:\n // some engines (e.g. WebKit) silently reject CSS Color 4 functions in\n // canvas, which used to turn every probed theme color black.\n probe.style.color = SUPPORTS_COLOR_MIX\n ? `color-mix(in srgb, ${cssValue} 100%, transparent)`\n : cssValue;\n const resolved = getComputedStyle(probe).color;\n probe.remove();\n return parseSrgbString(resolved) ?? rasterizeColor(resolved);\n } catch {\n return null;\n }\n}\n\n/** Resolve a CSS color to a 0xRRGGBB number (for PixiJS). */\nexport function cssColorToNumber(host: HTMLElement | null, cssValue: string, fallback: number): number {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n}\n\n/** Resolve a CSS color to a `#rrggbb` string (for persisted node data). */\nexport function cssColorToHexString(host: HTMLElement | null, cssValue: string, fallback: string): string {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return '#' + rgb.map((c) => c.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * The colors the Flow canvas derives from the active theme:\n * - `background`: the canvas backdrop, follows the theme's muted background.\n * - `gridDot`: grid dots, derived from the theme foreground color.\n * - `nodeFill`: default fill for new shapes, follows the theme base background.\n */\nexport interface FlowThemeColors {\n background: number;\n gridDot: number;\n nodeFill: string;\n nodeText: string;\n}\n\nexport function resolveFlowThemeColors(host: HTMLElement | null): FlowThemeColors {\n return {\n background: cssColorToNumber(host, 'var(--color-base-200)', 0xf8f9fa),\n gridDot: cssColorToNumber(host, 'var(--color-base-content)', 0xd1d5db),\n nodeFill: cssColorToHexString(host, 'var(--color-base-100)', '#ffffff'),\n nodeText: cssColorToHexString(host, 'var(--color-base-content)', '#111827'),\n };\n}\n\n/* ============================================================================\n * Theme color tokens\n *\n * Node/edge colors may be stored either as a literal color (`#rrggbb`,\n * `transparent`, …) or as a THEME TOKEN of the form `theme:<name>` (e.g.\n * `theme:base-100`). Theme tokens are resolved to the live theme color at\n * render time, so shapes that use them re-color automatically whenever the\n * DishUI theme changes. These tokens are the default colors for new shapes.\n * ========================================================================== */\n\nexport const THEME_COLOR_PREFIX = 'theme:';\n\n/** A selectable theme color, shown as a swatch in the inspector. */\nexport interface ThemeColorToken {\n /** Stored value, e.g. `theme:base-100`. */\n token: string;\n /** CSS custom property backing the token. */\n cssVar: string;\n /** Short label for the inspector tooltip. */\n label: string;\n}\n\n/** The theme colors offered as presets/defaults for Flow color fields. */\nexport const THEME_COLOR_TOKENS: ThemeColorToken[] = [\n { token: 'theme:base-100', cssVar: 'var(--color-base-100)', label: 'Base 100' },\n { token: 'theme:base-200', cssVar: 'var(--color-base-200)', label: 'Base 200' },\n { token: 'theme:base-300', cssVar: 'var(--color-base-300)', label: 'Base 300' },\n { token: 'theme:base-content', cssVar: 'var(--color-base-content)', label: 'Base Content' },\n { token: 'theme:primary', cssVar: 'var(--color-primary)', label: 'Primary' },\n { token: 'theme:secondary', cssVar: 'var(--color-secondary)', label: 'Secondary' },\n { token: 'theme:accent', cssVar: 'var(--color-accent)', label: 'Accent' },\n { token: 'theme:neutral', cssVar: 'var(--color-neutral)', label: 'Neutral' },\n { token: 'theme:info', cssVar: 'var(--color-info)', label: 'Info' },\n { token: 'theme:success', cssVar: 'var(--color-success)', label: 'Success' },\n { token: 'theme:warning', cssVar: 'var(--color-warning)', label: 'Warning' },\n { token: 'theme:error', cssVar: 'var(--color-error)', label: 'Error' },\n];\n\nconst TOKEN_TO_CSSVAR = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.cssVar]));\nconst TOKEN_TO_LABEL = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.label]));\n\n/**\n * The \"follow theme\" default token for each color field type. Each field syncs\n * to a theme role so shapes stay legible against the canvas:\n * - `fill` -> theme background (base-100)\n * - `stroke` -> theme hairline (base-300) — a calm, low-contrast outline\n * - `text` -> theme font color (base-content)\n * - `line` -> theme hairline (base-300) — lines/edges\n */\nexport type ThemeColorFieldKind = 'fill' | 'stroke' | 'text' | 'line';\n\nexport const THEME_SYNC_TOKEN: Record<ThemeColorFieldKind, string> = {\n fill: 'theme:base-100',\n stroke: 'theme:base-300',\n text: 'theme:base-content',\n line: 'theme:base-300',\n};\n\n/** The CSS var backing a given theme token (for live-updating DOM swatches). */\nexport function themeTokenCssVar(token: string): string | undefined {\n return TOKEN_TO_CSSVAR.get(token);\n}\n\n/** Human label for a theme token (for tooltips). */\nexport function themeTokenLabel(token: string): string | undefined {\n return TOKEN_TO_LABEL.get(token);\n}\n\n/**\n * Common named colors offered after the theme-sync swatch: a compact rainbow\n * plus black/white. Order follows 黑白赤橙黄绿青蓝紫粉 (black, white, red,\n * orange, yellow, green, cyan, blue, purple, pink).\n */\nexport interface NamedColor {\n value: string;\n /** Chinese label shown on hover. */\n label: string;\n}\n\nexport const COMMON_COLORS: NamedColor[] = [\n { value: '#000000', label: '黑' },\n { value: '#ffffff', label: '白' },\n { value: '#ef4444', label: '赤' },\n { value: '#f97316', label: '橙' },\n { value: '#eab308', label: '黄' },\n { value: '#22c55e', label: '绿' },\n { value: '#06b6d4', label: '青' },\n { value: '#3b82f6', label: '蓝' },\n { value: '#8b5cf6', label: '紫' },\n { value: '#ec4899', label: '粉' },\n];\n\n/** True when `value` is a `theme:*` token. */\nexport function isThemeToken(value: string | undefined | null): value is string {\n return typeof value === 'string' && value.startsWith(THEME_COLOR_PREFIX);\n}\n\n// Module-level cache of the currently resolved token -> `#rrggbb` mapping. The\n// render loop resolves tokens against this cache (cheap, synchronous) instead\n// of probing the DOM every frame. `refreshThemePalette` rebuilds it whenever\n// the theme changes.\nconst _palette = new Map<string, string>();\n\n/**\n * Re-resolve every theme token against the given host's themed scope and cache\n * the results. Call on init and whenever the active theme changes.\n */\nexport function refreshThemePalette(host: HTMLElement | null): void {\n for (const { token, cssVar } of THEME_COLOR_TOKENS) {\n _palette.set(token, cssColorToHexString(host, cssVar, '#000000'));\n }\n}\n\n/**\n * Resolve a stored color value to a concrete `#rrggbb`/literal color. Theme\n * tokens are looked up in the cached palette; anything else is returned as-is.\n */\nexport function resolveThemeColor(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return _palette.get(value) ?? fallback;\n return value;\n}\n\n/**\n * Resolve a stored color to a value usable directly in the DOM. Theme tokens\n * map to their CSS variable so the browser tracks theme changes natively.\n */\nexport function resolveThemeColorCss(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return TOKEN_TO_CSSVAR.get(value) ?? fallback;\n return value;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { KanbanProps } from "./types";
|
|
3
|
+
export default function Kanban({ columns, lanes, cards, onCardMove, renderCard, renderColumnHeader, renderLaneHeader, readOnly, loading, error, stale, empty, onRetry, labels: labelsInput, dragThreshold, columnWidth, height, collapsedLaneIds, defaultCollapsedLaneIds, onCollapsedLaneIdsChange, className, style, ...rest }: KanbanProps): React.JSX.Element;
|