@arronqzy/react-view 1.0.3 → 1.0.7
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/styles.css +555 -15
- package/package.json +14 -7
- package/readme.md +74 -5
- package/src/core/template.tsx +12 -2
- package/src/panel/ReactViewOnlinePreview.tsx +18 -8
- package/src/panel/ReactViewPanel.tsx +403 -177
- package/src/panel/ai/AssistantChatPanel.tsx +895 -0
- package/src/panel/ai/AssistantMarkdown.tsx +256 -0
- package/src/panel/ai/applyAssistantAction.ts +652 -0
- package/src/panel/ai/revealConfigField.ts +137 -0
- package/src/panel/components/ConfigHintIcon.tsx +50 -0
- package/src/panel/components/ElementsLayer.tsx +39 -22
- package/src/panel/components/MaterialSidebar.tsx +157 -109
- package/src/panel/components/MoveableLayer.tsx +75 -61
- package/src/panel/components/PanelCanvas.tsx +81 -64
- package/src/panel/components/PanelConfigSidebar.tsx +471 -448
- package/src/panel/components/SelectLayer.tsx +1 -0
- package/src/panel/components/ViewElementScopePanel.tsx +13 -12
- package/src/panel/components/WorkspaceConfigSidebar.tsx +5 -2
- package/src/panel/components/WorkspaceProjectNav.tsx +25 -14
- package/src/panel/components/WorkspaceStageSplit.tsx +3 -1
- package/src/panel/components/scope-config/ScopeConfigContext.tsx +9 -0
- package/src/panel/components/scope-config/ScopeTemplatePreviewHost.tsx +242 -0
- package/src/panel/components/scope-config/ScopeTemplateUsageHint.tsx +12 -0
- package/src/panel/components/scope-config/ScopeTemplateWarningsPanel.tsx +6 -3
- package/src/panel/components/table/ConditionEditor.tsx +205 -0
- package/src/panel/components/table/JsonCodeEditor.tsx +115 -0
- package/src/panel/components/table/PanelConfigTableSection.tsx +2192 -0
- package/src/panel/components/table/TableNodeContent.tsx +544 -0
- package/src/panel/constants/messages.ts +76 -34
- package/src/panel/hooks/usePanelElements.ts +64 -52
- package/src/panel/hooks/useRafThrottledScroll.ts +30 -0
- package/src/panel/hooks/useWorkspaceProjects.ts +11 -8
- package/src/panel/types.ts +6 -0
- package/src/panel/utils/chartOptionBuilder.ts +12 -1
- package/src/panel/utils/panelElementDefaults.ts +69 -39
- package/src/panel/utils/scope-field-labels.ts +51 -37
- package/src/panel/utils/scope-template-chart.ts +92 -0
- package/src/panel/utils/scope-template-preview.ts +128 -0
- package/src/panel/utils/scope-template-spread.ts +252 -0
- package/src/panel/utils/scope-template-warnings.ts +131 -11
- package/src/panel/utils/scope-template.ts +105 -3
- package/src/tailwind.css +36 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arronqzy/react-view",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"files": [
|
|
5
5
|
"src",
|
|
6
6
|
"dist",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@scena/react-ruler": "^0.19.0",
|
|
18
|
+
"@tanstack/react-virtual": "^3.13.2",
|
|
18
19
|
"react-infinite-viewer": "^0.28.1",
|
|
19
|
-
"react-zoom-pan-pinch": "^4.0.3",
|
|
20
20
|
"react-moveable": "^0.56.0",
|
|
21
21
|
"react-selecto": "^1.26.3",
|
|
22
22
|
"rxjs": "^7.8.2",
|
|
@@ -26,10 +26,17 @@
|
|
|
26
26
|
"infinite-viewer": "^0.29.1",
|
|
27
27
|
"echarts": "^6.0.0",
|
|
28
28
|
"uuid": "^13.0.0",
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
29
|
+
"@uiw/react-codemirror": "^4.23.8",
|
|
30
|
+
"@codemirror/lang-json": "^6.0.1",
|
|
31
|
+
"@codemirror/theme-one-dark": "^6.1.2",
|
|
32
|
+
"@codemirror/view": "^6.36.2",
|
|
33
|
+
"@arronqzy/ui": "1.0.3",
|
|
34
|
+
"@arronqzy/blueprint-dsl": "1.0.3",
|
|
35
|
+
"@arronqzy/i18n": "0.1.1",
|
|
36
|
+
"@arronqzy/rx-store": "1.0.2",
|
|
37
|
+
"@arronqzy/webllm-assistant": "0.1.1",
|
|
38
|
+
"@arronqzy/react-blueprint": "1.0.4",
|
|
39
|
+
"@arronqzy/view-table": "0.1.1"
|
|
33
40
|
},
|
|
34
41
|
"devDependencies": {
|
|
35
42
|
"@types/react": "^19.0.1",
|
|
@@ -39,7 +46,7 @@
|
|
|
39
46
|
"typescript": "^5.5.4",
|
|
40
47
|
"@arronqzy/eslint-config": "0.0.0",
|
|
41
48
|
"@arronqzy/typescript-config": "1.0.0",
|
|
42
|
-
"@arronqzy/tailwind": "1.0.
|
|
49
|
+
"@arronqzy/tailwind": "1.0.2"
|
|
43
50
|
},
|
|
44
51
|
"scripts": {
|
|
45
52
|
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
package/readme.md
CHANGED
|
@@ -1,17 +1,75 @@
|
|
|
1
1
|
# @arronqzy/react-view
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Abuilder 的**视图编辑器** React 包,提供可视化画布、图层、物料、在线预览与工作区管理能力。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 功能概览
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
7
|
+
- **无限画布**:平移、缩放、标尺、框选与 Moveable 拖拽/缩放/旋转
|
|
8
|
+
- **图层系统**:多图层、映射图层、主图层、锁定与合并
|
|
9
|
+
- **物料节点**:图表(ECharts)、文本、图片、音视频、几何、网格、引用节点等
|
|
10
|
+
- **Scope 模版**:节点属性支持 `{scope.xxx}` 表达式与解析预览
|
|
11
|
+
- **工作区**:IndexedDB 持久化、多项目切换、同步与在线预览
|
|
12
|
+
- **蓝图联动**:与 `@arronqzy/react-blueprint` 分屏编辑,运行时 Scope 回写视图
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @arronqzy/react-view
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
依赖 React 19,并需引入样式:
|
|
9
21
|
|
|
10
22
|
```ts
|
|
11
23
|
import "@arronqzy/react-view/styles.css";
|
|
12
24
|
```
|
|
13
25
|
|
|
14
|
-
|
|
26
|
+
## 使用
|
|
27
|
+
|
|
28
|
+
### 完整编辑器面板
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { ReactViewPanel } from "@arronqzy/react-view";
|
|
32
|
+
import "@arronqzy/react-view/styles.css";
|
|
33
|
+
|
|
34
|
+
export function Editor() {
|
|
35
|
+
return <ReactViewPanel className="h-screen" initialZoom={1} />;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 在线预览
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { ReactViewOnlinePreview } from "@arronqzy/react-view";
|
|
43
|
+
|
|
44
|
+
<ReactViewOnlinePreview projectId="your-project-id" />
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
URL 参数解析:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { parseOnlinePreviewSearchParams } from "@arronqzy/react-view";
|
|
51
|
+
|
|
52
|
+
const params = parseOnlinePreviewSearchParams("?preview=online&projectId=xxx");
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 核心导出
|
|
56
|
+
|
|
57
|
+
| 导出 | 说明 |
|
|
58
|
+
|------|------|
|
|
59
|
+
| `ReactViewPanel` | 主编辑面板(画布 + 配置侧栏 + 蓝图分屏) |
|
|
60
|
+
| `ReactViewOnlinePreview` | 只读在线预览页 |
|
|
61
|
+
| `parseOnlinePreviewSearchParams` | 解析预览 URL 参数 |
|
|
62
|
+
| `createView` / `createAction` 等 | 视图 DSL 与指令扩展(`src/core`) |
|
|
63
|
+
|
|
64
|
+
## 样式与 Tailwind
|
|
65
|
+
|
|
66
|
+
本包内置 Tailwind 配置,构建产物为 `dist/styles.css`:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm -C packages/react-view build:css
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
若由应用侧 Tailwind 扫描源码,请将本包加入 `content`:
|
|
15
73
|
|
|
16
74
|
```ts
|
|
17
75
|
content: [
|
|
@@ -19,3 +77,14 @@ content: [
|
|
|
19
77
|
"./node_modules/@arronqzy/react-view/src/**/*.{ts,tsx}",
|
|
20
78
|
]
|
|
21
79
|
```
|
|
80
|
+
|
|
81
|
+
## 依赖关系
|
|
82
|
+
|
|
83
|
+
- `@arronqzy/ui` — 基础 UI 组件
|
|
84
|
+
- `@arronqzy/rx-store` — 画布状态与历史
|
|
85
|
+
- `@arronqzy/react-blueprint` — 蓝图编辑与执行
|
|
86
|
+
- `@arronqzy/blueprint-dsl` — 蓝图运行时
|
|
87
|
+
|
|
88
|
+
## 许可证
|
|
89
|
+
|
|
90
|
+
MIT
|
package/src/core/template.tsx
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { JSX
|
|
1
|
+
import { JSX } from "react";
|
|
2
2
|
import { instructions } from "./instructions";
|
|
3
3
|
|
|
4
|
+
function isDevMode(): boolean {
|
|
5
|
+
try {
|
|
6
|
+
return Boolean(
|
|
7
|
+
(import.meta as { env?: { DEV?: boolean } }).env?.DEV
|
|
8
|
+
);
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
/**
|
|
5
15
|
* 事件需要补齐
|
|
6
16
|
* @param props
|
|
@@ -15,7 +25,7 @@ export const Template = (
|
|
|
15
25
|
if (props?.id) {
|
|
16
26
|
instructions.execute(props.id + "click", { e });
|
|
17
27
|
} else {
|
|
18
|
-
if (
|
|
28
|
+
if (isDevMode()) {
|
|
19
29
|
console.warn("Template 缺少 id,无法触发事件");
|
|
20
30
|
}
|
|
21
31
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/react";
|
|
2
3
|
import {
|
|
3
4
|
BlueprintGraph,
|
|
4
5
|
documentToRunnableGraph,
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
import type { LibraryBlueprintResolver, PageLifecyclePhase } from "@arronqzy/blueprint-dsl";
|
|
11
12
|
import type { State } from "@arronqzy/rx-store";
|
|
12
13
|
import { ElementsLayer } from "./components/ElementsLayer";
|
|
14
|
+
import type { TableCellActionHandler } from "./components/table/TableNodeContent";
|
|
13
15
|
import type { PanelElement } from "./types";
|
|
14
16
|
import {
|
|
15
17
|
clearViewElementScopes,
|
|
@@ -63,6 +65,8 @@ export function ReactViewOnlinePreview({
|
|
|
63
65
|
projectId,
|
|
64
66
|
previewInstanceId,
|
|
65
67
|
}: ReactViewOnlinePreviewProps) {
|
|
68
|
+
const { t } = useI18n();
|
|
69
|
+
|
|
66
70
|
const [loadError, setLoadError] = useState<string | null>(null);
|
|
67
71
|
const [panelState, setPanelState] = useState<State | null>(null);
|
|
68
72
|
const [projectRevision, setProjectRevision] = useState(0);
|
|
@@ -91,14 +95,14 @@ export function ReactViewOnlinePreview({
|
|
|
91
95
|
const loadProject = useCallback(async () => {
|
|
92
96
|
const record = await loadWorkspaceRecord(projectId);
|
|
93
97
|
if (!record) {
|
|
94
|
-
setLoadError("
|
|
98
|
+
setLoadError(t("panel.messages.workspaceNotFound"));
|
|
95
99
|
setPanelState(null);
|
|
96
100
|
return;
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
const normalized = normalizeImportedPanelState(record.panelState);
|
|
100
104
|
if (!normalized) {
|
|
101
|
-
setLoadError("
|
|
105
|
+
setLoadError(t("panel.messages.workspaceDataInvalid"));
|
|
102
106
|
setPanelState(null);
|
|
103
107
|
return;
|
|
104
108
|
}
|
|
@@ -107,7 +111,7 @@ export function ReactViewOnlinePreview({
|
|
|
107
111
|
clearViewElementScopes();
|
|
108
112
|
setPanelState(normalized);
|
|
109
113
|
setBlueprintGraph(BlueprintGraph.fromDocument(record.blueprintDocument));
|
|
110
|
-
document.title = record.productName.trim() || record.name || "
|
|
114
|
+
document.title = record.productName.trim() || record.name || t("panel.workspace.previewDocTitle");
|
|
111
115
|
applyTitleIcon(record.titleIconDataUrl);
|
|
112
116
|
setProjectRevision((v) => v + 1);
|
|
113
117
|
}, [projectId]);
|
|
@@ -228,7 +232,7 @@ export function ReactViewOnlinePreview({
|
|
|
228
232
|
const lifecycleReady =
|
|
229
233
|
!!panelState && layerElements.length > 0 && layoutReady;
|
|
230
234
|
|
|
231
|
-
useBlueprintPageLifecycle({
|
|
235
|
+
const { triggerBlueprintNode } = useBlueprintPageLifecycle({
|
|
232
236
|
graph: blueprintGraph,
|
|
233
237
|
active: true,
|
|
234
238
|
enabled: lifecycleReady,
|
|
@@ -249,7 +253,12 @@ export function ReactViewOnlinePreview({
|
|
|
249
253
|
|
|
250
254
|
const noopUpdate = useCallback((_id: string, _patch: Partial<PanelElement>) => {}, []);
|
|
251
255
|
const noopSelect = useCallback((_ids: string[]) => {}, []);
|
|
252
|
-
|
|
256
|
+
const onTableCellAction = useCallback<TableCellActionHandler>(
|
|
257
|
+
(payload) => {
|
|
258
|
+
void triggerBlueprintNode(payload.blueprintNodeId, payload);
|
|
259
|
+
},
|
|
260
|
+
[triggerBlueprintNode]
|
|
261
|
+
);
|
|
253
262
|
if (loadError) {
|
|
254
263
|
return (
|
|
255
264
|
<div className="flex min-h-[100vh] w-full items-center justify-center bg-white px-6 text-center text-sm text-gray-600">
|
|
@@ -261,7 +270,7 @@ export function ReactViewOnlinePreview({
|
|
|
261
270
|
if (!panelState) {
|
|
262
271
|
return (
|
|
263
272
|
<div className="flex min-h-[100vh] w-full items-center justify-center bg-white text-sm text-gray-600">
|
|
264
|
-
|
|
273
|
+
{t("panel.workspace.previewLoading")}
|
|
265
274
|
</div>
|
|
266
275
|
);
|
|
267
276
|
}
|
|
@@ -269,9 +278,9 @@ export function ReactViewOnlinePreview({
|
|
|
269
278
|
if (layerElements.length === 0) {
|
|
270
279
|
return (
|
|
271
280
|
<div className="flex min-h-[100vh] w-full flex-col items-center justify-center gap-2 bg-white px-6 text-center text-sm text-gray-600">
|
|
272
|
-
<div
|
|
281
|
+
<div>{t("panel.workspace.previewNoNodes")}</div>
|
|
273
282
|
<div className="text-xs text-gray-400">
|
|
274
|
-
|
|
283
|
+
{t("panel.workspace.previewHint")}
|
|
275
284
|
</div>
|
|
276
285
|
</div>
|
|
277
286
|
);
|
|
@@ -309,6 +318,7 @@ export function ReactViewOnlinePreview({
|
|
|
309
318
|
layerLocked
|
|
310
319
|
previewMode
|
|
311
320
|
previewLayoutKey={layoutRevision}
|
|
321
|
+
onTableCellAction={onTableCellAction}
|
|
312
322
|
/>
|
|
313
323
|
</div>
|
|
314
324
|
</div>
|