Skip to content

Commit 3cad3ad

Browse files
committed
css transition, cleanup
1 parent 3db7693 commit 3cad3ad

File tree

12 files changed

+134
-177
lines changed

12 files changed

+134
-177
lines changed

playground/components/update.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import { Portal } from 'solid-js/web';
44
import { Icon } from 'solid-heroicons';
55
import { x } from 'solid-heroicons/outline';
66

7-
interface Props {
7+
export const Update: Component<{
88
onDismiss: (...args: unknown[]) => unknown;
9-
}
10-
11-
export const Update: Component<Props> = (props) => {
9+
}> = (props) => {
1210
const mount = document.getElementById('update');
1311

1412
return (

playground/pages/edit.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export const Edit = (props: { horizontal: boolean }) => {
179179
>
180180
{resource()?.title && (
181181
<input
182-
class="bg-transparent"
182+
class="bg-transparent px-3 py-1.5 border border-solid border-transparent rounded transition focus:border-blue-600 focus:outline-none"
183183
value={resource()?.title}
184184
onChange={(e) => {
185185
mutate((x) => x && { ...x, title: e.currentTarget.value });

src/components/editor/index.tsx

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ import { Uri, languages, editor as mEditor } from 'monaco-editor';
33
import { liftOff } from './setupSolid';
44
import { useZoom } from '../../hooks/useZoom';
55

6-
interface Props {
6+
const Editor: Component<{
77
url: string;
88
disabled?: true;
99
isDark?: boolean;
1010
withMinimap?: boolean;
1111
formatter?: Worker;
1212
displayErrors?: boolean;
1313
onDocChange?: (code: string) => unknown;
14-
}
15-
16-
const Editor: Component<Props> = (props) => {
14+
}> = (props) => {
1715
let parent!: HTMLDivElement;
1816
let editor: mEditor.IStandaloneCodeEditor;
1917

@@ -30,22 +28,16 @@ const Editor: Component<Props> = (props) => {
3028
pos: editor.getPosition(),
3129
});
3230

33-
return new Promise((resolve, reject) => {
31+
return new Promise((resolve) => {
3432
props.formatter!.addEventListener(
3533
'message',
36-
({ data: { event, code } }) => {
37-
switch (event) {
38-
case 'RESULT':
39-
resolve([
40-
{
41-
range: model.getFullModelRange(),
42-
text: code,
43-
},
44-
]);
45-
break;
46-
default:
47-
reject();
48-
}
34+
({ data: { code } }) => {
35+
resolve([
36+
{
37+
range: model.getFullModelRange(),
38+
text: code,
39+
},
40+
]);
4941
},
5042
{ once: true },
5143
);

src/components/error.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ import { Component, createEffect, createSignal } from 'solid-js';
33
import { Icon } from 'solid-heroicons';
44
import { chevronDown, chevronRight } from 'solid-heroicons/solid';
55

6-
interface Props {
7-
onDismiss: (...args: unknown[]) => unknown;
8-
message: string;
9-
}
10-
116
function doSomethingWithError(message: string) {
127
const [firstLine, setFirstLine] = createSignal('');
138
const [stackTrace, setStackTrace] = createSignal('');
@@ -21,7 +16,10 @@ function doSomethingWithError(message: string) {
2116
return [firstLine, stackTrace] as const;
2217
}
2318

24-
export const Error: Component<Props> = (props) => {
19+
export const Error: Component<{
20+
onDismiss: (...args: unknown[]) => unknown;
21+
message: string;
22+
}> = (props) => {
2523
const [firstLine, stackTrace] = doSomethingWithError(props.message);
2624
const [isOpen, setIsOpen] = createSignal(false);
2725

src/components/gridResizer/index.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import { Component, createSignal, createEffect, onCleanup } from 'solid-js';
22
import { throttle } from '@solid-primitives/scheduled';
33
import { Dot } from './dot';
44

5-
interface GridResizerProps {
6-
ref: (el: HTMLDivElement) => void;
5+
type SolidRef = (el: HTMLDivElement) => void;
6+
export const GridResizer: Component<{
7+
ref: HTMLDivElement | SolidRef;
78
isHorizontal: boolean;
89
onResize: (clientX: number, clientY: number) => void;
9-
}
10-
11-
export const GridResizer: Component<GridResizerProps> = (props) => {
10+
}> = (props) => {
1211
const [isDragging, setIsDragging] = createSignal(false);
1312

1413
const onResizeStart = () => setIsDragging(true);
@@ -24,7 +23,7 @@ export const GridResizer: Component<GridResizerProps> = (props) => {
2423
}, 10);
2524

2625
const setRef = (el: HTMLDivElement) => {
27-
props.ref(el);
26+
(props.ref as SolidRef)(el);
2827

2928
el.addEventListener('mousedown', onResizeStart);
3029
el.addEventListener('touchstart', onResizeStart);

src/components/preview.tsx

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { Component, createEffect, createSignal, splitProps, JSX, onMount, onCleanup } from 'solid-js';
1+
import { Component, createEffect, createSignal, onMount, onCleanup } from 'solid-js';
22
import { useZoom } from '../hooks/useZoom';
33

44
export const Preview: Component<Props> = (props) => {
55
const { zoomState } = useZoom();
6-
const [internal, external] = splitProps(props, ['code', 'isDark', 'class', 'reloadSignal', 'devtools']);
76

87
let iframe!: HTMLIFrameElement;
98

@@ -13,11 +12,10 @@ export const Preview: Component<Props> = (props) => {
1312
const CODE_UPDATE = 'CODE_UPDATE';
1413

1514
createEffect(() => {
16-
const isEmpty = !internal.code;
15+
if (!props.code) return;
16+
if (!isIframeReady()) return;
1717

18-
if (isEmpty || !isIframeReady()) return;
19-
20-
latestCode = internal.code.replace('render(', 'window.dispose = render(');
18+
latestCode = props.code.replace('render(', 'window.dispose = render(');
2119

2220
const blob = new Blob([latestCode], {
2321
type: 'text/javascript',
@@ -29,20 +27,17 @@ export const Preview: Component<Props> = (props) => {
2927
});
3028

3129
createEffect(() => {
32-
if (!iframe) return;
33-
iframe.contentWindow!.postMessage({ event: 'DEVTOOLS', value: internal.devtools }, '*');
30+
iframe.contentWindow!.postMessage({ event: 'DEVTOOLS', value: props.devtools }, '*');
3431
});
3532

3633
const setDarkMode = () => {
37-
const doc = iframe.contentDocument || iframe.contentWindow?.document;
38-
doc?.body!.classList.toggle('dark', internal.isDark);
39-
iframe.contentWindow!.postMessage({ event: 'THEME', value: internal.isDark }, '*');
34+
const doc = iframe.contentDocument!.body;
35+
doc.classList.toggle('dark', props.isDark);
36+
iframe.contentWindow!.postMessage({ event: 'THEME', value: props.isDark }, '*');
4037
};
4138

4239
createEffect(() => {
43-
if (iframe && isIframeReady()) {
44-
setDarkMode();
45-
}
40+
if (isIframeReady()) setDarkMode();
4641
});
4742

4843
const html = `
@@ -112,7 +107,7 @@ export const Preview: Component<Props> = (props) => {
112107
tool: ["console", "network", "resources", "elements"],
113108
defaults: {
114109
displaySize: 40,
115-
theme: "${internal.isDark ? 'Dark' : 'Light'}"
110+
theme: "${props.isDark ? 'Dark' : 'Light'}"
116111
}
117112
});
118113
eruda.add(erudaDom);
@@ -122,7 +117,7 @@ export const Preview: Component<Props> = (props) => {
122117
href: '${location.origin}/eruda.css'
123118
});
124119
eruda._shadowRoot.appendChild(style);
125-
if (${internal.devtools}) eruda.show();
120+
${props.devtools ? 'eruda.show();' : ''}
126121
</script>
127122
<script type="module" id="setup">
128123
window.addEventListener('message', async ({ data }) => {
@@ -175,7 +170,7 @@ export const Preview: Component<Props> = (props) => {
175170

176171
createEffect(() => {
177172
// Bail early on first mount or we are already reloading
178-
if (!internal.reloadSignal) return;
173+
if (!props.reloadSignal) return;
179174

180175
// Otherwise, reload everytime we clicked the reload button
181176
setIframeReady(false);
@@ -191,28 +186,29 @@ export const Preview: Component<Props> = (props) => {
191186
};
192187

193188
onMount(() => {
194-
iframe.addEventListener('load', () => {
195-
setIframeReady(true);
196-
197-
setDarkMode();
198-
});
189+
iframe.addEventListener('load', () => setIframeReady(true));
199190
});
200191

201192
return (
202-
<iframe
203-
title="Solid REPL"
204-
class={`overflow-auto p-0 dark:bg-other block ${internal.class}`}
205-
style={styleScale()}
206-
ref={iframe}
207-
src={src}
208-
{...external}
209-
// @ts-ignore
210-
sandbox="allow-popups-to-escape-sandbox allow-scripts allow-popups allow-forms allow-pointer-lock allow-top-navigation allow-modals allow-same-origin"
211-
></iframe>
193+
<div class="h-full w-full relative">
194+
<iframe
195+
title="Solid REPL"
196+
class="overflow-auto p-0 dark:bg-other block h-full w-full bg-white row-start-5"
197+
classList={props.classList}
198+
style={styleScale()}
199+
ref={iframe}
200+
src={src}
201+
// @ts-ignore
202+
sandbox="allow-popups-to-escape-sandbox allow-scripts allow-popups allow-forms allow-pointer-lock allow-top-navigation allow-modals allow-same-origin"
203+
></iframe>
204+
</div>
212205
);
213206
};
214207

215-
type Props = JSX.HTMLAttributes<HTMLIFrameElement> & {
208+
type Props = {
209+
classList?: {
210+
[k: string]: boolean | undefined;
211+
};
216212
code: string;
217213
reloadSignal: boolean;
218214
devtools: boolean;

src/components/repl.tsx

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,14 @@ const Repl: ReplProps = (props) => {
8282
const [outputTab, setOutputTab] = createSignal(0);
8383

8484
compiler.addEventListener('message', ({ data }) => {
85-
const { event } = data;
85+
const { compiled, error } = data;
8686

87-
if (event === 'RESULT') {
88-
const { compiled, error } = data;
87+
if (error) return setError(error);
88+
else setError('');
8989

90-
if (error) return setError(error);
91-
else setError('');
90+
setCompiled(compiled);
9291

93-
setCompiled(compiled);
94-
95-
console.log(`Compilation took: ${performance.now() - now}ms`);
96-
}
92+
console.log(`Compilation took: ${performance.now() - now}ms`);
9793
});
9894

9995
/**
@@ -135,8 +131,8 @@ const Repl: ReplProps = (props) => {
135131
return Math.min(Math.max(percentage, lowerBound), upperBound);
136132
};
137133

138-
let grid: HTMLDivElement;
139-
let resizer: HTMLElement;
134+
let grid!: HTMLDivElement;
135+
let resizer!: HTMLDivElement;
140136
const [left, setLeft] = createSignal(1.25);
141137

142138
const isLarge = createMediaQuery('(min-width: 768px)');
@@ -164,12 +160,7 @@ const Repl: ReplProps = (props) => {
164160

165161
return (
166162
<div
167-
ref={(el) => {
168-
grid = el;
169-
if (props.ref) {
170-
(props.ref as (el: HTMLDivElement) => void)(el);
171-
}
172-
}}
163+
ref={grid}
173164
class="grid h-full min-h-0 bg-white dark:bg-solid-darkbg dark:text-white text-black font-sans"
174165
classList={{
175166
'wrapper--forced': props.isHorizontal,
@@ -185,37 +176,34 @@ const Repl: ReplProps = (props) => {
185176
<For each={props.tabs}>
186177
{(tab, index) => (
187178
<TabItem active={props.current === tab.name} class="mr-2">
188-
<button
189-
type="button"
179+
<div
180+
ref={(el) => tabRefs.set(tab.name, el)}
181+
class="cursor-pointer select-none py-2 px-3 border border-solid border-transparent rounded transition focus:border-blue-600 focus:outline-none"
182+
contentEditable={edit() == index()}
183+
onBlur={(e) => {
184+
setEdit(-1);
185+
setTabName(tab.name, e.currentTarget.textContent!);
186+
}}
187+
onKeyDown={(e) => {
188+
if (e.code === 'Space') e.preventDefault();
189+
if (e.code !== 'Enter') return;
190+
setEdit(-1);
191+
setTabName(tab.name, e.currentTarget.textContent!);
192+
}}
190193
onClick={() => setCurrentTab(tab.name)}
191-
onDblClick={() => {
194+
onDblClick={(e) => {
195+
e.preventDefault();
192196
setEdit(index());
193197
tabRefs.get(tab.name)?.focus();
194198
}}
195-
class="cursor-pointer -mb-0.5 py-2 px-3"
196199
>
197-
<span
198-
ref={(el) => tabRefs.set(tab.name, el)}
199-
contentEditable={edit() == index()}
200-
onBlur={(e) => {
201-
setEdit(-1);
202-
setTabName(tab.name, e.currentTarget.textContent!);
203-
}}
204-
onKeyDown={(e) => {
205-
if (e.code === 'Space') e.preventDefault();
206-
if (e.code !== 'Enter') return;
207-
setEdit(-1);
208-
setTabName(tab.name, e.currentTarget.textContent!);
209-
}}
210-
>
211-
{tab.name}
212-
</span>
213-
</button>
200+
{tab.name}
201+
</div>
214202

215203
<Show when={index() > 0}>
216204
<button
217205
type="button"
218-
class="border-0 cursor-pointer -mb-0.5"
206+
class="cursor-pointer"
219207
onClick={() => {
220208
removeTab(tab.name);
221209
}}
@@ -277,7 +265,7 @@ const Repl: ReplProps = (props) => {
277265
</Show>
278266
</div>
279267

280-
<GridResizer ref={(el) => (resizer = el)} isHorizontal={isHorizontal()} onResize={changeLeft} />
268+
<GridResizer ref={resizer} isHorizontal={isHorizontal()} onResize={changeLeft} />
281269

282270
<div class="h-full flex flex-col">
283271
<TabList>
@@ -331,7 +319,9 @@ const Repl: ReplProps = (props) => {
331319
devtools={devtoolsOpen()}
332320
isDark={props.dark}
333321
code={compiled()}
334-
class={`h-full w-full bg-white row-start-5 ${props.isHorizontal ? '' : 'md:row-start-2'}`}
322+
classList={{
323+
'md:row-start-2': !props.isHorizontal,
324+
}}
335325
/>
336326
</Match>
337327
<Match when={outputTab() == 1}>

src/components/tab/item.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import type { Component, JSX } from 'solid-js';
1+
import type { ParentComponent } from 'solid-js';
22

3-
export const TabItem: Component<Props> = (props) => {
3+
export const TabItem: ParentComponent<{
4+
active?: boolean;
5+
class?: string;
6+
}> = (props) => {
47
return (
58
<li
6-
class={`relative inline-flex text-sm font-sans leading-snug items-center bg-slate-500 bg-opacity-0 hover:bg-opacity-5 overflow-hidden space-x-2 border-brand-default dark:border-gray-200 border-b-2 ${
9+
class={`relative inline-flex text-sm font-sans transition leading-snug items-center bg-slate-500 bg-opacity-0 hover:bg-opacity-5 overflow-hidden border-brand-default dark:border-gray-200 border-b-2 ${
710
props.class || ''
811
}`}
912
classList={{
@@ -15,7 +18,3 @@ export const TabItem: Component<Props> = (props) => {
1518
</li>
1619
);
1720
};
18-
19-
interface Props extends JSX.LiHTMLAttributes<HTMLLIElement> {
20-
active?: boolean;
21-
}

0 commit comments

Comments
 (0)