@developer_tribe/react-builder 1.2.8 → 1.2.9
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/AttributesEditor.d.ts +2 -11
- package/dist/attribute-analyser/style/native/useExtractImageStyle.d.ts +10 -0
- package/dist/attribute-analyser/style/native/useExtractTextStyle.d.ts +9 -0
- package/dist/attribute-analyser/style/native/useExtractViewStyle.d.ts +8 -0
- package/dist/attribute-analyser/style/web/useExtractImageStyle.d.ts +4 -0
- package/dist/attribute-analyser/style/web/useExtractTextStyle.d.ts +4 -0
- package/dist/attribute-analyser/style/web/useExtractViewStyle.d.ts +4 -0
- package/dist/attributes-editor/AttributesEditorFields.d.ts +18 -0
- package/dist/attributes-editor/AttributesEditorView.d.ts +4 -0
- package/dist/attributes-editor/attributesEditorModelTypes.d.ts +67 -0
- package/dist/attributes-editor/attributesEditorUtils.d.ts +19 -0
- package/dist/attributes-editor/useAttributesEditorModel.d.ts +2 -0
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +6 -6
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +3 -3
- package/dist/build-components/Button/ButtonProps.generated.d.ts +1 -1
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +2 -2
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +4 -4
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +3 -3
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +1 -1
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +1 -1
- package/dist/build-components/Image/ImageProps.generated.d.ts +5 -3
- package/dist/build-components/Main/MainProps.generated.d.ts +2 -2
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +1 -1
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +9 -8
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +11 -11
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +15 -9
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +10 -10
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +8 -6
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +6 -3
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +5 -4
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +3 -3
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +3 -3
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +6 -6
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +1 -1
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +4 -4
- package/dist/build-components/Text/TextProps.generated.d.ts +3 -3
- package/dist/build-components/View/ViewProps.generated.d.ts +1 -1
- package/dist/build-components/patterns.generated.d.ts +2690 -5804
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +5 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +6 -4
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.d.ts +5 -6
- package/dist/index.native.esm.js +6 -4
- package/dist/index.native.esm.js.map +1 -1
- package/dist/migrations/migratePipe.d.ts +1 -1
- package/dist/migrations/migrations/1.1.2_extract_component_attributes_from_style.d.ts +2 -0
- package/dist/mockOS/components/PermissionModal.d.ts +1 -2
- package/dist/styles.css +1 -1
- package/dist/types/PreviewConfig.d.ts +1 -5
- package/dist/utils/getMeta.d.ts +5 -0
- package/dist/utils/patterns.d.ts +12 -0
- package/package.json +2 -1
- package/scripts/prebuild/prebuild.js +14 -0
- package/scripts/prebuild/utils/createGeneratedProps.js +19 -13
- package/scripts/prebuild/utils/index.js +1 -0
- package/scripts/prebuild/utils/updateMetaJson.js +66 -0
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +37 -3
- package/scripts/prebuild/utils/validatePatternJson.js +27 -2
- package/scripts/public/scripts/build/index.js +20 -3
- package/scripts/public/scripts/build/info.json +6 -0
- package/scripts/public/scripts/build/utils/createComponentsIndex.js +9 -3
- package/scripts/public/scripts/build/utils/createRenderNodeGenerated.js +66 -8
- package/src/AttributesEditor.tsx +8 -944
- package/src/assets/meta.json +4 -0
- package/src/assets/samples/carousel-sample.json +1 -1
- package/src/assets/samples/getSamples.ts +2 -0
- package/src/assets/samples/paywall-1.json +11 -7
- package/src/assets/samples/simple-1.json +3 -3
- package/src/assets/samples/simple-2.json +3 -3
- package/src/assets/samples/unmigrated-builder-1.1.1.json +87 -0
- package/src/assets/samples/unmigrated-builder1.json +1 -1
- package/src/assets/samples/unvalidated-builder1.json +3 -3
- package/src/assets/samples/unvalidated-crash1.json +1 -1
- package/src/assets/samples/unvalidated-crashcomponent1.json +1 -1
- package/src/assets/samples/vpn-onboard-1.json +1 -1
- package/src/assets/samples/vpn-onboard-2.json +1 -1
- package/src/assets/samples/vpn-onboard-3.json +1 -1
- package/src/assets/samples/vpn-onboard-4.json +1 -1
- package/src/assets/samples/vpn-onboard-5.json +1 -1
- package/src/assets/samples/vpn-onboard-6.json +1 -1
- package/src/attribute-analyser/style/native/useExtractImageStyle.ts +46 -0
- package/src/attribute-analyser/style/native/useExtractTextStyle.ts +50 -0
- package/src/attribute-analyser/style/native/useExtractViewStyle.ts +32 -0
- package/src/attribute-analyser/style/web/useExtractImageStyle.ts +20 -0
- package/src/attribute-analyser/style/web/useExtractTextStyle.ts +27 -0
- package/src/attribute-analyser/style/web/useExtractViewStyle.ts +20 -0
- package/src/attributes-editor/AttributesEditorFields.tsx +248 -0
- package/src/attributes-editor/AttributesEditorView.tsx +360 -0
- package/src/attributes-editor/attributesEditorModelTypes.ts +86 -0
- package/src/attributes-editor/attributesEditorUtils.ts +102 -0
- package/src/attributes-editor/useAttributesEditorModel.ts +477 -0
- package/src/build-components/BIcon/BIcon.tsx +4 -4
- package/src/build-components/BIcon/BIconProps.generated.ts +6 -6
- package/src/build-components/BIcon/pattern.json +5 -6
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +3 -2
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +3 -3
- package/src/build-components/Button/Button.tsx +2 -2
- package/src/build-components/Button/ButtonProps.generated.ts +1 -1
- package/src/build-components/Button/pattern.json +17 -15
- package/src/build-components/Carousel/Carousel.tsx +1 -1
- package/src/build-components/Carousel/CarouselProps.generated.ts +2 -2
- package/src/build-components/CarouselButtons/CarouselButtons.tsx +4 -7
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +7 -7
- package/src/build-components/CarouselButtons/pattern.json +2 -1
- package/src/build-components/CarouselDots/CarouselDots.tsx +2 -2
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +9 -9
- package/src/build-components/CarouselItem/CarouselItem.tsx +1 -1
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +1 -1
- package/src/build-components/CarouselProvider/CarouselProvider.tsx +1 -1
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +1 -1
- package/src/build-components/Image/Image.tsx +1 -1
- package/src/build-components/Image/ImageProps.generated.ts +5 -3
- package/src/build-components/Image/pattern.json +10 -9
- package/src/build-components/Main/Main.tsx +2 -2
- package/src/build-components/Main/MainProps.generated.ts +2 -2
- package/src/build-components/Main/pattern.json +2 -1
- package/src/build-components/Onboard/OnboardProps.generated.ts +1 -1
- package/src/build-components/OnboardButton/OnboardButton.tsx +7 -6
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +14 -13
- package/src/build-components/OnboardButton/pattern.json +9 -7
- package/src/build-components/OnboardButtons/OnboardButtons.tsx +31 -31
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +14 -14
- package/src/build-components/OnboardButtons/pattern.json +9 -7
- package/src/build-components/OnboardDot/OnboardDot.tsx +7 -6
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +26 -9
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +17 -16
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +10 -10
- package/src/build-components/OnboardFooter/pattern.json +16 -14
- package/src/build-components/OnboardImage/OnboardImage.tsx +8 -8
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +8 -6
- package/src/build-components/OnboardImage/pattern.json +2 -1
- package/src/build-components/OnboardItem/OnboardItem.tsx +1 -1
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +6 -3
- package/src/build-components/OnboardItem/pattern.json +2 -1
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +1 -1
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +5 -4
- package/src/build-components/OnboardProvider/pattern.json +2 -1
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +3 -3
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +3 -3
- package/src/build-components/PaywallBackground/PaywallBackground.tsx +1 -1
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +1 -1
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +5 -4
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +6 -6
- package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +1 -1
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +1 -1
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +1 -1
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +1 -1
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +1 -1
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +1 -1
- package/src/build-components/RadioButton/RadioButton.tsx +5 -5
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +4 -4
- package/src/build-components/RadioButton/pattern.json +9 -7
- package/src/build-components/Text/Text.tsx +6 -6
- package/src/build-components/Text/TextProps.generated.ts +3 -3
- package/src/build-components/Text/pattern.json +15 -11
- package/src/build-components/View/View.tsx +1 -1
- package/src/build-components/View/ViewProps.generated.ts +1 -1
- package/src/build-components/View/pattern.json +71 -66
- package/src/build-components/patterns.generated.ts +3059 -6008
- package/src/components/AttributesEditorPanel.tsx +2 -2
- package/src/index.native.ts +6 -9
- package/src/index.ts +4 -0
- package/src/migrations/migratePipe.ts +7 -3
- package/src/migrations/migrations/1.1.2_extract_component_attributes_from_style.ts +211 -0
- package/src/mockOS/components/MockOSRouter.tsx +3 -1
- package/src/mockOS/components/PermissionModal.tsx +20 -160
- package/src/mockOS/components/SubscriptionModal.tsx +41 -278
- package/src/pages/ProjectPage.tsx +12 -6
- package/src/styles/components/_attributes-editor.scss +122 -0
- package/src/styles/components/_mockos-router.scss +388 -0
- package/src/styles/components/_onboard.scss +23 -0
- package/src/styles/index.scss +1 -0
- package/src/types/PreviewConfig.ts +1 -5
- package/src/utils/analyseNodeByPatterns.ts +39 -4
- package/src/utils/extractTextStyle/extractTextStyle.ts +4 -1
- package/src/utils/getMeta.ts +15 -0
- package/src/utils/patterns.ts +47 -4
- package/dist/hooks/useExtractImageStyle.d.ts +0 -5
- package/dist/hooks/useExtractTextStyle.d.ts +0 -3
- package/dist/hooks/useExtractViewStyle.d.ts +0 -3
- package/src/hooks/useExtractImageStyle.ts +0 -30
- package/src/hooks/useExtractTextStyle.ts +0 -34
- package/src/hooks/useExtractViewStyle.ts +0 -30
- package/src/migrations/migrations/1.1.0_normalize_style_attributes.ts +0 -80
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import AttributesEditor from '../AttributesEditor';
|
|
1
|
+
import { AttributesEditor } from '../AttributesEditor';
|
|
2
2
|
import type { Node } from '../types/Node';
|
|
3
3
|
import type { ProjectColors } from '../types/Project';
|
|
4
4
|
import { useLogRender } from '../utils/useLogRender';
|
|
@@ -56,7 +56,7 @@ export function AttributesEditorPanel({
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
|
-
<div
|
|
59
|
+
<div className="attributes-editor-panel">
|
|
60
60
|
<AttributesEditor
|
|
61
61
|
node={current}
|
|
62
62
|
onChange={handleAttributesChange}
|
package/src/index.native.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* This file is meant to be used via the package `react-native` entry (Metro)
|
|
10
10
|
* or explicit `@developer_tribe/react-builder/native` style imports.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
//TODO: index's shoudl be reviewed and updated.
|
|
13
13
|
// Types
|
|
14
14
|
export type { TargetedScreenSize } from './types/TargetedScreenSize';
|
|
15
15
|
export type { Node, NodeData, NodeDefaultAttribute } from './types/Node';
|
|
@@ -45,14 +45,9 @@ export { LocalizationParamsProvider } from './components/LocalizationParamsProvi
|
|
|
45
45
|
export { useParams } from './hooks/useParams';
|
|
46
46
|
export { useLocalizationParams } from './hooks/useLocalizationParams';
|
|
47
47
|
export { useLocalize } from './hooks/useLocalize';
|
|
48
|
-
export { useExtractTextStyle } from './
|
|
49
|
-
export { useExtractViewStyle } from './
|
|
50
|
-
export { useExtractImageStyle } from './
|
|
51
|
-
|
|
52
|
-
// Native style extractors (RN-friendly style objects)
|
|
53
|
-
export { extractViewStyleNative } from './utils/extractViewStyle';
|
|
54
|
-
export { extractTextStyleNative } from './utils/extractTextStyle';
|
|
55
|
-
export { extractImageStyleNative } from './utils/extractImageStyle';
|
|
48
|
+
export { useExtractTextStyle } from './attribute-analyser/style/native/useExtractTextStyle';
|
|
49
|
+
export { useExtractViewStyle } from './attribute-analyser/style/native/useExtractViewStyle';
|
|
50
|
+
export { useExtractImageStyle } from './attribute-analyser/style/native/useExtractImageStyle';
|
|
56
51
|
|
|
57
52
|
// Pure utilities (RN-safe)
|
|
58
53
|
export {
|
|
@@ -63,6 +58,7 @@ export {
|
|
|
63
58
|
analyseNode,
|
|
64
59
|
analyseAndProccess,
|
|
65
60
|
} from './utils/analyseNode';
|
|
61
|
+
export { getMeta } from './utils/getMeta';
|
|
66
62
|
export { novaToJson } from './utils/novaToJson';
|
|
67
63
|
export { getDevices, getDefaultDevice } from './utils/getDevices';
|
|
68
64
|
export { querySelector } from './utils/querySelector';
|
|
@@ -93,3 +89,4 @@ export {
|
|
|
93
89
|
getOnboardSamples,
|
|
94
90
|
} from './assets/samples/getSamples';
|
|
95
91
|
export type { EventObjectGenerated } from './build-components/OnboardButton/OnboardButtonProps.generated';
|
|
92
|
+
export * from './build-components';
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,11 @@ import './styles/index.scss';
|
|
|
3
3
|
// Web entrypoint trimmed to what the `example/` app uses.
|
|
4
4
|
export { ProjectPage } from './pages/ProjectPage';
|
|
5
5
|
export { getSamples } from './assets/samples/getSamples';
|
|
6
|
+
export { getMeta } from './utils/getMeta';
|
|
6
7
|
export { defaultAppConfig } from './types/PreviewConfig';
|
|
8
|
+
export { useExtractTextStyle } from './attribute-analyser/style/web/useExtractTextStyle';
|
|
9
|
+
export { useExtractViewStyle } from './attribute-analyser/style/web/useExtractViewStyle';
|
|
10
|
+
export { useExtractImageStyle } from './attribute-analyser/style/web/useExtractImageStyle';
|
|
7
11
|
|
|
8
12
|
export type { AppConfig } from './types/PreviewConfig';
|
|
9
13
|
export type { Project, ProjectColors } from './types/Project';
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import metaJson from '../assets/meta.json';
|
|
1
2
|
import type { Project } from '../types/Project';
|
|
2
3
|
import type { Migration } from './types';
|
|
3
4
|
import { isSemverLess } from './semver';
|
|
4
|
-
import {
|
|
5
|
+
import { migration_1_1_2_extract_component_attributes_from_style } from './migrations/1.1.2_extract_component_attributes_from_style';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// CURRENT_PROJECT_VERSION is sourced from meta.json (written from package.json during prebuild) to avoid reading package.json directly at runtime.
|
|
8
|
+
export const CURRENT_PROJECT_VERSION = metaJson.supportedProjectVersion;
|
|
7
9
|
|
|
8
|
-
const MIGRATIONS: Migration[] = [
|
|
10
|
+
const MIGRATIONS: Migration[] = [
|
|
11
|
+
migration_1_1_2_extract_component_attributes_from_style,
|
|
12
|
+
];
|
|
9
13
|
|
|
10
14
|
export type MigrationPipe = {
|
|
11
15
|
projectVersion: string;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import type { Project } from '../../types/Project';
|
|
2
|
+
import type { Node, NodeData, NodeDefaultAttribute } from '../../types/Node';
|
|
3
|
+
import {
|
|
4
|
+
getAttributeSchema,
|
|
5
|
+
getStyleAttributeKeySet,
|
|
6
|
+
normalizeComponentType,
|
|
7
|
+
NON_STYLE_ATTRIBUTE_KEYS,
|
|
8
|
+
} from '../../utils/patterns';
|
|
9
|
+
import {
|
|
10
|
+
isEmptyObject,
|
|
11
|
+
isNodeArray,
|
|
12
|
+
isNodeNullOrUndefined,
|
|
13
|
+
isNodeString,
|
|
14
|
+
} from '../../utils/nodeGuards';
|
|
15
|
+
import type { Migration } from '../types';
|
|
16
|
+
|
|
17
|
+
type SchemaCache = Map<
|
|
18
|
+
string,
|
|
19
|
+
{ moveableKeys: Set<string>; styleKeys: Set<string> }
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
23
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function buildStyleKeySet(): Set<string> {
|
|
27
|
+
return getStyleAttributeKeySet();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function normalizeStyleAttributes(node: Node, styleKeys: Set<string>): Node {
|
|
31
|
+
if (
|
|
32
|
+
isNodeNullOrUndefined(node) ||
|
|
33
|
+
isNodeString(node) ||
|
|
34
|
+
isEmptyObject(node)
|
|
35
|
+
) {
|
|
36
|
+
return node;
|
|
37
|
+
}
|
|
38
|
+
if (isNodeArray(node)) {
|
|
39
|
+
return (node as Node[]).map((n) => normalizeStyleAttributes(n, styleKeys));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const record = node as NodeData<NodeDefaultAttribute>;
|
|
43
|
+
const nextChildren = normalizeStyleAttributes(
|
|
44
|
+
record.children as Node,
|
|
45
|
+
styleKeys,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (!isPlainObject(record.attributes)) {
|
|
49
|
+
return { ...record, children: nextChildren };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const nextAttrs: Record<string, unknown> = { ...(record.attributes ?? {}) };
|
|
53
|
+
const prevStyle = isPlainObject(nextAttrs.style) ? nextAttrs.style : {};
|
|
54
|
+
const nextStyle: Record<string, unknown> = { ...prevStyle };
|
|
55
|
+
|
|
56
|
+
for (const [k, v] of Object.entries(nextAttrs)) {
|
|
57
|
+
if (k === 'style') continue;
|
|
58
|
+
if (!styleKeys.has(k)) continue;
|
|
59
|
+
|
|
60
|
+
// If already set in style, prefer style (drop legacy flat key).
|
|
61
|
+
if (!(k in nextStyle)) nextStyle[k] = v;
|
|
62
|
+
delete nextAttrs[k];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (Object.keys(nextStyle).length > 0) {
|
|
66
|
+
nextAttrs.style = nextStyle;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
...record,
|
|
71
|
+
children: nextChildren,
|
|
72
|
+
attributes: nextAttrs as NodeDefaultAttribute,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getStyleSubSchemaKeys(
|
|
77
|
+
schema: Record<string, unknown> | undefined,
|
|
78
|
+
): Set<string> {
|
|
79
|
+
if (!schema) return new Set();
|
|
80
|
+
const style = (schema as any).style;
|
|
81
|
+
if (!isPlainObject(style)) return new Set();
|
|
82
|
+
return new Set(Object.keys(style));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getTopLevelAttributeKeys(
|
|
86
|
+
schema: Record<string, unknown> | undefined,
|
|
87
|
+
): Set<string> {
|
|
88
|
+
if (!schema) return new Set();
|
|
89
|
+
const keys = Object.keys(schema).filter((k) => k !== 'style');
|
|
90
|
+
return new Set(keys);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function buildKeyInfo(schema: Record<string, unknown> | undefined): {
|
|
94
|
+
moveableKeys: Set<string>;
|
|
95
|
+
styleKeys: Set<string>;
|
|
96
|
+
} {
|
|
97
|
+
const topLevelKeys = getTopLevelAttributeKeys(schema);
|
|
98
|
+
const moveableKeys = new Set<string>([
|
|
99
|
+
...Array.from(topLevelKeys),
|
|
100
|
+
...Array.from(NON_STYLE_ATTRIBUTE_KEYS),
|
|
101
|
+
]);
|
|
102
|
+
const styleKeys = getStyleSubSchemaKeys(schema);
|
|
103
|
+
return { moveableKeys, styleKeys };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function extractAttributesFromStyle(
|
|
107
|
+
node: Node,
|
|
108
|
+
schemaCache: SchemaCache,
|
|
109
|
+
): Node {
|
|
110
|
+
if (
|
|
111
|
+
isNodeNullOrUndefined(node) ||
|
|
112
|
+
isNodeString(node) ||
|
|
113
|
+
isEmptyObject(node)
|
|
114
|
+
) {
|
|
115
|
+
return node;
|
|
116
|
+
}
|
|
117
|
+
if (isNodeArray(node)) {
|
|
118
|
+
return (node as Node[]).map((n) =>
|
|
119
|
+
extractAttributesFromStyle(n, schemaCache),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const record = node as NodeData<NodeDefaultAttribute>;
|
|
124
|
+
const nextChildren = extractAttributesFromStyle(
|
|
125
|
+
record.children as Node,
|
|
126
|
+
schemaCache,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (!isPlainObject(record.attributes)) {
|
|
130
|
+
return { ...record, children: nextChildren };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const nextAttrs: Record<string, unknown> = { ...(record.attributes ?? {}) };
|
|
134
|
+
const style = nextAttrs.style;
|
|
135
|
+
|
|
136
|
+
if (!isPlainObject(style)) {
|
|
137
|
+
return { ...record, children: nextChildren, attributes: nextAttrs };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const rawType = typeof record.type === 'string' ? record.type : '';
|
|
141
|
+
const normalizedType = normalizeComponentType(rawType) ?? rawType;
|
|
142
|
+
if (!normalizedType) {
|
|
143
|
+
return { ...record, children: nextChildren, attributes: nextAttrs };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!schemaCache.has(normalizedType)) {
|
|
147
|
+
const schema = getAttributeSchema(normalizedType) as unknown as
|
|
148
|
+
| Record<string, unknown>
|
|
149
|
+
| undefined;
|
|
150
|
+
schemaCache.set(normalizedType, buildKeyInfo(schema));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const keyInfo = schemaCache.get(normalizedType);
|
|
154
|
+
const styleKeys = keyInfo?.styleKeys ?? new Set<string>();
|
|
155
|
+
const moveableKeys = keyInfo?.moveableKeys ?? NON_STYLE_ATTRIBUTE_KEYS;
|
|
156
|
+
|
|
157
|
+
const nextStyle: Record<string, unknown> = { ...style };
|
|
158
|
+
let moved = false;
|
|
159
|
+
|
|
160
|
+
for (const k of moveableKeys) {
|
|
161
|
+
if (!(k in nextStyle)) continue;
|
|
162
|
+
if (styleKeys.has(k)) continue;
|
|
163
|
+
// Prefer the direct attribute if already present.
|
|
164
|
+
if (!(k in nextAttrs)) {
|
|
165
|
+
nextAttrs[k] = nextStyle[k];
|
|
166
|
+
}
|
|
167
|
+
delete nextStyle[k];
|
|
168
|
+
moved = true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!moved) {
|
|
172
|
+
return { ...record, children: nextChildren, attributes: nextAttrs };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (Object.keys(nextStyle).length === 0) {
|
|
176
|
+
delete nextAttrs.style;
|
|
177
|
+
} else {
|
|
178
|
+
nextAttrs.style = nextStyle;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
...record,
|
|
183
|
+
children: nextChildren,
|
|
184
|
+
attributes: nextAttrs as NodeDefaultAttribute,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export const migration_1_1_2_extract_component_attributes_from_style: Migration =
|
|
189
|
+
{
|
|
190
|
+
id: '1.1.2-extract-attrs-from-style',
|
|
191
|
+
title:
|
|
192
|
+
'Normalize style keys then extract non-style + component props out of attributes.style',
|
|
193
|
+
fromVersion: '0.0.0',
|
|
194
|
+
toVersion: '1.1.2',
|
|
195
|
+
run: (project: Project): Project => {
|
|
196
|
+
const styleKeys = buildStyleKeySet();
|
|
197
|
+
const normalized = normalizeStyleAttributes(
|
|
198
|
+
project.data as unknown as Node,
|
|
199
|
+
styleKeys,
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const schemaCache: SchemaCache = new Map();
|
|
203
|
+
const migrated = extractAttributesFromStyle(normalized, schemaCache);
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
...project,
|
|
207
|
+
version: '1.1.2',
|
|
208
|
+
data: migrated as any,
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
};
|
|
@@ -28,7 +28,9 @@ function OnboardComponent() {
|
|
|
28
28
|
return (
|
|
29
29
|
<div className="mockos-screen mockos-screen--onboard">
|
|
30
30
|
<div className="mockos-screen__heading">Onboarding</div>
|
|
31
|
-
<div className="mockos-screen__text">
|
|
31
|
+
<div className="mockos-screen__text">
|
|
32
|
+
Welcome! Let's get you started.
|
|
33
|
+
</div>
|
|
32
34
|
</div>
|
|
33
35
|
);
|
|
34
36
|
}
|
|
@@ -50,111 +50,40 @@ const getPermissionText = (permission: PermissionType | string) => {
|
|
|
50
50
|
);
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
export
|
|
53
|
+
export function PermissionModal({
|
|
54
54
|
permission,
|
|
55
55
|
onAllow,
|
|
56
56
|
onDeny,
|
|
57
|
-
})
|
|
57
|
+
}: PermissionModalProps) {
|
|
58
58
|
const device = useRenderStore((s) => s.device);
|
|
59
59
|
const isIOS = device.platform === 'ios';
|
|
60
60
|
const { title, message } = getPermissionText(permission);
|
|
61
61
|
|
|
62
|
-
// iOS Style
|
|
63
62
|
if (isIOS) {
|
|
64
63
|
return (
|
|
65
64
|
<div
|
|
66
|
-
|
|
67
|
-
position: 'absolute',
|
|
68
|
-
top: 0,
|
|
69
|
-
left: 0,
|
|
70
|
-
right: 0,
|
|
71
|
-
bottom: 0,
|
|
72
|
-
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
|
73
|
-
display: 'flex',
|
|
74
|
-
alignItems: 'center',
|
|
75
|
-
justifyContent: 'center',
|
|
76
|
-
zIndex: 9999,
|
|
77
|
-
padding: 20,
|
|
78
|
-
}}
|
|
65
|
+
className="mockos-modal-overlay mockos-modal-overlay--center mockos-modal-overlay--ios"
|
|
79
66
|
onClick={(e) => {
|
|
80
67
|
if (e.target === e.currentTarget) {
|
|
81
68
|
onDeny();
|
|
82
69
|
}
|
|
83
70
|
}}
|
|
84
71
|
>
|
|
85
|
-
<div
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
borderRadius: 14,
|
|
90
|
-
width: '100%',
|
|
91
|
-
maxWidth: 270,
|
|
92
|
-
overflow: 'hidden',
|
|
93
|
-
backdropFilter: 'blur(20px)',
|
|
94
|
-
}}
|
|
95
|
-
>
|
|
96
|
-
<div
|
|
97
|
-
style={{
|
|
98
|
-
padding: '20px 16px',
|
|
99
|
-
textAlign: 'center',
|
|
100
|
-
}}
|
|
101
|
-
>
|
|
102
|
-
<div
|
|
103
|
-
style={{
|
|
104
|
-
fontSize: 17,
|
|
105
|
-
fontWeight: 600,
|
|
106
|
-
color: '#000',
|
|
107
|
-
marginBottom: 8,
|
|
108
|
-
lineHeight: 1.3,
|
|
109
|
-
}}
|
|
110
|
-
>
|
|
111
|
-
{title}
|
|
112
|
-
</div>
|
|
113
|
-
<div
|
|
114
|
-
style={{
|
|
115
|
-
fontSize: 13,
|
|
116
|
-
color: '#000',
|
|
117
|
-
lineHeight: 1.4,
|
|
118
|
-
opacity: 0.6,
|
|
119
|
-
}}
|
|
120
|
-
>
|
|
121
|
-
{message}
|
|
122
|
-
</div>
|
|
72
|
+
<div className="mockos-permission-modal mockos-permission-modal--ios">
|
|
73
|
+
<div className="mockos-permission-modal__content mockos-permission-modal__content--center">
|
|
74
|
+
<div className="mockos-permission-modal__title">{title}</div>
|
|
75
|
+
<div className="mockos-permission-modal__message">{message}</div>
|
|
123
76
|
</div>
|
|
124
|
-
<div
|
|
125
|
-
style={{
|
|
126
|
-
borderTop: '0.5px solid rgba(0, 0, 0, 0.2)',
|
|
127
|
-
display: 'flex',
|
|
128
|
-
}}
|
|
129
|
-
>
|
|
77
|
+
<div className="mockos-permission-modal__actions mockos-permission-modal__actions--ios">
|
|
130
78
|
<button
|
|
79
|
+
className="mockos-permission-modal__button mockos-permission-modal__button--ios"
|
|
131
80
|
onClick={onDeny}
|
|
132
|
-
style={{
|
|
133
|
-
flex: 1,
|
|
134
|
-
padding: '11px 0',
|
|
135
|
-
fontSize: 17,
|
|
136
|
-
fontWeight: 400,
|
|
137
|
-
color: '#007AFF',
|
|
138
|
-
background: 'transparent',
|
|
139
|
-
border: 'none',
|
|
140
|
-
borderRight: '0.5px solid rgba(0, 0, 0, 0.2)',
|
|
141
|
-
cursor: 'pointer',
|
|
142
|
-
}}
|
|
143
81
|
>
|
|
144
|
-
Don
|
|
82
|
+
Don't Allow
|
|
145
83
|
</button>
|
|
146
84
|
<button
|
|
85
|
+
className="mockos-permission-modal__button mockos-permission-modal__button--ios mockos-permission-modal__button--bold"
|
|
147
86
|
onClick={onAllow}
|
|
148
|
-
style={{
|
|
149
|
-
flex: 1,
|
|
150
|
-
padding: '11px 0',
|
|
151
|
-
fontSize: 17,
|
|
152
|
-
fontWeight: 600,
|
|
153
|
-
color: '#007AFF',
|
|
154
|
-
background: 'transparent',
|
|
155
|
-
border: 'none',
|
|
156
|
-
cursor: 'pointer',
|
|
157
|
-
}}
|
|
158
87
|
>
|
|
159
88
|
Allow
|
|
160
89
|
</button>
|
|
@@ -164,103 +93,34 @@ export const PermissionModal: React.FC<PermissionModalProps> = ({
|
|
|
164
93
|
);
|
|
165
94
|
}
|
|
166
95
|
|
|
167
|
-
// Android Material Design Style
|
|
168
96
|
return (
|
|
169
97
|
<div
|
|
170
|
-
|
|
171
|
-
position: 'absolute',
|
|
172
|
-
top: 0,
|
|
173
|
-
left: 0,
|
|
174
|
-
right: 0,
|
|
175
|
-
bottom: 0,
|
|
176
|
-
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
177
|
-
display: 'flex',
|
|
178
|
-
alignItems: 'center',
|
|
179
|
-
justifyContent: 'center',
|
|
180
|
-
zIndex: 9999,
|
|
181
|
-
padding: 24,
|
|
182
|
-
}}
|
|
98
|
+
className="mockos-modal-overlay mockos-modal-overlay--center mockos-modal-overlay--android"
|
|
183
99
|
onClick={(e) => {
|
|
184
100
|
if (e.target === e.currentTarget) {
|
|
185
101
|
onDeny();
|
|
186
102
|
}
|
|
187
103
|
}}
|
|
188
104
|
>
|
|
189
|
-
<div
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
borderRadius: 4,
|
|
193
|
-
width: '100%',
|
|
194
|
-
maxWidth: 280,
|
|
195
|
-
boxShadow:
|
|
196
|
-
'0 11px 15px -7px rgba(0,0,0,0.2), 0 24px 38px 3px rgba(0,0,0,0.14)',
|
|
197
|
-
}}
|
|
198
|
-
>
|
|
199
|
-
<div
|
|
200
|
-
style={{
|
|
201
|
-
padding: '24px 24px 20px',
|
|
202
|
-
}}
|
|
203
|
-
>
|
|
204
|
-
<div
|
|
205
|
-
style={{
|
|
206
|
-
fontSize: 20,
|
|
207
|
-
fontWeight: 500,
|
|
208
|
-
color: 'rgba(0, 0, 0, 0.87)',
|
|
209
|
-
marginBottom: 16,
|
|
210
|
-
lineHeight: 1.2,
|
|
211
|
-
}}
|
|
212
|
-
>
|
|
105
|
+
<div className="mockos-permission-modal mockos-permission-modal--android">
|
|
106
|
+
<div className="mockos-permission-modal__content">
|
|
107
|
+
<div className="mockos-permission-modal__title mockos-permission-modal__title--android">
|
|
213
108
|
{title}
|
|
214
109
|
</div>
|
|
215
|
-
<div
|
|
216
|
-
style={{
|
|
217
|
-
fontSize: 16,
|
|
218
|
-
color: 'rgba(0, 0, 0, 0.6)',
|
|
219
|
-
lineHeight: 1.5,
|
|
220
|
-
}}
|
|
221
|
-
>
|
|
110
|
+
<div className="mockos-permission-modal__message mockos-permission-modal__message--android">
|
|
222
111
|
{message}
|
|
223
112
|
</div>
|
|
224
113
|
</div>
|
|
225
|
-
<div
|
|
226
|
-
style={{
|
|
227
|
-
padding: '8px 8px 8px 0',
|
|
228
|
-
display: 'flex',
|
|
229
|
-
justifyContent: 'flex-end',
|
|
230
|
-
gap: 8,
|
|
231
|
-
}}
|
|
232
|
-
>
|
|
114
|
+
<div className="mockos-permission-modal__actions mockos-permission-modal__actions--android">
|
|
233
115
|
<button
|
|
116
|
+
className="mockos-permission-modal__button mockos-permission-modal__button--android mockos-permission-modal__button--deny"
|
|
234
117
|
onClick={onDeny}
|
|
235
|
-
style={{
|
|
236
|
-
padding: '8px 16px',
|
|
237
|
-
fontSize: 14,
|
|
238
|
-
fontWeight: 500,
|
|
239
|
-
color: '#5F6368',
|
|
240
|
-
background: 'transparent',
|
|
241
|
-
border: 'none',
|
|
242
|
-
borderRadius: 4,
|
|
243
|
-
cursor: 'pointer',
|
|
244
|
-
textTransform: 'uppercase',
|
|
245
|
-
letterSpacing: 0.5,
|
|
246
|
-
}}
|
|
247
118
|
>
|
|
248
119
|
Deny
|
|
249
120
|
</button>
|
|
250
121
|
<button
|
|
122
|
+
className="mockos-permission-modal__button mockos-permission-modal__button--android mockos-permission-modal__button--allow"
|
|
251
123
|
onClick={onAllow}
|
|
252
|
-
style={{
|
|
253
|
-
padding: '8px 16px',
|
|
254
|
-
fontSize: 14,
|
|
255
|
-
fontWeight: 500,
|
|
256
|
-
color: '#1A73E8',
|
|
257
|
-
background: 'transparent',
|
|
258
|
-
border: 'none',
|
|
259
|
-
borderRadius: 4,
|
|
260
|
-
cursor: 'pointer',
|
|
261
|
-
textTransform: 'uppercase',
|
|
262
|
-
letterSpacing: 0.5,
|
|
263
|
-
}}
|
|
264
124
|
>
|
|
265
125
|
Allow
|
|
266
126
|
</button>
|
|
@@ -268,4 +128,4 @@ export const PermissionModal: React.FC<PermissionModalProps> = ({
|
|
|
268
128
|
</div>
|
|
269
129
|
</div>
|
|
270
130
|
);
|
|
271
|
-
}
|
|
131
|
+
}
|