diff --git a/editor/src/components/canvas/__snapshots__/ui-jsx-canvas.spec.tsx.snap b/editor/src/components/canvas/__snapshots__/ui-jsx-canvas.spec.tsx.snap index 20b1d5af68a5..5655ec7ea763 100644 --- a/editor/src/components/canvas/__snapshots__/ui-jsx-canvas.spec.tsx.snap +++ b/editor/src/components/canvas/__snapshots__/ui-jsx-canvas.spec.tsx.snap @@ -6,7 +6,7 @@ exports[`UiJsxCanvas render Label carried through for generated elements 1`] = ` id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3 utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
@@ -513,6 +513,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -706,7 +709,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -821,6 +824,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -832,7 +838,7 @@ Object { ], Array [ "aaa", - "a8d", + "2c3", ], ], "type": "elementpath", @@ -902,7 +908,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -966,7 +972,7 @@ Object { ], Array [ "aaa", - "a8d", + "2c3", "bbb~~~1", ], ], @@ -1041,7 +1047,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -1105,7 +1111,7 @@ Object { ], Array [ "aaa", - "a8d", + "2c3", "bbb~~~2", ], ], @@ -1180,7 +1186,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/a8d/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/2c3/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -1244,7 +1250,7 @@ Object { ], Array [ "aaa", - "a8d", + "2c3", "bbb~~~3", ], ], @@ -2428,7 +2434,7 @@ exports[`UiJsxCanvas render arbitrary jsx block inside an element inside an arbi id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1 utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa/b6e\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa/b6e\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
1
2
3
@@ -2978,6 +2984,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -3091,7 +3100,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -3247,6 +3256,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -3258,7 +3270,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", ], ], "type": "elementpath", @@ -3328,7 +3340,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -3430,7 +3442,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~1", ], ], @@ -3505,7 +3517,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~1/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~1/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -3576,7 +3588,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~1", "b6e", ], @@ -3648,7 +3660,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -3750,7 +3762,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~2", ], ], @@ -3825,7 +3837,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~2/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~2/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -3896,7 +3908,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~2", "b6e", ], @@ -3968,7 +3980,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -4070,7 +4082,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~3", ], ], @@ -4145,7 +4157,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/4c1/aaa~~~3/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/76c/aaa~~~3/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -4216,7 +4228,7 @@ Object { ], Array [ "zzz", - "4c1", + "76c", "aaa~~~3", "b6e", ], @@ -4297,7 +4309,7 @@ exports[`UiJsxCanvas render arbitrary jsx block inside an element inside an arbi id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80 utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa/d9d utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa/d9d/bbb utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa/d9d/bbb/d0c\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5 utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa/60a utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa/60a/bbb utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa/60a/bbb/d0c\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
4
5
6
8
10
12
12
15
18
@@ -4923,6 +4935,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, ], "name": Object { @@ -5022,6 +5037,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -5135,7 +5153,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -5316,6 +5334,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, ], "name": Object { @@ -5415,6 +5436,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -5426,7 +5450,7 @@ Object { ], Array [ "zzz", - "e80", + "5c5", ], ], "type": "elementpath", @@ -5496,7 +5520,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -5667,6 +5691,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, ], "name": Object { @@ -5707,7 +5734,7 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", ], ], @@ -5782,7 +5809,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -5951,6 +5978,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, }, "elementPath": Object { @@ -5962,9 +5992,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", ], ], "type": "elementpath", @@ -6034,7 +6064,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6142,9 +6172,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~1", ], ], @@ -6219,7 +6249,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~1/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~1/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6296,9 +6326,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~1", "d0c", ], @@ -6370,7 +6400,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6478,9 +6508,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~2", ], ], @@ -6555,7 +6585,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~2/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~2/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6632,9 +6662,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~2", "d0c", ], @@ -6706,7 +6736,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6814,9 +6844,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~3", ], ], @@ -6891,7 +6921,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~1/d9d/bbb~~~3/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~1/60a/bbb~~~3/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -6968,9 +6998,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~1", - "d9d", + "60a", "bbb~~~3", "d0c", ], @@ -7042,7 +7072,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -7213,6 +7243,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, ], "name": Object { @@ -7253,7 +7286,7 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", ], ], @@ -7328,7 +7361,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -7497,6 +7530,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, }, "elementPath": Object { @@ -7508,9 +7544,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", ], ], "type": "elementpath", @@ -7580,7 +7616,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -7688,9 +7724,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~1", ], ], @@ -7765,7 +7801,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~1/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~1/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -7842,9 +7878,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~1", "d0c", ], @@ -7916,7 +7952,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -8024,9 +8060,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~2", ], ], @@ -8101,7 +8137,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~2/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~2/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -8178,9 +8214,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~2", "d0c", ], @@ -8252,7 +8288,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -8360,9 +8396,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~3", ], ], @@ -8437,7 +8473,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~2/d9d/bbb~~~3/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~2/60a/bbb~~~3/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -8514,9 +8550,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~2", - "d9d", + "60a", "bbb~~~3", "d0c", ], @@ -8588,7 +8624,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -8759,6 +8795,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, ], "name": Object { @@ -8799,7 +8838,7 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", ], ], @@ -8874,7 +8913,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9043,6 +9082,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "m", + ], }, }, "elementPath": Object { @@ -9054,9 +9096,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", ], ], "type": "elementpath", @@ -9126,7 +9168,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9234,9 +9276,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~1", ], ], @@ -9311,7 +9353,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~1/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~1/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9388,9 +9430,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~1", "d0c", ], @@ -9462,7 +9504,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9570,9 +9612,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~2", ], ], @@ -9647,7 +9689,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~2/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~2/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9724,9 +9766,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~2", "d0c", ], @@ -9798,7 +9840,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -9906,9 +9948,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~3", ], ], @@ -9983,7 +10025,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/e80/aaa~~~3/d9d/bbb~~~3/d0c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/5c5/aaa~~~3/60a/bbb~~~3/d0c": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -10060,9 +10102,9 @@ Object { ], Array [ "zzz", - "e80", + "5c5", "aaa~~~3", - "d9d", + "60a", "bbb~~~3", "d0c", ], @@ -11542,7 +11584,7 @@ exports[`UiJsxCanvas render does not crash if the metadata scenes are not the ap id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7 utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08 utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
n1
n2
n3
@@ -12102,6 +12144,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -12216,7 +12261,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -12382,6 +12427,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -12393,7 +12441,7 @@ Object { ], Array [ "aaa", - "6a7", + "f08", ], ], "type": "elementpath", @@ -12463,7 +12511,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -12575,7 +12623,7 @@ Object { ], Array [ "aaa", - "6a7", + "f08", "bbb~~~1", ], ], @@ -12650,7 +12698,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -12762,7 +12810,7 @@ Object { ], Array [ "aaa", - "6a7", + "f08", "bbb~~~2", ], ], @@ -12837,7 +12885,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/6a7/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f08/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -12949,7 +12997,7 @@ Object { ], Array [ "aaa", - "6a7", + "f08", "bbb~~~3", ], ], @@ -13033,7 +13081,7 @@ exports[`UiJsxCanvas render does not crash if the metadata scenes are undefined id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/311 utopia-storyboard-uid/scene-aaa/app-entity:aaa/311/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
n1
n2
n3
@@ -13593,6 +13641,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -13707,7 +13758,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/311": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -13873,6 +13924,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -13884,7 +13938,7 @@ Object { ], Array [ "aaa", - "dad", + "311", ], ], "type": "elementpath", @@ -13954,7 +14008,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/311/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -14066,7 +14120,7 @@ Object { ], Array [ "aaa", - "dad", + "311", "bbb~~~1", ], ], @@ -14141,7 +14195,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/311/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -14253,7 +14307,7 @@ Object { ], Array [ "aaa", - "dad", + "311", "bbb~~~2", ], ], @@ -14328,7 +14382,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/dad/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/311/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -14440,7 +14494,7 @@ Object { ], Array [ "aaa", - "dad", + "311", "bbb~~~3", ], ], @@ -15342,7 +15396,7 @@ exports[`UiJsxCanvas render function component works inside a map 1`] = ` id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/a97 utopia-storyboard-uid/scene-aaa/app-entity:zzz/a97/aaa\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:zzz utopia-storyboard-uid/scene-aaa/app-entity:zzz/fc2 utopia-storyboard-uid/scene-aaa/app-entity:zzz/fc2/aaa\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
Thing
Thing
@@ -15832,6 +15886,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "data", + ], }, ], "name": Object { @@ -15945,7 +16002,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/a97": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/fc2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -16047,6 +16104,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "data", + ], }, }, "elementPath": Object { @@ -16058,7 +16118,7 @@ Object { ], Array [ "zzz", - "a97", + "fc2", ], ], "type": "elementpath", @@ -16128,7 +16188,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/a97/aaa~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/fc2/aaa~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -16175,7 +16235,7 @@ Object { ], Array [ "zzz", - "a97", + "fc2", "aaa~~~1", ], ], @@ -16250,7 +16310,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:zzz/a97/aaa~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:zzz/fc2/aaa~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -16297,7 +16357,7 @@ Object { ], Array [ "zzz", - "a97", + "fc2", "aaa~~~2", ], ], @@ -21022,7 +21082,7 @@ exports[`UiJsxCanvas render handles fragments in an arbitrary block 1`] = ` id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834/604 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999/000\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834/604 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999 utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999/000\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
Copy
C @@ -21111,32 +21171,32 @@ exports[`UiJsxCanvas render handles fragments in an arbitrary block 1`] = `
Paste
V @@ -21144,32 +21204,32 @@ exports[`UiJsxCanvas render handles fragments in an arbitrary block 1`] = `
Cut
C @@ -22294,6 +22354,9 @@ export var storyboard = (props) => { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "pair", + ], }, ], "name": Object { @@ -23528,6 +23591,9 @@ export var storyboard = (props) => { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "pair", + ], }, ], "name": Object { @@ -23642,7 +23708,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -24414,6 +24480,9 @@ export var storyboard = (props) => { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "pair", + ], }, }, "elementPath": Object { @@ -24426,7 +24495,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", ], ], "type": "elementpath", @@ -24496,7 +24565,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -24801,7 +24870,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~1", ], ], @@ -24876,7 +24945,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~1/604": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~1/604": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -25018,7 +25087,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~1", "604", ], @@ -25090,7 +25159,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -25395,7 +25464,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~3", ], ], @@ -25470,7 +25539,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~3/604": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~3/604": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -25612,7 +25681,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~3", "604", ], @@ -25684,7 +25753,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~5": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~5": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -25989,7 +26058,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~5", ], ], @@ -26064,7 +26133,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/834~~~5/604": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/834~~~5/604": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -26206,7 +26275,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "834~~~5", "604", ], @@ -26278,7 +26347,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -26621,7 +26690,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~2", ], ], @@ -26696,7 +26765,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~2/000": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~2/000": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -26876,7 +26945,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~2", "000", ], @@ -26952,7 +27021,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~4": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~4": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -27295,7 +27364,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~4", ], ], @@ -27370,7 +27439,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~4/000": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~4/000": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -27550,7 +27619,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~4", "000", ], @@ -27626,7 +27695,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~6": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~6": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -27969,7 +28038,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~6", ], ], @@ -28044,7 +28113,7 @@ export var storyboard = (props) => { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/dfc/999~~~6/000": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/03a/d3e/999~~~6/000": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -28224,7 +28293,7 @@ export var storyboard = (props) => { Array [ "aaa", "03a", - "dfc", + "d3e", "999~~~6", "000", ], @@ -37133,7 +37202,7 @@ exports[`UiJsxCanvas render renders a component used in an arbitrary block corre id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/517 utopia-storyboard-uid/scene-aaa/app-entity:aaa/517/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05 utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
n1
n2
n3
@@ -37693,6 +37762,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -37807,7 +37879,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/517": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -37973,6 +38045,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -37984,7 +38059,7 @@ Object { ], Array [ "aaa", - "517", + "b05", ], ], "type": "elementpath", @@ -38054,7 +38129,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/517/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -38166,7 +38241,7 @@ Object { ], Array [ "aaa", - "517", + "b05", "bbb~~~1", ], ], @@ -38241,7 +38316,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/517/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -38353,7 +38428,7 @@ Object { ], Array [ "aaa", - "517", + "b05", "bbb~~~2", ], ], @@ -38428,7 +38503,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/517/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/b05/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -38540,7 +38615,7 @@ Object { ], Array [ "aaa", - "517", + "b05", "bbb~~~3", ], ], @@ -38624,7 +38699,7 @@ exports[`UiJsxCanvas render renders a component used in an arbitrary block corre id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8 utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0 utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
n1
n2
n3
@@ -39185,6 +39260,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "div", + ], }, ], "name": Object { @@ -39299,7 +39377,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -39466,6 +39544,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "div", + ], }, }, "elementPath": Object { @@ -39477,7 +39558,7 @@ Object { ], Array [ "aaa", - "5d8", + "ec0", ], ], "type": "elementpath", @@ -39547,7 +39628,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -39660,7 +39741,7 @@ Object { ], Array [ "aaa", - "5d8", + "ec0", "bbb~~~1", ], ], @@ -39735,7 +39816,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -39848,7 +39929,7 @@ Object { ], Array [ "aaa", - "5d8", + "ec0", "bbb~~~2", ], ], @@ -39923,7 +40004,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/5d8/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/ec0/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -40036,7 +40117,7 @@ Object { ], Array [ "aaa", - "5d8", + "ec0", "bbb~~~3", ], ], @@ -40120,7 +40201,7 @@ exports[`UiJsxCanvas render renders a component used in an arbitrary block with id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c/bbb\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9 utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9/bbb\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
n1
n2
n3
@@ -40687,6 +40768,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -40801,7 +40885,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -40974,6 +41058,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -40985,7 +41072,7 @@ Object { ], Array [ "aaa", - "d7c", + "4c9", ], ], "type": "elementpath", @@ -41055,7 +41142,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -41167,7 +41254,7 @@ Object { ], Array [ "aaa", - "d7c", + "4c9", "bbb~~~1", ], ], @@ -41242,7 +41329,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -41354,7 +41441,7 @@ Object { ], Array [ "aaa", - "d7c", + "4c9", "bbb~~~2", ], ], @@ -41429,7 +41516,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d7c/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/4c9/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -41541,7 +41628,7 @@ Object { ], Array [ "aaa", - "d7c", + "4c9", "bbb~~~3", ], ], @@ -50353,7 +50440,7 @@ exports[`UiJsxCanvas render supports passing down the scope to children of compo id=\\"canvas-container\\" data-testid=\\"canvas-container\\" style=\\"position: absolute\\" - data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62 utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb/ccc utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb/ccc/b6e\\" + data-utopia-valid-paths=\\"utopia-storyboard-uid utopia-storyboard-uid/scene-aaa utopia-storyboard-uid/scene-aaa/app-entity utopia-storyboard-uid/scene-aaa/app-entity:aaa utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59 utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb/ccc utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb/ccc/b6e\\" data-utopia-root-element-path=\\"utopia-storyboard-uid\\" >
1
2
3
@@ -50957,6 +51044,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, ], "name": Object { @@ -51071,7 +51161,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -51266,6 +51356,9 @@ Object { });", "type": "JSX_MAP_EXPRESSION", "uid": "", + "valuesInScopeFromParameters": Array [ + "n", + ], }, }, "elementPath": Object { @@ -51277,7 +51370,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", ], ], "type": "elementpath", @@ -51347,7 +51440,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~1": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~1": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -51483,7 +51576,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~1", ], ], @@ -51558,7 +51651,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~1/ccc": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~1/ccc": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -51663,7 +51756,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~1", "ccc", ], @@ -51739,7 +51832,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~1/ccc/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~1/ccc/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -51813,7 +51906,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~1", "ccc", "b6e", @@ -51886,7 +51979,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~2": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~2": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52022,7 +52115,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~2", ], ], @@ -52097,7 +52190,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~2/ccc": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~2/ccc": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52202,7 +52295,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~2", "ccc", ], @@ -52278,7 +52371,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~2/ccc/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~2/ccc/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52352,7 +52445,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~2", "ccc", "b6e", @@ -52425,7 +52518,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~3": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~3": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52561,7 +52654,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~3", ], ], @@ -52636,7 +52729,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~3/ccc": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~3/ccc": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52741,7 +52834,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~3", "ccc", ], @@ -52817,7 +52910,7 @@ Object { }, "textContent": null, }, - "utopia-storyboard-uid/scene-aaa/app-entity:aaa/f62/bbb~~~3/ccc/b6e": Object { + "utopia-storyboard-uid/scene-aaa/app-entity:aaa/d59/bbb~~~3/ccc/b6e": Object { "attributeMetadatada": Object {}, "componentInstance": false, "computedStyle": Object {}, @@ -52891,7 +52984,7 @@ Object { ], Array [ "aaa", - "f62", + "d59", "bbb~~~3", "ccc", "b6e", diff --git a/editor/src/components/canvas/canvas-strategies/strategies/reparent-utils.ts b/editor/src/components/canvas/canvas-strategies/strategies/reparent-utils.ts index 390b065ccbe9..c3130a9a5542 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/reparent-utils.ts +++ b/editor/src/components/canvas/canvas-strategies/strategies/reparent-utils.ts @@ -4,7 +4,12 @@ import { getJSXElementFromProjectContents, withUnderlyingTarget, } from '../../../editor/store/editor-state' -import type { ElementPath, Imports, NodeModules } from '../../../../core/shared/project-file-types' +import { + StaticElementPath, + type ElementPath, + type Imports, + type NodeModules, +} from '../../../../core/shared/project-file-types' import type { CanvasCommand } from '../../commands/commands' import { reparentElement } from '../../commands/reparent-element-command' import type { @@ -35,12 +40,12 @@ import { } from '../../../editor/store/insertion-path' import { getUtopiaID } from '../../../../core/shared/uid-utils' import type { IndexPosition } from '../../../../utils/utils' -import { fastForEach } from '../../../../core/shared/utils' +import { assertNever, fastForEach } from '../../../../core/shared/utils' import { addElements } from '../../commands/add-elements-command' import type { ElementPathTrees } from '../../../../core/shared/element-path-tree' import { getRequiredGroupTrueUps } from '../../commands/queue-true-up-command' import type { Either } from '../../../../core/shared/either' -import { left, right } from '../../../../core/shared/either' +import { flatMapEither, foldEither, left, right } from '../../../../core/shared/either' import { maybeBranchConditionalCase } from '../../../../core/model/conditionals' import type { NonEmptyArray } from '../../../../core/shared/array-utils' import { @@ -54,6 +59,9 @@ import { isElementRenderedBySameComponent } from './reparent-helpers/reparent-he import type { ParsedCopyData } from '../../../../utils/clipboard' import { getParseSuccessForFilePath } from '../../canvas-utils' import { renameDuplicateImports } from '../../../../core/shared/import-shared-utils' +import { modify, set } from '../../../../core/shared/optics/optic-utilities' +import { fromField, fromTypeGuard } from '../../../../core/shared/optics/optic-creators' +import { Optic } from '../../../../core/shared/optics/optics' interface GetReparentOutcomeResult { commands: Array @@ -366,14 +374,31 @@ function rectangleSizesEqual(a: CanvasRectangle, b: CanvasRectangle): boolean { return a.height === b.height && a.width === b.width } -export type ReparentTargetForPaste = - | { - type: 'sibling' - siblingPath: ElementPath - siblingBounds: CanvasRectangle - parentPath: InsertionPath - } - | { type: 'parent'; parentPath: InsertionPath } +export interface SiblingReparentTargetForPaste { + type: 'sibling' + siblingPath: ElementPath + siblingBounds: CanvasRectangle + parentPath: InsertionPath +} + +export interface ParentReparentTargetForPaste { + type: 'parent' + parentPath: InsertionPath +} + +export type ReparentTargetForPaste = SiblingReparentTargetForPaste | ParentReparentTargetForPaste + +export function isSiblingReparentTargetForPaste( + target: ReparentTargetForPaste, +): target is SiblingReparentTargetForPaste { + return target.type === 'sibling' +} + +export function isParentReparentTargetForPaste( + target: ReparentTargetForPaste, +): target is ParentReparentTargetForPaste { + return target.type === 'parent' +} type PasteParentNotFoundError = | 'Cannot find a suitable parent' @@ -509,34 +534,45 @@ function pasteNextToSameSizedElement( return null } -function pasteIntoParentOrGrandparent( - elementsToInsert: JSXElementChild[], +function canInsertIntoTarget( projectContents: ProjectContentTreeRoot, - selectedViews: NonEmptyArray, metadata: ElementInstanceMetadataMap, elementPathTree: ElementPathTrees, -): ReparentTargetForPaste | null { + parentTarget: ElementPath, + elementsToInsert: JSXElementChild[], +): boolean { const pastedElementNames = mapDropNulls( (element) => (element.type === 'JSX_ELEMENT' ? element.name : null), elementsToInsert, ) - const parentTarget = EP.getCommonParentOfNonemptyPathArray(selectedViews, true) - // paste into parent const targetElementSupportsInsertedElement = MetadataUtils.canInsertElementsToTargetText( parentTarget, metadata, pastedElementNames, ) + const supportsChildren = MetadataUtils.targetSupportsChildren( + projectContents, + metadata, + parentTarget, + elementPathTree, + ) + + return targetElementSupportsInsertedElement && supportsChildren +} + +function pasteIntoParentOrGrandparent( + elementsToInsert: JSXElementChild[], + projectContents: ProjectContentTreeRoot, + selectedViews: NonEmptyArray, + metadata: ElementInstanceMetadataMap, + elementPathTree: ElementPathTrees, +): ReparentTargetForPaste | null { + const parentTarget = EP.getCommonParentOfNonemptyPathArray(selectedViews, true) + if ( - MetadataUtils.targetSupportsChildren( - projectContents, - metadata, - parentTarget, - elementPathTree, - ) && - targetElementSupportsInsertedElement + canInsertIntoTarget(projectContents, metadata, elementPathTree, parentTarget, elementsToInsert) ) { return { type: 'parent', parentPath: childInsertionPath(parentTarget) } } @@ -556,6 +592,62 @@ function pasteIntoParentOrGrandparent( return null } +const intendedPathOptic = fromTypeGuard(isParentReparentTargetForPaste) + .compose(fromField('parentPath')) + .compose(fromField('intendedParentPath')) + +export function applyElementCeilingToReparentTarget( + projectContents: ProjectContentTreeRoot, + metadata: ElementInstanceMetadataMap, + elementsToInsert: JSXElementChild[], + elementPathTree: ElementPathTrees, + reparentTarget: Either, + elementCeiling: ElementPath | null, +): Either { + if (elementCeiling == null) { + return reparentTarget + } else { + return flatMapEither((targetForPaste) => { + switch (targetForPaste.type) { + case 'sibling': + return left('Cannot find a suitable parent') + case 'parent': + switch (targetForPaste.parentPath.type) { + case 'CHILD_INSERTION': + const intendedParentPath = targetForPaste.parentPath.intendedParentPath + // If the intended parent path is above the ceiling path then + // change it to the ceiling path instead. + const ceilingStaticPath = EP.dynamicPathToStaticPath(elementCeiling) + if (EP.depth(intendedParentPath) < EP.depth(ceilingStaticPath)) { + // Make sure it's valid to insert into. + if ( + canInsertIntoTarget( + projectContents, + metadata, + elementPathTree, + ceilingStaticPath, + elementsToInsert, + ) + ) { + return right(set(intendedPathOptic, ceilingStaticPath, targetForPaste)) + } else { + return left('Cannot find a suitable parent') + } + } else { + return right(targetForPaste) + } + case 'CONDITIONAL_CLAUSE_INSERTION': + return left('Cannot find a suitable parent') + default: + return assertNever(targetForPaste.parentPath) + } + default: + assertNever(targetForPaste) + } + }, reparentTarget) + } +} + export function getTargetParentForOneShotInsertion( storyboardPath: ElementPath, projectContents: ProjectContentTreeRoot, @@ -563,6 +655,7 @@ export function getTargetParentForOneShotInsertion( metadata: ElementInstanceMetadataMap, elementsToInsert: JSXElementChild[], elementPathTree: ElementPathTrees, + insertionCeiling: ElementPath | null, ): Either { if (!isNonEmptyArray(selectedViews)) { return right({ type: 'parent', parentPath: childInsertionPath(storyboardPath) }) @@ -591,7 +684,14 @@ export function getTargetParentForOneShotInsertion( elementPathTree, ) if (pasteIntoParentOrGrandparentResult != null) { - return right(pasteIntoParentOrGrandparentResult) + return applyElementCeilingToReparentTarget( + projectContents, + metadata, + elementsToInsert, + elementPathTree, + right(pasteIntoParentOrGrandparentResult), + insertionCeiling, + ) } return left('Cannot find a suitable parent') } diff --git a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-component-renderer.tsx b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-component-renderer.tsx index 9c7f30b659d1..00382ecdf753 100644 --- a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-component-renderer.tsx +++ b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-component-renderer.tsx @@ -8,7 +8,11 @@ import { isJSXElement, } from '../../../core/shared/element-template' import { optionalMap } from '../../../core/shared/optional-utils' -import type { DomWalkerInvalidatePathsCtxData, UiJsxCanvasContextData } from '../ui-jsx-canvas' +import type { + DomWalkerInvalidatePathsCtxData, + UiJsxCanvasContextData, + VariableData, +} from '../ui-jsx-canvas' import { DomWalkerInvalidatePathsCtxAtom, UiJsxCanvasCtxAtom, @@ -207,6 +211,8 @@ export function createComponentRendererComponent(params: { highlightBounds, rerenderUtopiaContext.editedText, null, + {}, + [], ) scope[JSX_CANVAS_LOOKUP_FUNCTION_NAME] = utopiaCanvasJSXLookup( @@ -229,9 +235,10 @@ export function createComponentRendererComponent(params: { instancePath, ) - const spiedVariablesInScope = objectMap( + const spiedVariablesInScope: VariableData = objectMap( (spiedValue) => ({ spiedValue: spiedValue, + insertionCeiling: null, }), definedWithinWithValues, ) diff --git a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-element-renderer-utils.tsx b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-element-renderer-utils.tsx index aed7173463bd..70cc0a00abb7 100644 --- a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-element-renderer-utils.tsx +++ b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-element-renderer-utils.tsx @@ -92,6 +92,8 @@ export function createLookupRender( highlightBounds: HighlightBoundsForUids | null, editedText: ElementPath | null, renderLimit: number | null, + variablesInScope: VariableData, + valuesInScopeFromParameters: Array, ): (element: JSXElement, scope: MapLike) => React.ReactChild | null { let index = 0 @@ -117,6 +119,17 @@ export function createLookupRender( props: attrs, } }) + + let innerVariablesInScope: VariableData = { + ...variablesInScope, + } + for (const valueInScope of valuesInScopeFromParameters) { + innerVariablesInScope[valueInScope] = { + spiedValue: scope[valueInScope], + insertionCeiling: innerPath, + } + } + return renderCoreElement( augmentedInnerElement, innerPath, @@ -140,7 +153,7 @@ export function createLookupRender( code, highlightBounds, editedText, - {}, + innerVariablesInScope, ) } } @@ -219,6 +232,8 @@ export function renderCoreElement( highlightBounds, editedText, null, + variablesInScope, + [], ) : NoOpLookupRender @@ -292,6 +307,9 @@ export function renderCoreElement( ) } + const valuesInScopeFromParameters = + element.type === 'JSX_MAP_EXPRESSION' ? element.valuesInScopeFromParameters : [] + if (elementIsTextEdited) { const runJSExpressionLazy = () => { const innerRender = createLookupRender( @@ -314,6 +332,8 @@ export function renderCoreElement( highlightBounds, editedText, mapCountOverride, + variablesInScope, + valuesInScopeFromParameters, ) const blockScope = { @@ -376,6 +396,8 @@ export function renderCoreElement( highlightBounds, editedText, mapCountOverride, + variablesInScope, + valuesInScopeFromParameters, ) const blockScope = { @@ -864,6 +886,8 @@ function renderJSXElement( highlightBounds, editedText, null, + variablesInScope, + [], ) const blockScope = { ...inScope, diff --git a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx index c97458367db2..355ea696ddaf 100644 --- a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx +++ b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx @@ -139,6 +139,8 @@ export function createExecutionScope( highlightBounds, editedText, null, + {}, + [], ) executionScope[JSX_CANVAS_LOOKUP_FUNCTION_NAME] = utopiaCanvasJSXLookup( diff --git a/editor/src/components/canvas/ui-jsx-canvas.tsx b/editor/src/components/canvas/ui-jsx-canvas.tsx index d69f06143b0d..eb6a9cfb349c 100644 --- a/editor/src/components/canvas/ui-jsx-canvas.tsx +++ b/editor/src/components/canvas/ui-jsx-canvas.tsx @@ -104,6 +104,7 @@ export const ElementsToRerenderGLOBAL: { current: ElementsToRerender } = { export interface VariableMetadata { spiedValue: unknown + insertionCeiling: ElementPath | null } export interface VariableData { diff --git a/editor/src/components/editor/actions/actions.spec.tsx b/editor/src/components/editor/actions/actions.spec.tsx index 5f2091ae5b8b..f60da0231fee 100644 --- a/editor/src/components/editor/actions/actions.spec.tsx +++ b/editor/src/components/editor/actions/actions.spec.tsx @@ -689,6 +689,7 @@ describe('INSERT_INSERTABLE', () => { 'Spring', [], null, + null, ) const targetPath = EP.elementPath([ diff --git a/editor/src/components/editor/canvas-toolbar.tsx b/editor/src/components/editor/canvas-toolbar.tsx index a13295984817..ee35bc340cd2 100644 --- a/editor/src/components/editor/canvas-toolbar.tsx +++ b/editor/src/components/editor/canvas-toolbar.tsx @@ -336,6 +336,7 @@ export const CanvasToolbar = React.memo(() => { defaultSize: null, source: insertableComponentGroupFragment(), key: fragmentComponentInfo.insertMenuLabel, + insertionCeiling: null, }, } convertToAndClose(convertToFragmentMenuItem) diff --git a/editor/src/components/editor/convert-callbacks.ts b/editor/src/components/editor/convert-callbacks.ts index d9b758f52a27..35d1d47c11c0 100644 --- a/editor/src/components/editor/convert-callbacks.ts +++ b/editor/src/components/editor/convert-callbacks.ts @@ -86,7 +86,7 @@ export function changeConditionalOrFragment( actionsToDispatch = [ insertInsertable( insertionPath, - insertableComponent(importsToAdd, () => element, '', [], null), + insertableComponent(importsToAdd, () => element, '', [], null, null), fixedSizeForInsertion ? 'add-size' : 'do-not-add', floatingMenuState.indexPosition, ), diff --git a/editor/src/components/editor/insert-callbacks.ts b/editor/src/components/editor/insert-callbacks.ts index 8427b2d1bb75..2447f3e7bfdd 100644 --- a/editor/src/components/editor/insert-callbacks.ts +++ b/editor/src/components/editor/insert-callbacks.ts @@ -204,6 +204,7 @@ export function useToInsert(): (elementToInsert: InsertMenuItem | null) => void jsxMetadataRef.current, [element.element], elementPathTreeRef.current, + elementToInsert.value.insertionCeiling, ) if (isLeft(targetParent)) { diff --git a/editor/src/components/editor/store/store-deep-equality-instances.spec.ts b/editor/src/components/editor/store/store-deep-equality-instances.spec.ts index 9de1c363ead3..c5821bf9184e 100644 --- a/editor/src/components/editor/store/store-deep-equality-instances.spec.ts +++ b/editor/src/components/editor/store/store-deep-equality-instances.spec.ts @@ -42,7 +42,7 @@ import { JSXAttributeKeepDeepEqualityCall, JSXAttributeNestedArrayKeepDeepEqualityCall, JSXAttributeNestedObjectKeepDeepEqualityCall, - JSXAttributeOtherJavaScriptKeepDeepEqualityCall, + JSExpressionOtherJavaScriptKeepDeepEqualityCall, JSXAttributesEntryDeepEqualityCall, JSXAttributesKeepDeepEqualityCall, JSXAttributesPartDeepEqualityCall, @@ -508,17 +508,17 @@ describe('JSXAttributeOtherJavaScriptKeepDeepEqualityCall', () => { } it('same reference returns the same reference', () => { - const result = JSXAttributeOtherJavaScriptKeepDeepEqualityCall()(oldValue, oldValue) + const result = JSExpressionOtherJavaScriptKeepDeepEqualityCall()(oldValue, oldValue) expect(result.value).toBe(oldValue) expect(result.areEqual).toEqual(true) }) it('same value returns the same reference', () => { - const result = JSXAttributeOtherJavaScriptKeepDeepEqualityCall()(oldValue, newSameValue) + const result = JSExpressionOtherJavaScriptKeepDeepEqualityCall()(oldValue, newSameValue) expect(result.value).toBe(oldValue) expect(result.areEqual).toEqual(true) }) it('different but similar value handled appropriately', () => { - const result = JSXAttributeOtherJavaScriptKeepDeepEqualityCall()(oldValue, newDifferentValue) + const result = JSExpressionOtherJavaScriptKeepDeepEqualityCall()(oldValue, newDifferentValue) expect(result.value.type).toBe(oldValue.type) expect(result.value.javascript).toBe(newDifferentValue.javascript) expect(result.value.transpiledJavascript).toBe(oldValue.transpiledJavascript) diff --git a/editor/src/components/editor/store/store-deep-equality-instances.ts b/editor/src/components/editor/store/store-deep-equality-instances.ts index c449bddea7b2..350c1686a5af 100644 --- a/editor/src/components/editor/store/store-deep-equality-instances.ts +++ b/editor/src/components/editor/store/store-deep-equality-instances.ts @@ -131,6 +131,7 @@ import type { ActiveAndDefaultConditionValues, JSXMapExpression, JSExpressionMapOrOtherJavascript, + JSExpressionOtherJavaScript, } from '../../../core/shared/element-template' import { elementInstanceMetadata, @@ -183,6 +184,8 @@ import { importedOrigin, isJSXConditionalExpression, jsxConditionalExpression, + isJSExpressionOtherJavaScript, + isJSXMapExpression, } from '../../../core/shared/element-template' import type { CanvasRectangle, @@ -853,10 +856,8 @@ export const RawSourceMapKeepDeepEquality: KeepDeepEqualityCall = }, ) -export function JSXAttributeOtherJavaScriptKeepDeepEqualityCall(): KeepDeepEqualityCall { - return combine9EqualityCalls( - (attribute) => attribute.type, - createCallWithTripleEquals(), +export function JSExpressionOtherJavaScriptKeepDeepEqualityCall(): KeepDeepEqualityCall { + return combine8EqualityCalls( (attribute) => attribute.javascript, createCallWithTripleEquals(), (attribute) => attribute.originalJavascript, @@ -874,7 +875,6 @@ export function JSXAttributeOtherJavaScriptKeepDeepEqualityCall(): KeepDeepEqual (block) => block.comments, ParsedCommentsKeepDeepEqualityCall, ( - type, javascript, originalJavascript, transpiledJavascript, @@ -885,7 +885,7 @@ export function JSXAttributeOtherJavaScriptKeepDeepEqualityCall(): KeepDeepEqual comments, ) => { return { - type: type, + type: 'ATTRIBUTE_OTHER_JAVASCRIPT', javascript: javascript, originalJavascript: originalJavascript, transpiledJavascript: transpiledJavascript, @@ -900,7 +900,7 @@ export function JSXAttributeOtherJavaScriptKeepDeepEqualityCall(): KeepDeepEqual } export function JSXMapExpressionKeepDeepEqualityCall(): KeepDeepEqualityCall { - return combine8EqualityCalls( + return combine9EqualityCalls( (attribute) => attribute.javascript, createCallWithTripleEquals(), (attribute) => attribute.originalJavascript, @@ -917,6 +917,8 @@ export function JSXMapExpressionKeepDeepEqualityCall(): KeepDeepEqualityCall block.comments, ParsedCommentsKeepDeepEqualityCall, + (block) => block.valuesInScopeFromParameters, + arrayDeepEquality(createCallWithTripleEquals()), ( javascript, originalJavascript, @@ -926,6 +928,7 @@ export function JSXMapExpressionKeepDeepEqualityCall(): KeepDeepEqualityCall { return { type: 'JSX_MAP_EXPRESSION', @@ -937,11 +940,24 @@ export function JSXMapExpressionKeepDeepEqualityCall(): KeepDeepEqualityCall = (oldValue, newValue) => { + if (isJSExpressionOtherJavaScript(oldValue) && isJSExpressionOtherJavaScript(newValue)) { + return JSExpressionOtherJavaScriptKeepDeepEqualityCall()(oldValue, newValue) + } else if (isJSXMapExpression(oldValue) && isJSXMapExpression(newValue)) { + return JSXMapExpressionKeepDeepEqualityCall()(oldValue, newValue) + } else { + return keepDeepEqualityResult(newValue, false) + } +} + export function JSXArrayValueKeepDeepEqualityCall(): KeepDeepEqualityCall { return combine2EqualityCalls( (value) => value.value, @@ -1056,7 +1072,7 @@ export const JSXAttributeKeepDeepEqualityCall: KeepDeepEqualityCall = (param) => param.paramName, createCallWithTripleEquals(), (param) => param.defaultExpression, - nullableDeepEquality(JSXAttributeOtherJavaScriptKeepDeepEqualityCall()), + nullableDeepEquality(JSExpressionOtherJavaScriptOrJSXMapExpressionKeepDeepEqualityCall), regularParam, ) @@ -1379,7 +1395,7 @@ export const DestructuredParamPartKeepDeepEquality: KeepDeepEqualityCall paramPart.param, ParamKeepDeepEquality(), (paramPart) => paramPart.defaultExpression, - nullableDeepEquality(JSXAttributeOtherJavaScriptKeepDeepEqualityCall()), + nullableDeepEquality(JSExpressionOtherJavaScriptOrJSXMapExpressionKeepDeepEqualityCall), destructuredParamPart, ) diff --git a/editor/src/components/editor/variablesmenu.spec.browser2.tsx b/editor/src/components/editor/variablesmenu.spec.browser2.tsx index 6094bda359c6..c0abe5156ea5 100644 --- a/editor/src/components/editor/variablesmenu.spec.browser2.tsx +++ b/editor/src/components/editor/variablesmenu.spec.browser2.tsx @@ -22,6 +22,7 @@ import type { ProjectContentTreeRoot } from '../assets' import { contentsToTree } from '../assets' import { PrettierConfig } from 'utopia-vscode-common' import { pressKey } from '../canvas/event-helpers.test-utils' +import { notice } from '../common/notice' function getInsertItems() { return screen.queryAllByTestId(/^insert-item-/gi) @@ -162,6 +163,114 @@ describe('variables menu', () => { ), ) }) + it('shows and does not insert scoped properties when not possible', async () => { + const editor = await renderTestEditorWithProjectContent( + makeMappingFunctionTestProjectContents(), + 'await-first-dom-report', + ) + + await selectComponentsForTest(editor, [ + EP.fromString( + `${BakedInStoryboardUID}/${TestSceneUID}/${TestAppUID}:container/676/020~~~1`, + ), + ]) + + await openVariablesMenu(editor) + + document.execCommand('insertText', false, 'value') + expect(getInsertItems().length).toEqual(1) + expect(getInsertItems()[0].innerText).toEqual('value') + + const filterBox = await screen.findByTestId(InsertMenuFilterTestId) + forceNotNull('the filter box must not be null', filterBox) + + await pressKey('Enter', { targetElement: filterBox }) + + expect(getPrintedUiJsCode(editor.getEditorState(), '/src/app.js')).toEqual( + Prettier.format(mappingFunctionAppJS, PrettierConfig), + ) + expect(editor.getEditorState().editor.toasts).toEqual([ + notice( + 'Cannot find a suitable parent', + 'INFO', + false, + 'to-insert-does-not-support-children', + ), + ]) + }) + xit('shows and inserts scoped properties when possible', async () => { + // Test disabled because it uncovered an issue with an exception being triggered for a frame on the canvas. + // But it has been seemingly impossible to capture the exception in a way that permits the test to continue. + // Solution appears to be to fix the flickering of an error in subsequent work. + const editor = await renderTestEditorWithProjectContent( + makeMappingFunctionTestProjectContents(), + 'await-first-dom-report', + ) + + await selectComponentsForTest(editor, [ + EP.fromString( + `${BakedInStoryboardUID}/${TestSceneUID}/${TestAppUID}:container/1ac/586~~~1`, + ), + ]) + + await openVariablesMenu(editor) + + document.execCommand('insertText', false, 'index') + expect(getInsertItems().length).toEqual(1) + expect(getInsertItems()[0].innerText).toEqual('index') + + const filterBox = await screen.findByTestId(InsertMenuFilterTestId) + forceNotNull('the filter box must not be null', filterBox) + + await pressKey('Enter', { targetElement: filterBox }) + + expect(getPrintedUiJsCode(editor.getEditorState(), '/src/app.js')).toEqual( + Prettier.format( + ` + import * as React from 'react' + export function App({objProp, imgProp, unusedProp}) { + return ( +
+ {[1, 2].map((value, index) => { + return ( + Utopia logo + ) + })} + {[{ thing: 1 }, { thing: 2 }, { thing: 3 }].map( + (someValue, index) => { + return ( +
+ Utopia logo +
+ ) + }, + )} +
+ ) + }`, + PrettierConfig, + ), + ) + }) }) describe('insertion', () => { @@ -356,3 +465,101 @@ function makeTestProjectContents(): ProjectContentTreeRoot { ), }) } + +const mappingFunctionAppJS: string = ` + import * as React from 'react' + export function App({objProp, imgProp, unusedProp}) { + return ( +
+ {[1, 2].map((value, index) => { + return ( + Utopia logo + ) + })} + {[{ thing: 1 }, { thing: 2 }, { thing: 3 }].map( + (someValue, index) => { + return ( +
+ Utopia logo +
+ ) + }, + )} +
+ ) + } + ` + +function makeMappingFunctionTestProjectContents(): ProjectContentTreeRoot { + return contentsToTree({ + ['/package.json']: codeFile( + ` +{ + "name": "Utopia Project", + "version": "0.1.0", + "utopia": { + "main-ui": "utopia/storyboard.js", + "html": "public/index.html", + "js": "src/index.js" + }, + "dependencies": { + "react": "16.13.1", + "react-dom": "16.13.1", + "utopia-api": "0.4.1", + "non-existant-dummy-library": "8.0.27", + "@heroicons/react": "1.0.1", + "@emotion/react": "11.9.3" + } +}`, + null, + ), + ['/src/app.js']: codeFile(mappingFunctionAppJS, null), + ['/utopia/storyboard.js']: codeFile( + ` + import * as React from 'react' + import { Scene, Storyboard } from 'utopia-api' + import { App } from '/src/app.js' + + export var storyboard = ( + + + + + +)`, + null, + ), + }) +} diff --git a/editor/src/components/navigator/navigator-conditionals.spec.browser2.tsx b/editor/src/components/navigator/navigator-conditionals.spec.browser2.tsx index 592732813aa0..fdb16c75e798 100644 --- a/editor/src/components/navigator/navigator-conditionals.spec.browser2.tsx +++ b/editor/src/components/navigator/navigator-conditionals.spec.browser2.tsx @@ -1685,7 +1685,7 @@ describe('conditionals in the navigator', () => { const labelColor = ( await screen.findByTestId( - `NavigatorItemTestId-regular_utopia_storyboard_uid/scene_aaa/containing_div/conditional/820/46a~~~1`, + `NavigatorItemTestId-regular_utopia_storyboard_uid/scene_aaa/containing_div/conditional/ae0/46a~~~1`, ) ).style.color @@ -1706,13 +1706,13 @@ describe('conditionals in the navigator', () => { regular-utopia-storyboard-uid/scene-aaa/containing-div regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional conditional-clause-utopia-storyboard-uid/scene-aaa/containing-div/conditional-true-case - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~1 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~1/33d - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~2 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~2/33d - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~3 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/820/46a~~~3/33d + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~1 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~1/33d + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~2 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~2/33d + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~3 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ae0/46a~~~3/33d conditional-clause-utopia-storyboard-uid/scene-aaa/containing-div/conditional-false-case synthetic-utopia-storyboard-uid/scene-aaa/containing-div/conditional/else-div-element-else-div`) }) @@ -1731,10 +1731,10 @@ describe('conditionals in the navigator', () => { regular-utopia-storyboard-uid/scene-aaa/containing-div regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional conditional-clause-utopia-storyboard-uid/scene-aaa/containing-div/conditional-true-case - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/d3e - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/d3e/33d~~~1 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/d3e/33d~~~2 - regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/d3e/33d~~~3 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ba8 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ba8/33d~~~1 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ba8/33d~~~2 + regular-utopia-storyboard-uid/scene-aaa/containing-div/conditional/ba8/33d~~~3 conditional-clause-utopia-storyboard-uid/scene-aaa/containing-div/conditional-false-case synthetic-utopia-storyboard-uid/scene-aaa/containing-div/conditional/a25-attribute regular-utopia-storyboard-uid/scene-aaa/268 diff --git a/editor/src/components/navigator/navigator.spec.browser2.tsx b/editor/src/components/navigator/navigator.spec.browser2.tsx index 9ee6dfea8a12..3274619c82db 100644 --- a/editor/src/components/navigator/navigator.spec.browser2.tsx +++ b/editor/src/components/navigator/navigator.spec.browser2.tsx @@ -5026,7 +5026,7 @@ describe('Navigator row order', () => { 'conditional-clause-sb/group/text-expr-cond-wrapper/text-expr-cond-false-case', 'synthetic-sb/group/text-expr-cond-wrapper/text-expr-cond/2f3-element-2f3', 'regular-sb/group/zero-length-map-wrapper', - 'regular-sb/group/zero-length-map-wrapper/063', + 'regular-sb/group/zero-length-map-wrapper/097', ], ) expect( @@ -5064,7 +5064,7 @@ describe('Navigator row order', () => { 'conditional-clause-sb/group/text-expr-cond-wrapper/text-expr-cond-false-case', 'synthetic-sb/group/text-expr-cond-wrapper/text-expr-cond/2f3-element-2f3', 'regular-sb/group/zero-length-map-wrapper', - 'regular-sb/group/zero-length-map-wrapper/063', + 'regular-sb/group/zero-length-map-wrapper/097', ]) }) diff --git a/editor/src/components/shared/__snapshots__/project-components.spec.ts.snap b/editor/src/components/shared/__snapshots__/project-components.spec.ts.snap index 698129edc2ec..365f03a39c4d 100644 --- a/editor/src/components/shared/__snapshots__/project-components.spec.ts.snap +++ b/editor/src/components/shared/__snapshots__/project-components.spec.ts.snap @@ -8,6 +8,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "App", "stylePropOptions": Array [ "do-not-add", @@ -45,6 +46,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "div", "stylePropOptions": Array [ "do-not-add", @@ -68,6 +70,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "span", "stylePropOptions": Array [ "do-not-add", @@ -84,6 +87,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "h1", "stylePropOptions": Array [ "do-not-add", @@ -100,6 +104,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "h2", "stylePropOptions": Array [ "do-not-add", @@ -116,6 +121,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "p", "stylePropOptions": Array [ "do-not-add", @@ -132,6 +138,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "button", "stylePropOptions": Array [ "do-not-add", @@ -148,6 +155,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "input", "stylePropOptions": Array [ "do-not-add", @@ -164,6 +172,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "video", "stylePropOptions": Array [ "do-not-add", @@ -180,6 +189,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "img", "stylePropOptions": Array [ "do-not-add", @@ -197,6 +207,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "Conditional", "stylePropOptions": Array [ "do-not-add", @@ -219,6 +230,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Fragment", "stylePropOptions": Array [ "do-not-add", @@ -235,6 +247,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "Sample text", "stylePropOptions": Array [ "do-not-add", @@ -264,6 +277,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "App", "stylePropOptions": Array [ "do-not-add", @@ -301,6 +315,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "div", "stylePropOptions": Array [ "do-not-add", @@ -324,6 +339,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "span", "stylePropOptions": Array [ "do-not-add", @@ -340,6 +356,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "h1", "stylePropOptions": Array [ "do-not-add", @@ -356,6 +373,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "h2", "stylePropOptions": Array [ "do-not-add", @@ -372,6 +390,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "p", "stylePropOptions": Array [ "do-not-add", @@ -388,6 +407,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "button", "stylePropOptions": Array [ "do-not-add", @@ -404,6 +424,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "input", "stylePropOptions": Array [ "do-not-add", @@ -420,6 +441,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "video", "stylePropOptions": Array [ "do-not-add", @@ -436,6 +458,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "img", "stylePropOptions": Array [ "do-not-add", @@ -453,6 +476,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "Conditional", "stylePropOptions": Array [ "do-not-add", @@ -475,6 +499,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Fragment", "stylePropOptions": Array [ "do-not-add", @@ -491,6 +516,7 @@ Array [ "defaultSize": null, "element": [Function], "importsToAdd": Object {}, + "insertionCeiling": null, "name": "Sample text", "stylePropOptions": Array [ "do-not-add", @@ -523,6 +549,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "DatePicker", "stylePropOptions": Array [ "do-not-add", @@ -549,6 +576,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Button", "stylePropOptions": Array [ "do-not-add", @@ -575,6 +603,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "InputNumber", "stylePropOptions": Array [ "do-not-add", @@ -601,6 +630,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Row", "stylePropOptions": Array [ "do-not-add", @@ -627,6 +657,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Col", "stylePropOptions": Array [ "do-not-add", @@ -653,6 +684,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Space", "stylePropOptions": Array [ "do-not-add", @@ -679,6 +711,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Menu", "stylePropOptions": Array [ "do-not-add", @@ -705,6 +738,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Menu.Item", "stylePropOptions": Array [ "do-not-add", @@ -731,6 +765,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Menu.SubMenu", "stylePropOptions": Array [ "do-not-add", @@ -757,6 +792,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Menu.ItemGroup", "stylePropOptions": Array [ "do-not-add", @@ -783,6 +819,7 @@ Array [ "importedWithName": null, }, }, + "insertionCeiling": null, "name": "Typography.Text", "stylePropOptions": Array [ "do-not-add", diff --git a/editor/src/components/shared/project-components.ts b/editor/src/components/shared/project-components.ts index 09912b7f42db..277f068a88cb 100644 --- a/editor/src/components/shared/project-components.ts +++ b/editor/src/components/shared/project-components.ts @@ -28,7 +28,7 @@ import type { PossiblyUnversionedNpmDependency, } from '../../core/shared/npm-dependency-types' import { isResolvedNpmDependency } from '../../core/shared/npm-dependency-types' -import type { Imports, ProjectFile } from '../../core/shared/project-file-types' +import type { ElementPath, Imports, ProjectFile } from '../../core/shared/project-file-types' import { isTextFile } from '../../core/shared/project-file-types' import { assertNever, fastForEach } from '../../core/shared/utils' import type { SelectOption } from '../../uuiui-deps' @@ -62,6 +62,7 @@ export interface InsertableComponent { name: string stylePropOptions: Array defaultSize: Size | null + insertionCeiling: ElementPath | null } export function insertableComponent( @@ -70,6 +71,7 @@ export function insertableComponent( name: string, stylePropOptions: Array, defaultSize: Size | null, + insertionCeiling: ElementPath | null, ): InsertableComponent { const component = { importsToAdd: importsToAdd, @@ -77,6 +79,7 @@ export function insertableComponent( name: name, stylePropOptions: stylePropOptions, defaultSize: defaultSize, + insertionCeiling: insertionCeiling, } return component } @@ -282,9 +285,17 @@ export function insertableVariable( variableType: InsertableVariableType, depth: number, originalName: string, + insertionCeiling: ElementPath | null, ): InsertableVariable { return { - ...insertableComponent(importsToAdd, element, name, stylePropOptions, defaultSize), + ...insertableComponent( + importsToAdd, + element, + name, + stylePropOptions, + defaultSize, + insertionCeiling, + ), variableType: variableType, depth: depth, originalName: originalName, @@ -559,6 +570,7 @@ export function moveSceneToTheBeginningAndSetDefaultSize( scene.name, scene.stylePropOptions, size(SceneDefaultWidth, SceneDefaultHeight), + null, ), ], ) @@ -640,6 +652,7 @@ export function getComponentGroups( insertOption.insertMenuLabel, stylePropOptions, null, + null, ), ) }) @@ -654,6 +667,7 @@ export function getComponentGroups( exportedComponent.listingName, stylePropOptions, null, + null, ), ) } @@ -689,6 +703,7 @@ export function getComponentGroups( insertOption.insertMenuLabel, stylePropOptions, null, + null, ), ) }) diff --git a/editor/src/components/shared/scoped-variables.ts b/editor/src/components/shared/scoped-variables.ts index f2f02a05ceaf..2c1dbb1dd23c 100644 --- a/editor/src/components/shared/scoped-variables.ts +++ b/editor/src/components/shared/scoped-variables.ts @@ -141,7 +141,7 @@ function getContainerPropsValue( if (isJSXAttributesEntry(prop)) { const value = simplifyAttributeIfPossible(prop.value) if (isJSXAttributeValue(value)) { - runtimeProps[prop.key] = { spiedValue: value.value as unknown } + runtimeProps[prop.key] = { spiedValue: value.value as unknown, insertionCeiling: null } } } }) @@ -153,12 +153,14 @@ function getContainerPropsValue( function generateVariableTypes(variables: VariableData): Variable[] { return Object.entries(variables).flatMap(([name, valueMetadata]) => { const value = valueMetadata.spiedValue + const insertionCeiling = valueMetadata.insertionCeiling const type = getTypeByValue(value) - const variable = { + const variable: Variable = { name, value, type, depth: 0, + insertionCeiling: insertionCeiling, } if (type === 'object' && value != null) { // iterate also first-level keys of object @@ -170,6 +172,7 @@ function generateVariableTypes(variables: VariableData): Variable[] { type: getTypeByValue(innerValue), parent: variable, depth: 1, + insertionCeiling: insertionCeiling, })), ) } else { @@ -194,6 +197,7 @@ export function convertVariablesToElements( variable.type, variable.depth, variable.name, + variable.insertionCeiling, ) }), } @@ -266,6 +270,7 @@ function arrayInsertableComponentAndJsx(variable: Variable): InsertableComponent name: 'item', type: arrayElementsType, depth: variable.depth + 1, + insertionCeiling: variable.insertionCeiling, }).jsx const arrayElementString = `${variable.name}.map((item) => (${innerElementString}))` const arrayElement = jsxFragmentWithoutUID([jsxTextBlock(`{${arrayElementString}}`)], true) @@ -318,4 +323,5 @@ interface Variable { value?: unknown parent?: Variable depth: number + insertionCeiling: ElementPath | null } diff --git a/editor/src/core/model/element-metadata.spec.browser2.tsx b/editor/src/core/model/element-metadata.spec.browser2.tsx index c5c34536b033..1deefbc9672b 100644 --- a/editor/src/core/model/element-metadata.spec.browser2.tsx +++ b/editor/src/core/model/element-metadata.spec.browser2.tsx @@ -1325,44 +1325,48 @@ describe('record variable values', () => { const editor = await renderTestEditorWithCode(ProjectWithVariables, 'await-first-dom-report') const { variablesInScope } = editor.getEditorState().editor expect(variablesInScope['sb/scene/pg:root']).toEqual({ - definedInsideNumber: { spiedValue: 12 }, + definedInsideNumber: { spiedValue: 12, insertionCeiling: null }, definedInsideObject: { spiedValue: { prop: [33], }, + insertionCeiling: null, }, - definedInsideString: { spiedValue: 'hello' }, - functionResult: { spiedValue: 35 }, + definedInsideString: { spiedValue: 'hello', insertionCeiling: null }, + functionResult: { spiedValue: 35, insertionCeiling: null }, }) expect(variablesInScope['sb/scene/pg:root/111']).toEqual({ - definedInsideNumber: { spiedValue: 12 }, + definedInsideNumber: { spiedValue: 12, insertionCeiling: null }, definedInsideObject: { spiedValue: { prop: [33], }, + insertionCeiling: null, }, - definedInsideString: { spiedValue: 'hello' }, - functionResult: { spiedValue: 35 }, + definedInsideString: { spiedValue: 'hello', insertionCeiling: null }, + functionResult: { spiedValue: 35, insertionCeiling: null }, }) expect(variablesInScope['sb/scene/pg:root/222']).toEqual({ - definedInsideNumber: { spiedValue: 12 }, + definedInsideNumber: { spiedValue: 12, insertionCeiling: null }, definedInsideObject: { spiedValue: { prop: [33], }, + insertionCeiling: null, }, - definedInsideString: { spiedValue: 'hello' }, - functionResult: { spiedValue: 35 }, + definedInsideString: { spiedValue: 'hello', insertionCeiling: null }, + functionResult: { spiedValue: 35, insertionCeiling: null }, }) expect(variablesInScope['sb/scene/pg:root/333']).toEqual({ - definedInsideNumber: { spiedValue: 12 }, + definedInsideNumber: { spiedValue: 12, insertionCeiling: null }, definedInsideObject: { spiedValue: { prop: [33], }, + insertionCeiling: null, }, - definedInsideString: { spiedValue: 'hello' }, - functionResult: { spiedValue: 35 }, + definedInsideString: { spiedValue: 'hello', insertionCeiling: null }, + functionResult: { spiedValue: 35, insertionCeiling: null }, }) }) }) diff --git a/editor/src/core/shared/element-template.ts b/editor/src/core/shared/element-template.ts index 5d26a5f3b4fa..8999f4e629c6 100644 --- a/editor/src/core/shared/element-template.ts +++ b/editor/src/core/shared/element-template.ts @@ -227,6 +227,7 @@ export interface JSXMapExpression extends WithComments, WithElementsWithin { transpiledJavascript: string definedElsewhere: Array sourceMap: RawSourceMap | null + valuesInScopeFromParameters: Array uid: string } @@ -238,6 +239,7 @@ export function jsxMapExpression( sourceMap: RawSourceMap | null, elementsWithin: ElementsWithin, comments: ParsedComments, + valuesInScopeFromParameters: Array, uid: string = UUID(), ): JSXMapExpression { return { @@ -250,6 +252,7 @@ export function jsxMapExpression( uid: uid, comments: comments, elementsWithin: elementsWithin, + valuesInScopeFromParameters: valuesInScopeFromParameters, } } diff --git a/editor/src/core/shared/uid-utils.ts b/editor/src/core/shared/uid-utils.ts index 4b1869b0b293..7484432187bb 100644 --- a/editor/src/core/shared/uid-utils.ts +++ b/editor/src/core/shared/uid-utils.ts @@ -766,6 +766,7 @@ export function setUtopiaID(element: JSXElementChild, uid: string): JSXElementCh element.sourceMap, element.elementsWithin, element.comments, + element.valuesInScopeFromParameters, uid, ) } else { diff --git a/editor/src/core/workers/parser-printer/parser-printer-arbitrary-elements.spec.tsx b/editor/src/core/workers/parser-printer/parser-printer-arbitrary-elements.spec.tsx index 6da9d8744f5e..ef780f1c6c77 100644 --- a/editor/src/core/workers/parser-printer/parser-printer-arbitrary-elements.spec.tsx +++ b/editor/src/core/workers/parser-printer/parser-printer-arbitrary-elements.spec.tsx @@ -338,6 +338,7 @@ export var whatever = (props) => { ), }, emptyComments, + ['n'], ), ], ) @@ -443,6 +444,7 @@ export var whatever = (props) => { ), }, emptyComments, + ['n'], ), ], ) @@ -555,6 +557,7 @@ export var whatever = (props) => { ), }, emptyComments, + ['n'], ), ], ) @@ -665,6 +668,7 @@ export var whatever = (props) => { ), }, emptyComments, + ['n'], ), ], ) @@ -868,6 +872,7 @@ export var whatever = (props) => { ), }, emptyComments, + ['n'], ), ], ) @@ -961,6 +966,7 @@ export var whatever = (props) => { ), }, emptyComments, + [], ), ], ) diff --git a/editor/src/core/workers/parser-printer/parser-printer-bugs.spec.ts b/editor/src/core/workers/parser-printer/parser-printer-bugs.spec.ts index 70135ca412e4..b7219907c7b4 100644 --- a/editor/src/core/workers/parser-printer/parser-printer-bugs.spec.ts +++ b/editor/src/core/workers/parser-printer/parser-printer-bugs.spec.ts @@ -47,7 +47,7 @@ export var App = props => { UNPARSED_CODE UTOPIA_JSX_COMPONENT - App JSX_ELEMENT - div - aaa - JSX_MAP_EXPRESSION - 9d0 + JSX_MAP_EXPRESSION - 79a JSX_ELEMENT - div - bbb ATTRIBUTE_OTHER_JAVASCRIPT - b6e JSX_TEXT_BLOCK - d01 @@ -184,7 +184,7 @@ export var App = props => { UNPARSED_CODE UTOPIA_JSX_COMPONENT - Test JSX_ELEMENT - div - mapper-parent - JSX_MAP_EXPRESSION - d4d + JSX_MAP_EXPRESSION - 919 JSX_ELEMENT - Card - card" `) expect(elementsStructure((testParseCode(spreadCode) as any).topLevelElements)) @@ -196,7 +196,7 @@ export var App = props => { UNPARSED_CODE UTOPIA_JSX_COMPONENT - Test JSX_ELEMENT - div - mapper-parent - JSX_MAP_EXPRESSION - 457 + JSX_MAP_EXPRESSION - c34 JSX_ELEMENT - Card - card" `) }) diff --git a/editor/src/core/workers/parser-printer/parser-printer-parsing.ts b/editor/src/core/workers/parser-printer/parser-printer-parsing.ts index f9bb2509b09e..0c29cbef02d0 100644 --- a/editor/src/core/workers/parser-printer/parser-printer-parsing.ts +++ b/editor/src/core/workers/parser-printer/parser-printer-parsing.ts @@ -531,6 +531,83 @@ function createExpressionAndText( } } +function addBindingNames( + sourceFile: TS.SourceFile, + name: TS.BindingName, + toAddTo: Array, +): void { + if (TS.isIdentifier(name)) { + toAddTo.push(name.getText(sourceFile)) + } else if (TS.isObjectBindingPattern(name)) { + for (const element of name.elements) { + addBindingNames(sourceFile, element.name, toAddTo) + } + } else if (TS.isArrayBindingPattern(name)) { + for (const element of name.elements) { + if (TS.isBindingElement(element)) { + addBindingNames(sourceFile, element.name, toAddTo) + } + } + } +} + +interface DefaultOtherJavaScript { + type: 'DEFAULT_OTHER_JAVASCRIPT' +} + +const defaultOtherJavaScript: DefaultOtherJavaScript = { + type: 'DEFAULT_OTHER_JAVASCRIPT', +} + +interface MapOtherJavaScript { + type: 'MAP_OTHER_JAVASCRIPT' + valuesInScopeFromParameters: JSXMapExpression['valuesInScopeFromParameters'] +} + +function mapOtherJavaScript( + valuesInScopeFromParameters: MapOtherJavaScript['valuesInScopeFromParameters'], +): MapOtherJavaScript { + return { + type: 'MAP_OTHER_JAVASCRIPT', + valuesInScopeFromParameters: valuesInScopeFromParameters, + } +} + +type OtherJavaScriptType = DefaultOtherJavaScript | MapOtherJavaScript + +function getOtherJavaScriptTypeFromExpression( + sourceFile: TS.SourceFile, + expr: TS.Node, +): OtherJavaScriptType { + if (TS.isCallExpression(expr) && TS.isPropertyAccessExpression(expr.expression)) { + const propertyAccessExpression: TS.PropertyAccessExpression = expr.expression + if (propertyAccessExpression.name.getText(sourceFile) === 'map') { + const firstArgument = expr.arguments[0] + if (TS.isArrowFunction(firstArgument)) { + let valuesInScopeFromParameters: MapOtherJavaScript['valuesInScopeFromParameters'] = [] + for (const parameter of firstArgument.parameters) { + addBindingNames(sourceFile, parameter.name, valuesInScopeFromParameters) + } + return mapOtherJavaScript(valuesInScopeFromParameters) + } + } + } + return defaultOtherJavaScript +} + +function getOtherJavaScriptType( + sourceFile: TS.SourceFile, + expressionsAndTexts: Array>, +): OtherJavaScriptType { + if (expressionsAndTexts.length === 1) { + const expr = expressionsAndTexts[0]?.expression + if (expr != null) { + return getOtherJavaScriptTypeFromExpression(sourceFile, expr) + } + } + return defaultOtherJavaScript +} + function parseOtherJavaScript( sourceFile: TS.SourceFile, sourceText: string, @@ -549,22 +626,13 @@ function parseOtherJavaScript( definedElsewhere: Array, fileNode: typeof SourceNode, parsedElementsWithin: ElementsWithinInPosition, - isList: boolean, + otherJavaScriptType: OtherJavaScriptType, ) => Either, ): Either> { if (expressionsAndTexts.length === 0) { throw new Error('Unable to deal with a collection of zero expressions.') } else { - const isMapExpression = (() => { - if (expressionsAndTexts.length !== 1) { - return false - } - const expr = expressionsAndTexts[0]?.expression - if (expr == null) { - return false - } - return isNodeAMapExpression(expr, sourceFile) - })() + const otherJavaScriptType = getOtherJavaScriptType(sourceFile, expressionsAndTexts) let startLineShift: number = 0 let startColumnShift: number = 0 @@ -586,19 +654,7 @@ function parseOtherJavaScript( } function addBindingNameToDefinedWithin(name: TS.BindingName): void { - if (TS.isIdentifier(name)) { - pushToDefinedWithinIfNotThere(name.getText(sourceFile)) - } else if (TS.isObjectBindingPattern(name)) { - for (const element of name.elements) { - addBindingNameToDefinedWithin(element.name) - } - } else if (TS.isArrayBindingPattern(name)) { - for (const element of name.elements) { - if (TS.isBindingElement(element)) { - addBindingNameToDefinedWithin(element.name) - } - } - } + addBindingNames(sourceFile, name, definedWithin) } function pushToDefinedElsewhereIfNotThere(inScope: Array, name: string): void { @@ -1022,7 +1078,7 @@ function parseOtherJavaScript( buildHighlightBoundsForExpressionsAndText(sourceFile, expressionsAndTexts, created.uid), ) return withParserMetadata(created, highlightBounds, propsUsed, definedElsewhere) - }, create(code, definedWithin, definedElsewhere, fileNode, parsedElementsWithin, isMapExpression)) + }, create(code, definedWithin, definedElsewhere, fileNode, parsedElementsWithin, otherJavaScriptType)) } } @@ -1057,7 +1113,7 @@ export function parseAttributeOtherJavaScript( alreadyExistingUIDs, '', applySteganography, - (code, _, definedElsewhere, fileSourceNode, parsedElementsWithin, isList) => { + (code, _, definedElsewhere, fileSourceNode, parsedElementsWithin, otherJavaScriptType) => { const { code: codeFromFile, map } = fileSourceNode.toStringWithSourceMap({ file: filename }) const rawMap = JSON.parse(map.toString()) @@ -1097,7 +1153,7 @@ export function parseAttributeOtherJavaScript( innerDefinedElsewhere, prependedWithReturn.sourceMap, inPositionToElementsWithin(parsedElementsWithin), - isList, + otherJavaScriptType, comments, alreadyExistingUIDs, existingHighlightBounds, @@ -1286,34 +1342,36 @@ function createExpressionOtherJavaScript( definedElsewhere: Array, sourceMap: RawSourceMap | null, elementsWithin: ElementsWithin, - isList: boolean, + otherJavaScriptType: OtherJavaScriptType, comments: ParsedComments, alreadyExistingUIDs: Set, existingHighlightBounds: Readonly, imports: Imports, ): JSExpressionMapOrOtherJavascript { // Ideally the value we hash is stable regardless of location, so exclude the SourceMap value from here and provide an empty UID. - const value = isList - ? jsxMapExpression( - originalJavascript, - javascript, - transpiledJavascript, - definedElsewhere, - null, - elementsWithin, - comments, - '', - ) - : jsExpressionOtherJavaScript( - originalJavascript, - javascript, - transpiledJavascript, - definedElsewhere, - null, - elementsWithin, - comments, - '', - ) + const value = + otherJavaScriptType.type === 'MAP_OTHER_JAVASCRIPT' + ? jsxMapExpression( + originalJavascript, + javascript, + transpiledJavascript, + definedElsewhere, + null, + elementsWithin, + comments, + otherJavaScriptType.valuesInScopeFromParameters, + '', + ) + : jsExpressionOtherJavaScript( + originalJavascript, + javascript, + transpiledJavascript, + definedElsewhere, + null, + elementsWithin, + comments, + '', + ) const { uid } = makeNewUIDFromOriginatingElement( sourceFile, @@ -1325,7 +1383,7 @@ function createExpressionOtherJavaScript( comments, imports, ) - return isList + return otherJavaScriptType.type === 'MAP_OTHER_JAVASCRIPT' ? jsxMapExpression( originalJavascript, javascript, @@ -1334,6 +1392,7 @@ function createExpressionOtherJavaScript( sourceMap, elementsWithin, comments, + otherJavaScriptType.valuesInScopeFromParameters, uid, ) : jsExpressionOtherJavaScript( @@ -1694,7 +1753,7 @@ function getAttributeExpression( // Handle the expression itself. if (initializer.expression == null) { - const isList = isNodeAMapExpression(initializer, sourceFile) + const otherJavaScriptType = getOtherJavaScriptTypeFromExpression(sourceFile, initializer) const comments = getComments(sourceText, initializer) const withoutParserMetadata = createExpressionOtherJavaScript( @@ -1706,7 +1765,7 @@ function getAttributeExpression( [], null, {}, - isList, + otherJavaScriptType, comments, alreadyExistingUIDs, existingHighlightBounds, diff --git a/editor/src/core/workers/parser-printer/parser-printer.spec.ts b/editor/src/core/workers/parser-printer/parser-printer.spec.ts index de348456d29a..2c676c0db8f0 100644 --- a/editor/src/core/workers/parser-printer/parser-printer.spec.ts +++ b/editor/src/core/workers/parser-printer/parser-printer.spec.ts @@ -3868,6 +3868,7 @@ export var App = props => { ), }, emptyComments, + ['x'], ), ], ), @@ -4001,6 +4002,7 @@ export var App = props => { ), }, emptyComments, + ['n'], ), ], ), @@ -4066,6 +4068,7 @@ export var App = props => { ), }, emptyComments, + ['n'], ), ], ), @@ -4711,6 +4714,7 @@ export var whatever = props => { }), { bbb: innerElement }, emptyComments, + ['n'], ) const view = clearJSXElementChildUniqueIDs( jsxElement( @@ -4824,6 +4828,7 @@ export var whatever = props => { }), { bbb: innerElement }, emptyComments, + ['n'], ) const topLevelArbitraryBlock = arbitraryJSBlock(