Skip to content

Commit 44a625a

Browse files
authored
Modernise playground (#430)
* delete some stuff * unused * unused * create workspace * WIP * WIP * various * add modified logic * more stuff * more * more * more * more * fixes * readonly * get JS/CSS output working * add/rename/delete files * tidy * markdown * AST view * tweak * tidy/fix * various * fix * lint * remove dependency * remove old comments * move theme * lockfile
1 parent d3407b6 commit 44a625a

File tree

38 files changed

+793
-1533
lines changed

38 files changed

+793
-1533
lines changed

apps/svelte.dev/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"dependencies": {
1919
"@jridgewell/sourcemap-codec": "^1.4.15",
2020
"@lezer/common": "^1.0.4",
21-
"@lezer/highlight": "^1.1.6",
2221
"@lezer/javascript": "^1.4.7",
2322
"@lezer/lr": "^1.3.10",
2423
"@rich_harris/svelte-split-pane": "^1.1.3",

apps/svelte.dev/src/lib/tutorial/adapters/rollup/index.svelte.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ export async function create(): Promise<Adapter> {
4444
[...current_stubs.values()]
4545
// TODO we can probably remove all the SvelteKit specific stuff from the tutorial content once this settles down
4646
.filter((f): f is File => f.name.startsWith('/src/lib/') && f.type === 'file')
47-
.map((f) => ({
48-
name: f.name.slice(9).split('.').slice(0, -1).join('.'),
49-
source: f.contents,
50-
type: f.name.split('.').pop() ?? 'svelte'
51-
}))
47+
.map((f) => ({ ...f, name: f.name.slice(9) }))
5248
);
5349
}
5450

apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { browser } from '$app/environment';
33
import { afterNavigate, goto, replaceState } from '$app/navigation';
44
import type { Gist } from '$lib/db/types';
5-
import { Repl, type File } from '@sveltejs/repl';
5+
import { Repl } from '@sveltejs/repl';
66
import { theme } from '@sveltejs/site-kit/stores';
77
import { onMount } from 'svelte';
88
import { mapbox_setup } from '../../../../config.js';
@@ -50,9 +50,21 @@
5050
5151
if (!hash) {
5252
repl?.set({
53-
files: structuredClone(data.gist.components)
53+
// TODO make this munging unnecessary
54+
files: structuredClone(data.gist.components).map((file: any) => {
55+
const basename = `${file.name}.${file.type}`;
56+
57+
return {
58+
type: 'file',
59+
name: basename,
60+
basename,
61+
contents: file.source,
62+
text: true
63+
};
64+
})
5465
});
5566
67+
modified = false;
5668
return;
5769
}
5870
@@ -89,9 +101,9 @@
89101
}, 500);
90102
}
91103
92-
function handle_change({ files }: { files: File[] }) {
104+
function handle_change() {
93105
const was_modified = modified;
94-
modified = files.some((c) => c.modified);
106+
modified = true;
95107
96108
if (
97109
!was_modified &&
@@ -142,27 +154,28 @@
142154
/>
143155

144156
{#if browser}
145-
<Repl
146-
bind:this={repl}
147-
{svelteUrl}
148-
{relaxed}
149-
{can_escape}
150-
vim={data.vim}
151-
injectedJS={mapbox_setup}
152-
showModified
153-
showAst
154-
change={handle_change}
155-
add={handle_change}
156-
remove={handle_change}
157-
blur={() => {
157+
<div
158+
style="display: contents"
159+
onfocusout={() => {
158160
// Only change hash on editor blur to not pollute everyone's browser history
159161
if (modified) {
160162
const json = JSON.stringify({ files: repl.toJSON().files });
161163
change_hash(json);
162164
}
163165
}}
164-
previewTheme={$theme.current}
165-
/>
166+
>
167+
<Repl
168+
bind:this={repl}
169+
{svelteUrl}
170+
{relaxed}
171+
{can_escape}
172+
injectedJS={mapbox_setup}
173+
change={handle_change}
174+
add={handle_change}
175+
remove={handle_change}
176+
previewTheme={$theme.current}
177+
/>
178+
</div>
166179
{/if}
167180
</div>
168181

@@ -192,14 +205,6 @@
192205
visibility: visible;
193206
}
194207
195-
.zen-mode {
196-
position: fixed;
197-
width: 100%;
198-
height: 100%;
199-
top: 0;
200-
z-index: 111;
201-
}
202-
203208
@keyframes fade-in {
204209
0% {
205210
opacity: 0;

apps/svelte.dev/src/routes/(authed)/playground/[id]/AppControls.svelte

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@
44
import { Icon } from '@sveltejs/site-kit/components';
55
import { enter } from '$lib/utils/events';
66
import { isMac } from '$lib/utils/compat.js';
7-
import { Repl } from '@sveltejs/repl';
87
import { get_app_context } from '../../app-context';
98
import type { Gist, User } from '$lib/db/types';
10-
import type { File } from '@sveltejs/repl';
119
import { browser } from '$app/environment';
1210
import SelectIcon from '$lib/components/SelectIcon.svelte';
1311
import { untrack } from 'svelte';
1412
import SecondaryNav from '$lib/components/SecondaryNav.svelte';
13+
import type { File } from 'editor';
1514
1615
interface Props {
1716
examples: Array<{ title: string; examples: any[] }>;
1817
user: User | null;
19-
repl: Repl;
18+
repl: any; // TODO
2019
gist: Gist;
2120
name: string;
2221
modified: boolean;
@@ -70,8 +69,8 @@
7069
body: JSON.stringify({
7170
name,
7271
files: files.map((file) => ({
73-
name: `${file.name}.${file.type}`,
74-
source: file.source
72+
name: file.name,
73+
source: file.contents
7574
}))
7675
})
7776
});
@@ -135,8 +134,8 @@
135134
body: JSON.stringify({
136135
name,
137136
files: files.map((file) => ({
138-
name: `${file.name}.${file.type}`,
139-
source: file.source
137+
name: file.name,
138+
source: file.contents
140139
}))
141140
})
142141
});

apps/svelte.dev/src/routes/(authed)/playground/[id]/embed/+page.svelte

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,8 @@
5252
{relaxed}
5353
can_escape
5454
injectedJS={mapbox_setup}
55-
showModified
56-
showAst
5755
previewTheme={$theme.current}
5856
embedded
59-
vim={false}
6057
/>
6158
{/if}
6259
</div>

packages/editor/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
"@codemirror/lang-css": "^6.2.1",
3939
"@codemirror/lang-html": "^6.4.6",
4040
"@codemirror/lang-javascript": "^6.2.1",
41-
"@codemirror/language": "^6.9.0",
42-
"@codemirror/lint": "^6.4.1",
43-
"@codemirror/search": "^6.5.2",
44-
"@codemirror/state": "^6.2.1",
45-
"@codemirror/view": "^6.17.1",
41+
"@codemirror/language": "^6.10.3",
42+
"@codemirror/lint": "^6.8.2",
43+
"@codemirror/search": "^6.5.6",
44+
"@codemirror/state": "^6.4.1",
45+
"@codemirror/view": "^6.34.1",
4646
"@replit/codemirror-lang-svelte": "^6.0.0",
4747
"@replit/codemirror-vim": "^6.0.14",
4848
"@sveltejs/adapter-auto": "^3.0.0",
@@ -62,6 +62,7 @@
6262
},
6363
"type": "module",
6464
"dependencies": {
65+
"@lezer/highlight": "^1.2.1",
6566
"esm-env": "^1.0.0"
6667
}
6768
}

packages/editor/src/lib/Editor.svelte

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { EditorState } from '@codemirror/state';
1010
import { EditorView, keymap } from '@codemirror/view';
1111
import { svelte } from '@replit/codemirror-lang-svelte';
12-
import { svelteTheme } from '@sveltejs/repl/theme';
12+
import { theme } from './theme';
1313
import { basicSetup } from 'codemirror';
1414
import { autocomplete_for_svelte } from '@sveltejs/site-kit/codemirror';
1515
import type { Diagnostic } from '@codemirror/lint';
@@ -18,11 +18,12 @@
1818
1919
interface Props {
2020
workspace: Workspace;
21-
onchange: (file: File, contents: string) => void;
21+
readonly?: boolean;
22+
onchange?: (file: File, contents: string) => void;
2223
autocomplete_filter?: (file: File) => boolean;
2324
}
2425
25-
let { workspace, onchange, autocomplete_filter = () => true }: Props = $props();
26+
let { workspace, readonly = false, onchange, autocomplete_filter = () => true }: Props = $props();
2627
2728
let container: HTMLDivElement;
2829
@@ -39,7 +40,7 @@
3940
EditorState.tabSize.of(2),
4041
keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]),
4142
indentUnit.of('\t'),
42-
svelteTheme
43+
theme
4344
];
4445
4546
let installed_vim = false;
@@ -108,7 +109,12 @@
108109
109110
state = EditorState.create({
110111
doc: file.contents,
111-
extensions: lang ? [...extensions, ...lang] : extensions
112+
extensions: [
113+
...extensions,
114+
...(lang || []),
115+
EditorState.readOnly.of(readonly),
116+
EditorView.editable.of(!readonly)
117+
]
112118
});
113119
114120
editor_states.set(file.name, state);
@@ -146,7 +152,7 @@
146152
editor_view.update([transaction]);
147153
148154
if (transaction.docChanged && workspace.selected_file) {
149-
onchange(workspace.selected_file, editor_view.state.doc.toString());
155+
onchange?.(workspace.selected_file, editor_view.state.doc.toString());
150156
151157
// keep `editor_states` updated so that undo/redo history is preserved for files independently
152158
editor_states.set(workspace.selected_file.name, editor_view.state);
@@ -164,12 +170,18 @@
164170
});
165171
166172
$effect(() => {
167-
if (!editor_view || !workspace.selected_name) return;
173+
// TODO we end up back here when we edit inside this component,
174+
// which is... fine but would be nice to avoid
175+
update_files(workspace.files);
176+
});
177+
178+
$effect(() => {
179+
if (!workspace.selected_name) return;
168180
169181
const diagnostics: Diagnostic[] = [];
170182
171-
const error = workspace.diagnostics[workspace.selected_name]?.error;
172-
const current_warnings = workspace.diagnostics[workspace.selected_name]?.warnings ?? [];
183+
const error = workspace.compiled[workspace.selected_name]?.error;
184+
const current_warnings = workspace.compiled[workspace.selected_name]?.result?.warnings ?? [];
173185
174186
if (error) {
175187
diagnostics.push({

0 commit comments

Comments
 (0)