@developer_tribe/react-builder 1.2.13 → 1.2.15
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.
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +2 -0
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +2 -0
- package/dist/build-components/Button/ButtonProps.generated.d.ts +2 -0
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +2 -0
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +2 -0
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +2 -0
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +2 -0
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +2 -0
- package/dist/build-components/CountDown/CountDown.d.ts +2 -0
- package/dist/build-components/CountDown/CountDownProps.generated.d.ts +61 -0
- package/dist/build-components/CountDown/formatCountdownTime.d.ts +1 -0
- package/dist/build-components/Counter/Counter.d.ts +2 -0
- package/dist/build-components/Counter/CounterProps.generated.d.ts +61 -0
- package/dist/build-components/Image/ImageProps.generated.d.ts +2 -0
- package/dist/build-components/Main/MainProps.generated.d.ts +2 -0
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +2 -0
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +2 -0
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +2 -0
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +2 -0
- package/dist/build-components/PaywallCounter/PaywallCounter.d.ts +2 -0
- package/dist/build-components/PaywallCounter/PaywallCounterProps.generated.d.ts +61 -0
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +2 -0
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +2 -0
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +2 -0
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +2 -0
- package/dist/build-components/Text/TextProps.generated.d.ts +2 -0
- package/dist/build-components/View/ViewProps.generated.d.ts +2 -0
- package/dist/build-components/index.d.ts +4 -1
- package/dist/build-components/patterns.generated.d.ts +2961 -1552
- package/dist/components/BuilderProvider.d.ts +0 -1
- package/dist/index.cjs.js +4 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +4 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.d.ts +7 -0
- package/dist/index.web.cjs.js +7 -5
- package/dist/index.web.cjs.js.map +1 -1
- package/dist/index.web.esm.js +7 -5
- package/dist/index.web.esm.js.map +1 -1
- package/dist/utils/getDefaultProject.d.ts +4 -0
- package/dist/utils/patterns.d.ts +3 -0
- package/package.json +2 -1
- package/scripts/prebuild/utils/createComponentTsx.js +1 -1
- package/scripts/prebuild/utils/createGeneratedProps.js +6 -2
- package/scripts/prebuild/utils/createRenderNodeGenerated.js +26 -5
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +17 -5
- package/scripts/prebuild/utils/validateExistingComponentTsx.js +12 -8
- package/src/AttributesEditor.tsx +7 -2
- package/src/RenderPage.tsx +34 -3
- package/src/assets/meta.json +1 -1
- package/src/assets/samples/carousel-sample.json +44 -14
- package/src/assets/samples/getSamples.ts +3 -1
- package/src/assets/samples/paywall-1.json +73 -29
- package/src/assets/samples/paywall-2.json +338 -0
- package/src/assets/samples/simple-1.json +9 -3
- package/src/assets/samples/simple-2.json +72 -24
- package/src/assets/samples/unmigrated-builder-1.1.1.json +19 -7
- package/src/assets/samples/unmigrated-builder1.json +10 -4
- package/src/assets/samples/unvalidated-builder1.json +10 -4
- package/src/assets/samples/unvalidated-crash1.json +3 -1
- package/src/assets/samples/unvalidated-crashcomponent1.json +3 -1
- package/src/assets/samples/vpn-onboard-1.json +88 -40
- package/src/assets/samples/vpn-onboard-2.json +85 -37
- package/src/assets/samples/vpn-onboard-3.json +93 -45
- package/src/assets/samples/vpn-onboard-4.json +93 -45
- package/src/assets/samples/vpn-onboard-5.json +121 -53
- package/src/assets/samples/vpn-onboard-6.json +93 -45
- package/src/attributes-editor/AttributesEditorView.tsx +39 -1
- package/src/attributes-editor/Field.tsx +30 -0
- package/src/build-components/BIcon/BIconProps.generated.ts +2 -0
- package/src/build-components/BIcon/pattern.json +2 -0
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +0 -1
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +2 -0
- package/src/build-components/BackgroundImage/pattern.json +2 -0
- package/src/build-components/Button/ButtonProps.generated.ts +2 -0
- package/src/build-components/Button/pattern.json +2 -0
- package/src/build-components/Carousel/CarouselProps.generated.ts +2 -0
- package/src/build-components/Carousel/pattern.json +2 -0
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +2 -0
- package/src/build-components/CarouselButtons/pattern.json +2 -0
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +2 -0
- package/src/build-components/CarouselDots/pattern.json +2 -0
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +2 -0
- package/src/build-components/CarouselItem/pattern.json +4 -1
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +2 -0
- package/src/build-components/CarouselProvider/pattern.json +4 -1
- package/src/build-components/CountDown/CountDown.tsx +73 -0
- package/src/build-components/CountDown/CountDownProps.generated.ts +78 -0
- package/src/build-components/CountDown/formatCountdownTime.ts +10 -0
- package/src/build-components/CountDown/pattern.json +24 -0
- package/src/build-components/Counter/Counter.tsx +44 -0
- package/src/build-components/Counter/CounterProps.generated.ts +78 -0
- package/src/build-components/Counter/pattern.json +26 -0
- package/src/build-components/Image/ImageProps.generated.ts +2 -0
- package/src/build-components/Image/pattern.json +2 -0
- package/src/build-components/Main/MainProps.generated.ts +2 -0
- package/src/build-components/Main/pattern.json +2 -0
- package/src/build-components/Onboard/OnboardProps.generated.ts +2 -0
- package/src/build-components/Onboard/pattern.json +4 -1
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +2 -0
- package/src/build-components/OnboardButton/pattern.json +2 -0
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +2 -0
- package/src/build-components/OnboardButtons/pattern.json +2 -0
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +2 -0
- package/src/build-components/OnboardDot/pattern.json +2 -0
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +2 -0
- package/src/build-components/OnboardFooter/pattern.json +2 -0
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +2 -0
- package/src/build-components/OnboardImage/pattern.json +2 -0
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +2 -0
- package/src/build-components/OnboardItem/pattern.json +2 -0
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +2 -0
- package/src/build-components/OnboardProvider/pattern.json +2 -0
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +2 -0
- package/src/build-components/OnboardSubtitle/pattern.json +4 -1
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +2 -0
- package/src/build-components/OnboardTitle/pattern.json +4 -1
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +2 -0
- package/src/build-components/PaywallBackground/pattern.json +4 -1
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +7 -5
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +2 -0
- package/src/build-components/PaywallCloseButton/pattern.json +4 -1
- package/src/build-components/PaywallCounter/PaywallCounter.tsx +49 -0
- package/src/build-components/PaywallCounter/PaywallCounterProps.generated.ts +78 -0
- package/src/build-components/PaywallCounter/pattern.json +24 -0
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +2 -0
- package/src/build-components/PaywallOptions/pattern.json +4 -1
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +8 -16
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +2 -0
- package/src/build-components/PaywallProvider/pattern.json +4 -1
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +2 -0
- package/src/build-components/PaywallSubscribeButton/pattern.json +4 -1
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +2 -0
- package/src/build-components/RadioButton/pattern.json +2 -0
- package/src/build-components/RenderNode.generated.tsx +17 -2
- package/src/build-components/Text/TextProps.generated.ts +2 -0
- package/src/build-components/Text/pattern.json +3 -1
- package/src/build-components/View/View.tsx +1 -1
- package/src/build-components/View/ViewProps.generated.ts +2 -0
- package/src/build-components/View/pattern.json +35 -38
- package/src/build-components/index.ts +15 -0
- package/src/build-components/patterns.generated.ts +3084 -1570
- package/src/components/BuilderButton.tsx +23 -6
- package/src/components/BuilderProvider.tsx +10 -7
- package/src/index.native.ts +7 -0
- package/src/index.ts +1 -0
- package/src/mockOS/context/MockOSContext.tsx +22 -8
- package/src/mockOS/managers/navigationManager.ts +4 -0
- package/src/pages/projectPageUtils.ts +3 -2
- package/src/utils/analyseNodeByPatterns.ts +21 -0
- package/src/utils/getDefaultProject.ts +34 -0
- package/src/utils/patterns.ts +6 -7
package/dist/utils/patterns.d.ts
CHANGED
|
@@ -5,7 +5,10 @@ export type AttributeMeta = {
|
|
|
5
5
|
category?: 'style' | 'container' | 'other' | string;
|
|
6
6
|
specialCategory?: 'padding' | 'margin' | 'offset' | null | string;
|
|
7
7
|
sort?: number;
|
|
8
|
+
/** Legacy typo kept for backwards compatibility with older patterns. */
|
|
8
9
|
preferedScale?: 's' | 'vs' | 'f' | '%' | '' | string;
|
|
10
|
+
/** Correct spelling. Prefer this in new/updated patterns. */
|
|
11
|
+
preferredScale?: 's' | 'vs' | 'f' | '%' | '' | string;
|
|
9
12
|
/**
|
|
10
13
|
* When true, this attribute should remain visible even if the component
|
|
11
14
|
* metadata requests hiding all attributes (e.g. `meta.hideAllAttributes`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@developer_tribe/react-builder",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"restricted": true,
|
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"axios": "^1.12.2",
|
|
111
|
+
"moment": "^2.30.1",
|
|
111
112
|
"react-toastify": "^11.0.5"
|
|
112
113
|
},
|
|
113
114
|
"resolutions": {
|
|
@@ -18,7 +18,7 @@ export async function createComponentTsx(componentDir, componentName) {
|
|
|
18
18
|
` node = useNode(node);\n` +
|
|
19
19
|
` return null;\n` +
|
|
20
20
|
`}\n\n` +
|
|
21
|
-
`export
|
|
21
|
+
`export { ${componentName} };\n`;
|
|
22
22
|
const formatted = await formatWithPrettier(content);
|
|
23
23
|
await fs.writeFile(filePath, formatted, 'utf8');
|
|
24
24
|
}
|
|
@@ -12,13 +12,17 @@ const isPrimitive = t =>
|
|
|
12
12
|
t === 'size' ||
|
|
13
13
|
t === 'fontFamily' ||
|
|
14
14
|
t === 'fontWeight' ||
|
|
15
|
-
t === 'iconType'
|
|
15
|
+
t === 'iconType' ||
|
|
16
|
+
t === 'title' ||
|
|
17
|
+
t === 'description';
|
|
16
18
|
const toTsPrimitive = t =>
|
|
17
19
|
t === 'color' ||
|
|
18
20
|
t === 'size' ||
|
|
19
21
|
t === 'iconType' ||
|
|
20
22
|
t === 'fontFamily' ||
|
|
21
|
-
t === 'fontWeight'
|
|
23
|
+
t === 'fontWeight' ||
|
|
24
|
+
t === 'title' ||
|
|
25
|
+
t === 'description'
|
|
22
26
|
? 'string'
|
|
23
27
|
: t;
|
|
24
28
|
const getArrayItem = t =>
|
|
@@ -10,13 +10,34 @@ export async function createRenderNodeGenerated(validated, paths) {
|
|
|
10
10
|
validated.find(v => v.componentName === 'Text')?.patternJson?.pattern
|
|
11
11
|
?.type ?? 'Text';
|
|
12
12
|
|
|
13
|
+
async function resolveComponentImport(componentName) {
|
|
14
|
+
const filePath = path.join(
|
|
15
|
+
COMPONENTS_ROOT,
|
|
16
|
+
componentName,
|
|
17
|
+
`${componentName}.tsx`
|
|
18
|
+
);
|
|
19
|
+
const content = await fs.readFile(filePath, 'utf8').catch(() => '');
|
|
20
|
+
const hasNamedExport =
|
|
21
|
+
new RegExp(`export\\s+function\\s+${componentName}\\s*\\(`).test(
|
|
22
|
+
content
|
|
23
|
+
) ||
|
|
24
|
+
new RegExp(`export\\s*\\{[^}]*\\b${componentName}\\b[^}]*\\}`).test(
|
|
25
|
+
content
|
|
26
|
+
);
|
|
27
|
+
if (hasNamedExport) {
|
|
28
|
+
return `import { ${componentName} } from './${componentName}/${componentName}';`;
|
|
29
|
+
}
|
|
30
|
+
return `import ${componentName} from './${componentName}/${componentName}';`;
|
|
31
|
+
}
|
|
32
|
+
|
|
13
33
|
// Build imports for all components discovered
|
|
14
|
-
const componentImports =
|
|
15
|
-
.
|
|
16
|
-
({ componentName }) =>
|
|
17
|
-
|
|
34
|
+
const componentImports = (
|
|
35
|
+
await Promise.all(
|
|
36
|
+
validated.map(({ componentName }) =>
|
|
37
|
+
resolveComponentImport(componentName)
|
|
38
|
+
)
|
|
18
39
|
)
|
|
19
|
-
|
|
40
|
+
).join('\n');
|
|
20
41
|
|
|
21
42
|
// Import each component's generated prop type so we can build a strongly-typed node union
|
|
22
43
|
const componentPropTypeImports = validated
|
|
@@ -135,7 +135,9 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
135
135
|
t === 'size' ||
|
|
136
136
|
t === 'fontFamily' ||
|
|
137
137
|
t === 'fontWeight' ||
|
|
138
|
-
t === 'iconType'
|
|
138
|
+
t === 'iconType' ||
|
|
139
|
+
t === 'title' ||
|
|
140
|
+
t === 'description';
|
|
139
141
|
const isNeverType = t => t === 'never';
|
|
140
142
|
const hasCustomTypes = typeof data.types === 'object' && data.types != null;
|
|
141
143
|
const isCustomType = t =>
|
|
@@ -354,8 +356,12 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
354
356
|
const parentMeta = parentData?.meta ?? undefined;
|
|
355
357
|
const childMeta = data?.meta ?? undefined;
|
|
356
358
|
|
|
357
|
-
const parentStyles = isPlainObject(parentMeta?.styles)
|
|
358
|
-
|
|
359
|
+
const parentStyles = isPlainObject(parentMeta?.styles)
|
|
360
|
+
? parentMeta.styles
|
|
361
|
+
: {};
|
|
362
|
+
const childStyles = isPlainObject(childMeta?.styles)
|
|
363
|
+
? childMeta.styles
|
|
364
|
+
: {};
|
|
359
365
|
const mergedMetaStyles = { ...parentStyles, ...childStyles };
|
|
360
366
|
|
|
361
367
|
const parentAttributesMeta = isPlainObject(parentMeta?.attributes)
|
|
@@ -364,7 +370,10 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
364
370
|
const childAttributesMeta = isPlainObject(childMeta?.attributes)
|
|
365
371
|
? childMeta.attributes
|
|
366
372
|
: {};
|
|
367
|
-
const mergedMetaAttributes = {
|
|
373
|
+
const mergedMetaAttributes = {
|
|
374
|
+
...parentAttributesMeta,
|
|
375
|
+
...childAttributesMeta,
|
|
376
|
+
};
|
|
368
377
|
|
|
369
378
|
const parentSpecialCategories = isPlainObject(parentMeta?.specialCategories)
|
|
370
379
|
? parentMeta.specialCategories
|
|
@@ -372,7 +381,10 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
372
381
|
const childSpecialCategories = isPlainObject(childMeta?.specialCategories)
|
|
373
382
|
? childMeta.specialCategories
|
|
374
383
|
: {};
|
|
375
|
-
const mergedSpecialCategories = {
|
|
384
|
+
const mergedSpecialCategories = {
|
|
385
|
+
...parentSpecialCategories,
|
|
386
|
+
...childSpecialCategories,
|
|
387
|
+
};
|
|
376
388
|
|
|
377
389
|
const mergedMeta =
|
|
378
390
|
parentMeta || childMeta
|
|
@@ -21,20 +21,24 @@ export async function validateExistingComponentTsx(
|
|
|
21
21
|
`function\\s+${componentName}\\s*\\(`
|
|
22
22
|
).test(content);
|
|
23
23
|
const hasDeclaration = hasConstDeclaration || hasFunctionDeclaration;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
|
|
25
|
+
const hasNamedExport =
|
|
26
|
+
new RegExp(`export\\s+function\\s+${componentName}\\s*\\(`).test(content) ||
|
|
27
|
+
new RegExp(`export\\s*\\{[^}]*\\b${componentName}\\b[^}]*\\}`).test(
|
|
28
|
+
content
|
|
29
|
+
);
|
|
30
|
+
const hasDefaultExport = new RegExp(
|
|
31
|
+
`export\\s+default\\s+(React\\.memo\\(\\s*${componentName}\\s*\\)|${componentName})\\s*;?`
|
|
26
32
|
).test(content);
|
|
27
|
-
const usesMemo = /React\\.memo\(/.test(content) || defaultExportMemo;
|
|
28
33
|
|
|
29
34
|
if (!hasDeclaration) {
|
|
30
35
|
return fail(
|
|
31
36
|
`${filePath} must declare component as 'const ${componentName}: React.FC = (...)' or 'function ${componentName}()'`
|
|
32
37
|
);
|
|
33
38
|
}
|
|
34
|
-
if (!
|
|
35
|
-
return fail(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return fail(`${filePath} must default export React.memo(${componentName})`);
|
|
39
|
+
if (!hasNamedExport && !hasDefaultExport) {
|
|
40
|
+
return fail(
|
|
41
|
+
`${filePath} must export ${componentName} (named export preferred)`
|
|
42
|
+
);
|
|
39
43
|
}
|
|
40
44
|
}
|
package/src/AttributesEditor.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import type { AttributesEditorProps } from './attributes-editor/attributesEditorModelTypes';
|
|
3
3
|
import { useLogRender } from './utils/useLogRender';
|
|
4
4
|
import { AttributesEditorView } from './attributes-editor/AttributesEditorView';
|
|
@@ -7,7 +7,12 @@ import { useAttributesEditorModel } from './attributes-editor/useAttributesEdito
|
|
|
7
7
|
export function AttributesEditor(props: AttributesEditorProps) {
|
|
8
8
|
useLogRender('AttributesEditor');
|
|
9
9
|
const model = useAttributesEditorModel(props);
|
|
10
|
-
|
|
10
|
+
const titleValue = model.attributes?.title;
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (typeof titleValue === 'string' && titleValue.length > 20) {
|
|
13
|
+
model.handleAttributeChange('title', titleValue.slice(0, 20));
|
|
14
|
+
}
|
|
15
|
+
}, [titleValue, model.handleAttributeChange]);
|
|
11
16
|
return <AttributesEditorView {...model} />;
|
|
12
17
|
}
|
|
13
18
|
|
package/src/RenderPage.tsx
CHANGED
|
@@ -84,30 +84,60 @@ export function RenderPage({
|
|
|
84
84
|
const showEmptyState = isEmptyPreview(data);
|
|
85
85
|
|
|
86
86
|
useEffect(() => {
|
|
87
|
+
console.info('[preview] RenderPage effect', {
|
|
88
|
+
previewMode,
|
|
89
|
+
forceRender,
|
|
90
|
+
hasRoot: !!previewRootRef.current,
|
|
91
|
+
});
|
|
92
|
+
|
|
87
93
|
if (!previewMode) {
|
|
88
94
|
return;
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
const root = previewRootRef.current;
|
|
92
|
-
if (!root)
|
|
98
|
+
if (!root) {
|
|
99
|
+
console.info('[preview] RenderPage effect skipped (no root)');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.info('[preview] RenderPage effect bound', {
|
|
104
|
+
rootTag: root.tagName,
|
|
105
|
+
rootClass: root.className,
|
|
106
|
+
});
|
|
93
107
|
|
|
94
108
|
const handleClick = (event: MouseEvent) => {
|
|
95
109
|
const target = event.target as HTMLElement | null;
|
|
110
|
+
console.info('[preview] click', {
|
|
111
|
+
target: target ? target.tagName : null,
|
|
112
|
+
className: target ? target.className : null,
|
|
113
|
+
});
|
|
114
|
+
|
|
96
115
|
if (!target) return;
|
|
97
116
|
|
|
98
117
|
// Ignore clicks on carousel dots to avoid interfering with navigation
|
|
99
118
|
if (target.closest('.embla__dot')) {
|
|
119
|
+
console.info('[preview] click ignored (embla dot)');
|
|
100
120
|
return;
|
|
101
121
|
}
|
|
102
122
|
|
|
103
123
|
const element = target.closest('[attribute-key]') as HTMLElement | null;
|
|
104
|
-
if (!element)
|
|
124
|
+
if (!element) {
|
|
125
|
+
console.info('[preview] click ignored (no attribute-key ancestor)');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
105
128
|
|
|
106
129
|
const key = element.getAttribute('attribute-key');
|
|
107
130
|
|
|
108
|
-
if (!key)
|
|
131
|
+
if (!key) {
|
|
132
|
+
console.info('[preview] click ignored (no attribute-key value)');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
109
135
|
|
|
110
136
|
const node = findNodeByKeyNested(data, key);
|
|
137
|
+
console.info('[preview] click resolved', {
|
|
138
|
+
key,
|
|
139
|
+
foundNode: !!node,
|
|
140
|
+
});
|
|
111
141
|
setCurrent(node);
|
|
112
142
|
onSelectNode?.(node);
|
|
113
143
|
};
|
|
@@ -115,6 +145,7 @@ export function RenderPage({
|
|
|
115
145
|
root.addEventListener('click', handleClick);
|
|
116
146
|
|
|
117
147
|
return () => {
|
|
148
|
+
console.info('[preview] RenderPage effect cleanup');
|
|
118
149
|
root.removeEventListener('click', handleClick);
|
|
119
150
|
};
|
|
120
151
|
}, [previewMode, data, onSelectNode, setCurrent, forceRender]); // forceRender: retrigger effect when we want to force a refresh (e.g. route change)
|
package/src/assets/meta.json
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"attributes": {
|
|
14
14
|
"loop": true,
|
|
15
15
|
"align": "center",
|
|
16
|
-
"dragFree": true
|
|
16
|
+
"dragFree": true,
|
|
17
|
+
"description": "carousel element 1 in sample.",
|
|
18
|
+
"title": "carousel 1"
|
|
17
19
|
},
|
|
18
20
|
"children": [
|
|
19
21
|
{
|
|
@@ -21,7 +23,9 @@
|
|
|
21
23
|
"attributes": {
|
|
22
24
|
"style": {
|
|
23
25
|
"minWidth": 0
|
|
24
|
-
}
|
|
26
|
+
},
|
|
27
|
+
"description": "carouselItem element 1 in sample.",
|
|
28
|
+
"title": "carouselItem 1"
|
|
25
29
|
},
|
|
26
30
|
"children": {
|
|
27
31
|
"type": "view",
|
|
@@ -34,7 +38,9 @@
|
|
|
34
38
|
"gap": 14,
|
|
35
39
|
"height": "100%",
|
|
36
40
|
"justifyContent": "center"
|
|
37
|
-
}
|
|
41
|
+
},
|
|
42
|
+
"description": "view element 1 in sample.",
|
|
43
|
+
"title": "view 1"
|
|
38
44
|
},
|
|
39
45
|
"children": [
|
|
40
46
|
{
|
|
@@ -57,7 +63,9 @@
|
|
|
57
63
|
"fontWeight": "700",
|
|
58
64
|
"textAlign": "center",
|
|
59
65
|
"color": "#0f172a"
|
|
60
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"description": "text element 1 in sample.",
|
|
68
|
+
"title": "text 1"
|
|
61
69
|
},
|
|
62
70
|
"children": "Welcome aboard"
|
|
63
71
|
},
|
|
@@ -69,7 +77,9 @@
|
|
|
69
77
|
"textAlign": "center",
|
|
70
78
|
"color": "#334155",
|
|
71
79
|
"paddingHorizontal": 8
|
|
72
|
-
}
|
|
80
|
+
},
|
|
81
|
+
"description": "text element 2 in sample.",
|
|
82
|
+
"title": "text 2"
|
|
73
83
|
},
|
|
74
84
|
"children": "Swipe through a beautiful, validated carousel sample with images."
|
|
75
85
|
}
|
|
@@ -81,7 +91,9 @@
|
|
|
81
91
|
"attributes": {
|
|
82
92
|
"style": {
|
|
83
93
|
"minWidth": 0
|
|
84
|
-
}
|
|
94
|
+
},
|
|
95
|
+
"description": "carouselItem element 2 in sample.",
|
|
96
|
+
"title": "carouselItem 2"
|
|
85
97
|
},
|
|
86
98
|
"children": {
|
|
87
99
|
"type": "view",
|
|
@@ -94,7 +106,9 @@
|
|
|
94
106
|
"gap": 14,
|
|
95
107
|
"height": "100%",
|
|
96
108
|
"justifyContent": "center"
|
|
97
|
-
}
|
|
109
|
+
},
|
|
110
|
+
"description": "view element 2 in sample.",
|
|
111
|
+
"title": "view 2"
|
|
98
112
|
},
|
|
99
113
|
"children": [
|
|
100
114
|
{
|
|
@@ -117,7 +131,9 @@
|
|
|
117
131
|
"fontWeight": "700",
|
|
118
132
|
"textAlign": "center",
|
|
119
133
|
"color": "#0f172a"
|
|
120
|
-
}
|
|
134
|
+
},
|
|
135
|
+
"description": "text element 3 in sample.",
|
|
136
|
+
"title": "text 3"
|
|
121
137
|
},
|
|
122
138
|
"children": "Discover features"
|
|
123
139
|
},
|
|
@@ -129,7 +145,9 @@
|
|
|
129
145
|
"textAlign": "center",
|
|
130
146
|
"color": "#334155",
|
|
131
147
|
"paddingHorizontal": 8
|
|
132
|
-
}
|
|
148
|
+
},
|
|
149
|
+
"description": "text element 4 in sample.",
|
|
150
|
+
"title": "text 4"
|
|
133
151
|
},
|
|
134
152
|
"children": "Dots + buttons are included, and slide sizing comes from the carousel CSS."
|
|
135
153
|
}
|
|
@@ -141,7 +159,9 @@
|
|
|
141
159
|
"attributes": {
|
|
142
160
|
"style": {
|
|
143
161
|
"minWidth": 0
|
|
144
|
-
}
|
|
162
|
+
},
|
|
163
|
+
"description": "carouselItem element 3 in sample.",
|
|
164
|
+
"title": "carouselItem 3"
|
|
145
165
|
},
|
|
146
166
|
"children": {
|
|
147
167
|
"type": "view",
|
|
@@ -154,7 +174,9 @@
|
|
|
154
174
|
"gap": 14,
|
|
155
175
|
"height": "100%",
|
|
156
176
|
"justifyContent": "center"
|
|
157
|
-
}
|
|
177
|
+
},
|
|
178
|
+
"description": "view element 3 in sample.",
|
|
179
|
+
"title": "view 3"
|
|
158
180
|
},
|
|
159
181
|
"children": [
|
|
160
182
|
{
|
|
@@ -177,7 +199,9 @@
|
|
|
177
199
|
"fontWeight": "700",
|
|
178
200
|
"textAlign": "center",
|
|
179
201
|
"color": "#0f172a"
|
|
180
|
-
}
|
|
202
|
+
},
|
|
203
|
+
"description": "text element 5 in sample.",
|
|
204
|
+
"title": "text 5"
|
|
181
205
|
},
|
|
182
206
|
"children": "Get started"
|
|
183
207
|
},
|
|
@@ -189,7 +213,9 @@
|
|
|
189
213
|
"textAlign": "center",
|
|
190
214
|
"color": "#334155",
|
|
191
215
|
"paddingHorizontal": 8
|
|
192
|
-
}
|
|
216
|
+
},
|
|
217
|
+
"description": "text element 6 in sample.",
|
|
218
|
+
"title": "text 6"
|
|
193
219
|
},
|
|
194
220
|
"children": "This sample stays within validation rules (no string flex shorthand)."
|
|
195
221
|
}
|
|
@@ -215,6 +241,10 @@
|
|
|
215
241
|
"skipNumber": 3
|
|
216
242
|
}
|
|
217
243
|
}
|
|
218
|
-
]
|
|
244
|
+
],
|
|
245
|
+
"attributes": {
|
|
246
|
+
"description": "carouselProvider element 1 in sample.",
|
|
247
|
+
"title": "carouselProvider 1"
|
|
248
|
+
}
|
|
219
249
|
}
|
|
220
250
|
}
|
|
@@ -8,6 +8,7 @@ import unvalidatedCrashComponent1 from './unvalidated-crashcomponent1.json';
|
|
|
8
8
|
import unmigratedBuilder1 from './unmigrated-builder1.json';
|
|
9
9
|
import unmigratedBuilder1_1_1 from './unmigrated-builder-1.1.1.json';
|
|
10
10
|
import paywall1 from './paywall-1.json';
|
|
11
|
+
import paywall2 from './paywall-2.json';
|
|
11
12
|
import vpnOnboard1 from './vpn-onboard-1.json';
|
|
12
13
|
import vpnOnboard2 from './vpn-onboard-2.json';
|
|
13
14
|
import vpnOnboard3 from './vpn-onboard-3.json';
|
|
@@ -43,6 +44,7 @@ export function getSamples(): Project[] {
|
|
|
43
44
|
normalizeSample(unmigratedBuilder1),
|
|
44
45
|
normalizeSample(unmigratedBuilder1_1_1),
|
|
45
46
|
normalizeSample(paywall1),
|
|
47
|
+
normalizeSample(paywall2),
|
|
46
48
|
...onboardSamples,
|
|
47
49
|
];
|
|
48
50
|
}
|
|
@@ -68,5 +70,5 @@ export function getOnboardSamples(): Project[] {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
export function getPaywallSamples(): Project[] {
|
|
71
|
-
return [normalizeSample(paywall1)];
|
|
73
|
+
return [normalizeSample(paywall1), normalizeSample(paywall2)];
|
|
72
74
|
}
|