@developer_tribe/react-builder 1.0.2 → 1.0.3

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 (124) hide show
  1. package/dist/AttributesEditor.d.ts +3 -1
  2. package/dist/RenderPage.d.ts +2 -1
  3. package/dist/attributes-editor/Field.d.ts +2 -1
  4. package/dist/attributes-editor/SpecialCategorySection.d.ts +2 -1
  5. package/dist/build-components/BackgroundImage/BackgroundImage.d.ts +5 -0
  6. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +44 -0
  7. package/dist/build-components/Button/ButtonProps.generated.d.ts +7 -0
  8. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +7 -0
  9. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +7 -0
  10. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +7 -0
  11. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +7 -0
  12. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +7 -0
  13. package/dist/build-components/Image/ImageProps.generated.d.ts +7 -0
  14. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +7 -0
  15. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +7 -0
  16. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +7 -0
  17. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +7 -0
  18. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +7 -0
  19. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +7 -0
  20. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +7 -0
  21. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +7 -1
  22. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +7 -0
  23. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +7 -0
  24. package/dist/build-components/Text/TextProps.generated.d.ts +7 -0
  25. package/dist/build-components/View/ViewProps.generated.d.ts +7 -0
  26. package/dist/build-components/index.d.ts +2 -1
  27. package/dist/build-components/patterns.generated.d.ts +1444 -15
  28. package/dist/components/AttributesEditorPanel.d.ts +3 -4
  29. package/dist/components/Builder.d.ts +2 -1
  30. package/dist/components/BuilderButton.d.ts +9 -0
  31. package/dist/index.cjs.js +5 -5
  32. package/dist/index.cjs.js.map +1 -1
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.esm.js +5 -5
  35. package/dist/index.esm.js.map +1 -1
  36. package/dist/modals/ColorModal.d.ts +3 -1
  37. package/dist/pages/ProjectPage.d.ts +3 -3
  38. package/dist/pages/tabs/BuilderPanel.d.ts +8 -0
  39. package/dist/pages/tabs/{DebugTab.d.ts → SideTool.d.ts} +2 -2
  40. package/dist/store.d.ts +7 -1
  41. package/dist/styles.css +1 -1
  42. package/dist/types/Project.d.ts +11 -0
  43. package/dist/utils/analyseNode.d.ts +1 -0
  44. package/dist/utils/extractTextStyle.d.ts +8 -1
  45. package/dist/utils/extractViewStyle.d.ts +8 -1
  46. package/dist/utils/parseColor.d.ts +7 -0
  47. package/package.json +1 -1
  48. package/src/AttributesEditor.tsx +76 -14
  49. package/src/RenderPage.tsx +82 -4
  50. package/src/attributes-editor/Field.tsx +12 -5
  51. package/src/attributes-editor/SpecialCategorySection.tsx +2 -1
  52. package/src/build-components/BackgroundImage/BackgroundImage.tsx +87 -0
  53. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +60 -0
  54. package/src/build-components/BackgroundImage/pattern.json +45 -0
  55. package/src/build-components/Button/Button.tsx +31 -4
  56. package/src/build-components/Button/ButtonProps.generated.ts +7 -0
  57. package/src/build-components/Carousel/Carousel.tsx +27 -3
  58. package/src/build-components/Carousel/CarouselProps.generated.ts +7 -0
  59. package/src/build-components/CarouselButtons/CarouselButtons.tsx +19 -4
  60. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +7 -0
  61. package/src/build-components/CarouselDots/CarouselDots.tsx +13 -4
  62. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +7 -0
  63. package/src/build-components/CarouselItem/CarouselItem.tsx +20 -4
  64. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +7 -0
  65. package/src/build-components/CarouselProvider/CarouselProvider.tsx +14 -3
  66. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +7 -0
  67. package/src/build-components/Image/Image.tsx +29 -4
  68. package/src/build-components/Image/ImageProps.generated.ts +7 -0
  69. package/src/build-components/Onboard/Onboard.tsx +2 -2
  70. package/src/build-components/Onboard/OnboardProps.generated.ts +7 -0
  71. package/src/build-components/OnboardButton/OnboardButton.tsx +11 -4
  72. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +7 -0
  73. package/src/build-components/OnboardButtons/OnboardButtons.tsx +17 -5
  74. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +7 -0
  75. package/src/build-components/OnboardDot/OnboardDot.tsx +15 -6
  76. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +7 -0
  77. package/src/build-components/OnboardDot/pattern.json +1 -1
  78. package/src/build-components/OnboardFooter/OnboardFooter.tsx +15 -5
  79. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +7 -0
  80. package/src/build-components/OnboardImage/OnboardImage.tsx +28 -6
  81. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +7 -0
  82. package/src/build-components/OnboardItem/OnboardItem.tsx +14 -3
  83. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +7 -0
  84. package/src/build-components/OnboardProvider/OnboardProvider.tsx +34 -12
  85. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +7 -1
  86. package/src/build-components/OnboardProvider/pattern.json +0 -8
  87. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +7 -0
  88. package/src/build-components/OnboardSubtitle/pattern.json +1 -1
  89. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +7 -0
  90. package/src/build-components/OnboardTitle/pattern.json +1 -1
  91. package/src/build-components/RenderNode.generated.tsx +3 -0
  92. package/src/build-components/Text/Text.tsx +33 -9
  93. package/src/build-components/Text/TextProps.generated.ts +7 -0
  94. package/src/build-components/View/View.tsx +27 -3
  95. package/src/build-components/View/ViewProps.generated.ts +7 -0
  96. package/src/build-components/View/pattern.json +59 -1
  97. package/src/build-components/index.ts +5 -0
  98. package/src/build-components/patterns.generated.ts +1452 -15
  99. package/src/components/AttributesEditorPanel.tsx +13 -6
  100. package/src/components/Builder.tsx +140 -40
  101. package/src/components/BuilderButton.tsx +127 -0
  102. package/src/index.ts +2 -2
  103. package/src/mockOS/components/MockOSRouter.tsx +11 -3
  104. package/src/modals/ColorModal.tsx +212 -55
  105. package/src/pages/ProjectPage.tsx +293 -55
  106. package/src/pages/tabs/{BuilderTab.tsx → BuilderPanel.tsx} +13 -9
  107. package/src/pages/tabs/SideTool.tsx +259 -0
  108. package/src/size-matters/index.ts +6 -0
  109. package/src/store.ts +13 -1
  110. package/src/styles/base/_global.scss +158 -7
  111. package/src/styles/components/_attributes-editor.scss +12 -0
  112. package/src/styles/components/_editor-shell.scss +23 -0
  113. package/src/styles/foundation/_sizes.scss +1 -1
  114. package/src/styles/layout/_builder.scss +66 -10
  115. package/src/styles/modals/_color-modal.scss +29 -0
  116. package/src/types/Project.ts +14 -0
  117. package/src/utils/analyseNode.ts +98 -0
  118. package/src/utils/extractTextStyle.ts +24 -8
  119. package/src/utils/extractViewStyle.ts +27 -3
  120. package/src/utils/parseColor.ts +43 -0
  121. package/dist/pages/tabs/BuilderTab.d.ts +0 -9
  122. package/dist/pages/tabs/PreviewTab.d.ts +0 -3
  123. package/src/pages/tabs/DebugTab.tsx +0 -64
  124. package/src/pages/tabs/PreviewTab.tsx +0 -206
@@ -1,20 +1,23 @@
1
- import { AttributesEditor, Node, NodeData } from '..';
1
+ import { AttributesEditor, Node, NodeData, ProjectColors } from '..';
2
2
  import { useLogRender } from '../utils/useLogRender';
3
+ import { useRenderStore } from '../store';
3
4
 
4
5
  interface AttributesEditorPanelProps {
5
- current: Node;
6
6
  attributes: any;
7
7
  onChange: (data: Node) => void;
8
- setCurrent: (current: Node) => void;
8
+ projectColors?: ProjectColors;
9
9
  }
10
10
 
11
11
  export function AttributesEditorPanel({
12
- current,
13
12
  attributes,
14
13
  onChange,
15
- setCurrent,
14
+ projectColors,
16
15
  }: AttributesEditorPanelProps) {
17
16
  useLogRender('AttributesEditorPanel');
17
+ const { current, setCurrent } = useRenderStore((s) => ({
18
+ current: s.current,
19
+ setCurrent: s.setCurrent,
20
+ }));
18
21
  if (!current) return null;
19
22
 
20
23
  function replaceNode(root: Node, target: Node, next: Node): Node {
@@ -52,7 +55,11 @@ export function AttributesEditorPanel({
52
55
 
53
56
  return (
54
57
  <div style={{ padding: 12 }}>
55
- <AttributesEditor node={current} onChange={handleAttributesChange} />
58
+ <AttributesEditor
59
+ node={current}
60
+ onChange={handleAttributesChange}
61
+ projectColors={projectColors}
62
+ />
56
63
  </div>
57
64
  );
58
65
  }
@@ -12,52 +12,34 @@ import { Breadcrumb } from './Breadcrumb';
12
12
  import { useLogRender } from '../utils/useLogRender';
13
13
  import { getDefaultsForType, getPatternByType } from '../utils/patterns';
14
14
  import { AddComponentModal } from '../modals/AddComponentModal';
15
+ import { BuilderButton } from './BuilderButton';
15
16
 
16
17
  type BuilderEditorProps = {
17
18
  data: Node;
18
19
  setData: (data: Node) => void;
19
20
  current: Node;
20
21
  setCurrent: (current: Node) => void;
22
+ onDeleteNode: (node: Node) => void;
21
23
  };
22
24
 
23
25
  interface BuilderEditorComponentProps {
24
26
  node: Node;
25
27
  onClick: (node: Node) => void;
26
28
  onAdd?: () => void;
27
- }
28
-
29
- function BuilderButton({ node, onClick }: { node: Node; onClick: () => void }) {
30
- if (isNodeNullOrUndefined(node)) {
31
- return <div className="builder__placeholder">Null or undefined</div>;
32
- }
33
- if (isNodeString(node)) {
34
- return <div className="builder__text">{node as string}</div>;
35
- }
36
- const nodeData = node as NodeData<NodeDefaultAttribute>;
37
-
38
- let extra = '';
39
- if (nodeData.attributes?.condition) {
40
- extra = ` (${nodeData.attributes.condition} ${nodeData.attributes.conditionVariable})`;
41
- }
42
- const patternLabel = getPatternByType(nodeData.type)?.meta?.label?.trim();
43
- const baseLabel =
44
- patternLabel && patternLabel.length > 0 ? patternLabel : nodeData.type;
45
- const conditionLabel = extra.trim() ? extra : '';
46
- const fullLabel = `${baseLabel}${conditionLabel}`.trim();
47
- return (
48
- <a onClick={onClick} className="builder__button">
49
- <span className="builder__button-label">{baseLabel}</span> <br />
50
- {conditionLabel && (
51
- <span className="builder__button-condition">{conditionLabel}</span>
52
- )}
53
- </a>
54
- );
29
+ onDelete?: (node: Node) => void;
30
+ onReorder?: (prev: Node[], next: Node[]) => void;
31
+ onMoveChildUp?: (parent: Node, childIndex: number) => void;
32
+ onMoveChildDown?: (parent: Node, childIndex: number) => void;
55
33
  }
56
34
 
57
35
  function BuilderComponent({
58
36
  node,
59
37
  onClick,
60
38
  onAdd,
39
+ onDelete,
40
+ onReorder,
41
+ onMoveChildUp,
42
+ onMoveChildDown,
61
43
  }: BuilderEditorComponentProps) {
62
44
  if (isNodeNullOrUndefined(node)) {
63
45
  return <div className="builder__placeholder">Null or undefined</div>;
@@ -84,16 +66,38 @@ function BuilderComponent({
84
66
  );
85
67
 
86
68
  if (isNodeArray(node)) {
69
+ const list = node as Node[];
70
+
71
+ const moveItem = (index: number, direction: -1 | 1) => {
72
+ if (!onReorder) return;
73
+ const targetIndex = index + direction;
74
+ if (targetIndex < 0 || targetIndex >= list.length) return;
75
+ const updated = [...list];
76
+ const [moved] = updated.splice(index, 1);
77
+ updated.splice(targetIndex, 0, moved);
78
+ onReorder(list, updated);
79
+ };
80
+
87
81
  return (
88
82
  <div className="builder__list">
89
- {(node as Node[]).map((item, index) => (
90
- <BuilderButton
91
- onClick={() => {
92
- onClick(item);
93
- }}
94
- key={index}
95
- node={item}
96
- />
83
+ {list.map((item, index) => (
84
+ <div key={index} className="builder__list-item">
85
+ <BuilderButton
86
+ onClick={() => {
87
+ onClick(item);
88
+ }}
89
+ node={item}
90
+ onDelete={onDelete}
91
+ onMoveUp={
92
+ onReorder && index > 0 ? () => moveItem(index, -1) : undefined
93
+ }
94
+ onMoveDown={
95
+ onReorder && index < list.length - 1
96
+ ? () => moveItem(index, 1)
97
+ : undefined
98
+ }
99
+ />
100
+ </div>
97
101
  ))}
98
102
  {addButton}
99
103
  </div>
@@ -101,15 +105,24 @@ function BuilderComponent({
101
105
  }
102
106
 
103
107
  const nodeData = node as NodeData<NodeDefaultAttribute>;
104
- const children = nodeData.children
105
- ? isNodeArray(nodeData.children)
106
- ? (nodeData.children as Node[])
107
- : [nodeData.children]
108
+ const rawChildren = nodeData.children;
109
+ const hasArrayChildren = isNodeArray(rawChildren);
110
+ const children = rawChildren
111
+ ? hasArrayChildren
112
+ ? (rawChildren as Node[])
113
+ : [rawChildren]
108
114
  : null;
109
115
 
110
116
  return (
111
117
  <div className="builder__node">
112
118
  <div className="builder__children">
119
+ <BuilderButton
120
+ onClick={() => {
121
+ onClick(node);
122
+ }}
123
+ node={node}
124
+ onDelete={onDelete}
125
+ />
113
126
  {children &&
114
127
  children.map((child, index) => (
115
128
  <BuilderButton
@@ -118,6 +131,19 @@ function BuilderComponent({
118
131
  }}
119
132
  key={index}
120
133
  node={child}
134
+ onDelete={onDelete}
135
+ onMoveUp={
136
+ onMoveChildUp && hasArrayChildren && index > 0
137
+ ? () => onMoveChildUp(node, index)
138
+ : undefined
139
+ }
140
+ onMoveDown={
141
+ onMoveChildDown &&
142
+ hasArrayChildren &&
143
+ index < (children as Node[]).length - 1
144
+ ? () => onMoveChildDown(node, index)
145
+ : undefined
146
+ }
121
147
  />
122
148
  ))}
123
149
  </div>
@@ -131,6 +157,7 @@ export function Builder({
131
157
  setData,
132
158
  current,
133
159
  setCurrent,
160
+ onDeleteNode,
134
161
  }: BuilderEditorProps) {
135
162
  useLogRender('Builder');
136
163
  const [isAddModalOpen, setIsAddModalOpen] = useState(false);
@@ -222,6 +249,75 @@ export function Builder({
222
249
  [handleAddChild],
223
250
  );
224
251
 
252
+ const handleReorder = useCallback(
253
+ (prev: Node[], next: Node[]) => {
254
+ const updatedRoot = replaceNode(data, prev, next);
255
+ setData(updatedRoot);
256
+ if (current === prev) {
257
+ setCurrent(next);
258
+ }
259
+ },
260
+ [current, data, setCurrent, setData],
261
+ );
262
+
263
+ const handleMoveChildUp = useCallback(
264
+ (parentNode: Node, childIndex: number) => {
265
+ if (
266
+ isNodeNullOrUndefined(parentNode) ||
267
+ isNodeString(parentNode) ||
268
+ isNodeArray(parentNode)
269
+ ) {
270
+ return;
271
+ }
272
+ const parentData = parentNode as NodeData<NodeDefaultAttribute>;
273
+ const children = parentData.children;
274
+ if (!Array.isArray(children)) return;
275
+ if (childIndex <= 0 || childIndex >= children.length) return;
276
+ const updatedChildren = [...children];
277
+ const [movedChild] = updatedChildren.splice(childIndex, 1);
278
+ updatedChildren.splice(childIndex - 1, 0, movedChild);
279
+ const updatedParent: NodeData<NodeDefaultAttribute> = {
280
+ ...parentData,
281
+ children: updatedChildren,
282
+ };
283
+ const updatedRoot = replaceNode(data, parentNode, updatedParent);
284
+ setData(updatedRoot);
285
+ if (current === parentNode) {
286
+ setCurrent(updatedParent);
287
+ }
288
+ },
289
+ [current, data, setCurrent, setData],
290
+ );
291
+
292
+ const handleMoveChildDown = useCallback(
293
+ (parentNode: Node, childIndex: number) => {
294
+ if (
295
+ isNodeNullOrUndefined(parentNode) ||
296
+ isNodeString(parentNode) ||
297
+ isNodeArray(parentNode)
298
+ ) {
299
+ return;
300
+ }
301
+ const parentData = parentNode as NodeData<NodeDefaultAttribute>;
302
+ const children = parentData.children;
303
+ if (!Array.isArray(children)) return;
304
+ if (childIndex < 0 || childIndex >= children.length - 1) return;
305
+ const updatedChildren = [...children];
306
+ const [movedChild] = updatedChildren.splice(childIndex, 1);
307
+ updatedChildren.splice(childIndex + 1, 0, movedChild);
308
+ const updatedParent: NodeData<NodeDefaultAttribute> = {
309
+ ...parentData,
310
+ children: updatedChildren,
311
+ };
312
+ const updatedRoot = replaceNode(data, parentNode, updatedParent);
313
+ setData(updatedRoot);
314
+ if (current === parentNode) {
315
+ setCurrent(updatedParent);
316
+ }
317
+ },
318
+ [current, data, setCurrent, setData],
319
+ );
320
+
225
321
  function replaceNode(root: Node, target: Node, next: Node): Node {
226
322
  if (root === target) return next;
227
323
  if (root === null || root === undefined) return root;
@@ -312,6 +408,10 @@ export function Builder({
312
408
  <BuilderComponent
313
409
  onClick={handleNodeSelect}
314
410
  onAdd={canAddChild ? handleOpenAddModal : undefined}
411
+ onDelete={onDeleteNode}
412
+ onReorder={handleReorder}
413
+ onMoveChildUp={handleMoveChildUp}
414
+ onMoveChildDown={handleMoveChildDown}
315
415
  node={current}
316
416
  />
317
417
  {isAddModalOpen && (
@@ -0,0 +1,127 @@
1
+ import { useRef } from 'react';
2
+ import {
3
+ isNodeNullOrUndefined,
4
+ isNodeString,
5
+ Node,
6
+ NodeData,
7
+ NodeDefaultAttribute,
8
+ } from '..';
9
+ import { getPatternByType } from '../utils/patterns';
10
+
11
+ export type BuilderButtonProps = {
12
+ node: Node;
13
+ onClick: () => void;
14
+ onDelete?: (node: Node) => void;
15
+ onMoveUp?: () => void;
16
+ onMoveDown?: () => void;
17
+ };
18
+
19
+ export function BuilderButton({
20
+ node,
21
+ onClick,
22
+ onDelete,
23
+ onMoveUp,
24
+ onMoveDown,
25
+ }: BuilderButtonProps) {
26
+ if (isNodeNullOrUndefined(node)) {
27
+ return <div className="builder__placeholder">Null or undefined</div>;
28
+ }
29
+ if (isNodeString(node)) {
30
+ return <div className="builder__text">{node as string}</div>;
31
+ }
32
+ const nodeData = node as NodeData<NodeDefaultAttribute>;
33
+
34
+ const longPressTimeoutRef = useRef<number | null>(null);
35
+ const longPressTriggeredRef = useRef(false);
36
+
37
+ const handleDelete = () => {
38
+ if (onDelete) {
39
+ onDelete(node);
40
+ }
41
+ };
42
+
43
+ const clearLongPress = () => {
44
+ if (longPressTimeoutRef.current !== null) {
45
+ window.clearTimeout(longPressTimeoutRef.current);
46
+ longPressTimeoutRef.current = null;
47
+ }
48
+ };
49
+
50
+ const handlePressStart = () => {
51
+ longPressTriggeredRef.current = false;
52
+ longPressTimeoutRef.current = window.setTimeout(() => {
53
+ longPressTriggeredRef.current = true;
54
+ const shouldDelete = window.confirm('Do you want to delete');
55
+ if (shouldDelete) {
56
+ handleDelete();
57
+ }
58
+ }, 600);
59
+ };
60
+
61
+ const handlePressEnd = () => {
62
+ if (!longPressTriggeredRef.current) {
63
+ onClick();
64
+ }
65
+ clearLongPress();
66
+ };
67
+
68
+ const handlePressCancel = () => {
69
+ clearLongPress();
70
+ };
71
+
72
+ let extra = '';
73
+ if (nodeData.attributes?.condition) {
74
+ extra = ` (${nodeData.attributes.condition} ${nodeData.attributes.conditionVariable})`;
75
+ }
76
+ const patternLabel = getPatternByType(nodeData.type)?.meta?.label?.trim();
77
+ const baseLabel =
78
+ patternLabel && patternLabel.length > 0 ? patternLabel : nodeData.type;
79
+ const conditionLabel = extra.trim() ? extra : '';
80
+
81
+ return (
82
+ <div className="builder__button">
83
+ {(onMoveUp || onMoveDown) && (
84
+ <div className="builder__sort-controls">
85
+ <button
86
+ type="button"
87
+ className="builder__sort-button"
88
+ onClick={(event) => {
89
+ event.stopPropagation();
90
+ onMoveUp?.();
91
+ }}
92
+ disabled={!onMoveUp}
93
+ aria-label="Move up"
94
+ >
95
+
96
+ </button>
97
+ <button
98
+ type="button"
99
+ className="builder__sort-button"
100
+ onClick={(event) => {
101
+ event.stopPropagation();
102
+ onMoveDown?.();
103
+ }}
104
+ disabled={!onMoveDown}
105
+ aria-label="Move down"
106
+ >
107
+
108
+ </button>
109
+ </div>
110
+ )}
111
+ <a
112
+ className="builder__button-link"
113
+ onMouseDown={handlePressStart}
114
+ onMouseUp={handlePressEnd}
115
+ onMouseLeave={handlePressCancel}
116
+ onTouchStart={handlePressStart}
117
+ onTouchEnd={handlePressEnd}
118
+ onTouchCancel={handlePressCancel}
119
+ >
120
+ {baseLabel}
121
+ </a>
122
+ {conditionLabel && (
123
+ <span className="builder__button-condition">{conditionLabel}</span>
124
+ )}
125
+ </div>
126
+ );
127
+ }
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@ import AttributesEditor from './AttributesEditor';
3
3
 
4
4
  export type { TargetedScreenSize } from './types/TargetedScreenSize';
5
5
  export type { Node, NodeData, NodeDefaultAttribute } from './types/Node';
6
- export type { Project } from './types/Project';
6
+ export type { Project, ProjectColors } from './types/Project';
7
7
  export {
8
8
  isNodeNullOrUndefined,
9
9
  isNodeString,
@@ -28,7 +28,7 @@ export { extractViewStyle } from './utils/extractViewStyle';
28
28
  export { extractImageStyle } from './utils/extractImageStyle';
29
29
  export { extractTextStyle } from './utils/extractTextStyle';
30
30
  export { ProjectPage } from './pages/ProjectPage';
31
- export type { ProjectPageProps, Tab } from './pages/ProjectPage';
31
+ export type { ProjectPageProps } from './pages/ProjectPage';
32
32
  export { copyNode } from './utils/copyNode';
33
33
  export { logger } from './utils/logger';
34
34
  export type { LogLevel } from './types/Project';
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React, { ReactNode, useCallback, useEffect } from 'react';
2
2
  import { useMockOSContext } from '../context/MockOSContext';
3
3
  import { MockLaunchScreenComponent } from './MockLaunchScreenComponent';
4
4
  // Note: We might use react-router or similar library in the future for more complex routing
@@ -92,11 +92,19 @@ export function MockOSRouter({
92
92
 
93
93
  const { currentRoute, navigation } = context;
94
94
 
95
- function handleLaunchApp() {
95
+ const handleLaunchApp = useCallback(() => {
96
96
  // Navigate to the route specified in childrenBelongTo or default to 'onboard'
97
97
  const targetRoute = childrenBelongTo || 'onboard';
98
98
  navigation(targetRoute);
99
- }
99
+ }, [childrenBelongTo, navigation]);
100
+
101
+ useEffect(() => {
102
+ const timer = setTimeout(() => {
103
+ handleLaunchApp();
104
+ }, 1000);
105
+
106
+ return () => clearTimeout(timer);
107
+ }, [handleLaunchApp]);
100
108
 
101
109
  return (
102
110
  <div className="mockos-router">