@developer_tribe/react-builder 1.2.44-test.1 → 1.2.44-test.2

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.
Files changed (47) hide show
  1. package/dist/attributes-editor/Field.d.ts +3 -1
  2. package/dist/attributes-editor/attributesEditorModelTypes.d.ts +3 -0
  3. package/dist/attributes-editor/useAttributesEditorModel.d.ts +1 -1
  4. package/dist/build-components/FormSubmitButton/FormSubmitButtonProps.generated.d.ts +8 -3
  5. package/dist/build-components/GlobalProvider/globalProviderUtils.d.ts +4 -13
  6. package/dist/build-components/GlobalProvider/useGlobalProviderLogic.d.ts +15 -0
  7. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +8 -3
  8. package/dist/build-components/SystemButton/SystemButtonProps.generated.d.ts +8 -3
  9. package/dist/build-components/SystemButton/usePlacementButtonEvents.d.ts +9 -2
  10. package/dist/build-components/patterns.generated.d.ts +15 -9
  11. package/dist/index.cjs.js +1 -1
  12. package/dist/index.cjs.js.map +1 -1
  13. package/dist/index.esm.js +1 -1
  14. package/dist/index.esm.js.map +1 -1
  15. package/dist/index.web.cjs.js +3 -3
  16. package/dist/index.web.cjs.js.map +1 -1
  17. package/dist/index.web.esm.js +3 -3
  18. package/dist/index.web.esm.js.map +1 -1
  19. package/dist/utils/nodeTree.d.ts +18 -0
  20. package/package.json +1 -1
  21. package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +68 -4
  22. package/src/assets/meta.json +1 -1
  23. package/src/assets/samples/global-onboard-flow.json +7 -1
  24. package/src/assets/samples/terms-and-privacy-no-form.json +1 -1
  25. package/src/assets/samples/terms-and-privacy.json +1 -1
  26. package/src/attributes-editor/AttributesEditorView.tsx +3 -0
  27. package/src/attributes-editor/Field.tsx +91 -2
  28. package/src/attributes-editor/attributesEditorModelTypes.ts +3 -0
  29. package/src/attributes-editor/useAttributesEditorModel.ts +8 -0
  30. package/src/build-components/FormCheckbox/FormCheckbox.tsx +3 -1
  31. package/src/build-components/FormSubmitButton/FormSubmitButton.tsx +3 -0
  32. package/src/build-components/FormSubmitButton/FormSubmitButtonProps.generated.ts +26 -3
  33. package/src/build-components/GlobalProvider/GlobalProvider.tsx +4 -144
  34. package/src/build-components/GlobalProvider/globalProviderUtils.ts +79 -38
  35. package/src/build-components/GlobalProvider/useGlobalNavigation.ts +0 -5
  36. package/src/build-components/GlobalProvider/useGlobalProviderLogic.ts +172 -0
  37. package/src/build-components/OnboardButton/OnboardButton.tsx +3 -0
  38. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +26 -3
  39. package/src/build-components/OnboardButton/pattern.json +5 -3
  40. package/src/build-components/SystemButton/SystemButton.tsx +3 -0
  41. package/src/build-components/SystemButton/SystemButtonProps.generated.ts +26 -3
  42. package/src/build-components/SystemButton/pattern.json +5 -3
  43. package/src/build-components/SystemButton/usePlacementButtonEvents.ts +22 -9
  44. package/src/build-components/patterns.generated.ts +45 -9
  45. package/src/components/AttributesEditorPanel.tsx +1 -0
  46. package/src/patterns/event-constants.json +19 -0
  47. package/src/utils/nodeTree.ts +115 -0
@@ -33,11 +33,13 @@
33
33
  },
34
34
  "types": {
35
35
  "EventObject": {
36
- "type": ["Permission", "Navigate", "Placement"],
37
- "permission": "string",
36
+ "type": "$ref:event-constants.eventTypes",
37
+ "permission": "$ref:event-constants.permissionTypes",
38
38
  "navigate_to": "string",
39
39
  "targetIndex": "number",
40
- "placementKey": "string"
40
+ "placementKey": "$ref:event-constants.placementKeys",
41
+ "conditionKey": "$ref:event-constants.conditionKeys",
42
+ "value": "boolean"
41
43
  }
42
44
  },
43
45
  "meta": {
@@ -2,13 +2,15 @@ import { useRef, useCallback } from 'react';
2
2
  import type { MockOSContextValue } from '../../mockOS/context/MockOSContextBase';
3
3
  import type { PermissionStatus } from '../../mockOS/managers/mockPermissionManager';
4
4
 
5
- /** Event shape shared by SystemButton and OnboardButton. Placement = go to placementKey (onboard/terms/paywall); Navigate = navigate_to or carousel. */
5
+ /** Event shape shared by SystemButton and OnboardButton. Placement = go to placementKey (onboard/terms/paywall); Navigate = navigate_to or carousel; SetCondition = update a global boolean condition. */
6
6
  export interface PlacementEventObject {
7
- type?: 'Permission' | 'Navigate' | 'Placement';
7
+ type?: 'Permission' | 'Navigate' | 'Placement' | 'SetCondition';
8
8
  permission?: string | null;
9
9
  placementKey?: string;
10
10
  navigate_to?: string;
11
11
  targetIndex?: number;
12
+ conditionKey?: string;
13
+ value?: boolean;
12
14
  }
13
15
 
14
16
  export interface UsePlacementButtonEventsOptions {
@@ -24,6 +26,11 @@ export interface UsePlacementButtonEventsOptions {
24
26
  * to MockOSContext. Return true if the navigation was handled.
25
27
  */
26
28
  globalNavigate?: (target: string) => boolean;
29
+ /**
30
+ * Optional callback to set a global boolean condition (from GlobalContext).
31
+ * Used by SetCondition events.
32
+ */
33
+ setCondition?: (key: string, value: boolean) => void;
27
34
  }
28
35
 
29
36
  /**
@@ -40,6 +47,7 @@ export function usePlacementButtonEvents(
40
47
  requestPermission,
41
48
  onNavigateWithoutPlacement,
42
49
  globalNavigate,
50
+ setCondition,
43
51
  } = options;
44
52
  const handledEventsRef = useRef<PlacementEventObject[]>([]);
45
53
 
@@ -47,10 +55,13 @@ export function usePlacementButtonEvents(
47
55
  * Attempts to navigate to a target. Tries globalNavigate first (GlobalProvider),
48
56
  * then falls back to MockOSContext.
49
57
  */
50
- function navigateTo(target: string): void {
51
- if (globalNavigate?.(target)) return;
52
- context?.navigation(target as Parameters<typeof context.navigation>[0]);
53
- }
58
+ const navigateTo = useCallback(
59
+ (target: string): void => {
60
+ if (globalNavigate?.(target)) return;
61
+ context?.navigation(target as Parameters<typeof context.navigation>[0]);
62
+ },
63
+ [context, globalNavigate],
64
+ );
54
65
 
55
66
  const handleClick = useCallback(async () => {
56
67
  const list = events ?? [];
@@ -64,6 +75,9 @@ export function usePlacementButtonEvents(
64
75
  const permission = e.permission ?? 'camera';
65
76
  await requestPermission(permission);
66
77
  handledEventsRef.current.push(e);
78
+ } else if (e.type === 'SetCondition' && e.conditionKey) {
79
+ setCondition?.(e.conditionKey, e.value ?? false);
80
+ handledEventsRef.current.push(e);
67
81
  } else if (e.type === 'Placement' && e.placementKey) {
68
82
  const target =
69
83
  e.placementKey === 'paywall' ? 'paywall' : e.placementKey;
@@ -88,13 +102,12 @@ export function usePlacementButtonEvents(
88
102
  }
89
103
  }
90
104
  }
91
- // eslint-disable-next-line react-hooks/exhaustive-deps
92
105
  }, [
93
106
  events,
94
- context,
95
107
  requestPermission,
108
+ setCondition,
109
+ navigateTo,
96
110
  onNavigateWithoutPlacement,
97
- globalNavigate,
98
111
  ]);
99
112
 
100
113
  return handleClick;
@@ -5621,11 +5621,23 @@ export const patterns = [
5621
5621
  },
5622
5622
  types: {
5623
5623
  EventObject: {
5624
- type: ['Permission', 'Navigate', 'Placement'],
5625
- permission: 'string',
5624
+ type: ['Permission', 'Navigate', 'Placement', 'SetCondition'],
5625
+ permission: [
5626
+ 'notification',
5627
+ 'camera',
5628
+ 'microphone',
5629
+ 'location',
5630
+ 'photos',
5631
+ 'contacts',
5632
+ 'att',
5633
+ 'rating',
5634
+ 'GDPR',
5635
+ ],
5626
5636
  navigate_to: 'string',
5627
5637
  targetIndex: 'number',
5628
- placementKey: 'string',
5638
+ placementKey: ['terms', 'onboard', 'paywall', 'subscription', 'home'],
5639
+ conditionKey: ['termsAccepted'],
5640
+ value: 'boolean',
5629
5641
  },
5630
5642
  },
5631
5643
  meta: {
@@ -7748,11 +7760,23 @@ export const patterns = [
7748
7760
  },
7749
7761
  types: {
7750
7762
  EventObject: {
7751
- type: ['Permission', 'Navigate', 'Placement'],
7752
- permission: 'string',
7763
+ type: ['Permission', 'Navigate', 'Placement', 'SetCondition'],
7764
+ permission: [
7765
+ 'notification',
7766
+ 'camera',
7767
+ 'microphone',
7768
+ 'location',
7769
+ 'photos',
7770
+ 'contacts',
7771
+ 'att',
7772
+ 'rating',
7773
+ 'GDPR',
7774
+ ],
7753
7775
  navigate_to: 'string',
7754
7776
  targetIndex: 'number',
7755
- placementKey: 'string',
7777
+ placementKey: ['terms', 'onboard', 'paywall', 'subscription', 'home'],
7778
+ conditionKey: ['termsAccepted'],
7779
+ value: 'boolean',
7756
7780
  },
7757
7781
  },
7758
7782
  meta: {
@@ -16593,11 +16617,23 @@ export const patterns = [
16593
16617
  },
16594
16618
  types: {
16595
16619
  EventObject: {
16596
- type: ['Permission', 'Navigate', 'Placement'],
16597
- permission: 'string',
16620
+ type: ['Permission', 'Navigate', 'Placement', 'SetCondition'],
16621
+ permission: [
16622
+ 'notification',
16623
+ 'camera',
16624
+ 'microphone',
16625
+ 'location',
16626
+ 'photos',
16627
+ 'contacts',
16628
+ 'att',
16629
+ 'rating',
16630
+ 'GDPR',
16631
+ ],
16598
16632
  navigate_to: 'string',
16599
16633
  targetIndex: 'number',
16600
- placementKey: 'string',
16634
+ placementKey: ['terms', 'onboard', 'paywall', 'subscription', 'home'],
16635
+ conditionKey: ['termsAccepted'],
16636
+ value: 'boolean',
16601
16637
  },
16602
16638
  },
16603
16639
  },
@@ -88,6 +88,7 @@ export function AttributesEditorPanel({
88
88
  node={nodeForEditor}
89
89
  onChange={handleAttributesChange}
90
90
  projectColors={projectColors}
91
+ projectRoot={attributes}
91
92
  />
92
93
  </div>
93
94
  );
@@ -0,0 +1,19 @@
1
+ {
2
+ "$comment": "Central event constants. Referenced via $ref in pattern.json types blocks. Run 'yarn prebuild' after changes.",
3
+ "eventTypes": ["Permission", "Navigate", "Placement", "SetCondition"],
4
+ "placementKeys": ["terms", "onboard", "paywall", "subscription", "home"],
5
+ "conditionKeys": ["termsAccepted"],
6
+ "permissionTypes": [
7
+ "notification",
8
+ "camera",
9
+ "microphone",
10
+ "location",
11
+ "photos",
12
+ "contacts",
13
+ "att",
14
+ "rating",
15
+ "GDPR"
16
+ ],
17
+ "validationTypes": ["required", "email", "url", "min", "max"],
18
+ "formFieldNames": ["email", "firstName", "lastName", "phone", "birthday"]
19
+ }
@@ -1,4 +1,5 @@
1
1
  import type { Node, NodeData } from '../types/Node';
2
+ import eventConstants from '../patterns/event-constants.json';
2
3
 
3
4
  export function deleteNodeFromTree(root: Node, target: Node): Node {
4
5
  if (root === null || root === undefined) return root;
@@ -97,3 +98,117 @@ export function findNodeByKey(root: Node, key?: string): Node | null {
97
98
 
98
99
  return null;
99
100
  }
101
+
102
+ export type ProjectOptions = {
103
+ pageKeys: string[];
104
+ conditionKeys: string[];
105
+ placementKeys: string[];
106
+ formFieldNames: string[];
107
+ eventTypes: string[];
108
+ validationTypes: string[];
109
+ };
110
+
111
+ /**
112
+ * Traverses the entire node tree to dynamically discover project-level metadata
113
+ * (page keys, condition keys, form field names, etc.) and merges them with
114
+ * central constants from event-constants.json.
115
+ *
116
+ * This enables the Attributes Editor to provide a complete list of valid options
117
+ * for dropdown fields, combining predefined standards with actually used keys
118
+ * in the current design.
119
+ */
120
+ export function collectProjectMetadata(root: Node): ProjectOptions {
121
+ const pageKeys = new Set<string>();
122
+ const conditionKeys = new Set<string>();
123
+ const placementKeys = new Set<string>();
124
+ const formFieldNames = new Set<string>();
125
+ const eventTypes = new Set<string>();
126
+
127
+ function traverse(node: Node) {
128
+ if (!node || typeof node === 'string') return;
129
+
130
+ if (Array.isArray(node)) {
131
+ node.forEach(traverse);
132
+ return;
133
+ }
134
+
135
+ const data = node as NodeData;
136
+ const type = data.type;
137
+ const attrs = (data.attributes ?? {}) as Record<string, any>;
138
+
139
+ // Collect Page Keys
140
+ if (type === 'GlobalProvider' && Array.isArray(data.children)) {
141
+ data.children.forEach((child) => {
142
+ if (typeof child === 'object' && child !== null && 'key' in child) {
143
+ if (typeof child.key === 'string') pageKeys.add(child.key);
144
+ }
145
+ });
146
+ }
147
+ if (attrs.pageKey && typeof attrs.pageKey === 'string') {
148
+ pageKeys.add(attrs.pageKey);
149
+ }
150
+
151
+ // Collect Condition Keys
152
+ if (attrs.conditionKey && typeof attrs.conditionKey === 'string') {
153
+ conditionKeys.add(attrs.conditionKey);
154
+ }
155
+ if (Array.isArray(attrs.skipConditions)) {
156
+ attrs.skipConditions.forEach((entry: any) => {
157
+ if (entry?.conditionKey) conditionKeys.add(entry.conditionKey);
158
+ });
159
+ }
160
+
161
+ // Collect Placement Keys
162
+ if (attrs.placementKey && typeof attrs.placementKey === 'string') {
163
+ placementKeys.add(attrs.placementKey);
164
+ }
165
+
166
+ // Collect Form Field Names
167
+ if (type.startsWith('Form') && type !== 'FormProvider' && attrs.name) {
168
+ if (typeof attrs.name === 'string') formFieldNames.add(attrs.name);
169
+ }
170
+
171
+ // Collect from events
172
+ if (Array.isArray(attrs.events)) {
173
+ attrs.events.forEach((evt: any) => {
174
+ if (evt.type && typeof evt.type === 'string') eventTypes.add(evt.type);
175
+ if (evt.navigate_to) pageKeys.add(evt.navigate_to);
176
+ if (evt.placementKey) placementKeys.add(evt.placementKey);
177
+ if (evt.conditionKey) conditionKeys.add(evt.conditionKey);
178
+ });
179
+ }
180
+
181
+ if (data.children) {
182
+ traverse(data.children as Node);
183
+ }
184
+ }
185
+
186
+ traverse(root);
187
+
188
+ // Merge with central constants for a complete set of options
189
+ const result: ProjectOptions = {
190
+ pageKeys: Array.from(
191
+ new Set([...pageKeys, ...eventConstants.placementKeys]),
192
+ ).sort(),
193
+ conditionKeys: Array.from(
194
+ new Set([...conditionKeys, ...eventConstants.conditionKeys]),
195
+ ).sort(),
196
+ placementKeys: Array.from(
197
+ new Set([...placementKeys, ...eventConstants.placementKeys]),
198
+ ).sort(),
199
+ formFieldNames: Array.from(
200
+ new Set([
201
+ ...formFieldNames,
202
+ ...((eventConstants as any).formFieldNames as string[]),
203
+ ]),
204
+ ).sort(),
205
+ eventTypes: Array.from(
206
+ new Set([...eventTypes, ...eventConstants.eventTypes]),
207
+ ).sort(),
208
+ validationTypes: Array.from(
209
+ new Set((eventConstants as any).validationTypes as string[]),
210
+ ).sort(),
211
+ };
212
+
213
+ return result;
214
+ }