Skip to content

Commit 02520ae

Browse files
authored
better tooltips in playground (#11705)
* better tooltips in playground * update some tests that a drive-by fix broke
1 parent 506f9d2 commit 02520ae

File tree

9 files changed

+153
-54
lines changed

9 files changed

+153
-54
lines changed

packages/svelte/src/compiler/phases/1-parse/state/element.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ export default function tag(parser) {
217217
while ((attribute = read(parser))) {
218218
if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') {
219219
if (unique_names.includes(attribute.name)) {
220-
e.attribute_duplicate(attribute.start);
220+
e.attribute_duplicate(attribute);
221221
// <svelte:element bind:this this=..> is allowed
222222
} else if (attribute.name !== 'this') {
223223
unique_names.push(attribute.name);

packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ export default test({
44
error: {
55
code: 'attribute_duplicate',
66
message: 'Attributes need to be unique',
7-
position: [17, 17]
7+
position: [17, 25]
88
}
99
});

packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ export default test({
44
error: {
55
code: 'attribute_duplicate',
66
message: 'Attributes need to be unique',
7-
position: [17, 17]
7+
position: [17, 24]
88
}
99
});

packages/svelte/tests/compiler-errors/samples/attribute-unique/_config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ export default test({
44
error: {
55
code: 'attribute_duplicate',
66
message: 'Attributes need to be unique',
7-
position: [17, 17]
7+
position: [17, 28]
88
}
99
});

pnpm-lock.yaml

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sites/svelte-5-preview/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"@lezer/highlight": "^1.1.6",
4747
"@neocodemirror/svelte": "0.0.15",
4848
"@replit/codemirror-lang-svelte": "^6.0.0",
49-
"@rich_harris/svelte-split-pane": "^1.1.2",
49+
"@rich_harris/svelte-split-pane": "^1.1.3",
5050
"@rollup/browser": "^3.28.0",
5151
"acorn": "^8.10.0",
5252
"codemirror": "^6.0.1",

sites/svelte-5-preview/src/lib/CodeMirror.svelte

Lines changed: 120 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@
246246
247247
<style>
248248
.codemirror-container {
249+
--warning: hsl(40 100% 70%);
250+
--error: hsl(0 100% 90%);
249251
position: relative;
250252
width: 100%;
251253
height: 100%;
@@ -254,26 +256,129 @@
254256
overflow: hidden;
255257
}
256258
257-
.codemirror-container :global(.mark-text) {
258-
background-color: var(--sk-selection-color);
259-
backdrop-filter: opacity(40%);
259+
:global(.dark) .codemirror-container {
260+
--warning: hsl(40 100% 50%);
261+
--error: hsl(0 100% 70%);
260262
}
261263
262-
.codemirror-container :global(.cm-editor) {
263-
height: 100%;
264-
}
264+
.codemirror-container :global {
265+
* {
266+
font: 400 var(--sk-text-xs) / 1.7 var(--sk-font-mono);
267+
}
265268
266-
.codemirror-container :global(*) {
267-
font: 400 var(--sk-text-xs) / 1.7 var(--sk-font-mono) !important;
268-
}
269+
.mark-text {
270+
background-color: var(--sk-selection-color);
271+
backdrop-filter: opacity(40%);
272+
}
269273
270-
.codemirror-container :global(.error-loc) {
271-
position: relative;
272-
border-bottom: 2px solid #da106e;
273-
}
274+
.cm-editor {
275+
height: 100%;
276+
}
277+
278+
.error-loc {
279+
position: relative;
280+
border-bottom: 2px solid #da106e;
281+
}
282+
283+
.error-line {
284+
background-color: rgba(200, 0, 0, 0.05);
285+
}
286+
287+
.cm-tooltip {
288+
border: none;
289+
background-color: transparent;
290+
font-family: var(--sk-font);
291+
max-width: calc(100vw - 10em);
292+
position: relative;
293+
}
294+
295+
.cm-tooltip-section {
296+
position: relative;
297+
padding: 0.5em;
298+
/* width: calc(100vw - 10em); */
299+
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.1));
300+
background: var(--bg);
301+
border-radius: 2px;
302+
}
303+
304+
.cm-tooltip-section::before {
305+
content: '';
306+
position: absolute;
307+
left: 20px;
308+
width: 8px;
309+
height: 8px;
310+
transform: rotate(45deg);
311+
background-color: var(--bg);
312+
border-radius: 2px;
313+
}
314+
315+
.cm-tooltip-below .cm-tooltip-section {
316+
top: 10px;
317+
}
318+
319+
.cm-tooltip-above .cm-tooltip-section {
320+
bottom: 10px;
321+
}
274322
275-
.codemirror-container :global(.error-line) {
276-
background-color: rgba(200, 0, 0, 0.05);
323+
.cm-tooltip-below .cm-tooltip-section::before {
324+
top: -4px;
325+
}
326+
327+
.cm-tooltip-above .cm-tooltip-section::before {
328+
bottom: -4px;
329+
}
330+
331+
.cm-tooltip:has(.cm-diagnostic-warning) {
332+
--bg: var(--warning);
333+
--fg: #222;
334+
}
335+
336+
.cm-tooltip:has(.cm-diagnostic-error) {
337+
--bg: var(--error);
338+
--fg: #222;
339+
}
340+
341+
.cm-diagnostic {
342+
padding: 0.2em 0.4em;
343+
position: relative;
344+
border: none;
345+
border-radius: 2px;
346+
}
347+
348+
.cm-diagnostic:not(:last-child) {
349+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
350+
}
351+
352+
.cm-diagnostic-error {
353+
border: none;
354+
filter: drop-shadow(0px 0px 6px var(--error-bg));
355+
}
356+
357+
.cm-diagnostic :not(code) {
358+
font-family: var(--sk-font);
359+
}
360+
361+
.cm-diagnosticText {
362+
color: var(--fg);
363+
position: relative;
364+
z-index: 2;
365+
}
366+
367+
.cm-diagnosticText code {
368+
color: inherit;
369+
background-color: rgba(0, 0, 0, 0.05);
370+
border-radius: 2px;
371+
top: 0;
372+
padding: 0.2em;
373+
font-size: 0.9em;
374+
}
375+
376+
.cm-diagnosticText strong {
377+
font-size: 0.9em;
378+
/* font-weight: 700; */
379+
font-family: var(--sk-font-mono);
380+
opacity: 0.7;
381+
}
277382
}
278383
279384
pre {

sites/svelte-5-preview/src/lib/Input/ModuleEditor.svelte

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,23 @@
2222
<div class="editor notranslate" translate="no">
2323
<CodeMirror
2424
bind:this={$module_editor}
25-
{autocomplete}
2625
diagnostics={() => {
2726
if (error) {
2827
return [
2928
{
3029
severity: 'error',
3130
from: error.position[0],
3231
to: error.position[1],
33-
message: error.message
32+
message: error.message,
33+
renderMessage: () => {
34+
// TODO expose error codes, so we can link to docs in future
35+
const span = document.createElement('span');
36+
span.innerHTML = `${error.message
37+
.replace(/&/g, '&amp;')
38+
.replace(/</g, '&lt;')
39+
.replace(/`(.+?)`/g, `<code>$1</code>`)}`;
40+
return span;
41+
}
3442
}
3543
];
3644
}
@@ -40,7 +48,15 @@
4048
severity: 'warning',
4149
from: warning.start.character,
4250
to: warning.end.character,
43-
message: warning.message
51+
message: warning.message,
52+
renderMessage: () => {
53+
const span = document.createElement('span');
54+
span.innerHTML = `${warning.message
55+
.replace(/&/g, '&amp;')
56+
.replace(/</g, '&lt;')
57+
.replace(/`(.+?)`/g, `<code>$1</code>`)} <strong>(${warning.code})</strong>`;
58+
return span;
59+
}
4460
}));
4561
}
4662

sites/svelte-5-preview/src/lib/theme.js

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { tags as t } from '@lezer/highlight';
55
const ERROR_HUE = 0;
66
const WARNING_HUE = 40;
77

8-
const WARNING_FG = `hsl(${WARNING_HUE} 100% 40%)`;
8+
const WARNING_FG = `hsl(${WARNING_HUE} 100% 60%)`;
99
const WARNING_BG = `hsl(${WARNING_HUE} 100% 40% / 0.5)`;
1010

1111
const ERROR_FG = `hsl(${ERROR_HUE} 100% 40%)`;
@@ -80,28 +80,6 @@ const svelteThemeStyles = EditorView.theme(
8080
color: '#ddd'
8181
},
8282

83-
'.cm-tooltip': {
84-
border: 'none',
85-
backgroundColor: 'var(--sk-back-3)'
86-
},
87-
'.cm-diagnostic': {
88-
padding: '0.2em 0.4em',
89-
backgroundColor: 'var(--sk-back-3)',
90-
color: 'var(--sk-text-1)',
91-
border: 'none',
92-
borderRadius: '2px',
93-
position: 'relative',
94-
top: '2px',
95-
zIndex: 2
96-
},
97-
'.cm-diagnostic-error': {
98-
border: `1px solid ${ERROR_FG}`,
99-
filter: `drop-shadow(0px 0px 6px ${ERROR_BG})`
100-
},
101-
'.cm-diagnostic-warning': {
102-
border: `1px solid ${WARNING_FG}`,
103-
filter: `drop-shadow(0px 0px 6px ${WARNING_BG})`
104-
},
10583
// https://github.com/codemirror/lint/blob/271b35f5d31a7e3645eaccbfec608474022098e1/src/lint.ts#L620
10684
'.cm-lintRange': {
10785
backgroundPosition: 'left bottom',

0 commit comments

Comments
 (0)