{
	"$schema": "https://shadcn-svelte.com/schema/registry-item.json",
	"name": "sticky-note",
	"title": "Sticky Note",
	"type": "registry:ui",
	"description": "An editable coloured note for boards and canvases.",
	"dependencies": [
		"@lucide/svelte@^0.554.0"
	],
	"devDependencies": [
		"@lucide/svelte@^0.544.0",
		"tailwind-variants@^3.1.1"
	],
	"files": [
		{
			"content": "<script lang=\"ts\" module>\n\timport { tv, type VariantProps } from 'tailwind-variants';\n\n\texport const stickyNoteVariants = tv({\n\t\tbase: 'group relative flex flex-col gap-1 rounded-sm p-3 text-sm shadow-md transition-shadow',\n\t\tvariants: {\n\t\t\tcolor: {\n\t\t\t\tyellow: 'bg-amber-200 text-amber-950',\n\t\t\t\tpink: 'bg-pink-200 text-pink-950',\n\t\t\t\tblue: 'bg-sky-200 text-sky-950',\n\t\t\t\tgreen: 'bg-emerald-200 text-emerald-950',\n\t\t\t\tpurple: 'bg-violet-200 text-violet-950',\n\t\t\t\tgray: 'bg-neutral-200 text-neutral-900'\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tsm: 'min-h-24 w-40',\n\t\t\t\tmd: 'min-h-32 w-52',\n\t\t\t\tlg: 'min-h-44 w-64'\n\t\t\t}\n\t\t},\n\t\tdefaultVariants: { color: 'yellow', size: 'md' }\n\t});\n\n\texport type StickyNoteColor = NonNullable<VariantProps<typeof stickyNoteVariants>['color']>;\n\texport type StickyNoteSize = VariantProps<typeof stickyNoteVariants>['size'];\n\n\texport const STICKY_NOTE_COLORS: StickyNoteColor[] = [\n\t\t'yellow',\n\t\t'pink',\n\t\t'blue',\n\t\t'green',\n\t\t'purple',\n\t\t'gray'\n\t];\n\n\t/** Swatch fills for the palette. Kept separate so the classes stay statically visible to Tailwind. */\n\texport const STICKY_NOTE_SWATCH: Record<StickyNoteColor, string> = {\n\t\tyellow: 'bg-amber-200',\n\t\tpink: 'bg-pink-200',\n\t\tblue: 'bg-sky-200',\n\t\tgreen: 'bg-emerald-200',\n\t\tpurple: 'bg-violet-200',\n\t\tgray: 'bg-neutral-200'\n\t};\n</script>\n\n<script lang=\"ts\">\n\timport { cn } from '$UTILS$';\n\timport { tick, type Snippet } from 'svelte';\n\timport { X } from '@lucide/svelte';\n\n\tlet {\n\t\ttext = $bindable(''),\n\t\tcolor = $bindable<StickyNoteColor>('yellow'),\n\t\tsize = 'md',\n\t\tplaceholder = 'Write something…',\n\t\teditable = true,\n\t\tshowPalette = true,\n\t\tremovable = false,\n\t\trotate = 0,\n\t\tauthor,\n\t\tclass: className,\n\t\tonremove,\n\t\tonedit,\n\t\tchildren,\n\t\t...rest\n\t}: {\n\t\ttext?: string;\n\t\tcolor?: StickyNoteColor;\n\t\tsize?: StickyNoteSize;\n\t\tplaceholder?: string;\n\t\teditable?: boolean;\n\t\t/** Show the colour swatches on hover. */\n\t\tshowPalette?: boolean;\n\t\tremovable?: boolean;\n\t\t/** Degrees of tilt, for a pinned-to-the-wall look. */\n\t\trotate?: number;\n\t\tauthor?: string;\n\t\tclass?: string;\n\t\tonremove?: () => void;\n\t\tonedit?: (text: string) => void;\n\t\tchildren?: Snippet;\n\t\t[key: string]: unknown;\n\t} = $props();\n\n\tlet editing = $state(false);\n\tlet field = $state<HTMLTextAreaElement | null>(null);\n\n\tasync function startEditing() {\n\t\tif (!editable) return;\n\t\tediting = true;\n\t\tawait tick();\n\t\tfield?.focus();\n\t\tfield?.setSelectionRange(text.length, text.length);\n\t}\n\n\tfunction stopEditing() {\n\t\tediting = false;\n\t\tonedit?.(text);\n\t}\n</script>\n\n<div\n\tclass={cn(stickyNoteVariants({ color, size }), className)}\n\tstyle:transform={rotate ? `rotate(${rotate}deg)` : undefined}\n\t{...rest}\n>\n\t{#if removable}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-label=\"Remove note\"\n\t\t\tonclick={onremove}\n\t\t\tclass=\"absolute right-1 top-1 rounded-sm p-0.5 opacity-0 transition-opacity hover:bg-black/10 focus-visible:opacity-100 group-hover:opacity-100\"\n\t\t>\n\t\t\t<X class=\"size-3.5\" />\n\t\t</button>\n\t{/if}\n\n\t<div class=\"flex-1\">\n\t\t{#if children}\n\t\t\t{@render children()}\n\t\t{:else if editing}\n\t\t\t<textarea\n\t\t\t\tbind:this={field}\n\t\t\t\tbind:value={text}\n\t\t\t\tonblur={stopEditing}\n\t\t\t\tonkeydown={(e) => {\n\t\t\t\t\tif (e.key === 'Escape') {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tstopEditing();\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\t{placeholder}\n\t\t\t\tclass=\"size-full min-h-20 resize-none bg-transparent leading-snug outline-none placeholder:opacity-50\"\n\t\t\t></textarea>\n\t\t{:else}\n\t\t\t<!-- The whole face is the edit affordance, which is how a real sticky behaves. -->\n\t\t\t<div\n\t\t\t\trole={editable ? 'button' : undefined}\n\t\t\t\ttabindex={editable ? 0 : undefined}\n\t\t\t\tondblclick={startEditing}\n\t\t\t\tonkeydown={(e) => {\n\t\t\t\t\tif (editable && (e.key === 'Enter' || e.key === ' ')) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tstartEditing();\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\tclass={cn(\n\t\t\t\t\t'whitespace-pre-wrap break-words leading-snug outline-none',\n\t\t\t\t\t!text && 'opacity-50',\n\t\t\t\t\teditable && 'cursor-text'\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{text || placeholder}\n\t\t\t</div>\n\t\t{/if}\n\t</div>\n\n\t{#if author}\n\t\t<span class=\"text-[10px] font-medium opacity-60\">{author}</span>\n\t{/if}\n\n\t{#if showPalette}\n\t\t<!-- Keyed on :focus-visible rather than :focus-within so that clicking a\n\t\t     swatch does not pin the palette open until focus moves elsewhere,\n\t\t     while tabbing into it still reveals it. -->\n\t\t<div\n\t\t\tclass=\"pointer-events-none absolute -bottom-3 left-1/2 flex -translate-x-1/2 gap-1 rounded-full border bg-popover p-1 opacity-0 shadow-sm transition-opacity group-hover:pointer-events-auto group-hover:opacity-100 group-has-[:focus-visible]:pointer-events-auto group-has-[:focus-visible]:opacity-100\"\n\t\t>\n\t\t\t{#each STICKY_NOTE_COLORS as swatch}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label={`Colour ${swatch}`}\n\t\t\t\t\taria-pressed={color === swatch}\n\t\t\t\t\tonclick={() => (color = swatch)}\n\t\t\t\t\tclass={cn(\n\t\t\t\t\t\t'size-3.5 rounded-full border transition-transform',\n\t\t\t\t\t\tSTICKY_NOTE_SWATCH[swatch],\n\t\t\t\t\t\tcolor === swatch ? 'scale-125 border-foreground' : 'border-transparent'\n\t\t\t\t\t)}\n\t\t\t\t></button>\n\t\t\t{/each}\n\t\t</div>\n\t{/if}\n</div>\n",
			"type": "registry:ui",
			"target": "sticky-note/sticky-note.svelte"
		},
		{
			"content": "import StickyNote, {\r\n\tstickyNoteVariants,\r\n\tSTICKY_NOTE_COLORS,\r\n\tSTICKY_NOTE_SWATCH,\r\n\ttype StickyNoteColor,\r\n\ttype StickyNoteSize\r\n} from './sticky-note.svelte';\r\n\r\nexport {\r\n\tStickyNote,\r\n\tStickyNote as Root,\r\n\tstickyNoteVariants,\r\n\tSTICKY_NOTE_COLORS,\r\n\tSTICKY_NOTE_SWATCH,\r\n\ttype StickyNoteColor,\r\n\ttype StickyNoteSize\r\n};\r\n",
			"type": "registry:ui",
			"target": "sticky-note/index.ts"
		}
	]
}