@neuronection/assistant-ui 0.19.0 → 0.21.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/dictation/DictationButton.tsx","../src/components/dictation/useDictation.ts"],"names":["useRef","useEffect"],"mappings":"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","file":"chunk-KAC2DOLH.js","sourcesContent":["import * as React from 'react'\nimport { Loader2, Mic, Square, X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nimport type { DictationError, DictationStatus } from './useDictation'\n\nconst BAR_WEIGHTS = [0.45, 0.62, 0.8, 0.92, 1.05]\n\nexport interface DictationButtonProps {\n status: DictationStatus\n onStart: () => void\n /** Accessible name / tooltip. English default: 'Dictate'. */\n label?: string\n recordingLabel?: string\n className?: string\n}\n\nexport function DictationButton({\n status,\n onStart,\n label = 'Dictate',\n recordingLabel,\n className,\n}: DictationButtonProps) {\n return (\n <button\n type=\"button\"\n title={label}\n aria-label={label}\n aria-pressed={status === 'recording' ? true : status === 'transcribing' ? undefined : false}\n disabled={status === 'transcribing'}\n data-as=\"dictation-button\"\n className={cn(\n 'rounded p-1.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)]',\n status === 'recording'\n ? 'animate-pulse bg-[var(--as-danger)]/10 text-[var(--as-danger)]'\n : 'text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]',\n className,\n )}\n onClick={onStart}\n >\n <Mic className=\"size-4\" aria-hidden />\n <span className=\"sr-only\">{recordingLabel ?? label}</span>\n </button>\n )\n}\n\nfunction LevelBars({\n levelRef,\n active,\n}: {\n levelRef: React.RefObject<number>\n active: boolean\n}) {\n const barsRef = React.useRef<Array<HTMLSpanElement | null>>([])\n React.useEffect(() => {\n if (!active) {\n return\n }\n let frame = requestAnimationFrame(function tick() {\n const level = Math.min(1, levelRef.current ?? 0)\n barsRef.current.forEach((bar, index) => {\n if (bar !== null) {\n const weight = BAR_WEIGHTS[index] ?? 1\n const height = Math.max(0.15, Math.min(1, level * weight))\n bar.style.transform = `scaleY(${height})`\n }\n })\n frame = requestAnimationFrame(tick)\n })\n return () => cancelAnimationFrame(frame)\n }, [active, levelRef])\n return (\n <span className=\"flex h-4 items-end gap-0.5\" aria-hidden>\n {BAR_WEIGHTS.map((_, index) => (\n <span\n key={index}\n ref={(element) => {\n barsRef.current[index] = element\n }}\n className=\"h-4 w-1 origin-bottom rounded-full bg-[var(--as-danger)] opacity-40\"\n />\n ))}\n </span>\n )\n}\n\nexport interface DictationStripLabels {\n recording?: string\n transcribing?: string\n stop?: string\n cancel?: string\n dismissError?: string\n unsupported?: string\n denied?: string\n unassigned?: string\n /** `{detail}` is interpolated with the transport error message. */\n failed?: string\n}\n\nconst DEFAULT_STRIP_LABELS: Required<DictationStripLabels> = {\n recording: 'Recording…',\n transcribing: 'Transcribing…',\n stop: 'Stop',\n cancel: 'Cancel',\n dismissError: 'Dismiss',\n unsupported: 'Speech input is not supported in this browser.',\n denied: 'Microphone access was denied.',\n unassigned: 'No speech-to-text model is assigned.',\n failed: 'Transcription failed. {detail}',\n}\n\nexport interface DictationStripProps {\n status: DictationStatus\n seconds: number\n levelRef: React.RefObject<number>\n error: DictationError | null\n labels?: Partial<DictationStripLabels>\n onStop: () => void\n onCancel: () => void\n onDismissError: () => void\n className?: string\n}\n\nexport function DictationStrip({\n status,\n seconds,\n levelRef,\n error,\n labels,\n onStop,\n onCancel,\n onDismissError,\n className,\n}: DictationStripProps) {\n const merged = { ...DEFAULT_STRIP_LABELS, ...labels }\n const formatTime = (total: number) => {\n const minutes = Math.floor(total / 60)\n const padded = String(total % 60).padStart(2, '0')\n return `${String(minutes).padStart(2, '0')}:${padded}`\n }\n const errorText =\n error === null\n ? ''\n : error.kind === 'unsupported'\n ? merged.unsupported\n : error.kind === 'denied'\n ? merged.denied\n : error.kind === 'unassigned'\n ? merged.unassigned\n : merged.failed.replace('{detail}', error.detail ?? '')\n if (error !== null) {\n return (\n <div\n data-as=\"dictation-strip\"\n className={cn(\n 'flex items-center gap-2 rounded-md border border-dashed border-[var(--as-warning)] px-2.5 py-1.5 text-xs text-[var(--as-warning)]',\n className,\n )}\n role=\"alert\"\n >\n <span className=\"min-w-0 flex-1 break-words\">{errorText}</span>\n <button\n type=\"button\"\n aria-label={merged.dismissError}\n title={merged.dismissError}\n className=\"rounded-full p-0.5 hover:opacity-70\"\n onClick={onDismissError}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n }\n if (status === 'idle') {\n return null\n }\n return (\n <div\n data-as=\"dictation-strip\"\n className={cn(\n 'flex items-center gap-2 rounded-md border border-[var(--as-border)] bg-[var(--as-surface)] px-2.5 py-1.5 text-xs',\n className,\n )}\n role=\"status\"\n aria-label={merged.recording}\n >\n {status === 'recording' ? (\n <>\n <span\n className=\"size-2 shrink-0 animate-pulse rounded-full bg-[var(--as-danger)]\"\n aria-hidden\n />\n <span className=\"tabular-nums font-medium text-[var(--as-fg)]\">\n {formatTime(seconds)}\n </span>\n <LevelBars levelRef={levelRef} active />\n <span className=\"min-w-0 flex-1 truncate text-[var(--as-muted-fg)]\">\n {merged.recording}\n </span>\n <button\n type=\"button\"\n aria-label={merged.cancel}\n title={merged.cancel}\n className=\"rounded p-1 text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]\"\n onClick={onCancel}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n title={merged.stop}\n aria-label={merged.stop}\n className=\"flex items-center gap-1 rounded bg-[var(--as-danger)] px-2 py-1 font-medium\"\n onClick={onStop}\n >\n <Square className=\"size-3\" aria-hidden />\n {merged.stop}\n </button>\n </>\n ) : (\n <>\n <Loader2\n className=\"size-3.5 shrink-0 animate-spin text-[var(--as-muted-fg)]\"\n aria-hidden\n />\n <span className=\"min-w-0 flex-1 text-[var(--as-muted-fg)]\">\n {merged.transcribing}\n </span>\n </>\n )}\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nexport type DictationStatus = 'idle' | 'recording' | 'transcribing'\n\nexport interface DictationError {\n kind: 'unsupported' | 'denied' | 'unassigned' | 'failed'\n detail?: string\n}\n\nexport interface DictationResult {\n text: string\n}\n\nexport interface UseDictationOptions {\n /** App-owned transport: upload the blob, resolve with the transcript. */\n transcribe: (audio: Blob) => Promise<DictationResult>\n /** Map a transport failure to a structured error (e.g. 409 → 'unassigned'). */\n classifyError?: (error: unknown) => DictationError\n /** Called with the transcript on success. */\n onResult?: (text: string) => void\n}\n\nconst PREFERRED_MIME_TYPES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/ogg;codecs=opus',\n 'audio/mp4',\n]\n\nconst MAX_LEVEL = 1\nconst LEVEL_BOOST = 4\nconst LEVEL_DECAY = 0.85\n\nfunction pickMimeType(): string | null {\n if (typeof MediaRecorder === 'undefined') {\n return null\n }\n for (const mimeType of PREFERRED_MIME_TYPES) {\n if (MediaRecorder.isTypeSupported(mimeType)) {\n return mimeType\n }\n }\n return null\n}\n\nexport function useDictation(options: UseDictationOptions) {\n const [status, setStatus] = useState<DictationStatus>('idle')\n const [seconds, setSeconds] = useState(0)\n const [error, setError] = useState<DictationError | null>(null)\n\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const recorderRef = useRef<MediaRecorder | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n const chunksRef = useRef<BlobPart[]>([])\n const audioContextRef = useRef<AudioContext | null>(null)\n const rafRef = useRef<number | null>(null)\n const timerRef = useRef<number | null>(null)\n const levelRef = useRef(0)\n\n const teardown = useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n if (timerRef.current !== null) {\n window.clearInterval(timerRef.current)\n timerRef.current = null\n }\n audioContextRef.current?.close().catch(() => undefined)\n audioContextRef.current = null\n streamRef.current?.getTracks().forEach((track) => track.stop())\n streamRef.current = null\n recorderRef.current = null\n levelRef.current = 0\n }, [])\n\n const startMeter = useCallback((stream: MediaStream) => {\n if (typeof AudioContext === 'undefined') {\n return\n }\n const context = new AudioContext()\n audioContextRef.current = context\n const analyser = context.createAnalyser()\n analyser.fftSize = 512\n context.createMediaStreamSource(stream).connect(analyser)\n const buffer = new Uint8Array(analyser.fftSize)\n const tick = () => {\n analyser.getByteTimeDomainData(buffer)\n let sum = 0\n for (const value of buffer) {\n const centered = (value - 128) / 128\n sum += centered * centered\n }\n const rms = Math.sqrt(sum / buffer.length)\n levelRef.current = Math.min(\n MAX_LEVEL,\n Math.max(rms * LEVEL_BOOST, levelRef.current * LEVEL_DECAY),\n )\n rafRef.current = requestAnimationFrame(tick)\n }\n rafRef.current = requestAnimationFrame(tick)\n }, [])\n\n const start = useCallback(async () => {\n if (status !== 'idle') {\n return\n }\n setError(null)\n if (\n typeof navigator === 'undefined' ||\n !navigator.mediaDevices?.getUserMedia ||\n typeof MediaRecorder === 'undefined'\n ) {\n setError({ kind: 'unsupported' })\n return\n }\n let stream: MediaStream\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n } catch (requestError) {\n const name = requestError instanceof DOMException ? requestError.name : ''\n setError(\n name === 'NotAllowedError' || name === 'SecurityError' || name === 'NotFoundError'\n ? { kind: 'denied' }\n : {\n kind: 'failed',\n detail:\n requestError instanceof Error\n ? requestError.message\n : String(requestError),\n },\n )\n return\n }\n const mimeType = pickMimeType()\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined)\n const chunks: BlobPart[] = []\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunks.push(event.data)\n }\n }\n recorderRef.current = recorder\n streamRef.current = stream\n chunksRef.current = chunks\n recorder.start(250)\n setSeconds(0)\n setStatus('recording')\n startMeter(stream)\n timerRef.current = window.setInterval(() => {\n setSeconds((current) => current + 1)\n }, 1000)\n }, [startMeter, status])\n\n const cancel = useCallback(() => {\n const recorder = recorderRef.current\n if (recorder !== null && recorder.state !== 'inactive') {\n recorder.onstop = null\n recorder.stop()\n }\n teardown()\n setSeconds(0)\n setStatus('idle')\n }, [teardown])\n\n const stop = useCallback(async () => {\n const recorder = recorderRef.current\n if (recorder === null || recorder.state === 'inactive') {\n return\n }\n const mimeType = recorder.mimeType || 'audio/webm'\n const chunks = chunksRef.current\n const stopped = new Promise<void>((resolve) => {\n recorder.onstop = () => resolve()\n })\n recorder.stop()\n await stopped\n teardown()\n setSeconds(0)\n setStatus('transcribing')\n try {\n const blob = new Blob(chunks, { type: mimeType })\n const result = await optionsRef.current.transcribe(blob)\n setStatus('idle')\n optionsRef.current.onResult?.(result.text)\n } catch (transcribeError) {\n const classified =\n optionsRef.current.classifyError?.(transcribeError) ??\n ({\n kind: 'failed',\n detail:\n transcribeError instanceof Error\n ? transcribeError.message\n : String(transcribeError),\n } satisfies DictationError)\n setError(classified)\n setStatus('idle')\n }\n }, [teardown])\n\n const dismissError = useCallback(() => {\n setError(null)\n }, [])\n\n useEffect(\n () => () => {\n const recorder = recorderRef.current\n if (recorder !== null && recorder.state !== 'inactive') {\n recorder.onstop = null\n recorder.stop()\n }\n teardown()\n },\n [teardown],\n )\n\n return { status, seconds, error, levelRef, start, stop, cancel, dismissError }\n}\n"]}
@@ -30,7 +30,7 @@ var SettingsShell = React.forwardRef(
30
30
  ) : null,
31
31
  /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-bold text-[var(--as-fg)]", children: header.title })
32
32
  ] }) : null,
33
- nav.map(({ id, label, description, icon: Icon }) => {
33
+ nav.map(({ id, label, description, icon: Icon, trailing }) => {
34
34
  const isActive = id === active;
35
35
  return /* @__PURE__ */ jsxs(
36
36
  "button",
@@ -53,7 +53,8 @@ var SettingsShell = React.forwardRef(
53
53
  /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col", children: [
54
54
  /* @__PURE__ */ jsx("span", { className: "truncate", children: label }),
55
55
  description ? /* @__PURE__ */ jsx("span", { className: "text-[11px] font-normal text-[var(--as-muted-fg)]", children: description }) : null
56
- ] })
56
+ ] }),
57
+ trailing ? /* @__PURE__ */ jsx("span", { className: "ml-auto flex items-center self-center pl-2", children: trailing }) : null
57
58
  ]
58
59
  },
59
60
  id
@@ -70,5 +71,5 @@ var SettingsShell = React.forwardRef(
70
71
  );
71
72
 
72
73
  export { SettingsShell };
73
- //# sourceMappingURL=chunk-AHLNXCP2.js.map
74
- //# sourceMappingURL=chunk-AHLNXCP2.js.map
74
+ //# sourceMappingURL=chunk-UJVNCZ5Z.js.map
75
+ //# sourceMappingURL=chunk-UJVNCZ5Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/settings-shell/SettingsShell.tsx"],"names":["SettingsShell"],"mappings":";;;;AAuBO,IAAM,aAAA,GAAsB,KAAA,CAAA,UAAA;AAAA,EACjC,SAASA,cAAAA,CACP,EAAE,GAAA,EAAK,MAAA,EAAQ,UAAA,EAAY,MAAA,EAAQ,QAAA,EAAU,SAAA,EAAW,YAAA,EAAa,EACrE,GAAA,EACA;AACA,IAAA,MAAM,aAAa,MAAA,EAAQ,IAAA;AAC3B,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAQ,gBAAA;AAAA,QACR,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,QAEhE,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EAAgB,YAAA,EAAW,mBAAA,EACxC,QAAA,kBAAA,IAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,gIAAA;AAAA,gBACA;AAAA,eACF;AAAA,cAEC,QAAA,EAAA;AAAA,gBAAA,MAAA,mBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6EAAA,EACZ,QAAA,EAAA;AAAA,kBAAA,UAAA,mBACC,GAAA;AAAA,oBAAC,UAAA;AAAA,oBAAA;AAAA,sBACC,SAAA,EAAU,0CAAA;AAAA,sBACV,aAAA,EAAW;AAAA;AAAA,mBACb,GACE,IAAA;AAAA,kCACJ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gDAAA,EACb,iBAAO,KAAA,EACV;AAAA,iBAAA,EACF,CAAA,GACE,IAAA;AAAA,gBACH,GAAA,CAAI,GAAA,CAAI,CAAC,EAAE,EAAA,EAAI,OAAO,WAAA,EAAa,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS,KAAM;AAC7D,kBAAA,MAAM,WAAW,EAAA,KAAO,MAAA;AACxB,kBAAA,uBACE,IAAA;AAAA,oBAAC,QAAA;AAAA,oBAAA;AAAA,sBAEC,IAAA,EAAK,QAAA;AAAA,sBACL,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,sBAClC,OAAA,EAAS,MAAM,UAAA,CAAW,EAAE,CAAA;AAAA,sBAC5B,SAAA,EAAW,EAAA;AAAA,wBACT,uNAAA;AAAA,wBACA,WACI,8FAAA,GACA;AAAA,uBACN;AAAA,sBAEC,QAAA,EAAA;AAAA,wBAAA,IAAA,mBACC,GAAA;AAAA,0BAAC,IAAA;AAAA,0BAAA;AAAA,4BACC,SAAA,EAAU,6BAAA;AAAA,4BACV,aAAA,EAAW;AAAA;AAAA,yBACb,GACE,IAAA;AAAA,wCACJ,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EACd,QAAA,EAAA;AAAA,0CAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACjC,8BACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EACb,uBACH,CAAA,GACE;AAAA,yBAAA,EACN,CAAA;AAAA,wBACC,2BACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4CAAA,EACb,oBACH,CAAA,GACE;AAAA;AAAA,qBAAA;AAAA,oBA7BC;AAAA,mBA8BP;AAAA,gBAEJ,CAAC;AAAA;AAAA;AAAA,WACH,EACF,CAAA;AAAA,0BACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAyB,QAAA,EAAS;AAAA;AAAA;AAAA,KACnD;AAAA,EAEJ;AACF","file":"chunk-UJVNCZ5Z.js","sourcesContent":["import * as React from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface SettingsNavItem {\n id: string\n label: string\n description?: string\n icon?: LucideIcon\n /** Optional trailing node (status dot, count, badge) at the row edge. */\n trailing?: React.ReactNode\n}\n\nexport interface SettingsShellProps {\n nav: SettingsNavItem[]\n active: string\n onNavigate: (id: string) => void\n header?: { icon?: LucideIcon; title: string }\n children: React.ReactNode\n className?: string\n navClassName?: string\n}\n\nexport const SettingsShell = React.forwardRef<HTMLDivElement, SettingsShellProps>(\n function SettingsShell(\n { nav, active, onNavigate, header, children, className, navClassName },\n ref,\n ) {\n const HeaderIcon = header?.icon\n return (\n <div\n ref={ref}\n data-as=\"settings-shell\"\n className={cn('grid grid-cols-1 gap-8 lg:grid-cols-4', className)}\n >\n <nav className=\"lg:col-span-1\" aria-label=\"Settings sections\">\n <div\n className={cn(\n 'space-y-1 rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] p-3 lg:sticky lg:top-24',\n navClassName,\n )}\n >\n {header ? (\n <div className=\"mb-2 flex items-center gap-2.5 border-b border-[var(--as-border)] px-3 py-2\">\n {HeaderIcon ? (\n <HeaderIcon\n className=\"size-5 shrink-0 text-[var(--as-primary)]\"\n aria-hidden\n />\n ) : null}\n <span className=\"truncate text-sm font-bold text-[var(--as-fg)]\">\n {header.title}\n </span>\n </div>\n ) : null}\n {nav.map(({ id, label, description, icon: Icon, trailing }) => {\n const isActive = id === active\n return (\n <button\n key={id}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n onClick={() => onNavigate(id)}\n className={cn(\n 'flex w-full cursor-pointer items-start rounded-[var(--as-radius)] px-3 py-2.5 text-left text-sm transition-colors focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]',\n isActive\n ? 'bg-[color-mix(in_srgb,var(--as-primary)_12%,transparent)] font-bold text-[var(--as-primary)]'\n : 'font-medium text-[var(--as-fg)] hover:bg-[var(--as-muted)]',\n )}\n >\n {Icon ? (\n <Icon\n className=\"mr-3 mt-0.5 size-4 shrink-0\"\n aria-hidden\n />\n ) : null}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate\">{label}</span>\n {description ? (\n <span className=\"text-[11px] font-normal text-[var(--as-muted-fg)]\">\n {description}\n </span>\n ) : null}\n </span>\n {trailing ? (\n <span className=\"ml-auto flex items-center self-center pl-2\">\n {trailing}\n </span>\n ) : null}\n </button>\n )\n })}\n </div>\n </nav>\n <div className=\"min-w-0 lg:col-span-3\">{children}</div>\n </div>\n )\n },\n)\n"]}
@@ -0,0 +1,253 @@
1
+ import { cn } from './chunk-BLJWR4ZV.js';
2
+ import * as React from 'react';
3
+ import { useEditor, EditorContent } from '@tiptap/react';
4
+ import StarterKit from '@tiptap/starter-kit';
5
+ import { Redo2, Undo2, Quote, ListOrdered, List, Heading2, Code, Strikethrough, Italic, Bold } from 'lucide-react';
6
+ import { Markdown } from 'tiptap-markdown';
7
+ import { jsxs, jsx } from 'react/jsx-runtime';
8
+
9
+ var DEFAULT_TOOLBAR = [
10
+ "history",
11
+ "heading",
12
+ "format",
13
+ "list",
14
+ "quote"
15
+ ];
16
+ var DEFAULT_LABELS = {
17
+ toolbar: "Formatting",
18
+ bold: "Bold",
19
+ italic: "Italic",
20
+ strike: "Strikethrough",
21
+ code: "Code",
22
+ heading: "Heading",
23
+ bulletList: "Bulleted list",
24
+ orderedList: "Numbered list",
25
+ blockquote: "Quote",
26
+ undo: "Undo",
27
+ redo: "Redo"
28
+ };
29
+ var DEFAULT_ICONS = {
30
+ bold: Bold,
31
+ italic: Italic,
32
+ strike: Strikethrough,
33
+ code: Code,
34
+ heading: Heading2,
35
+ bulletList: List,
36
+ orderedList: ListOrdered,
37
+ blockquote: Quote,
38
+ undo: Undo2,
39
+ redo: Redo2
40
+ };
41
+ function getMarkdown(editor) {
42
+ const storage = editor.storage;
43
+ return storage.markdown?.getMarkdown?.() ?? "";
44
+ }
45
+ function applyExternalValue(editor, markdown) {
46
+ const hadFocus = editor.isFocused;
47
+ const caret = editor.state.selection.head;
48
+ editor.commands.setContent(markdown, { emitUpdate: false });
49
+ if (hadFocus) {
50
+ editor.commands.setTextSelection(Math.min(caret, editor.state.doc.content.size));
51
+ editor.commands.focus();
52
+ }
53
+ }
54
+ var RichTextEditor = React.forwardRef(
55
+ function RichTextEditor2({
56
+ value,
57
+ onValueChange,
58
+ ariaLabel,
59
+ disabled = false,
60
+ toolbar = DEFAULT_TOOLBAR,
61
+ toolbarExtra,
62
+ extensions,
63
+ parseMarkdown,
64
+ serializeMarkdown,
65
+ labels,
66
+ icons,
67
+ className
68
+ }, ref) {
69
+ const mergedLabels = { ...DEFAULT_LABELS, ...labels };
70
+ const mergedIcons = { ...DEFAULT_ICONS, ...icons };
71
+ const lastEmittedRef = React.useRef(value);
72
+ const onValueChangeRef = React.useRef(onValueChange);
73
+ onValueChangeRef.current = onValueChange;
74
+ const hooksRef = React.useRef({ parseMarkdown, serializeMarkdown });
75
+ hooksRef.current = { parseMarkdown, serializeMarkdown };
76
+ const [, bump] = React.useReducer((count) => count + 1, 0);
77
+ const toDocument = React.useCallback(
78
+ (markdown) => parseMarkdown ? parseMarkdown(markdown) : markdown,
79
+ [parseMarkdown]
80
+ );
81
+ const toApp = React.useCallback(
82
+ (markdown) => serializeMarkdown ? serializeMarkdown(markdown) : markdown,
83
+ [serializeMarkdown]
84
+ );
85
+ const editor = useEditor(
86
+ {
87
+ extensions: React.useMemo(
88
+ () => [StarterKit, Markdown, ...extensions ?? []],
89
+ [extensions]
90
+ ),
91
+ content: toDocument(value),
92
+ editable: !disabled,
93
+ immediatelyRender: false,
94
+ editorProps: {
95
+ attributes: {
96
+ "aria-label": ariaLabel,
97
+ class: "as-rich-text-editor__content min-h-24 w-full bg-transparent px-3 py-2 text-sm text-[var(--as-fg)] outline-none"
98
+ }
99
+ },
100
+ onUpdate: ({ editor: current }) => {
101
+ const markdown = toApp(getMarkdown(current));
102
+ lastEmittedRef.current = markdown;
103
+ onValueChangeRef.current(markdown);
104
+ }
105
+ }
106
+ );
107
+ const isMounted = editor !== null;
108
+ React.useEffect(() => {
109
+ if (!isMounted || editor === null) {
110
+ return;
111
+ }
112
+ const handler = () => bump();
113
+ editor.on("transaction", handler);
114
+ editor.on("update", handler);
115
+ return () => {
116
+ editor.off("transaction", handler);
117
+ editor.off("update", handler);
118
+ };
119
+ }, [editor, isMounted]);
120
+ React.useEffect(() => {
121
+ if (editor === null || editor.isDestroyed) {
122
+ return;
123
+ }
124
+ editor.setEditable(!disabled);
125
+ }, [editor, disabled]);
126
+ React.useEffect(() => {
127
+ if (editor === null || editor.isDestroyed) {
128
+ return;
129
+ }
130
+ if (value === lastEmittedRef.current) {
131
+ return;
132
+ }
133
+ const current = toApp(getMarkdown(editor));
134
+ if (value === current) {
135
+ lastEmittedRef.current = value;
136
+ return;
137
+ }
138
+ applyExternalValue(editor, toDocument(value));
139
+ lastEmittedRef.current = value;
140
+ }, [editor, value, toApp, toDocument]);
141
+ const groups = toolbar === false ? [] : toolbar ?? DEFAULT_TOOLBAR;
142
+ const renderButton = (key, group, onClick, active) => {
143
+ const Icon = mergedIcons[key];
144
+ return /* @__PURE__ */ jsx(
145
+ "button",
146
+ {
147
+ type: "button",
148
+ "aria-label": mergedLabels[key],
149
+ "aria-pressed": active,
150
+ title: mergedLabels[key],
151
+ disabled,
152
+ className: cn(
153
+ "rounded p-1.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50",
154
+ active && "bg-[var(--as-surface-active)] text-[var(--as-fg)]"
155
+ ),
156
+ onClick,
157
+ children: /* @__PURE__ */ jsx(Icon, { className: "size-4", "aria-hidden": true })
158
+ },
159
+ `${group}-${key}`
160
+ );
161
+ };
162
+ return /* @__PURE__ */ jsxs(
163
+ "div",
164
+ {
165
+ ref,
166
+ "data-as": "rich-text-editor",
167
+ className: cn(
168
+ "w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] focus-within:border-[var(--as-focus-ring)]",
169
+ disabled && "opacity-50",
170
+ className
171
+ ),
172
+ children: [
173
+ groups.length > 0 || toolbarExtra ? /* @__PURE__ */ jsxs(
174
+ "div",
175
+ {
176
+ role: "toolbar",
177
+ "aria-label": mergedLabels.toolbar,
178
+ className: "flex flex-wrap items-center gap-0.5 border-b border-[var(--as-border)] p-1",
179
+ children: [
180
+ groups.includes("history") ? renderButton(
181
+ "undo",
182
+ "history",
183
+ () => editor?.chain().focus().undo().run(),
184
+ false
185
+ ) : null,
186
+ groups.includes("history") ? renderButton(
187
+ "redo",
188
+ "history",
189
+ () => editor?.chain().focus().redo().run(),
190
+ false
191
+ ) : null,
192
+ groups.includes("heading") ? renderButton(
193
+ "heading",
194
+ "heading",
195
+ () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
196
+ editor?.isActive("heading", { level: 2 }) === true
197
+ ) : null,
198
+ groups.includes("format") ? renderButton(
199
+ "bold",
200
+ "format",
201
+ () => editor?.chain().focus().toggleBold().run(),
202
+ editor?.isActive("bold") === true
203
+ ) : null,
204
+ groups.includes("format") ? renderButton(
205
+ "italic",
206
+ "format",
207
+ () => editor?.chain().focus().toggleItalic().run(),
208
+ editor?.isActive("italic") === true
209
+ ) : null,
210
+ groups.includes("format") ? renderButton(
211
+ "strike",
212
+ "format",
213
+ () => editor?.chain().focus().toggleStrike().run(),
214
+ editor?.isActive("strike") === true
215
+ ) : null,
216
+ groups.includes("format") ? renderButton(
217
+ "code",
218
+ "format",
219
+ () => editor?.chain().focus().toggleCode().run(),
220
+ editor?.isActive("code") === true
221
+ ) : null,
222
+ groups.includes("list") ? renderButton(
223
+ "bulletList",
224
+ "list",
225
+ () => editor?.chain().focus().toggleBulletList().run(),
226
+ editor?.isActive("bulletList") === true
227
+ ) : null,
228
+ groups.includes("list") ? renderButton(
229
+ "orderedList",
230
+ "list",
231
+ () => editor?.chain().focus().toggleOrderedList().run(),
232
+ editor?.isActive("orderedList") === true
233
+ ) : null,
234
+ groups.includes("quote") ? renderButton(
235
+ "blockquote",
236
+ "quote",
237
+ () => editor?.chain().focus().toggleBlockquote().run(),
238
+ editor?.isActive("blockquote") === true
239
+ ) : null,
240
+ typeof toolbarExtra === "function" ? toolbarExtra(editor) : toolbarExtra
241
+ ]
242
+ }
243
+ ) : null,
244
+ /* @__PURE__ */ jsx(EditorContent, { editor })
245
+ ]
246
+ }
247
+ );
248
+ }
249
+ );
250
+
251
+ export { RichTextEditor };
252
+ //# sourceMappingURL=chunk-XUDCCQRN.js.map
253
+ //# sourceMappingURL=chunk-XUDCCQRN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/rich-text-editor/RichTextEditor.tsx"],"names":["RichTextEditor"],"mappings":"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","file":"chunk-XUDCCQRN.js","sourcesContent":["import * as React from 'react'\nimport { Editor, EditorContent, useEditor, type Extensions } from '@tiptap/react'\nimport StarterKit from '@tiptap/starter-kit'\nimport {\n Bold,\n Code,\n Heading2,\n Italic,\n List,\n ListOrdered,\n Quote,\n Redo2,\n Strikethrough,\n Undo2,\n type LucideIcon,\n} from 'lucide-react'\nimport { Markdown } from 'tiptap-markdown'\n\nimport { cn } from '../../lib/utils'\n\nexport type RichTextToolbarGroup = 'history' | 'heading' | 'format' | 'list' | 'quote'\n\nconst DEFAULT_TOOLBAR: RichTextToolbarGroup[] = [\n 'history',\n 'heading',\n 'format',\n 'list',\n 'quote',\n]\n\nexport interface RichTextEditorLabels {\n toolbar?: string\n bold?: string\n italic?: string\n strike?: string\n code?: string\n heading?: string\n bulletList?: string\n orderedList?: string\n blockquote?: string\n undo?: string\n redo?: string\n}\n\nexport interface RichTextEditorIcons {\n bold?: LucideIcon\n italic?: LucideIcon\n strike?: LucideIcon\n code?: LucideIcon\n heading?: LucideIcon\n bulletList?: LucideIcon\n orderedList?: LucideIcon\n blockquote?: LucideIcon\n undo?: LucideIcon\n redo?: LucideIcon\n}\n\nconst DEFAULT_LABELS: Required<RichTextEditorLabels> = {\n toolbar: 'Formatting',\n bold: 'Bold',\n italic: 'Italic',\n strike: 'Strikethrough',\n code: 'Code',\n heading: 'Heading',\n bulletList: 'Bulleted list',\n orderedList: 'Numbered list',\n blockquote: 'Quote',\n undo: 'Undo',\n redo: 'Redo',\n}\n\nconst DEFAULT_ICONS: Required<RichTextEditorIcons> = {\n bold: Bold,\n italic: Italic,\n strike: Strikethrough,\n code: Code,\n heading: Heading2,\n bulletList: List,\n orderedList: ListOrdered,\n blockquote: Quote,\n undo: Undo2,\n redo: Redo2,\n}\n\nexport interface RichTextEditorProps {\n value: string\n onValueChange: (markdown: string) => void\n ariaLabel: string\n disabled?: boolean\n toolbar?: RichTextToolbarGroup[] | false\n /** App-owned controls at the end of the toolbar; render-prop form receives the editor. */\n toolbarExtra?: React.ReactNode | ((editor: Editor | null) => React.ReactNode)\n /** App extensions merged after the starter kit (math, tables, custom nodes…). */\n extensions?: Extensions\n /** Map incoming app-domain markdown before it reaches the document. */\n parseMarkdown?: (markdown: string) => string\n /** Map the serialized document before it is emitted / echo-compared. */\n serializeMarkdown?: (markdown: string) => string\n labels?: Partial<RichTextEditorLabels>\n icons?: Partial<RichTextEditorIcons>\n className?: string\n}\n\nfunction getMarkdown(editor: Editor): string {\n const storage = editor.storage as { markdown?: { getMarkdown?: () => string } }\n return storage.markdown?.getMarkdown?.() ?? ''\n}\n\nfunction applyExternalValue(editor: Editor, markdown: string): void {\n const hadFocus = editor.isFocused\n const caret = editor.state.selection.head\n editor.commands.setContent(markdown, { emitUpdate: false })\n if (hadFocus) {\n editor.commands.setTextSelection(Math.min(caret, editor.state.doc.content.size))\n editor.commands.focus()\n }\n}\n\nexport const RichTextEditor = React.forwardRef<HTMLDivElement, RichTextEditorProps>(\n function RichTextEditor(\n {\n value,\n onValueChange,\n ariaLabel,\n disabled = false,\n toolbar = DEFAULT_TOOLBAR,\n toolbarExtra,\n extensions,\n parseMarkdown,\n serializeMarkdown,\n labels,\n icons,\n className,\n },\n ref,\n ) {\n const mergedLabels = { ...DEFAULT_LABELS, ...labels }\n const mergedIcons = { ...DEFAULT_ICONS, ...icons }\n const lastEmittedRef = React.useRef<string>(value)\n const onValueChangeRef = React.useRef(onValueChange)\n onValueChangeRef.current = onValueChange\n const hooksRef = React.useRef({ parseMarkdown, serializeMarkdown })\n hooksRef.current = { parseMarkdown, serializeMarkdown }\n const [, bump] = React.useReducer((count: number) => count + 1, 0)\n\n const toDocument = React.useCallback(\n (markdown: string) => (parseMarkdown ? parseMarkdown(markdown) : markdown),\n [parseMarkdown],\n )\n const toApp = React.useCallback(\n (markdown: string) => (serializeMarkdown ? serializeMarkdown(markdown) : markdown),\n [serializeMarkdown],\n )\n\n const editor = useEditor(\n {\n extensions: React.useMemo(\n () => [StarterKit, Markdown, ...(extensions ?? [])],\n [extensions],\n ),\n content: toDocument(value),\n editable: !disabled,\n immediatelyRender: false,\n editorProps: {\n attributes: {\n 'aria-label': ariaLabel,\n class:\n 'as-rich-text-editor__content min-h-24 w-full bg-transparent px-3 py-2 text-sm text-[var(--as-fg)] outline-none',\n },\n },\n onUpdate: ({ editor: current }) => {\n const markdown = toApp(getMarkdown(current))\n lastEmittedRef.current = markdown\n onValueChangeRef.current(markdown)\n },\n },\n )\n\n const isMounted = editor !== null\n\n React.useEffect(() => {\n if (!isMounted || editor === null) {\n return\n }\n const handler = () => bump()\n editor.on('transaction', handler)\n editor.on('update', handler)\n return () => {\n editor.off('transaction', handler)\n editor.off('update', handler)\n }\n }, [editor, isMounted])\n\n React.useEffect(() => {\n if (editor === null || editor.isDestroyed) {\n return\n }\n editor.setEditable(!disabled)\n }, [editor, disabled])\n\n React.useEffect(() => {\n if (editor === null || editor.isDestroyed) {\n return\n }\n if (value === lastEmittedRef.current) {\n return\n }\n const current = toApp(getMarkdown(editor))\n if (value === current) {\n lastEmittedRef.current = value\n return\n }\n applyExternalValue(editor, toDocument(value))\n lastEmittedRef.current = value\n }, [editor, value, toApp, toDocument])\n\n const groups = toolbar === false ? [] : (toolbar ?? DEFAULT_TOOLBAR)\n\n const renderButton = (\n key: Exclude<keyof RichTextEditorLabels, 'toolbar'>,\n group: Exclude<RichTextToolbarGroup, 'history'> | 'history',\n onClick: () => void,\n active: boolean,\n ) => {\n const Icon = mergedIcons[key]\n return (\n <button\n key={`${group}-${key}`}\n type=\"button\"\n aria-label={mergedLabels[key]}\n aria-pressed={active}\n title={mergedLabels[key]}\n disabled={disabled}\n className={cn(\n 'rounded p-1.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50',\n active && 'bg-[var(--as-surface-active)] text-[var(--as-fg)]',\n )}\n onClick={onClick}\n >\n <Icon className=\"size-4\" aria-hidden />\n </button>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"rich-text-editor\"\n className={cn(\n 'w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] focus-within:border-[var(--as-focus-ring)]',\n disabled && 'opacity-50',\n className,\n )}\n >\n {groups.length > 0 || toolbarExtra ? (\n <div\n role=\"toolbar\"\n aria-label={mergedLabels.toolbar}\n className=\"flex flex-wrap items-center gap-0.5 border-b border-[var(--as-border)] p-1\"\n >\n {groups.includes('history')\n ? renderButton(\n 'undo',\n 'history',\n () => editor?.chain().focus().undo().run(),\n false,\n )\n : null}\n {groups.includes('history')\n ? renderButton(\n 'redo',\n 'history',\n () => editor?.chain().focus().redo().run(),\n false,\n )\n : null}\n {groups.includes('heading')\n ? renderButton(\n 'heading',\n 'heading',\n () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),\n editor?.isActive('heading', { level: 2 }) === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'bold',\n 'format',\n () => editor?.chain().focus().toggleBold().run(),\n editor?.isActive('bold') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'italic',\n 'format',\n () => editor?.chain().focus().toggleItalic().run(),\n editor?.isActive('italic') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'strike',\n 'format',\n () => editor?.chain().focus().toggleStrike().run(),\n editor?.isActive('strike') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'code',\n 'format',\n () => editor?.chain().focus().toggleCode().run(),\n editor?.isActive('code') === true,\n )\n : null}\n {groups.includes('list')\n ? renderButton(\n 'bulletList',\n 'list',\n () => editor?.chain().focus().toggleBulletList().run(),\n editor?.isActive('bulletList') === true,\n )\n : null}\n {groups.includes('list')\n ? renderButton(\n 'orderedList',\n 'list',\n () => editor?.chain().focus().toggleOrderedList().run(),\n editor?.isActive('orderedList') === true,\n )\n : null}\n {groups.includes('quote')\n ? renderButton(\n 'blockquote',\n 'quote',\n () => editor?.chain().focus().toggleBlockquote().run(),\n editor?.isActive('blockquote') === true,\n )\n : null}\n {typeof toolbarExtra === 'function' ? toolbarExtra(editor) : toolbarExtra}\n </div>\n ) : null}\n <EditorContent editor={editor} />\n </div>\n )\n },\n)\n"]}
@@ -0,0 +1,64 @@
1
+ import * as React from 'react';
2
+
3
+ type DictationStatus = 'idle' | 'recording' | 'transcribing';
4
+ interface DictationError {
5
+ kind: 'unsupported' | 'denied' | 'unassigned' | 'failed';
6
+ detail?: string;
7
+ }
8
+ interface DictationResult {
9
+ text: string;
10
+ }
11
+ interface UseDictationOptions {
12
+ /** App-owned transport: upload the blob, resolve with the transcript. */
13
+ transcribe: (audio: Blob) => Promise<DictationResult>;
14
+ /** Map a transport failure to a structured error (e.g. 409 → 'unassigned'). */
15
+ classifyError?: (error: unknown) => DictationError;
16
+ /** Called with the transcript on success. */
17
+ onResult?: (text: string) => void;
18
+ }
19
+ declare function useDictation(options: UseDictationOptions): {
20
+ status: DictationStatus;
21
+ seconds: number;
22
+ error: DictationError | null;
23
+ levelRef: React.RefObject<number>;
24
+ start: () => Promise<void>;
25
+ stop: () => Promise<void>;
26
+ cancel: () => void;
27
+ dismissError: () => void;
28
+ };
29
+
30
+ interface DictationButtonProps {
31
+ status: DictationStatus;
32
+ onStart: () => void;
33
+ /** Accessible name / tooltip. English default: 'Dictate'. */
34
+ label?: string;
35
+ recordingLabel?: string;
36
+ className?: string;
37
+ }
38
+ declare function DictationButton({ status, onStart, label, recordingLabel, className, }: DictationButtonProps): React.JSX.Element;
39
+ interface DictationStripLabels {
40
+ recording?: string;
41
+ transcribing?: string;
42
+ stop?: string;
43
+ cancel?: string;
44
+ dismissError?: string;
45
+ unsupported?: string;
46
+ denied?: string;
47
+ unassigned?: string;
48
+ /** `{detail}` is interpolated with the transport error message. */
49
+ failed?: string;
50
+ }
51
+ interface DictationStripProps {
52
+ status: DictationStatus;
53
+ seconds: number;
54
+ levelRef: React.RefObject<number>;
55
+ error: DictationError | null;
56
+ labels?: Partial<DictationStripLabels>;
57
+ onStop: () => void;
58
+ onCancel: () => void;
59
+ onDismissError: () => void;
60
+ className?: string;
61
+ }
62
+ declare function DictationStrip({ status, seconds, levelRef, error, labels, onStop, onCancel, onDismissError, className, }: DictationStripProps): React.JSX.Element | null;
63
+
64
+ export { DictationButton, type DictationButtonProps, type DictationError, type DictationResult, type DictationStatus, DictationStrip, type DictationStripLabels, type DictationStripProps, type UseDictationOptions, useDictation };
@@ -0,0 +1,3 @@
1
+ export { DictationButton, DictationStrip, useDictation } from './chunk-KAC2DOLH.js';
2
+ //# sourceMappingURL=dictation.js.map
3
+ //# sourceMappingURL=dictation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"dictation.js"}
package/dist/index.d.ts CHANGED
@@ -58,6 +58,10 @@ export { TimePicker, TimePickerContent, TimePickerContentProps, TimePickerProps
58
58
  export { UndoNotice, UndoNoticeProps } from './undo-notice.js';
59
59
  export { ViewToggle, ViewToggleProps, ViewToggleView } from './view-toggle.js';
60
60
  export { Stepper, StepperProps, StepperStep, Wizard, WizardContext, WizardProps, WizardStep } from './wizard.js';
61
+ export { RichTextEditor, RichTextEditorIcons, RichTextEditorLabels, RichTextEditorProps, RichTextToolbarGroup } from './rich-text-editor.js';
62
+ export { DictationButton, DictationButtonProps, DictationError, DictationResult, DictationStatus, DictationStrip, DictationStripLabels, DictationStripProps, UseDictationOptions, useDictation } from './dictation.js';
63
+ export { AiTextTransformEventHandlers, AiTextTransformStatus, AiTextTransformTransport, UseAiTextTransformOptions, useAiTextTransform } from './ai-text-transform.js';
64
+ export { DiffCell, DiffRow, DiffSegment, LineDiffOptions, LineDiffResult, TextDiffView, TextDiffViewLabels, TextDiffViewProps, computeLineDiff, wordSegments } from './text-diff-view.js';
61
65
  import 'class-variance-authority/types';
62
66
  import 'class-variance-authority';
63
67
  import 'lucide-react';
@@ -65,6 +69,7 @@ import '@radix-ui/react-dropdown-menu';
65
69
  import '@radix-ui/react-dialog';
66
70
  import '@radix-ui/react-popover';
67
71
  import '@radix-ui/react-tooltip';
72
+ import '@tiptap/react';
68
73
 
69
74
  declare function cn(...inputs: ClassValue[]): string;
70
75
 
package/dist/index.js CHANGED
@@ -1,31 +1,35 @@
1
+ export { ThemeScope } from './chunk-TGU3PKNM.js';
2
+ export { TimeList } from './chunk-GVOC3ARM.js';
3
+ export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
4
+ export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
1
5
  export { UndoNotice } from './chunk-OUHUVACM.js';
2
6
  export { ViewToggle } from './chunk-MXOBOS4Y.js';
3
7
  export { Stepper, Wizard } from './chunk-YMCMUAIF.js';
8
+ export { ModelRegistry } from './chunk-RBEPQY2A.js';
9
+ export { SelectionBar } from './chunk-HSUCCANX.js';
10
+ export { Table } from './chunk-5LRRVD27.js';
4
11
  export { TaskAssignmentPicker } from './chunk-VULOVVKF.js';
5
- export { SettingsShell } from './chunk-AHLNXCP2.js';
12
+ export { SettingsShell } from './chunk-UJVNCZ5Z.js';
6
13
  export { SidebarNav } from './chunk-SW3YNICQ.js';
7
14
  export { UserMenu } from './chunk-535TM7SK.js';
8
- export { ThemeScope } from './chunk-TGU3PKNM.js';
9
- export { TimeList } from './chunk-GVOC3ARM.js';
10
- export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
11
- export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
15
+ export { Portal } from './chunk-7YLR4AGA.js';
16
+ export { ProviderForm } from './chunk-4WDXLXHL.js';
17
+ export { RangeBar } from './chunk-PFAH25VU.js';
12
18
  export { ScaleSlider, scaleColorForValue } from './chunk-PSFJN7WH.js';
13
19
  export { SearchInput } from './chunk-H5U4KNXF.js';
14
- export { ModelRegistry } from './chunk-RBEPQY2A.js';
15
20
  export { CapabilityChips } from './chunk-G3DWN2DJ.js';
16
- export { SelectionBar } from './chunk-HSUCCANX.js';
17
- export { Table } from './chunk-5LRRVD27.js';
21
+ export { DictationButton, DictationStrip, useDictation } from './chunk-KAC2DOLH.js';
22
+ export { useAiTextTransform } from './chunk-BKAO7BTU.js';
23
+ export { TextDiffView, computeLineDiff, wordSegments } from './chunk-2PR6POP6.js';
24
+ export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee } from './chunk-RU3DEF2O.js';
18
25
  export { ModelPicker } from './chunk-SVQK7TXU.js';
19
26
  export { PanelModal } from './chunk-G6557MEN.js';
20
- export { Portal } from './chunk-7YLR4AGA.js';
21
- export { ProviderForm } from './chunk-4WDXLXHL.js';
22
- export { RangeBar } from './chunk-PFAH25VU.js';
23
27
  export { FlowStatusCard } from './chunk-PRHTQBCP.js';
24
28
  export { FieldLabel } from './chunk-I5J6SDLK.js';
25
29
  export { InfoButton } from './chunk-OT6EQFMP.js';
26
30
  export { PopoverButton } from './chunk-BE3XFZWU.js';
27
31
  export { Input } from './chunk-M4V7XHL7.js';
28
- export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee } from './chunk-RU3DEF2O.js';
32
+ export { RichTextEditor } from './chunk-XUDCCQRN.js';
29
33
  export { CopyButton } from './chunk-CZ2BL2ZL.js';
30
34
  export { ContextMenu } from './chunk-YIGLULRG.js';
31
35
  export { ActionMenu, Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuLabel, MenuSeparator, MenuTrigger } from './chunk-XSJ3TWWZ.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBO,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA;AAAA,EAClC,SAASA,eAAAA,CACP;AAAA,IACE,OAAA;AAAA,IACA,SAAA,GAAY,KAAA;AAAA,IACZ,OAAA,GAAU,OAAA;AAAA,IACV,KAAA,GAAQ,oCAAA;AAAA,IACR,IAAA;AAAA,IACA,WAAA,GAAc,cAAA;AAAA,IACd,WAAA,GAAc,eAAA;AAAA,IACd,MAAA;AAAA,IACA,QAAA,GAAW,IAAA;AAAA,IACX,YAAA,GAAe,KAAA;AAAA,IACf,QAAA,GAAW,KAAA;AAAA,IACX;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,KAAK,CAAA;AACpD,IAAA,MAAM,SAAA,GAAkB,aAAyB,IAAI,CAAA;AACrD,IAAA,MAAM,WAAA,GAAoB,aAAyB,IAAI,CAAA;AAEvD,IAAA,MAAM,MAAA,GAAS,CAAC,QAAA,IAAY,CAAC,SAAA;AAE7B,IAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAA0B;AACtC,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,IAAA,IAAQ,IAAA,CAAK,WAAW,CAAA,EAAG;AAC3C,MAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAC1B,CAAA;AAEA,IAAA,MAAM,KAAA,GAAQ,+BACZ,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,IAAA,EAAK,MAAA;AAAA,UACL,MAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA,EAAU,QAAA;AAAA,UACV,aAAA,EAAW,IAAA;AAAA,UACX,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,YAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,YAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,UACvB;AAAA;AAAA,OACF;AAAA,sBACA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,WAAA;AAAA,UACL,IAAA,EAAK,MAAA;AAAA,UACL,QAAA,EAAQ,IAAA;AAAA,UACR,SAAA,EAAU,QAAA;AAAA,UAEV,eAAA,EAAgB,EAAA;AAAA,UAChB,aAAA,EAAW,IAAA;AAAA,UACX,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,YAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,YAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,UACvB;AAAA;AAAA;AACF,KAAA,EACF,CAAA,mBAEA,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,SAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA,EAAU,QAAA;AAAA,QACV,aAAA,EAAW,IAAA;AAAA,QACX,QAAA,EAAU,EAAA;AAAA,QACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,UAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,UAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,QACvB;AAAA;AAAA,KACF;AAGF,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,KAAA;AAAA,sBACD,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,SAAA,EAAQ,iBAAA;AAAA,UACR,cAAA,EAAc,OAAA;AAAA,UACd,iBAAe,QAAA,IAAY,MAAA;AAAA,UAC3B,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,SAAS,CAAA,GAAI,EAAA;AAAA,UACvB,YAAA,EAAY,KAAA;AAAA,UACZ,eAAA,EAAe,YAAY,SAAA,IAAa,MAAA;AAAA,UACxC,OAAA,EAAS,MAAM,MAAA,IAAU,SAAA,CAAU,SAAS,KAAA,EAAM;AAAA,UAClD,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,YAAA,IAAI,WAAW,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,CAAA,EAAM;AAC1D,cAAA,KAAA,CAAM,cAAA,EAAe;AACrB,cAAA,SAAA,CAAU,SAAS,KAAA,EAAM;AAAA,YAC3B;AAAA,UACF,CAAA;AAAA,UACA,UAAA,EAAY,CAAC,KAAA,KAAU;AACrB,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,IAAI,MAAA,cAAoB,IAAI,CAAA;AAAA,UAC9B,CAAA;AAAA,UACA,WAAA,EAAa,MAAM,WAAA,CAAY,KAAK,CAAA;AAAA,UACpC,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,WAAA,CAAY,KAAK,CAAA;AACjB,YAAA,IAAA,CAAK,KAAA,CAAM,aAAa,KAAK,CAAA;AAAA,UAC/B,CAAA;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACT,yKAAA;AAAA,YACA,4DAAA;AAAA,YACA,qGAAA;AAAA,YACA,OAAA,KAAY,UAAU,mCAAA,GAAsC,sCAAA;AAAA,YAC5D,QAAA,IAAY,yGAAA;AAAA,YACZ,SAAA,IAAa,4BAAA;AAAA,YACb,QAAA,IAAY,gCAAA;AAAA,YACZ;AAAA,WACF;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,SAAA,mBACC,GAAA,CAAC,WAAQ,SAAA,EAAU,8BAAA,EAA+B,eAAW,IAAA,EAAC,CAAA,GAC5D,+BACF,GAAA,CAAC,QAAA,EAAA,EAAS,WAAU,iBAAA,EAAkB,aAAA,EAAW,MAAC,CAAA,mBAElD,GAAA,CAAC,UAAO,SAAA,EAAU,iBAAA,EAAkB,eAAW,IAAA,EAAC,CAAA;AAAA,4BAElD,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EACd,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAA+B,IAAA,EAAM,SAAA,GAAY,QAAA,GAAW,MAAA,EACzE,QAAA,EAAA,SAAA,GAAY,CAAA,EAAG,WAAW,CAAA,MAAA,CAAA,GAAM,QAAA,GAAW,cAAc,KAAA,EAC5D,CAAA;AAAA,cACC,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAoB,gBAAK,CAAA,GAAU;AAAA,aAAA,EAC7D;AAAA;AAAA;AAAA;AACF,KAAA,EACF,CAAA;AAAA,EAEJ;AACF","file":"index.js","sourcesContent":["import * as React from 'react'\nimport { FolderUp, Loader2, Upload } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface UploadDropzoneProps {\n onFiles: (files: File[]) => void\n uploading?: boolean\n variant?: 'block' | 'row'\n label?: string\n hint?: string\n browseLabel?: string\n folderLabel?: string\n accept?: string\n multiple?: boolean\n allowFolders?: boolean\n disabled?: boolean\n className?: string\n}\n\n/**\n * Presentational dropzone: drag events and file-picker results go out via\n * `onFiles` — uploading, storage and progress stay app-side. Pass\n * `uploading` to render a busy state and suppress input.\n */\nexport const UploadDropzone = React.forwardRef<HTMLDivElement, UploadDropzoneProps>(\n function UploadDropzone(\n {\n onFiles,\n uploading = false,\n variant = 'block',\n label = 'Drop files here or click to browse',\n hint,\n browseLabel = 'Choose files',\n folderLabel = 'Choose folder',\n accept,\n multiple = true,\n allowFolders = false,\n disabled = false,\n className,\n },\n ref,\n ) {\n const [dragging, setDragging] = React.useState(false)\n const fileInput = React.useRef<HTMLInputElement>(null)\n const folderInput = React.useRef<HTMLInputElement>(null)\n\n const active = !disabled && !uploading\n\n const emit = (list: FileList | null) => {\n if (!active || !list || list.length === 0) return\n onFiles(Array.from(list))\n }\n\n const input = allowFolders ? (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n <input\n ref={folderInput}\n type=\"file\"\n multiple\n className=\"hidden\"\n // @ts-expect-error non-standard but universally supported directory picker\n webkitdirectory=\"\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n </>\n ) : (\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n )\n\n return (\n <>\n {input}\n <div\n ref={ref}\n data-as=\"upload-dropzone\"\n data-variant={variant}\n data-dragging={dragging || undefined}\n role=\"button\"\n tabIndex={active ? 0 : -1}\n aria-label={label}\n aria-disabled={disabled || uploading || undefined}\n onClick={() => active && fileInput.current?.click()}\n onKeyDown={(event) => {\n if (active && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault()\n fileInput.current?.click()\n }\n }}\n onDragOver={(event) => {\n event.preventDefault()\n if (active) setDragging(true)\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={(event) => {\n event.preventDefault()\n setDragging(false)\n emit(event.dataTransfer.files)\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-center gap-3 border border-dashed border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] transition-colors',\n 'hover:border-[var(--as-primary)] hover:text-[var(--as-fg)]',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n variant === 'block' ? 'rounded-[var(--as-radius-lg)] p-8' : 'rounded-[var(--as-radius)] px-4 py-3',\n dragging && 'border-[var(--as-primary)] bg-[color-mix(in_srgb,var(--as-primary)_8%,transparent)] text-[var(--as-fg)]',\n uploading && 'cursor-progress opacity-70',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n >\n {uploading ? (\n <Loader2 className=\"size-5 shrink-0 animate-spin\" aria-hidden />\n ) : allowFolders ? (\n <FolderUp className=\"size-5 shrink-0\" aria-hidden />\n ) : (\n <Upload className=\"size-5 shrink-0\" aria-hidden />\n )}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-sm font-medium\" role={uploading ? 'status' : undefined}>\n {uploading ? `${browseLabel}…` : dragging ? folderLabel : label}\n </span>\n {hint ? <span className=\"truncate text-xs\">{hint}</span> : null}\n </span>\n </div>\n </>\n )\n },\n)\n"]}
1
+ {"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBO,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA;AAAA,EAClC,SAASA,eAAAA,CACP;AAAA,IACE,OAAA;AAAA,IACA,SAAA,GAAY,KAAA;AAAA,IACZ,OAAA,GAAU,OAAA;AAAA,IACV,KAAA,GAAQ,oCAAA;AAAA,IACR,IAAA;AAAA,IACA,WAAA,GAAc,cAAA;AAAA,IACd,WAAA,GAAc,eAAA;AAAA,IACd,MAAA;AAAA,IACA,QAAA,GAAW,IAAA;AAAA,IACX,YAAA,GAAe,KAAA;AAAA,IACf,QAAA,GAAW,KAAA;AAAA,IACX;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,KAAK,CAAA;AACpD,IAAA,MAAM,SAAA,GAAkB,aAAyB,IAAI,CAAA;AACrD,IAAA,MAAM,WAAA,GAAoB,aAAyB,IAAI,CAAA;AAEvD,IAAA,MAAM,MAAA,GAAS,CAAC,QAAA,IAAY,CAAC,SAAA;AAE7B,IAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAA0B;AACtC,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,IAAA,IAAQ,IAAA,CAAK,WAAW,CAAA,EAAG;AAC3C,MAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAC1B,CAAA;AAEA,IAAA,MAAM,KAAA,GAAQ,+BACZ,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,IAAA,EAAK,MAAA;AAAA,UACL,MAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA,EAAU,QAAA;AAAA,UACV,aAAA,EAAW,IAAA;AAAA,UACX,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,YAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,YAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,UACvB;AAAA;AAAA,OACF;AAAA,sBACA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,WAAA;AAAA,UACL,IAAA,EAAK,MAAA;AAAA,UACL,QAAA,EAAQ,IAAA;AAAA,UACR,SAAA,EAAU,QAAA;AAAA,UAEV,eAAA,EAAgB,EAAA;AAAA,UAChB,aAAA,EAAW,IAAA;AAAA,UACX,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,YAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,YAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,UACvB;AAAA;AAAA;AACF,KAAA,EACF,CAAA,mBAEA,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,SAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA,EAAU,QAAA;AAAA,QACV,aAAA,EAAW,IAAA;AAAA,QACX,QAAA,EAAU,EAAA;AAAA,QACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,UAAA,IAAA,CAAK,KAAA,CAAM,OAAO,KAAK,CAAA;AACvB,UAAA,KAAA,CAAM,OAAO,KAAA,GAAQ,EAAA;AAAA,QACvB;AAAA;AAAA,KACF;AAGF,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,KAAA;AAAA,sBACD,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,SAAA,EAAQ,iBAAA;AAAA,UACR,cAAA,EAAc,OAAA;AAAA,UACd,iBAAe,QAAA,IAAY,MAAA;AAAA,UAC3B,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,SAAS,CAAA,GAAI,EAAA;AAAA,UACvB,YAAA,EAAY,KAAA;AAAA,UACZ,eAAA,EAAe,YAAY,SAAA,IAAa,MAAA;AAAA,UACxC,OAAA,EAAS,MAAM,MAAA,IAAU,SAAA,CAAU,SAAS,KAAA,EAAM;AAAA,UAClD,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,YAAA,IAAI,WAAW,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,CAAA,EAAM;AAC1D,cAAA,KAAA,CAAM,cAAA,EAAe;AACrB,cAAA,SAAA,CAAU,SAAS,KAAA,EAAM;AAAA,YAC3B;AAAA,UACF,CAAA;AAAA,UACA,UAAA,EAAY,CAAC,KAAA,KAAU;AACrB,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,IAAI,MAAA,cAAoB,IAAI,CAAA;AAAA,UAC9B,CAAA;AAAA,UACA,WAAA,EAAa,MAAM,WAAA,CAAY,KAAK,CAAA;AAAA,UACpC,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,WAAA,CAAY,KAAK,CAAA;AACjB,YAAA,IAAA,CAAK,KAAA,CAAM,aAAa,KAAK,CAAA;AAAA,UAC/B,CAAA;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACT,yKAAA;AAAA,YACA,4DAAA;AAAA,YACA,qGAAA;AAAA,YACA,OAAA,KAAY,UAAU,mCAAA,GAAsC,sCAAA;AAAA,YAC5D,QAAA,IAAY,yGAAA;AAAA,YACZ,SAAA,IAAa,4BAAA;AAAA,YACb,QAAA,IAAY,gCAAA;AAAA,YACZ;AAAA,WACF;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,SAAA,mBACC,GAAA,CAAC,WAAQ,SAAA,EAAU,8BAAA,EAA+B,eAAW,IAAA,EAAC,CAAA,GAC5D,+BACF,GAAA,CAAC,QAAA,EAAA,EAAS,WAAU,iBAAA,EAAkB,aAAA,EAAW,MAAC,CAAA,mBAElD,GAAA,CAAC,UAAO,SAAA,EAAU,iBAAA,EAAkB,eAAW,IAAA,EAAC,CAAA;AAAA,4BAElD,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EACd,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAA+B,IAAA,EAAM,SAAA,GAAY,QAAA,GAAW,MAAA,EACzE,QAAA,EAAA,SAAA,GAAY,CAAA,EAAG,WAAW,CAAA,MAAA,CAAA,GAAM,QAAA,GAAW,cAAc,KAAA,EAC5D,CAAA;AAAA,cACC,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAoB,gBAAK,CAAA,GAAU;AAAA,aAAA,EAC7D;AAAA;AAAA;AAAA;AACF,KAAA,EACF,CAAA;AAAA,EAEJ;AACF","file":"index.js","sourcesContent":["import * as React from 'react'\nimport { FolderUp, Loader2, Upload } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface UploadDropzoneProps {\n onFiles: (files: File[]) => void\n uploading?: boolean\n variant?: 'block' | 'row'\n label?: string\n hint?: string\n browseLabel?: string\n folderLabel?: string\n accept?: string\n multiple?: boolean\n allowFolders?: boolean\n disabled?: boolean\n className?: string\n}\n\n/**\n * Presentational dropzone: drag events and file-picker results go out via\n * `onFiles` — uploading, storage and progress stay app-side. Pass\n * `uploading` to render a busy state and suppress input.\n */\nexport const UploadDropzone = React.forwardRef<HTMLDivElement, UploadDropzoneProps>(\n function UploadDropzone(\n {\n onFiles,\n uploading = false,\n variant = 'block',\n label = 'Drop files here or click to browse',\n hint,\n browseLabel = 'Choose files',\n folderLabel = 'Choose folder',\n accept,\n multiple = true,\n allowFolders = false,\n disabled = false,\n className,\n },\n ref,\n ) {\n const [dragging, setDragging] = React.useState(false)\n const fileInput = React.useRef<HTMLInputElement>(null)\n const folderInput = React.useRef<HTMLInputElement>(null)\n\n const active = !disabled && !uploading\n\n const emit = (list: FileList | null) => {\n if (!active || !list || list.length === 0) return\n onFiles(Array.from(list))\n }\n\n const input = allowFolders ? (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n <input\n ref={folderInput}\n type=\"file\"\n multiple\n className=\"hidden\"\n // @ts-expect-error non-standard but universally supported directory picker\n webkitdirectory=\"\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n </>\n ) : (\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n )\n\n return (\n <>\n {input}\n <div\n ref={ref}\n data-as=\"upload-dropzone\"\n data-variant={variant}\n data-dragging={dragging || undefined}\n role=\"button\"\n tabIndex={active ? 0 : -1}\n aria-label={label}\n aria-disabled={disabled || uploading || undefined}\n onClick={() => active && fileInput.current?.click()}\n onKeyDown={(event) => {\n if (active && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault()\n fileInput.current?.click()\n }\n }}\n onDragOver={(event) => {\n event.preventDefault()\n if (active) setDragging(true)\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={(event) => {\n event.preventDefault()\n setDragging(false)\n emit(event.dataTransfer.files)\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-center gap-3 border border-dashed border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] transition-colors',\n 'hover:border-[var(--as-primary)] hover:text-[var(--as-fg)]',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n variant === 'block' ? 'rounded-[var(--as-radius-lg)] p-8' : 'rounded-[var(--as-radius)] px-4 py-3',\n dragging && 'border-[var(--as-primary)] bg-[color-mix(in_srgb,var(--as-primary)_8%,transparent)] text-[var(--as-fg)]',\n uploading && 'cursor-progress opacity-70',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n >\n {uploading ? (\n <Loader2 className=\"size-5 shrink-0 animate-spin\" aria-hidden />\n ) : allowFolders ? (\n <FolderUp className=\"size-5 shrink-0\" aria-hidden />\n ) : (\n <Upload className=\"size-5 shrink-0\" aria-hidden />\n )}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-sm font-medium\" role={uploading ? 'status' : undefined}>\n {uploading ? `${browseLabel}…` : dragging ? folderLabel : label}\n </span>\n {hint ? <span className=\"truncate text-xs\">{hint}</span> : null}\n </span>\n </div>\n </>\n )\n },\n)\n"]}
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import { Editor, Extensions } from '@tiptap/react';
3
+ import { LucideIcon } from 'lucide-react';
4
+
5
+ type RichTextToolbarGroup = 'history' | 'heading' | 'format' | 'list' | 'quote';
6
+ interface RichTextEditorLabels {
7
+ toolbar?: string;
8
+ bold?: string;
9
+ italic?: string;
10
+ strike?: string;
11
+ code?: string;
12
+ heading?: string;
13
+ bulletList?: string;
14
+ orderedList?: string;
15
+ blockquote?: string;
16
+ undo?: string;
17
+ redo?: string;
18
+ }
19
+ interface RichTextEditorIcons {
20
+ bold?: LucideIcon;
21
+ italic?: LucideIcon;
22
+ strike?: LucideIcon;
23
+ code?: LucideIcon;
24
+ heading?: LucideIcon;
25
+ bulletList?: LucideIcon;
26
+ orderedList?: LucideIcon;
27
+ blockquote?: LucideIcon;
28
+ undo?: LucideIcon;
29
+ redo?: LucideIcon;
30
+ }
31
+ interface RichTextEditorProps {
32
+ value: string;
33
+ onValueChange: (markdown: string) => void;
34
+ ariaLabel: string;
35
+ disabled?: boolean;
36
+ toolbar?: RichTextToolbarGroup[] | false;
37
+ /** App-owned controls at the end of the toolbar; render-prop form receives the editor. */
38
+ toolbarExtra?: React.ReactNode | ((editor: Editor | null) => React.ReactNode);
39
+ /** App extensions merged after the starter kit (math, tables, custom nodes…). */
40
+ extensions?: Extensions;
41
+ /** Map incoming app-domain markdown before it reaches the document. */
42
+ parseMarkdown?: (markdown: string) => string;
43
+ /** Map the serialized document before it is emitted / echo-compared. */
44
+ serializeMarkdown?: (markdown: string) => string;
45
+ labels?: Partial<RichTextEditorLabels>;
46
+ icons?: Partial<RichTextEditorIcons>;
47
+ className?: string;
48
+ }
49
+ declare const RichTextEditor: React.ForwardRefExoticComponent<RichTextEditorProps & React.RefAttributes<HTMLDivElement>>;
50
+
51
+ export { RichTextEditor, type RichTextEditorIcons, type RichTextEditorLabels, type RichTextEditorProps, type RichTextToolbarGroup };