@atom-forge/brickee 0.0.2 → 0.0.3
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/CHANGELOG.md +40 -0
- package/README-AI.md +10 -7
- package/dist/Editor.svelte +691 -833
- package/dist/LinkPrompt.svelte +1 -14
- package/dist/Preview.svelte +27 -54
- package/dist/Preview.svelte.d.ts +2 -4
- package/dist/PropsBar.svelte +35 -219
- package/dist/code.js +1 -1
- package/dist/dom.d.ts +8 -0
- package/dist/dom.js +9 -0
- package/dist/editor/BlockMenu.svelte +102 -0
- package/dist/editor/BlockMenu.svelte.d.ts +32 -0
- package/dist/editor/FormatBar.svelte +41 -0
- package/dist/editor/FormatBar.svelte.d.ts +16 -0
- package/dist/editor/drag.svelte.d.ts +63 -0
- package/dist/editor/drag.svelte.js +95 -0
- package/dist/editor/history.d.ts +24 -0
- package/dist/editor/history.js +86 -0
- package/dist/editor/sweep.svelte.d.ts +21 -0
- package/dist/editor/sweep.svelte.js +56 -0
- package/dist/html.d.ts +12 -0
- package/dist/html.js +206 -0
- package/dist/i18n.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/kit/Empty.svelte +4 -15
- package/dist/kit/Frame.svelte +7 -37
- package/dist/locales/hu.js +4 -1
- package/dist/markdown.d.ts +20 -4
- package/dist/markdown.js +380 -85
- package/dist/model.js +2 -3
- package/dist/plugins/Gap.svelte +5 -8
- package/dist/plugins/GapPreview.svelte +4 -6
- package/dist/plugins/Map.svelte +2 -17
- package/dist/plugins/MapPreview.svelte +8 -10
- package/dist/plugins/Table.svelte +233 -256
- package/dist/plugins/TablePreview.svelte +28 -28
- package/dist/plugins/YouTube.svelte +3 -31
- package/dist/plugins/YouTubePreview.svelte +45 -43
- package/dist/plugins/index.js +3 -1
- package/dist/types.d.ts +21 -3
- package/dist/types.js +8 -1
- package/dist/view.js +1 -1
- package/docs/en/bundled-plugins.md +1 -1
- package/docs/en/documents-and-markdown.md +20 -14
- package/docs/en/editor-and-preview.md +6 -7
- package/docs/en/getting-started.md +8 -0
- package/docs/en/index.md +1 -1
- package/docs/en/recipes-and-pitfalls.md +2 -2
- package/docs/en/server-side.md +0 -17
- package/docs/en/upgrading.md +14 -0
- package/docs/en/writing-plugins.md +36 -10
- package/docs/hu/bundled-plugins.md +1 -1
- package/docs/hu/documents-and-markdown.md +20 -14
- package/docs/hu/editor-and-preview.md +6 -7
- package/docs/hu/getting-started.md +8 -0
- package/docs/hu/index.md +1 -1
- package/docs/hu/recipes-and-pitfalls.md +2 -2
- package/docs/hu/server-side.md +0 -17
- package/docs/hu/upgrading.md +14 -0
- package/docs/hu/writing-plugins.md +36 -10
- package/package.json +9 -1
|
@@ -14,13 +14,11 @@
|
|
|
14
14
|
<iframe class="map" title={tr('Map: {place}', { place: String(props.q ?? '') })} {src} loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
|
15
15
|
{/if}
|
|
16
16
|
|
|
17
|
-
<style
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
</style>
|
|
17
|
+
<style>.map {
|
|
18
|
+
display: block;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 300px;
|
|
21
|
+
margin: 0 0 1em;
|
|
22
|
+
border: 0;
|
|
23
|
+
border-radius: 10px;
|
|
24
|
+
}</style>
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
Trash2
|
|
63
63
|
} from '@lucide/svelte';
|
|
64
64
|
import { tick } from 'svelte';
|
|
65
|
+
import { inline } from '../markdown';
|
|
65
66
|
import type { PluginViewProps } from '../types';
|
|
66
67
|
|
|
67
68
|
let { props = $bindable(), readonly }: PluginViewProps<TableProps> = $props();
|
|
@@ -110,7 +111,14 @@
|
|
|
110
111
|
};
|
|
111
112
|
addEventListener('pointermove', move);
|
|
112
113
|
addEventListener('pointerup', up);
|
|
114
|
+
stopDrag = () => {
|
|
115
|
+
removeEventListener('pointermove', move);
|
|
116
|
+
removeEventListener('pointerup', up);
|
|
117
|
+
};
|
|
113
118
|
}
|
|
119
|
+
// A table removed in the middle of a drag leaves no listener behind.
|
|
120
|
+
let stopDrag = () => {};
|
|
121
|
+
$effect(() => () => stopDrag());
|
|
114
122
|
/** The drop line of a row or column: before it, after it (the last one), or none. */
|
|
115
123
|
function dropMark(kind: 'row' | 'col', i: number, count: number) {
|
|
116
124
|
if (drag?.kind !== kind || drag.to === drag.from || drag.to === drag.from + 1) return null;
|
|
@@ -151,9 +159,38 @@
|
|
|
151
159
|
}
|
|
152
160
|
const setAlign = (c: number, a: Align) => set({ align: align.map((x, j) => (j === c ? a : x)) });
|
|
153
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Wraps the selected text of a cell in a mark (Ctrl+B and the like); then selects the text again, or, for a link,
|
|
164
|
+
* the address to type over.
|
|
165
|
+
*/
|
|
166
|
+
async function mark(t: HTMLTextAreaElement, r: number, c: number, open: string, close: string, link = false) {
|
|
167
|
+
const { selectionStart: a, selectionEnd: b, value } = t;
|
|
168
|
+
const text = value.slice(a, b);
|
|
169
|
+
edit(r, c, value.slice(0, a) + open + text + close + value.slice(b));
|
|
170
|
+
await tick();
|
|
171
|
+
const cell = root.querySelector<HTMLTextAreaElement>(`textarea[data-cell="${r}:${c}"]`);
|
|
172
|
+
if (!cell) return;
|
|
173
|
+
cell.focus();
|
|
174
|
+
if (link) cell.setSelectionRange(a + open.length + text.length + 2, a + open.length + text.length + close.length - 1);
|
|
175
|
+
else cell.setSelectionRange(a + open.length, a + open.length + text.length);
|
|
176
|
+
}
|
|
177
|
+
const MARKS: Record<string, [string, string]> = { b: ['**', '**'], i: ['*', '*'], e: ['`', '`'] };
|
|
178
|
+
|
|
154
179
|
function onKey(e: KeyboardEvent, r: number, c: number) {
|
|
155
180
|
const t = e.currentTarget as HTMLTextAreaElement;
|
|
156
181
|
const last = r === rows.length - 1;
|
|
182
|
+
const k = e.key.toLowerCase();
|
|
183
|
+
if ((e.ctrlKey || e.metaKey) && !e.altKey) {
|
|
184
|
+
const m = e.shiftKey ? (k === 'x' ? (['~~', '~~'] as [string, string]) : null) : MARKS[k];
|
|
185
|
+
if (m) {
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
return void mark(t, r, c, m[0], m[1]);
|
|
188
|
+
}
|
|
189
|
+
if (k === 'k' && !e.shiftKey) {
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
return void mark(t, r, c, '[', '](https://)', true);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
157
194
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
158
195
|
// Enter goes down a row (a new one after the last); Shift+Enter breaks the line inside the cell.
|
|
159
196
|
e.preventDefault();
|
|
@@ -199,6 +236,18 @@
|
|
|
199
236
|
return { update: fit, destroy: () => node.removeEventListener('input', fit) };
|
|
200
237
|
}
|
|
201
238
|
|
|
239
|
+
// The toolbar's look (Tailwind; whole class names, so Tailwind finds them): segments of small buttons.
|
|
240
|
+
const SEG = 'inline-flex items-center gap-px rounded-lg bg-muted p-0.5';
|
|
241
|
+
const LABEL = 'inline-grid place-items-center pr-1 pl-[5px] text-muted-contrast';
|
|
242
|
+
const TOOL =
|
|
243
|
+
'inline-grid h-6 min-w-[26px] cursor-pointer place-items-center rounded-md border-0 bg-transparent px-[5px] text-surface-contrast enabled:hover:bg-surface enabled:hover:shadow-[0_1px_2px_rgb(0_0_0/0.08)] disabled:cursor-default disabled:opacity-30';
|
|
244
|
+
const TOOL_ON =
|
|
245
|
+
'inline-grid h-6 min-w-[26px] cursor-pointer place-items-center rounded-md border-0 bg-surface px-[5px] text-accent shadow-[0_1px_2px_rgb(0_0_0/0.08)]';
|
|
246
|
+
const DANGER = `${TOOL} enabled:hover:text-[#dc2626]`;
|
|
247
|
+
const ADD = $derived(
|
|
248
|
+
`grid cursor-pointer place-items-center rounded-md border-0 bg-muted p-0 text-muted-contrast transition-[opacity,background] duration-[120ms] hover:bg-accent/12 hover:text-accent ${at ? 'opacity-100' : 'opacity-0 group-hover/table:opacity-100'}`
|
|
249
|
+
);
|
|
250
|
+
|
|
202
251
|
const ALIGNS: { value: Align; icon: typeof TextAlignStart; label: string }[] = [
|
|
203
252
|
{ value: 'left', icon: TextAlignStart, label: 'Align column left' },
|
|
204
253
|
{ value: 'center', icon: TextAlignCenter, label: 'Center column' },
|
|
@@ -207,41 +256,42 @@
|
|
|
207
256
|
</script>
|
|
208
257
|
|
|
209
258
|
<div
|
|
210
|
-
class="table"
|
|
211
|
-
class:editing={!!at}
|
|
259
|
+
class="table-editor group/table text-[15px] leading-[1.45]"
|
|
212
260
|
bind:this={root}
|
|
213
261
|
onfocusout={(e) => {
|
|
214
262
|
if (!root.contains(e.relatedTarget as Node)) at = null;
|
|
215
263
|
}}
|
|
216
264
|
>
|
|
217
265
|
{#if !readonly}
|
|
218
|
-
|
|
266
|
+
<!-- The row and column tools of the cell being edited; when it wraps, it pushes the table down. -->
|
|
267
|
+
<div class="mb-2 flex min-h-7 flex-wrap items-center gap-1.5" role="toolbar" aria-label={tr('Table')}>
|
|
219
268
|
{#if at}
|
|
220
269
|
{@const { r, c } = at}
|
|
221
|
-
<div class=
|
|
222
|
-
<span class=
|
|
223
|
-
<button type="button" title={tr('Insert a row above')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertRow(r); focusCell(r, c); }}><BetweenHorizontalStart size={15} /></button>
|
|
224
|
-
<button type="button" title={tr('Insert a row below')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertRow(r + 1); focusCell(r + 1, c); }}><BetweenHorizontalEnd size={15} /></button>
|
|
225
|
-
<button type="button" class=
|
|
270
|
+
<div class={SEG}>
|
|
271
|
+
<span class={LABEL} title={tr('Row')}><Rows3 size={14} /></span>
|
|
272
|
+
<button type="button" class={TOOL} title={tr('Insert a row above')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertRow(r); focusCell(r, c); }}><BetweenHorizontalStart size={15} /></button>
|
|
273
|
+
<button type="button" class={TOOL} title={tr('Insert a row below')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertRow(r + 1); focusCell(r + 1, c); }}><BetweenHorizontalEnd size={15} /></button>
|
|
274
|
+
<button type="button" class={DANGER} title={tr('Delete this row')} disabled={rows.length < 2} onclick={() => dropRow(r)}><Trash2 size={14} /></button>
|
|
226
275
|
</div>
|
|
227
|
-
<div class=
|
|
228
|
-
<span class=
|
|
229
|
-
<button type="button" title={tr('Insert a column left')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertCol(c); focusCell(r, c); }}><BetweenVerticalStart size={15} /></button>
|
|
230
|
-
<button type="button" title={tr('Insert a column right')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertCol(c + 1); focusCell(r, c + 1); }}><BetweenVerticalEnd size={15} /></button>
|
|
231
|
-
<button type="button" class=
|
|
276
|
+
<div class={SEG}>
|
|
277
|
+
<span class={LABEL} title={tr('Column')}><Columns3 size={14} /></span>
|
|
278
|
+
<button type="button" class={TOOL} title={tr('Insert a column left')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertCol(c); focusCell(r, c); }}><BetweenVerticalStart size={15} /></button>
|
|
279
|
+
<button type="button" class={TOOL} title={tr('Insert a column right')} onmousedown={(e) => e.preventDefault()} onclick={() => { insertCol(c + 1); focusCell(r, c + 1); }}><BetweenVerticalEnd size={15} /></button>
|
|
280
|
+
<button type="button" class={DANGER} title={tr('Delete this column')} disabled={width < 2} onclick={() => dropCol(c)}><Trash2 size={14} /></button>
|
|
232
281
|
</div>
|
|
233
|
-
<div class=
|
|
282
|
+
<div class={SEG}>
|
|
234
283
|
{#each ALIGNS as a (a.value)}
|
|
235
|
-
<button type="button"
|
|
284
|
+
<button type="button" class={align[c] === a.value ? TOOL_ON : TOOL} title={tr(a.label)} onmousedown={(e) => e.preventDefault()} onclick={() => setAlign(c, a.value)}><a.icon size={15} /></button>
|
|
236
285
|
{/each}
|
|
237
286
|
</div>
|
|
238
287
|
{:else}
|
|
239
|
-
<span class="
|
|
288
|
+
<span class="text-[12px] text-muted-contrast">{tr('Click a cell to edit its row and column')}</span>
|
|
240
289
|
{/if}
|
|
241
290
|
</div>
|
|
242
291
|
{/if}
|
|
243
|
-
|
|
244
|
-
|
|
292
|
+
<!-- The table, with a + bar on the right (column) and below (row) that shows on hover. -->
|
|
293
|
+
<div class="grid grid-cols-[minmax(0,1fr)_18px] grid-rows-[auto_18px] gap-1">
|
|
294
|
+
<div class="overflow-x-auto rounded-[10px] border border-frame bg-surface">
|
|
245
295
|
<table class:dragging={!!drag}>
|
|
246
296
|
{#if !readonly}
|
|
247
297
|
<!-- the column grips -->
|
|
@@ -265,12 +315,16 @@
|
|
|
265
315
|
</td>
|
|
266
316
|
{/if}
|
|
267
317
|
{#each row as cell, c (c)}
|
|
318
|
+
{@const editing = at?.r === r && at?.c === c}
|
|
268
319
|
<td
|
|
269
320
|
class={dropMark('col', c, width) ? 'c-' + dropMark('col', c, width) : ''}
|
|
270
321
|
class:col-on={at?.c === c}
|
|
271
322
|
class:moving={drag?.kind === 'col' && drag.from === c}
|
|
272
323
|
>
|
|
324
|
+
<!-- Out of editing a cell shows its text formatted (sizing the cell, over its textarea); editing shows the
|
|
325
|
+
markdown. -->
|
|
273
326
|
<textarea
|
|
327
|
+
class:hidden-text={!editing && !!cell.trim()}
|
|
274
328
|
rows="1"
|
|
275
329
|
value={cell}
|
|
276
330
|
{readonly}
|
|
@@ -284,6 +338,9 @@
|
|
|
284
338
|
onkeydown={(e) => onKey(e, r, c)}
|
|
285
339
|
onpaste={(e) => onPaste(e, r, c)}
|
|
286
340
|
></textarea>
|
|
341
|
+
{#if !editing && cell.trim()}
|
|
342
|
+
<div class="shown" style:text-align={align[c]} aria-hidden="true">{@html inline(cell)}</div>
|
|
343
|
+
{/if}
|
|
287
344
|
</td>
|
|
288
345
|
{/each}
|
|
289
346
|
</tr>
|
|
@@ -292,246 +349,166 @@
|
|
|
292
349
|
</table>
|
|
293
350
|
</div>
|
|
294
351
|
{#if !readonly}
|
|
295
|
-
<button type="button" class=
|
|
296
|
-
<button type="button" class="
|
|
352
|
+
<button type="button" class={ADD} title={tr('Add a column')} aria-label={tr('Add a column')} onclick={() => { insertCol(width); focusCell(0, width); }}><Plus size={14} /></button>
|
|
353
|
+
<button type="button" class="col-start-1 {ADD}" title={tr('Add a row')} aria-label={tr('Add a row')} onclick={() => { insertRow(rows.length); focusCell(rows.length, 0); }}><Plus size={14} /></button>
|
|
297
354
|
{/if}
|
|
298
355
|
</div>
|
|
299
356
|
</div>
|
|
300
357
|
|
|
301
|
-
<style>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
flex-wrap: wrap;
|
|
310
|
-
align-items: center;
|
|
311
|
-
gap: 6px;
|
|
312
|
-
min-height: 28px;
|
|
313
|
-
}
|
|
314
|
-
.seg {
|
|
315
|
-
display: inline-flex;
|
|
316
|
-
align-items: center;
|
|
317
|
-
gap: 1px;
|
|
318
|
-
padding: 2px;
|
|
319
|
-
border-radius: 8px;
|
|
320
|
-
background: var(--color-muted, #f4f4f6);
|
|
321
|
-
}
|
|
322
|
-
.idle {
|
|
323
|
-
font-size: 12px;
|
|
324
|
-
color: var(--color-muted-contrast, #a0a0a8);
|
|
325
|
-
}
|
|
326
|
-
.label {
|
|
327
|
-
display: inline-grid;
|
|
328
|
-
place-items: center;
|
|
329
|
-
padding: 0 4px 0 5px;
|
|
330
|
-
color: var(--color-muted-contrast, #a0a0a8);
|
|
331
|
-
}
|
|
332
|
-
.bar button {
|
|
333
|
-
display: inline-grid;
|
|
334
|
-
place-items: center;
|
|
335
|
-
height: 24px;
|
|
336
|
-
min-width: 26px;
|
|
337
|
-
padding: 0 5px;
|
|
338
|
-
border: 0;
|
|
339
|
-
border-radius: 6px;
|
|
340
|
-
background: none;
|
|
341
|
-
color: var(--color-surface-contrast, #4b4b55);
|
|
342
|
-
cursor: pointer;
|
|
343
|
-
}
|
|
344
|
-
.bar button:hover:not(:disabled) {
|
|
345
|
-
background: var(--color-surface, #fff);
|
|
346
|
-
color: var(--color-surface-contrast, #1d1d1f);
|
|
347
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
|
348
|
-
}
|
|
349
|
-
.bar button.on {
|
|
350
|
-
background: var(--color-surface, #fff);
|
|
351
|
-
color: #2563eb;
|
|
352
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
|
353
|
-
}
|
|
354
|
-
.bar button.danger:hover:not(:disabled) {
|
|
355
|
-
color: #dc2626;
|
|
356
|
-
}
|
|
357
|
-
.bar button:disabled {
|
|
358
|
-
opacity: 0.3;
|
|
359
|
-
cursor: default;
|
|
360
|
-
}
|
|
361
|
-
.bar .toggle {
|
|
362
|
-
display: inline-flex;
|
|
363
|
-
gap: 5px;
|
|
364
|
-
height: 28px;
|
|
365
|
-
padding: 0 10px;
|
|
366
|
-
border: 1px solid var(--color-frame, #e5e5ea);
|
|
367
|
-
border-radius: 8px;
|
|
368
|
-
font-size: 12px;
|
|
369
|
-
font-weight: 500;
|
|
370
|
-
}
|
|
371
|
-
.bar .toggle.on {
|
|
372
|
-
border-color: color-mix(in srgb, #3b82f6 35%, transparent);
|
|
373
|
-
background: color-mix(in srgb, #3b82f6 8%, transparent);
|
|
374
|
-
box-shadow: none;
|
|
375
|
-
}
|
|
358
|
+
<style>table {
|
|
359
|
+
width: 100%;
|
|
360
|
+
border-collapse: collapse;
|
|
361
|
+
}
|
|
362
|
+
table.dragging, table.dragging * {
|
|
363
|
+
cursor: grabbing !important;
|
|
364
|
+
user-select: none;
|
|
365
|
+
}
|
|
376
366
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
.table:hover .add-col,
|
|
527
|
-
.table:hover .add-row,
|
|
528
|
-
.table.editing .add-col,
|
|
529
|
-
.table.editing .add-row {
|
|
530
|
-
opacity: 1;
|
|
531
|
-
}
|
|
532
|
-
.add-col:hover,
|
|
533
|
-
.add-row:hover {
|
|
534
|
-
background: color-mix(in srgb, #3b82f6 12%, transparent);
|
|
535
|
-
color: #2563eb;
|
|
536
|
-
}
|
|
537
|
-
</style>
|
|
367
|
+
td {
|
|
368
|
+
height: 1px;
|
|
369
|
+
padding: 0;
|
|
370
|
+
border-right: 1px solid var(--color-frame, #ececf0);
|
|
371
|
+
border-bottom: 1px solid var(--color-frame, #ececf0);
|
|
372
|
+
vertical-align: top;
|
|
373
|
+
transition: background 0.1s;
|
|
374
|
+
}
|
|
375
|
+
td:last-child {
|
|
376
|
+
border-right: 0;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
tr:last-child td {
|
|
380
|
+
border-bottom: 0;
|
|
381
|
+
}
|
|
382
|
+
tr.row-on td,
|
|
383
|
+
tr td.col-on {
|
|
384
|
+
background: color-mix(in srgb, var(--color-accent, #3b82f6) 4%, transparent);
|
|
385
|
+
}
|
|
386
|
+
tr.h-top td:not(.rgrip) {
|
|
387
|
+
background: var(--color-muted, #f1f1f4);
|
|
388
|
+
border-bottom: 2px solid var(--color-frame, #d8d8de);
|
|
389
|
+
}
|
|
390
|
+
tr.h-bottom td:not(.rgrip) {
|
|
391
|
+
background: var(--color-muted, #f1f1f4);
|
|
392
|
+
border-top: 2px solid var(--color-frame, #d8d8de);
|
|
393
|
+
}
|
|
394
|
+
tr.h-top textarea, tr.h-top .shown {
|
|
395
|
+
font-weight: 600;
|
|
396
|
+
font-size: 13px;
|
|
397
|
+
letter-spacing: 0.04em;
|
|
398
|
+
text-transform: uppercase;
|
|
399
|
+
color: var(--color-surface-contrast, #3a3a44);
|
|
400
|
+
}
|
|
401
|
+
tr.h-bottom textarea, tr.h-bottom .shown {
|
|
402
|
+
font-weight: 600;
|
|
403
|
+
color: var(--color-surface-contrast, #1d1d1f);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
td {
|
|
407
|
+
position: relative;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
textarea {
|
|
411
|
+
display: block;
|
|
412
|
+
width: 100%;
|
|
413
|
+
height: 100%;
|
|
414
|
+
min-width: 6em;
|
|
415
|
+
box-sizing: border-box;
|
|
416
|
+
padding: 8px 11px;
|
|
417
|
+
border: 0;
|
|
418
|
+
border-radius: 0;
|
|
419
|
+
background: none;
|
|
420
|
+
resize: none;
|
|
421
|
+
font: inherit;
|
|
422
|
+
color: inherit;
|
|
423
|
+
outline: none;
|
|
424
|
+
}
|
|
425
|
+
textarea::placeholder {
|
|
426
|
+
color: var(--color-muted-contrast, #b8b8c0);
|
|
427
|
+
}
|
|
428
|
+
textarea:focus {
|
|
429
|
+
background: var(--color-surface, #fff);
|
|
430
|
+
box-shadow: inset 0 0 0 2px var(--color-accent, #3b82f6);
|
|
431
|
+
}
|
|
432
|
+
textarea.hidden-text {
|
|
433
|
+
position: absolute;
|
|
434
|
+
inset: 0;
|
|
435
|
+
min-height: 0 !important;
|
|
436
|
+
color: transparent;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.shown {
|
|
440
|
+
position: relative;
|
|
441
|
+
box-sizing: border-box;
|
|
442
|
+
min-width: 6em;
|
|
443
|
+
padding: 8px 11px;
|
|
444
|
+
overflow: hidden;
|
|
445
|
+
pointer-events: none;
|
|
446
|
+
white-space: pre-wrap;
|
|
447
|
+
word-break: break-word;
|
|
448
|
+
}
|
|
449
|
+
.shown :global(code) {
|
|
450
|
+
padding: 0.1em 0.35em;
|
|
451
|
+
border-radius: 4px;
|
|
452
|
+
background: rgba(120, 120, 140, 0.14);
|
|
453
|
+
font: 0.88em ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
454
|
+
}
|
|
455
|
+
.shown :global(a) {
|
|
456
|
+
color: var(--color-accent, #3b82f6);
|
|
457
|
+
text-decoration: underline;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
td.corner,
|
|
461
|
+
td.rgrip {
|
|
462
|
+
width: 14px;
|
|
463
|
+
border-right: 1px solid var(--color-frame, #ececf0);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
tr.grips td {
|
|
467
|
+
height: 14px;
|
|
468
|
+
border-bottom: 1px solid var(--color-frame, #ececf0);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.grip {
|
|
472
|
+
display: grid;
|
|
473
|
+
place-items: center;
|
|
474
|
+
width: 100%;
|
|
475
|
+
height: 100%;
|
|
476
|
+
min-height: 14px;
|
|
477
|
+
padding: 0;
|
|
478
|
+
border: 0;
|
|
479
|
+
background: none;
|
|
480
|
+
color: var(--color-muted-contrast, #b0b0b8);
|
|
481
|
+
cursor: grab;
|
|
482
|
+
opacity: 0;
|
|
483
|
+
touch-action: none;
|
|
484
|
+
transition: opacity 0.12s;
|
|
485
|
+
}
|
|
486
|
+
.table-editor:hover .grip, table.dragging .grip {
|
|
487
|
+
opacity: 1;
|
|
488
|
+
}
|
|
489
|
+
.grip:hover {
|
|
490
|
+
color: var(--color-accent, #3b82f6);
|
|
491
|
+
background: color-mix(in srgb, var(--color-accent, #3b82f6) 9%, transparent);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.moving {
|
|
495
|
+
opacity: 0.45;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
tr.before td {
|
|
499
|
+
box-shadow: inset 0 2px 0 var(--color-accent, #3b82f6);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
tr.after td {
|
|
503
|
+
box-shadow: inset 0 -2px 0 var(--color-accent, #3b82f6);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
td.before,
|
|
507
|
+
td.c-before {
|
|
508
|
+
box-shadow: inset 2px 0 0 var(--color-accent, #3b82f6);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
td.after,
|
|
512
|
+
td.c-after {
|
|
513
|
+
box-shadow: inset -2px 0 0 var(--color-accent, #3b82f6);
|
|
514
|
+
}</style>
|
|
@@ -32,31 +32,31 @@
|
|
|
32
32
|
</div>
|
|
33
33
|
{/if}
|
|
34
34
|
|
|
35
|
-
<style
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</style>
|
|
35
|
+
<style>.wrap {
|
|
36
|
+
margin: 0 0 1em;
|
|
37
|
+
overflow-x: auto;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
table {
|
|
41
|
+
width: 100%;
|
|
42
|
+
border-collapse: collapse;
|
|
43
|
+
font: 15px/1.5 system-ui, sans-serif;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
th,
|
|
47
|
+
td {
|
|
48
|
+
padding: 0.45em 0.7em;
|
|
49
|
+
border-bottom: 1px solid color-mix(in srgb, currentColor 15%, transparent);
|
|
50
|
+
text-align: left;
|
|
51
|
+
vertical-align: top;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
th {
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
}
|
|
57
|
+
th.top {
|
|
58
|
+
border-bottom-width: 2px;
|
|
59
|
+
}
|
|
60
|
+
th.bottom {
|
|
61
|
+
border-top: 2px solid color-mix(in srgb, currentColor 22%, transparent);
|
|
62
|
+
}</style>
|