playroom 0.28.1 → 0.28.2
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/.babelrc +0 -6
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.github/workflows/preview-site.yml +8 -4
- package/.github/workflows/release.yml +12 -6
- package/.github/workflows/snapshot.yml +5 -1
- package/.github/workflows/validate.yml +31 -4
- package/.husky/pre-commit +4 -0
- package/.nvmrc +1 -1
- package/CHANGELOG.md +26 -0
- package/cypress/{integration/editor.js → e2e/editor.cy.js} +0 -0
- package/cypress/{integration/scope.js → e2e/scope.cy.js} +0 -0
- package/cypress/{integration/smoke.js → e2e/smoke.cy.js} +0 -0
- package/cypress/{integration/snippets.js → e2e/snippets.cy.js} +0 -0
- package/cypress/{integration/toolbar.js → e2e/toolbar.cy.js} +0 -0
- package/cypress/{integration/urlHandling.js → e2e/urlHandling.cy.js} +0 -0
- package/cypress/support/{index.js → e2e.js} +0 -0
- package/cypress.config.ts +7 -0
- package/lib/build.js +1 -1
- package/package.json +82 -103
- package/src/Playroom/CodeEditor/CodeEditor.tsx +22 -14
- package/src/Playroom/FramesPanel/FramesPanel.css.ts +5 -4
- package/src/Playroom/FramesPanel/FramesPanel.tsx +2 -3
- package/src/Playroom/Playroom.tsx +2 -2
- package/src/Playroom/Preview.tsx +13 -16
- package/src/Playroom/Snippets/Snippets.tsx +4 -5
- package/src/StoreContext/StoreContext.tsx +223 -225
- package/src/utils/compileJsx.ts +4 -1
- package/tsconfig.json +1 -1
- package/cypress.json +0 -4
package/.babelrc
CHANGED
|
@@ -3,11 +3,5 @@
|
|
|
3
3
|
"@babel/preset-typescript",
|
|
4
4
|
"@babel/preset-env",
|
|
5
5
|
"@babel/preset-react"
|
|
6
|
-
],
|
|
7
|
-
"plugins": [
|
|
8
|
-
"@babel/plugin-proposal-class-properties",
|
|
9
|
-
"@babel/plugin-proposal-optional-chaining",
|
|
10
|
-
"@babel/plugin-proposal-nullish-coalescing-operator",
|
|
11
|
-
"@vanilla-extract/babel-plugin"
|
|
12
6
|
]
|
|
13
7
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "public",
|
|
8
|
+
"baseBranch": "master",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
|
@@ -15,24 +15,28 @@ jobs:
|
|
|
15
15
|
- name: Checkout Repo
|
|
16
16
|
uses: actions/checkout@v3
|
|
17
17
|
|
|
18
|
+
- name: Set up pnpm
|
|
19
|
+
uses: pnpm/action-setup@v2.2.2
|
|
20
|
+
|
|
18
21
|
- name: Set up Node.js
|
|
19
22
|
uses: actions/setup-node@v3
|
|
20
23
|
with:
|
|
21
24
|
node-version-file: 'package.json'
|
|
25
|
+
cache: 'pnpm'
|
|
22
26
|
|
|
23
27
|
- name: Install Dependencies
|
|
24
|
-
run:
|
|
28
|
+
run: pnpm i
|
|
25
29
|
|
|
26
30
|
- name: Build
|
|
27
|
-
run:
|
|
31
|
+
run: pnpm build:themed
|
|
28
32
|
|
|
29
33
|
- name: Deploy to surge
|
|
30
|
-
run:
|
|
34
|
+
run: pnpm deploy-preview -d playroom--${GITHUB_SHA}.surge.sh
|
|
31
35
|
env:
|
|
32
36
|
SURGE_LOGIN: ${{ secrets.SURGE_LOGIN }}
|
|
33
37
|
SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
|
|
34
38
|
|
|
35
39
|
- name: Update PR status
|
|
36
|
-
run:
|
|
40
|
+
run: pnpm post-commit-status
|
|
37
41
|
env:
|
|
38
42
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -15,20 +15,26 @@ jobs:
|
|
|
15
15
|
- name: Checkout Repo
|
|
16
16
|
uses: actions/checkout@v3
|
|
17
17
|
with:
|
|
18
|
-
# This makes Actions fetch all Git history
|
|
18
|
+
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
|
|
19
19
|
fetch-depth: 0
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
- name: Set up pnpm
|
|
22
|
+
uses: pnpm/action-setup@v2.2.2
|
|
21
23
|
|
|
22
24
|
- name: Set up Node.js
|
|
23
25
|
uses: actions/setup-node@v3
|
|
24
26
|
with:
|
|
25
27
|
node-version-file: 'package.json'
|
|
28
|
+
cache: 'pnpm'
|
|
26
29
|
|
|
27
30
|
- name: Install Dependencies
|
|
28
|
-
run:
|
|
31
|
+
run: pnpm i
|
|
29
32
|
|
|
30
|
-
- name: Publish to npm
|
|
31
|
-
|
|
33
|
+
- name: Create Release Pull Request or Publish to npm
|
|
34
|
+
uses: changesets/action@v1
|
|
35
|
+
with:
|
|
36
|
+
version: pnpm run version
|
|
37
|
+
publish: pnpm release
|
|
32
38
|
env:
|
|
33
|
-
GITHUB_TOKEN: ${{ secrets.
|
|
39
|
+
GITHUB_TOKEN: ${{ secrets.SEEK_OSS_CI_GITHUB_TOKEN }}
|
|
34
40
|
NPM_TOKEN: ${{ secrets.SEEK_OSS_CI_NPM_TOKEN }}
|
|
@@ -16,13 +16,17 @@ jobs:
|
|
|
16
16
|
fetch-depth: 0
|
|
17
17
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
18
18
|
|
|
19
|
+
- name: Set up pnpm
|
|
20
|
+
uses: pnpm/action-setup@v2.2.2
|
|
21
|
+
|
|
19
22
|
- name: Set up Node.js
|
|
20
23
|
uses: actions/setup-node@v3
|
|
21
24
|
with:
|
|
22
25
|
node-version-file: 'package.json'
|
|
26
|
+
cache: 'pnpm'
|
|
23
27
|
|
|
24
28
|
- name: Install dependencies
|
|
25
|
-
run:
|
|
29
|
+
run: pnpm i
|
|
26
30
|
|
|
27
31
|
- name: Publish
|
|
28
32
|
uses: seek-oss/changesets-snapshot@v0
|
|
@@ -12,19 +12,46 @@ jobs:
|
|
|
12
12
|
- name: Checkout Repo
|
|
13
13
|
uses: actions/checkout@v3
|
|
14
14
|
|
|
15
|
+
- name: Set up pnpm
|
|
16
|
+
uses: pnpm/action-setup@v2.2.2
|
|
17
|
+
|
|
15
18
|
- name: Set up Node.js
|
|
16
19
|
uses: actions/setup-node@v3
|
|
17
20
|
with:
|
|
18
21
|
node-version-file: 'package.json'
|
|
19
22
|
|
|
23
|
+
- name: Get pnpm store directory
|
|
24
|
+
id: pnpm-cache
|
|
25
|
+
shell: bash
|
|
26
|
+
run: |
|
|
27
|
+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
28
|
+
|
|
29
|
+
- name: Cache node modules
|
|
30
|
+
uses: actions/cache@v3
|
|
31
|
+
with:
|
|
32
|
+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
33
|
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
34
|
+
restore-keys: |
|
|
35
|
+
${{ runner.os }}-pnpm-store-
|
|
36
|
+
|
|
37
|
+
- name: Cache Cypress binary
|
|
38
|
+
uses: actions/cache@v3
|
|
39
|
+
with:
|
|
40
|
+
path: ~/.cache/Cypress
|
|
41
|
+
key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
42
|
+
restore-keys: |
|
|
43
|
+
cypress-${{ runner.os }}-cypress-
|
|
44
|
+
|
|
20
45
|
- name: Install Dependencies
|
|
21
|
-
run:
|
|
46
|
+
run: pnpm i
|
|
22
47
|
|
|
23
48
|
- name: Lint
|
|
24
|
-
run:
|
|
49
|
+
run: pnpm lint
|
|
25
50
|
|
|
26
51
|
- name: Test
|
|
27
|
-
run:
|
|
52
|
+
run: pnpm test
|
|
28
53
|
|
|
29
54
|
- name: Cypress
|
|
30
|
-
run:
|
|
55
|
+
run: |
|
|
56
|
+
pnpm cypress:verify
|
|
57
|
+
pnpm cypress
|
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
16.13.0
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# playroom
|
|
2
|
+
|
|
3
|
+
## 0.28.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8030325: Update all dependencies
|
|
8
|
+
- 8030325: Fix error message on gutter marker tooltip
|
|
9
|
+
|
|
10
|
+
Playroom wraps the code in a Fragment to compile it and then removes it from the error message displayed as a tooltip on the gutter marker if it fails to compile.
|
|
11
|
+
|
|
12
|
+
The logic has been improved to remove the first occurence of an opening `<React.Fragment>` and the last occurence of `</React.Fragment>`.
|
|
13
|
+
|
|
14
|
+
Errors should no longer incorrectly have a stray closing fragment:
|
|
15
|
+
|
|
16
|
+
```diff
|
|
17
|
+
"unknown: Expected corresponding JSX closing tag for <Boxerror>. (3:0)
|
|
18
|
+
|
|
19
|
+
1 | <Boxerror>
|
|
20
|
+
2 | ...
|
|
21
|
+
-> 3 | </Box></React.Fragment>
|
|
22
|
+
+> 3 | </Box>
|
|
23
|
+
| ^"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- cbcf1cf: Update dependencies (and move to pnpm internally)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/build.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = async (config, callback = noop) => {
|
|
|
16
16
|
|
|
17
17
|
if (stats.hasErrors()) {
|
|
18
18
|
const info = stats.toJson();
|
|
19
|
-
return callback(info.errors.join('\n\n'));
|
|
19
|
+
return callback(info.errors.map((error) => error.message).join('\n\n'));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
return callback();
|
package/package.json
CHANGED
|
@@ -1,55 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playroom",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.2",
|
|
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",
|
|
7
7
|
"bin": {
|
|
8
8
|
"playroom": "bin/cli.js"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"cypress": "start-server-and-test build-and-serve:all '9000|9001' 'cypress run'",
|
|
12
|
-
"cypress:dev": "start-server-and-test start:all '9000|9001' 'cypress open'",
|
|
13
|
-
"start:basic": "./bin/cli.js start --config cypress/projects/basic/playroom.config.js",
|
|
14
|
-
"build:basic": "./bin/cli.js build --config cypress/projects/basic/playroom.config.js",
|
|
15
|
-
"serve:basic": "PORT=9000 serve cypress/projects/basic/dist",
|
|
16
|
-
"start:themed": "./bin/cli.js start --config cypress/projects/themed/playroom.config.js",
|
|
17
|
-
"build:themed": "./bin/cli.js build --config cypress/projects/themed/playroom.config.js",
|
|
18
|
-
"serve:themed": "PORT=9001 serve --config ../serve.json cypress/projects/themed/dist",
|
|
19
|
-
"start:all": "concurrently 'npm:start:basic' 'npm:start:themed'",
|
|
20
|
-
"build:all": "concurrently 'npm:build:basic' 'npm:build:themed'",
|
|
21
|
-
"serve:all": "concurrently 'npm:serve:basic' 'npm:serve:themed'",
|
|
22
|
-
"build-and-serve:all": "yarn build:all && yarn serve:all",
|
|
23
|
-
"commit": "git-cz",
|
|
24
|
-
"lint": "eslint . && prettier --list-different '**/*.{js,md,less,ts,tsx}' && tsc --noEmit",
|
|
25
|
-
"format": "prettier --write '**/*.{js,md,less,ts,tsx}'",
|
|
26
|
-
"semantic-release": "semantic-release",
|
|
27
|
-
"test": "jest src",
|
|
28
|
-
"post-commit-status": "node scripts/postCommitStatus.js",
|
|
29
|
-
"deploy-preview": "surge -p ./cypress/projects/themed/dist"
|
|
30
|
-
},
|
|
31
|
-
"husky": {
|
|
32
|
-
"hooks": {
|
|
33
|
-
"commit-msg": "commitlint --edit --extends seek",
|
|
34
|
-
"pre-commit": "lint-staged"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
10
|
"lint-staged": {
|
|
38
11
|
"**/*.{js,ts,tsx}": [
|
|
39
|
-
"
|
|
12
|
+
"eslint"
|
|
40
13
|
],
|
|
41
|
-
"**/*.{js,md,
|
|
14
|
+
"**/*.{js,md,ts,tsx}": [
|
|
42
15
|
"prettier --write"
|
|
43
16
|
]
|
|
44
17
|
},
|
|
45
|
-
"config": {
|
|
46
|
-
"commitizen": {
|
|
47
|
-
"path": "cz-conventional-changelog"
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
"release": {
|
|
51
|
-
"success": false
|
|
52
|
-
},
|
|
53
18
|
"repository": {
|
|
54
19
|
"type": "git",
|
|
55
20
|
"url": "https://github.com/seek-oss/playroom.git"
|
|
@@ -61,92 +26,106 @@
|
|
|
61
26
|
},
|
|
62
27
|
"homepage": "https://github.com/seek-oss/playroom#readme",
|
|
63
28
|
"dependencies": {
|
|
64
|
-
"@babel/cli": "^7.
|
|
65
|
-
"@babel/core": "^7.
|
|
66
|
-
"@babel/preset-env": "^7.
|
|
67
|
-
"@babel/preset-react": "^7.
|
|
68
|
-
"@babel/preset-typescript": "^7.
|
|
69
|
-
"@babel/standalone": "^7.
|
|
70
|
-
"@soda/friendly-errors-webpack-plugin": "^1.8.
|
|
29
|
+
"@babel/cli": "^7.19.3",
|
|
30
|
+
"@babel/core": "^7.20.5",
|
|
31
|
+
"@babel/preset-env": "^7.20.2",
|
|
32
|
+
"@babel/preset-react": "^7.18.6",
|
|
33
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
34
|
+
"@babel/standalone": "^7.20.6",
|
|
35
|
+
"@soda/friendly-errors-webpack-plugin": "^1.8.1",
|
|
71
36
|
"@types/base64-url": "^2.2.0",
|
|
72
|
-
"@types/codemirror": "^
|
|
37
|
+
"@types/codemirror": "^5.60.5",
|
|
73
38
|
"@types/dedent": "^0.7.0",
|
|
74
|
-
"@types/
|
|
75
|
-
"@types/lodash": "^4.14.168",
|
|
39
|
+
"@types/lodash": "^4.14.191",
|
|
76
40
|
"@types/lz-string": "^1.3.34",
|
|
77
|
-
"@types/prettier": "^2.
|
|
78
|
-
"@types/react": "^18.0.
|
|
79
|
-
"@types/react-dom": "^18.0.
|
|
80
|
-
"@vanilla-extract/
|
|
81
|
-
"@vanilla-extract/css": "^1.
|
|
82
|
-
"@vanilla-extract/
|
|
83
|
-
"@vanilla-extract/
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"command-line-
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"css-loader": "^5.1.3",
|
|
41
|
+
"@types/prettier": "^2.7.1",
|
|
42
|
+
"@types/react": "^18.0.26",
|
|
43
|
+
"@types/react-dom": "^18.0.9",
|
|
44
|
+
"@vanilla-extract/css": "^1.9.2",
|
|
45
|
+
"@vanilla-extract/css-utils": "^0.1.3",
|
|
46
|
+
"@vanilla-extract/sprinkles": "^1.5.1",
|
|
47
|
+
"@vanilla-extract/webpack-plugin": "2.1.12",
|
|
48
|
+
"babel-loader": "^9.1.0",
|
|
49
|
+
"classnames": "^2.3.2",
|
|
50
|
+
"codemirror": "^5.65.10",
|
|
51
|
+
"command-line-args": "^5.2.1",
|
|
52
|
+
"command-line-usage": "^6.1.3",
|
|
53
|
+
"copy-to-clipboard": "^3.3.3",
|
|
54
|
+
"css-loader": "^6.7.2",
|
|
92
55
|
"current-git-branch": "^1.1.0",
|
|
93
56
|
"dedent": "^0.7.0",
|
|
94
|
-
"fast-glob": "^3.2.
|
|
57
|
+
"fast-glob": "^3.2.12",
|
|
95
58
|
"find-up": "^5.0.0",
|
|
96
59
|
"fuzzy": "^0.1.3",
|
|
97
|
-
"history": "^5.
|
|
98
|
-
"html-webpack-plugin": "^5.
|
|
99
|
-
"intersection-observer": "^0.12.
|
|
100
|
-
"localforage": "^1.
|
|
101
|
-
"locate-path": "^6.0.0",
|
|
60
|
+
"history": "^5.3.0",
|
|
61
|
+
"html-webpack-plugin": "^5.5.0",
|
|
62
|
+
"intersection-observer": "^0.12.2",
|
|
63
|
+
"localforage": "^1.10.0",
|
|
102
64
|
"lodash": "^4.17.21",
|
|
103
65
|
"lz-string": "^1.4.4",
|
|
104
|
-
"mini-css-extract-plugin": "^2.
|
|
66
|
+
"mini-css-extract-plugin": "^2.7.2",
|
|
105
67
|
"parse-prop-types": "^0.3.0",
|
|
106
|
-
"polished": "^4.
|
|
107
|
-
"portfinder": "^1.0.
|
|
108
|
-
"prettier": "^2.
|
|
109
|
-
"prop-types": "^15.
|
|
110
|
-
"query-string": "^
|
|
111
|
-
"re-resizable": "^6.9.
|
|
112
|
-
"react-docgen-typescript": "^2.
|
|
68
|
+
"polished": "^4.2.2",
|
|
69
|
+
"portfinder": "^1.0.32",
|
|
70
|
+
"prettier": "^2.8.1",
|
|
71
|
+
"prop-types": "^15.8.1",
|
|
72
|
+
"query-string": "^7.1.3",
|
|
73
|
+
"re-resizable": "^6.9.9",
|
|
74
|
+
"react-docgen-typescript": "^2.2.2",
|
|
113
75
|
"react-use": "^17.4.0",
|
|
114
76
|
"read-pkg-up": "^7.0.1",
|
|
115
77
|
"scope-eval": "^1.0.0",
|
|
116
|
-
"typescript": "^4.
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"webpack": "^
|
|
120
|
-
"webpack-
|
|
121
|
-
"webpack-merge": "^5.7.3"
|
|
78
|
+
"typescript": "^4.5.4",
|
|
79
|
+
"use-debounce": "^9.0.2",
|
|
80
|
+
"webpack": "^5.75.0",
|
|
81
|
+
"webpack-dev-server": "^4.11.1",
|
|
82
|
+
"webpack-merge": "^5.8.0"
|
|
122
83
|
},
|
|
123
84
|
"devDependencies": {
|
|
124
|
-
"@
|
|
125
|
-
"@octokit/rest": "^
|
|
126
|
-
"@types/jest": "^
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"husky": "^4.3.8",
|
|
135
|
-
"jest": "^26.6.3",
|
|
136
|
-
"lint-staged": "^10.5.4",
|
|
85
|
+
"@changesets/cli": "^2.25.2",
|
|
86
|
+
"@octokit/rest": "^19.0.5",
|
|
87
|
+
"@types/jest": "^29.2.4",
|
|
88
|
+
"concurrently": "^7.6.0",
|
|
89
|
+
"cypress": "^12.0.2",
|
|
90
|
+
"eslint": "^8.29.0",
|
|
91
|
+
"eslint-config-seek": "^10.1.2",
|
|
92
|
+
"husky": "^8.0.2",
|
|
93
|
+
"jest": "^29.3.1",
|
|
94
|
+
"lint-staged": "^13.1.0",
|
|
137
95
|
"react": "^18.0.1",
|
|
138
96
|
"react-dom": "^18.0.1",
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"surge": "^0.22.1"
|
|
97
|
+
"serve": "^14.1.2",
|
|
98
|
+
"start-server-and-test": "^1.15.2",
|
|
99
|
+
"surge": "^0.23.1"
|
|
143
100
|
},
|
|
144
101
|
"peerDependencies": {
|
|
145
102
|
"react": "^16.8 || ^17 || ^18",
|
|
146
103
|
"react-dom": "^16.8 || ^17 || ^18"
|
|
147
104
|
},
|
|
105
|
+
"packageManager": "pnpm@7.18.1",
|
|
148
106
|
"volta": {
|
|
149
|
-
"node": "
|
|
150
|
-
|
|
107
|
+
"node": "16.13.0"
|
|
108
|
+
},
|
|
109
|
+
"scripts": {
|
|
110
|
+
"cypress": "start-server-and-test build-and-serve:all '9000|9001' 'cypress run'",
|
|
111
|
+
"cypress:dev": "start-server-and-test start:all '9000|9001' 'cypress open --browser chrome --e2e'",
|
|
112
|
+
"cypress:verify": "cypress verify",
|
|
113
|
+
"start:basic": "./bin/cli.js start --config cypress/projects/basic/playroom.config.js",
|
|
114
|
+
"build:basic": "./bin/cli.js build --config cypress/projects/basic/playroom.config.js",
|
|
115
|
+
"serve:basic": "PORT=9000 serve --no-request-logging cypress/projects/basic/dist",
|
|
116
|
+
"start:themed": "./bin/cli.js start --config cypress/projects/themed/playroom.config.js",
|
|
117
|
+
"build:themed": "./bin/cli.js build --config cypress/projects/themed/playroom.config.js",
|
|
118
|
+
"serve:themed": "PORT=9001 serve --config ../serve.json --no-request-logging cypress/projects/themed/dist",
|
|
119
|
+
"start:all": "concurrently 'npm:start:basic' 'npm:start:themed'",
|
|
120
|
+
"build:all": "concurrently 'npm:build:basic' 'npm:build:themed'",
|
|
121
|
+
"serve:all": "concurrently 'npm:serve:basic' 'npm:serve:themed'",
|
|
122
|
+
"build-and-serve:all": "pnpm build:all && pnpm serve:all",
|
|
123
|
+
"lint": "eslint . && prettier --list-different '**/*.{js,md,ts,tsx}' && tsc --noEmit",
|
|
124
|
+
"format": "prettier --write '**/*.{js,md,ts,tsx}'",
|
|
125
|
+
"version": "changeset version",
|
|
126
|
+
"release": "changeset publish",
|
|
127
|
+
"test": "jest src",
|
|
128
|
+
"post-commit-status": "node scripts/postCommitStatus.js",
|
|
129
|
+
"deploy-preview": "surge -p ./cypress/projects/themed/dist"
|
|
151
130
|
}
|
|
152
|
-
}
|
|
131
|
+
}
|
|
@@ -6,7 +6,11 @@ import 'codemirror/theme/neo.css';
|
|
|
6
6
|
|
|
7
7
|
import { StoreContext, CursorPosition } from '../../StoreContext/StoreContext';
|
|
8
8
|
import { formatCode as format } from '../../utils/formatting';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
closeFragmentTag,
|
|
11
|
+
compileJsx,
|
|
12
|
+
openFragmentTag,
|
|
13
|
+
} from '../../utils/compileJsx';
|
|
10
14
|
|
|
11
15
|
import * as styles from './CodeEditor.css';
|
|
12
16
|
|
|
@@ -60,21 +64,27 @@ const validateCode = (editorInstance: Editor, code: string) => {
|
|
|
60
64
|
try {
|
|
61
65
|
compileJsx(code);
|
|
62
66
|
} catch (err) {
|
|
63
|
-
const errorMessage = err
|
|
67
|
+
const errorMessage = err instanceof Error ? err.message : '';
|
|
64
68
|
const matches = errorMessage.match(/\(([0-9]+):/);
|
|
65
69
|
const lineNumber =
|
|
66
70
|
matches && matches.length >= 2 && matches[1] && parseInt(matches[1], 10);
|
|
67
71
|
|
|
68
72
|
if (lineNumber) {
|
|
73
|
+
// Remove our wrapping Fragment from error message
|
|
74
|
+
const openWrapperStartIndex = errorMessage.indexOf(openFragmentTag);
|
|
75
|
+
const closeWrapperStartIndex = errorMessage.lastIndexOf(closeFragmentTag);
|
|
76
|
+
const formattedMessage = [
|
|
77
|
+
errorMessage.slice(0, openWrapperStartIndex),
|
|
78
|
+
errorMessage.slice(
|
|
79
|
+
openWrapperStartIndex + openFragmentTag.length,
|
|
80
|
+
closeWrapperStartIndex
|
|
81
|
+
),
|
|
82
|
+
errorMessage.slice(closeWrapperStartIndex + closeFragmentTag.length),
|
|
83
|
+
].join('');
|
|
84
|
+
|
|
69
85
|
const marker = document.createElement('div');
|
|
70
86
|
marker.setAttribute('class', styles.errorMarker);
|
|
71
|
-
marker.setAttribute(
|
|
72
|
-
'title',
|
|
73
|
-
// Remove our wrapping Fragment from error message
|
|
74
|
-
(err.message || '')
|
|
75
|
-
.replace(/\<React\.Fragment\>/, '')
|
|
76
|
-
.replace(/\<\/React\.Fragment\>$/, '')
|
|
77
|
-
);
|
|
87
|
+
marker.setAttribute('title', formattedMessage);
|
|
78
88
|
marker.innerText = String(lineNumber);
|
|
79
89
|
editorInstance.setGutterMarker(lineNumber - 1, 'errorGutter', marker);
|
|
80
90
|
}
|
|
@@ -97,11 +107,10 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => {
|
|
|
97
107
|
const insertionPointRef = useRef<ReturnType<Editor['addLineClass']> | null>(
|
|
98
108
|
null
|
|
99
109
|
);
|
|
100
|
-
const [{ cursorPosition, highlightLineNumber }, dispatch] =
|
|
101
|
-
StoreContext
|
|
102
|
-
);
|
|
110
|
+
const [{ cursorPosition, highlightLineNumber }, dispatch] =
|
|
111
|
+
useContext(StoreContext);
|
|
103
112
|
|
|
104
|
-
const
|
|
113
|
+
const debouncedChange = useDebouncedCallback(
|
|
105
114
|
(newCode: string) => onChange(newCode),
|
|
106
115
|
100
|
|
107
116
|
);
|
|
@@ -247,7 +256,6 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => {
|
|
|
247
256
|
autoCloseBrackets: true,
|
|
248
257
|
theme: 'neo',
|
|
249
258
|
gutters: ['errorGutter', 'CodeMirror-linenumbers', styles.foldGutter],
|
|
250
|
-
// @ts-expect-error
|
|
251
259
|
hintOptions: { schemaInfo: hints },
|
|
252
260
|
viewportMargin: 50,
|
|
253
261
|
lineNumbers: true,
|
|
@@ -120,10 +120,11 @@ export const fakeCheckbox = style([
|
|
|
120
120
|
background: colorPaletteVars.background.surface,
|
|
121
121
|
},
|
|
122
122
|
selectors: {
|
|
123
|
-
[`${checkbox}:hover:not(:focus) ~ &::before, ${checkbox}:focus ~ &::before`]:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
[`${checkbox}:hover:not(:focus) ~ &::before, ${checkbox}:focus ~ &::before`]:
|
|
124
|
+
{
|
|
125
|
+
opacity: 1,
|
|
126
|
+
transform: 'scale(1)',
|
|
127
|
+
},
|
|
127
128
|
},
|
|
128
129
|
},
|
|
129
130
|
]);
|
|
@@ -77,9 +77,8 @@ function FrameOption<Option>({
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export default ({ availableWidths, availableThemes }: FramesPanelProps) => {
|
|
80
|
-
const [{ visibleWidths = [], visibleThemes = [] }, dispatch] =
|
|
81
|
-
StoreContext
|
|
82
|
-
);
|
|
80
|
+
const [{ visibleWidths = [], visibleThemes = [] }, dispatch] =
|
|
81
|
+
useContext(StoreContext);
|
|
83
82
|
const hasThemes =
|
|
84
83
|
availableThemes.filter(
|
|
85
84
|
(themeName) => themeName !== '__PLAYROOM__NO_THEME__'
|
|
@@ -66,7 +66,7 @@ export default ({ components, themes, widths, snippets }: PlayroomProps) => {
|
|
|
66
66
|
dispatch,
|
|
67
67
|
] = useContext(StoreContext);
|
|
68
68
|
|
|
69
|
-
const
|
|
69
|
+
const updateEditorSize = useDebouncedCallback(
|
|
70
70
|
({
|
|
71
71
|
isVerticalEditor,
|
|
72
72
|
offsetWidth,
|
|
@@ -84,7 +84,7 @@ export default ({ components, themes, widths, snippets }: PlayroomProps) => {
|
|
|
84
84
|
1
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
const
|
|
87
|
+
const resetEditorPosition = useDebouncedCallback(() => {
|
|
88
88
|
if (editorPosition === 'undocked') {
|
|
89
89
|
dispatch({ type: 'resetEditorPosition' });
|
|
90
90
|
}
|
package/src/Playroom/Preview.tsx
CHANGED
|
@@ -25,23 +25,20 @@ export interface PreviewProps {
|
|
|
25
25
|
}>;
|
|
26
26
|
}
|
|
27
27
|
export default ({ themes, components, FrameComponent }: PreviewProps) => {
|
|
28
|
-
const { themeName, code } = useParams(
|
|
29
|
-
(rawParams)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
themeName: result.theme,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return {};
|
|
28
|
+
const { themeName, code } = useParams((rawParams): PreviewState => {
|
|
29
|
+
if (rawParams.code) {
|
|
30
|
+
const result = JSON.parse(
|
|
31
|
+
lzString.decompressFromEncodedURIComponent(String(rawParams.code)) ?? ''
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
code: compileJsx(result.code),
|
|
36
|
+
themeName: result.theme,
|
|
37
|
+
};
|
|
43
38
|
}
|
|
44
|
-
|
|
39
|
+
|
|
40
|
+
return {};
|
|
41
|
+
});
|
|
45
42
|
|
|
46
43
|
const resolvedTheme = themeName ? themes[themeName] : null;
|
|
47
44
|
|
|
@@ -77,9 +77,8 @@ const scrollToHighlightedSnippet = (
|
|
|
77
77
|
|
|
78
78
|
export default ({ snippets, onHighlight, onClose }: Props) => {
|
|
79
79
|
const [searchTerm, setSearchTerm] = useState<string>('');
|
|
80
|
-
const [highlightedIndex, setHighlightedIndex] =
|
|
81
|
-
null
|
|
82
|
-
);
|
|
80
|
+
const [highlightedIndex, setHighlightedIndex] =
|
|
81
|
+
useState<HighlightIndex>(null);
|
|
83
82
|
const listEl = useRef<HTMLUListElement | null>(null);
|
|
84
83
|
const highlightedEl = useRef<HTMLLIElement | null>(null);
|
|
85
84
|
const closeHandler = (returnValue: ReturnedSnippet) => {
|
|
@@ -87,7 +86,7 @@ export default ({ snippets, onHighlight, onClose }: Props) => {
|
|
|
87
86
|
onClose(returnValue);
|
|
88
87
|
}
|
|
89
88
|
};
|
|
90
|
-
const
|
|
89
|
+
const debouncedPreview = useDebouncedCallback(
|
|
91
90
|
(previewSnippet: ReturnedSnippet) => {
|
|
92
91
|
if (typeof onHighlight === 'function') {
|
|
93
92
|
onHighlight(previewSnippet);
|
|
@@ -95,7 +94,7 @@ export default ({ snippets, onHighlight, onClose }: Props) => {
|
|
|
95
94
|
},
|
|
96
95
|
50
|
|
97
96
|
);
|
|
98
|
-
const
|
|
97
|
+
const debounceScrollToHighlighted = useDebouncedCallback(
|
|
99
98
|
scrollToHighlightedSnippet,
|
|
100
99
|
50
|
|
101
100
|
);
|
|
@@ -117,270 +117,276 @@ interface CreateReducerParams {
|
|
|
117
117
|
themes: PlayroomProps['themes'];
|
|
118
118
|
widths: PlayroomProps['widths'];
|
|
119
119
|
}
|
|
120
|
-
const createReducer =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
const createReducer =
|
|
121
|
+
({
|
|
122
|
+
themes: configuredThemes,
|
|
123
|
+
widths: configuredWidths,
|
|
124
|
+
}: CreateReducerParams) =>
|
|
125
|
+
(state: State, action: Action): State => {
|
|
126
|
+
switch (action.type) {
|
|
127
|
+
case 'initialLoad': {
|
|
128
|
+
return {
|
|
129
|
+
...state,
|
|
130
|
+
...action.payload,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
case 'updateCode': {
|
|
135
|
+
const { code, cursor } = action.payload;
|
|
136
|
+
store.setItem('code', code);
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
return {
|
|
139
|
+
...state,
|
|
140
|
+
code,
|
|
141
|
+
cursorPosition: cursor || state.cursorPosition,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
142
144
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
case 'dismissMessage': {
|
|
146
|
+
return {
|
|
147
|
+
...state,
|
|
148
|
+
statusMessage: undefined,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
149
151
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
case 'copyToClipboard': {
|
|
153
|
+
const { url, trigger } = action.payload;
|
|
152
154
|
|
|
153
|
-
|
|
155
|
+
copy(url);
|
|
154
156
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
return {
|
|
158
|
+
...state,
|
|
159
|
+
statusMessage:
|
|
160
|
+
trigger === 'toolbarItem'
|
|
161
|
+
? {
|
|
162
|
+
message: 'Copied to clipboard',
|
|
163
|
+
tone: 'positive',
|
|
164
|
+
}
|
|
165
|
+
: undefined,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
166
168
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
case 'persistSnippet': {
|
|
170
|
+
const { snippet } = action.payload;
|
|
171
|
+
const { activeToolbarPanel, ...currentState } = state;
|
|
170
172
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
const { code, cursor } = formatAndInsert({
|
|
174
|
+
code: state.code,
|
|
175
|
+
snippet: snippet.code,
|
|
176
|
+
cursor: state.cursorPosition,
|
|
177
|
+
});
|
|
176
178
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
return {
|
|
180
|
+
...resetPreview(currentState),
|
|
181
|
+
code,
|
|
182
|
+
cursorPosition: cursor,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
183
185
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
case 'updateCursorPosition': {
|
|
187
|
+
const { position, code } = action.payload;
|
|
188
|
+
const newCode = code && code !== state.code ? code : state.code;
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
code: newCode,
|
|
191
|
-
cursorPosition: position,
|
|
192
|
-
statusMessage: undefined,
|
|
193
|
-
validCursorPosition: isValidLocation({
|
|
190
|
+
return {
|
|
191
|
+
...state,
|
|
194
192
|
code: newCode,
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const previewRenderCode = snippet
|
|
204
|
-
? formatAndInsert({
|
|
205
|
-
code: state.code,
|
|
206
|
-
snippet: snippet.code,
|
|
207
|
-
cursor: state.cursorPosition,
|
|
208
|
-
}).code
|
|
209
|
-
: undefined;
|
|
193
|
+
cursorPosition: position,
|
|
194
|
+
statusMessage: undefined,
|
|
195
|
+
validCursorPosition: isValidLocation({
|
|
196
|
+
code: newCode,
|
|
197
|
+
cursor: position,
|
|
198
|
+
}),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
210
201
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
previewRenderCode,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
202
|
+
case 'previewSnippet': {
|
|
203
|
+
const { snippet } = action.payload;
|
|
216
204
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
205
|
+
const previewRenderCode = snippet
|
|
206
|
+
? formatAndInsert({
|
|
207
|
+
code: state.code,
|
|
208
|
+
snippet: snippet.code,
|
|
209
|
+
cursor: state.cursorPosition,
|
|
210
|
+
}).code
|
|
211
|
+
: undefined;
|
|
221
212
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
message: 'Must have code to preview',
|
|
228
|
-
tone: 'critical',
|
|
229
|
-
},
|
|
230
|
-
};
|
|
231
|
-
}
|
|
213
|
+
return {
|
|
214
|
+
...state,
|
|
215
|
+
previewRenderCode,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
232
218
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
});
|
|
219
|
+
case 'toggleToolbar': {
|
|
220
|
+
const { panel } = action.payload;
|
|
221
|
+
const { activeToolbarPanel: currentPanel, ...currentState } = state;
|
|
222
|
+
const shouldOpen = panel !== currentPanel;
|
|
238
223
|
|
|
239
|
-
|
|
224
|
+
if (shouldOpen) {
|
|
225
|
+
if (panel === 'preview' && state.code.trim().length === 0) {
|
|
240
226
|
return {
|
|
241
|
-
...
|
|
227
|
+
...state,
|
|
242
228
|
statusMessage: {
|
|
243
|
-
message:
|
|
229
|
+
message: 'Must have code to preview',
|
|
244
230
|
tone: 'critical',
|
|
245
231
|
},
|
|
246
|
-
validCursorPosition,
|
|
247
232
|
};
|
|
248
233
|
}
|
|
249
234
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
235
|
+
if (panel === 'snippets') {
|
|
236
|
+
const validCursorPosition = isValidLocation({
|
|
237
|
+
code: currentState.code,
|
|
238
|
+
cursor: currentState.cursorPosition,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
if (!validCursorPosition) {
|
|
242
|
+
return {
|
|
243
|
+
...currentState,
|
|
244
|
+
statusMessage: {
|
|
245
|
+
message: "Can't insert snippet at cursor",
|
|
246
|
+
tone: 'critical',
|
|
247
|
+
},
|
|
248
|
+
validCursorPosition,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const { code, cursor } = formatForInsertion({
|
|
253
|
+
code: currentState.code,
|
|
254
|
+
cursor: currentState.cursorPosition,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
...currentState,
|
|
259
|
+
statusMessage: undefined,
|
|
260
|
+
activeToolbarPanel: panel,
|
|
261
|
+
previewEditorCode: code,
|
|
262
|
+
highlightLineNumber: cursor.line,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
254
265
|
|
|
255
266
|
return {
|
|
256
|
-
...currentState,
|
|
267
|
+
...resetPreview(currentState),
|
|
257
268
|
statusMessage: undefined,
|
|
258
269
|
activeToolbarPanel: panel,
|
|
259
|
-
previewEditorCode: code,
|
|
260
|
-
highlightLineNumber: cursor.line,
|
|
261
270
|
};
|
|
262
271
|
}
|
|
263
272
|
|
|
264
|
-
return
|
|
265
|
-
...resetPreview(currentState),
|
|
266
|
-
statusMessage: undefined,
|
|
267
|
-
activeToolbarPanel: panel,
|
|
268
|
-
};
|
|
273
|
+
return resetPreview(currentState);
|
|
269
274
|
}
|
|
270
275
|
|
|
271
|
-
|
|
272
|
-
|
|
276
|
+
case 'closeToolbar': {
|
|
277
|
+
const { activeToolbarPanel, ...currentState } = state;
|
|
273
278
|
|
|
274
|
-
|
|
275
|
-
|
|
279
|
+
return resetPreview(currentState);
|
|
280
|
+
}
|
|
276
281
|
|
|
277
|
-
|
|
278
|
-
|
|
282
|
+
case 'hideEditor': {
|
|
283
|
+
return {
|
|
284
|
+
...state,
|
|
285
|
+
activeToolbarPanel: undefined,
|
|
286
|
+
editorHidden: true,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
279
289
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
}
|
|
290
|
+
case 'showEditor': {
|
|
291
|
+
return {
|
|
292
|
+
...state,
|
|
293
|
+
editorHidden: false,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
287
296
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
editorHidden: false,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
297
|
+
case 'updateColorScheme': {
|
|
298
|
+
const { colorScheme } = action.payload;
|
|
299
|
+
store.setItem('colorScheme', colorScheme);
|
|
294
300
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
return {
|
|
302
|
+
...state,
|
|
303
|
+
colorScheme,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
298
306
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
};
|
|
303
|
-
}
|
|
307
|
+
case 'updateEditorPosition': {
|
|
308
|
+
const { position } = action.payload;
|
|
309
|
+
store.setItem('editorPosition', position);
|
|
304
310
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
311
|
+
return {
|
|
312
|
+
...state,
|
|
313
|
+
editorPosition: position,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
308
316
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
editorPosition: position,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
317
|
+
case 'resetEditorPosition': {
|
|
318
|
+
store.setItem('editorPosition', defaultPosition);
|
|
314
319
|
|
|
315
|
-
|
|
316
|
-
|
|
320
|
+
return {
|
|
321
|
+
...state,
|
|
322
|
+
editorPosition: defaultPosition,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
317
325
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
};
|
|
322
|
-
}
|
|
326
|
+
case 'updateEditorHeight': {
|
|
327
|
+
const { size } = action.payload;
|
|
328
|
+
store.setItem('editorHeight', size);
|
|
323
329
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
330
|
+
return {
|
|
331
|
+
...state,
|
|
332
|
+
editorHeight: size,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
327
335
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
};
|
|
332
|
-
}
|
|
336
|
+
case 'updateEditorWidth': {
|
|
337
|
+
const { size } = action.payload;
|
|
338
|
+
store.setItem('editorWidth', size);
|
|
333
339
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
340
|
+
return {
|
|
341
|
+
...state,
|
|
342
|
+
editorWidth: size,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
337
345
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
346
|
+
case 'updateVisibleThemes': {
|
|
347
|
+
const { themes } = action.payload;
|
|
348
|
+
const visibleThemes = configuredThemes.filter((t) =>
|
|
349
|
+
themes.includes(t)
|
|
350
|
+
);
|
|
351
|
+
store.setItem('visibleThemes', visibleThemes);
|
|
343
352
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
return {
|
|
354
|
+
...state,
|
|
355
|
+
visibleThemes,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
348
358
|
|
|
349
|
-
|
|
350
|
-
...state
|
|
351
|
-
visibleThemes
|
|
352
|
-
};
|
|
353
|
-
}
|
|
359
|
+
case 'resetVisibleThemes': {
|
|
360
|
+
const { visibleThemes, ...restState } = state;
|
|
361
|
+
store.removeItem('visibleThemes');
|
|
354
362
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
store.removeItem('visibleThemes');
|
|
363
|
+
return restState;
|
|
364
|
+
}
|
|
358
365
|
|
|
359
|
-
|
|
360
|
-
|
|
366
|
+
case 'updateVisibleWidths': {
|
|
367
|
+
const { widths } = action.payload;
|
|
368
|
+
const visibleWidths = configuredWidths.filter((w) =>
|
|
369
|
+
widths.includes(w)
|
|
370
|
+
);
|
|
371
|
+
store.setItem('visibleWidths', visibleWidths);
|
|
361
372
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
373
|
+
return {
|
|
374
|
+
...state,
|
|
375
|
+
visibleWidths,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
366
378
|
|
|
367
|
-
|
|
368
|
-
...state
|
|
369
|
-
visibleWidths
|
|
370
|
-
};
|
|
371
|
-
}
|
|
379
|
+
case 'resetVisibleWidths': {
|
|
380
|
+
const { visibleWidths, ...restState } = state;
|
|
381
|
+
store.removeItem('visibleWidths');
|
|
372
382
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
store.removeItem('visibleWidths');
|
|
383
|
+
return restState;
|
|
384
|
+
}
|
|
376
385
|
|
|
377
|
-
|
|
386
|
+
default:
|
|
387
|
+
return state;
|
|
378
388
|
}
|
|
379
|
-
|
|
380
|
-
default:
|
|
381
|
-
return state;
|
|
382
|
-
}
|
|
383
|
-
};
|
|
389
|
+
};
|
|
384
390
|
|
|
385
391
|
type StoreContextValues = [State, Dispatch<Action>];
|
|
386
392
|
|
|
@@ -414,7 +420,7 @@ export const StoreProvider = ({
|
|
|
414
420
|
createReducer({ themes, widths }),
|
|
415
421
|
initialState
|
|
416
422
|
);
|
|
417
|
-
const
|
|
423
|
+
const debouncedCodeUpdate = useDebouncedCallback(
|
|
418
424
|
(params: DebounceUpdateUrl) => {
|
|
419
425
|
// Ensure that when removing theme/width preferences
|
|
420
426
|
// they are also removed from the url. Replacing state
|
|
@@ -448,22 +454,14 @@ export const StoreProvider = ({
|
|
|
448
454
|
widthsFromQuery = parsedWidths;
|
|
449
455
|
}
|
|
450
456
|
|
|
451
|
-
Promise.all
|
|
452
|
-
string
|
|
453
|
-
EditorPosition
|
|
454
|
-
number
|
|
455
|
-
number
|
|
456
|
-
number[]
|
|
457
|
-
string[]
|
|
458
|
-
ColorScheme
|
|
459
|
-
>([
|
|
460
|
-
store.getItem('code'),
|
|
461
|
-
store.getItem('editorPosition'),
|
|
462
|
-
store.getItem('editorHeight'),
|
|
463
|
-
store.getItem('editorWidth'),
|
|
464
|
-
store.getItem('visibleWidths'),
|
|
465
|
-
store.getItem('visibleThemes'),
|
|
466
|
-
store.getItem('colorScheme'),
|
|
457
|
+
Promise.all([
|
|
458
|
+
store.getItem<string>('code'),
|
|
459
|
+
store.getItem<EditorPosition>('editorPosition'),
|
|
460
|
+
store.getItem<number>('editorHeight'),
|
|
461
|
+
store.getItem<number>('editorWidth'),
|
|
462
|
+
store.getItem<number[]>('visibleWidths'),
|
|
463
|
+
store.getItem<string[]>('visibleThemes'),
|
|
464
|
+
store.getItem<ColorScheme>('colorScheme'),
|
|
467
465
|
]).then(
|
|
468
466
|
([
|
|
469
467
|
storedCode,
|
package/src/utils/compileJsx.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { transform } from '@babel/standalone';
|
|
2
2
|
|
|
3
|
+
export const openFragmentTag = '<React.Fragment>';
|
|
4
|
+
export const closeFragmentTag = '</React.Fragment>';
|
|
5
|
+
|
|
3
6
|
export const compileJsx = (code: string) =>
|
|
4
|
-
transform(
|
|
7
|
+
transform(`${openFragmentTag}${code.trim() || ''}${closeFragmentTag}`, {
|
|
5
8
|
presets: ['react'],
|
|
6
9
|
}).code;
|
|
7
10
|
|
package/tsconfig.json
CHANGED
package/cypress.json
DELETED