@builder.io/react 2.0.3 → 2.0.4-10
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 +4 -0
- 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 +4 -2
- package/dist/lib/src/blocks/Section.js +2 -0
- package/dist/lib/src/blocks/Section.js.map +1 -1
- package/dist/lib/src/blocks/Symbol.js +2 -2
- package/dist/lib/src/blocks/Symbol.js.map +1 -1
- package/dist/lib/src/components/builder-block.component.js +17 -11
- package/dist/lib/src/components/builder-block.component.js.map +1 -1
- package/dist/lib/src/components/builder-blocks.component.js.map +1 -1
- package/dist/lib/src/components/builder-component.component.js +30 -73
- package/dist/lib/src/components/builder-component.component.js.map +1 -1
- package/dist/lib/src/components/builder-content.component.js +5 -4
- package/dist/lib/src/components/builder-content.component.js.map +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.js +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.js.map +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.test.js +54 -0
- package/dist/lib/src/functions/apply-patch-with-mutation.test.js.map +1 -0
- package/dist/lib/src/scripts/init-editing.js +1 -1
- package/dist/types/src/components/builder-component.component.d.ts +6 -0
- package/dist/types/src/functions/apply-patch-with-mutation.d.ts +2 -2
- package/dist/types/src/functions/apply-patch-with-mutation.test.d.ts +1 -0
- package/package.json +4 -2
- package/src/blocks/Section.tsx +16 -11
- package/src/blocks/Symbol.tsx +1 -0
- package/src/components/builder-block.component.tsx +26 -14
- package/src/components/builder-blocks.component.tsx +10 -8
- package/src/components/builder-component.component.tsx +35 -73
- package/src/components/builder-content.component.tsx +4 -4
- package/src/functions/apply-patch-with-mutation.test.ts +55 -0
- package/src/functions/apply-patch-with-mutation.ts +5 -5
- package/src/scripts/init-editing.ts +1 -1
|
@@ -98,31 +98,6 @@ const sizeMap = {
|
|
|
98
98
|
mobile: 'small',
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
function decorator(fn: Function) {
|
|
102
|
-
return function argReceiver(...fnArgs: any[]) {
|
|
103
|
-
// Check if the decorator is being called without arguments (ex `@foo methodName() {}`)
|
|
104
|
-
if (fnArgs.length === 3) {
|
|
105
|
-
const [target, key, descriptor] = fnArgs;
|
|
106
|
-
if (descriptor && (descriptor.value || descriptor.get)) {
|
|
107
|
-
fnArgs = [];
|
|
108
|
-
return descriptorChecker(target, key, descriptor);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return descriptorChecker;
|
|
113
|
-
|
|
114
|
-
// descriptorChecker determines whether a method or getter is being decorated
|
|
115
|
-
// and replaces the appropriate key with the decorated function.
|
|
116
|
-
function descriptorChecker(target: any, key: any, descriptor: any) {
|
|
117
|
-
const descriptorKey = descriptor.value ? 'value' : 'get';
|
|
118
|
-
return {
|
|
119
|
-
...descriptor,
|
|
120
|
-
[descriptorKey]: fn(descriptor[descriptorKey], ...fnArgs),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
101
|
const fetchCache: { [key: string]: any } = {};
|
|
127
102
|
|
|
128
103
|
export interface BuilderComponentProps {
|
|
@@ -301,6 +276,11 @@ export interface BuilderComponentProps {
|
|
|
301
276
|
* navigation to other pages unintended
|
|
302
277
|
*/
|
|
303
278
|
stopClickPropagationWhenEditing?: boolean;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Locale code, should match one of the locales in your spaces locale, wll auto resolve the localized inputs to the localized value
|
|
282
|
+
*/
|
|
283
|
+
locale?: string;
|
|
304
284
|
}
|
|
305
285
|
|
|
306
286
|
export interface BuilderComponentState {
|
|
@@ -865,7 +845,7 @@ export class BuilderComponent extends React.Component<
|
|
|
865
845
|
get data() {
|
|
866
846
|
const data = {
|
|
867
847
|
...(this.inlinedContent && this.inlinedContent.data?.state),
|
|
868
|
-
...this.
|
|
848
|
+
...this.externalState,
|
|
869
849
|
...this.state.state,
|
|
870
850
|
};
|
|
871
851
|
Object.assign(this.rootState, data);
|
|
@@ -876,7 +856,7 @@ export class BuilderComponent extends React.Component<
|
|
|
876
856
|
// TODO: shallow diff
|
|
877
857
|
if (this.props.data && prevProps.data !== this.props.data) {
|
|
878
858
|
this.state.update((state: any) => {
|
|
879
|
-
Object.assign(state, this.
|
|
859
|
+
Object.assign(state, this.externalState);
|
|
880
860
|
});
|
|
881
861
|
}
|
|
882
862
|
|
|
@@ -916,6 +896,13 @@ export class BuilderComponent extends React.Component<
|
|
|
916
896
|
return content;
|
|
917
897
|
}
|
|
918
898
|
|
|
899
|
+
get externalState() {
|
|
900
|
+
return {
|
|
901
|
+
...this.props.data,
|
|
902
|
+
...(this.props.locale ? { locale: this.props.locale } : {}),
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
919
906
|
get useContent() {
|
|
920
907
|
return this.content || this.state.context.builderContent;
|
|
921
908
|
}
|
|
@@ -924,7 +911,10 @@ export class BuilderComponent extends React.Component<
|
|
|
924
911
|
const content = this.content;
|
|
925
912
|
|
|
926
913
|
const dataString =
|
|
927
|
-
Builder.isBrowser &&
|
|
914
|
+
Builder.isBrowser &&
|
|
915
|
+
this.externalState &&
|
|
916
|
+
size(this.externalState) &&
|
|
917
|
+
hash(this.externalState);
|
|
928
918
|
let key = Builder.isEditing ? this.name : this.props.entry;
|
|
929
919
|
if (key && !Builder.isEditing && dataString && dataString.length < 300) {
|
|
930
920
|
key += ':' + dataString;
|
|
@@ -995,6 +985,7 @@ export class BuilderComponent extends React.Component<
|
|
|
995
985
|
!this.isPreviewing && { initialContent: [] }),
|
|
996
986
|
...(this.props.url && { url: this.props.url }),
|
|
997
987
|
...this.props.options,
|
|
988
|
+
...(this.props.locale ? { locale: this.props.locale } : {}),
|
|
998
989
|
...(this.options.codegen && {
|
|
999
990
|
format: 'react',
|
|
1000
991
|
}),
|
|
@@ -1264,7 +1255,6 @@ export class BuilderComponent extends React.Component<
|
|
|
1264
1255
|
this.notifyStateChange();
|
|
1265
1256
|
}
|
|
1266
1257
|
|
|
1267
|
-
// Unsubscribe all? TODO: maybe don't continuous fire when editing.....
|
|
1268
1258
|
if (this.props.contentLoaded) {
|
|
1269
1259
|
this.props.contentLoaded(data, content);
|
|
1270
1260
|
}
|
|
@@ -1274,12 +1264,6 @@ export class BuilderComponent extends React.Component<
|
|
|
1274
1264
|
data.state = {};
|
|
1275
1265
|
}
|
|
1276
1266
|
|
|
1277
|
-
// Maybe...
|
|
1278
|
-
// if (data.context) {
|
|
1279
|
-
// Object.assign(this.state.context, data.context)
|
|
1280
|
-
// }
|
|
1281
|
-
// TODO: may not want this... or make sure anything overriden
|
|
1282
|
-
// explitily sets to null
|
|
1283
1267
|
data.inputs.forEach((input: any) => {
|
|
1284
1268
|
if (input) {
|
|
1285
1269
|
if (
|
|
@@ -1303,7 +1287,7 @@ export class BuilderComponent extends React.Component<
|
|
|
1303
1287
|
deviceSize: this.deviceSizeState,
|
|
1304
1288
|
device: this.device,
|
|
1305
1289
|
...data.state,
|
|
1306
|
-
...this.
|
|
1290
|
+
...this.externalState,
|
|
1307
1291
|
}),
|
|
1308
1292
|
};
|
|
1309
1293
|
if (this.mounted) {
|
|
@@ -1380,8 +1364,6 @@ export class BuilderComponent extends React.Component<
|
|
|
1380
1364
|
for (const key in data.httpRequests) {
|
|
1381
1365
|
const url: string | undefined = data.httpRequests[key];
|
|
1382
1366
|
if (url && (!this.data[key] || Builder.isEditing)) {
|
|
1383
|
-
// TODO: if Builder.isEditing and url patches https://builder.io/api/v2/content/{editingModel}
|
|
1384
|
-
// Then use this.builder.get().subscribe(...)
|
|
1385
1367
|
if (Builder.isBrowser) {
|
|
1386
1368
|
const finalUrl = this.evalExpression(url);
|
|
1387
1369
|
if (Builder.isEditing && this.lastHttpRequests[key] === finalUrl) {
|
|
@@ -1391,47 +1373,27 @@ export class BuilderComponent extends React.Component<
|
|
|
1391
1373
|
const builderModelRe = /builder\.io\/api\/v2\/([^\/\?]+)/i;
|
|
1392
1374
|
const builderModelMatch = url.match(builderModelRe);
|
|
1393
1375
|
const model = builderModelMatch && builderModelMatch[1];
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
// this.builder.get(model).subscribe(data => {
|
|
1399
|
-
// this.state.update((state: any) => {
|
|
1400
|
-
// state[key] = data
|
|
1401
|
-
// })
|
|
1402
|
-
// })
|
|
1403
|
-
// )
|
|
1404
|
-
} else {
|
|
1405
|
-
this.handleRequest(key, finalUrl);
|
|
1406
|
-
const currentSubscription = this.httpSubscriptionPerKey[key];
|
|
1407
|
-
if (currentSubscription) {
|
|
1408
|
-
currentSubscription.unsubscribe();
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
// TODO: fix this
|
|
1412
|
-
const newSubscription = (this.httpSubscriptionPerKey[key] =
|
|
1413
|
-
this.onStateChange.subscribe(() => {
|
|
1414
|
-
const newUrl = this.evalExpression(url);
|
|
1415
|
-
if (newUrl !== finalUrl) {
|
|
1416
|
-
this.handleRequest(key, newUrl);
|
|
1417
|
-
this.lastHttpRequests[key] = newUrl;
|
|
1418
|
-
}
|
|
1419
|
-
}));
|
|
1420
|
-
this.subscriptions.add(newSubscription);
|
|
1376
|
+
this.handleRequest(key, finalUrl);
|
|
1377
|
+
const currentSubscription = this.httpSubscriptionPerKey[key];
|
|
1378
|
+
if (currentSubscription) {
|
|
1379
|
+
currentSubscription.unsubscribe();
|
|
1421
1380
|
}
|
|
1381
|
+
|
|
1382
|
+
// TODO: fix this
|
|
1383
|
+
const newSubscription = (this.httpSubscriptionPerKey[key] =
|
|
1384
|
+
this.onStateChange.subscribe(() => {
|
|
1385
|
+
const newUrl = this.evalExpression(url);
|
|
1386
|
+
if (newUrl !== finalUrl) {
|
|
1387
|
+
this.handleRequest(key, newUrl);
|
|
1388
|
+
this.lastHttpRequests[key] = newUrl;
|
|
1389
|
+
}
|
|
1390
|
+
}));
|
|
1391
|
+
this.subscriptions.add(newSubscription);
|
|
1422
1392
|
} else {
|
|
1423
1393
|
this.handleRequest(key, this.evalExpression(url));
|
|
1424
1394
|
}
|
|
1425
1395
|
}
|
|
1426
1396
|
}
|
|
1427
|
-
|
|
1428
|
-
// @DEPRECATED
|
|
1429
|
-
// for (const key in data.builderData) {
|
|
1430
|
-
// const url = data.builderData[key]
|
|
1431
|
-
// if (url && !this.data[key]) {
|
|
1432
|
-
// this.handleBuilderRequest(key, this.evalExpression(url))
|
|
1433
|
-
// }
|
|
1434
|
-
// }
|
|
1435
1397
|
}
|
|
1436
1398
|
}
|
|
1437
1399
|
};
|
|
@@ -140,17 +140,17 @@ export class BuilderContent<ContentType extends object = any> extends React.Comp
|
|
|
140
140
|
if (location.href.includes('builder.debug=true')) {
|
|
141
141
|
eval('debugger');
|
|
142
142
|
}
|
|
143
|
+
let newData = this.state.data as any;
|
|
143
144
|
for (const patch of patches) {
|
|
144
|
-
applyPatchWithMinimalMutationChain(
|
|
145
|
+
newData = applyPatchWithMinimalMutationChain(newData, patch, false);
|
|
145
146
|
}
|
|
146
147
|
this.setState({
|
|
147
148
|
updates: this.state.updates + 1,
|
|
148
|
-
data:
|
|
149
|
+
data: newData,
|
|
149
150
|
});
|
|
150
151
|
if (this.props.contentLoaded) {
|
|
151
|
-
this.props.contentLoaded(
|
|
152
|
+
this.props.contentLoaded(newData.data, newData);
|
|
152
153
|
}
|
|
153
|
-
|
|
154
154
|
break;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { applyPatchWithMinimalMutationChain } from './apply-patch-with-mutation';
|
|
2
|
+
|
|
3
|
+
describe('applyPatchWithMinimalMutationChain', () => {
|
|
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 = applyPatchWithMinimalMutationChain(obj, patch);
|
|
14
|
+
expect(applied.foo).toBe('60px');
|
|
15
|
+
expect(applied).not.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 = applyPatchWithMinimalMutationChain(obj, patch);
|
|
31
|
+
expect(applied.foo.bar).toBe('60px');
|
|
32
|
+
expect(applied).not.toBe(obj);
|
|
33
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
34
|
+
expect(applied.baz).toBe(obj.baz);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('Deep array updates', () => {
|
|
38
|
+
const obj = {
|
|
39
|
+
foo: [{ bar: true }],
|
|
40
|
+
baz: {},
|
|
41
|
+
};
|
|
42
|
+
const patch = {
|
|
43
|
+
op: 'replace',
|
|
44
|
+
path: '/foo/0/bar',
|
|
45
|
+
value: '60px',
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
const applied = applyPatchWithMinimalMutationChain(obj, patch);
|
|
49
|
+
expect(applied.foo[0].bar).toBe('60px');
|
|
50
|
+
expect(applied).not.toBe(obj);
|
|
51
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
52
|
+
expect(applied.foo[0]).not.toBe(obj.foo[0]);
|
|
53
|
+
expect(applied.baz).toBe(obj.baz);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export const applyPatchWithMinimalMutationChain = (
|
|
2
|
-
obj:
|
|
1
|
+
export const applyPatchWithMinimalMutationChain = <T extends object>(
|
|
2
|
+
obj: T,
|
|
3
3
|
patch: { path: string; op: 'add' | 'remove' | 'replace'; value: any },
|
|
4
|
-
preserveRoot =
|
|
5
|
-
) => {
|
|
4
|
+
preserveRoot = false
|
|
5
|
+
): T => {
|
|
6
6
|
if (Object(obj) !== obj) {
|
|
7
7
|
return obj;
|
|
8
8
|
}
|
|
@@ -13,7 +13,7 @@ export const applyPatchWithMinimalMutationChain = (
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const newObj = preserveRoot ? obj : { ...obj };
|
|
16
|
-
let objPart = newObj;
|
|
16
|
+
let objPart = newObj as any;
|
|
17
17
|
for (let i = 0; i < pathArr.length; i++) {
|
|
18
18
|
const isLast = i === pathArr.length - 1;
|
|
19
19
|
const property = pathArr[i];
|