@builder.io/react 2.0.6 → 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.
Files changed (46) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +51 -41
  3. package/dist/builder-react-lite.cjs.js +1 -1
  4. package/dist/builder-react-lite.cjs.js.map +1 -1
  5. package/dist/builder-react-lite.esm.js +1 -1
  6. package/dist/builder-react-lite.esm.js.map +1 -1
  7. package/dist/builder-react.browser.js +1 -1
  8. package/dist/builder-react.browser.js.map +1 -1
  9. package/dist/builder-react.cjs.js +1 -1
  10. package/dist/builder-react.cjs.js.map +1 -1
  11. package/dist/builder-react.es5.js +1 -1
  12. package/dist/builder-react.es5.js.map +1 -1
  13. package/dist/builder-react.unpkg.js +1 -1
  14. package/dist/builder-react.unpkg.js.map +1 -1
  15. package/dist/lib/package.json +2 -2
  16. package/dist/lib/src/components/builder-block.component.js +14 -10
  17. package/dist/lib/src/components/builder-block.component.js.map +1 -1
  18. package/dist/lib/src/components/builder-component.component.js +9 -2
  19. package/dist/lib/src/components/builder-component.component.js.map +1 -1
  20. package/dist/lib/src/constants/device-sizes.constant.js +41 -2
  21. package/dist/lib/src/constants/device-sizes.constant.js.map +1 -1
  22. package/dist/lib/src/functions/apply-patch.js +38 -0
  23. package/dist/lib/src/functions/apply-patch.js.map +1 -0
  24. package/dist/lib/src/functions/apply-patch.test.js +85 -0
  25. package/dist/lib/src/functions/apply-patch.test.js.map +1 -0
  26. package/dist/lib/src/functions/try-eval.js.map +1 -1
  27. package/dist/lib/src/functions/utils.js +7 -0
  28. package/dist/lib/src/functions/utils.js.map +1 -0
  29. package/dist/lib/src/scripts/init-editing.js +2 -1
  30. package/dist/lib/src/scripts/init-editing.js.map +1 -1
  31. package/dist/types/src/components/builder-component.component.d.ts +1 -0
  32. package/dist/types/src/constants/device-sizes.constant.d.ts +31 -1
  33. package/dist/types/src/functions/apply-patch.d.ts +5 -0
  34. package/dist/types/src/functions/apply-patch.test.d.ts +1 -0
  35. package/dist/types/src/functions/utils.d.ts +1 -0
  36. package/jest.config.js +5 -0
  37. package/package.json +2 -2
  38. package/src/components/builder-block.component.tsx +15 -7
  39. package/src/components/builder-component.component.tsx +10 -2
  40. package/src/constants/device-sizes.constant.ts +43 -1
  41. package/src/functions/apply-patch.test.ts +90 -0
  42. package/src/functions/apply-patch.ts +37 -0
  43. package/src/functions/try-eval.tsx +1 -1
  44. package/src/functions/utils.ts +2 -0
  45. package/src/scripts/init-editing.ts +2 -1
  46. package/src/components/core-react.code-workspace +0 -14
@@ -1,6 +1,6 @@
1
1
  export declare type Size = 'large' | 'medium' | 'small' | 'xsmall';
2
2
  export declare const sizeNames: Size[];
3
- export declare const sizes: {
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,5 @@
1
+ export declare const applyPatch: <T extends object>(obj: T, patch: {
2
+ path: string;
3
+ op: 'add' | 'remove' | 'replace';
4
+ value: any;
5
+ }) => T;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/react",
3
- "version": "2.0.6",
3
+ "version": "2.0.8-0",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "main": "dist/builder-react.cjs.js",
@@ -123,7 +123,7 @@
123
123
  "react-dom": ">=16.8.0"
124
124
  },
125
125
  "dependencies": {
126
- "@builder.io/sdk": "^1.1.29",
126
+ "@builder.io/sdk": "^1.1.30",
127
127
  "@emotion/core": "^10.0.17",
128
128
  "hash-sum": "^2.0.0",
129
129
  "preact": "^10.1.0",
@@ -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, sizes } from '../constants/device-sizes.constant';
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
- styles[`@media only screen and (max-width: ${sizes[size].max}px)`] = {
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
- applyPatchWithMinimalMutationChain(this.props.block, patch, true);
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((collectionPath || '').trim().split('(')[0].trim().split('.'));
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 { sizes } from '../constants/device-sizes.constant';
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
- export const sizes = {
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
+ };
@@ -36,7 +36,7 @@ export const tryEval = (str?: string, data: any = {}, errors?: Error[]): any =>
36
36
  }`
37
37
  );
38
38
  }
39
- } catch (error) {
39
+ } catch (error: any) {
40
40
  if (Builder.isBrowser) {
41
41
  console.warn('Could not compile javascript', error);
42
42
  } else {
@@ -0,0 +1,2 @@
1
+ // TODO: pull from builder internal utils
2
+ export const fastClone = <T extends object>(obj: T): T => JSON.parse(JSON.stringify(obj));
@@ -6,7 +6,8 @@ if (typeof window !== 'undefined') {
6
6
  type: 'builder.isReactSdk',
7
7
  data: {
8
8
  value: true,
9
- supportsPatchUpdates: 'v4',
9
+ supportsPatchUpdates: 'v5',
10
+ supportsCustomBreakpoints: true,
10
11
  priorVersion: version,
11
12
  },
12
13
  },
@@ -1,14 +0,0 @@
1
- {
2
- "folders": [
3
- {
4
- "path": "../.."
5
- },
6
- {
7
- "path": "../../../core"
8
- },
9
- {
10
- "path": "../../../../examples/next-js-simple"
11
- }
12
- ],
13
- "settings": {}
14
- }