Add markdown support

This commit is contained in:
Guilhem
2025-09-22 11:19:32 +01:00
parent 34435dc747
commit e82c336f16
3 changed files with 82 additions and 22 deletions
@@ -3,7 +3,12 @@
import { gfmPlugin } from 'svelte-exmarkdown/gfm'
import rehypeRaw from 'rehype-raw'
import { rehypeGithubAlerts } from 'rehype-github-alerts'
export let md: string
interface Props {
md: string
noPadding?: boolean
}
let { md, noPadding }: Props = $props()
const plugins: Plugin[] = [
gfmPlugin(),
{ rehypePlugin: [rehypeRaw] },
@@ -11,7 +16,7 @@
]
</script>
<div class="!prose-xs pgap">
<div class="!prose-xs {noPadding ? '' : 'pgap'}">
<Markdown {md} {plugins} />
</div>
@@ -29,7 +29,6 @@
}
function onPointerMove(event: PointerEvent) {
console.log('NoteTool: pointer move', event)
if (event.buttons !== 1) return
// Use page coordinates as reference
@@ -2,6 +2,8 @@
import { NodeResizer } from '@xyflow/svelte'
import { X } from 'lucide-svelte'
import { twMerge } from 'tailwind-merge'
import GfmMarkdown from '$lib/components/GfmMarkdown.svelte'
import { fade } from 'svelte/transition'
interface Props {
data: {
@@ -18,15 +20,14 @@
let { data, selected = false, dragging = false }: Props = $props()
let textareaElement: HTMLTextAreaElement | undefined = $state(undefined)
let editMode = $state(false)
let hovering = $state(false)
function handleTextChange(event: Event) {
const target = event.target as HTMLTextAreaElement
console.log('Text change detected', target.value)
// Call the update callback
data.onUpdate?.(target.value)
// Auto-resize textarea
target.style.height = 'auto'
target.style.height = target.scrollHeight + 'px'
}
function handleDelete(event: Event) {
@@ -36,14 +37,31 @@
data.onDelete?.()
}
// Auto-resize textarea when text changes
function handleDoubleClick(event: Event) {
console.log('Double click detected', { editMode, selected, dragging })
event.preventDefault()
event.stopPropagation()
editMode = true
// Focus the textarea after a short delay to ensure it's rendered
setTimeout(() => {
textareaElement?.focus()
}, 0)
}
function handleMouseEnter() {
hovering = true
}
function handleMouseLeave() {
hovering = false
}
// Exit edit mode when note is deselected
$effect(() => {
if (textareaElement) {
textareaElement.style.height = 'auto'
textareaElement.style.height = textareaElement.scrollHeight + 'px'
if (!selected) {
editMode = false
}
})
$inspect('dbg selected', selected)
</script>
<div
@@ -61,11 +79,13 @@
ondragend={() => {
dragging = false
}}
onmouseenter={handleMouseEnter}
onmouseleave={handleMouseLeave}
role="note"
>
<!-- Delete button -->
<button
class="opacity-0 group-hover:opacity-100 hover:opacity-100 absolute -top-6 right-0 w-5 h-5 bg-transparent text-secondary hover:bg-red-500 hover:border-red-500 hover:text-white border rounded-md flex items-center justify-center transition-colors z-10"
class="opacity-0 group-hover:opacity-100 hover:opacity-100 absolute -top-6 right-0 w-5 h-5 bg-transparent text-secondary hover:bg-red-500 hover:border-red-500 hover:text-white border rounded-md flex items-center justify-center transition-all duration-100 z-10"
onclick={handleDelete}
title="Delete note"
aria-label="Delete note"
@@ -73,16 +93,52 @@
<X size="12" />
</button>
<!-- Hover help text -->
{#if hovering}
{#if !editMode && data.text}
<div
in:fade={{ duration: 200 }}
class="absolute -top-5 h-5 left-0 text-xs text-gray-400 rounded-md z-10 transition-opacity duration-300"
>
Double click to edit
</div>
{:else}
<div
in:fade={{ duration: 200 }}
class="absolute -top-5 h-5 left-0 text-xs text-gray-400 rounded-md z-10 transition-opacity duration-300"
>GH Markdown</div
>
{/if}
{/if}
<!-- Note content -->
<div class="p-2 h-full">
<textarea
bind:this={textareaElement}
class="windmillapp w-full h-full !bg-transparent !border-none outline-none shadow-none focus:outline-none focus:ring-transparent resize-none text-xs font-mono overflow-hidden"
placeholder="Add your note here..."
value={data.text}
oninput={handleTextChange}
spellcheck="false"
></textarea>
<div class="p-2 h-full rounded-md">
{#if editMode}
<!-- Edit mode: show textarea -->
<textarea
bind:this={textareaElement}
class="windmillapp w-full h-full min-h-0 shadow-none resize-none text-xs overflow-y-auto border-none rounded-md bg-transparent transition-colors p-2"
placeholder="Add your note here... (Markdown supported)"
value={data.text ?? ''}
oninput={handleTextChange}
spellcheck="false"
></textarea>
{:else}
<!-- Render mode: show markdown or empty state -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="w-full h-full overflow-auto cursor-pointer flex items-start justify-center hover:bg-gray-400/10 rounded-md p-2"
ondblclick={handleDoubleClick}
>
{#if data.text}
<div class="w-full h-full text-xs rounded-md">
<GfmMarkdown md={data.text} noPadding />
</div>
{:else}
<div class="text-secondary text-xs italic"> Double-click to add a note </div>
{/if}
</div>
{/if}
</div>
<!-- Node resizer - only visible when selected -->