Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
"@babel/preset-typescript": "^7.28.5",
"@babel/types": "^7.29.0",
"@solidjs/router": "^0.16.1",
"@solidjs/web": "2.0.0-beta.10",
"@types/babel__standalone": "^7.1.9",
"@types/dedent": "^0.7.2",
"assert": "^2.1.0",
"csstype": "^3.2.3",
"jszip": "^3.10.1",
"monaco-editor": "^0.55.1",
"register-service-worker": "^1.7.2",
"solid-js-v2": "npm:solid-js@2.0.0-beta.10",
"typescript": "^6.0.3",
"unocss": "^66.6.8",
"vite": "^8.0.10",
Expand Down
4 changes: 3 additions & 1 deletion packages/playground/src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { exportToZip } from '../utils/exportFiles';
import { ZoomDropdown } from './zoomDropdown';
import { API, useAppContext } from '../context';
import { Button, LinkButton } from 'solid-repl/src/components/ui/Button';
import type { SolidVersion } from 'solid-repl';

import logo from '../assets/logo.svg?url';

export const Header: ParentComponent<{
compiler?: Worker;
fork?: () => void;
share: () => Promise<string>;
solidVersion?: SolidVersion;
}> = (props) => {
const [copy, setCopy] = createSignal(false);
const context = useAppContext()!;
Expand Down Expand Up @@ -79,7 +81,7 @@ export const Header: ParentComponent<{

<Show when={context.tabs()}>
<Button
onClick={() => exportToZip(unwrap(context.tabs())!)}
onClick={() => exportToZip(unwrap(context.tabs())!, props.solidVersion)}
classList={menuButtonClasses(showMenu())}
title="Export to Zip"
>
Expand Down
71 changes: 64 additions & 7 deletions packages/playground/src/components/setupSolid.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,72 @@
import { typescript } from 'monaco-editor';
import { createEffect } from 'solid-js';
import type { SolidVersion } from 'solid-repl';
import type { Repl as ReplProps } from 'solid-repl/dist/repl';
import repl from 'solid-repl/src/repl';

const solidTypes: Record<string, string> = import.meta.glob('/node_modules/{solid-js,csstype}/**/*.{d.ts,json}', {
const commonTypes: Record<string, string> = import.meta.glob('/node_modules/csstype/**/*.{d.ts,json}', {
eager: true,
query: '?raw',
import: 'default',
});
const solidV1Types: Record<string, string> = import.meta.glob('/node_modules/solid-js/**/*.{d.ts,json}', {
eager: true,
query: '?raw',
import: 'default',
});
const solidV2Types: Record<string, string> = import.meta.glob(
'/node_modules/{solid-js-v2,@solidjs\\/signals,@solidjs\\/web}/**/*.{d.ts,json}',
{
eager: true,
query: '?raw',
import: 'default',
},
);

for (const path in solidTypes) {
typescript.typescriptDefaults.addExtraLib(solidTypes[path], `file://${path}`);
typescript.javascriptDefaults.addExtraLib(solidTypes[path], `file://${path}`);
}
let currentVersion: SolidVersion | undefined;
let disposables: { dispose: () => void }[] = [];

import repl from 'solid-repl/src/repl';
export default repl;
const addLib = (path: string, source: string) => {
disposables.push(typescript.typescriptDefaults.addExtraLib(source, `file://${path}`));
disposables.push(typescript.javascriptDefaults.addExtraLib(source, `file://${path}`));
};

const setCompilerOptions = (version: SolidVersion) => {
const compilerOptions: typescript.CompilerOptions = {
strict: true,
target: typescript.ScriptTarget.ESNext,
module: typescript.ModuleKind.ESNext,
moduleResolution: typescript.ModuleResolutionKind.NodeJs,
jsx: typescript.JsxEmit.Preserve,
jsxImportSource: version === 'v2' ? '@solidjs/web' : 'solid-js',
allowNonTsExtensions: true,
};

typescript.typescriptDefaults.setCompilerOptions(compilerOptions);
typescript.javascriptDefaults.setCompilerOptions(compilerOptions);
};

const setSolidTypes = (version: SolidVersion) => {
if (version === currentVersion) return;

currentVersion = version;
setCompilerOptions(version);
for (const disposable of disposables) disposable.dispose();
disposables = [];

for (const path in commonTypes) {
addLib(path, commonTypes[path]);
}

const solidTypes = version === 'v2' ? solidV2Types : solidV1Types;
for (const path in solidTypes) {
addLib(path.replace('/solid-js-v2/', '/solid-js/'), solidTypes[path]);
}
};

const Repl: ReplProps = (props) => {
createEffect(() => setSolidTypes(props.solidVersion));
return repl(props);
};

export default Repl;
60 changes: 57 additions & 3 deletions packages/playground/src/pages/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { API, useAppContext } from '../context';
import { debounce } from '@solid-primitives/scheduled';
import { decompressFromURL } from '@amoutonbrady/lz-string';
import { defaultTabs } from 'solid-repl/src';
import type { Tab } from 'solid-repl';
import type { SolidVersion, Tab } from 'solid-repl';
import type { APIRepl } from './home';
import { Header } from '../components/header';
import { Button } from 'solid-repl/src/components/ui/Button';
Expand All @@ -24,6 +24,18 @@ function parseHash<T>(hash: string, fallback: T): T {
}
}

const normalizeSolidVersion = (version: unknown): SolidVersion => (version === 'v2' ? 'v2' : 'v1');

const solidWebImport = {
v1: 'solid-js/web',
v2: '@solidjs/web',
} as const;

const updateSolidWebImport = (source: string, version: SolidVersion) =>
source.replace(/from\s+(['"])(solid-js\/web|@solidjs\/web)\1/g, (_match, quote) => {
return `from ${quote}${solidWebImport[version]}${quote}`;
});

const Repl = lazy(() => import('../components/setupSolid'));

window.MonacoEnvironment = {
Expand Down Expand Up @@ -71,6 +83,7 @@ export const Edit = () => {
localStorage.setItem(
'scratchpad',
JSON.stringify({
solidVersion: 'v1',
files: initialTabs.map((x) => ({ name: x.name, content: x.source })),
}),
);
Expand Down Expand Up @@ -106,6 +119,8 @@ export const Edit = () => {
context.setTabs(tabs);
onCleanup(() => context.setTabs(undefined));

const [solidVersion, trueSetSolidVersion] = createSignal<SolidVersion>('v1');

const [current, setCurrent] = createSignal<string | undefined>(undefined, { equals: false });
const [resource, { mutate }] = createResource<APIRepl, { repl: string | undefined; scratchpad: boolean }>(
() => ({ repl: params.repl, scratchpad: !!scratchpad() }),
Expand All @@ -120,6 +135,7 @@ export const Edit = () => {
const myScratchpad = localStorage.getItem('scratchpad');
if (!myScratchpad) {
output = {
solidVersion: 'v1',
files: defaultTabs.map((x) => ({
name: x.name,
content: x.source,
Expand All @@ -136,6 +152,7 @@ export const Edit = () => {
}

batch(() => {
trueSetSolidVersion(normalizeSolidVersion(output.solidVersion));
setTabs(
output.files.map((x) => {
return { name: x.name, source: x.content };
Expand All @@ -150,7 +167,14 @@ export const Edit = () => {

const reset = () => {
batch(() => {
setTabs(mapTabs(defaultTabs));
setTabs(
mapTabs(
defaultTabs.map((tab) => ({
...tab,
source: updateSolidWebImport(tab.source, solidVersion()),
})),
),
);
setCurrent(defaultTabs[0].name);
});
};
Expand All @@ -161,6 +185,7 @@ export const Edit = () => {
public: true,
labels: [] as string[],
version: '1.0',
solidVersion: solidVersion(),
files: tabs().map((x) => ({ name: x.name, content: x.source })),
};
const response = await fetch(`${API}/repl`, {
Expand Down Expand Up @@ -190,6 +215,7 @@ export const Edit = () => {
labels: newRepl.labels,
files: newRepl.files,
version: newRepl.version,
solidVersion: newRepl.solidVersion,
public: newRepl.public,
size: 0,
created_at: '',
Expand All @@ -216,7 +242,7 @@ export const Edit = () => {
const files = tabs().map((x) => ({ name: x.name, content: x.source }));

if (scratchpad()) {
localStorage.setItem('scratchpad', JSON.stringify({ files }));
localStorage.setItem('scratchpad', JSON.stringify({ solidVersion: solidVersion(), files }));
}

const repl = resource.latest;
Expand All @@ -235,6 +261,7 @@ export const Edit = () => {
...(localStorage.getItem(params.repl) ? { write_token: localStorage.getItem(params.repl) } : {}),
title: repl.title,
version: repl.version,
solidVersion: solidVersion(),
public: repl.public,
labels: repl.labels,
files,
Expand All @@ -245,11 +272,25 @@ export const Edit = () => {
!!scratchpad() ? 10 : 1000,
);

const setSolidVersion = (version: SolidVersion) => {
batch(() => {
trueSetSolidVersion(version);
setTabs(
tabs().map((tab) => ({
name: tab.name,
source: tab.name === 'import_map.json' ? tab.source : updateSolidWebImport(tab.source, version),
})),
);
});
updateRepl();
};

return (
<>
<Header
compiler={compiler}
fork={() => {}}
solidVersion={solidVersion()}
share={async () => {
if (scratchpad()) {
const url = await publishScratchpad(`${context.user()?.display || 'Anonymous'}'s Scratchpad`);
Expand All @@ -263,6 +304,17 @@ export const Edit = () => {
}
}}
>
<label class="ml-2 flex items-center gap-2 text-sm text-neutral-600 dark:text-neutral-300">
<span>Solid</span>
<select
class="border-neutral-200 bg-transparent px-2 py-1 dark:border-neutral-700 rounded-md border text-sm transition focus:border-solidc focus:outline-none"
value={solidVersion()}
onChange={(e) => setSolidVersion(e.currentTarget.value as SolidVersion)}
>
<option value="v1">v1</option>
<option value="v2">v2</option>
</select>
</label>
<Show when={resource() && (resource()?.title || (scratchpad() && context.token))}>
<input
class="w-96 border-transparent bg-transparent px-3 py-1.5 shrink rounded-md border transition focus:border-solidc focus:outline-none"
Expand Down Expand Up @@ -310,6 +362,8 @@ export const Edit = () => {
tabs={tabs()}
setTabs={setTabs}
reset={reset}
solidVersion={solidVersion()}
setSolidVersion={setSolidVersion}
current={current()}
setCurrent={setCurrent}
onUserEdit={onUserEdit}
Expand Down
2 changes: 2 additions & 0 deletions packages/playground/src/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { API, useAppContext } from '../context';
import { Header } from '../components/header';
import { timeAgo } from '../utils/date';
import { Button } from 'solid-repl/src/components/ui/Button';
import type { SolidVersion } from 'solid-repl';

interface ReplFile {
name: string;
Expand All @@ -18,6 +19,7 @@ export interface APIRepl {
labels: string[];
files: ReplFile[];
version: string;
solidVersion?: SolidVersion;
public: boolean;
size: number;
created_at: string;
Expand Down
3 changes: 3 additions & 0 deletions packages/playground/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module '@amoutonbrady/lz-string' {
export function decompressFromURL(value: string): string | null;
}
Loading