@developer_tribe/react-builder 0.1.20 → 0.1.22

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.
@@ -0,0 +1 @@
1
+ .embla{max-width:48rem;margin:auto;--slide-height: 19rem;--slide-spacing: 1rem;--slide-size: 70%}.embla__viewport{overflow:hidden}.embla__container{display:flex;touch-action:pan-y pinch-zoom;margin-left:calc(var(--slide-spacing)*-1)}.embla__slide{transform:translate3d(0, 0, 0);flex:0 0 var(--slide-size);min-width:0;padding-left:var(--slide-spacing);flex:0 0 100%}.embla__slide__number{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);border-radius:1.8rem;font-size:4rem;font-weight:600;display:flex;align-items:center;justify-content:center;height:var(--slide-height);user-select:none}.embla__controls{display:grid;grid-template-columns:auto 1fr;justify-content:space-between;gap:1.2rem;margin-top:1.8rem}.embla__buttons{display:grid;grid-template-columns:repeat(2, 1fr);gap:.6rem;align-items:center}.embla__button{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:3.6rem;height:3.6rem;z-index:1;border-radius:50%;color:var(--text-body);display:flex;align-items:center;justify-content:center}.embla__button:disabled{color:var(--detail-high-contrast)}.embla__button__svg{width:35%;height:35%}.embla__dots{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;margin-right:0;height:50px}.embla__dot{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;width:2.6rem;height:2.6rem;display:flex;align-items:center;justify-content:center;border-radius:50%}.embla__dot:after{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:1.4rem;height:1.4rem;border-radius:50%;display:flex;align-items:center;content:""}.embla__dot--selected:after{box-shadow:inset 0 0 0 .2rem var(--text-body)}.carousel-provider{height:100%}.embla{height:100%}.embla__viewport{height:100%;display:flex;flex-direction:column}.embla__container{flex:1}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@developer_tribe/react-builder",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "restricted": true,
6
6
  "main": "dist/index.cjs.js",
@@ -1,10 +1,10 @@
1
1
  import React, { useContext } from 'react';
2
2
  import type { OnboardButtonComponentProps } from './OnboardButtonProps.generated';
3
- import { carouselContext } from '../CarouselProvider/CarouselProvider';
3
+ import { onboardContext } from '../OnboardProvider/OnboardProvider';
4
4
  import { mainNodeContext } from '../../RenderMainNode';
5
5
 
6
6
  function OnboardButton({ node }: OnboardButtonComponentProps) {
7
- const emblaApi = useContext(carouselContext);
7
+ const { emblaApi } = useContext(onboardContext) ?? {};
8
8
  const { localication, defaultLanguage } = useContext(mainNodeContext) ?? {};
9
9
 
10
10
  const labelRaw = node.attributes?.labelKey ?? '';
@@ -1,7 +1,7 @@
1
1
  import React, { useContext, useEffect, useState } from 'react';
2
2
  import type { Node } from '../../types/Node';
3
3
  import type { OnboardButtonsComponentProps } from './OnboardButtonsProps.generated';
4
- import { carouselContext } from '../CarouselProvider/CarouselProvider';
4
+ import { onboardContext } from '../OnboardProvider/OnboardProvider';
5
5
  import RenderNode from '../RenderNode.generated';
6
6
 
7
7
  const THEME_COLORS = {
@@ -9,22 +9,21 @@ const THEME_COLORS = {
9
9
  };
10
10
 
11
11
  function OnboardButtons({ node }: OnboardButtonsComponentProps) {
12
- const emblaApi = useContext(carouselContext);
13
- const [selectedIndex, setSelectedIndex] = useState(0);
12
+ const ctx = useContext(onboardContext) ?? {};
13
+ const emblaApi = ctx.emblaApi;
14
+ const [selectedIndex, setSelectedIndex] = useState(ctx.selectedIndex ?? 0);
14
15
 
15
16
  useEffect(() => {
16
- if (!emblaApi) return;
17
- setSelectedIndex(emblaApi.selectedScrollSnap());
18
- emblaApi.on('select', () => {
19
- setSelectedIndex(emblaApi.selectedScrollSnap());
20
- });
21
- }, [emblaApi]);
17
+ if (typeof ctx.selectedIndex === 'number') {
18
+ setSelectedIndex(ctx.selectedIndex);
19
+ }
20
+ }, [ctx.selectedIndex]);
22
21
 
23
- if (
24
- typeof node.attributes?.forIndex === 'number' &&
25
- node.attributes?.forIndex !== selectedIndex
26
- ) {
27
- return null;
22
+ // New condition logic: hide when condition is carousel-index and does not match
23
+ const condition = (node.attributes as any)?.condition;
24
+ const conditionVariable = (node.attributes as any)?.conditionVariable;
25
+ if (condition === 'carousel-index' && typeof conditionVariable === 'number') {
26
+ if (conditionVariable !== selectedIndex) return null;
28
27
  }
29
28
 
30
29
  const direction =
@@ -10,6 +10,8 @@ export interface OnboardButtonsPropsGenerated {
10
10
  buttons_direction?: 'row' | 'column';
11
11
  forIndex?: number;
12
12
  seperatorColor?: string;
13
+ condition?: 'carousel-index';
14
+ conditionVariable?: number;
13
15
  };
14
16
  }
15
17
 
@@ -9,7 +9,9 @@
9
9
  "skipNumber": "number",
10
10
  "buttons_direction": ["row", "column"],
11
11
  "forIndex": "number",
12
- "seperatorColor": "string"
12
+ "seperatorColor": "string",
13
+ "condition": ["carousel-index"],
14
+ "conditionVariable": "number"
13
15
  }
14
16
  }
15
17
  }
@@ -12,6 +12,11 @@ export interface OnboardDotPropsGenerated {
12
12
  | 'sliding_border'
13
13
  | 'sliding_dot'
14
14
  | 'liquid_like';
15
+ inactive_dot_opacity?: number;
16
+ expanding_dot_width?: number;
17
+ dot_style?: string;
18
+ container_style?: string;
19
+ active_dot_color?: string;
15
20
  };
16
21
  }
17
22
 
@@ -12,7 +12,12 @@
12
12
  "sliding_border",
13
13
  "sliding_dot",
14
14
  "liquid_like"
15
- ]
15
+ ],
16
+ "inactive_dot_opacity": "number",
17
+ "expanding_dot_width": "number",
18
+ "dot_style": "string",
19
+ "container_style": "string",
20
+ "active_dot_color": "string"
16
21
  }
17
22
  }
18
23
  }
@@ -1,12 +1,17 @@
1
- import React, { useContext, useEffect, useMemo, useState } from 'react';
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useEffect,
5
+ useMemo,
6
+ useState,
7
+ } from 'react';
2
8
  import type { NodeData } from '../../types/Node';
3
9
  import type { OnboardProviderComponentProps } from './OnboardProviderProps.generated';
4
- import { carouselContext } from '../CarouselProvider/CarouselProvider';
5
10
  import { mainNodeContext } from '../../RenderMainNode';
6
- import { isNodeArray } from '../../utils/analyseNode';
7
11
  import useEmblaCarousel from 'embla-carousel-react';
8
12
  import RenderNode from '../RenderNode.generated';
9
13
 
14
+ export const onboardContext = createContext<any>(undefined);
10
15
  function OnboardProvider({ node }: OnboardProviderComponentProps) {
11
16
  const [emblaRef, emblaApi] = useEmblaCarousel(node.attributes as any);
12
17
  const { theme, setWarning } = useContext(mainNodeContext) ?? {};
@@ -43,7 +48,7 @@ function OnboardProvider({ node }: OnboardProviderComponentProps) {
43
48
  }, [theme]);
44
49
 
45
50
  return (
46
- <carouselContext.Provider value={emblaApi}>
51
+ <onboardContext.Provider value={{ emblaApi, selectedIndex }}>
47
52
  <div className="carousel-provider">
48
53
  <div className="embla">
49
54
  <div className="embla__viewport" ref={emblaRef}>
@@ -51,7 +56,7 @@ function OnboardProvider({ node }: OnboardProviderComponentProps) {
51
56
  </div>
52
57
  </div>
53
58
  </div>
54
- </carouselContext.Provider>
59
+ </onboardContext.Provider>
55
60
  );
56
61
  }
57
62
 
@@ -77,6 +77,13 @@ function buildCarouselItem(
77
77
  const components = (page?.attributes?.components || []) as any[];
78
78
  const children: Node[] = [];
79
79
 
80
+ // Resolve page index for condition mapping
81
+ const currentKey = page?.attributes?.key as string | undefined;
82
+ const pageIndex =
83
+ typeof currentKey === 'string' && pageKeyToIndex.has(currentKey)
84
+ ? pageKeyToIndex.get(currentKey)!
85
+ : undefined;
86
+
80
87
  for (const comp of components) {
81
88
  if (comp?.layout === 'title-layout') {
82
89
  const title = comp?.attributes?.title_localization_key || '';
@@ -195,11 +202,14 @@ function buildCarouselItem(
195
202
  }
196
203
 
197
204
  if (buttonNodes.length > 0) {
198
- // Place buttons inside the page (OnboardItem) instead of provider level
199
- children.push({
205
+ // Place buttons at provider level with visibility conditioned by page index
206
+ providerLevelButtons.push({
200
207
  type: 'OnboardButtons',
201
208
  attributes: {
202
209
  ...(direction ? { buttons_direction: direction } : {}),
210
+ ...(typeof pageIndex === 'number'
211
+ ? { condition: 'carousel-index', conditionVariable: pageIndex }
212
+ : {}),
203
213
  },
204
214
  children: buttonNodes as unknown as Node,
205
215
  } as unknown as NodeData);
@@ -223,16 +233,52 @@ function mapDotsFromGeneralComponents(generalComponents: any[]): Node | null {
223
233
  const dots = generalComponents.find((gc) => gc?.layout === 'dots-layout');
224
234
  if (!dots) return null;
225
235
  const dotArray = dots?.attributes?.dot || [];
226
- const dotType = dotArray?.[0]?.layout as
236
+ const firstDot = dotArray?.[0];
237
+ const dotType = firstDot?.layout as
227
238
  | 'expanding_dot'
228
239
  | 'normal_dot'
229
240
  | 'scaling_dot'
230
241
  | 'sliding_border'
231
242
  | 'sliding_dot'
232
243
  | 'liquid_like';
244
+ const dotAttrs = (firstDot?.attributes || {}) as Record<string, unknown>;
245
+
246
+ const parseNumber = (value: unknown): number | undefined => {
247
+ if (typeof value === 'number') return value;
248
+ if (typeof value === 'string' && value.trim().length > 0) {
249
+ const n = Number(value);
250
+ return Number.isFinite(n) ? n : undefined;
251
+ }
252
+ return undefined;
253
+ };
254
+
255
+ const inactiveDotOpacity = parseNumber(dotAttrs?.inactive_dot_opacity);
256
+ const expandingDotWidth = parseNumber(dotAttrs?.expanding_dot_width);
257
+ const dot_style =
258
+ typeof dotAttrs?.dot_style === 'string'
259
+ ? (dotAttrs.dot_style as string)
260
+ : undefined;
261
+ const container_style =
262
+ typeof dotAttrs?.container_style === 'string'
263
+ ? (dotAttrs.container_style as string)
264
+ : undefined;
265
+ const active_dot_color =
266
+ typeof dotAttrs?.active_dot_color === 'string'
267
+ ? (dotAttrs.active_dot_color as string)
268
+ : undefined;
269
+
270
+ const attributes: Record<string, unknown> = {};
271
+ if (dotType) attributes.dotType = dotType;
272
+ if (inactiveDotOpacity !== undefined)
273
+ attributes.inactive_dot_opacity = inactiveDotOpacity;
274
+ if (expandingDotWidth !== undefined)
275
+ attributes.expanding_dot_width = expandingDotWidth;
276
+ if (dot_style) attributes.dot_style = dot_style;
277
+ if (container_style) attributes.container_style = container_style;
278
+ if (active_dot_color) attributes.active_dot_color = active_dot_color;
233
279
  return {
234
280
  type: 'OnboardDot',
235
- attributes: dotType ? { dotType } : undefined,
281
+ attributes: Object.keys(attributes).length ? attributes : undefined,
236
282
  children: undefined as unknown as Node,
237
283
  } as unknown as NodeData;
238
284
  }