playroom 0.34.2 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/preview-site.yml +3 -3
- package/.github/workflows/release.yml +3 -3
- package/.github/workflows/snapshot.yml +3 -3
- package/.github/workflows/validate.yml +5 -5
- package/.nvmrc +1 -1
- package/CHANGELOG.md +55 -0
- package/README.md +6 -0
- package/bin/cli.cjs +2 -1
- package/cypress/e2e/editor.cy.js +1 -1
- package/cypress/e2e/keymaps.cy.js +1507 -11
- package/cypress/e2e/scope.cy.js +1 -1
- package/cypress/e2e/smoke.cy.js +2 -2
- package/cypress/e2e/toolbar.cy.js +1 -2
- package/cypress/e2e/urlHandling.cy.js +4 -5
- package/cypress/support/utils.js +62 -54
- package/lib/makeWebpackConfig.js +0 -3
- package/lib/provideDefaultConfig.js +13 -2
- package/package.json +18 -17
- package/src/Playroom/CatchErrors/CatchErrors.tsx +5 -6
- package/src/Playroom/CodeEditor/CodeEditor.tsx +11 -0
- package/src/Playroom/CodeEditor/keymaps/comment.ts +326 -0
- package/src/Playroom/CodeEditor/keymaps/wrap.ts +4 -1
- package/src/Playroom/Frame.tsx +9 -5
- package/src/Playroom/FramesPanel/FramesPanel.css.ts +19 -0
- package/src/Playroom/FramesPanel/FramesPanel.tsx +89 -46
- package/src/Playroom/Preview.tsx +12 -3
- package/src/Playroom/PreviewPanel/PreviewPanel.tsx +1 -1
- package/src/Playroom/SettingsPanel/SettingsPanel.tsx +11 -7
- package/src/Playroom/Stack/Stack.css.ts +4 -35
- package/src/Playroom/Stack/Stack.tsx +2 -9
- package/src/Playroom/Toolbar/Toolbar.tsx +2 -2
- package/src/Playroom/sprinkles.css.ts +1 -0
- package/src/StoreContext/StoreContext.tsx +31 -6
- package/src/index.d.ts +2 -0
- package/src/utils/params.ts +5 -8
- package/src/utils/usePreviewUrl.ts +2 -1
- package/utils/index.d.ts +3 -0
- package/utils/index.js +21 -7
package/cypress/e2e/scope.cy.js
CHANGED
package/cypress/e2e/smoke.cy.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertPreviewContains,
|
|
3
|
-
|
|
3
|
+
getPreviewFrames,
|
|
4
4
|
loadPlayroom,
|
|
5
5
|
} from '../support/utils';
|
|
6
6
|
|
|
7
7
|
describe('Smoke', () => {
|
|
8
8
|
it('frames are interactive', () => {
|
|
9
9
|
loadPlayroom();
|
|
10
|
-
|
|
10
|
+
getPreviewFrames().first().click('center');
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
it('preview mode loads correctly', () => {
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
assertPreviewContains,
|
|
5
5
|
typeCode,
|
|
6
6
|
gotoPreview,
|
|
7
|
-
visit,
|
|
8
7
|
loadPlayroom,
|
|
9
8
|
} from '../support/utils';
|
|
10
9
|
|
|
@@ -33,7 +32,7 @@ describe('Toolbar', () => {
|
|
|
33
32
|
it('copy to clipboard', () => {
|
|
34
33
|
const copySpy = cy.spy();
|
|
35
34
|
|
|
36
|
-
visit(
|
|
35
|
+
cy.visit(
|
|
37
36
|
'http://localhost:9000/#?code=N4Igxg9gJgpiBcIA8AxCEB8r1YEIEMAnAei2LUyXJxAF8g'
|
|
38
37
|
);
|
|
39
38
|
|
|
@@ -2,13 +2,12 @@ import {
|
|
|
2
2
|
assertFirstFrameContains,
|
|
3
3
|
assertCodePaneContains,
|
|
4
4
|
assertFramesMatch,
|
|
5
|
-
visit,
|
|
6
5
|
} from '../support/utils';
|
|
7
6
|
|
|
8
7
|
describe('URL handling', () => {
|
|
9
8
|
describe('where paramType is hash', () => {
|
|
10
9
|
it('code', () => {
|
|
11
|
-
visit(
|
|
10
|
+
cy.visit(
|
|
12
11
|
'http://localhost:9000/#?code=N4Igxg9gJgpiBcIA8AxCEB8r1YEIEMAnAei2LUyXJxAF8g'
|
|
13
12
|
);
|
|
14
13
|
|
|
@@ -17,7 +16,7 @@ describe('URL handling', () => {
|
|
|
17
16
|
});
|
|
18
17
|
|
|
19
18
|
it('widths', () => {
|
|
20
|
-
visit(
|
|
19
|
+
cy.visit(
|
|
21
20
|
'http://localhost:9000/#?code=N4Ig7glgJgLgFgZxALgNoGYDsBWANJgNgA4BdAXyA'
|
|
22
21
|
);
|
|
23
22
|
|
|
@@ -27,7 +26,7 @@ describe('URL handling', () => {
|
|
|
27
26
|
|
|
28
27
|
describe('where paramType is search', () => {
|
|
29
28
|
it('code', () => {
|
|
30
|
-
visit(
|
|
29
|
+
cy.visit(
|
|
31
30
|
'http://localhost:9001/index.html?code=N4Igxg9gJgpiBcIA8AxCEB8r1YEIEMAnAei2LUyXJxAF8g'
|
|
32
31
|
);
|
|
33
32
|
|
|
@@ -36,7 +35,7 @@ describe('URL handling', () => {
|
|
|
36
35
|
});
|
|
37
36
|
|
|
38
37
|
it('widths', () => {
|
|
39
|
-
visit(
|
|
38
|
+
cy.visit(
|
|
40
39
|
'http://localhost:9001/index.html?code=N4Ig7glgJgLgFgZxALgNoGYDsBWANJgNgA4BdAXyA'
|
|
41
40
|
);
|
|
42
41
|
|
package/cypress/support/utils.js
CHANGED
|
@@ -5,38 +5,20 @@ import dedent from 'dedent';
|
|
|
5
5
|
import { createUrl } from '../../utils';
|
|
6
6
|
import { isMac } from '../../src/utils/formatting';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const getCodeEditor = () => cy.get('.CodeMirror-code');
|
|
8
|
+
const getCodeEditor = () =>
|
|
9
|
+
cy.get('.CodeMirror-code').then((editor) => cy.wrap(editor));
|
|
11
10
|
|
|
12
11
|
export const getPreviewFrames = () => cy.get('[data-testid="previewFrame"]');
|
|
13
12
|
|
|
14
13
|
export const getPreviewFrameNames = () => cy.get('[data-testid="frameName"]');
|
|
15
14
|
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
export const visit = (url) =>
|
|
19
|
-
cy
|
|
20
|
-
.visit(url)
|
|
21
|
-
.reload()
|
|
22
|
-
.then(() => {
|
|
23
|
-
getFirstFrame().then(
|
|
24
|
-
($iframe) =>
|
|
25
|
-
new Cypress.Promise((resolve) => $iframe.on('load', resolve))
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export const typeCode = (code, { delay = 200 } = {}) =>
|
|
30
|
-
getCodeEditor()
|
|
31
|
-
.focused()
|
|
32
|
-
.type(code, { force: true, delay })
|
|
33
|
-
.wait(WAIT_FOR_FRAME_TO_RENDER);
|
|
15
|
+
export const typeCode = (code, { delay } = {}) =>
|
|
16
|
+
getCodeEditor().focused().type(code, { delay });
|
|
34
17
|
|
|
35
18
|
export const formatCode = () =>
|
|
36
19
|
getCodeEditor()
|
|
37
20
|
.focused()
|
|
38
|
-
.type(`${isMac() ? '{cmd}' : '{ctrl}'}s`)
|
|
39
|
-
.wait(WAIT_FOR_FRAME_TO_RENDER);
|
|
21
|
+
.type(`${isMac() ? '{cmd}' : '{ctrl}'}s`);
|
|
40
22
|
|
|
41
23
|
export const selectWidthPreferenceByIndex = (index) =>
|
|
42
24
|
cy
|
|
@@ -59,9 +41,7 @@ export const toggleSnippets = () =>
|
|
|
59
41
|
cy.get('[data-testid="toggleSnippets"]').click();
|
|
60
42
|
|
|
61
43
|
export const filterSnippets = (search) => {
|
|
62
|
-
cy.get('[data-testid="filterSnippets"]').type(search
|
|
63
|
-
// eslint-disable-next-line @finsit/cypress/no-unnecessary-waiting
|
|
64
|
-
cy.wait(200);
|
|
44
|
+
cy.get('[data-testid="filterSnippets"]').type(search);
|
|
65
45
|
};
|
|
66
46
|
|
|
67
47
|
export const assertSnippetsListIsVisible = () =>
|
|
@@ -72,38 +52,71 @@ const getSnippets = () => cy.get('[data-testid="snippet-list"] li');
|
|
|
72
52
|
export const selectSnippetByIndex = (index) => getSnippets().eq(index);
|
|
73
53
|
|
|
74
54
|
export const mouseOverSnippet = (index) =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.wait(WAIT_FOR_FRAME_TO_RENDER);
|
|
55
|
+
// force stops cypress scrolling the panel out of the editor
|
|
56
|
+
selectSnippetByIndex(index).trigger('mousemove', { force: true });
|
|
78
57
|
|
|
79
58
|
export const assertSnippetCount = (count) =>
|
|
80
59
|
getSnippets().should('have.length', count);
|
|
81
60
|
|
|
82
|
-
export const assertFirstFrameContains = (text) =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
.
|
|
88
|
-
|
|
89
|
-
expect(el.get(0).innerText).to.eq(text);
|
|
90
|
-
})
|
|
91
|
-
);
|
|
92
|
-
};
|
|
61
|
+
export const assertFirstFrameContains = (text) =>
|
|
62
|
+
getPreviewFrames()
|
|
63
|
+
.first()
|
|
64
|
+
.its('0.contentDocument.body')
|
|
65
|
+
.should((frameBody) => {
|
|
66
|
+
expect(frameBody.innerText).to.eq(text);
|
|
67
|
+
});
|
|
93
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @param {number} numCharacters
|
|
71
|
+
*/
|
|
94
72
|
export const selectNextCharacters = (numCharacters) => {
|
|
95
73
|
typeCode('{shift+rightArrow}'.repeat(numCharacters));
|
|
96
74
|
};
|
|
97
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @param {number} numWords
|
|
78
|
+
*/
|
|
98
79
|
export const selectNextWords = (numWords) => {
|
|
99
80
|
const modifier = isMac() ? 'alt' : 'ctrl';
|
|
100
81
|
typeCode(`{shift+${modifier}+rightArrow}`.repeat(numWords));
|
|
101
82
|
};
|
|
102
83
|
|
|
84
|
+
export const selectToStartOfLine = () => {
|
|
85
|
+
typeCode(isMac() ? '{shift+cmd+leftArrow}' : '{shift+home}');
|
|
86
|
+
};
|
|
87
|
+
|
|
103
88
|
export const selectToEndOfLine = () => {
|
|
104
89
|
typeCode(isMac() ? '{shift+cmd+rightArrow}' : '{shift+end}');
|
|
105
90
|
};
|
|
106
91
|
|
|
92
|
+
/**
|
|
93
|
+
* @param {number} x;
|
|
94
|
+
* @param {number | undefined} y
|
|
95
|
+
*/
|
|
96
|
+
export const moveBy = (x, y = 0) => {
|
|
97
|
+
if (x) {
|
|
98
|
+
const xDirection = x >= 0 ? '{rightArrow}' : '{leftArrow}';
|
|
99
|
+
typeCode(xDirection.repeat(x));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (y) {
|
|
103
|
+
const yDirection = y >= 0 ? '{downArrow}' : '{upArrow}';
|
|
104
|
+
typeCode(yDirection.repeat(y));
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {number} numWords
|
|
110
|
+
*/
|
|
111
|
+
export const moveByWords = (numWords) => {
|
|
112
|
+
const modifier = isMac() ? 'alt' : 'ctrl';
|
|
113
|
+
typeCode(`{${modifier}+rightArrow}`.repeat(numWords));
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const moveToEndOfLine = () => {
|
|
117
|
+
typeCode(isMac() ? '{cmd+rightArrow}' : '{end}');
|
|
118
|
+
};
|
|
119
|
+
|
|
107
120
|
/**
|
|
108
121
|
* @typedef {import('../../src/Playroom/CodeEditor/keymaps/types').Direction} Direction
|
|
109
122
|
*/
|
|
@@ -111,20 +124,22 @@ export const selectToEndOfLine = () => {
|
|
|
111
124
|
* @param {number} numLines
|
|
112
125
|
* @param {Direction} direction
|
|
113
126
|
*/
|
|
114
|
-
export const
|
|
127
|
+
export const selectNextLines = (numLines, direction = 'down') => {
|
|
115
128
|
const arrowCode = direction === 'down' ? 'downArrow' : 'upArrow';
|
|
116
129
|
typeCode(`{shift+${arrowCode}}`.repeat(numLines));
|
|
117
130
|
};
|
|
118
131
|
|
|
119
132
|
export const assertCodePaneContains = (text) => {
|
|
120
133
|
getCodeEditor().within(() => {
|
|
134
|
+
// Accumulate text from individual line elements as they don't include line numbers
|
|
121
135
|
const lines = [];
|
|
122
136
|
cy.get('.CodeMirror-line').each(($el) => lines.push($el.text()));
|
|
137
|
+
|
|
123
138
|
cy.then(() => {
|
|
124
|
-
const code = lines.join('\n');
|
|
125
139
|
// removes code mirrors invisible last line character placeholder
|
|
126
|
-
// which is inserted to preserve
|
|
127
|
-
|
|
140
|
+
// which is inserted to preserve prettier's new line at end of string.
|
|
141
|
+
const code = lines.join('\n').replace(/[\u200b]$/, '');
|
|
142
|
+
expect(code).to.equal(text);
|
|
128
143
|
});
|
|
129
144
|
});
|
|
130
145
|
};
|
|
@@ -138,7 +153,7 @@ export const assertCodePaneLineCount = (lines) => {
|
|
|
138
153
|
export const assertFramesMatch = (matches) =>
|
|
139
154
|
getPreviewFrameNames()
|
|
140
155
|
.should('have.length', matches.length)
|
|
141
|
-
.
|
|
156
|
+
.should((frames) => {
|
|
142
157
|
const frameNames = frames.map((_, el) => el.innerText).toArray();
|
|
143
158
|
return expect(frameNames).to.deep.equal(matches);
|
|
144
159
|
});
|
|
@@ -149,7 +164,7 @@ export const assertPreviewContains = (text) =>
|
|
|
149
164
|
cy.get('[data-testid="splashscreen"]').should('not.be.visible');
|
|
150
165
|
})
|
|
151
166
|
.get('body')
|
|
152
|
-
.
|
|
167
|
+
.should((el) => {
|
|
153
168
|
expect(el.get(0).innerText).to.eq(text);
|
|
154
169
|
});
|
|
155
170
|
|
|
@@ -165,12 +180,5 @@ export const loadPlayroom = (initialCode) => {
|
|
|
165
180
|
.then((win) => {
|
|
166
181
|
const { storageKey } = win.__playroomConfig__;
|
|
167
182
|
indexedDB.deleteDatabase(storageKey);
|
|
168
|
-
})
|
|
169
|
-
.reload()
|
|
170
|
-
.then(() =>
|
|
171
|
-
getFirstFrame().then(
|
|
172
|
-
($iframe) =>
|
|
173
|
-
new Cypress.Promise((resolve) => $iframe.on('load', resolve))
|
|
174
|
-
)
|
|
175
|
-
);
|
|
183
|
+
});
|
|
176
184
|
};
|
package/lib/makeWebpackConfig.js
CHANGED
|
@@ -74,9 +74,6 @@ module.exports = async (playroomConfig, options) => {
|
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
76
|
module: {
|
|
77
|
-
// This option fixes https://github.com/prettier/prettier/issues/4959
|
|
78
|
-
// Once this issue is fixed, we can remove this line:
|
|
79
|
-
exprContextCritical: false,
|
|
80
77
|
rules: [
|
|
81
78
|
{
|
|
82
79
|
test: /\.(ts|tsx)$/,
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
const readPackage = require('read-pkg-up');
|
|
2
|
-
const
|
|
2
|
+
const { execSync } = require('child_process');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @returns {string | null} The current git branch name, or null if no branch is found
|
|
6
|
+
*/
|
|
7
|
+
const getGitBranch = () => {
|
|
8
|
+
try {
|
|
9
|
+
return execSync('git branch --show-current').toString().trim();
|
|
10
|
+
} catch (e) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
3
14
|
|
|
4
15
|
const generateStorageKey = () => {
|
|
5
16
|
const pkg = readPackage.sync();
|
|
6
17
|
const packageName = (pkg && pkg.packageJson && pkg.packageJson.name) || null;
|
|
7
|
-
const branchName =
|
|
18
|
+
const branchName = getGitBranch();
|
|
8
19
|
|
|
9
20
|
const packageLabel = packageName ? `package:${packageName}` : null;
|
|
10
21
|
const branchLabel = branchName ? `branch:${branchName}` : null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "Design with code, powered by your own component library",
|
|
5
5
|
"main": "utils/index.js",
|
|
6
6
|
"types": "utils/index.d.ts",
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
"@soda/friendly-errors-webpack-plugin": "^1.8.1",
|
|
35
35
|
"@types/base64-url": "^2.2.0",
|
|
36
36
|
"@types/codemirror": "^5.60.5",
|
|
37
|
-
"@types/dedent": "^0.7.0",
|
|
38
37
|
"@types/lodash": "^4.14.191",
|
|
39
38
|
"@types/lz-string": "^1.3.34",
|
|
40
39
|
"@types/prettier": "^2.7.1",
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
"@vanilla-extract/css": "^1.9.2",
|
|
44
43
|
"@vanilla-extract/css-utils": "^0.1.3",
|
|
45
44
|
"@vanilla-extract/sprinkles": "^1.5.1",
|
|
46
|
-
"@vanilla-extract/webpack-plugin": "2.
|
|
45
|
+
"@vanilla-extract/webpack-plugin": "^2.3.6",
|
|
47
46
|
"babel-loader": "^9.1.0",
|
|
48
47
|
"classnames": "^2.3.2",
|
|
49
48
|
"codemirror": "^5.65.10",
|
|
@@ -51,8 +50,7 @@
|
|
|
51
50
|
"command-line-usage": "^6.1.3",
|
|
52
51
|
"copy-to-clipboard": "^3.3.3",
|
|
53
52
|
"css-loader": "^6.7.2",
|
|
54
|
-
"
|
|
55
|
-
"dedent": "^0.7.0",
|
|
53
|
+
"dedent": "^1.5.1",
|
|
56
54
|
"fast-glob": "^3.2.12",
|
|
57
55
|
"find-up": "^5.0.0",
|
|
58
56
|
"fuzzy": "^0.1.3",
|
|
@@ -69,17 +67,17 @@
|
|
|
69
67
|
"portfinder": "^1.0.32",
|
|
70
68
|
"prettier": "^2.8.1",
|
|
71
69
|
"prop-types": "^15.8.1",
|
|
72
|
-
"query-string": "^7.1.3",
|
|
73
70
|
"re-resizable": "^6.9.9",
|
|
74
71
|
"react-docgen-typescript": "^2.2.2",
|
|
72
|
+
"react-helmet": "^6.1.0",
|
|
75
73
|
"react-use": "^17.4.0",
|
|
76
74
|
"read-pkg-up": "^7.0.1",
|
|
77
75
|
"scope-eval": "^1.0.0",
|
|
78
76
|
"sucrase": "^3.34.0",
|
|
79
77
|
"typescript": ">=5.0.0",
|
|
80
|
-
"use-debounce": "^
|
|
78
|
+
"use-debounce": "^10.0.0",
|
|
81
79
|
"webpack": "^5.75.0",
|
|
82
|
-
"webpack-dev-server": "^
|
|
80
|
+
"webpack-dev-server": "^5.0.2",
|
|
83
81
|
"webpack-merge": "^5.8.0"
|
|
84
82
|
},
|
|
85
83
|
"devDependencies": {
|
|
@@ -87,13 +85,13 @@
|
|
|
87
85
|
"@changesets/cli": "^2.25.2",
|
|
88
86
|
"@octokit/rest": "^19.0.5",
|
|
89
87
|
"@types/jest": "^29.2.4",
|
|
90
|
-
"
|
|
91
|
-
"cypress": "^
|
|
88
|
+
"@types/react-helmet": "^6.1.6",
|
|
89
|
+
"cypress": "^13.6.6",
|
|
92
90
|
"eslint": "^8.44.0",
|
|
93
91
|
"eslint-config-seek": "^11.3.1",
|
|
94
92
|
"husky": "^8.0.2",
|
|
95
93
|
"jest": "^29.3.1",
|
|
96
|
-
"lint-staged": "^
|
|
94
|
+
"lint-staged": "^15.2.2",
|
|
97
95
|
"react": "^18.0.1",
|
|
98
96
|
"react-dom": "^18.0.1",
|
|
99
97
|
"serve": "^14.1.2",
|
|
@@ -104,9 +102,12 @@
|
|
|
104
102
|
"react": "^17 || ^18",
|
|
105
103
|
"react-dom": "^17 || ^18"
|
|
106
104
|
},
|
|
107
|
-
"
|
|
105
|
+
"engines": {
|
|
106
|
+
"node": ">=18.12.0"
|
|
107
|
+
},
|
|
108
|
+
"packageManager": "pnpm@8.15.3",
|
|
108
109
|
"volta": {
|
|
109
|
-
"node": "
|
|
110
|
+
"node": "18.19.1"
|
|
110
111
|
},
|
|
111
112
|
"scripts": {
|
|
112
113
|
"cypress": "start-server-and-test build-and-serve:all '9000|9001|9002' 'cypress run'",
|
|
@@ -121,11 +122,11 @@
|
|
|
121
122
|
"start:typescript": "./bin/cli.cjs start --config cypress/projects/typescript/playroom.config.js",
|
|
122
123
|
"build:typescript": "./bin/cli.cjs build --config cypress/projects/typescript/playroom.config.js",
|
|
123
124
|
"serve:typescript": "PORT=9002 serve --no-request-logging cypress/projects/typescript/dist",
|
|
124
|
-
"start:all": "
|
|
125
|
-
"build:all": "
|
|
126
|
-
"serve:all": "
|
|
125
|
+
"start:all": "pnpm run '/^start:(?!all)/'",
|
|
126
|
+
"build:all": "pnpm run '/^build:(?!all)/'",
|
|
127
|
+
"serve:all": "pnpm run '/^serve:(?!all)/'",
|
|
127
128
|
"build-and-serve:all": "pnpm build:all && pnpm serve:all",
|
|
128
|
-
"lint": "
|
|
129
|
+
"lint": "pnpm run '/^lint:.*/'",
|
|
129
130
|
"lint:eslint": "eslint --cache .",
|
|
130
131
|
"lint:prettier": "prettier --list-different '**/*.{js,md,ts,tsx}'",
|
|
131
132
|
"lint:tsc": "tsc --noEmit",
|
|
@@ -34,12 +34,11 @@ export default class CatchErrors extends Component<Props, State> {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// Ensure the stack only contains user-provided components
|
|
37
|
-
const componentStack =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
: [];
|
|
37
|
+
const componentStack =
|
|
38
|
+
errorInfo?.componentStack
|
|
39
|
+
?.split('\n')
|
|
40
|
+
.filter((line: string) => /RenderCode/.test(line))
|
|
41
|
+
.map((line: string) => line.replace(/ \(created by .*/g, '')) ?? [];
|
|
43
42
|
|
|
44
43
|
// Ignore the RenderCode container component
|
|
45
44
|
const lines = componentStack.slice(0, componentStack.length - 1);
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
selectNextOccurrence,
|
|
37
37
|
} from './keymaps/cursors';
|
|
38
38
|
import { wrapInTag } from './keymaps/wrap';
|
|
39
|
+
import { toggleComment } from './keymaps/comment';
|
|
39
40
|
|
|
40
41
|
const validateCodeInEditor = (editorInstance: Editor, code: string) => {
|
|
41
42
|
const maybeValid = validateCode(code);
|
|
@@ -257,6 +258,16 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => {
|
|
|
257
258
|
[`${keymapModifierKey}-Alt-Down`]: addCursorToNextLine,
|
|
258
259
|
[`${keymapModifierKey}-D`]: selectNextOccurrence,
|
|
259
260
|
[`Shift-${keymapModifierKey}-,`]: wrapInTag,
|
|
261
|
+
[`${keymapModifierKey}-/`]: toggleComment,
|
|
262
|
+
[`Shift-${keymapModifierKey}-C`]: () => {
|
|
263
|
+
dispatch({
|
|
264
|
+
type: 'copyToClipboard',
|
|
265
|
+
payload: {
|
|
266
|
+
url: window.location.href,
|
|
267
|
+
trigger: 'toolbarItem',
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
},
|
|
260
271
|
},
|
|
261
272
|
}}
|
|
262
273
|
/>
|