mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-06 00:02:13 +00:00
`GfmMarkdown` defaulted to `prose-xs`, which Tailwind Typography does not define — the class only ever matched four hand-rolled rules in app.css, all scoped to `ul`. Every surface on that default (script and flow descriptions, flow-graph notes, markdown job results) therefore rendered `<ol>` with Preflight's `list-style: none` and no typography at all: no numbers, no heading or paragraph rhythm. Route the default through the shared `markdownProse` stacks instead, and cut the app.css list rules down to the dash glyph so ordered and unordered lists share Tailwind Typography's indentation and rhythm. Fixes #10971 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6G5gDXJnm6uqch4uCPkPE
152 lines
4.4 KiB
Svelte
152 lines
4.4 KiB
Svelte
<script lang="ts">
|
|
import GfmMarkdown from '$lib/components/GfmMarkdown.svelte'
|
|
import { Check, X } from 'lucide-svelte'
|
|
import { NOTE_COLORS, NOTE_TEXT_COLOR_OVERRIDE, NoteColor } from './noteColors'
|
|
import { stopPropagation, preventDefault } from 'svelte/legacy'
|
|
|
|
interface Props {
|
|
note: string
|
|
color?: string
|
|
collapsed?: boolean
|
|
editMode: boolean
|
|
onHeightChange: (height: number) => void
|
|
onNoteUpdate: (text: string) => void
|
|
}
|
|
|
|
let { note, color, collapsed = false, editMode, onHeightChange, onNoteUpdate }: Props = $props()
|
|
|
|
let editing = $state(false)
|
|
let editHeight = $state(0)
|
|
let textContent = $state('')
|
|
let textareaElement: HTMLTextAreaElement | undefined = $state(undefined)
|
|
let containerElement: HTMLDivElement | undefined = $state(undefined)
|
|
|
|
function autoResize(el: HTMLTextAreaElement) {
|
|
el.style.height = 'auto'
|
|
el.style.height = el.scrollHeight + 'px'
|
|
}
|
|
|
|
let noteColorConfig = $derived(
|
|
color
|
|
? (NOTE_COLORS[color as NoteColor] ?? NOTE_COLORS[NoteColor.BLUE])
|
|
: NOTE_COLORS[NoteColor.BLUE]
|
|
)
|
|
|
|
// Measure height and report to parent (skip while editing to avoid full graph rebuilds)
|
|
$effect(() => {
|
|
if (containerElement && !editing) {
|
|
const height = containerElement.clientHeight
|
|
onHeightChange(height)
|
|
}
|
|
})
|
|
|
|
// Also observe resize for dynamic content
|
|
$effect(() => {
|
|
if (!containerElement) return
|
|
const observer = new ResizeObserver((entries) => {
|
|
if (editing) return
|
|
for (const entry of entries) {
|
|
onHeightChange(entry.contentRect.height)
|
|
}
|
|
})
|
|
observer.observe(containerElement)
|
|
return () => {
|
|
observer.disconnect()
|
|
onHeightChange(0)
|
|
}
|
|
})
|
|
|
|
function handleDoubleClick() {
|
|
if (!editMode) return
|
|
editHeight = containerElement?.clientHeight ?? 0
|
|
editing = true
|
|
textContent = note
|
|
requestAnimationFrame(() => {
|
|
if (textareaElement) {
|
|
autoResize(textareaElement)
|
|
textareaElement.focus()
|
|
}
|
|
})
|
|
}
|
|
|
|
function handleSave() {
|
|
editing = false
|
|
if (textContent !== note) {
|
|
onNoteUpdate(textContent)
|
|
}
|
|
}
|
|
|
|
function handleCancel() {
|
|
editing = false
|
|
textContent = note
|
|
}
|
|
|
|
function handleKeydown(event: KeyboardEvent) {
|
|
event.stopPropagation()
|
|
if (event.key === 'Escape') {
|
|
handleSave()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
bind:this={containerElement}
|
|
class="nodrag nopan {collapsed ? 'mx-px' : 'w-full rounded-b-md'}"
|
|
>
|
|
<div class={collapsed ? 'relative' : 'w-full rounded-b-md relative'}>
|
|
{#if editing}
|
|
<div class="absolute top-0 right-1 flex gap-0.5 z-10">
|
|
<button
|
|
class="p-0.5 {noteColorConfig.text} opacity-60 hover:opacity-100 cursor-pointer"
|
|
onpointerdown={stopPropagation(preventDefault(handleSave))}
|
|
title="Save (Esc)"
|
|
>
|
|
<Check size={11} />
|
|
</button>
|
|
<button
|
|
class="p-0.5 {noteColorConfig.text} opacity-60 hover:opacity-100 cursor-pointer"
|
|
onpointerdown={stopPropagation(preventDefault(handleCancel))}
|
|
title="Cancel"
|
|
>
|
|
<X size={11} />
|
|
</button>
|
|
</div>
|
|
<textarea
|
|
bind:this={textareaElement}
|
|
bind:value={textContent}
|
|
class="w-full shadow-none resize-none !text-2xs overflow-y-auto border-none bg-transparent p-1 nodrag nopan nowheel focus:outline-none select-text {noteColorConfig.text}"
|
|
style:max-height="max({editHeight}px, 4lh)"
|
|
oninput={() => textareaElement && autoResize(textareaElement)}
|
|
placeholder="Write a note (markdown supported)"
|
|
onblur={handleSave}
|
|
onkeydown={handleKeydown}
|
|
onpointerdown={stopPropagation(() => {})}
|
|
spellcheck="false"
|
|
></textarea>
|
|
{:else if note}
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
class="w-full text-2xs break-words overflow-hidden p-2 select-text {noteColorConfig.text} {NOTE_TEXT_COLOR_OVERRIDE} {editMode
|
|
? 'cursor-pointer'
|
|
: ''}"
|
|
ondblclick={editMode ? stopPropagation(preventDefault(handleDoubleClick)) : undefined}
|
|
onpointerdown={editMode ? stopPropagation(() => {}) : undefined}
|
|
>
|
|
<GfmMarkdown md={note} noPadding />
|
|
</div>
|
|
{:else}
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
class="text-2xs italic opacity-60 p-2 {noteColorConfig.text} {editMode
|
|
? 'cursor-pointer'
|
|
: ''}"
|
|
ondblclick={editMode ? stopPropagation(preventDefault(handleDoubleClick)) : undefined}
|
|
onpointerdown={editMode ? stopPropagation(() => {}) : undefined}
|
|
>
|
|
Double click to edit the note
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|