@nocobase/plugin-flow-engine 2.1.0-alpha.6 → 2.1.0-alpha.8
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/ai/docs/runjs/context/block-model.md +35 -35
- package/dist/ai/docs/runjs/context/collection-field.md +53 -51
- package/dist/ai/docs/runjs/context/collection.md +39 -39
- package/dist/ai/docs/runjs/context/data-source-manager.md +40 -30
- package/dist/ai/docs/runjs/context/data-source.md +52 -44
- package/dist/ai/docs/runjs/context/element.md +44 -38
- package/dist/ai/docs/runjs/context/exit-all.md +37 -35
- package/dist/ai/docs/runjs/context/exit.md +38 -35
- package/dist/ai/docs/runjs/context/filter-manager.md +36 -30
- package/dist/ai/docs/runjs/context/form.md +57 -57
- package/dist/ai/docs/runjs/context/get-model.md +22 -21
- package/dist/ai/docs/runjs/context/get-value.md +20 -19
- package/dist/ai/docs/runjs/context/get-var.md +61 -55
- package/dist/ai/docs/runjs/context/i18n.md +17 -14
- package/dist/ai/docs/runjs/context/import-async.md +333 -45
- package/dist/ai/docs/runjs/context/init-resource.md +20 -20
- package/dist/ai/docs/runjs/context/libs.md +31 -31
- package/dist/ai/docs/runjs/context/location.md +34 -31
- package/dist/ai/docs/runjs/context/logger.md +41 -40
- package/dist/ai/docs/runjs/context/make-resource.md +27 -26
- package/dist/ai/docs/runjs/context/message.md +42 -41
- package/dist/ai/docs/runjs/context/modal.md +44 -44
- package/dist/ai/docs/runjs/context/model.md +36 -33
- package/dist/ai/docs/runjs/context/notification.md +41 -40
- package/dist/ai/docs/runjs/context/off.md +14 -14
- package/dist/ai/docs/runjs/context/on.md +30 -29
- package/dist/ai/docs/runjs/context/open-view.md +40 -40
- package/dist/ai/docs/runjs/context/render.md +37 -32
- package/dist/ai/docs/runjs/context/request.md +46 -45
- package/dist/ai/docs/runjs/context/require-async.md +28 -25
- package/dist/ai/docs/runjs/context/resource.md +34 -34
- package/dist/ai/docs/runjs/context/route.md +36 -34
- package/dist/ai/docs/runjs/context/router.md +43 -31
- package/dist/ai/docs/runjs/context/set-value.md +18 -17
- package/dist/ai/docs/runjs/context/sql.md +7 -15
- package/dist/ai/docs/runjs/context/t.md +20 -17
- package/dist/ai/docs/runjs/context/view.md +49 -46
- package/dist/ai/docs/runjs/document.md +1 -0
- package/dist/ai/docs/runjs/import-modules.md +32 -32
- package/dist/ai/docs/runjs/index.md +13 -13
- package/dist/ai/docs/runjs/jsx.md +19 -19
- package/dist/ai/docs/runjs/model/form-block-model.md +1 -3
- package/dist/ai/docs/runjs/render.md +15 -15
- package/dist/ai/docs/runjs/resource/api-resource.md +53 -53
- package/dist/ai/docs/runjs/resource/multi-record-resource.md +64 -64
- package/dist/ai/docs/runjs/resource/single-record-resource.md +55 -55
- package/dist/ai/docs/runjs/resource/sql-resource.md +57 -57
- package/dist/ai/docs/runjs/window.md +5 -5
- package/dist/externalVersion.js +10 -10
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/collections/flowsql.js +1 -0
- package/package.json +2 -2
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# ctx.view
|
|
2
2
|
|
|
3
|
-
The currently active view controller (dialog, drawer, popover,
|
|
3
|
+
The currently active view controller (dialog, drawer, popover, embedded area, etc.), used to access view-level information and operations. Provided by `FlowViewContext`, it is only available within view content opened via `ctx.viewer` or `ctx.openView`.
|
|
4
4
|
|
|
5
5
|
## Use Cases
|
|
6
6
|
|
|
7
7
|
| Scenario | Description |
|
|
8
|
-
|
|
9
|
-
| **Dialog/
|
|
10
|
-
| **After
|
|
11
|
-
| **JSBlock / Action** |
|
|
12
|
-
| **Association
|
|
8
|
+
|------|------|
|
|
9
|
+
| **Dialog/Drawer Content** | Use `ctx.view.close()` within the `content` to close the current view, or use `Header` and `Footer` to render titles and footers. |
|
|
10
|
+
| **After Form Submission** | Call `ctx.view.close(result)` after a successful submission to close the view and return the result. |
|
|
11
|
+
| **JSBlock / Action** | Determine the current view type via `ctx.view.type`, or read opening parameters from `ctx.view.inputArgs`. |
|
|
12
|
+
| **Association Selection, Sub-tables** | Read `collectionName`, `filterByTk`, `parentId`, etc., from `inputArgs` for data loading. |
|
|
13
13
|
|
|
14
|
-
> Note: `ctx.view` is only available in RunJS
|
|
14
|
+
> Note: `ctx.view` is only available in RunJS environments with a view context (e.g., inside the `content` of `ctx.viewer.dialog()`, in dialog forms, or inside association selectors). In standard pages or backend contexts, it is `undefined`. It is recommended to use optional chaining (`ctx.view?.close?.()`).
|
|
15
15
|
|
|
16
|
-
## Type
|
|
16
|
+
## Type Definition
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
type FlowView = {
|
|
@@ -25,54 +25,56 @@ type FlowView = {
|
|
|
25
25
|
update: (newConfig: any) => void;
|
|
26
26
|
navigation?: ViewNavigation;
|
|
27
27
|
destroy?: () => void;
|
|
28
|
-
submit?: () => Promise<any>;
|
|
28
|
+
submit?: () => Promise<any>; // Available in workflow configuration views
|
|
29
29
|
};
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
## Common
|
|
32
|
+
## Common Properties and Methods
|
|
33
33
|
|
|
34
34
|
| Property/Method | Type | Description |
|
|
35
|
-
|
|
35
|
+
|-----------|------|------|
|
|
36
36
|
| `type` | `'drawer' \| 'popover' \| 'dialog' \| 'embed'` | Current view type |
|
|
37
|
-
| `inputArgs` | `Record<string, any>` |
|
|
38
|
-
| `Header` | `React.FC \| null` | Header component
|
|
39
|
-
| `Footer` | `React.FC \| null` | Footer
|
|
40
|
-
| `close(result?, force?)` | `void` |
|
|
41
|
-
| `update(newConfig)` | `void` |
|
|
42
|
-
| `navigation` | `ViewNavigation \| undefined` | In-view navigation
|
|
37
|
+
| `inputArgs` | `Record<string, any>` | Parameters passed when opening the view (see below) |
|
|
38
|
+
| `Header` | `React.FC \| null` | Header component, used to render titles and action areas |
|
|
39
|
+
| `Footer` | `React.FC \| null` | Footer component, used to render buttons, etc. |
|
|
40
|
+
| `close(result?, force?)` | `void` | Closes the current view; `result` can be passed back to the caller |
|
|
41
|
+
| `update(newConfig)` | `void` | Updates view configuration (e.g., width, title) |
|
|
42
|
+
| `navigation` | `ViewNavigation \| undefined` | In-page view navigation, including Tab switching, etc. |
|
|
43
43
|
|
|
44
|
-
> Currently only `dialog` and `drawer` support `Header` and `Footer`.
|
|
44
|
+
> Currently, only `dialog` and `drawer` support `Header` and `Footer`.
|
|
45
45
|
|
|
46
|
-
## inputArgs
|
|
46
|
+
## Common inputArgs Fields
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
The fields in `inputArgs` vary depending on the opening scenario. Common fields include:
|
|
49
49
|
|
|
50
50
|
| Field | Description |
|
|
51
|
-
|
|
51
|
+
|------|------|
|
|
52
52
|
| `viewUid` | View UID |
|
|
53
53
|
| `collectionName` | Collection name |
|
|
54
|
-
| `filterByTk` | Primary key filter (single record) |
|
|
55
|
-
| `parentId` | Parent
|
|
56
|
-
| `sourceId` | Source record
|
|
54
|
+
| `filterByTk` | Primary key filter (for single record details) |
|
|
55
|
+
| `parentId` | Parent ID (for association scenarios) |
|
|
56
|
+
| `sourceId` | Source record ID |
|
|
57
57
|
| `parentItem` | Parent item data |
|
|
58
|
-
| `scene` | Scene (e.g
|
|
59
|
-
| `onChange` | Callback after
|
|
60
|
-
| `tabUid` | Current
|
|
58
|
+
| `scene` | Scene (e.g., `create`, `edit`, `select`) |
|
|
59
|
+
| `onChange` | Callback after selection or change |
|
|
60
|
+
| `tabUid` | Current Tab UID (within a page) |
|
|
61
61
|
|
|
62
|
-
Access via `ctx.getVar('ctx.view.inputArgs.xxx')` or `ctx.view.inputArgs.xxx`.
|
|
62
|
+
Access these via `ctx.getVar('ctx.view.inputArgs.xxx')` or `ctx.view.inputArgs.xxx`.
|
|
63
63
|
|
|
64
64
|
## Examples
|
|
65
65
|
|
|
66
|
-
###
|
|
66
|
+
### Closing the Current View
|
|
67
67
|
|
|
68
68
|
```ts
|
|
69
|
+
// Close dialog after successful submission
|
|
69
70
|
await ctx.resource.runAction('create', { data: formData });
|
|
70
71
|
ctx.view?.close();
|
|
71
72
|
|
|
73
|
+
// Close and return results
|
|
72
74
|
ctx.view?.close({ id: newRecord.id, name: newRecord.name });
|
|
73
75
|
```
|
|
74
76
|
|
|
75
|
-
### Header / Footer in
|
|
77
|
+
### Using Header / Footer in Content
|
|
76
78
|
|
|
77
79
|
```tsx
|
|
78
80
|
function DialogContent() {
|
|
@@ -84,45 +86,46 @@ function DialogContent() {
|
|
|
84
86
|
<div>Form content...</div>
|
|
85
87
|
<Footer>
|
|
86
88
|
<Button onClick={() => close()}>Cancel</Button>
|
|
87
|
-
<Button type="primary" onClick={handleSubmit}>
|
|
89
|
+
<Button type="primary" onClick={handleSubmit}>Submit</Button>
|
|
88
90
|
</Footer>
|
|
89
91
|
</div>
|
|
90
92
|
);
|
|
91
93
|
}
|
|
92
94
|
```
|
|
93
95
|
|
|
94
|
-
###
|
|
96
|
+
### Branching Based on View Type or inputArgs
|
|
95
97
|
|
|
96
98
|
```ts
|
|
97
99
|
if (ctx.view?.type === 'embed') {
|
|
100
|
+
// Hide header in embedded views
|
|
98
101
|
ctx.model.setProps('headerStyle', { display: 'none' });
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
const collectionName = ctx.view?.inputArgs?.collectionName;
|
|
102
105
|
if (collectionName === 'users') {
|
|
103
|
-
// User selector
|
|
106
|
+
// User selector scenario
|
|
104
107
|
}
|
|
105
108
|
```
|
|
106
109
|
|
|
107
|
-
##
|
|
110
|
+
## Relationship with ctx.viewer and ctx.openView
|
|
108
111
|
|
|
109
|
-
|
|
|
110
|
-
|
|
111
|
-
| **Open new view** | `ctx.viewer.dialog()` / `ctx.viewer.drawer()` or `ctx.openView()` |
|
|
112
|
-
| **Operate current view** | `ctx.view.close()`, `ctx.view.update()` |
|
|
113
|
-
| **
|
|
112
|
+
| Purpose | Recommended Usage |
|
|
113
|
+
|------|----------|
|
|
114
|
+
| **Open a new view** | `ctx.viewer.dialog()` / `ctx.viewer.drawer()` or `ctx.openView()` |
|
|
115
|
+
| **Operate on current view** | `ctx.view.close()`, `ctx.view.update()` |
|
|
116
|
+
| **Get opening parameters** | `ctx.view.inputArgs` |
|
|
114
117
|
|
|
115
|
-
`ctx.viewer`
|
|
118
|
+
`ctx.viewer` is responsible for "opening" a view, while `ctx.view` represents the "current" view instance. `ctx.openView` is used to open pre-configured workflow views.
|
|
116
119
|
|
|
117
120
|
## Notes
|
|
118
121
|
|
|
119
|
-
- `ctx.view` is only available inside a view;
|
|
120
|
-
- Use optional chaining: `ctx.view?.close?.()` to avoid errors when no view context.
|
|
121
|
-
- `
|
|
122
|
+
- `ctx.view` is only available inside a view; it is `undefined` on standard pages.
|
|
123
|
+
- Use optional chaining: `ctx.view?.close?.()` to avoid errors when no view context exists.
|
|
124
|
+
- The `result` from `close(result)` is passed to the Promise returned by `ctx.viewer.open()`.
|
|
122
125
|
|
|
123
126
|
## Related
|
|
124
127
|
|
|
125
|
-
- [ctx.openView()](./open-view.md):
|
|
126
|
-
- [ctx.modal](./modal.md):
|
|
128
|
+
- [ctx.openView()](./open-view.md): Open a pre-configured workflow view
|
|
129
|
+
- [ctx.modal](./modal.md): Lightweight popups (info, confirmation, etc.)
|
|
127
130
|
|
|
128
|
-
> `ctx.viewer` provides `dialog()`, `drawer()`, `popover()`, `embed()
|
|
131
|
+
> `ctx.viewer` provides methods like `dialog()`, `drawer()`, `popover()`, and `embed()` to open views. The `content` opened by these methods can access `ctx.view`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Please provide the Chinese source text you would like me to translate. I am ready to apply all the rules and terminology specified in your instructions.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Importing Modules
|
|
2
2
|
|
|
3
|
-
In RunJS you can use two
|
|
3
|
+
In RunJS, you can use two types of modules: **Built-in modules** (accessed directly via `ctx.libs` without importing) and **External modules** (loaded on demand via `ctx.importAsync()` or `ctx.requireAsync()`).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Built-in Modules - ctx.libs (
|
|
7
|
+
## Built-in Modules - ctx.libs (No import required)
|
|
8
8
|
|
|
9
|
-
RunJS
|
|
9
|
+
RunJS includes several built-in libraries that can be accessed directly through `ctx.libs`. You **do not** need to use `import` or asynchronous loading for these.
|
|
10
10
|
|
|
11
11
|
| Property | Description |
|
|
12
|
-
|
|
13
|
-
| **ctx.libs.React** | React core for JSX and Hooks |
|
|
14
|
-
| **ctx.libs.ReactDOM** | ReactDOM (
|
|
15
|
-
| **ctx.libs.antd** | Ant Design
|
|
12
|
+
|------|------|
|
|
13
|
+
| **ctx.libs.React** | React core, used for JSX and Hooks |
|
|
14
|
+
| **ctx.libs.ReactDOM** | ReactDOM (can be used for `createRoot`, etc.) |
|
|
15
|
+
| **ctx.libs.antd** | Ant Design component library |
|
|
16
16
|
| **ctx.libs.antdIcons** | Ant Design icons |
|
|
17
|
-
| **ctx.libs.math** | [Math.js](https://mathjs.org/):
|
|
17
|
+
| **ctx.libs.math** | [Math.js](https://mathjs.org/): Mathematical expressions, matrix operations, etc. |
|
|
18
18
|
| **ctx.libs.formula** | [Formula.js](https://formulajs.github.io/): Excel-like formulas (SUM, AVERAGE, etc.) |
|
|
19
19
|
|
|
20
20
|
### Example: React and antd
|
|
@@ -22,7 +22,7 @@ RunJS provides common libraries via `ctx.libs`; you can use them directly **with
|
|
|
22
22
|
```tsx
|
|
23
23
|
const { Button } = ctx.libs.antd;
|
|
24
24
|
|
|
25
|
-
ctx.render(<Button>Click</Button>);
|
|
25
|
+
ctx.render(<Button>Click Me</Button>);
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### Example: ctx.libs.math
|
|
@@ -44,67 +44,67 @@ const avg = ctx.libs.formula.AVERAGE(values);
|
|
|
44
44
|
|
|
45
45
|
## External Modules
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
When you need third-party libraries, choose the loading method based on the module format:
|
|
48
48
|
|
|
49
|
-
- **ESM** →
|
|
50
|
-
- **UMD/AMD** →
|
|
49
|
+
- **ESM Modules** → Use `ctx.importAsync()`
|
|
50
|
+
- **UMD/AMD Modules** → Use `ctx.requireAsync()`
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### Importing ESM Modules
|
|
55
55
|
|
|
56
|
-
Use **`ctx.importAsync()`** to load ESM modules by URL
|
|
56
|
+
Use **`ctx.importAsync()`** to dynamically load ESM modules by URL. This is suitable for scenarios like JS blocks, JS fields, and JS actions.
|
|
57
57
|
|
|
58
58
|
```ts
|
|
59
59
|
importAsync<T = any>(url: string): Promise<T>;
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
- **url**: ESM module
|
|
62
|
+
- **url**: The ESM module address. Supports shorthand formats like `<package>@<version>` or subpaths like `<package>@<version>/<file-path>` (e.g., `vue@3.4.0`, `lodash@4/lodash.js`). These will be prefixed with the configured CDN base URL. Full URLs are also supported.
|
|
63
63
|
- **Returns**: The resolved module namespace object.
|
|
64
64
|
|
|
65
65
|
#### Default: https://esm.sh
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
If not configured otherwise, shorthand forms will use **https://esm.sh** as the CDN prefix. For example:
|
|
68
68
|
|
|
69
69
|
```ts
|
|
70
70
|
const Vue = await ctx.importAsync('vue@3.4.0');
|
|
71
|
-
//
|
|
71
|
+
// Equivalent to loading from https://esm.sh/vue@3.4.0
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
#### Self-hosted esm.sh
|
|
74
|
+
#### Self-hosted esm.sh Service
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
If you need to use an internal network or a self-built CDN, you can deploy a service compatible with the esm.sh protocol and specify it via environment variables:
|
|
77
77
|
|
|
78
|
-
- **ESM_CDN_BASE_URL**:
|
|
79
|
-
- **ESM_CDN_SUFFIX**: Optional suffix (e.g
|
|
78
|
+
- **ESM_CDN_BASE_URL**: The base URL for the ESM CDN (defaults to `https://esm.sh`)
|
|
79
|
+
- **ESM_CDN_SUFFIX**: Optional suffix (e.g., `/+esm` for jsDelivr)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
For self-hosting, refer to: [https://github.com/nocobase/esm-server](https://github.com/nocobase/esm-server)
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
|
-
###
|
|
85
|
+
### Importing UMD/AMD Modules
|
|
86
86
|
|
|
87
|
-
Use **`ctx.requireAsync()`** to load UMD/AMD
|
|
87
|
+
Use **`ctx.requireAsync()`** to asynchronously load UMD/AMD modules or scripts that attach to the global object.
|
|
88
88
|
|
|
89
89
|
```ts
|
|
90
90
|
requireAsync<T = any>(url: string): Promise<T>;
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
- **url**:
|
|
94
|
-
- **Shorthand path**: `<package>@<version>/<path>`,
|
|
95
|
-
- **Full URL**: Any CDN
|
|
96
|
-
- **Returns**: The loaded library object (
|
|
93
|
+
- **url**: Supports two forms:
|
|
94
|
+
- **Shorthand path**: `<package>@<version>/<file-path>`, similar to `ctx.importAsync()`, resolved according to the current ESM CDN configuration. When resolving, `?raw` is appended to request the raw file directly (usually a UMD build). For example, `echarts@5/dist/echarts.min.js` actually requests `https://esm.sh/echarts@5/dist/echarts.min.js?raw` (when using the default esm.sh).
|
|
95
|
+
- **Full URL**: Any full CDN address (e.g., `https://cdn.jsdelivr.net/npm/xxx`).
|
|
96
|
+
- **Returns**: The loaded library object (the specific form depends on how the library exports its content).
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
After loading, many UMD libraries attach themselves to the global object (e.g., `window.xxx`). You can use them as described in the library's documentation.
|
|
99
99
|
|
|
100
100
|
**Example**
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
|
-
// Shorthand (resolved via esm.sh
|
|
103
|
+
// Shorthand path (resolved via esm.sh as ...?raw)
|
|
104
104
|
const echarts = await ctx.requireAsync('echarts@5/dist/echarts.min.js');
|
|
105
105
|
|
|
106
106
|
// Full URL
|
|
107
107
|
const dayjs = await ctx.requireAsync('https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js');
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
**Note**: If a library provides
|
|
110
|
+
**Note**: If a library provides an ESM version, prefer using `ctx.importAsync()` for better module semantics and Tree-shaking.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# RunJS Overview
|
|
2
2
|
|
|
3
|
-
RunJS is the JavaScript execution environment in NocoBase
|
|
3
|
+
RunJS is the JavaScript execution environment used in NocoBase for scenarios such as **JS Blocks**, **JS Fields**, and **JS Actions**. Code runs in a restricted sandbox, providing safe access to the `ctx` (Context API) and includes the following capabilities:
|
|
4
4
|
|
|
5
5
|
- Top-level `await`
|
|
6
6
|
- Importing external modules
|
|
7
|
-
-
|
|
7
|
+
- Rendering within containers
|
|
8
8
|
- Global variables
|
|
9
9
|
|
|
10
|
-
## Top-level
|
|
10
|
+
## Top-level await
|
|
11
11
|
|
|
12
|
-
RunJS supports top-level `await
|
|
12
|
+
RunJS supports top-level `await`, eliminating the need to wrap code in an IIFE.
|
|
13
13
|
|
|
14
|
-
**Not
|
|
14
|
+
**Not Recommended**
|
|
15
15
|
|
|
16
16
|
```jsx
|
|
17
17
|
async function test() {}
|
|
@@ -29,20 +29,20 @@ await test();
|
|
|
29
29
|
|
|
30
30
|
## Importing External Modules
|
|
31
31
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
32
|
+
- Use `ctx.importAsync()` for ESM modules (Recommended)
|
|
33
|
+
- Use `ctx.requireAsync()` for UMD/AMD modules
|
|
34
34
|
|
|
35
|
-
##
|
|
35
|
+
## Rendering within Containers
|
|
36
36
|
|
|
37
|
-
Use `ctx.render()` to render content into the current container (`ctx.element`)
|
|
37
|
+
Use `ctx.render()` to render content into the current container (`ctx.element`). It supports the following three formats:
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### Rendering JSX
|
|
40
40
|
|
|
41
41
|
```jsx
|
|
42
42
|
ctx.render(<button>Button</button>);
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
###
|
|
45
|
+
### Rendering DOM Nodes
|
|
46
46
|
|
|
47
47
|
```js
|
|
48
48
|
const div = document.createElement('div');
|
|
@@ -51,7 +51,7 @@ div.innerHTML = 'Hello World';
|
|
|
51
51
|
ctx.render(div);
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### Rendering HTML Strings
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
57
|
ctx.render('<h1>Hello World</h1>');
|
|
@@ -62,4 +62,4 @@ ctx.render('<h1>Hello World</h1>');
|
|
|
62
62
|
- `window`
|
|
63
63
|
- `document`
|
|
64
64
|
- `navigator`
|
|
65
|
-
- `ctx`
|
|
65
|
+
- `ctx`
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# JSX
|
|
2
2
|
|
|
3
|
-
RunJS supports JSX
|
|
3
|
+
RunJS supports JSX syntax, allowing you to write code similar to React components. JSX is automatically compiled before execution.
|
|
4
4
|
|
|
5
|
-
## Compilation
|
|
5
|
+
## Compilation Notes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- JSX
|
|
9
|
-
- **No need to import React**: write JSX directly;
|
|
10
|
-
- When loading external React via `ctx.importAsync('react@x.x.x')`, JSX
|
|
7
|
+
- Uses [sucrase](https://github.com/alangpierce/sucrase) to transform JSX.
|
|
8
|
+
- JSX is compiled into `ctx.libs.React.createElement` and `ctx.libs.React.Fragment`.
|
|
9
|
+
- **No need to import React**: You can write JSX directly; it will automatically use `ctx.libs.React` after compilation.
|
|
10
|
+
- When loading external React via `ctx.importAsync('react@x.x.x')`, JSX will switch to using the `createElement` method from that specific instance.
|
|
11
11
|
|
|
12
12
|
## Using Built-in React and Components
|
|
13
13
|
|
|
14
|
-
RunJS includes React and common UI libraries
|
|
14
|
+
RunJS includes React and common UI libraries built-in. You can access them directly via `ctx.libs` without using `import`:
|
|
15
15
|
|
|
16
16
|
- **ctx.libs.React** — React core
|
|
17
|
-
- **ctx.libs.ReactDOM** — ReactDOM (
|
|
17
|
+
- **ctx.libs.ReactDOM** — ReactDOM (can be used with `createRoot` if needed)
|
|
18
18
|
- **ctx.libs.antd** — Ant Design components
|
|
19
19
|
- **ctx.libs.antdIcons** — Ant Design icons
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@ const { Button } = ctx.libs.antd;
|
|
|
24
24
|
ctx.render(<Button>Click</Button>);
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
When writing JSX directly, you don't need to destructure React. You only need to destructure from `ctx.libs` when using **Hooks** (such as `useState`, `useEffect`) or **Fragment** (`<>...</>`):
|
|
28
28
|
|
|
29
29
|
```tsx
|
|
30
30
|
const { React } = ctx.libs;
|
|
@@ -38,11 +38,11 @@ const Counter = () => {
|
|
|
38
38
|
ctx.render(<Counter />);
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
**Note**: Built-in React and React
|
|
41
|
+
**Note**: Built-in React and external React imported via `ctx.importAsync()` **cannot be mixed**. If you use an external UI library, React must also be imported from the same external source.
|
|
42
42
|
|
|
43
43
|
## Using External React and Components
|
|
44
44
|
|
|
45
|
-
When
|
|
45
|
+
When loading a specific version of React and UI libraries via `ctx.importAsync()`, JSX will use that React instance:
|
|
46
46
|
|
|
47
47
|
```tsx
|
|
48
48
|
const React = await ctx.importAsync('react@19.2.4');
|
|
@@ -51,7 +51,7 @@ const { Button } = await ctx.importAsync('antd@6.2.2?bundle');
|
|
|
51
51
|
ctx.render(<Button>Click</Button>);
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
If antd depends on react/react-dom,
|
|
54
|
+
If antd depends on react/react-dom, you can specify the same version via `deps` to avoid multiple instances:
|
|
55
55
|
|
|
56
56
|
```tsx
|
|
57
57
|
const React = await ctx.importAsync('react@18.2.0');
|
|
@@ -60,15 +60,15 @@ const { Button } = await ctx.importAsync('antd@5.29.3?bundle&deps=react@18.2.0,r
|
|
|
60
60
|
ctx.render(<Button>Button</Button>);
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
**Note**:
|
|
63
|
+
**Note**: When using external React, UI libraries like antd must also be imported via `ctx.importAsync()`. Do not mix them with `ctx.libs.antd`.
|
|
64
64
|
|
|
65
|
-
## JSX
|
|
65
|
+
## JSX Syntax Key Points
|
|
66
66
|
|
|
67
67
|
- **Components and props**: `<Button type="primary">Text</Button>`
|
|
68
|
-
- **Fragment**: `<>...</>` or `<React.Fragment>...</React.Fragment>` (
|
|
69
|
-
- **Expressions**: Use `{expression}` in JSX
|
|
70
|
-
- **Conditional
|
|
71
|
-
- **List
|
|
68
|
+
- **Fragment**: `<>...</>` or `<React.Fragment>...</React.Fragment>` (requires destructuring `const { React } = ctx.libs` when using Fragment)
|
|
69
|
+
- **Expressions**: Use `{expression}` in JSX to insert variables or operations, such as `{ctx.user.name}` or `{count + 1}`. Do not use `{{ }}` template syntax.
|
|
70
|
+
- **Conditional Rendering**: `{flag && <span>Content</span>}` or `{flag ? <A /> : <B />}`
|
|
71
|
+
- **List Rendering**: Use `array.map()` to return a list of elements, and ensure each element has a stable `key`.
|
|
72
72
|
|
|
73
73
|
```tsx
|
|
74
74
|
const { React } = ctx.libs;
|
|
@@ -81,4 +81,4 @@ ctx.render(
|
|
|
81
81
|
))}
|
|
82
82
|
</ul>
|
|
83
83
|
);
|
|
84
|
-
```
|
|
84
|
+
```
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
# FormBlockModel
|
|
2
|
-
|
|
3
|
-
Form block model: the block model type for form blocks (Form, EditForm, etc.). In RunJS, when the current JS runs inside a form block, `ctx.blockModel` is often a FormBlockModel (or EditFormModel). See [ctx.blockModel](../context/block-model.md) and [ctx.form](../context/form.md) for usage.
|
|
1
|
+
# FormBlockModel
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# In-container Rendering
|
|
2
2
|
|
|
3
|
-
Use `ctx.render()` to render content into the current container (`ctx.element`)
|
|
3
|
+
Use `ctx.render()` to render content into the current container (`ctx.element`). It supports the following three forms:
|
|
4
4
|
|
|
5
|
-
## ctx.render()
|
|
5
|
+
## `ctx.render()`
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Rendering JSX
|
|
8
8
|
|
|
9
9
|
```jsx
|
|
10
10
|
ctx.render(<button>Button</button>);
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Rendering DOM Nodes
|
|
14
14
|
|
|
15
15
|
```js
|
|
16
16
|
const div = document.createElement('div');
|
|
@@ -18,17 +18,17 @@ div.innerHTML = 'Hello World';
|
|
|
18
18
|
ctx.render(div);
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### Rendering HTML Strings
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
ctx.render('<h1>Hello World</h1>');
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
## JSX
|
|
27
|
+
## JSX Description
|
|
28
28
|
|
|
29
|
-
RunJS can render JSX directly
|
|
29
|
+
RunJS can render JSX directly. You can use the built-in React/component libraries or load external dependencies on demand.
|
|
30
30
|
|
|
31
|
-
### Using Built-in React and
|
|
31
|
+
### Using Built-in React and Component Libraries
|
|
32
32
|
|
|
33
33
|
```jsx
|
|
34
34
|
const { Button } = ctx.libs.antd;
|
|
@@ -36,9 +36,9 @@ const { Button } = ctx.libs.antd;
|
|
|
36
36
|
ctx.render(<Button>Click</Button>);
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
### Using External React and
|
|
39
|
+
### Using External React and Component Libraries
|
|
40
40
|
|
|
41
|
-
Load
|
|
41
|
+
Load specific versions on demand via `ctx.importAsync()`:
|
|
42
42
|
|
|
43
43
|
```jsx
|
|
44
44
|
const React = await ctx.importAsync('react@19.2.4');
|
|
@@ -47,18 +47,18 @@ const { Button } = await ctx.importAsync('antd@6.2.2?bundle');
|
|
|
47
47
|
ctx.render(<Button>Click</Button>);
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Suitable for scenarios requiring specific versions or third-party components.
|
|
51
51
|
|
|
52
52
|
## ctx.element
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Not recommended (deprecated):
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
57
|
ctx.element.innerHTML = '<h1>Hello World</h1>';
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
Recommended way:
|
|
61
61
|
|
|
62
62
|
```js
|
|
63
63
|
ctx.render(<h1>Hello World</h1>);
|
|
64
|
-
```
|
|
64
|
+
```
|