@developer_tribe/react-builder 0.1.32 → 1.1.0

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 (67) hide show
  1. package/dist/DeviceMockFrame.d.ts +1 -17
  2. package/dist/RenderPage.d.ts +1 -9
  3. package/dist/build-components/index.d.ts +1 -0
  4. package/dist/components/AttributesEditorPanel.d.ts +9 -0
  5. package/dist/components/Breadcrumb.d.ts +13 -0
  6. package/dist/components/Builder.d.ts +9 -0
  7. package/dist/components/EditorHeader.d.ts +15 -0
  8. package/dist/index.cjs.js +6 -5
  9. package/dist/index.cjs.js.map +1 -0
  10. package/dist/index.d.ts +5 -4
  11. package/dist/index.esm.js +6 -5
  12. package/dist/index.esm.js.map +1 -0
  13. package/dist/pages/ProjectPage.d.ts +9 -0
  14. package/dist/pages/tabs/BuilderTab.d.ts +9 -0
  15. package/dist/pages/tabs/DebugTab.d.ts +7 -0
  16. package/dist/pages/tabs/PreviewTab.d.ts +3 -0
  17. package/dist/store.d.ts +8 -18
  18. package/dist/styles.css +1 -1
  19. package/dist/types/PreviewConfig.d.ts +6 -3
  20. package/dist/types/Project.d.ts +2 -2
  21. package/dist/utils/copyNode.d.ts +2 -0
  22. package/package.json +16 -9
  23. package/scripts/prebuild/utils/createBuildComponentsIndex.js +15 -1
  24. package/src/DeviceMockFrame.tsx +20 -31
  25. package/src/RenderPage.tsx +3 -38
  26. package/src/assets/images/android.svg +43 -0
  27. package/src/assets/images/apple.svg +16 -0
  28. package/src/assets/images/background.jpg +0 -0
  29. package/src/assets/samples/carousel-sample.json +2 -3
  30. package/src/assets/samples/getSamples.ts +49 -12
  31. package/src/assets/samples/simple-1.json +1 -2
  32. package/src/assets/samples/simple-2.json +1 -2
  33. package/src/assets/samples/vpn-onboard-1.json +1 -2
  34. package/src/assets/samples/vpn-onboard-2.json +1 -2
  35. package/src/assets/samples/vpn-onboard-3.json +1 -2
  36. package/src/assets/samples/vpn-onboard-4.json +1 -2
  37. package/src/assets/samples/vpn-onboard-5.json +1 -2
  38. package/src/assets/samples/vpn-onboard-6.json +1 -2
  39. package/src/build-components/OnboardButton/OnboardButton.tsx +5 -4
  40. package/src/build-components/OnboardButtons/OnboardButtons.tsx +5 -7
  41. package/src/build-components/OnboardFooter/OnboardFooter.tsx +3 -3
  42. package/src/build-components/Text/Text.tsx +3 -3
  43. package/src/build-components/index.ts +22 -0
  44. package/src/components/AttributesEditorPanel.tsx +110 -0
  45. package/src/components/Breadcrumb.tsx +46 -0
  46. package/src/components/Builder.tsx +270 -0
  47. package/src/components/EditorHeader.tsx +184 -0
  48. package/src/index.ts +5 -4
  49. package/src/pages/ProjectPage.tsx +112 -0
  50. package/src/pages/tabs/BuilderTab.tsx +31 -0
  51. package/src/pages/tabs/DebugTab.tsx +21 -0
  52. package/src/pages/tabs/PreviewTab.tsx +192 -0
  53. package/src/size-matters/index.ts +5 -1
  54. package/src/store.ts +26 -38
  55. package/src/styles/_mixins.scss +21 -0
  56. package/src/styles/_variables.scss +27 -0
  57. package/src/styles/builder.scss +60 -0
  58. package/src/styles/components.scss +88 -0
  59. package/src/styles/editor.scss +174 -0
  60. package/src/styles/global.scss +200 -0
  61. package/src/styles/index.scss +7 -0
  62. package/src/styles/pages.scss +2 -0
  63. package/src/types/PreviewConfig.ts +14 -5
  64. package/src/types/Project.ts +2 -2
  65. package/src/utils/copyNode.ts +7 -0
  66. package/src/utils/extractTextStyle.ts +4 -2
  67. package/src/utils/getDevices.ts +1 -0
@@ -0,0 +1,174 @@
1
+ @use './variables' as *;
2
+ @use './mixins' as *;
3
+
4
+ .editor-tabs {
5
+ display: flex;
6
+ gap: 8px;
7
+ border-bottom: 1px solid #e5e7eb;
8
+ }
9
+
10
+ .editor-tab {
11
+ padding: 8px 12px;
12
+ cursor: pointer;
13
+ border: 1px solid transparent;
14
+ border-top-left-radius: 4px;
15
+ border-top-right-radius: 4px;
16
+ color: #111827;
17
+ padding: 8px 12px;
18
+ }
19
+
20
+ .editor-tab--active {
21
+ background: #fff;
22
+ border-color: #e5e7eb #e5e7eb #fff #e5e7eb;
23
+ }
24
+
25
+ .editor-panels {
26
+ padding: 12px;
27
+ &.editor-panels-debug {
28
+ padding: 0;
29
+ }
30
+ }
31
+ .jer-editor-container {
32
+ padding-left: 0 !important;
33
+ padding-right: 0 !important;
34
+ }
35
+ .editor-panel {
36
+ display: none;
37
+ }
38
+
39
+ .editor-panel--active {
40
+ display: block;
41
+ }
42
+
43
+ /* Editor utility header */
44
+ .editor-header {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 12px;
48
+ padding: 0 $space-4;
49
+ height: 60px;
50
+ background: #f9fafb;
51
+ border-bottom: 1px solid #e5e7eb;
52
+ }
53
+
54
+ .editor-header__title {
55
+ color: #111827;
56
+ font-weight: 600;
57
+ }
58
+
59
+ .editor-header__devices {
60
+ @include thin-scrollbar;
61
+ display: flex;
62
+ flex-direction: row;
63
+ align-items: stretch;
64
+ gap: 8px;
65
+ overflow: auto;
66
+ height: 60px;
67
+ padding: $space-1;
68
+ }
69
+
70
+ .editor-device-button {
71
+ position: relative;
72
+ min-width: 160px;
73
+ height: 100%;
74
+ border: 1px solid #e5e7eb;
75
+ border-radius: 6px;
76
+ background: #ffffff;
77
+ color: #111827;
78
+ cursor: pointer;
79
+ font-size: 12px;
80
+ &.editor-device-button--selected {
81
+ border-color: #000;
82
+ }
83
+ }
84
+
85
+ .editor-device-button img {
86
+ position: absolute;
87
+ bottom: 4px;
88
+ right: 4px;
89
+ width: 16px;
90
+ height: 16px;
91
+ }
92
+
93
+ .editor-header__actions {
94
+ margin-left: auto; /* push actions to the far right */
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 8px;
98
+ }
99
+
100
+ .editor-button {
101
+ display: inline-flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ height: 36px;
105
+ min-width: 120px; /* visible even without content */
106
+ padding: 0 12px;
107
+ border: 1px solid #e5e7eb;
108
+ border-radius: 6px;
109
+ background: #ffffff;
110
+ color: #111827;
111
+ cursor: pointer;
112
+ }
113
+
114
+ .editor-button:disabled {
115
+ opacity: 0.6;
116
+ cursor: default;
117
+ }
118
+
119
+ /* Specific hooks for save buttons (kept empty for now) */
120
+ .editor-save-button,
121
+ .editor-save-previewconfig-button {
122
+ color: #000;
123
+ font-weight: 600;
124
+ font-size: 12px;
125
+ }
126
+
127
+ /* Modal */
128
+ .editor-modal {
129
+ position: fixed;
130
+ inset: 0;
131
+ z-index: 1000;
132
+ }
133
+
134
+ .editor-modal__overlay {
135
+ position: absolute;
136
+ inset: 0;
137
+ background: rgba(0, 0, 0, 0.4);
138
+ }
139
+
140
+ .editor-modal__content {
141
+ position: absolute;
142
+ top: 50%;
143
+ left: 50%;
144
+ transform: translate(-50%, -50%);
145
+ background: #fff;
146
+ border-radius: 8px;
147
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
148
+ width: min(960px, calc(100vw - 40px));
149
+ max-height: calc(100vh - 120px);
150
+ display: flex;
151
+ flex-direction: column;
152
+ }
153
+
154
+ .editor-modal__header {
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: space-between;
158
+ padding: 12px 16px;
159
+ border-bottom: 1px solid #e5e7eb;
160
+ }
161
+
162
+ .editor-device-grid {
163
+ padding: 16px;
164
+ display: grid;
165
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
166
+ gap: 12px;
167
+ overflow: auto;
168
+ }
169
+
170
+ /* Reuse device button style inside modal grid */
171
+ .editor-device-grid .editor-device-button {
172
+ height: 80px;
173
+ min-width: unset;
174
+ }
@@ -0,0 +1,200 @@
1
+ @use './variables' as *;
2
+ @use './mixins' as *;
3
+ @use './reset';
4
+
5
+ /* Global utility classes */
6
+ html,
7
+ body,
8
+ #root {
9
+ font-family: $font-sans;
10
+ }
11
+
12
+ .editor-container {
13
+ height: 100vh;
14
+ width: 100vw;
15
+ display: flex;
16
+ overflow: hidden; /* Split panels manage their own scroll */
17
+ }
18
+ .editor-panel-builder {
19
+ padding: 4px 8px;
20
+ }
21
+ .app-shell {
22
+ min-height: 100vh;
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+
27
+ .app-main {
28
+ flex: 1 1 auto;
29
+ background: $color-background;
30
+ }
31
+
32
+ .page-bg {
33
+ background: $color-background;
34
+ }
35
+
36
+ .grid-cards {
37
+ display: grid;
38
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
39
+ gap: $space-4;
40
+ }
41
+
42
+ .btn-add {
43
+ height: 120px;
44
+ border: 2px dashed $color-muted;
45
+ border-radius: $radius-md;
46
+ background: #fff;
47
+ cursor: pointer;
48
+ font-weight: 600;
49
+ color: $color-text;
50
+ transition:
51
+ border-color 0.2s ease,
52
+ transform 0.1s ease,
53
+ box-shadow 0.2s ease;
54
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
55
+
56
+ &:hover {
57
+ border-color: darken($color-muted, 10%);
58
+ transform: translateY(-1px);
59
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
60
+ }
61
+ }
62
+
63
+ .split-left {
64
+ @include thin-scrollbar;
65
+ flex: 1 1 30%;
66
+ min-width: 0;
67
+ border-right: 1px solid $color-border;
68
+ overflow: auto;
69
+ }
70
+
71
+ .split-right {
72
+ position: relative;
73
+ flex: 1 1 45%;
74
+ min-width: 0;
75
+ max-height: calc(100vh - 120px);
76
+ overflow: auto;
77
+ }
78
+
79
+ .split-third {
80
+ flex: 1 1 25%;
81
+ min-width: 0;
82
+ border-right: 1px solid $color-border;
83
+ overflow: auto;
84
+ max-height: calc(100vh - 120px);
85
+ }
86
+
87
+ .split-right-background {
88
+ position: absolute;
89
+ inset: 0;
90
+ background-size: cover;
91
+ background-position: center;
92
+ background-repeat: repeat;
93
+ background-size: 500px auto;
94
+ opacity: 0.2;
95
+ }
96
+
97
+ .stage-wrapper {
98
+ display: flex;
99
+ justify-content: center;
100
+ background: $color-background;
101
+ padding: $space-4;
102
+ }
103
+
104
+ .stage {
105
+ @include card;
106
+ border: 1px solid $color-border;
107
+
108
+ .scroll-container {
109
+ /* Mobile-like scrollbar styling */
110
+ &::-webkit-scrollbar {
111
+ width: 8px;
112
+ height: 8px;
113
+ }
114
+
115
+ &::-webkit-scrollbar-track {
116
+ background: transparent;
117
+ }
118
+
119
+ &::-webkit-scrollbar-thumb {
120
+ background: rgba(0, 0, 0, 0.25);
121
+ border-radius: 8px;
122
+ }
123
+
124
+ /* For Firefox */
125
+ scrollbar-width: thin;
126
+ scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
127
+ }
128
+ }
129
+
130
+ /* Header */
131
+ .app-header {
132
+ position: sticky;
133
+ top: 0;
134
+ z-index: 10;
135
+ background: #fff;
136
+ border-bottom: 1px solid $color-border;
137
+ height: 60px;
138
+ padding: 0 $space-4;
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: space-between;
142
+
143
+ a {
144
+ color: $color-text;
145
+ text-decoration: none;
146
+ }
147
+ }
148
+
149
+ .app-header__brand {
150
+ font-weight: 700;
151
+ }
152
+
153
+ .app-header__nav {
154
+ display: flex;
155
+ gap: $space-4;
156
+ }
157
+ .warning {
158
+ color: $color-error;
159
+ font-size: 12px;
160
+ font-weight: 600;
161
+ margin-bottom: $space-4;
162
+ }
163
+
164
+ /* Breadcrumb */
165
+ .breadcrumb {
166
+ display: block;
167
+ font-size: 12px;
168
+ color: $color-muted;
169
+ }
170
+
171
+ .breadcrumb__list {
172
+ list-style: none;
173
+ padding: 0;
174
+ margin: 0;
175
+ display: flex;
176
+ align-items: center;
177
+ gap: $space-2;
178
+ }
179
+
180
+ .breadcrumb__item {
181
+ display: inline-flex;
182
+ align-items: center;
183
+ }
184
+
185
+ .breadcrumb__separator {
186
+ color: $color-border;
187
+ margin: 0 $space-1;
188
+ }
189
+
190
+ .breadcrumb__link {
191
+ color: $color-text;
192
+ text-decoration: none;
193
+ &:hover {
194
+ text-decoration: underline;
195
+ }
196
+ }
197
+
198
+ .breadcrumb__current {
199
+ color: $color-muted;
200
+ }
@@ -1,4 +1,11 @@
1
+ @use './variables' as *;
2
+ @use './mixins' as *;
1
3
  @use './reset';
4
+ @use './global.scss';
5
+ @use './pages.scss';
6
+ @use './components.scss';
7
+ @use './builder.scss';
8
+ @use './editor.scss';
2
9
 
3
10
  .embla {
4
11
  max-width: 48rem;
@@ -0,0 +1,2 @@
1
+ @use './variables' as *;
2
+ @use './mixins' as *;
@@ -1,17 +1,26 @@
1
- import { TargetedScreenSize } from './TargetedScreenSize';
2
-
3
- export interface PreviewConfig {
1
+ export interface AppConfig {
4
2
  theme: 'light' | 'dark';
5
- screenSize: TargetedScreenSize;
6
- isRtl: boolean;
3
+ isRtl: boolean; //This could be device in future
7
4
  screenStyle: {
8
5
  light: { backgroundColor: string; color: string; seperatorColor?: string };
9
6
  dark: { backgroundColor: string; color: string; seperatorColor?: string };
10
7
  };
11
8
  localication: Localication;
12
9
  defaultLanguage?: string;
10
+ baseSize: { width: number; height: number };
13
11
  }
14
12
 
13
+ export const defaultAppConfig: AppConfig = {
14
+ theme: 'light',
15
+ isRtl: false,
16
+ screenStyle: {
17
+ light: { backgroundColor: '#FDFDFD', color: '#161827' },
18
+ dark: { backgroundColor: '#12131A', color: '#E9EBF9' },
19
+ },
20
+ localication: {},
21
+ baseSize: { width: 375, height: 812 },
22
+ };
23
+
15
24
  export type Localication = {
16
25
  [key: string]: {
17
26
  [key: string]: string;
@@ -1,11 +1,11 @@
1
1
  import { Node } from '../types/Node';
2
- import { PreviewConfig } from './PreviewConfig';
2
+ import { AppConfig } from './PreviewConfig';
3
3
 
4
4
  export interface ProjectBase<T> {
5
5
  name: string;
6
6
  version: string;
7
7
  data: T;
8
- previewConfig?: PreviewConfig;
8
+ appConfig?: AppConfig;
9
9
  }
10
10
 
11
11
  export interface Project extends ProjectBase<Node> {}
@@ -0,0 +1,7 @@
1
+ import { useRenderStore } from '../store';
2
+ import { Node } from '../types/Node';
3
+
4
+ export function copyNode(node: Node) {
5
+ const { setCopiedNode } = useRenderStore.getState();
6
+ setCopiedNode(node);
7
+ }
@@ -7,8 +7,10 @@ export function extractTextStyle<T extends TextPropsGenerated['attributes']>(
7
7
  node: NodeData<T>,
8
8
  ) {
9
9
  const attributes = node.attributes;
10
-
11
- const { screenStyle, theme } = useRenderStore.getState();
10
+ //TODO: it should be passed as a prop to the function (need a state)
11
+ const {
12
+ appConfig: { screenStyle, theme },
13
+ } = useRenderStore.getState();
12
14
  const fallbackColor =
13
15
  theme === 'light' ? screenStyle.light.color : screenStyle.dark.color;
14
16
 
@@ -11,6 +11,7 @@ export function getDevices(): Device[] {
11
11
  return deviceList;
12
12
  }
13
13
 
14
+ //TODO: object instead of function
14
15
  export function getDefaultDevice(): Device {
15
16
  return getDevices()[0];
16
17
  }