@developer_tribe/react-builder 0.1.26 → 0.1.28

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 (76) hide show
  1. package/dist/RenderPage.d.ts +13 -13
  2. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +18 -4
  3. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +6 -1
  4. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +4 -0
  5. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +23 -0
  6. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +23 -0
  7. package/dist/build-components/Text/TextProps.generated.d.ts +23 -0
  8. package/dist/build-components/View/ViewProps.generated.d.ts +15 -3
  9. package/dist/build-components/index.d.ts +1 -0
  10. package/dist/build-components/patterns.generated.d.ts +389 -0
  11. package/dist/index.cjs.js +28 -1
  12. package/dist/index.d.ts +1 -2
  13. package/dist/index.esm.js +28 -1
  14. package/dist/size-matters/index.d.ts +6 -0
  15. package/dist/store.d.ts +25 -0
  16. package/dist/styles.css +1 -1
  17. package/dist/types/PreviewConfig.d.ts +2 -0
  18. package/dist/types/Project.d.ts +1 -1
  19. package/dist/utils/getDevices.d.ts +1 -0
  20. package/dist/utils/patterns.d.ts +3 -2
  21. package/package.json +2 -1
  22. package/scripts/prebuild/build-components.js +2 -0
  23. package/scripts/prebuild/utils/createBuildComponentsIndex.js +5 -1
  24. package/scripts/prebuild/utils/createPatternsGenerated.js +23 -0
  25. package/scripts/prebuild/utils/index.js +1 -0
  26. package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +126 -1
  27. package/src/RenderPage.tsx +33 -29
  28. package/src/assets/samples/getSamples.ts +5 -1
  29. package/src/build-components/Button/Button.tsx +2 -2
  30. package/src/build-components/Carousel/Carousel.tsx +2 -2
  31. package/src/build-components/CarouselButtons/CarouselButtons.tsx +2 -2
  32. package/src/build-components/CarouselDots/CarouselDots.tsx +2 -2
  33. package/src/build-components/CarouselItem/CarouselItem.tsx +2 -2
  34. package/src/build-components/CarouselProvider/CarouselProvider.tsx +2 -2
  35. package/src/build-components/Image/Image.tsx +2 -3
  36. package/src/build-components/Onboard/Onboard.tsx +2 -2
  37. package/src/build-components/OnboardButton/OnboardButton.tsx +7 -4
  38. package/src/build-components/OnboardButtons/OnboardButtons.tsx +14 -9
  39. package/src/build-components/OnboardDot/OnboardDot.tsx +2 -2
  40. package/src/build-components/OnboardFooter/OnboardFooter.tsx +22 -12
  41. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +29 -4
  42. package/src/build-components/OnboardFooter/pattern.json +4 -19
  43. package/src/build-components/OnboardImage/OnboardImage.tsx +2 -2
  44. package/src/build-components/OnboardItem/OnboardItem.tsx +20 -19
  45. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +6 -1
  46. package/src/build-components/OnboardItem/pattern.json +12 -1
  47. package/src/build-components/OnboardProvider/OnboardProvider.tsx +15 -12
  48. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +4 -0
  49. package/src/build-components/OnboardProvider/pattern.json +11 -1
  50. package/src/build-components/OnboardSubtitle/OnboardSubtitle.tsx +3 -17
  51. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +29 -0
  52. package/src/build-components/OnboardSubtitle/pattern.json +3 -18
  53. package/src/build-components/OnboardTitle/OnboardTitle.tsx +4 -17
  54. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +29 -0
  55. package/src/build-components/OnboardTitle/pattern.json +5 -19
  56. package/src/build-components/Text/Text.tsx +21 -9
  57. package/src/build-components/Text/TextProps.generated.ts +29 -0
  58. package/src/build-components/Text/pattern.json +1 -0
  59. package/src/build-components/View/View.tsx +3 -3
  60. package/src/build-components/View/ViewProps.generated.ts +15 -3
  61. package/src/build-components/View/pattern.json +15 -3
  62. package/src/build-components/index.ts +2 -0
  63. package/src/build-components/patterns.generated.ts +502 -0
  64. package/src/build-components/useNode.ts +1 -0
  65. package/src/index.ts +1 -2
  66. package/src/size-matters/index.ts +64 -0
  67. package/src/store.ts +56 -0
  68. package/src/styles/_reset.scss +30 -0
  69. package/src/styles/index.scss +2 -0
  70. package/src/types/PreviewConfig.ts +2 -2
  71. package/src/types/Project.ts +1 -1
  72. package/src/utils/getDevices.ts +4 -0
  73. package/src/utils/novaToJson.ts +189 -3
  74. package/src/utils/patterns.ts +14 -45
  75. package/dist/RenderMainNode.d.ts +0 -16
  76. package/src/RenderMainNode.tsx +0 -37
package/src/store.ts ADDED
@@ -0,0 +1,56 @@
1
+ import { createWithEqualityFn } from 'zustand/traditional';
2
+ import { shallow } from 'zustand/shallow';
3
+ import type { Device } from './types/Device';
4
+ import type { Localication } from './types/PreviewConfig';
5
+ import { getDefaultDevice } from './utils/getDevices';
6
+ import { ScreenStyle } from './RenderPage';
7
+
8
+ type RenderStore = {
9
+ device: Device;
10
+ localication: Localication | null;
11
+ defaultLanguage?: string;
12
+ baseSize: {
13
+ width: number;
14
+ height: number;
15
+ };
16
+ theme: 'dark' | 'light';
17
+ screenStyle: ScreenStyle;
18
+ setBaseSize: (baseSize: { width: number; height: number }) => void;
19
+ setDevice: (device: Device) => void;
20
+ setLocalication: (localication: Localication | null) => void;
21
+ setDefaultLanguage: (defaultLanguage?: string) => void;
22
+ setTheme: (theme: 'dark' | 'light') => void;
23
+ setScreenStyle: (screenStyle: ScreenStyle) => void;
24
+ };
25
+
26
+ export const useRenderStore = createWithEqualityFn<RenderStore>()(
27
+ (set) => ({
28
+ device: getDefaultDevice(),
29
+ localication: null,
30
+ defaultLanguage: undefined,
31
+ baseSize: {
32
+ width: 390,
33
+ height: 844,
34
+ },
35
+ theme: 'light',
36
+ screenStyle: {
37
+ light: {
38
+ backgroundColor: '#FDFDFD',
39
+ color: '#161827',
40
+ seperatorColor: '#E5E7EB',
41
+ },
42
+ dark: {
43
+ backgroundColor: '#12131A',
44
+ color: '#E9EBF9',
45
+ seperatorColor: '#E5E7EB',
46
+ },
47
+ },
48
+ setBaseSize: (baseSize) => set({ baseSize }),
49
+ setDevice: (device) => set({ device }),
50
+ setLocalication: (localication) => set({ localication }),
51
+ setDefaultLanguage: (defaultLanguage) => set({ defaultLanguage }),
52
+ setTheme: (theme) => set({ theme }),
53
+ setScreenStyle: (screenStyle) => set({ screenStyle }),
54
+ }),
55
+ shallow,
56
+ );
@@ -0,0 +1,30 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ }
6
+ html,
7
+ body,
8
+ #root {
9
+ height: 100%;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+ body {
14
+ background: #fff;
15
+ //font-family: $font-sans;
16
+ -webkit-font-smoothing: antialiased;
17
+ -moz-osx-font-smoothing: grayscale;
18
+ overflow: hidden; /* Prevent page scroll; panels will handle their own scroll */
19
+ }
20
+ button {
21
+ font-family: inherit;
22
+ }
23
+ input,
24
+ button {
25
+ font-size: 100%;
26
+ }
27
+ p {
28
+ margin: 0;
29
+ padding: 0;
30
+ }
@@ -1,3 +1,5 @@
1
+ @use './reset';
2
+
1
3
  .embla {
2
4
  max-width: 48rem;
3
5
  margin: auto;
@@ -5,8 +5,8 @@ export interface PreviewConfig {
5
5
  screenSize: TargetedScreenSize;
6
6
  isRtl: boolean;
7
7
  screenStyle: {
8
- light: { backgroundColor: string; color: string };
9
- dark: { backgroundColor: string; color: string };
8
+ light: { backgroundColor: string; color: string; seperatorColor?: string };
9
+ dark: { backgroundColor: string; color: string; seperatorColor?: string };
10
10
  };
11
11
  localication: Localication;
12
12
  defaultLanguage?: string;
@@ -5,7 +5,7 @@ export interface ProjectBase<T> {
5
5
  name: string;
6
6
  version: string;
7
7
  data: T;
8
- previewConfig: PreviewConfig;
8
+ previewConfig?: PreviewConfig;
9
9
  }
10
10
 
11
11
  export interface Project extends ProjectBase<Node> {}
@@ -10,3 +10,7 @@ export function getDevices(): Device[] {
10
10
  });
11
11
  return deviceList;
12
12
  }
13
+
14
+ export function getDefaultDevice(): Device {
15
+ return getDevices()[0];
16
+ }
@@ -95,17 +95,65 @@ function buildCarouselItem(
95
95
  if (comp?.layout === 'title-layout') {
96
96
  const title = comp?.attributes?.title_localization_key || '';
97
97
  const color = comp?.attributes?.title_color || undefined;
98
+ const {
99
+ fontSize: titleFontSize,
100
+ textAlign: titleTextAlign,
101
+ marginTop: titleMarginTop,
102
+ fontWeight: titleFontWeight,
103
+ } = extractTextStyleAttributesFromComponent(comp);
98
104
  children.push({
99
105
  type: 'OnboardTitle',
100
- attributes: color ? { color } : undefined,
106
+ attributes:
107
+ color ||
108
+ titleFontSize ||
109
+ titleTextAlign ||
110
+ titleMarginTop ||
111
+ titleFontWeight
112
+ ? {
113
+ ...(color ? { color } : {}),
114
+ ...(typeof titleFontSize === 'number'
115
+ ? { fontSize: titleFontSize }
116
+ : {}),
117
+ ...(titleTextAlign ? { textAlign: titleTextAlign } : {}),
118
+ ...(typeof titleMarginTop === 'number'
119
+ ? { marginTop: titleMarginTop }
120
+ : {}),
121
+ ...(titleFontWeight ? { fontWeight: titleFontWeight } : {}),
122
+ }
123
+ : undefined,
101
124
  children: title,
102
125
  });
103
126
  } else if (comp?.layout === 'subtitle-layout') {
104
127
  const subtitle = comp?.attributes?.subtitle_localization_key || '';
105
128
  const color = comp?.attributes?.subtitle_color || undefined;
129
+ const {
130
+ fontSize: subtitleFontSize,
131
+ textAlign: subtitleTextAlign,
132
+ marginTop: subtitleMarginTop,
133
+ fontWeight: subtitleFontWeight,
134
+ } = extractTextStyleAttributesFromComponent(comp);
106
135
  children.push({
107
136
  type: 'OnboardSubtitle',
108
- attributes: color ? { color } : undefined,
137
+ attributes:
138
+ color ||
139
+ subtitleFontSize ||
140
+ subtitleTextAlign ||
141
+ subtitleMarginTop ||
142
+ subtitleFontWeight
143
+ ? {
144
+ ...(color ? { color } : {}),
145
+ ...(typeof subtitleFontSize === 'number'
146
+ ? { fontSize: subtitleFontSize }
147
+ : {}),
148
+ ...(subtitleTextAlign ? { textAlign: subtitleTextAlign } : {}),
149
+ ...(typeof subtitleMarginTop === 'number'
150
+ ? { marginTop: subtitleMarginTop }
151
+ : {}),
152
+ ...(subtitleFontWeight
153
+ ? { fontWeight: subtitleFontWeight }
154
+ : {}),
155
+ }
156
+ : undefined,
109
157
  children: subtitle,
110
158
  });
111
159
  } else if (comp?.layout === 'image-layout') {
@@ -121,13 +169,20 @@ function buildCarouselItem(
121
169
  ? rawHeight
122
170
  : undefined;
123
171
 
172
+ // derive resizeMode from is_bg_image and try to extract borderRadius from styles
173
+ const isBgImage = Boolean(comp?.attributes?.is_bg_image);
174
+ const imageStyle = extractViewStyleAttributesFromComponent(comp);
175
+
124
176
  if (src) {
125
177
  children.push({
126
178
  type: 'OnboardImage',
127
179
  attributes: {
128
180
  src,
129
181
  ...(height ? { height } : {}),
130
- resizeMode: 'contain',
182
+ resizeMode: isBgImage ? 'cover' : 'contain',
183
+ ...(typeof imageStyle.borderRadius === 'number'
184
+ ? { borderRadius: imageStyle.borderRadius }
185
+ : {}),
131
186
  },
132
187
  children: undefined as unknown as Node,
133
188
  } as unknown as NodeData);
@@ -236,6 +291,137 @@ function buildCarouselItem(
236
291
  };
237
292
  }
238
293
 
294
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
295
+ function extractTextStyleAttributesFromComponent(comp: any): {
296
+ fontSize?: number;
297
+ textAlign?: 'left' | 'center' | 'right' | 'justify';
298
+ marginTop?: number;
299
+ fontWeight?:
300
+ | 'normal'
301
+ | 'bold'
302
+ | '100'
303
+ | '200'
304
+ | '300'
305
+ | '400'
306
+ | '500'
307
+ | '600'
308
+ | '700'
309
+ | '800'
310
+ | '900';
311
+ } {
312
+ const result: {
313
+ fontSize?: number;
314
+ textAlign?: 'left' | 'center' | 'right' | 'justify';
315
+ marginTop?: number;
316
+ fontWeight?:
317
+ | 'normal'
318
+ | 'bold'
319
+ | '100'
320
+ | '200'
321
+ | '300'
322
+ | '400'
323
+ | '500'
324
+ | '600'
325
+ | '700'
326
+ | '800'
327
+ | '900';
328
+ } = {};
329
+
330
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
331
+ const stylesRoot = (comp?.attributes?.styles || []) as any[];
332
+ if (!Array.isArray(stylesRoot) || stylesRoot.length === 0) return result;
333
+
334
+ const allowedAligns = new Set(['left', 'center', 'right', 'justify']);
335
+ const allowedWeights = new Set([
336
+ 'normal',
337
+ 'bold',
338
+ '100',
339
+ '200',
340
+ '300',
341
+ '400',
342
+ '500',
343
+ '600',
344
+ '700',
345
+ '800',
346
+ '900',
347
+ ]);
348
+
349
+ for (const s of stylesRoot) {
350
+ if (s?.layout !== 'style-layout') continue;
351
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
352
+ const nested = (s?.attributes?.styles || []) as any[];
353
+ if (!Array.isArray(nested)) continue;
354
+ for (const st of nested) {
355
+ if (st?.layout !== 'Styles') continue;
356
+ const type = st?.attributes?.type;
357
+ if (type !== 'textStyle') continue;
358
+ const style = st?.attributes?.style || {};
359
+
360
+ const rawFontSize = style?.fontSize;
361
+ if (typeof rawFontSize === 'number' && Number.isFinite(rawFontSize)) {
362
+ result.fontSize = rawFontSize;
363
+ } else if (typeof rawFontSize === 'string') {
364
+ const n = Number.parseInt(rawFontSize, 10);
365
+ if (Number.isFinite(n)) result.fontSize = n;
366
+ }
367
+
368
+ const align = style?.textAlign;
369
+ if (typeof align === 'string' && allowedAligns.has(align)) {
370
+ result.textAlign = align as typeof result.textAlign;
371
+ }
372
+
373
+ const rawMarginTop = style?.marginTop;
374
+ if (typeof rawMarginTop === 'number' && Number.isFinite(rawMarginTop)) {
375
+ result.marginTop = rawMarginTop;
376
+ } else if (typeof rawMarginTop === 'string') {
377
+ const n = Number.parseInt(rawMarginTop, 10);
378
+ if (Number.isFinite(n)) result.marginTop = n;
379
+ }
380
+
381
+ const rawWeight = style?.fontWeight;
382
+ let normalizedWeight: string | undefined;
383
+ if (typeof rawWeight === 'number' && Number.isFinite(rawWeight)) {
384
+ normalizedWeight = String(rawWeight);
385
+ } else if (typeof rawWeight === 'string') {
386
+ normalizedWeight = rawWeight;
387
+ }
388
+ if (normalizedWeight && allowedWeights.has(normalizedWeight)) {
389
+ result.fontWeight = normalizedWeight as typeof result.fontWeight;
390
+ }
391
+ }
392
+ }
393
+
394
+ return result;
395
+ }
396
+
397
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
398
+ function extractViewStyleAttributesFromComponent(comp: any): {
399
+ borderRadius?: number;
400
+ } {
401
+ const result: { borderRadius?: number } = {};
402
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
403
+ const stylesRoot = (comp?.attributes?.styles || []) as any[];
404
+ if (!Array.isArray(stylesRoot) || stylesRoot.length === 0) return result;
405
+ for (const s of stylesRoot) {
406
+ if (s?.layout !== 'style-layout') continue;
407
+ //@eslint-disable-next-line @typescript-eslint/no-explicit-any
408
+ const nested = (s?.attributes?.styles || []) as any[];
409
+ if (!Array.isArray(nested)) continue;
410
+ for (const st of nested) {
411
+ if (st?.layout !== 'Styles') continue;
412
+ const style = st?.attributes?.style || {};
413
+ const rawBr = style?.borderRadius;
414
+ if (typeof rawBr === 'number' && Number.isFinite(rawBr)) {
415
+ result.borderRadius = rawBr;
416
+ } else if (typeof rawBr === 'string') {
417
+ const n = Number.parseInt(rawBr, 10);
418
+ if (Number.isFinite(n)) result.borderRadius = n;
419
+ }
420
+ }
421
+ }
422
+ return result;
423
+ }
424
+
239
425
  function mapDotsFromGeneralComponents(generalComponents: any[]): Node | null {
240
426
  const dots = generalComponents.find((gc) => gc?.layout === 'dots-layout');
241
427
  if (!dots) return null;
@@ -1,65 +1,34 @@
1
- import imagePattern from '../build-components/Image/pattern.json';
2
- import textPattern from '../build-components/Text/pattern.json';
3
- import buttonPattern from '../build-components/Button/pattern.json';
4
- import viewPattern from '../build-components/View/pattern.json';
5
- import carouselPattern from '../build-components/Carousel/pattern.json';
6
- import carouselButtonsPattern from '../build-components/CarouselButtons/pattern.json';
7
- import carouselDotsPattern from '../build-components/CarouselDots/pattern.json';
8
- import carouselItemPattern from '../build-components/CarouselItem/pattern.json';
9
- import carouselProviderPattern from '../build-components/CarouselProvider/pattern.json';
10
- import onboardPattern from '../build-components/Onboard/pattern.json';
11
- import onboardProviderPattern from '../build-components/OnboardProvider/pattern.json';
12
- import onboardItemPattern from '../build-components/OnboardItem/pattern.json';
13
- import onboardImagePattern from '../build-components/OnboardImage/pattern.json';
14
- import onboardButtonsPattern from '../build-components/OnboardButtons/pattern.json';
15
- import onboardButtonPattern from '../build-components/OnboardButton/pattern.json';
16
- import OnboardTitlePattern from '../build-components/OnboardTitle/pattern.json';
17
- import onboardSubtitlePattern from '../build-components/OnboardSubtitle/pattern.json';
18
- import onboardFooterPattern from '../build-components/OnboardFooter/pattern.json';
19
- import onboardExpandingDotPattern from '../build-components/OnboardDot/pattern.json';
1
+ import { patterns as generatedPatterns } from '../build-components';
20
2
  import type { NodeDefaultAttribute } from '../types/Node';
21
3
 
22
4
  type Pattern = {
23
5
  schemaVersion: number;
24
6
  allowUnknownAttributes: boolean;
7
+ extends: string;
25
8
  pattern: {
26
9
  type: string;
27
10
  children: unknown;
28
- attributes: Record<string, string | string[]>;
11
+ attributes?: Record<string, string | string[]>;
29
12
  };
13
+ defaults?: NodeDefaultAttribute;
14
+
30
15
  // Optional custom complex types referenced by attributes like "X[]" or "X"
31
16
  // Each entry maps a type name (e.g., "EventObject") to its field schema
32
17
  // where the inner record maps fieldName -> primitive type or enum options
33
18
  types?: Record<string, Record<string, string | string[]>>;
34
19
  // Optional defaults to be applied to node.attributes if not provided
35
- defaults?: NodeDefaultAttribute;
36
20
  };
37
21
 
38
- const patterns: Pattern[] = [
39
- imagePattern as Pattern,
40
- textPattern as Pattern,
41
- buttonPattern as Pattern,
42
- viewPattern as Pattern,
43
- carouselPattern as Pattern,
44
- carouselButtonsPattern as Pattern,
45
- carouselDotsPattern as Pattern,
46
- carouselItemPattern as Pattern,
47
- carouselProviderPattern as Pattern,
48
- onboardPattern as Pattern,
49
- onboardProviderPattern as Pattern,
50
- onboardItemPattern as Pattern,
51
- onboardImagePattern as Pattern,
52
- onboardButtonsPattern as Pattern,
53
- onboardButtonPattern as Pattern,
54
- OnboardTitlePattern as Pattern,
55
- onboardSubtitlePattern as Pattern,
56
- onboardFooterPattern as Pattern,
57
- onboardExpandingDotPattern as Pattern,
58
- ];
22
+ const patterns: Pattern[] = generatedPatterns as unknown as Pattern[];
23
+
24
+ // Build a fast lookup map without normalization for direct access
25
+ const patternIndex: Map<string, Pattern> = new Map(
26
+ patterns.map((p) => [p.pattern.type, p]),
27
+ );
59
28
 
60
- export function getPatternByType(type?: string | null) {
61
- if (!type) return undefined;
62
- return patterns.find((p) => p.pattern.type === type);
29
+ export function getPatternByType(type?: string | null): Pattern | undefined {
30
+ if (typeof type !== 'string') return undefined;
31
+ return patternIndex.get(type);
63
32
  }
64
33
 
65
34
  export function getAttributeSchema(
@@ -1,16 +0,0 @@
1
- import { Localication } from './types/PreviewConfig';
2
- export declare const mainNodeContext: import("react").Context<{
3
- localication?: Localication;
4
- defaultLanguage?: string;
5
- theme?: "light" | "dark";
6
- warning?: string;
7
- setWarning?: (message: string) => void;
8
- } | null>;
9
- export declare function RenderMainNode({ children, localication, defaultLanguage, theme, }: {
10
- localication?: Localication;
11
- defaultLanguage?: string;
12
- theme?: 'light' | 'dark';
13
- children: React.ReactNode;
14
- warning?: string;
15
- setWarning?: (message: string) => void;
16
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,37 +0,0 @@
1
- import { createContext, useState } from 'react';
2
- import { Node } from './index';
3
-
4
- import { Localication } from './types/PreviewConfig';
5
- import RenderNode from './build-components/RenderNode.generated';
6
- export const mainNodeContext = createContext<{
7
- localication?: Localication;
8
- defaultLanguage?: string;
9
- theme?: 'light' | 'dark';
10
- warning?: string;
11
- setWarning?: (message: string) => void;
12
- } | null>(null);
13
-
14
- export function RenderMainNode({
15
- children,
16
- localication,
17
- defaultLanguage,
18
- theme,
19
- }: {
20
- localication?: Localication;
21
- defaultLanguage?: string;
22
- theme?: 'light' | 'dark';
23
- children: React.ReactNode;
24
- warning?: string;
25
- setWarning?: (message: string) => void;
26
- }) {
27
- const [warning, setWarning] = useState<string>('');
28
-
29
- return (
30
- <mainNodeContext.Provider
31
- value={{ localication, defaultLanguage, theme, warning, setWarning }}
32
- >
33
- {warning && <div className="warning">{warning}</div>}
34
- {children}
35
- </mainNodeContext.Provider>
36
- );
37
- }