cogsbox-state 0.5.468 → 0.5.470
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 +62 -311
- package/dist/CogsState.d.ts +63 -69
- package/dist/CogsState.d.ts.map +1 -1
- package/dist/CogsState.jsx +945 -995
- package/dist/CogsState.jsx.map +1 -1
- package/dist/Components.d.ts +10 -0
- package/dist/Components.d.ts.map +1 -1
- package/dist/Components.jsx +141 -119
- package/dist/Components.jsx.map +1 -1
- package/dist/index.js +5 -4
- package/dist/store.d.ts +3 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +23 -18
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +149 -209
- package/src/Components.tsx +55 -4
- package/src/store.ts +11 -6
package/src/Components.tsx
CHANGED
|
@@ -8,7 +8,12 @@ import React, {
|
|
|
8
8
|
useRef,
|
|
9
9
|
useState,
|
|
10
10
|
} from 'react';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
formRefStore,
|
|
13
|
+
getGlobalStore,
|
|
14
|
+
ValidationError,
|
|
15
|
+
ValidationSeverity,
|
|
16
|
+
} from './store';
|
|
12
17
|
import { useInView } from 'react-intersection-observer';
|
|
13
18
|
import { v4 as uuidv4 } from 'uuid';
|
|
14
19
|
import { isDeepEqual } from './utility';
|
|
@@ -60,7 +65,12 @@ export function ValidationWrapper({
|
|
|
60
65
|
|
|
61
66
|
// Use first error, or first warning if no errors
|
|
62
67
|
const message = errorMessages[0] || warningMessages[0];
|
|
63
|
-
|
|
68
|
+
const primarySeverity: ValidationSeverity =
|
|
69
|
+
errorMessages.length > 0
|
|
70
|
+
? 'error'
|
|
71
|
+
: warningMessages.length > 0
|
|
72
|
+
? 'warning'
|
|
73
|
+
: undefined;
|
|
64
74
|
return (
|
|
65
75
|
<>
|
|
66
76
|
{thisStateOpts?.formElements?.validation &&
|
|
@@ -73,7 +83,7 @@ export function ValidationWrapper({
|
|
|
73
83
|
message: formOpts?.validation?.hideMessage
|
|
74
84
|
? ''
|
|
75
85
|
: formOpts?.validation?.message || message || '',
|
|
76
|
-
|
|
86
|
+
severity: primarySeverity,
|
|
77
87
|
hasErrors: errorMessages.length > 0,
|
|
78
88
|
hasWarnings: warningMessages.length > 0,
|
|
79
89
|
allErrors: errors,
|
|
@@ -450,7 +460,7 @@ export function FormElementWrapper({
|
|
|
450
460
|
|
|
451
461
|
const stateWithInputProps = new Proxy(baseState, {
|
|
452
462
|
get(target, prop) {
|
|
453
|
-
if (prop === 'inputProps') {
|
|
463
|
+
if (prop === '$inputProps') {
|
|
454
464
|
return {
|
|
455
465
|
value: localValue ?? '',
|
|
456
466
|
onChange: (e: any) => {
|
|
@@ -540,3 +550,44 @@ const useImageLoaded = (ref: RefObject<HTMLElement>): boolean => {
|
|
|
540
550
|
|
|
541
551
|
return loaded;
|
|
542
552
|
};
|
|
553
|
+
// Components.tsx
|
|
554
|
+
|
|
555
|
+
// Generic isolated component wrapper
|
|
556
|
+
export function IsolatedComponentWrapper({
|
|
557
|
+
stateKey,
|
|
558
|
+
path,
|
|
559
|
+
rebuildStateShape,
|
|
560
|
+
renderFn,
|
|
561
|
+
}: {
|
|
562
|
+
stateKey: string;
|
|
563
|
+
path: string[];
|
|
564
|
+
rebuildStateShape: (options: {
|
|
565
|
+
path: string[];
|
|
566
|
+
componentId: string;
|
|
567
|
+
meta?: any;
|
|
568
|
+
}) => any;
|
|
569
|
+
renderFn: (state: any) => React.ReactNode;
|
|
570
|
+
}) {
|
|
571
|
+
const [componentId] = useState(() => uuidv4());
|
|
572
|
+
const [, forceUpdate] = useState({});
|
|
573
|
+
|
|
574
|
+
const stateKeyPathKey = [stateKey, ...path].join('.');
|
|
575
|
+
useRegisterComponent(stateKey, componentId, forceUpdate);
|
|
576
|
+
|
|
577
|
+
useEffect(() => {
|
|
578
|
+
const unsubscribe = getGlobalStore
|
|
579
|
+
.getState()
|
|
580
|
+
.subscribeToPath(stateKeyPathKey, () => {
|
|
581
|
+
forceUpdate({});
|
|
582
|
+
});
|
|
583
|
+
return () => unsubscribe();
|
|
584
|
+
}, [stateKeyPathKey]);
|
|
585
|
+
|
|
586
|
+
const baseState = rebuildStateShape({
|
|
587
|
+
path: path,
|
|
588
|
+
componentId: componentId,
|
|
589
|
+
meta: undefined,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
return <>{renderFn(baseState)}</>;
|
|
593
|
+
}
|
package/src/store.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { create } from 'zustand';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import type {
|
|
4
4
|
OptionsType,
|
|
5
5
|
ReactivityType,
|
|
@@ -85,11 +85,11 @@ export type ValidationStatus =
|
|
|
85
85
|
| 'VALIDATING'
|
|
86
86
|
| 'VALID'
|
|
87
87
|
| 'INVALID';
|
|
88
|
-
|
|
88
|
+
export type ValidationSeverity = 'warning' | 'error' | undefined;
|
|
89
89
|
export type ValidationError = {
|
|
90
90
|
source: 'client' | 'sync_engine' | 'api';
|
|
91
91
|
message: string;
|
|
92
|
-
severity:
|
|
92
|
+
severity: ValidationSeverity;
|
|
93
93
|
code?: string;
|
|
94
94
|
};
|
|
95
95
|
|
|
@@ -266,7 +266,7 @@ export function buildShadowNode(value: any): ShadowNode {
|
|
|
266
266
|
const idKeys: string[] = [];
|
|
267
267
|
|
|
268
268
|
value.forEach((item) => {
|
|
269
|
-
const itemId = `id:${
|
|
269
|
+
const itemId = `id:${generateId()}`;
|
|
270
270
|
arrayNode[itemId] = buildShadowNode(item);
|
|
271
271
|
idKeys.push(itemId);
|
|
272
272
|
});
|
|
@@ -292,6 +292,11 @@ export function buildShadowNode(value: any): ShadowNode {
|
|
|
292
292
|
|
|
293
293
|
// Module-level mutable store
|
|
294
294
|
const shadowStateStore = new Map<string, ShadowNode>();
|
|
295
|
+
let globalCounter = 0;
|
|
296
|
+
|
|
297
|
+
export function generateId(prefix = 'id'): string {
|
|
298
|
+
return `${prefix}:${(globalCounter++).toString(36)}`;
|
|
299
|
+
}
|
|
295
300
|
|
|
296
301
|
export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
|
|
297
302
|
// Remove shadowStateStore from Zustand state
|
|
@@ -550,7 +555,7 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
|
|
|
550
555
|
return;
|
|
551
556
|
}
|
|
552
557
|
|
|
553
|
-
const newItemId = `id:${
|
|
558
|
+
const newItemId = `id:${generateId()}`;
|
|
554
559
|
const itemsToAdd = { [newItemId]: buildShadowNode(newItem) };
|
|
555
560
|
|
|
556
561
|
// Mutate the array directly
|
|
@@ -595,7 +600,7 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
|
|
|
595
600
|
const newIds: string[] = [];
|
|
596
601
|
|
|
597
602
|
newItems.forEach((item) => {
|
|
598
|
-
const newItemId = `id:${
|
|
603
|
+
const newItemId = `id:${generateId()}`;
|
|
599
604
|
newIds.push(newItemId);
|
|
600
605
|
itemsToAdd[newItemId] = buildShadowNode(item);
|
|
601
606
|
});
|