@nocobase/plugin-flow-engine 2.1.0-alpha.9 → 2.1.0-beta.10
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 +51 -53
- package/dist/ai/docs/runjs/context/collection.md +39 -39
- package/dist/ai/docs/runjs/context/data-source-manager.md +30 -40
- package/dist/ai/docs/runjs/context/data-source.md +44 -52
- package/dist/ai/docs/runjs/context/element.md +38 -44
- package/dist/ai/docs/runjs/context/exit-all.md +35 -37
- package/dist/ai/docs/runjs/context/exit.md +35 -38
- package/dist/ai/docs/runjs/context/filter-manager.md +30 -36
- package/dist/ai/docs/runjs/context/form.md +57 -57
- package/dist/ai/docs/runjs/context/get-model.md +21 -22
- package/dist/ai/docs/runjs/context/get-value.md +19 -20
- package/dist/ai/docs/runjs/context/get-var.md +55 -61
- package/dist/ai/docs/runjs/context/i18n.md +14 -17
- package/dist/ai/docs/runjs/context/import-async.md +45 -333
- 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 +31 -34
- package/dist/ai/docs/runjs/context/logger.md +40 -41
- package/dist/ai/docs/runjs/context/make-resource.md +26 -27
- package/dist/ai/docs/runjs/context/message.md +41 -42
- package/dist/ai/docs/runjs/context/modal.md +44 -44
- package/dist/ai/docs/runjs/context/model.md +33 -36
- package/dist/ai/docs/runjs/context/notification.md +40 -41
- package/dist/ai/docs/runjs/context/off.md +14 -14
- package/dist/ai/docs/runjs/context/on.md +29 -30
- package/dist/ai/docs/runjs/context/open-view.md +40 -40
- package/dist/ai/docs/runjs/context/render.md +32 -37
- package/dist/ai/docs/runjs/context/request.md +45 -46
- package/dist/ai/docs/runjs/context/require-async.md +25 -28
- package/dist/ai/docs/runjs/context/resource.md +34 -34
- package/dist/ai/docs/runjs/context/route.md +34 -36
- package/dist/ai/docs/runjs/context/router.md +31 -43
- package/dist/ai/docs/runjs/context/set-value.md +17 -18
- package/dist/ai/docs/runjs/context/t.md +17 -20
- package/dist/ai/docs/runjs/context/view.md +46 -49
- package/dist/ai/docs/runjs/document.md +0 -1
- 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 +3 -1
- 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/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, embed, etc.); used to access view-level info and actions. Provided by FlowViewContext; only available inside 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** | In `content`, use `ctx.view.close()` to close, or render `Header`, `Footer` for title and actions |
|
|
10
|
+
| **After form submit** | Call `ctx.view.close(result)` to close and pass result back |
|
|
11
|
+
| **JSBlock / Action** | Check `ctx.view.type` for view type, or read `ctx.view.inputArgs` for open params |
|
|
12
|
+
| **Association select, sub-table** | Read `inputArgs` for `collectionName`, `filterByTk`, `parentId`, etc. for loading data |
|
|
13
13
|
|
|
14
|
-
> Note: `ctx.view` is only available in RunJS
|
|
14
|
+
> Note: `ctx.view` is only available in RunJS when a view context exists (e.g. inside `ctx.viewer.dialog()` content, dialog form, association selector); in a normal page or backend context it is `undefined`—use optional chaining: `ctx.view?.close?.()`.
|
|
15
15
|
|
|
16
|
-
## Type
|
|
16
|
+
## Type
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
type FlowView = {
|
|
@@ -25,56 +25,54 @@ type FlowView = {
|
|
|
25
25
|
update: (newConfig: any) => void;
|
|
26
26
|
navigation?: ViewNavigation;
|
|
27
27
|
destroy?: () => void;
|
|
28
|
-
submit?: () => Promise<any>;
|
|
28
|
+
submit?: () => Promise<any>;
|
|
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-
|
|
37
|
+
| `inputArgs` | `Record<string, any>` | Params passed when opening the view |
|
|
38
|
+
| `Header` | `React.FC \| null` | Header component for title and actions |
|
|
39
|
+
| `Footer` | `React.FC \| null` | Footer for buttons, etc. |
|
|
40
|
+
| `close(result?, force?)` | `void` | Close current view; optional `result` passed back to caller |
|
|
41
|
+
| `update(newConfig)` | `void` | Update view config (e.g. width, title) |
|
|
42
|
+
| `navigation` | `ViewNavigation \| undefined` | In-view navigation (tabs, etc.) |
|
|
43
43
|
|
|
44
|
-
> Currently
|
|
44
|
+
> Currently only `dialog` and `drawer` support `Header` and `Footer`.
|
|
45
45
|
|
|
46
|
-
##
|
|
46
|
+
## inputArgs (common fields)
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Fields in `inputArgs` depend on how the view was opened; common ones:
|
|
49
49
|
|
|
50
50
|
| Field | Description |
|
|
51
|
-
|
|
51
|
+
|-------|-------------|
|
|
52
52
|
| `viewUid` | View UID |
|
|
53
53
|
| `collectionName` | Collection name |
|
|
54
|
-
| `filterByTk` | Primary key filter (
|
|
55
|
-
| `parentId` | Parent
|
|
56
|
-
| `sourceId` | Source record
|
|
54
|
+
| `filterByTk` | Primary key filter (single record) |
|
|
55
|
+
| `parentId` | Parent id (associations) |
|
|
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 select/change |
|
|
60
|
+
| `tabUid` | Current tab UID (in-page) |
|
|
61
61
|
|
|
62
|
-
Access
|
|
62
|
+
Access via `ctx.getVar('ctx.view.inputArgs.xxx')` or `ctx.view.inputArgs.xxx`.
|
|
63
63
|
|
|
64
64
|
## Examples
|
|
65
65
|
|
|
66
|
-
###
|
|
66
|
+
### Close current view
|
|
67
67
|
|
|
68
68
|
```ts
|
|
69
|
-
// Close dialog after successful submission
|
|
70
69
|
await ctx.resource.runAction('create', { data: formData });
|
|
71
70
|
ctx.view?.close();
|
|
72
71
|
|
|
73
|
-
// Close and return results
|
|
74
72
|
ctx.view?.close({ id: newRecord.id, name: newRecord.name });
|
|
75
73
|
```
|
|
76
74
|
|
|
77
|
-
###
|
|
75
|
+
### Header / Footer in content
|
|
78
76
|
|
|
79
77
|
```tsx
|
|
80
78
|
function DialogContent() {
|
|
@@ -86,46 +84,45 @@ function DialogContent() {
|
|
|
86
84
|
<div>Form content...</div>
|
|
87
85
|
<Footer>
|
|
88
86
|
<Button onClick={() => close()}>Cancel</Button>
|
|
89
|
-
<Button type="primary" onClick={handleSubmit}>
|
|
87
|
+
<Button type="primary" onClick={handleSubmit}>OK</Button>
|
|
90
88
|
</Footer>
|
|
91
89
|
</div>
|
|
92
90
|
);
|
|
93
91
|
}
|
|
94
92
|
```
|
|
95
93
|
|
|
96
|
-
###
|
|
94
|
+
### Branch by view type or inputArgs
|
|
97
95
|
|
|
98
96
|
```ts
|
|
99
97
|
if (ctx.view?.type === 'embed') {
|
|
100
|
-
// Hide header in embedded views
|
|
101
98
|
ctx.model.setProps('headerStyle', { display: 'none' });
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
const collectionName = ctx.view?.inputArgs?.collectionName;
|
|
105
102
|
if (collectionName === 'users') {
|
|
106
|
-
// User selector
|
|
103
|
+
// User selector
|
|
107
104
|
}
|
|
108
105
|
```
|
|
109
106
|
|
|
110
|
-
##
|
|
107
|
+
## Relation to ctx.viewer, ctx.openView
|
|
111
108
|
|
|
112
|
-
|
|
|
113
|
-
|
|
114
|
-
| **Open
|
|
115
|
-
| **Operate
|
|
116
|
-
| **
|
|
109
|
+
| Use | Recommended |
|
|
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
|
+
| **Open params** | `ctx.view.inputArgs` |
|
|
117
114
|
|
|
118
|
-
`ctx.viewer`
|
|
115
|
+
`ctx.viewer` opens views; `ctx.view` is the current view instance; `ctx.openView` opens configured flow views.
|
|
119
116
|
|
|
120
117
|
## Notes
|
|
121
118
|
|
|
122
|
-
- `ctx.view` is only available inside a view; it is `undefined
|
|
123
|
-
- Use optional chaining: `ctx.view?.close?.()` to avoid errors when no view context
|
|
124
|
-
-
|
|
119
|
+
- `ctx.view` is only available inside a view; on a normal page it is `undefined`.
|
|
120
|
+
- Use optional chaining: `ctx.view?.close?.()` to avoid errors when no view context.
|
|
121
|
+
- `close(result)` passes `result` to the Promise returned by `ctx.viewer.open()`.
|
|
125
122
|
|
|
126
123
|
## Related
|
|
127
124
|
|
|
128
|
-
- [ctx.openView()](./open-view.md):
|
|
129
|
-
- [ctx.modal](./modal.md):
|
|
125
|
+
- [ctx.openView()](./open-view.md): open configured flow view
|
|
126
|
+
- [ctx.modal](./modal.md): lightweight modals (info, confirm, etc.)
|
|
130
127
|
|
|
131
|
-
> `ctx.viewer` provides
|
|
128
|
+
> `ctx.viewer` provides `dialog()`, `drawer()`, `popover()`, `embed()`; inside their `content` you can use `ctx.view`.
|
|
@@ -1 +0,0 @@
|
|
|
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
|
+
# Import Modules
|
|
2
2
|
|
|
3
|
-
In RunJS
|
|
3
|
+
In RunJS you can use two kinds of modules: **built-in modules** (via `ctx.libs`, no import needed) 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)
|
|
8
8
|
|
|
9
|
-
RunJS
|
|
9
|
+
RunJS provides common libraries via `ctx.libs`; you can use them directly **without** `import` or async loading.
|
|
10
10
|
|
|
11
11
|
| Property | Description |
|
|
12
|
-
|
|
13
|
-
| **ctx.libs.React** | React core
|
|
14
|
-
| **ctx.libs.ReactDOM** | ReactDOM (
|
|
15
|
-
| **ctx.libs.antd** | Ant Design
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| **ctx.libs.React** | React core for JSX and Hooks |
|
|
14
|
+
| **ctx.libs.ReactDOM** | ReactDOM (e.g. for createRoot) |
|
|
15
|
+
| **ctx.libs.antd** | Ant Design components |
|
|
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/): math 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 includes several built-in libraries that can be accessed directly through
|
|
|
22
22
|
```tsx
|
|
23
23
|
const { Button } = ctx.libs.antd;
|
|
24
24
|
|
|
25
|
-
ctx.render(<Button>Click
|
|
25
|
+
ctx.render(<Button>Click</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
|
+
For third-party libraries, choose the loader by module format:
|
|
48
48
|
|
|
49
|
-
- **ESM
|
|
50
|
-
- **UMD/AMD
|
|
49
|
+
- **ESM** → use `ctx.importAsync()`
|
|
50
|
+
- **UMD/AMD** → use `ctx.requireAsync()`
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### Import ESM Modules
|
|
55
55
|
|
|
56
|
-
Use **`ctx.importAsync()`** to
|
|
56
|
+
Use **`ctx.importAsync()`** to load ESM modules by URL at runtime. Suitable for JS Block, JS Field, JS Action, etc.
|
|
57
57
|
|
|
58
58
|
```ts
|
|
59
59
|
importAsync<T = any>(url: string): Promise<T>;
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
- **url**:
|
|
62
|
+
- **url**: ESM module URL. Supports shorthand `<package>@<version>` or subpath `<package>@<version>/<path>` (e.g. `vue@3.4.0`, `lodash@4/lodash.js`), which is resolved with the configured CDN prefix; 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
|
+
When not configured, the shorthand form uses **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
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
For intranet or custom CDN, deploy an esm.sh-compatible service and set:
|
|
77
77
|
|
|
78
|
-
- **ESM_CDN_BASE_URL**:
|
|
79
|
-
- **ESM_CDN_SUFFIX**: Optional suffix (e.g
|
|
78
|
+
- **ESM_CDN_BASE_URL**: ESM CDN base URL (default `https://esm.sh`)
|
|
79
|
+
- **ESM_CDN_SUFFIX**: Optional suffix (e.g. jsDelivr’s `/+esm`)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Reference: [https://github.com/nocobase/esm-server](https://github.com/nocobase/esm-server)
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
|
-
###
|
|
85
|
+
### Import UMD/AMD Modules
|
|
86
86
|
|
|
87
|
-
Use **`ctx.requireAsync()`** to
|
|
87
|
+
Use **`ctx.requireAsync()`** to load UMD/AMD scripts or scripts that attach to the global object by URL.
|
|
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>/<
|
|
95
|
-
- **Full URL**: Any
|
|
96
|
-
- **Returns**: The loaded library object (
|
|
93
|
+
- **url**: Either:
|
|
94
|
+
- **Shorthand path**: `<package>@<version>/<path>`, same as `ctx.importAsync()`; resolved with the current ESM CDN config; `?raw` is appended to request the raw file (usually UMD). E.g. `echarts@5/dist/echarts.min.js` becomes `https://esm.sh/echarts@5/dist/echarts.min.js?raw` when using default esm.sh.
|
|
95
|
+
- **Full URL**: Any CDN URL (e.g. `https://cdn.jsdelivr.net/npm/xxx`).
|
|
96
|
+
- **Returns**: The loaded library object (shape depends on the library’s exports).
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
Many UMD libraries attach to the global (e.g. `window.xxx`); use them as documented.
|
|
99
99
|
|
|
100
100
|
**Example**
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
|
-
// Shorthand
|
|
103
|
+
// Shorthand (resolved via esm.sh with ...?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 both ESM and UMD, prefer `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
|
|
3
|
+
RunJS is the JavaScript execution environment in NocoBase used for **JS Block**, **JS Field**, **JS Action**, and similar scenarios. Code runs in a restricted sandbox with safe access to the `ctx` (context API) and supports:
|
|
4
4
|
|
|
5
5
|
- Top-level `await`
|
|
6
6
|
- Importing external modules
|
|
7
|
-
-
|
|
7
|
+
- Render in container
|
|
8
8
|
- Global variables
|
|
9
9
|
|
|
10
|
-
## Top-level await
|
|
10
|
+
## Top-level `await`
|
|
11
11
|
|
|
12
|
-
RunJS supports top-level `await
|
|
12
|
+
RunJS supports top-level `await`; you do not 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
|
+
- ESM modules: use `ctx.importAsync()` (recommended)
|
|
33
|
+
- UMD/AMD modules: use `ctx.requireAsync()`
|
|
34
34
|
|
|
35
|
-
##
|
|
35
|
+
## Render in Container
|
|
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`) in three ways:
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### Render JSX
|
|
40
40
|
|
|
41
41
|
```jsx
|
|
42
42
|
ctx.render(<button>Button</button>);
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
###
|
|
45
|
+
### Render DOM Node
|
|
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
|
+
### Render HTML String
|
|
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; you can write code like React components, and JSX is compiled before execution.
|
|
4
4
|
|
|
5
|
-
## Compilation
|
|
5
|
+
## Compilation
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- JSX
|
|
9
|
-
- **No need to import React**:
|
|
10
|
-
- When loading external React via `ctx.importAsync('react@x.x.x')`, JSX
|
|
7
|
+
- JSX is transformed with [sucrase](https://github.com/alangpierce/sucrase)
|
|
8
|
+
- JSX compiles to `ctx.libs.React.createElement` and `ctx.libs.React.Fragment`
|
|
9
|
+
- **No need to import React**: write JSX directly; the compiler uses `ctx.libs.React`
|
|
10
|
+
- When loading external React via `ctx.importAsync('react@x.x.x')`, JSX uses that instance’s `createElement`
|
|
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; use them via `ctx.libs` without `import`:
|
|
15
15
|
|
|
16
16
|
- **ctx.libs.React** — React core
|
|
17
|
-
- **ctx.libs.ReactDOM** — ReactDOM (
|
|
17
|
+
- **ctx.libs.ReactDOM** — ReactDOM (e.g. for createRoot)
|
|
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
|
+
You don’t need to destructure React for plain JSX; destructure from `ctx.libs` only when using **Hooks** (e.g. `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
|
|
41
|
+
**Note**: Built-in React and React loaded via `ctx.importAsync()` **must not be mixed**. If you use an external UI library, import React from the same external source.
|
|
42
42
|
|
|
43
43
|
## Using External React and Components
|
|
44
44
|
|
|
45
|
-
When
|
|
45
|
+
When you load React and a UI library with `ctx.importAsync()`, JSX uses 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, use `deps` to pin the same version and 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**: With external React, load antd and other UI libraries via `ctx.importAsync()`; do not mix with `ctx.libs.antd`.
|
|
64
64
|
|
|
65
|
-
## JSX
|
|
65
|
+
## JSX Basics
|
|
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>` (destructure `const { React } = ctx.libs` when using Fragment)
|
|
69
|
+
- **Expressions**: Use `{expression}` in JSX for variables or expressions, e.g. `{ctx.user.name}`, `{count + 1}`; do not use `{{ }}` template syntax
|
|
70
|
+
- **Conditional render**: `{flag && <span>Content</span>}` or `{flag ? <A /> : <B />}`
|
|
71
|
+
- **List render**: Use `array.map()` and give each element 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 +1,3 @@
|
|
|
1
|
-
# FormBlockModel
|
|
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,16 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Render in Container
|
|
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`) in three ways:
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## ctx.render()
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Render JSX
|
|
8
8
|
|
|
9
9
|
```jsx
|
|
10
10
|
ctx.render(<button>Button</button>);
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Render DOM Node
|
|
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
|
+
### Render HTML String
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
ctx.render('<h1>Hello World</h1>');
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
## JSX
|
|
27
|
+
## JSX Notes
|
|
28
28
|
|
|
29
|
-
RunJS can render JSX directly
|
|
29
|
+
RunJS can render JSX directly, using either the built-in React/component library or externally loaded dependencies.
|
|
30
30
|
|
|
31
|
-
### Using Built-in React and
|
|
31
|
+
### Using Built-in React and Components
|
|
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 Components
|
|
40
40
|
|
|
41
|
-
Load specific
|
|
41
|
+
Load a specific version 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
|
+
Use this when you need a specific version or third-party components.
|
|
51
51
|
|
|
52
52
|
## ctx.element
|
|
53
53
|
|
|
54
|
-
Not recommended (deprecated):
|
|
54
|
+
**Not recommended** (deprecated):
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
57
|
ctx.element.innerHTML = '<h1>Hello World</h1>';
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
Recommended
|
|
60
|
+
**Recommended**:
|
|
61
61
|
|
|
62
62
|
```js
|
|
63
63
|
ctx.render(<h1>Hello World</h1>);
|
|
64
|
-
```
|
|
64
|
+
```
|