@builder.io/react 2.0.7 → 2.0.8-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +51 -41
- package/dist/builder-react-lite.cjs.js +1 -1
- package/dist/builder-react-lite.cjs.js.map +1 -1
- package/dist/builder-react-lite.esm.js +1 -1
- package/dist/builder-react-lite.esm.js.map +1 -1
- package/dist/builder-react.browser.js +1 -1
- package/dist/builder-react.browser.js.map +1 -1
- package/dist/builder-react.cjs.js +1 -1
- package/dist/builder-react.cjs.js.map +1 -1
- package/dist/builder-react.es5.js +1 -1
- package/dist/builder-react.es5.js.map +1 -1
- package/dist/builder-react.unpkg.js +1 -1
- package/dist/builder-react.unpkg.js.map +1 -1
- package/dist/lib/package.json +1 -1
- package/dist/lib/src/components/builder-block.component.js +14 -10
- package/dist/lib/src/components/builder-block.component.js.map +1 -1
- package/dist/lib/src/components/builder-component.component.js +9 -2
- package/dist/lib/src/components/builder-component.component.js.map +1 -1
- package/dist/lib/src/constants/device-sizes.constant.js +41 -2
- package/dist/lib/src/constants/device-sizes.constant.js.map +1 -1
- package/dist/lib/src/functions/apply-patch.js +38 -0
- package/dist/lib/src/functions/apply-patch.js.map +1 -0
- package/dist/lib/src/functions/apply-patch.test.js +85 -0
- package/dist/lib/src/functions/apply-patch.test.js.map +1 -0
- package/dist/lib/src/functions/try-eval.js.map +1 -1
- package/dist/lib/src/functions/utils.js +7 -0
- package/dist/lib/src/functions/utils.js.map +1 -0
- package/dist/lib/src/scripts/init-editing.js +2 -1
- package/dist/lib/src/scripts/init-editing.js.map +1 -1
- package/dist/types/src/components/builder-component.component.d.ts +1 -0
- package/dist/types/src/constants/device-sizes.constant.d.ts +31 -1
- package/dist/types/src/functions/apply-patch.d.ts +5 -0
- package/dist/types/src/functions/apply-patch.test.d.ts +1 -0
- package/dist/types/src/functions/utils.d.ts +1 -0
- package/jest.config.js +5 -0
- package/package.json +1 -1
- package/src/components/builder-block.component.tsx +15 -7
- package/src/components/builder-component.component.tsx +10 -2
- package/src/constants/device-sizes.constant.ts +43 -1
- package/src/functions/apply-patch.test.ts +90 -0
- package/src/functions/apply-patch.ts +37 -0
- package/src/functions/try-eval.tsx +1 -1
- package/src/functions/utils.ts +2 -0
- package/src/scripts/init-editing.ts +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare type Size = 'large' | 'medium' | 'small' | 'xsmall';
|
|
2
2
|
export declare const sizeNames: Size[];
|
|
3
|
-
|
|
3
|
+
declare const sizes: {
|
|
4
4
|
xsmall: {
|
|
5
5
|
min: number;
|
|
6
6
|
default: number;
|
|
@@ -24,3 +24,33 @@ export declare const sizes: {
|
|
|
24
24
|
getWidthForSize(size: Size): number;
|
|
25
25
|
getSizeForWidth(width: number): Size;
|
|
26
26
|
};
|
|
27
|
+
export declare type Sizes = typeof sizes;
|
|
28
|
+
interface Breakpoints {
|
|
29
|
+
small?: number;
|
|
30
|
+
medium?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare const getSizesForBreakpoints: ({ small, medium }: Breakpoints) => {
|
|
33
|
+
xsmall: {
|
|
34
|
+
min: number;
|
|
35
|
+
default: number;
|
|
36
|
+
max: number;
|
|
37
|
+
};
|
|
38
|
+
small: {
|
|
39
|
+
min: number;
|
|
40
|
+
default: number;
|
|
41
|
+
max: number;
|
|
42
|
+
};
|
|
43
|
+
medium: {
|
|
44
|
+
min: number;
|
|
45
|
+
default: number;
|
|
46
|
+
max: number;
|
|
47
|
+
};
|
|
48
|
+
large: {
|
|
49
|
+
min: number;
|
|
50
|
+
default: number;
|
|
51
|
+
max: number;
|
|
52
|
+
};
|
|
53
|
+
getWidthForSize(size: Size): number;
|
|
54
|
+
getSizeForWidth(width: number): Size;
|
|
55
|
+
};
|
|
56
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fastClone: <T extends object>(obj: T) => T;
|
package/jest.config.js
CHANGED
|
@@ -6,6 +6,7 @@ module.exports = {
|
|
|
6
6
|
'ts-jest': {
|
|
7
7
|
tsConfig: 'tsconfig.json',
|
|
8
8
|
diagnostics: false,
|
|
9
|
+
useESM: true,
|
|
9
10
|
},
|
|
10
11
|
},
|
|
11
12
|
testEnvironment: 'node',
|
|
@@ -20,4 +21,8 @@ module.exports = {
|
|
|
20
21
|
},
|
|
21
22
|
},
|
|
22
23
|
collectCoverage: true,
|
|
24
|
+
moduleNameMapper: {
|
|
25
|
+
'(.+)\\.js': '$1',
|
|
26
|
+
},
|
|
27
|
+
extensionsToTreatAsEsm: ['.ts'],
|
|
23
28
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { Builder, builder, BuilderElement, Component } from '@builder.io/sdk';
|
|
4
4
|
import { ClassNames, jsx } from '@emotion/core';
|
|
5
5
|
import React from 'react';
|
|
6
|
-
import { Size, sizeNames
|
|
6
|
+
import { getSizesForBreakpoints, Size, sizeNames } from '../constants/device-sizes.constant';
|
|
7
7
|
import { set } from '../functions/set';
|
|
8
8
|
import { api, stringToFunction } from '../functions/string-to-function';
|
|
9
9
|
import { BuilderAsyncRequestsContext, RequestOrPromise } from '../store/builder-async-requests';
|
|
@@ -11,6 +11,8 @@ import { BuilderStoreContext } from '../store/builder-store';
|
|
|
11
11
|
import { applyPatchWithMinimalMutationChain } from '../functions/apply-patch-with-mutation';
|
|
12
12
|
import { blockToHtmlString } from '../functions/block-to-html-string';
|
|
13
13
|
import { Link } from './Link';
|
|
14
|
+
import { fastClone } from '../functions/utils';
|
|
15
|
+
import { applyPatch } from '../functions/apply-patch';
|
|
14
16
|
|
|
15
17
|
const camelCaseToKebabCase = (str?: string) =>
|
|
16
18
|
str ? str.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`) : '';
|
|
@@ -62,9 +64,6 @@ const cssCase = (property: string) => {
|
|
|
62
64
|
return str;
|
|
63
65
|
};
|
|
64
66
|
|
|
65
|
-
// TODO: pull from builer internal utils
|
|
66
|
-
const fastClone = (obj: object) => JSON.parse(JSON.stringify(obj));
|
|
67
|
-
|
|
68
67
|
// TODO: share these types in shared
|
|
69
68
|
type ElementType = any;
|
|
70
69
|
|
|
@@ -166,7 +165,10 @@ export class BuilderBlock extends React.Component<
|
|
|
166
165
|
);
|
|
167
166
|
}
|
|
168
167
|
} else {
|
|
169
|
-
|
|
168
|
+
const sizesPerBreakpoints = getSizesForBreakpoints(
|
|
169
|
+
this.privateState.context.builderContent?.meta?.breakpoints || {}
|
|
170
|
+
);
|
|
171
|
+
styles[`@media only screen and (max-width: ${sizesPerBreakpoints[size].max}px)`] = {
|
|
170
172
|
'&.builder-block': self.responsiveStyles[size],
|
|
171
173
|
};
|
|
172
174
|
}
|
|
@@ -251,7 +253,7 @@ export class BuilderBlock extends React.Component<
|
|
|
251
253
|
eval('debugger');
|
|
252
254
|
}
|
|
253
255
|
for (const patch of patches) {
|
|
254
|
-
|
|
256
|
+
applyPatch(this.props.block, patch);
|
|
255
257
|
}
|
|
256
258
|
this.setState({ updates: this.state.updates + 1 });
|
|
257
259
|
|
|
@@ -635,7 +637,13 @@ export class BuilderBlock extends React.Component<
|
|
|
635
637
|
|
|
636
638
|
if (block.repeat && block.repeat.collection) {
|
|
637
639
|
const collectionPath = block.repeat.collection;
|
|
638
|
-
const collectionName = last(
|
|
640
|
+
const collectionName = last(
|
|
641
|
+
(collectionPath || '')
|
|
642
|
+
.trim()
|
|
643
|
+
.split('(')[0]
|
|
644
|
+
.trim()
|
|
645
|
+
.split('.')
|
|
646
|
+
);
|
|
639
647
|
const itemName = block.repeat.itemName || (collectionName ? collectionName + 'Item' : 'item');
|
|
640
648
|
const array = this.stringToFunction(collectionPath)(
|
|
641
649
|
state.state,
|
|
@@ -18,7 +18,7 @@ import onChange from '../../lib/on-change';
|
|
|
18
18
|
|
|
19
19
|
export { onChange };
|
|
20
20
|
|
|
21
|
-
import {
|
|
21
|
+
import { getSizesForBreakpoints, Sizes } from '../constants/device-sizes.constant';
|
|
22
22
|
import {
|
|
23
23
|
BuilderAsyncRequestsContext,
|
|
24
24
|
RequestOrPromise,
|
|
@@ -361,6 +361,7 @@ export class BuilderComponent extends React.Component<
|
|
|
361
361
|
private _asyncRequests?: RequestOrPromise[];
|
|
362
362
|
private _errors?: Error[];
|
|
363
363
|
private _logs?: string[];
|
|
364
|
+
private sizes: Sizes;
|
|
364
365
|
|
|
365
366
|
get element() {
|
|
366
367
|
return this.ref;
|
|
@@ -376,6 +377,13 @@ export class BuilderComponent extends React.Component<
|
|
|
376
377
|
constructor(props: BuilderComponentProps) {
|
|
377
378
|
super(props);
|
|
378
379
|
|
|
380
|
+
let _content: any = this.inlinedContent;
|
|
381
|
+
if (_content && _content.content) {
|
|
382
|
+
_content = _content.content;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
this.sizes = getSizesForBreakpoints(_content?.meta?.breakpoints || {});
|
|
386
|
+
|
|
379
387
|
// TODO: pass this all the way down - symbols, etc
|
|
380
388
|
// this.asServer = Boolean(props.hydrate && Builder.isBrowser)
|
|
381
389
|
|
|
@@ -461,7 +469,7 @@ export class BuilderComponent extends React.Component<
|
|
|
461
469
|
get deviceSizeState() {
|
|
462
470
|
// TODO: use context to pass this down on server
|
|
463
471
|
return Builder.isBrowser
|
|
464
|
-
? sizes.getSizeForWidth(window.innerWidth)
|
|
472
|
+
? this.sizes.getSizeForWidth(window.innerWidth)
|
|
465
473
|
: sizeMap[this.device] || 'large';
|
|
466
474
|
}
|
|
467
475
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { fastClone } from '../functions/utils';
|
|
2
|
+
|
|
1
3
|
export type Size = 'large' | 'medium' | 'small' | 'xsmall';
|
|
2
4
|
export const sizeNames: Size[] = ['xsmall', 'small', 'medium', 'large'];
|
|
3
5
|
|
|
4
6
|
// TODO: put in @builder.io/core
|
|
5
|
-
|
|
7
|
+
const sizes = {
|
|
6
8
|
xsmall: {
|
|
7
9
|
min: 0,
|
|
8
10
|
default: 0,
|
|
@@ -36,3 +38,43 @@ export const sizes = {
|
|
|
36
38
|
return 'large';
|
|
37
39
|
},
|
|
38
40
|
};
|
|
41
|
+
export type Sizes = typeof sizes;
|
|
42
|
+
|
|
43
|
+
interface Breakpoints {
|
|
44
|
+
small?: number;
|
|
45
|
+
medium?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const getSizesForBreakpoints = ({ small, medium }: Breakpoints) => {
|
|
49
|
+
const newSizes = {
|
|
50
|
+
...sizes, // Note: this helps get the function from sizes
|
|
51
|
+
...fastClone(sizes), // Note: this helps to get a deep clone of fields like small, medium etc
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (!small || !medium) {
|
|
55
|
+
return newSizes;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const smallMin = Math.floor(small / 2);
|
|
59
|
+
newSizes.small = {
|
|
60
|
+
max: small,
|
|
61
|
+
min: smallMin,
|
|
62
|
+
default: smallMin + 1,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const mediumMin = newSizes.small.max + 1;
|
|
66
|
+
newSizes.medium = {
|
|
67
|
+
max: medium,
|
|
68
|
+
min: mediumMin,
|
|
69
|
+
default: mediumMin + 1,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const largeMin = newSizes.medium.max + 1;
|
|
73
|
+
newSizes.large = {
|
|
74
|
+
max: 2000, // TODO: decide upper limit
|
|
75
|
+
min: largeMin,
|
|
76
|
+
default: largeMin + 1,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return newSizes;
|
|
80
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { applyPatch } from './apply-patch.js';
|
|
2
|
+
|
|
3
|
+
describe('applyPatch', () => {
|
|
4
|
+
test('Basic shallow update', () => {
|
|
5
|
+
const obj = {
|
|
6
|
+
foo: 'bar',
|
|
7
|
+
};
|
|
8
|
+
const patch = {
|
|
9
|
+
op: 'replace',
|
|
10
|
+
path: '/foo',
|
|
11
|
+
value: '60px',
|
|
12
|
+
} as const;
|
|
13
|
+
const applied = applyPatch(obj, patch);
|
|
14
|
+
expect(applied.foo).toBe('60px');
|
|
15
|
+
expect(applied).toBe(obj);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('Deep object updates', () => {
|
|
19
|
+
const obj = {
|
|
20
|
+
foo: {
|
|
21
|
+
bar: true,
|
|
22
|
+
},
|
|
23
|
+
baz: {},
|
|
24
|
+
};
|
|
25
|
+
const patch = {
|
|
26
|
+
op: 'replace',
|
|
27
|
+
path: '/foo/bar',
|
|
28
|
+
value: '60px',
|
|
29
|
+
} as const;
|
|
30
|
+
const applied = applyPatch(obj, patch);
|
|
31
|
+
expect(applied.foo.bar).toBe('60px');
|
|
32
|
+
expect(applied).toBe(obj);
|
|
33
|
+
expect(applied.foo).toBe(obj.foo);
|
|
34
|
+
expect(applied.baz).toBe(obj.baz);
|
|
35
|
+
|
|
36
|
+
applyPatch(obj, {
|
|
37
|
+
op: 'add',
|
|
38
|
+
path: 'foo/baz',
|
|
39
|
+
value: 'hi',
|
|
40
|
+
});
|
|
41
|
+
expect((applied.foo as any).baz).toBe('hi');
|
|
42
|
+
|
|
43
|
+
applyPatch(obj, {
|
|
44
|
+
op: 'remove',
|
|
45
|
+
path: 'foo/baz',
|
|
46
|
+
value: undefined,
|
|
47
|
+
});
|
|
48
|
+
expect((applied.foo as any).baz).toBe(undefined);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('Deep array updates', () => {
|
|
52
|
+
const obj = {
|
|
53
|
+
foo: [{ bar: true }],
|
|
54
|
+
baz: {},
|
|
55
|
+
};
|
|
56
|
+
const patch = {
|
|
57
|
+
op: 'replace',
|
|
58
|
+
path: '/foo/0/bar',
|
|
59
|
+
value: '60px',
|
|
60
|
+
} as const;
|
|
61
|
+
|
|
62
|
+
const applied = applyPatch(obj, patch);
|
|
63
|
+
expect(applied.foo[0].bar).toBe('60px');
|
|
64
|
+
expect(applied).toBe(obj);
|
|
65
|
+
expect(applied.foo).toBe(obj.foo);
|
|
66
|
+
expect(applied.foo[0]).toBe(obj.foo[0]);
|
|
67
|
+
expect(applied.baz).toBe(obj.baz);
|
|
68
|
+
|
|
69
|
+
const patch2 = {
|
|
70
|
+
op: 'add',
|
|
71
|
+
path: '/foo/0',
|
|
72
|
+
value: '60px',
|
|
73
|
+
} as const;
|
|
74
|
+
const obj2 = {
|
|
75
|
+
foo: [{ bar: true }],
|
|
76
|
+
baz: {},
|
|
77
|
+
};
|
|
78
|
+
applyPatch(obj2, patch2);
|
|
79
|
+
expect(obj2.foo[0]).toBe('60px');
|
|
80
|
+
expect(obj2.foo[1]).toMatchObject({ bar: true });
|
|
81
|
+
|
|
82
|
+
applyPatch(obj2, {
|
|
83
|
+
op: 'remove',
|
|
84
|
+
path: '/foo/0',
|
|
85
|
+
value: undefined,
|
|
86
|
+
});
|
|
87
|
+
expect(obj2.foo[0]).toMatchObject({ bar: true });
|
|
88
|
+
expect(obj2.foo.length).toBe(1);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { get } from './get.js';
|
|
2
|
+
import { set } from './set.js';
|
|
3
|
+
|
|
4
|
+
export const applyPatch = <T extends object>(
|
|
5
|
+
obj: T,
|
|
6
|
+
patch: { path: string; op: 'add' | 'remove' | 'replace'; value: any }
|
|
7
|
+
): T => {
|
|
8
|
+
const pathArr: string[] = patch.path.split('/');
|
|
9
|
+
|
|
10
|
+
// If starts with slash
|
|
11
|
+
if (pathArr[0] === '') {
|
|
12
|
+
pathArr.shift();
|
|
13
|
+
}
|
|
14
|
+
if (patch.op === 'replace') {
|
|
15
|
+
set(obj, pathArr, patch.value);
|
|
16
|
+
return obj;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const lastChunk = get(obj, pathArr.slice(0, -1).join('.'));
|
|
20
|
+
if (patch.op === 'add') {
|
|
21
|
+
const newKey = pathArr.slice(-1)[0];
|
|
22
|
+
if (Array.isArray(lastChunk)) {
|
|
23
|
+
lastChunk.splice(Number(newKey), 0, patch.value);
|
|
24
|
+
} else {
|
|
25
|
+
lastChunk[newKey] = patch.value;
|
|
26
|
+
}
|
|
27
|
+
} else if (patch.op === 'remove') {
|
|
28
|
+
const key = pathArr.slice(-1)[0];
|
|
29
|
+
if (Array.isArray(lastChunk)) {
|
|
30
|
+
lastChunk.splice(Number(key), 1);
|
|
31
|
+
} else {
|
|
32
|
+
delete lastChunk[key];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return obj;
|
|
37
|
+
};
|