wenay-react2 1.0.20 → 1.0.22
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/README.md +383 -382
- package/lib/common/api.d.ts +28 -0
- package/lib/common/api.js +41 -16
- package/lib/common/src/components/Buttons/MiniButton.d.ts +1 -0
- package/lib/common/src/components/Buttons/MiniButton.js +2 -2
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.d.ts +1 -0
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.js +7 -6
- package/lib/common/src/components/Dnd/RNDFunc.js +28 -17
- package/lib/common/src/components/Dnd/RNDFunc3.d.ts +27 -17
- package/lib/common/src/components/Dnd/RNDFunc3.js +107 -105
- package/lib/common/src/components/Dnd/Resizable.js +3 -3
- package/lib/common/src/components/Menu/RightMenu.js +11 -17
- package/lib/common/src/components/Menu/StickerMenu.js +42 -28
- package/lib/common/src/components/Menu/index.d.ts +1 -1
- package/lib/common/src/components/Menu/index.js +1 -1
- package/lib/common/src/components/Modal/LeftModal.d.ts +14 -12
- package/lib/common/src/components/Modal/LeftModal.js +30 -16
- package/lib/common/src/components/Modal/Modal.d.ts +26 -12
- package/lib/common/src/components/Modal/Modal.js +66 -89
- package/lib/common/src/components/Modal/ModalContextProvider.d.ts +20 -3
- package/lib/common/src/components/Modal/ModalContextProvider.js +35 -8
- package/lib/common/src/components/MyResizeObserver.js +15 -18
- package/lib/common/src/components/Other.js +3 -2
- package/lib/common/src/components/Parameters.js +7 -6
- package/lib/common/src/components/ParametersEngine.js +25 -54
- package/lib/common/src/grid/agGrid4/agGrid4.d.ts +53 -0
- package/lib/common/src/grid/agGrid4/agGrid4.js +132 -0
- package/lib/common/src/grid/agGrid4/core.d.ts +56 -0
- package/lib/common/src/grid/agGrid4/core.js +127 -0
- package/lib/common/src/grid/agGrid4/index.d.ts +6 -0
- package/lib/common/src/grid/agGrid4/index.js +3 -0
- package/lib/common/src/grid/agGrid4/theme.d.ts +7 -0
- package/lib/common/src/grid/agGrid4/theme.js +18 -0
- package/lib/common/src/hooks/useAddDownAnyKey.d.ts +21 -2
- package/lib/common/src/hooks/useAddDownAnyKey.js +46 -8
- package/lib/common/src/hooks/useDraggable.d.ts +20 -2
- package/lib/common/src/hooks/useDraggable.js +146 -115
- package/lib/common/src/hooks/useOutside.d.ts +24 -4
- package/lib/common/src/hooks/useOutside.js +76 -27
- package/lib/common/src/logs/logs.d.ts +5 -2
- package/lib/common/src/logs/logs.js +15 -31
- package/lib/common/src/logs/logs3.d.ts +9 -9
- package/lib/common/src/logs/logs3.js +47 -38
- package/lib/common/src/logs/miniLogs.d.ts +3 -3
- package/lib/common/src/logs/miniLogs.js +28 -36
- package/lib/common/src/menu/menu.d.ts +18 -18
- package/lib/common/src/menu/menu.js +48 -24
- package/lib/common/src/menu/menuMouse.js +4 -1
- package/lib/common/src/menu/menuR.d.ts +2 -2
- package/lib/common/src/menu/menuR.js +34 -34
- package/lib/common/src/myChart/1/myChart.d.ts +5 -5
- package/lib/common/src/myChart/1/myChart.js +58 -47
- package/lib/common/src/myChart/1/myChartTest.js +8 -4
- package/lib/common/src/myChart/chartEngine/chartEngineReact.d.ts +24 -27
- package/lib/common/src/myChart/chartEngine/chartEngineReact.js +166 -117
- package/lib/common/src/styles/styleGrid.d.ts +2 -1
- package/lib/common/src/styles/styleGrid.js +10 -12
- package/lib/common/src/styles/tokens.d.ts +39 -0
- package/lib/common/src/styles/tokens.js +40 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.d.ts +7 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.js +19 -12
- package/lib/common/src/utils/arrayPromise.d.ts +6 -0
- package/lib/common/src/utils/arrayPromise.js +7 -1
- package/lib/common/src/utils/cache.js +24 -21
- package/lib/common/src/utils/inputAutoStep.d.ts +1 -1
- package/lib/common/src/utils/inputAutoStep.js +30 -19
- package/lib/common/src/utils/mapMemory.js +9 -10
- package/lib/common/updateBy.d.ts +21 -2
- package/lib/common/updateBy.js +66 -31
- package/lib/index.js +0 -2
- package/lib/style/menuRight.css +13 -26
- package/lib/style/style.css +51 -39
- package/lib/style/tokens.css +34 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,383 +1,384 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
###
|
|
8
|
-
|
|
9
|
-
#### `DivRnd3`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
type tDivRndBase = {
|
|
15
|
-
children: React.ReactElement | ((update: number) => React.ReactElement);
|
|
16
|
-
position?: { x: number; y: number };
|
|
17
|
-
size?: { height: number | string; width: number | string };
|
|
18
|
-
keyForSave?: string; //
|
|
19
|
-
limit?: { x?: { max?: number; min?: number }, y?: { max?: number; min?: number } };
|
|
20
|
-
onCLickClose?: () => void; //
|
|
21
|
-
header?: React.ReactElement | boolean; //
|
|
22
|
-
zIndex?: number;
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```textmate
|
|
28
|
-
<DivRnd3
|
|
29
|
-
keyForSave="my_tool_window"
|
|
30
|
-
size={{ width: 300, height: 200 }}
|
|
31
|
-
onCLickClose={() => setOpen(false)}
|
|
32
|
-
header={<div
|
|
33
|
-
>
|
|
34
|
-
<div
|
|
35
|
-
</DivRnd3>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
#### `GetModalJSX()`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```textmate
|
|
44
|
-
const myModal = GetModalJSX();
|
|
45
|
-
|
|
46
|
-
// 1.
|
|
47
|
-
<myModal.Render />
|
|
48
|
-
|
|
49
|
-
// 2.
|
|
50
|
-
myModal.set(<div onClick={() => myModal.set(null)}
|
|
51
|
-
//
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
###
|
|
58
|
-
|
|
59
|
-
#### `useOutside` / `DivOutsideClick`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
// Hook
|
|
65
|
-
function useOutside(params: { outsideClick: () => void, status?: boolean, ref?: RefObject }): RefObject;
|
|
66
|
-
|
|
67
|
-
// Component
|
|
68
|
-
type Props = { outsideClick: () => void, status?: boolean, zIndex?: number } & HTMLAttributes;
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```textmate
|
|
73
|
-
<DivOutsideClick outsideClick={() => setDropdownOpen(false)} status={isOpen}>
|
|
74
|
-
<div className="dropdown-menu">...</div>
|
|
75
|
-
</DivOutsideClick>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
#### `Drag22`
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
type Drag2Props = {
|
|
85
|
-
x?: number; y?: number; //
|
|
86
|
-
onX?: (val: number) => void; //
|
|
87
|
-
onY?: (val: number) => void; //
|
|
88
|
-
onStart?: () => void; onStop?: () => void;
|
|
89
|
-
children: ReactNode;
|
|
90
|
-
};
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
###
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
type tMenuReactStrictly = {
|
|
103
|
-
name: string | ((status?: any) => string);
|
|
104
|
-
onClick?: (e: any) => void | Promise<any> | Promise<any>[]; //
|
|
105
|
-
status?: boolean; //
|
|
106
|
-
next?: () => tMenuReact[] | Promise<tMenuReact[]>; //
|
|
107
|
-
func?: () => React.ReactElement | Promise<React.ReactElement>; //
|
|
108
|
-
};
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
```textmate
|
|
113
|
-
// 1.
|
|
114
|
-
const menuItems = () => [
|
|
115
|
-
{ name: "
|
|
116
|
-
{ name: "
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
<MenuR other={menuItems}>
|
|
120
|
-
<div className="item"
|
|
121
|
-
</MenuR>
|
|
122
|
-
|
|
123
|
-
// 2.
|
|
124
|
-
mouseMenuApi.map.set("global_action", [{ name: "
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
###
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
type Params<T> = {
|
|
137
|
-
gridRef?: React.RefObject<GridReadyEvent<T, any>>;
|
|
138
|
-
newData: Partial<T>[]; //
|
|
139
|
-
getId: (row: Partial<T>) => string; //
|
|
140
|
-
bufTable: { [id: string]: Partial<T> }; //
|
|
141
|
-
option?: { update?: boolean, add?: boolean, updateBuffer?: boolean, sync?: boolean };
|
|
142
|
-
};
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
```textmate
|
|
147
|
-
//
|
|
148
|
-
applyTransactionAsyncUpdate2({
|
|
149
|
-
gridRef: apiGrid,
|
|
150
|
-
newData: [{ id: "user_1", balance: 500 }],
|
|
151
|
-
getId: (e) => e.id,
|
|
152
|
-
bufTable: myLocalBuffer,
|
|
153
|
-
option: { update: true, add: true }
|
|
154
|
-
});
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
###
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
```textmate
|
|
170
|
-
const mySettings = {
|
|
171
|
-
showGrid: true, //
|
|
172
|
-
opacity: {
|
|
173
|
-
value: 0.5,
|
|
174
|
-
range: { min: 0, max: 1, step: 0.1 },
|
|
175
|
-
name: "
|
|
176
|
-
}, //
|
|
177
|
-
theme: {
|
|
178
|
-
value: "dark",
|
|
179
|
-
range: ["dark", "light", "system"]
|
|
180
|
-
} //
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
<ParametersReact
|
|
184
|
-
params={mySettings}
|
|
185
|
-
onChange={(newParams) => {
|
|
186
|
-
console.log("
|
|
187
|
-
}}
|
|
188
|
-
/>
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
###
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
**API:**
|
|
199
|
-
```typescript
|
|
200
|
-
// 1.
|
|
201
|
-
logsApi.addLogs({
|
|
202
|
-
id: "system",
|
|
203
|
-
var: 10, //
|
|
204
|
-
time: new Date(),
|
|
205
|
-
txt: "
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// 2.
|
|
209
|
-
<logsApi.React.Message zIndex={9999} /> //
|
|
210
|
-
<logsApi.React.PageLogs /> //
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{ textB: "
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
import {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
1
|
+
Here is an expanded API guide with typings and usage examples. This format is suitable for documentation so other developers or AI assistants can quickly understand which props a component accepts and how to integrate it.
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## API Reference (Components & Hooks)
|
|
6
|
+
|
|
7
|
+
### Modal and Floating Windows (MDI)
|
|
8
|
+
|
|
9
|
+
#### `DivRnd3`
|
|
10
|
+
Wrapper for creating freely movable, resizable windows with state persistence.
|
|
11
|
+
|
|
12
|
+
**Typing:**
|
|
13
|
+
```typescript
|
|
14
|
+
type tDivRndBase = {
|
|
15
|
+
children: React.ReactElement | ((update: number) => React.ReactElement);
|
|
16
|
+
position?: { x: number; y: number };
|
|
17
|
+
size?: { height: number | string; width: number | string };
|
|
18
|
+
keyForSave?: string; // Key for caching the position/size in memory
|
|
19
|
+
limit?: { x?: { max?: number; min?: number }, y?: { max?: number; min?: number } };
|
|
20
|
+
onCLickClose?: () => void; // Adds a close button to the window
|
|
21
|
+
header?: React.ReactElement | boolean; // Drag handle header; otherwise the whole block is draggable
|
|
22
|
+
zIndex?: number;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Example:**
|
|
27
|
+
```textmate
|
|
28
|
+
<DivRnd3
|
|
29
|
+
keyForSave="my_tool_window"
|
|
30
|
+
size={{ width: 300, height: 200 }}
|
|
31
|
+
onCLickClose={() => setOpen(false)}
|
|
32
|
+
header={<div>My tool</div>}
|
|
33
|
+
>
|
|
34
|
+
<div>Window content</div>
|
|
35
|
+
</DivRnd3>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#### `GetModalJSX()`
|
|
40
|
+
Factory for global modal windows. It lets business logic open windows without being tied to local component state.
|
|
41
|
+
|
|
42
|
+
**Example:**
|
|
43
|
+
```textmate
|
|
44
|
+
const myModal = GetModalJSX();
|
|
45
|
+
|
|
46
|
+
// 1. In the app root file (App.tsx):
|
|
47
|
+
<myModal.Render />
|
|
48
|
+
|
|
49
|
+
// 2. Anywhere in the logic:
|
|
50
|
+
myModal.set(<div onClick={() => myModal.set(null)}>Close me</div>);
|
|
51
|
+
// For multiple windows: myModal.addJSX(<Component/>)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Drag-and-Drop and Interaction (Hooks & Wrappers)
|
|
58
|
+
|
|
59
|
+
#### `useOutside` / `DivOutsideClick`
|
|
60
|
+
Tracks clicks outside an element, useful for closing dropdowns and menus.
|
|
61
|
+
|
|
62
|
+
**Typing:**
|
|
63
|
+
```typescript
|
|
64
|
+
// Hook
|
|
65
|
+
function useOutside(params: { outsideClick: () => void, status?: boolean, ref?: RefObject }): RefObject;
|
|
66
|
+
|
|
67
|
+
// Component
|
|
68
|
+
type Props = { outsideClick: () => void, status?: boolean, zIndex?: number } & HTMLAttributes;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Example:**
|
|
72
|
+
```textmate
|
|
73
|
+
<DivOutsideClick outsideClick={() => setDropdownOpen(false)} status={isOpen}>
|
|
74
|
+
<div className="dropdown-menu">...</div>
|
|
75
|
+
</DivOutsideClick>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#### `Drag22`
|
|
80
|
+
Tracks mouse/finger movement and returns new coordinates without touching CSS directly.
|
|
81
|
+
|
|
82
|
+
**Typing:**
|
|
83
|
+
```typescript
|
|
84
|
+
type Drag2Props = {
|
|
85
|
+
x?: number; y?: number; // Start/current coordinates
|
|
86
|
+
onX?: (val: number) => void; // X change callback
|
|
87
|
+
onY?: (val: number) => void; // Y change callback
|
|
88
|
+
onStart?: () => void; onStop?: () => void;
|
|
89
|
+
children: ReactNode;
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### Context Menus (`MenuR` / `mouseMenuApi`)
|
|
97
|
+
|
|
98
|
+
Smart context menus. They open on desktop via right click and on mobile via long tap / double tap. They support asynchronous item generation.
|
|
99
|
+
|
|
100
|
+
**Menu item typing (`tMenuReactStrictly`):**
|
|
101
|
+
```typescript
|
|
102
|
+
type tMenuReactStrictly = {
|
|
103
|
+
name: string | ((status?: any) => string);
|
|
104
|
+
onClick?: (e: any) => void | Promise<any> | Promise<any>[]; // Promise support with ok/error counters
|
|
105
|
+
status?: boolean; // Whether the submenu is expanded
|
|
106
|
+
next?: () => tMenuReact[] | Promise<tMenuReact[]>; // Nested menu
|
|
107
|
+
func?: () => React.ReactElement | Promise<React.ReactElement>; // Custom hover render
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Examples:**
|
|
112
|
+
```textmate
|
|
113
|
+
// 1. Using the wrapper component
|
|
114
|
+
const menuItems = () => [
|
|
115
|
+
{ name: "Copy", onClick: () => copy() },
|
|
116
|
+
{ name: "Options", next: () => [{ name: "Option 1", onClick: () => {} }] }
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
<MenuR other={menuItems}>
|
|
120
|
+
<div className="item">Right-click me</div>
|
|
121
|
+
</MenuR>
|
|
122
|
+
|
|
123
|
+
// 2. Global call through the API
|
|
124
|
+
mouseMenuApi.map.set("global_action", [{ name: "Global action", onClick: () => {} }]);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### Ag-Grid Table Updates (`applyTransactionAsyncUpdate2`)
|
|
131
|
+
|
|
132
|
+
Function for safe batched asynchronous table data updates synchronized with a local buffer/cache.
|
|
133
|
+
|
|
134
|
+
**Typing:**
|
|
135
|
+
```typescript
|
|
136
|
+
type Params<T> = {
|
|
137
|
+
gridRef?: React.RefObject<GridReadyEvent<T, any>>;
|
|
138
|
+
newData: Partial<T>[]; // New data array
|
|
139
|
+
getId: (row: Partial<T>) => string; // ID getter
|
|
140
|
+
bufTable: { [id: string]: Partial<T> }; // Local cache dictionary
|
|
141
|
+
option?: { update?: boolean, add?: boolean, updateBuffer?: boolean, sync?: boolean };
|
|
142
|
+
};
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Example:**
|
|
146
|
+
```textmate
|
|
147
|
+
// Immediately updates the cache and sends a transaction to Ag-Grid
|
|
148
|
+
applyTransactionAsyncUpdate2({
|
|
149
|
+
gridRef: apiGrid,
|
|
150
|
+
newData: [{ id: "user_1", balance: 500 }],
|
|
151
|
+
getId: (e) => e.id,
|
|
152
|
+
bufTable: myLocalBuffer,
|
|
153
|
+
option: { update: true, add: true }
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### UI Settings Autogeneration (`ParametersReact`)
|
|
161
|
+
|
|
162
|
+
Engine that accepts an object with a data schema and renders a ready-to-use control form with inputs, sliders, and selects.
|
|
163
|
+
|
|
164
|
+
**Typing:**
|
|
165
|
+
The schema is built from `Params.IParamsExpandableReadonly` types.
|
|
166
|
+
Supported types: `number`, `string`, `boolean`, `Date`, arrays, and nested objects.
|
|
167
|
+
|
|
168
|
+
**Example:**
|
|
169
|
+
```textmate
|
|
170
|
+
const mySettings = {
|
|
171
|
+
showGrid: true, // Generates a Checkbox
|
|
172
|
+
opacity: {
|
|
173
|
+
value: 0.5,
|
|
174
|
+
range: { min: 0, max: 1, step: 0.1 },
|
|
175
|
+
name: "Opacity"
|
|
176
|
+
}, // Generates a Range Slider + Number Input
|
|
177
|
+
theme: {
|
|
178
|
+
value: "dark",
|
|
179
|
+
range: ["dark", "light", "system"]
|
|
180
|
+
} // Generates a Select
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
<ParametersReact
|
|
184
|
+
params={mySettings}
|
|
185
|
+
onChange={(newParams) => {
|
|
186
|
+
console.log("New value:", newParams.opacity.value);
|
|
187
|
+
}}
|
|
188
|
+
/>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Logging System (`logsApi`)
|
|
195
|
+
|
|
196
|
+
Log registration, log viewer table, and toast notification system.
|
|
197
|
+
|
|
198
|
+
**API:**
|
|
199
|
+
```typescript
|
|
200
|
+
// 1. Adding a log
|
|
201
|
+
logsApi.addLogs({
|
|
202
|
+
id: "system",
|
|
203
|
+
var: 10, // Severity, important for notification filtering
|
|
204
|
+
time: new Date(),
|
|
205
|
+
txt: "Connection lost"
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// 2. Rendering components, usually somewhere near the root:
|
|
209
|
+
<logsApi.React.Message zIndex={9999} /> // Toast notifications in the top-right corner
|
|
210
|
+
<logsApi.React.PageLogs /> // Ag-Grid table with all logs
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
There are several other important architectural patterns and UI components actively used in the codebase. They should be documented so another developer or AI assistant can understand how interfaces are built in this project.
|
|
214
|
+
|
|
215
|
+
Here is the second part of the `README.md` additions:
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
### Sidebar Navigation
|
|
220
|
+
|
|
221
|
+
#### `ApiLeftMenu`
|
|
222
|
+
Ready-made API for controlling the left slide-out sidebar menu. It supports swipes, smooth snap scrolling, and imperative tab control.
|
|
223
|
+
|
|
224
|
+
**API and Typing:**
|
|
225
|
+
```typescript
|
|
226
|
+
type MenuItem = {
|
|
227
|
+
el: () => React.JSX.Element; // Tab component
|
|
228
|
+
button?: React.JSX.Element; // Custom button, optional
|
|
229
|
+
color?: ColorString; // Background color
|
|
230
|
+
textB?: string; // Default button text
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Register menu items:
|
|
234
|
+
ApiLeftMenu.setMenu(items: MenuItem[], key?: string);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Usage example:**
|
|
238
|
+
```textmate
|
|
239
|
+
// 1. Register tabs, can be done anywhere in the logic:
|
|
240
|
+
ApiLeftMenu.setMenu([
|
|
241
|
+
{ textB: "Dashboard", el: () => <Dashboard />, color: "rgb(92,50,213)" },
|
|
242
|
+
{ textB: "Settings", el: () => <Settings /> }
|
|
243
|
+
], "main_menu");
|
|
244
|
+
|
|
245
|
+
// 2. Render the menu itself in the root Layout:
|
|
246
|
+
export function AppLayout() {
|
|
247
|
+
return <ApiLeftMenu.Modal2 zIndex={20} />;
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### Interactive Elements and Buttons
|
|
255
|
+
|
|
256
|
+
#### `Button` (from `useOutside.tsx`) / `MiniButton`
|
|
257
|
+
Advanced button components that encapsulate dropdown logic, popover panels, and outside-click tracking for automatic closing.
|
|
258
|
+
|
|
259
|
+
**`Button` typing:**
|
|
260
|
+
```typescript
|
|
261
|
+
type tButton = {
|
|
262
|
+
button: ReactElement | ((status: boolean) => ReactElement); // The button itself; can change by status
|
|
263
|
+
children: ReactNode | ((api: {onClose: () => void}) => ReactNode); // Dropdown content
|
|
264
|
+
outClick?: boolean | (() => void); // Whether to close on outside click; true by default
|
|
265
|
+
statusDef?: boolean; // Initial state, open/closed
|
|
266
|
+
};
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Example:**
|
|
270
|
+
```textmate
|
|
271
|
+
<Button
|
|
272
|
+
outClick={true}
|
|
273
|
+
button={(isOpen) => <div className={isOpen ? "active" : ""}>Options</div>}
|
|
274
|
+
>
|
|
275
|
+
{({ onClose }) => (
|
|
276
|
+
<div className="dropdown-panel">
|
|
277
|
+
<div onClick={() => { doSomething(); onClose(); }}>Action 1</div>
|
|
278
|
+
</div>
|
|
279
|
+
)}
|
|
280
|
+
</Button>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
#### `FResizableReact`
|
|
285
|
+
Wrapper over `re-resizable`. It creates resizable panels, for example columns or lower log panes, and stores their size in cache.
|
|
286
|
+
|
|
287
|
+
**Example:**
|
|
288
|
+
```textmate
|
|
289
|
+
<FResizableReact
|
|
290
|
+
keyForSave="bottom_panel_size"
|
|
291
|
+
size={{ height: 200, width: "100%" }}
|
|
292
|
+
moveWith={false} // Allow resize only by height
|
|
293
|
+
>
|
|
294
|
+
<LogsTable />
|
|
295
|
+
</FResizableReact>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### Global Reactivity (`renderBy` / `updateBy` Pattern)
|
|
302
|
+
|
|
303
|
+
*(Note: this is a key project concept used instead of classic `useState` / `Redux` for complex business logic.)*
|
|
304
|
+
|
|
305
|
+
Many places in the project use a mutable state approach: you mutate properties of a plain JS object and call `renderBy(obj)` to force an update of all components subscribed to that object through `updateBy(obj)`.
|
|
306
|
+
|
|
307
|
+
**Pattern example:**
|
|
308
|
+
```textmate
|
|
309
|
+
import { renderBy, updateBy } from "./updateBy";
|
|
310
|
+
|
|
311
|
+
// 1. Global or local state, a plain object
|
|
312
|
+
const myState = {
|
|
313
|
+
count: 0,
|
|
314
|
+
text: "hello"
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// 2. Consumer component
|
|
318
|
+
function CounterViewer() {
|
|
319
|
+
// The component subscribes to myState changes
|
|
320
|
+
updateBy(myState);
|
|
321
|
+
|
|
322
|
+
return <div>{myState.count}</div>;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 3. State change, anywhere, even outside React
|
|
326
|
+
function increment() {
|
|
327
|
+
myState.count += 1;
|
|
328
|
+
renderBy(myState); // Triggers a CounterViewer rerender
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
### Useful Ag-Grid Utilities
|
|
336
|
+
|
|
337
|
+
#### `GridStyleDefault` and `StyleCSSHeadGrid`
|
|
338
|
+
Quickly apply the common corporate style to all application tables.
|
|
339
|
+
|
|
340
|
+
**Root integration example:**
|
|
341
|
+
```typescript
|
|
342
|
+
import { GridStyleDefault, StyleCSSHeadGrid } from "./styleGrid";
|
|
343
|
+
|
|
344
|
+
// Applies the dark theme, compresses spacing, and centers headers
|
|
345
|
+
GridStyleDefault();
|
|
346
|
+
StyleCSSHeadGrid();
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
#### `getComparatorGrid`
|
|
351
|
+
Factory for creating custom Ag-Grid column sort functions that correctly handle `undefined`, `NaN`, and inversion.
|
|
352
|
+
**Example:**
|
|
353
|
+
```textmate
|
|
354
|
+
const columnDefs = [
|
|
355
|
+
{
|
|
356
|
+
field: "price",
|
|
357
|
+
comparator: getComparatorGrid() // Safe numeric sorting
|
|
358
|
+
}
|
|
359
|
+
];
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### Global Hooks
|
|
366
|
+
|
|
367
|
+
#### `useAddDownAnyKey`
|
|
368
|
+
Registers a global keyboard listener and stores the last pressed key in the exported reactive object `KeyDown`.
|
|
369
|
+
|
|
370
|
+
**Usage example:**
|
|
371
|
+
```textmate
|
|
372
|
+
import { KeyDown, useAddDownAnyKey } from "./useAddDownAnyKey";
|
|
373
|
+
import { updateBy } from "./updateBy";
|
|
374
|
+
|
|
375
|
+
function HotkeyListener() {
|
|
376
|
+
useAddDownAnyKey(); // Hook initialization
|
|
377
|
+
updateBy(KeyDown); // Subscribe to key presses
|
|
378
|
+
|
|
379
|
+
if (KeyDown.key === "Escape") {
|
|
380
|
+
return <div>Escape pressed!</div>;
|
|
381
|
+
}
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
383
384
|
```
|