@developer_tribe/react-builder 1.0.1 → 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 (218) hide show
  1. package/dist/AttributesEditor.d.ts +3 -1
  2. package/dist/DeviceMockFrame.d.ts +2 -1
  3. package/dist/RenderPage.d.ts +5 -3
  4. package/dist/attributes-editor/Field.d.ts +17 -0
  5. package/dist/attributes-editor/FieldInfoTooltip.d.ts +7 -0
  6. package/dist/attributes-editor/LayoutPreviewPicker.d.ts +12 -0
  7. package/dist/attributes-editor/SpecialCategorySection.d.ts +20 -0
  8. package/dist/attributes-editor/types.d.ts +14 -0
  9. package/dist/background.jpg +0 -0
  10. package/dist/build-components/BackgroundImage/BackgroundImage.d.ts +5 -0
  11. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +44 -0
  12. package/dist/build-components/Button/Button.d.ts +1 -1
  13. package/dist/build-components/Button/ButtonProps.generated.d.ts +33 -1
  14. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +34 -1
  15. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +32 -0
  16. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +32 -0
  17. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +34 -1
  18. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +34 -1
  19. package/dist/build-components/Image/ImageProps.generated.d.ts +32 -3
  20. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +34 -1
  21. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +32 -0
  22. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +32 -0
  23. package/dist/build-components/OnboardDot/OnboardDot.d.ts +1 -1
  24. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +29 -0
  25. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +11 -5
  26. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +32 -3
  27. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +31 -3
  28. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +32 -5
  29. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +11 -5
  30. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +11 -5
  31. package/dist/build-components/Text/TextProps.generated.d.ts +11 -5
  32. package/dist/build-components/View/ViewProps.generated.d.ts +10 -4
  33. package/dist/build-components/index.d.ts +2 -1
  34. package/dist/build-components/patterns.generated.d.ts +6288 -136
  35. package/dist/components/AttributesEditorPanel.d.ts +3 -4
  36. package/dist/components/Breadcrumb.d.ts +3 -1
  37. package/dist/components/Builder.d.ts +2 -1
  38. package/dist/components/BuilderButton.d.ts +9 -0
  39. package/dist/components/Checkbox.d.ts +17 -0
  40. package/dist/components/DeviceButton.d.ts +8 -0
  41. package/dist/components/DeviceNavigationBar.d.ts +10 -0
  42. package/dist/components/DeviceStatusBar.d.ts +9 -0
  43. package/dist/components/EditorHeader.d.ts +3 -8
  44. package/dist/index.cjs.js +5 -5
  45. package/dist/index.cjs.js.map +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.esm.js +5 -5
  48. package/dist/index.esm.js.map +1 -1
  49. package/dist/mockOS/components/MockLaunchScreenComponent.d.ts +6 -0
  50. package/dist/mockOS/components/MockOSRouter.d.ts +8 -0
  51. package/dist/mockOS/components/PermissionModal.d.ts +9 -0
  52. package/dist/mockOS/context/MockOSContext.d.ts +36 -0
  53. package/dist/mockOS/hooks/useMockNavigation.d.ts +3 -0
  54. package/dist/mockOS/hooks/useMockPermission.d.ts +3 -0
  55. package/dist/mockOS/index.d.ts +9 -0
  56. package/dist/mockOS/managers/mockPermissionManager.d.ts +10 -0
  57. package/dist/mockOS/managers/navigationManager.d.ts +17 -0
  58. package/dist/modals/AddComponentModal.d.ts +8 -0
  59. package/dist/modals/ColorModal.d.ts +11 -0
  60. package/dist/modals/DeviceSelectorModal.d.ts +9 -0
  61. package/dist/modals/LocalicationModal.d.ts +8 -0
  62. package/dist/modals/Modal.d.ts +12 -0
  63. package/dist/modals/index.d.ts +5 -0
  64. package/dist/pages/ProjectPage.d.ts +3 -3
  65. package/dist/pages/tabs/BuilderPanel.d.ts +8 -0
  66. package/dist/pages/tabs/{DebugTab.d.ts → SideTool.d.ts} +2 -2
  67. package/dist/store.d.ts +7 -3
  68. package/dist/styles.css +1 -1
  69. package/dist/types/Project.d.ts +11 -0
  70. package/dist/utils/analyseNode.d.ts +1 -0
  71. package/dist/utils/extractTextStyle.d.ts +8 -1
  72. package/dist/utils/extractViewStyle.d.ts +8 -1
  73. package/dist/utils/parseColor.d.ts +7 -0
  74. package/dist/utils/patterns.d.ts +24 -0
  75. package/package.json +2 -1
  76. package/scripts/prebuild/utils/createGeneratedProps.js +11 -3
  77. package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +45 -6
  78. package/scripts/prebuild/utils/validatePatternJson.js +13 -5
  79. package/src/AttributesEditor.tsx +493 -310
  80. package/src/DeviceMockFrame.tsx +21 -37
  81. package/src/RenderPage.tsx +86 -7
  82. package/src/assets/images/android.svg +42 -42
  83. package/src/assets/images/apple.svg +15 -15
  84. package/src/attributes-editor/Field.tsx +669 -0
  85. package/src/attributes-editor/FieldInfoTooltip.tsx +49 -0
  86. package/src/attributes-editor/LayoutPreviewPicker.tsx +199 -0
  87. package/src/attributes-editor/SpecialCategorySection.tsx +285 -0
  88. package/src/attributes-editor/types.ts +30 -0
  89. package/src/build-components/BackgroundImage/BackgroundImage.tsx +87 -0
  90. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +60 -0
  91. package/src/build-components/BackgroundImage/pattern.json +45 -0
  92. package/src/build-components/Button/Button.tsx +37 -2
  93. package/src/build-components/Button/ButtonProps.generated.ts +44 -1
  94. package/src/build-components/Button/pattern.json +31 -2
  95. package/src/build-components/Carousel/Carousel.tsx +39 -2
  96. package/src/build-components/Carousel/CarouselProps.generated.ts +46 -1
  97. package/src/build-components/Carousel/pattern.json +10 -0
  98. package/src/build-components/CarouselButtons/CarouselButtons.tsx +21 -2
  99. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +43 -0
  100. package/src/build-components/CarouselButtons/pattern.json +22 -0
  101. package/src/build-components/CarouselDots/CarouselDots.tsx +49 -8
  102. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +43 -0
  103. package/src/build-components/CarouselDots/pattern.json +15 -0
  104. package/src/build-components/CarouselItem/CarouselItem.tsx +21 -2
  105. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +46 -1
  106. package/src/build-components/CarouselItem/pattern.json +7 -0
  107. package/src/build-components/CarouselProvider/CarouselProvider.tsx +21 -2
  108. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +46 -1
  109. package/src/build-components/CarouselProvider/pattern.json +7 -0
  110. package/src/build-components/Image/Image.tsx +33 -2
  111. package/src/build-components/Image/ImageProps.generated.ts +43 -3
  112. package/src/build-components/Image/pattern.json +46 -3
  113. package/src/build-components/Onboard/Onboard.tsx +6 -1
  114. package/src/build-components/Onboard/OnboardProps.generated.ts +46 -1
  115. package/src/build-components/Onboard/pattern.json +11 -0
  116. package/src/build-components/OnboardButton/OnboardButton.tsx +54 -6
  117. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +43 -0
  118. package/src/build-components/OnboardButton/pattern.json +71 -5
  119. package/src/build-components/OnboardButtons/OnboardButtons.tsx +33 -11
  120. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +43 -0
  121. package/src/build-components/OnboardButtons/pattern.json +70 -4
  122. package/src/build-components/OnboardDot/OnboardDot.tsx +113 -4
  123. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +29 -0
  124. package/src/build-components/OnboardDot/pattern.json +55 -2
  125. package/src/build-components/OnboardFooter/OnboardFooter.tsx +20 -4
  126. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +11 -5
  127. package/src/build-components/OnboardFooter/pattern.json +58 -2
  128. package/src/build-components/OnboardImage/OnboardImage.tsx +49 -5
  129. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +43 -3
  130. package/src/build-components/OnboardImage/pattern.json +21 -0
  131. package/src/build-components/OnboardItem/OnboardItem.tsx +17 -1
  132. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +42 -3
  133. package/src/build-components/OnboardItem/pattern.json +38 -2
  134. package/src/build-components/OnboardProvider/OnboardProvider.tsx +52 -18
  135. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +44 -5
  136. package/src/build-components/OnboardProvider/pattern.json +44 -5
  137. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +11 -5
  138. package/src/build-components/OnboardSubtitle/pattern.json +7 -1
  139. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +11 -5
  140. package/src/build-components/OnboardTitle/pattern.json +7 -1
  141. package/src/build-components/RenderNode.generated.tsx +3 -0
  142. package/src/build-components/Text/Text.tsx +34 -6
  143. package/src/build-components/Text/TextProps.generated.ts +11 -5
  144. package/src/build-components/Text/pattern.json +38 -2
  145. package/src/build-components/View/View.tsx +33 -6
  146. package/src/build-components/View/ViewProps.generated.ts +10 -4
  147. package/src/build-components/View/pattern.json +285 -19
  148. package/src/build-components/index.ts +5 -0
  149. package/src/build-components/patterns.generated.ts +6346 -143
  150. package/src/components/AttributesEditorPanel.tsx +17 -64
  151. package/src/components/Breadcrumb.tsx +37 -5
  152. package/src/components/Builder.tsx +311 -108
  153. package/src/components/BuilderButton.tsx +127 -0
  154. package/src/components/Checkbox.tsx +81 -0
  155. package/src/components/DeviceButton.tsx +39 -0
  156. package/src/components/DeviceNavigationBar.tsx +201 -0
  157. package/src/components/DeviceStatusBar.tsx +85 -0
  158. package/src/components/EditorHeader.tsx +26 -74
  159. package/src/index.ts +2 -2
  160. package/src/mockOS/components/MockLaunchScreenComponent.tsx +43 -0
  161. package/src/mockOS/components/MockOSRouter.tsx +123 -0
  162. package/src/mockOS/components/PermissionModal.tsx +270 -0
  163. package/src/mockOS/context/MockOSContext.tsx +179 -0
  164. package/src/mockOS/hooks/useMockNavigation.ts +11 -0
  165. package/src/mockOS/hooks/useMockPermission.ts +11 -0
  166. package/src/mockOS/index.ts +26 -0
  167. package/src/mockOS/managers/mockPermissionManager.ts +54 -0
  168. package/src/mockOS/managers/navigationManager.ts +91 -0
  169. package/src/modals/AddComponentModal.tsx +313 -0
  170. package/src/modals/ColorModal.tsx +425 -0
  171. package/src/modals/DeviceSelectorModal.tsx +57 -0
  172. package/src/modals/LocalicationModal.tsx +54 -0
  173. package/src/modals/Modal.tsx +57 -0
  174. package/src/modals/index.ts +5 -0
  175. package/src/pages/ProjectPage.tsx +307 -71
  176. package/src/pages/tabs/{BuilderTab.tsx → BuilderPanel.tsx} +13 -9
  177. package/src/pages/tabs/SideTool.tsx +259 -0
  178. package/src/size-matters/index.ts +27 -5
  179. package/src/store.ts +13 -5
  180. package/src/styles/base/_global.scss +404 -0
  181. package/src/styles/components/_attributes-editor.scss +273 -0
  182. package/src/styles/components/_editor-shell.scss +212 -0
  183. package/src/styles/components/_mockos-router.scss +140 -0
  184. package/src/styles/components/_ui-components.scss +183 -0
  185. package/src/styles/foundation/_colors.scss +8 -0
  186. package/src/styles/{_mixins.scss → foundation/_mixins.scss} +5 -4
  187. package/src/styles/{_reset.scss → foundation/_reset.scss} +5 -2
  188. package/src/styles/foundation/_sizes.scss +37 -0
  189. package/src/styles/foundation/_typography.scss +4 -0
  190. package/src/styles/foundation/_variables.scss +3 -0
  191. package/src/styles/index.scss +22 -136
  192. package/src/styles/layout/_builder.scss +124 -0
  193. package/src/styles/layout/_pages.scss +3 -0
  194. package/src/styles/modals/_add-component.scss +122 -0
  195. package/src/styles/modals/_color-modal.scss +159 -0
  196. package/src/styles/modals/_device-selector.scss +18 -0
  197. package/src/styles/modals/_localication-modal.scss +68 -0
  198. package/src/styles/modals/_modal-shell.scss +46 -0
  199. package/src/styles/utilities/_carousel.scss +125 -0
  200. package/src/types/Project.ts +14 -0
  201. package/src/types/images.d.ts +8 -0
  202. package/src/utils/analyseNode.ts +98 -0
  203. package/src/utils/extractTextStyle.ts +28 -10
  204. package/src/utils/extractViewStyle.ts +77 -9
  205. package/src/utils/parseColor.ts +43 -0
  206. package/src/utils/patterns.ts +33 -0
  207. package/dist/build-components/OnboardDot/OnboardExpandingDotProps.generated.d.ts +0 -10
  208. package/dist/pages/tabs/BuilderTab.d.ts +0 -9
  209. package/dist/pages/tabs/PreviewTab.d.ts +0 -3
  210. package/src/build-components/OnboardDot/OnboardExpandingDotProps.generated.ts +0 -20
  211. package/src/pages/tabs/DebugTab.tsx +0 -23
  212. package/src/pages/tabs/PreviewTab.tsx +0 -194
  213. package/src/styles/_variables.scss +0 -27
  214. package/src/styles/builder.scss +0 -60
  215. package/src/styles/components.scss +0 -88
  216. package/src/styles/editor.scss +0 -174
  217. package/src/styles/global.scss +0 -200
  218. package/src/styles/pages.scss +0 -2
@@ -0,0 +1,259 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { JsonEditor } from 'json-edit-react';
3
+ import { Modal } from '../../modals';
4
+ import { Localication, Node } from '../..';
5
+ import { useLogRender } from '../../utils/useLogRender';
6
+ import { useRenderStore } from '../../store';
7
+ import { Checkbox } from '../../components/Checkbox';
8
+ import { LocalicationModal } from '../../modals/LocalicationModal';
9
+
10
+ const screenStyleDefaults = {
11
+ light: { backgroundColor: '#FDFDFD', color: '#161827' },
12
+ dark: { backgroundColor: '#12131A', color: '#E9EBF9' },
13
+ } as const;
14
+
15
+ type ScreenMode = keyof typeof screenStyleDefaults;
16
+ type ScreenColorKey = keyof (typeof screenStyleDefaults)['light'];
17
+
18
+ type SideToolProps = {
19
+ data: Node;
20
+ setData: (data: Node) => void;
21
+ };
22
+
23
+ const colorFields = [
24
+ {
25
+ id: 'light-bg',
26
+ label: 'Light Background Color',
27
+ mode: 'light' as ScreenMode,
28
+ key: 'backgroundColor' as ScreenColorKey,
29
+ },
30
+ {
31
+ id: 'light-color',
32
+ label: 'Light Color',
33
+ mode: 'light' as ScreenMode,
34
+ key: 'color' as ScreenColorKey,
35
+ },
36
+ {
37
+ id: 'dark-bg',
38
+ label: 'Dark Background Color',
39
+ mode: 'dark' as ScreenMode,
40
+ key: 'backgroundColor' as ScreenColorKey,
41
+ },
42
+ {
43
+ id: 'dark-color',
44
+ label: 'Dark Color',
45
+ mode: 'dark' as ScreenMode,
46
+ key: 'color' as ScreenColorKey,
47
+ },
48
+ ];
49
+
50
+ export function SideTool({ data, setData }: SideToolProps) {
51
+ useLogRender('SideTool');
52
+ const [isDebugModalOpen, setIsDebugModalOpen] = useState(false);
53
+ const [isLocalicationModalOpen, setIsLocalicationModalOpen] = useState(false);
54
+ const [isCompactMode, setIsCompactMode] = useState(() => {
55
+ if (typeof window === 'undefined') {
56
+ return false;
57
+ }
58
+ return window.innerWidth < 1000;
59
+ });
60
+ const [isCompactPanelVisible, setIsCompactPanelVisible] = useState(false);
61
+ const { appConfig, setAppConfig, previewMode, setPreviewMode } =
62
+ useRenderStore((s) => ({
63
+ appConfig: s.appConfig,
64
+ setAppConfig: s.setAppConfig,
65
+ previewMode: s.previewMode,
66
+ setPreviewMode: s.setPreviewMode,
67
+ }));
68
+
69
+ useEffect(() => {
70
+ if (typeof window === 'undefined') {
71
+ return;
72
+ }
73
+
74
+ const handleResize = () => {
75
+ const compact = window.innerWidth < 1000;
76
+ setIsCompactMode(compact);
77
+ };
78
+
79
+ handleResize();
80
+ window.addEventListener('resize', handleResize);
81
+ return () => window.removeEventListener('resize', handleResize);
82
+ }, []);
83
+
84
+ const getScreenColorValue = (mode: ScreenMode, key: ScreenColorKey) =>
85
+ appConfig.screenStyle?.[mode]?.[key] ?? screenStyleDefaults[mode][key];
86
+
87
+ const handleScreenStyleChange = (
88
+ mode: ScreenMode,
89
+ key: ScreenColorKey,
90
+ value: string,
91
+ ) => {
92
+ setAppConfig({
93
+ ...appConfig,
94
+ screenStyle: {
95
+ ...screenStyleDefaults,
96
+ ...appConfig.screenStyle,
97
+ [mode]: {
98
+ ...screenStyleDefaults[mode],
99
+ ...appConfig.screenStyle?.[mode],
100
+ [key]: value,
101
+ },
102
+ },
103
+ });
104
+ };
105
+
106
+ const handleLocalicationChange = (data: Localication) => {
107
+ setAppConfig({ ...appConfig, localication: data });
108
+ };
109
+
110
+ return (
111
+ <div
112
+ style={{
113
+ height: '100%',
114
+ display: 'flex',
115
+ flexDirection: 'column',
116
+ gap: 8,
117
+ backgroundColor: isCompactMode ? '#fff' : undefined,
118
+ }}
119
+ >
120
+ <button
121
+ type="button"
122
+ className="editor-button"
123
+ onClick={() => setIsCompactPanelVisible((prev) => !prev)}
124
+ aria-pressed={isCompactPanelVisible}
125
+ style={{ alignSelf: 'flex-start' }}
126
+ >
127
+ {isCompactPanelVisible ? 'Hide tools' : 'Show tools'}
128
+ </button>
129
+
130
+ {isCompactPanelVisible && (
131
+ <div className="side-tool" style={{ display: 'flex', height: '100%' }}>
132
+ <select
133
+ value={appConfig.defaultLanguage ?? 'en'}
134
+ onChange={(e) =>
135
+ setAppConfig({ ...appConfig, defaultLanguage: e.target.value })
136
+ }
137
+ >
138
+ {Object.keys(appConfig.localication ?? {}).map((language) => (
139
+ <option key={language} value={language}>
140
+ {language}
141
+ </option>
142
+ ))}
143
+ </select>
144
+
145
+ <Checkbox
146
+ label="Dark Mode"
147
+ checked={appConfig.theme === 'dark'}
148
+ onChange={(checked) =>
149
+ setAppConfig({ ...appConfig, theme: checked ? 'dark' : 'light' })
150
+ }
151
+ />
152
+
153
+ <Checkbox
154
+ label="Is RTL"
155
+ checked={appConfig.isRtl ?? false}
156
+ onChange={(checked) =>
157
+ setAppConfig({ ...appConfig, isRtl: checked })
158
+ }
159
+ />
160
+
161
+ <Checkbox
162
+ label="Preview mode"
163
+ checked={previewMode}
164
+ onChange={setPreviewMode}
165
+ />
166
+
167
+ <div>
168
+ <div
169
+ style={{
170
+ display: 'grid',
171
+ gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
172
+ gap: 12,
173
+ }}
174
+ >
175
+ {colorFields.map(({ id, label, mode, key }) => (
176
+ <React.Fragment key={id}>
177
+ <div>{label}</div>
178
+ <input
179
+ id={id}
180
+ type="color"
181
+ className="input input--color"
182
+ value={getScreenColorValue(mode, key)}
183
+ onChange={(e) =>
184
+ handleScreenStyleChange(mode, key, e.target.value)
185
+ }
186
+ />
187
+ </React.Fragment>
188
+ ))}
189
+ </div>
190
+ </div>
191
+
192
+ <div
193
+ style={{
194
+ marginTop: 'auto',
195
+ paddingTop: 16,
196
+ display: 'flex',
197
+ flexDirection: 'column',
198
+ gap: 8,
199
+ }}
200
+ >
201
+ <button
202
+ type="button"
203
+ className="editor-button"
204
+ onClick={() => setIsLocalicationModalOpen(true)}
205
+ >
206
+ Open localization editor
207
+ </button>
208
+ <button
209
+ type="button"
210
+ className="editor-button debug-button"
211
+ title="Inspect raw JSON data"
212
+ onClick={() => setIsDebugModalOpen(true)}
213
+ >
214
+ Debug JSON
215
+ </button>
216
+ </div>
217
+
218
+ {isDebugModalOpen && (
219
+ <Modal
220
+ onClose={() => setIsDebugModalOpen(false)}
221
+ ariaLabelledBy="debug-json-editor-title"
222
+ className="modal--large modal--scrollable"
223
+ contentClassName="localication-modal__content"
224
+ >
225
+ <div className="modal__header localication-modal__header">
226
+ <button
227
+ type="button"
228
+ className="editor-button"
229
+ onClick={() => setIsDebugModalOpen(false)}
230
+ >
231
+ Close
232
+ </button>
233
+ </div>
234
+ <div className="localication-modal__body">
235
+ <div className="localication-modal__editor">
236
+ <JsonEditor
237
+ rootName="debug"
238
+ data={data as any}
239
+ setData={setData as any}
240
+ className="localication-modal__json-editor"
241
+ maxWidth="100%"
242
+ />
243
+ </div>
244
+ </div>
245
+ </Modal>
246
+ )}
247
+
248
+ {isLocalicationModalOpen && (
249
+ <LocalicationModal
250
+ data={appConfig.localication ?? {}}
251
+ onChange={handleLocalicationChange}
252
+ onClose={() => setIsLocalicationModalOpen(false)}
253
+ />
254
+ )}
255
+ </div>
256
+ )}
257
+ </div>
258
+ );
259
+ }
@@ -1,15 +1,31 @@
1
1
  import { useRenderStore } from '../store';
2
+ import { defaultAppConfig } from '../types/PreviewConfig';
3
+ import { getDefaultDevice } from '../utils/getDevices';
4
+
5
+ const fallbackDevice = getDefaultDevice();
6
+ const fallbackBaseSize = defaultAppConfig.baseSize;
7
+
8
+ function ensureNumber(value: number | undefined, fallback: number) {
9
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
10
+ }
2
11
 
3
12
  function getBaseDimensions() {
4
13
  const currentState = useRenderStore.getState();
5
- let device = currentState.device;
14
+ const device = currentState.device ?? fallbackDevice;
15
+ const baseSize = currentState.appConfig?.baseSize ?? fallbackBaseSize;
16
+
17
+ const deviceWidth = ensureNumber(device?.width, fallbackDevice.width);
18
+ const deviceHeight = ensureNumber(device?.height, fallbackDevice.height);
19
+ const baseWidth = ensureNumber(baseSize?.width, fallbackBaseSize.width);
20
+ const baseHeight = ensureNumber(baseSize?.height, fallbackBaseSize.height);
21
+
6
22
  const [shortDimension, longDimension] =
7
- device.width < device.height
8
- ? [device.width, device.height]
9
- : [device.height, device.width];
23
+ deviceWidth < deviceHeight
24
+ ? [deviceWidth, deviceHeight]
25
+ : [deviceHeight, deviceWidth];
10
26
 
11
27
  return {
12
- baseSize: currentState.appConfig.baseSize,
28
+ baseSize: { width: baseWidth, height: baseHeight },
13
29
  shortDimension,
14
30
  longDimension,
15
31
  };
@@ -51,6 +67,12 @@ export function parseSize(value?: string | number) {
51
67
  return Number.isFinite(n) ? fs(n) : raw;
52
68
  }
53
69
 
70
+ // Preserve percentage values as-is
71
+ if (lower.endsWith('%')) {
72
+ const numericPortion = parseFloat(lower.slice(0, -1));
73
+ return Number.isFinite(numericPortion) ? `${numericPortion}%` : raw;
74
+ }
75
+
54
76
  // Handle px explicitly (treat as absolute, not scaled)
55
77
  if (lower.endsWith('px')) {
56
78
  const n = parseFloat(lower.replace('px', ''));
package/src/store.ts CHANGED
@@ -10,17 +10,21 @@ import { getDefaultDevice } from './utils/getDevices';
10
10
  import { ScreenStyle } from './RenderPage';
11
11
  import { createJSONStorage } from 'zustand/middleware';
12
12
  import { Node } from './types/Node';
13
- import type { LogEntry, LogLevel } from './types/Project';
13
+ import type { LogEntry, LogLevel, ProjectColors } from './types/Project';
14
14
 
15
15
  type RenderStore = {
16
16
  copiedNode: Node | null;
17
17
  setCopiedNode: (node: Node | null) => void;
18
+ current: Node | null;
19
+ setCurrent: (node: Node | null) => void;
18
20
  device: Device;
19
21
  setDevice: (device: Device) => void;
20
22
  appConfig: AppConfig;
21
23
  setAppConfig: (appConfig: AppConfig) => void;
22
- renderCount: number;
23
- forceRender: () => void;
24
+ projectColors?: ProjectColors;
25
+ setProjectColors: (projectColors?: ProjectColors) => void;
26
+ previewMode: boolean;
27
+ setPreviewMode: (previewMode: boolean) => void;
24
28
  // Logging
25
29
  logs: LogEntry[];
26
30
  logLevel: LogLevel;
@@ -38,12 +42,16 @@ export const useRenderStore = createWithEqualityFn<RenderStore>()(
38
42
  (set) => ({
39
43
  copiedNode: null,
40
44
  setCopiedNode: (node) => set({ copiedNode: node }),
41
- renderCount: 0,
42
- forceRender: () => set((state) => ({ renderCount: state.renderCount + 1 })),
45
+ current: null,
46
+ setCurrent: (node) => set({ current: node }),
43
47
  device: getDefaultDevice(),
44
48
  setDevice: (device) => set({ device }),
45
49
  appConfig: defaultAppConfig,
46
50
  setAppConfig: (appConfig) => set({ appConfig }),
51
+ projectColors: undefined,
52
+ setProjectColors: (projectColors) => set({ projectColors }),
53
+ previewMode: false,
54
+ setPreviewMode: (previewMode) => set({ previewMode }),
47
55
  // Logging defaults
48
56
  logs: [],
49
57
  logLevel: 'INFO',