@nucleux/md3-handwriting 0.9.0 → 0.10.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.
- package/dist/index.cjs +59 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -9
- package/dist/index.js.map +1 -1
- package/package.json +10 -8
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ var React = require('react');
|
|
|
5
5
|
var utils = require('@nucleux/utils');
|
|
6
6
|
var md3Button = require('@nucleux/md3-button');
|
|
7
7
|
var md3Chip = require('@nucleux/md3-chip');
|
|
8
|
+
var md3IconButton = require('@nucleux/md3-icon-button');
|
|
8
9
|
var md3LoadingIndicator = require('@nucleux/md3-loading-indicator');
|
|
9
10
|
var md3Menu = require('@nucleux/md3-menu');
|
|
10
11
|
var md3TextField = require('@nucleux/md3-text-field');
|
|
@@ -150,6 +151,9 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
150
151
|
acceptLabel = "Add to message",
|
|
151
152
|
typingLabel = "Type your request",
|
|
152
153
|
disabled = false,
|
|
154
|
+
padLabel,
|
|
155
|
+
compact = false,
|
|
156
|
+
onClose,
|
|
153
157
|
className,
|
|
154
158
|
children,
|
|
155
159
|
...props
|
|
@@ -378,6 +382,8 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
378
382
|
setAnnouncement("Added to message.");
|
|
379
383
|
};
|
|
380
384
|
const undoStroke = () => setStrokes(strokes.slice(0, -1));
|
|
385
|
+
const banner = compact && inputMode === "draw" && status === "recognized" && !!recognition && !unsettled && editedText === null;
|
|
386
|
+
const showToolbar = !banner;
|
|
381
387
|
const setRef = (node) => {
|
|
382
388
|
if (typeof ref === "function") ref(node);
|
|
383
389
|
else if (ref) ref.current = node;
|
|
@@ -394,6 +400,33 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
394
400
|
className: utils.cn("flex flex-col gap-3 text-md-on-surface", className),
|
|
395
401
|
...props,
|
|
396
402
|
children: [
|
|
403
|
+
(padLabel != null || compact && (inputMode === "draw" || onClose)) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "-mb-1 flex items-center gap-2", children: [
|
|
404
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.PenLine, { "aria-hidden": "true", className: "size-5 shrink-0 text-md-primary" }),
|
|
405
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex-1 text-sm font-medium tracking-[0.1px] text-md-on-surface-variant", children: padLabel }),
|
|
406
|
+
compact && inputMode === "draw" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
407
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
408
|
+
md3IconButton.Md3IconButton,
|
|
409
|
+
{
|
|
410
|
+
"aria-label": "Undo stroke",
|
|
411
|
+
onClick: undoStroke,
|
|
412
|
+
disabled: disabled || strokes.length === 0 || status === "recognizing",
|
|
413
|
+
className: "[&_svg]:size-5",
|
|
414
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo2, { "aria-hidden": "true" })
|
|
415
|
+
}
|
|
416
|
+
),
|
|
417
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
418
|
+
md3IconButton.Md3IconButton,
|
|
419
|
+
{
|
|
420
|
+
"aria-label": "Clear",
|
|
421
|
+
onClick: reset,
|
|
422
|
+
disabled: disabled || strokes.length === 0,
|
|
423
|
+
className: "[&_svg]:size-5",
|
|
424
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eraser, { "aria-hidden": "true" })
|
|
425
|
+
}
|
|
426
|
+
)
|
|
427
|
+
] }),
|
|
428
|
+
compact && onClose && /* @__PURE__ */ jsxRuntime.jsx(md3IconButton.Md3IconButton, { "aria-label": "Close handwriting", onClick: onClose, className: "[&_svg]:size-5", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true" }) })
|
|
429
|
+
] }),
|
|
397
430
|
inputMode === "type" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
398
431
|
"textarea",
|
|
399
432
|
{
|
|
@@ -415,7 +448,7 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
415
448
|
ref: padRef,
|
|
416
449
|
className: utils.cn(
|
|
417
450
|
"relative overflow-hidden rounded-md-lg",
|
|
418
|
-
isAnnotation ? "min-h-40 border border-md-outline-variant" : "h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low",
|
|
451
|
+
isAnnotation ? "min-h-40 border border-md-outline-variant" : compact ? "h-28 rounded-b-md-xs border-b border-md-outline-variant bg-md-surface-container-low" : "h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low",
|
|
419
452
|
variant === "live-ocr" && "h-36 border border-solid border-md-outline-variant",
|
|
420
453
|
disabled && "opacity-[0.38]"
|
|
421
454
|
),
|
|
@@ -439,13 +472,14 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
439
472
|
)
|
|
440
473
|
}
|
|
441
474
|
),
|
|
475
|
+
compact && !isAnnotation && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-[49%] border-t border-md-outline-variant" }),
|
|
442
476
|
strokes.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
443
477
|
"p",
|
|
444
478
|
{
|
|
445
479
|
"aria-hidden": "true",
|
|
446
480
|
className: utils.cn(
|
|
447
|
-
"pointer-events-none absolute text-
|
|
448
|
-
isAnnotation ? "bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 font-medium" : "inset-x-0 bottom-3 text-center"
|
|
481
|
+
"pointer-events-none absolute text-md-on-surface-variant",
|
|
482
|
+
isAnnotation ? "bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium" : compact ? "left-4 top-[23%] text-base" : "inset-x-0 bottom-3 text-center text-xs"
|
|
449
483
|
),
|
|
450
484
|
children: emptyHint
|
|
451
485
|
}
|
|
@@ -488,7 +522,24 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
488
522
|
/* @__PURE__ */ jsxRuntime.jsx(md3Button.Md3Button, { variant: "text", onClick: reset, className: "text-md-on-error-container", children: "Rewrite" })
|
|
489
523
|
] })
|
|
490
524
|
] }),
|
|
491
|
-
|
|
525
|
+
banner && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
526
|
+
"div",
|
|
527
|
+
{
|
|
528
|
+
id: resultId,
|
|
529
|
+
"data-slot": "handwriting-result",
|
|
530
|
+
className: "flex items-center gap-3 rounded-md-md bg-md-secondary-container py-2 pl-4 pr-2 text-md-on-secondary-container",
|
|
531
|
+
children: [
|
|
532
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "min-w-0 flex-1 text-sm font-medium", children: [
|
|
533
|
+
isAnnotation ? "Read as" : "Recognised",
|
|
534
|
+
": \u201C",
|
|
535
|
+
resultText,
|
|
536
|
+
"\u201D"
|
|
537
|
+
] }),
|
|
538
|
+
/* @__PURE__ */ jsxRuntime.jsx(md3Button.Md3Button, { variant: "filled", onClick: accept, disabled: disabled || !resultText.trim(), children: acceptLabel })
|
|
539
|
+
]
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
inputMode === "draw" && status === "recognized" && recognition && !banner && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
492
543
|
"div",
|
|
493
544
|
{
|
|
494
545
|
id: resultId,
|
|
@@ -530,8 +581,8 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
530
581
|
]
|
|
531
582
|
}
|
|
532
583
|
),
|
|
533
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
534
|
-
inputMode === "draw" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
584
|
+
showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
585
|
+
inputMode === "draw" && !compact && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
535
586
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
536
587
|
md3Button.Md3Button,
|
|
537
588
|
{
|
|
@@ -567,14 +618,14 @@ var Md3HandwritingInput = React__namespace.forwardRef(
|
|
|
567
618
|
inputMode === "draw" && onRecognize && (status !== "recognized" || mode === "review") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
568
619
|
md3Button.Md3Button,
|
|
569
620
|
{
|
|
570
|
-
variant: "tonal",
|
|
621
|
+
variant: compact ? "filled" : "tonal",
|
|
571
622
|
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ScanText, { "aria-hidden": "true" }),
|
|
572
623
|
onClick: () => void recognize(),
|
|
573
624
|
disabled: disabled || strokes.length === 0 || status === "recognizing",
|
|
574
625
|
children: "Recognise"
|
|
575
626
|
}
|
|
576
627
|
),
|
|
577
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
628
|
+
!(compact && inputMode === "draw" && status !== "recognized") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
578
629
|
md3Button.Md3Button,
|
|
579
630
|
{
|
|
580
631
|
variant: "filled",
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx","Md3Menu","Md3MenuItem","Md3LoadingIndicator","AlertCircle","Md3Button","RotateCcw","Fragment","Md3TextField","Md3Chip","Undo2","Eraser","Keyboard","PenLine","ScanText"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Md3Button } from \"@nucleux/md3-button\";\nimport { Md3Chip } from \"@nucleux/md3-chip\";\nimport { Md3LoadingIndicator } from \"@nucleux/md3-loading-indicator\";\nimport { Md3Menu, Md3MenuItem } from \"@nucleux/md3-menu\";\nimport { Md3TextField } from \"@nucleux/md3-text-field\";\nimport type {\n HandwritingInputMode,\n HandwritingInputProps,\n HandwritingInputStatus,\n HandwritingPoint,\n HandwritingRecognition,\n HandwritingStroke,\n HandwritingWord,\n} from \"@nucleux/handwriting\";\nimport { AlertCircle, Eraser, Keyboard, PenLine, RotateCcw, ScanText, Undo2 } from \"lucide-react\";\n\n// Same API as the shadcn twin: the props and data shapes are the twin's own types.\nexport type Md3HandwritingInputProps = HandwritingInputProps;\nexport type {\n HandwritingInputVariant as Md3HandwritingInputVariant,\n HandwritingInputConvert as Md3HandwritingInputConvert,\n HandwritingInputMode as Md3HandwritingInputMode,\n HandwritingInputStatus as Md3HandwritingInputStatus,\n HandwritingPoint,\n HandwritingStroke,\n HandwritingWord,\n HandwritingRecognition,\n HandwritingRecognizeRequest,\n HandwritingAcceptDetail,\n} from \"@nucleux/handwriting\";\n\n// useLayoutEffect warns when rendered on the server; fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\nconst wordsText = (words: HandwritingWord[]) => words.map((w) => w.text).join(\" \");\n\n/** The “?” word: a button that opens its alternatives in an MD3 menu. */\nfunction UncertainWord({\n word,\n onChoose,\n}: {\n word: HandwritingWord;\n onChoose: (text: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLSpanElement>(null);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const menuRef = React.useRef<HTMLDivElement>(null);\n const menuId = React.useId();\n const choices = [word.text, ...(word.alternatives ?? [])].filter((t, j, all) => all.indexOf(t) === j);\n\n React.useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() => menuRef.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus());\n const onDown = (e: PointerEvent) => {\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", onDown);\n return () => document.removeEventListener(\"pointerdown\", onDown);\n }, [open]);\n\n const close = () => {\n setOpen(false);\n triggerRef.current?.focus();\n };\n\n const onMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const items = Array.from(menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []);\n const i = items.indexOf(document.activeElement as HTMLElement);\n if (e.key === \"Escape\" || e.key === \"Tab\") {\n if (e.key === \"Escape\") e.preventDefault();\n close();\n } else if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const step = e.key === \"ArrowDown\" ? 1 : -1;\n items[(i + step + items.length) % items.length]?.focus();\n } else if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n items[e.key === \"Home\" ? 0 : items.length - 1]?.focus();\n }\n };\n\n return (\n <span ref={wrapRef} className=\"relative inline-flex\">\n <button\n ref={triggerRef}\n type=\"button\"\n aria-label={`${word.text} — uncertain, choose the right word`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n className={cn(\n \"relative inline-flex h-8 items-center gap-0.5 overflow-hidden rounded-md-sm px-1.5 text-sm text-md-on-surface\",\n \"underline decoration-md-error decoration-dotted decoration-2 underline-offset-4\",\n \"before:absolute before:inset-0 before:bg-md-primary before:opacity-0 before:transition-opacity before:content-['']\",\n \"hover:before:opacity-[0.08] focus-visible:before:opacity-[0.12] active:before:opacity-[0.12]\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-md-primary\",\n \"transition-transform duration-200 active:scale-95 motion-reduce:transition-none\",\n )}\n >\n <span className=\"relative\">{word.text}</span>\n <span aria-hidden=\"true\" className=\"relative font-semibold text-md-error no-underline\">\n ?\n </span>\n </button>\n {open && (\n <Md3Menu\n ref={menuRef}\n id={menuId}\n aria-label=\"Did you write…\"\n onKeyDown={onMenuKeyDown}\n className=\"absolute left-0 top-full z-50 mt-1 animate-nx-fade-in motion-reduce:animate-none\"\n >\n <span aria-hidden=\"true\" className=\"block px-3 pb-1 pt-1 text-xs font-medium text-md-on-surface-variant\">\n Did you write…\n </span>\n {choices.map((alt) => (\n <Md3MenuItem\n key={alt}\n tabIndex={-1}\n onClick={() => {\n onChoose(alt);\n setOpen(false);\n }}\n >\n {alt}\n </Md3MenuItem>\n ))}\n </Md3Menu>\n )}\n </span>\n );\n}\n\n/**\n * Material 3 handwriting input: a pointer-driven writing pad (pen pressure\n * aware) whose ink the app's own recogniser (`onRecognize`) reads into text.\n * The reading appears under the ink, never over it; words the recogniser was\n * unsure of carry a dotted underline and a “?” in the error tone and must be\n * settled from their alternatives (an MD3 menu) before Add to message is\n * enabled, and the reading stays editable in an MD3 text field. Undo stroke,\n * Clear, Retry and a Type-instead fallback are always available, a slow sheen\n * crosses the pad while it is read (still under reduced motion), and nothing is\n * sent when writing finishes. Shares its API with `HandwritingInput` from\n * `@nucleux/handwriting`. Variants: draw-pad, live-ocr, annotation-stroke.\n */\nexport const Md3HandwritingInput = React.forwardRef<HTMLDivElement, Md3HandwritingInputProps>(\n (\n {\n variant = \"draw-pad\",\n onRecognize,\n convert,\n autoDelay = 900,\n onAccept,\n strokes: strokesProp,\n defaultStrokes,\n onStrokesChange,\n defaultRecognition,\n defaultMode = \"draw\",\n strokeWidth = variant === \"annotation-stroke\" ? 3 : 2.5,\n label = \"Handwriting pad\",\n placeholder,\n statusText = \"Recognising your writing…\",\n failureText = \"Couldn’t recognise this writing.\",\n acceptLabel = \"Add to message\",\n typingLabel = \"Type your request\",\n disabled = false,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const mode = convert ?? (variant === \"live-ocr\" ? \"auto\" : \"review\");\n const isAnnotation = variant === \"annotation-stroke\";\n\n const [internalStrokes, setInternalStrokes] = React.useState<HandwritingStroke[]>(defaultStrokes ?? []);\n const strokes = strokesProp ?? internalStrokes;\n const [inputMode, setInputMode] = React.useState<HandwritingInputMode>(defaultMode);\n const [status, setStatus] = React.useState<HandwritingInputStatus>(defaultRecognition ? \"recognized\" : \"idle\");\n const [recognition, setRecognition] = React.useState<HandwritingRecognition | null>(defaultRecognition ?? null);\n const [words, setWords] = React.useState<HandwritingWord[] | null>(defaultRecognition?.words ?? null);\n const [editedText, setEditedText] = React.useState<string | null>(null);\n const [typed, setTyped] = React.useState(\"\");\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const padRef = React.useRef<HTMLDivElement>(null);\n const drawing = React.useRef<HandwritingStroke | null>(null);\n const requestId = React.useRef(0);\n const strokesRef = React.useRef(strokes);\n strokesRef.current = strokes;\n const resultId = React.useId();\n const resultInputRef = React.useRef<HTMLInputElement>(null);\n\n const setStrokes = (next: HandwritingStroke[]) => {\n if (strokesProp === undefined) setInternalStrokes(next);\n onStrokesChange?.(next);\n };\n\n // ---- drawing (copied from @nucleux/handwriting, where it is internal) ---\n const widthFor = (stroke: HandwritingStroke, p: HandwritingPoint) =>\n stroke.pointerType === \"pen\" && p.pressure > 0 ? strokeWidth * (0.4 + p.pressure * 1.2) : strokeWidth;\n\n const noCanvas = React.useRef(false);\n const getContext = () => {\n const canvas = canvasRef.current;\n if (!canvas || noCanvas.current) return null;\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n ctx = canvas.getContext(\"2d\");\n } catch {\n ctx = null;\n }\n if (!ctx) {\n noCanvas.current = true; // e.g. a non-rendering environment\n return null;\n }\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const color = typeof getComputedStyle === \"function\" ? getComputedStyle(canvas).color : \"\";\n ctx.strokeStyle = color || \"currentColor\";\n ctx.fillStyle = ctx.strokeStyle;\n return ctx;\n };\n\n const drawSegment = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, a: HandwritingPoint, b: HandwritingPoint) => {\n ctx.lineWidth = widthFor(stroke, b);\n ctx.beginPath();\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n ctx.stroke();\n };\n\n const drawDot = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, p: HandwritingPoint) => {\n ctx.beginPath();\n ctx.arc(p.x, p.y, widthFor(stroke, p) / 2, 0, Math.PI * 2);\n ctx.fill();\n };\n\n const redraw = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = getContext();\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const stroke of strokesRef.current) {\n const pts = stroke.points;\n if (pts.length === 1) drawDot(ctx, stroke, pts[0]);\n for (let i = 1; i < pts.length; i++) drawSegment(ctx, stroke, pts[i - 1], pts[i]);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokeWidth]);\n\n // Keep the backing store matched to the pad size (crisp on HiDPI).\n React.useEffect(() => {\n const pad = padRef.current;\n const canvas = canvasRef.current;\n if (!pad || !canvas || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n const rect = pad.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const dpr = window.devicePixelRatio || 1;\n canvas.width = Math.round(rect.width * dpr);\n canvas.height = Math.round(rect.height * dpr);\n redraw();\n });\n ro.observe(pad);\n return () => ro.disconnect();\n }, [redraw, inputMode]);\n\n const hasDrawn = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (strokes.length === 0 && !hasDrawn.current) return;\n hasDrawn.current = true;\n redraw();\n }, [strokes, redraw]);\n\n const pointFrom = (e: React.PointerEvent<HTMLCanvasElement> | PointerEvent): HandwritingPoint => {\n const rect = canvasRef.current!.getBoundingClientRect();\n return {\n x: (e.clientX ?? 0) - rect.left,\n y: (e.clientY ?? 0) - rect.top,\n pressure: typeof e.pressure === \"number\" && e.pressure > 0 ? e.pressure : 0.5,\n t: e.timeStamp ?? Date.now(),\n };\n };\n\n const onPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (disabled || status === \"recognizing\") return;\n if (e.pointerType === \"mouse\" && e.button !== 0) return;\n e.preventDefault();\n e.currentTarget.setPointerCapture?.(e.pointerId);\n const stroke: HandwritingStroke = { pointerType: e.pointerType || \"mouse\", points: [pointFrom(e)] };\n drawing.current = stroke;\n const ctx = getContext();\n if (ctx) drawDot(ctx, stroke, stroke.points[0]);\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const stroke = drawing.current;\n if (!stroke) return;\n const native = e.nativeEvent as PointerEvent & { getCoalescedEvents?: () => PointerEvent[] };\n const events = native.getCoalescedEvents?.() ?? [];\n const ctx = getContext();\n for (const ev of events.length ? events : [native]) {\n const p = pointFrom(ev);\n const prev = stroke.points[stroke.points.length - 1];\n stroke.points.push(p);\n if (ctx) drawSegment(ctx, stroke, prev, p);\n }\n };\n\n const endStroke = () => {\n const stroke = drawing.current;\n if (!stroke) return;\n drawing.current = null;\n setStrokes([...strokesRef.current, stroke]);\n };\n\n // ---- recognition -------------------------------------------------------\n const toImage = (type = \"image/png\") =>\n new Promise<Blob | null>((resolve) => {\n const canvas = canvasRef.current;\n if (!canvas || typeof canvas.toBlob !== \"function\") return resolve(null);\n try {\n canvas.toBlob((blob) => resolve(blob), type);\n } catch {\n resolve(null);\n }\n });\n\n const applyRecognition = (result: HandwritingRecognition) => {\n setRecognition(result);\n setWords(result.words ?? null);\n setEditedText(null);\n setStatus(\"recognized\");\n const unsure = result.words?.filter((w) => w.uncertain).length ?? 0;\n setAnnouncement(\n `Recognised: ${result.words ? wordsText(result.words) : result.text}.` +\n (unsure ? ` ${unsure} ${unsure === 1 ? \"word needs\" : \"words need\"} checking.` : \"\"),\n );\n };\n\n const recognize = async () => {\n if (!onRecognize || strokesRef.current.length === 0) return;\n const id = ++requestId.current;\n setStatus(\"recognizing\");\n setAnnouncement(typeof statusText === \"string\" ? statusText : \"Recognising your writing…\");\n const rect = padRef.current?.getBoundingClientRect();\n try {\n const result = await onRecognize({\n strokes: strokesRef.current,\n width: rect?.width ?? 0,\n height: rect?.height ?? 0,\n toImage,\n });\n if (id !== requestId.current) return;\n applyRecognition(result);\n } catch {\n if (id !== requestId.current) return;\n setStatus(\"error\");\n setAnnouncement(typeof failureText === \"string\" ? failureText : \"Couldn’t recognise this writing.\");\n }\n };\n\n // New ink makes an old reading stale: auto mode re-reads after a pause,\n // review mode drops the reading until the person asks again.\n const prevStrokes = React.useRef(strokes);\n React.useEffect(() => {\n if (prevStrokes.current === strokes) return;\n prevStrokes.current = strokes;\n requestId.current += 1;\n if (strokes.length === 0) {\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n return;\n }\n if (mode === \"auto\" && onRecognize) {\n const timer = setTimeout(() => void recognize(), autoDelay);\n return () => clearTimeout(timer);\n }\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokes]);\n\n // ---- result ------------------------------------------------------------\n const unsettled = editedText === null && !!words?.some((w) => w.uncertain);\n const resultText = editedText ?? (words ? wordsText(words) : (recognition?.text ?? \"\"));\n\n const settleWord = (index: number, text: string) => {\n if (!words) return;\n const next = words.map((w, i) => (i === index ? { text, uncertain: false } : w));\n setWords(next);\n const left = next.filter((w) => w.uncertain).length;\n // The word buttons go away once everything is settled — keep focus in the reading.\n if (!left) requestAnimationFrame(() => resultInputRef.current?.focus());\n setAnnouncement(`“${text}” chosen.${left ? ` ${left} still to check.` : \" Ready to add.\"}`);\n };\n\n const reset = () => {\n requestId.current += 1;\n setStrokes([]);\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n };\n\n const accept = () => {\n if (inputMode === \"type\") {\n const text = typed.trim();\n if (!text) return;\n onAccept?.(text, { source: \"typed\", strokes: [] });\n setTyped(\"\");\n } else {\n const text = resultText.trim();\n if (!text || unsettled) return;\n onAccept?.(text, { source: \"handwriting\", strokes, recognition: recognition ?? undefined });\n reset();\n }\n setAnnouncement(\"Added to message.\");\n };\n\n const undoStroke = () => setStrokes(strokes.slice(0, -1));\n\n const setRef = (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const emptyHint =\n placeholder ?? (isAnnotation ? \"Draw on the content to mark what you mean\" : \"Draw or write…\");\n\n return (\n <div\n ref={setRef}\n role=\"group\"\n aria-label={isAnnotation ? \"Annotation input\" : \"Handwriting input\"}\n data-variant={variant}\n data-status={status}\n className={cn(\"flex flex-col gap-3 text-md-on-surface\", className)}\n {...props}\n >\n {inputMode === \"type\" ? (\n <textarea\n aria-label={typingLabel}\n placeholder={typingLabel}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none rounded-md-xs border border-md-outline bg-transparent px-4 py-3 text-base text-md-on-surface outline-none transition-colors\",\n \"placeholder:text-md-on-surface-variant focus:border-2 focus:border-md-primary focus:px-[15px] focus:py-[11px]\",\n \"disabled:cursor-not-allowed disabled:opacity-[0.38]\",\n )}\n />\n ) : (\n <div\n ref={padRef}\n className={cn(\n \"relative overflow-hidden rounded-md-lg\",\n isAnnotation\n ? \"min-h-40 border border-md-outline-variant\"\n : \"h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low\",\n variant === \"live-ocr\" && \"h-36 border border-solid border-md-outline-variant\",\n disabled && \"opacity-[0.38]\",\n )}\n aria-busy={status === \"recognizing\" || undefined}\n >\n {isAnnotation && children}\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={`${label}${strokes.length ? ` — ${strokes.length} ${strokes.length === 1 ? \"stroke\" : \"strokes\"}` : \" — empty\"}`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endStroke}\n onPointerCancel={endStroke}\n className={cn(\n \"absolute inset-0 size-full touch-none\",\n disabled ? \"cursor-not-allowed\" : \"cursor-crosshair\",\n isAnnotation ? \"text-md-error\" : \"text-md-on-surface\",\n )}\n />\n {strokes.length === 0 && (\n <p\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute text-xs text-md-on-surface-variant\",\n isAnnotation\n ? \"bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 font-medium\"\n : \"inset-x-0 bottom-3 text-center\",\n )}\n >\n {emptyHint}\n </p>\n )}\n {isAnnotation && status === \"recognized\" && resultText && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium text-md-on-surface shadow-md-1\"\n >\n “{resultText}”\n </span>\n )}\n {status === \"recognizing\" && (\n // A slow, low-contrast sheen while the ink is read; the ink stays visible beneath it.\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 animate-pulse bg-md-primary/[0.08] motion-reduce:animate-none\"\n />\n )}\n </div>\n )}\n\n {/* Reading — under the ink, never over it. */}\n {inputMode === \"draw\" && status === \"recognizing\" && (\n <div className=\"flex items-center gap-2 text-sm text-md-on-surface-variant\">\n <Md3LoadingIndicator size={24} aria-hidden=\"true\" />\n {statusText}\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"error\" && (\n <div className=\"flex flex-col gap-2 rounded-md-md bg-md-error-container px-3 py-2.5 text-md-on-error-container\">\n <p className=\"flex items-center gap-2 text-sm\">\n <AlertCircle className=\"size-[18px] shrink-0\" aria-hidden=\"true\" />\n {failureText} Your writing is kept.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Md3Button variant=\"filled\" icon={<RotateCcw aria-hidden=\"true\" />} onClick={() => void recognize()}>\n Retry\n </Md3Button>\n <Md3Button variant=\"text\" onClick={reset} className=\"text-md-on-error-container\">\n Rewrite\n </Md3Button>\n </div>\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"recognized\" && recognition && (\n <div\n id={resultId}\n className=\"flex flex-col gap-2 border-t border-md-outline-variant pt-3\"\n data-slot=\"handwriting-result\"\n >\n <span className=\"text-xs font-medium tracking-[0.5px] text-md-on-surface-variant\">\n {isAnnotation ? \"Read as an instruction\" : \"Recognised\"}\n </span>\n {unsettled && words ? (\n <>\n <div className=\"flex flex-wrap items-center gap-1 text-base text-md-on-surface\">\n {words.map((w, i) =>\n w.uncertain ? (\n <UncertainWord key={i} word={w} onChoose={(text) => settleWord(i, text)} />\n ) : (\n <span key={i} className=\"animate-nx-fade-in motion-reduce:animate-none\">\n {w.text}\n </span>\n ),\n )}\n </div>\n <p className=\"text-xs text-md-on-surface-variant\">\n Check the words marked “?” to add this to your message.{\" \"}\n <button\n type=\"button\"\n onClick={() => setEditedText(resultText)}\n className=\"rounded-md-xs font-medium text-md-primary underline-offset-2 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-md-primary\"\n >\n Edit text instead\n </button>\n </p>\n </>\n ) : (\n <Md3TextField\n ref={resultInputRef}\n label=\"Recognised text\"\n value={resultText}\n onChange={(e) => setEditedText(e.target.value)}\n disabled={disabled}\n />\n )}\n {!unsettled && recognition.alternatives && recognition.alternatives.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Other readings\">\n <span className=\"text-xs text-md-on-surface-variant\">Other readings:</span>\n {recognition.alternatives.map((alt) => (\n <Md3Chip key={alt} variant=\"filter\" selected={resultText === alt} onClick={() => setEditedText(alt)}>\n {alt}\n </Md3Chip>\n ))}\n </div>\n )}\n </div>\n )}\n\n <div className=\"flex flex-wrap items-center gap-1\">\n {inputMode === \"draw\" && (\n <>\n <Md3Button\n variant=\"text\"\n icon={<Undo2 aria-hidden=\"true\" />}\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Undo stroke\n </Md3Button>\n <Md3Button\n variant=\"text\"\n icon={<Eraser aria-hidden=\"true\" />}\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n >\n Clear\n </Md3Button>\n </>\n )}\n <Md3Button\n variant=\"text\"\n icon={inputMode === \"draw\" ? <Keyboard aria-hidden=\"true\" /> : <PenLine aria-hidden=\"true\" />}\n onClick={() => setInputMode(inputMode === \"draw\" ? \"type\" : \"draw\")}\n disabled={disabled}\n >\n {inputMode === \"draw\" ? \"Type instead\" : \"Write instead\"}\n </Md3Button>\n <span className=\"flex-1\" />\n {inputMode === \"draw\" && onRecognize && (status !== \"recognized\" || mode === \"review\") && (\n <Md3Button\n variant=\"tonal\"\n icon={<ScanText aria-hidden=\"true\" />}\n onClick={() => void recognize()}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Recognise\n </Md3Button>\n )}\n <Md3Button\n variant=\"filled\"\n onClick={accept}\n disabled={\n disabled ||\n (inputMode === \"type\" ? !typed.trim() : status !== \"recognized\" || unsettled || !resultText.trim())\n }\n aria-describedby={inputMode === \"draw\" && status === \"recognized\" ? resultId : undefined}\n >\n {acceptLabel}\n </Md3Button>\n </div>\n\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </div>\n );\n },\n);\nMd3HandwritingInput.displayName = \"Md3HandwritingInput\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx","Md3Menu","Md3MenuItem","PenLine","Fragment","Md3IconButton","Undo2","Eraser","X","Md3LoadingIndicator","AlertCircle","Md3Button","RotateCcw","Md3TextField","Md3Chip","Keyboard","ScanText"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Md3Button } from \"@nucleux/md3-button\";\nimport { Md3Chip } from \"@nucleux/md3-chip\";\nimport { Md3IconButton } from \"@nucleux/md3-icon-button\";\nimport { Md3LoadingIndicator } from \"@nucleux/md3-loading-indicator\";\nimport { Md3Menu, Md3MenuItem } from \"@nucleux/md3-menu\";\nimport { Md3TextField } from \"@nucleux/md3-text-field\";\nimport type {\n HandwritingInputMode,\n HandwritingInputProps,\n HandwritingInputStatus,\n HandwritingPoint,\n HandwritingRecognition,\n HandwritingStroke,\n HandwritingWord,\n} from \"@nucleux/handwriting\";\nimport { AlertCircle, Eraser, Keyboard, PenLine, RotateCcw, ScanText, Undo2, X } from \"lucide-react\";\n\n// Same API as the shadcn twin: the props and data shapes are the twin's own types.\nexport type Md3HandwritingInputProps = HandwritingInputProps;\nexport type {\n HandwritingInputVariant as Md3HandwritingInputVariant,\n HandwritingInputConvert as Md3HandwritingInputConvert,\n HandwritingInputMode as Md3HandwritingInputMode,\n HandwritingInputStatus as Md3HandwritingInputStatus,\n HandwritingPoint,\n HandwritingStroke,\n HandwritingWord,\n HandwritingRecognition,\n HandwritingRecognizeRequest,\n HandwritingAcceptDetail,\n} from \"@nucleux/handwriting\";\n\n// useLayoutEffect warns when rendered on the server; fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\nconst wordsText = (words: HandwritingWord[]) => words.map((w) => w.text).join(\" \");\n\n/** The “?” word: a button that opens its alternatives in an MD3 menu. */\nfunction UncertainWord({\n word,\n onChoose,\n}: {\n word: HandwritingWord;\n onChoose: (text: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLSpanElement>(null);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const menuRef = React.useRef<HTMLDivElement>(null);\n const menuId = React.useId();\n const choices = [word.text, ...(word.alternatives ?? [])].filter((t, j, all) => all.indexOf(t) === j);\n\n React.useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() => menuRef.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus());\n const onDown = (e: PointerEvent) => {\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", onDown);\n return () => document.removeEventListener(\"pointerdown\", onDown);\n }, [open]);\n\n const close = () => {\n setOpen(false);\n triggerRef.current?.focus();\n };\n\n const onMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const items = Array.from(menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []);\n const i = items.indexOf(document.activeElement as HTMLElement);\n if (e.key === \"Escape\" || e.key === \"Tab\") {\n if (e.key === \"Escape\") e.preventDefault();\n close();\n } else if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const step = e.key === \"ArrowDown\" ? 1 : -1;\n items[(i + step + items.length) % items.length]?.focus();\n } else if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n items[e.key === \"Home\" ? 0 : items.length - 1]?.focus();\n }\n };\n\n return (\n <span ref={wrapRef} className=\"relative inline-flex\">\n <button\n ref={triggerRef}\n type=\"button\"\n aria-label={`${word.text} — uncertain, choose the right word`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n className={cn(\n \"relative inline-flex h-8 items-center gap-0.5 overflow-hidden rounded-md-sm px-1.5 text-sm text-md-on-surface\",\n \"underline decoration-md-error decoration-dotted decoration-2 underline-offset-4\",\n \"before:absolute before:inset-0 before:bg-md-primary before:opacity-0 before:transition-opacity before:content-['']\",\n \"hover:before:opacity-[0.08] focus-visible:before:opacity-[0.12] active:before:opacity-[0.12]\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-md-primary\",\n \"transition-transform duration-200 active:scale-95 motion-reduce:transition-none\",\n )}\n >\n <span className=\"relative\">{word.text}</span>\n <span aria-hidden=\"true\" className=\"relative font-semibold text-md-error no-underline\">\n ?\n </span>\n </button>\n {open && (\n <Md3Menu\n ref={menuRef}\n id={menuId}\n aria-label=\"Did you write…\"\n onKeyDown={onMenuKeyDown}\n className=\"absolute left-0 top-full z-50 mt-1 animate-nx-fade-in motion-reduce:animate-none\"\n >\n <span aria-hidden=\"true\" className=\"block px-3 pb-1 pt-1 text-xs font-medium text-md-on-surface-variant\">\n Did you write…\n </span>\n {choices.map((alt) => (\n <Md3MenuItem\n key={alt}\n tabIndex={-1}\n onClick={() => {\n onChoose(alt);\n setOpen(false);\n }}\n >\n {alt}\n </Md3MenuItem>\n ))}\n </Md3Menu>\n )}\n </span>\n );\n}\n\n/**\n * Material 3 handwriting input: a pointer-driven writing pad (pen pressure\n * aware) whose ink the app's own recogniser (`onRecognize`) reads into text.\n * The reading appears under the ink, never over it; words the recogniser was\n * unsure of carry a dotted underline and a “?” in the error tone and must be\n * settled from their alternatives (an MD3 menu) before Add to message is\n * enabled, and the reading stays editable in an MD3 text field. Undo stroke,\n * Clear, Retry and a Type-instead fallback are always available, a slow sheen\n * crosses the pad while it is read (still under reduced motion), and nothing is\n * sent when writing finishes. Shares its API with `HandwritingInput` from\n * `@nucleux/handwriting`. Variants: draw-pad, live-ocr, annotation-stroke.\n */\nexport const Md3HandwritingInput = React.forwardRef<HTMLDivElement, Md3HandwritingInputProps>(\n (\n {\n variant = \"draw-pad\",\n onRecognize,\n convert,\n autoDelay = 900,\n onAccept,\n strokes: strokesProp,\n defaultStrokes,\n onStrokesChange,\n defaultRecognition,\n defaultMode = \"draw\",\n strokeWidth = variant === \"annotation-stroke\" ? 3 : 2.5,\n label = \"Handwriting pad\",\n placeholder,\n statusText = \"Recognising your writing…\",\n failureText = \"Couldn’t recognise this writing.\",\n acceptLabel = \"Add to message\",\n typingLabel = \"Type your request\",\n disabled = false,\n padLabel,\n compact = false,\n onClose,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const mode = convert ?? (variant === \"live-ocr\" ? \"auto\" : \"review\");\n const isAnnotation = variant === \"annotation-stroke\";\n\n const [internalStrokes, setInternalStrokes] = React.useState<HandwritingStroke[]>(defaultStrokes ?? []);\n const strokes = strokesProp ?? internalStrokes;\n const [inputMode, setInputMode] = React.useState<HandwritingInputMode>(defaultMode);\n const [status, setStatus] = React.useState<HandwritingInputStatus>(defaultRecognition ? \"recognized\" : \"idle\");\n const [recognition, setRecognition] = React.useState<HandwritingRecognition | null>(defaultRecognition ?? null);\n const [words, setWords] = React.useState<HandwritingWord[] | null>(defaultRecognition?.words ?? null);\n const [editedText, setEditedText] = React.useState<string | null>(null);\n const [typed, setTyped] = React.useState(\"\");\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const padRef = React.useRef<HTMLDivElement>(null);\n const drawing = React.useRef<HandwritingStroke | null>(null);\n const requestId = React.useRef(0);\n const strokesRef = React.useRef(strokes);\n strokesRef.current = strokes;\n const resultId = React.useId();\n const resultInputRef = React.useRef<HTMLInputElement>(null);\n\n const setStrokes = (next: HandwritingStroke[]) => {\n if (strokesProp === undefined) setInternalStrokes(next);\n onStrokesChange?.(next);\n };\n\n // ---- drawing (copied from @nucleux/handwriting, where it is internal) ---\n const widthFor = (stroke: HandwritingStroke, p: HandwritingPoint) =>\n stroke.pointerType === \"pen\" && p.pressure > 0 ? strokeWidth * (0.4 + p.pressure * 1.2) : strokeWidth;\n\n const noCanvas = React.useRef(false);\n const getContext = () => {\n const canvas = canvasRef.current;\n if (!canvas || noCanvas.current) return null;\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n ctx = canvas.getContext(\"2d\");\n } catch {\n ctx = null;\n }\n if (!ctx) {\n noCanvas.current = true; // e.g. a non-rendering environment\n return null;\n }\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const color = typeof getComputedStyle === \"function\" ? getComputedStyle(canvas).color : \"\";\n ctx.strokeStyle = color || \"currentColor\";\n ctx.fillStyle = ctx.strokeStyle;\n return ctx;\n };\n\n const drawSegment = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, a: HandwritingPoint, b: HandwritingPoint) => {\n ctx.lineWidth = widthFor(stroke, b);\n ctx.beginPath();\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n ctx.stroke();\n };\n\n const drawDot = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, p: HandwritingPoint) => {\n ctx.beginPath();\n ctx.arc(p.x, p.y, widthFor(stroke, p) / 2, 0, Math.PI * 2);\n ctx.fill();\n };\n\n const redraw = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = getContext();\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const stroke of strokesRef.current) {\n const pts = stroke.points;\n if (pts.length === 1) drawDot(ctx, stroke, pts[0]);\n for (let i = 1; i < pts.length; i++) drawSegment(ctx, stroke, pts[i - 1], pts[i]);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokeWidth]);\n\n // Keep the backing store matched to the pad size (crisp on HiDPI).\n React.useEffect(() => {\n const pad = padRef.current;\n const canvas = canvasRef.current;\n if (!pad || !canvas || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n const rect = pad.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const dpr = window.devicePixelRatio || 1;\n canvas.width = Math.round(rect.width * dpr);\n canvas.height = Math.round(rect.height * dpr);\n redraw();\n });\n ro.observe(pad);\n return () => ro.disconnect();\n }, [redraw, inputMode]);\n\n const hasDrawn = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (strokes.length === 0 && !hasDrawn.current) return;\n hasDrawn.current = true;\n redraw();\n }, [strokes, redraw]);\n\n const pointFrom = (e: React.PointerEvent<HTMLCanvasElement> | PointerEvent): HandwritingPoint => {\n const rect = canvasRef.current!.getBoundingClientRect();\n return {\n x: (e.clientX ?? 0) - rect.left,\n y: (e.clientY ?? 0) - rect.top,\n pressure: typeof e.pressure === \"number\" && e.pressure > 0 ? e.pressure : 0.5,\n t: e.timeStamp ?? Date.now(),\n };\n };\n\n const onPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (disabled || status === \"recognizing\") return;\n if (e.pointerType === \"mouse\" && e.button !== 0) return;\n e.preventDefault();\n e.currentTarget.setPointerCapture?.(e.pointerId);\n const stroke: HandwritingStroke = { pointerType: e.pointerType || \"mouse\", points: [pointFrom(e)] };\n drawing.current = stroke;\n const ctx = getContext();\n if (ctx) drawDot(ctx, stroke, stroke.points[0]);\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const stroke = drawing.current;\n if (!stroke) return;\n const native = e.nativeEvent as PointerEvent & { getCoalescedEvents?: () => PointerEvent[] };\n const events = native.getCoalescedEvents?.() ?? [];\n const ctx = getContext();\n for (const ev of events.length ? events : [native]) {\n const p = pointFrom(ev);\n const prev = stroke.points[stroke.points.length - 1];\n stroke.points.push(p);\n if (ctx) drawSegment(ctx, stroke, prev, p);\n }\n };\n\n const endStroke = () => {\n const stroke = drawing.current;\n if (!stroke) return;\n drawing.current = null;\n setStrokes([...strokesRef.current, stroke]);\n };\n\n // ---- recognition -------------------------------------------------------\n const toImage = (type = \"image/png\") =>\n new Promise<Blob | null>((resolve) => {\n const canvas = canvasRef.current;\n if (!canvas || typeof canvas.toBlob !== \"function\") return resolve(null);\n try {\n canvas.toBlob((blob) => resolve(blob), type);\n } catch {\n resolve(null);\n }\n });\n\n const applyRecognition = (result: HandwritingRecognition) => {\n setRecognition(result);\n setWords(result.words ?? null);\n setEditedText(null);\n setStatus(\"recognized\");\n const unsure = result.words?.filter((w) => w.uncertain).length ?? 0;\n setAnnouncement(\n `Recognised: ${result.words ? wordsText(result.words) : result.text}.` +\n (unsure ? ` ${unsure} ${unsure === 1 ? \"word needs\" : \"words need\"} checking.` : \"\"),\n );\n };\n\n const recognize = async () => {\n if (!onRecognize || strokesRef.current.length === 0) return;\n const id = ++requestId.current;\n setStatus(\"recognizing\");\n setAnnouncement(typeof statusText === \"string\" ? statusText : \"Recognising your writing…\");\n const rect = padRef.current?.getBoundingClientRect();\n try {\n const result = await onRecognize({\n strokes: strokesRef.current,\n width: rect?.width ?? 0,\n height: rect?.height ?? 0,\n toImage,\n });\n if (id !== requestId.current) return;\n applyRecognition(result);\n } catch {\n if (id !== requestId.current) return;\n setStatus(\"error\");\n setAnnouncement(typeof failureText === \"string\" ? failureText : \"Couldn’t recognise this writing.\");\n }\n };\n\n // New ink makes an old reading stale: auto mode re-reads after a pause,\n // review mode drops the reading until the person asks again.\n const prevStrokes = React.useRef(strokes);\n React.useEffect(() => {\n if (prevStrokes.current === strokes) return;\n prevStrokes.current = strokes;\n requestId.current += 1;\n if (strokes.length === 0) {\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n return;\n }\n if (mode === \"auto\" && onRecognize) {\n const timer = setTimeout(() => void recognize(), autoDelay);\n return () => clearTimeout(timer);\n }\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokes]);\n\n // ---- result ------------------------------------------------------------\n const unsettled = editedText === null && !!words?.some((w) => w.uncertain);\n const resultText = editedText ?? (words ? wordsText(words) : (recognition?.text ?? \"\"));\n\n const settleWord = (index: number, text: string) => {\n if (!words) return;\n const next = words.map((w, i) => (i === index ? { text, uncertain: false } : w));\n setWords(next);\n const left = next.filter((w) => w.uncertain).length;\n // The word buttons go away once everything is settled — keep focus in the reading.\n if (!left) requestAnimationFrame(() => resultInputRef.current?.focus());\n setAnnouncement(`“${text}” chosen.${left ? ` ${left} still to check.` : \" Ready to add.\"}`);\n };\n\n const reset = () => {\n requestId.current += 1;\n setStrokes([]);\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n };\n\n const accept = () => {\n if (inputMode === \"type\") {\n const text = typed.trim();\n if (!text) return;\n onAccept?.(text, { source: \"typed\", strokes: [] });\n setTyped(\"\");\n } else {\n const text = resultText.trim();\n if (!text || unsettled) return;\n onAccept?.(text, { source: \"handwriting\", strokes, recognition: recognition ?? undefined });\n reset();\n }\n setAnnouncement(\"Added to message.\");\n };\n\n const undoStroke = () => setStrokes(strokes.slice(0, -1));\n // Compact: once there is a reading, the one-line result carries the accept button.\n const banner =\n compact && inputMode === \"draw\" && status === \"recognized\" && !!recognition && !unsettled && editedText === null;\n const showToolbar = !banner;\n\n const setRef = (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const emptyHint =\n placeholder ?? (isAnnotation ? \"Draw on the content to mark what you mean\" : \"Draw or write…\");\n\n return (\n <div\n ref={setRef}\n role=\"group\"\n aria-label={isAnnotation ? \"Annotation input\" : \"Handwriting input\"}\n data-variant={variant}\n data-status={status}\n className={cn(\"flex flex-col gap-3 text-md-on-surface\", className)}\n {...props}\n >\n {(padLabel != null || (compact && (inputMode === \"draw\" || onClose))) && (\n <div className=\"-mb-1 flex items-center gap-2\">\n <PenLine aria-hidden=\"true\" className=\"size-5 shrink-0 text-md-primary\" />\n <p className=\"flex-1 text-sm font-medium tracking-[0.1px] text-md-on-surface-variant\">{padLabel}</p>\n {compact && inputMode === \"draw\" && (\n <>\n <Md3IconButton\n aria-label=\"Undo stroke\"\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n className=\"[&_svg]:size-5\"\n >\n <Undo2 aria-hidden=\"true\" />\n </Md3IconButton>\n <Md3IconButton\n aria-label=\"Clear\"\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n className=\"[&_svg]:size-5\"\n >\n <Eraser aria-hidden=\"true\" />\n </Md3IconButton>\n </>\n )}\n {compact && onClose && (\n <Md3IconButton aria-label=\"Close handwriting\" onClick={onClose} className=\"[&_svg]:size-5\">\n <X aria-hidden=\"true\" />\n </Md3IconButton>\n )}\n </div>\n )}\n\n {inputMode === \"type\" ? (\n <textarea\n aria-label={typingLabel}\n placeholder={typingLabel}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none rounded-md-xs border border-md-outline bg-transparent px-4 py-3 text-base text-md-on-surface outline-none transition-colors\",\n \"placeholder:text-md-on-surface-variant focus:border-2 focus:border-md-primary focus:px-[15px] focus:py-[11px]\",\n \"disabled:cursor-not-allowed disabled:opacity-[0.38]\",\n )}\n />\n ) : (\n <div\n ref={padRef}\n className={cn(\n \"relative overflow-hidden rounded-md-lg\",\n isAnnotation\n ? \"min-h-40 border border-md-outline-variant\"\n : compact\n ? \"h-28 rounded-b-md-xs border-b border-md-outline-variant bg-md-surface-container-low\"\n : \"h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low\",\n variant === \"live-ocr\" && \"h-36 border border-solid border-md-outline-variant\",\n disabled && \"opacity-[0.38]\",\n )}\n aria-busy={status === \"recognizing\" || undefined}\n >\n {isAnnotation && children}\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={`${label}${strokes.length ? ` — ${strokes.length} ${strokes.length === 1 ? \"stroke\" : \"strokes\"}` : \" — empty\"}`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endStroke}\n onPointerCancel={endStroke}\n className={cn(\n \"absolute inset-0 size-full touch-none\",\n disabled ? \"cursor-not-allowed\" : \"cursor-crosshair\",\n isAnnotation ? \"text-md-error\" : \"text-md-on-surface\",\n )}\n />\n {compact && !isAnnotation && (\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute inset-x-0 top-[49%] border-t border-md-outline-variant\" />\n )}\n {strokes.length === 0 && (\n <p\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute text-md-on-surface-variant\",\n isAnnotation\n ? \"bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium\"\n : compact\n ? \"left-4 top-[23%] text-base\"\n : \"inset-x-0 bottom-3 text-center text-xs\",\n )}\n >\n {emptyHint}\n </p>\n )}\n {isAnnotation && status === \"recognized\" && resultText && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium text-md-on-surface shadow-md-1\"\n >\n “{resultText}”\n </span>\n )}\n {status === \"recognizing\" && (\n // A slow, low-contrast sheen while the ink is read; the ink stays visible beneath it.\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 animate-pulse bg-md-primary/[0.08] motion-reduce:animate-none\"\n />\n )}\n </div>\n )}\n\n {/* Reading — under the ink, never over it. */}\n {inputMode === \"draw\" && status === \"recognizing\" && (\n <div className=\"flex items-center gap-2 text-sm text-md-on-surface-variant\">\n <Md3LoadingIndicator size={24} aria-hidden=\"true\" />\n {statusText}\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"error\" && (\n <div className=\"flex flex-col gap-2 rounded-md-md bg-md-error-container px-3 py-2.5 text-md-on-error-container\">\n <p className=\"flex items-center gap-2 text-sm\">\n <AlertCircle className=\"size-[18px] shrink-0\" aria-hidden=\"true\" />\n {failureText} Your writing is kept.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Md3Button variant=\"filled\" icon={<RotateCcw aria-hidden=\"true\" />} onClick={() => void recognize()}>\n Retry\n </Md3Button>\n <Md3Button variant=\"text\" onClick={reset} className=\"text-md-on-error-container\">\n Rewrite\n </Md3Button>\n </div>\n </div>\n )}\n\n {banner && (\n <div\n id={resultId}\n data-slot=\"handwriting-result\"\n className=\"flex items-center gap-3 rounded-md-md bg-md-secondary-container py-2 pl-4 pr-2 text-md-on-secondary-container\"\n >\n <p className=\"min-w-0 flex-1 text-sm font-medium\">\n {isAnnotation ? \"Read as\" : \"Recognised\"}: “{resultText}”\n </p>\n <Md3Button variant=\"filled\" onClick={accept} disabled={disabled || !resultText.trim()}>\n {acceptLabel}\n </Md3Button>\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"recognized\" && recognition && !banner && (\n <div\n id={resultId}\n className=\"flex flex-col gap-2 border-t border-md-outline-variant pt-3\"\n data-slot=\"handwriting-result\"\n >\n <span className=\"text-xs font-medium tracking-[0.5px] text-md-on-surface-variant\">\n {isAnnotation ? \"Read as an instruction\" : \"Recognised\"}\n </span>\n {unsettled && words ? (\n <>\n <div className=\"flex flex-wrap items-center gap-1 text-base text-md-on-surface\">\n {words.map((w, i) =>\n w.uncertain ? (\n <UncertainWord key={i} word={w} onChoose={(text) => settleWord(i, text)} />\n ) : (\n <span key={i} className=\"animate-nx-fade-in motion-reduce:animate-none\">\n {w.text}\n </span>\n ),\n )}\n </div>\n <p className=\"text-xs text-md-on-surface-variant\">\n Check the words marked “?” to add this to your message.{\" \"}\n <button\n type=\"button\"\n onClick={() => setEditedText(resultText)}\n className=\"rounded-md-xs font-medium text-md-primary underline-offset-2 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-md-primary\"\n >\n Edit text instead\n </button>\n </p>\n </>\n ) : (\n <Md3TextField\n ref={resultInputRef}\n label=\"Recognised text\"\n value={resultText}\n onChange={(e) => setEditedText(e.target.value)}\n disabled={disabled}\n />\n )}\n {!unsettled && recognition.alternatives && recognition.alternatives.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Other readings\">\n <span className=\"text-xs text-md-on-surface-variant\">Other readings:</span>\n {recognition.alternatives.map((alt) => (\n <Md3Chip key={alt} variant=\"filter\" selected={resultText === alt} onClick={() => setEditedText(alt)}>\n {alt}\n </Md3Chip>\n ))}\n </div>\n )}\n </div>\n )}\n\n {showToolbar && (\n <div className=\"flex flex-wrap items-center gap-1\">\n {inputMode === \"draw\" && !compact && (\n <>\n <Md3Button\n variant=\"text\"\n icon={<Undo2 aria-hidden=\"true\" />}\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Undo stroke\n </Md3Button>\n <Md3Button\n variant=\"text\"\n icon={<Eraser aria-hidden=\"true\" />}\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n >\n Clear\n </Md3Button>\n </>\n )}\n <Md3Button\n variant=\"text\"\n icon={inputMode === \"draw\" ? <Keyboard aria-hidden=\"true\" /> : <PenLine aria-hidden=\"true\" />}\n onClick={() => setInputMode(inputMode === \"draw\" ? \"type\" : \"draw\")}\n disabled={disabled}\n >\n {inputMode === \"draw\" ? \"Type instead\" : \"Write instead\"}\n </Md3Button>\n <span className=\"flex-1\" />\n {inputMode === \"draw\" && onRecognize && (status !== \"recognized\" || mode === \"review\") && (\n <Md3Button\n variant={compact ? \"filled\" : \"tonal\"}\n icon={<ScanText aria-hidden=\"true\" />}\n onClick={() => void recognize()}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Recognise\n </Md3Button>\n )}\n {!(compact && inputMode === \"draw\" && status !== \"recognized\") && (\n <Md3Button\n variant=\"filled\"\n onClick={accept}\n disabled={\n disabled ||\n (inputMode === \"type\" ? !typed.trim() : status !== \"recognized\" || unsettled || !resultText.trim())\n }\n aria-describedby={inputMode === \"draw\" && status === \"recognized\" ? resultId : undefined}\n >\n {acceptLabel}\n </Md3Button>\n )}\n </div>\n )}\n\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </div>\n );\n },\n);\nMd3HandwritingInput.displayName = \"Md3HandwritingInput\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,11 @@ import * as React from 'react';
|
|
|
3
3
|
import { cn } from '@nucleux/utils';
|
|
4
4
|
import { Md3Button } from '@nucleux/md3-button';
|
|
5
5
|
import { Md3Chip } from '@nucleux/md3-chip';
|
|
6
|
+
import { Md3IconButton } from '@nucleux/md3-icon-button';
|
|
6
7
|
import { Md3LoadingIndicator } from '@nucleux/md3-loading-indicator';
|
|
7
8
|
import { Md3Menu, Md3MenuItem } from '@nucleux/md3-menu';
|
|
8
9
|
import { Md3TextField } from '@nucleux/md3-text-field';
|
|
9
|
-
import {
|
|
10
|
+
import { PenLine, Undo2, Eraser, X, AlertCircle, RotateCcw, Keyboard, ScanText } from 'lucide-react';
|
|
10
11
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
11
12
|
|
|
12
13
|
// src/index.tsx
|
|
@@ -128,6 +129,9 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
128
129
|
acceptLabel = "Add to message",
|
|
129
130
|
typingLabel = "Type your request",
|
|
130
131
|
disabled = false,
|
|
132
|
+
padLabel,
|
|
133
|
+
compact = false,
|
|
134
|
+
onClose,
|
|
131
135
|
className,
|
|
132
136
|
children,
|
|
133
137
|
...props
|
|
@@ -356,6 +360,8 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
356
360
|
setAnnouncement("Added to message.");
|
|
357
361
|
};
|
|
358
362
|
const undoStroke = () => setStrokes(strokes.slice(0, -1));
|
|
363
|
+
const banner = compact && inputMode === "draw" && status === "recognized" && !!recognition && !unsettled && editedText === null;
|
|
364
|
+
const showToolbar = !banner;
|
|
359
365
|
const setRef = (node) => {
|
|
360
366
|
if (typeof ref === "function") ref(node);
|
|
361
367
|
else if (ref) ref.current = node;
|
|
@@ -372,6 +378,33 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
372
378
|
className: cn("flex flex-col gap-3 text-md-on-surface", className),
|
|
373
379
|
...props,
|
|
374
380
|
children: [
|
|
381
|
+
(padLabel != null || compact && (inputMode === "draw" || onClose)) && /* @__PURE__ */ jsxs("div", { className: "-mb-1 flex items-center gap-2", children: [
|
|
382
|
+
/* @__PURE__ */ jsx(PenLine, { "aria-hidden": "true", className: "size-5 shrink-0 text-md-primary" }),
|
|
383
|
+
/* @__PURE__ */ jsx("p", { className: "flex-1 text-sm font-medium tracking-[0.1px] text-md-on-surface-variant", children: padLabel }),
|
|
384
|
+
compact && inputMode === "draw" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
385
|
+
/* @__PURE__ */ jsx(
|
|
386
|
+
Md3IconButton,
|
|
387
|
+
{
|
|
388
|
+
"aria-label": "Undo stroke",
|
|
389
|
+
onClick: undoStroke,
|
|
390
|
+
disabled: disabled || strokes.length === 0 || status === "recognizing",
|
|
391
|
+
className: "[&_svg]:size-5",
|
|
392
|
+
children: /* @__PURE__ */ jsx(Undo2, { "aria-hidden": "true" })
|
|
393
|
+
}
|
|
394
|
+
),
|
|
395
|
+
/* @__PURE__ */ jsx(
|
|
396
|
+
Md3IconButton,
|
|
397
|
+
{
|
|
398
|
+
"aria-label": "Clear",
|
|
399
|
+
onClick: reset,
|
|
400
|
+
disabled: disabled || strokes.length === 0,
|
|
401
|
+
className: "[&_svg]:size-5",
|
|
402
|
+
children: /* @__PURE__ */ jsx(Eraser, { "aria-hidden": "true" })
|
|
403
|
+
}
|
|
404
|
+
)
|
|
405
|
+
] }),
|
|
406
|
+
compact && onClose && /* @__PURE__ */ jsx(Md3IconButton, { "aria-label": "Close handwriting", onClick: onClose, className: "[&_svg]:size-5", children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" }) })
|
|
407
|
+
] }),
|
|
375
408
|
inputMode === "type" ? /* @__PURE__ */ jsx(
|
|
376
409
|
"textarea",
|
|
377
410
|
{
|
|
@@ -393,7 +426,7 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
393
426
|
ref: padRef,
|
|
394
427
|
className: cn(
|
|
395
428
|
"relative overflow-hidden rounded-md-lg",
|
|
396
|
-
isAnnotation ? "min-h-40 border border-md-outline-variant" : "h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low",
|
|
429
|
+
isAnnotation ? "min-h-40 border border-md-outline-variant" : compact ? "h-28 rounded-b-md-xs border-b border-md-outline-variant bg-md-surface-container-low" : "h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low",
|
|
397
430
|
variant === "live-ocr" && "h-36 border border-solid border-md-outline-variant",
|
|
398
431
|
disabled && "opacity-[0.38]"
|
|
399
432
|
),
|
|
@@ -417,13 +450,14 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
417
450
|
)
|
|
418
451
|
}
|
|
419
452
|
),
|
|
453
|
+
compact && !isAnnotation && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-[49%] border-t border-md-outline-variant" }),
|
|
420
454
|
strokes.length === 0 && /* @__PURE__ */ jsx(
|
|
421
455
|
"p",
|
|
422
456
|
{
|
|
423
457
|
"aria-hidden": "true",
|
|
424
458
|
className: cn(
|
|
425
|
-
"pointer-events-none absolute text-
|
|
426
|
-
isAnnotation ? "bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 font-medium" : "inset-x-0 bottom-3 text-center"
|
|
459
|
+
"pointer-events-none absolute text-md-on-surface-variant",
|
|
460
|
+
isAnnotation ? "bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium" : compact ? "left-4 top-[23%] text-base" : "inset-x-0 bottom-3 text-center text-xs"
|
|
427
461
|
),
|
|
428
462
|
children: emptyHint
|
|
429
463
|
}
|
|
@@ -466,7 +500,24 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
466
500
|
/* @__PURE__ */ jsx(Md3Button, { variant: "text", onClick: reset, className: "text-md-on-error-container", children: "Rewrite" })
|
|
467
501
|
] })
|
|
468
502
|
] }),
|
|
469
|
-
|
|
503
|
+
banner && /* @__PURE__ */ jsxs(
|
|
504
|
+
"div",
|
|
505
|
+
{
|
|
506
|
+
id: resultId,
|
|
507
|
+
"data-slot": "handwriting-result",
|
|
508
|
+
className: "flex items-center gap-3 rounded-md-md bg-md-secondary-container py-2 pl-4 pr-2 text-md-on-secondary-container",
|
|
509
|
+
children: [
|
|
510
|
+
/* @__PURE__ */ jsxs("p", { className: "min-w-0 flex-1 text-sm font-medium", children: [
|
|
511
|
+
isAnnotation ? "Read as" : "Recognised",
|
|
512
|
+
": \u201C",
|
|
513
|
+
resultText,
|
|
514
|
+
"\u201D"
|
|
515
|
+
] }),
|
|
516
|
+
/* @__PURE__ */ jsx(Md3Button, { variant: "filled", onClick: accept, disabled: disabled || !resultText.trim(), children: acceptLabel })
|
|
517
|
+
]
|
|
518
|
+
}
|
|
519
|
+
),
|
|
520
|
+
inputMode === "draw" && status === "recognized" && recognition && !banner && /* @__PURE__ */ jsxs(
|
|
470
521
|
"div",
|
|
471
522
|
{
|
|
472
523
|
id: resultId,
|
|
@@ -508,8 +559,8 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
508
559
|
]
|
|
509
560
|
}
|
|
510
561
|
),
|
|
511
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
512
|
-
inputMode === "draw" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
562
|
+
showToolbar && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
563
|
+
inputMode === "draw" && !compact && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
513
564
|
/* @__PURE__ */ jsx(
|
|
514
565
|
Md3Button,
|
|
515
566
|
{
|
|
@@ -545,14 +596,14 @@ var Md3HandwritingInput = React.forwardRef(
|
|
|
545
596
|
inputMode === "draw" && onRecognize && (status !== "recognized" || mode === "review") && /* @__PURE__ */ jsx(
|
|
546
597
|
Md3Button,
|
|
547
598
|
{
|
|
548
|
-
variant: "tonal",
|
|
599
|
+
variant: compact ? "filled" : "tonal",
|
|
549
600
|
icon: /* @__PURE__ */ jsx(ScanText, { "aria-hidden": "true" }),
|
|
550
601
|
onClick: () => void recognize(),
|
|
551
602
|
disabled: disabled || strokes.length === 0 || status === "recognizing",
|
|
552
603
|
children: "Recognise"
|
|
553
604
|
}
|
|
554
605
|
),
|
|
555
|
-
/* @__PURE__ */ jsx(
|
|
606
|
+
!(compact && inputMode === "draw" && status !== "recognized") && /* @__PURE__ */ jsx(
|
|
556
607
|
Md3Button,
|
|
557
608
|
{
|
|
558
609
|
variant: "filled",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Md3Button } from \"@nucleux/md3-button\";\nimport { Md3Chip } from \"@nucleux/md3-chip\";\nimport { Md3LoadingIndicator } from \"@nucleux/md3-loading-indicator\";\nimport { Md3Menu, Md3MenuItem } from \"@nucleux/md3-menu\";\nimport { Md3TextField } from \"@nucleux/md3-text-field\";\nimport type {\n HandwritingInputMode,\n HandwritingInputProps,\n HandwritingInputStatus,\n HandwritingPoint,\n HandwritingRecognition,\n HandwritingStroke,\n HandwritingWord,\n} from \"@nucleux/handwriting\";\nimport { AlertCircle, Eraser, Keyboard, PenLine, RotateCcw, ScanText, Undo2 } from \"lucide-react\";\n\n// Same API as the shadcn twin: the props and data shapes are the twin's own types.\nexport type Md3HandwritingInputProps = HandwritingInputProps;\nexport type {\n HandwritingInputVariant as Md3HandwritingInputVariant,\n HandwritingInputConvert as Md3HandwritingInputConvert,\n HandwritingInputMode as Md3HandwritingInputMode,\n HandwritingInputStatus as Md3HandwritingInputStatus,\n HandwritingPoint,\n HandwritingStroke,\n HandwritingWord,\n HandwritingRecognition,\n HandwritingRecognizeRequest,\n HandwritingAcceptDetail,\n} from \"@nucleux/handwriting\";\n\n// useLayoutEffect warns when rendered on the server; fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\nconst wordsText = (words: HandwritingWord[]) => words.map((w) => w.text).join(\" \");\n\n/** The “?” word: a button that opens its alternatives in an MD3 menu. */\nfunction UncertainWord({\n word,\n onChoose,\n}: {\n word: HandwritingWord;\n onChoose: (text: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLSpanElement>(null);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const menuRef = React.useRef<HTMLDivElement>(null);\n const menuId = React.useId();\n const choices = [word.text, ...(word.alternatives ?? [])].filter((t, j, all) => all.indexOf(t) === j);\n\n React.useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() => menuRef.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus());\n const onDown = (e: PointerEvent) => {\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", onDown);\n return () => document.removeEventListener(\"pointerdown\", onDown);\n }, [open]);\n\n const close = () => {\n setOpen(false);\n triggerRef.current?.focus();\n };\n\n const onMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const items = Array.from(menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []);\n const i = items.indexOf(document.activeElement as HTMLElement);\n if (e.key === \"Escape\" || e.key === \"Tab\") {\n if (e.key === \"Escape\") e.preventDefault();\n close();\n } else if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const step = e.key === \"ArrowDown\" ? 1 : -1;\n items[(i + step + items.length) % items.length]?.focus();\n } else if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n items[e.key === \"Home\" ? 0 : items.length - 1]?.focus();\n }\n };\n\n return (\n <span ref={wrapRef} className=\"relative inline-flex\">\n <button\n ref={triggerRef}\n type=\"button\"\n aria-label={`${word.text} — uncertain, choose the right word`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n className={cn(\n \"relative inline-flex h-8 items-center gap-0.5 overflow-hidden rounded-md-sm px-1.5 text-sm text-md-on-surface\",\n \"underline decoration-md-error decoration-dotted decoration-2 underline-offset-4\",\n \"before:absolute before:inset-0 before:bg-md-primary before:opacity-0 before:transition-opacity before:content-['']\",\n \"hover:before:opacity-[0.08] focus-visible:before:opacity-[0.12] active:before:opacity-[0.12]\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-md-primary\",\n \"transition-transform duration-200 active:scale-95 motion-reduce:transition-none\",\n )}\n >\n <span className=\"relative\">{word.text}</span>\n <span aria-hidden=\"true\" className=\"relative font-semibold text-md-error no-underline\">\n ?\n </span>\n </button>\n {open && (\n <Md3Menu\n ref={menuRef}\n id={menuId}\n aria-label=\"Did you write…\"\n onKeyDown={onMenuKeyDown}\n className=\"absolute left-0 top-full z-50 mt-1 animate-nx-fade-in motion-reduce:animate-none\"\n >\n <span aria-hidden=\"true\" className=\"block px-3 pb-1 pt-1 text-xs font-medium text-md-on-surface-variant\">\n Did you write…\n </span>\n {choices.map((alt) => (\n <Md3MenuItem\n key={alt}\n tabIndex={-1}\n onClick={() => {\n onChoose(alt);\n setOpen(false);\n }}\n >\n {alt}\n </Md3MenuItem>\n ))}\n </Md3Menu>\n )}\n </span>\n );\n}\n\n/**\n * Material 3 handwriting input: a pointer-driven writing pad (pen pressure\n * aware) whose ink the app's own recogniser (`onRecognize`) reads into text.\n * The reading appears under the ink, never over it; words the recogniser was\n * unsure of carry a dotted underline and a “?” in the error tone and must be\n * settled from their alternatives (an MD3 menu) before Add to message is\n * enabled, and the reading stays editable in an MD3 text field. Undo stroke,\n * Clear, Retry and a Type-instead fallback are always available, a slow sheen\n * crosses the pad while it is read (still under reduced motion), and nothing is\n * sent when writing finishes. Shares its API with `HandwritingInput` from\n * `@nucleux/handwriting`. Variants: draw-pad, live-ocr, annotation-stroke.\n */\nexport const Md3HandwritingInput = React.forwardRef<HTMLDivElement, Md3HandwritingInputProps>(\n (\n {\n variant = \"draw-pad\",\n onRecognize,\n convert,\n autoDelay = 900,\n onAccept,\n strokes: strokesProp,\n defaultStrokes,\n onStrokesChange,\n defaultRecognition,\n defaultMode = \"draw\",\n strokeWidth = variant === \"annotation-stroke\" ? 3 : 2.5,\n label = \"Handwriting pad\",\n placeholder,\n statusText = \"Recognising your writing…\",\n failureText = \"Couldn’t recognise this writing.\",\n acceptLabel = \"Add to message\",\n typingLabel = \"Type your request\",\n disabled = false,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const mode = convert ?? (variant === \"live-ocr\" ? \"auto\" : \"review\");\n const isAnnotation = variant === \"annotation-stroke\";\n\n const [internalStrokes, setInternalStrokes] = React.useState<HandwritingStroke[]>(defaultStrokes ?? []);\n const strokes = strokesProp ?? internalStrokes;\n const [inputMode, setInputMode] = React.useState<HandwritingInputMode>(defaultMode);\n const [status, setStatus] = React.useState<HandwritingInputStatus>(defaultRecognition ? \"recognized\" : \"idle\");\n const [recognition, setRecognition] = React.useState<HandwritingRecognition | null>(defaultRecognition ?? null);\n const [words, setWords] = React.useState<HandwritingWord[] | null>(defaultRecognition?.words ?? null);\n const [editedText, setEditedText] = React.useState<string | null>(null);\n const [typed, setTyped] = React.useState(\"\");\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const padRef = React.useRef<HTMLDivElement>(null);\n const drawing = React.useRef<HandwritingStroke | null>(null);\n const requestId = React.useRef(0);\n const strokesRef = React.useRef(strokes);\n strokesRef.current = strokes;\n const resultId = React.useId();\n const resultInputRef = React.useRef<HTMLInputElement>(null);\n\n const setStrokes = (next: HandwritingStroke[]) => {\n if (strokesProp === undefined) setInternalStrokes(next);\n onStrokesChange?.(next);\n };\n\n // ---- drawing (copied from @nucleux/handwriting, where it is internal) ---\n const widthFor = (stroke: HandwritingStroke, p: HandwritingPoint) =>\n stroke.pointerType === \"pen\" && p.pressure > 0 ? strokeWidth * (0.4 + p.pressure * 1.2) : strokeWidth;\n\n const noCanvas = React.useRef(false);\n const getContext = () => {\n const canvas = canvasRef.current;\n if (!canvas || noCanvas.current) return null;\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n ctx = canvas.getContext(\"2d\");\n } catch {\n ctx = null;\n }\n if (!ctx) {\n noCanvas.current = true; // e.g. a non-rendering environment\n return null;\n }\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const color = typeof getComputedStyle === \"function\" ? getComputedStyle(canvas).color : \"\";\n ctx.strokeStyle = color || \"currentColor\";\n ctx.fillStyle = ctx.strokeStyle;\n return ctx;\n };\n\n const drawSegment = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, a: HandwritingPoint, b: HandwritingPoint) => {\n ctx.lineWidth = widthFor(stroke, b);\n ctx.beginPath();\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n ctx.stroke();\n };\n\n const drawDot = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, p: HandwritingPoint) => {\n ctx.beginPath();\n ctx.arc(p.x, p.y, widthFor(stroke, p) / 2, 0, Math.PI * 2);\n ctx.fill();\n };\n\n const redraw = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = getContext();\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const stroke of strokesRef.current) {\n const pts = stroke.points;\n if (pts.length === 1) drawDot(ctx, stroke, pts[0]);\n for (let i = 1; i < pts.length; i++) drawSegment(ctx, stroke, pts[i - 1], pts[i]);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokeWidth]);\n\n // Keep the backing store matched to the pad size (crisp on HiDPI).\n React.useEffect(() => {\n const pad = padRef.current;\n const canvas = canvasRef.current;\n if (!pad || !canvas || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n const rect = pad.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const dpr = window.devicePixelRatio || 1;\n canvas.width = Math.round(rect.width * dpr);\n canvas.height = Math.round(rect.height * dpr);\n redraw();\n });\n ro.observe(pad);\n return () => ro.disconnect();\n }, [redraw, inputMode]);\n\n const hasDrawn = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (strokes.length === 0 && !hasDrawn.current) return;\n hasDrawn.current = true;\n redraw();\n }, [strokes, redraw]);\n\n const pointFrom = (e: React.PointerEvent<HTMLCanvasElement> | PointerEvent): HandwritingPoint => {\n const rect = canvasRef.current!.getBoundingClientRect();\n return {\n x: (e.clientX ?? 0) - rect.left,\n y: (e.clientY ?? 0) - rect.top,\n pressure: typeof e.pressure === \"number\" && e.pressure > 0 ? e.pressure : 0.5,\n t: e.timeStamp ?? Date.now(),\n };\n };\n\n const onPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (disabled || status === \"recognizing\") return;\n if (e.pointerType === \"mouse\" && e.button !== 0) return;\n e.preventDefault();\n e.currentTarget.setPointerCapture?.(e.pointerId);\n const stroke: HandwritingStroke = { pointerType: e.pointerType || \"mouse\", points: [pointFrom(e)] };\n drawing.current = stroke;\n const ctx = getContext();\n if (ctx) drawDot(ctx, stroke, stroke.points[0]);\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const stroke = drawing.current;\n if (!stroke) return;\n const native = e.nativeEvent as PointerEvent & { getCoalescedEvents?: () => PointerEvent[] };\n const events = native.getCoalescedEvents?.() ?? [];\n const ctx = getContext();\n for (const ev of events.length ? events : [native]) {\n const p = pointFrom(ev);\n const prev = stroke.points[stroke.points.length - 1];\n stroke.points.push(p);\n if (ctx) drawSegment(ctx, stroke, prev, p);\n }\n };\n\n const endStroke = () => {\n const stroke = drawing.current;\n if (!stroke) return;\n drawing.current = null;\n setStrokes([...strokesRef.current, stroke]);\n };\n\n // ---- recognition -------------------------------------------------------\n const toImage = (type = \"image/png\") =>\n new Promise<Blob | null>((resolve) => {\n const canvas = canvasRef.current;\n if (!canvas || typeof canvas.toBlob !== \"function\") return resolve(null);\n try {\n canvas.toBlob((blob) => resolve(blob), type);\n } catch {\n resolve(null);\n }\n });\n\n const applyRecognition = (result: HandwritingRecognition) => {\n setRecognition(result);\n setWords(result.words ?? null);\n setEditedText(null);\n setStatus(\"recognized\");\n const unsure = result.words?.filter((w) => w.uncertain).length ?? 0;\n setAnnouncement(\n `Recognised: ${result.words ? wordsText(result.words) : result.text}.` +\n (unsure ? ` ${unsure} ${unsure === 1 ? \"word needs\" : \"words need\"} checking.` : \"\"),\n );\n };\n\n const recognize = async () => {\n if (!onRecognize || strokesRef.current.length === 0) return;\n const id = ++requestId.current;\n setStatus(\"recognizing\");\n setAnnouncement(typeof statusText === \"string\" ? statusText : \"Recognising your writing…\");\n const rect = padRef.current?.getBoundingClientRect();\n try {\n const result = await onRecognize({\n strokes: strokesRef.current,\n width: rect?.width ?? 0,\n height: rect?.height ?? 0,\n toImage,\n });\n if (id !== requestId.current) return;\n applyRecognition(result);\n } catch {\n if (id !== requestId.current) return;\n setStatus(\"error\");\n setAnnouncement(typeof failureText === \"string\" ? failureText : \"Couldn’t recognise this writing.\");\n }\n };\n\n // New ink makes an old reading stale: auto mode re-reads after a pause,\n // review mode drops the reading until the person asks again.\n const prevStrokes = React.useRef(strokes);\n React.useEffect(() => {\n if (prevStrokes.current === strokes) return;\n prevStrokes.current = strokes;\n requestId.current += 1;\n if (strokes.length === 0) {\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n return;\n }\n if (mode === \"auto\" && onRecognize) {\n const timer = setTimeout(() => void recognize(), autoDelay);\n return () => clearTimeout(timer);\n }\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokes]);\n\n // ---- result ------------------------------------------------------------\n const unsettled = editedText === null && !!words?.some((w) => w.uncertain);\n const resultText = editedText ?? (words ? wordsText(words) : (recognition?.text ?? \"\"));\n\n const settleWord = (index: number, text: string) => {\n if (!words) return;\n const next = words.map((w, i) => (i === index ? { text, uncertain: false } : w));\n setWords(next);\n const left = next.filter((w) => w.uncertain).length;\n // The word buttons go away once everything is settled — keep focus in the reading.\n if (!left) requestAnimationFrame(() => resultInputRef.current?.focus());\n setAnnouncement(`“${text}” chosen.${left ? ` ${left} still to check.` : \" Ready to add.\"}`);\n };\n\n const reset = () => {\n requestId.current += 1;\n setStrokes([]);\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n };\n\n const accept = () => {\n if (inputMode === \"type\") {\n const text = typed.trim();\n if (!text) return;\n onAccept?.(text, { source: \"typed\", strokes: [] });\n setTyped(\"\");\n } else {\n const text = resultText.trim();\n if (!text || unsettled) return;\n onAccept?.(text, { source: \"handwriting\", strokes, recognition: recognition ?? undefined });\n reset();\n }\n setAnnouncement(\"Added to message.\");\n };\n\n const undoStroke = () => setStrokes(strokes.slice(0, -1));\n\n const setRef = (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const emptyHint =\n placeholder ?? (isAnnotation ? \"Draw on the content to mark what you mean\" : \"Draw or write…\");\n\n return (\n <div\n ref={setRef}\n role=\"group\"\n aria-label={isAnnotation ? \"Annotation input\" : \"Handwriting input\"}\n data-variant={variant}\n data-status={status}\n className={cn(\"flex flex-col gap-3 text-md-on-surface\", className)}\n {...props}\n >\n {inputMode === \"type\" ? (\n <textarea\n aria-label={typingLabel}\n placeholder={typingLabel}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none rounded-md-xs border border-md-outline bg-transparent px-4 py-3 text-base text-md-on-surface outline-none transition-colors\",\n \"placeholder:text-md-on-surface-variant focus:border-2 focus:border-md-primary focus:px-[15px] focus:py-[11px]\",\n \"disabled:cursor-not-allowed disabled:opacity-[0.38]\",\n )}\n />\n ) : (\n <div\n ref={padRef}\n className={cn(\n \"relative overflow-hidden rounded-md-lg\",\n isAnnotation\n ? \"min-h-40 border border-md-outline-variant\"\n : \"h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low\",\n variant === \"live-ocr\" && \"h-36 border border-solid border-md-outline-variant\",\n disabled && \"opacity-[0.38]\",\n )}\n aria-busy={status === \"recognizing\" || undefined}\n >\n {isAnnotation && children}\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={`${label}${strokes.length ? ` — ${strokes.length} ${strokes.length === 1 ? \"stroke\" : \"strokes\"}` : \" — empty\"}`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endStroke}\n onPointerCancel={endStroke}\n className={cn(\n \"absolute inset-0 size-full touch-none\",\n disabled ? \"cursor-not-allowed\" : \"cursor-crosshair\",\n isAnnotation ? \"text-md-error\" : \"text-md-on-surface\",\n )}\n />\n {strokes.length === 0 && (\n <p\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute text-xs text-md-on-surface-variant\",\n isAnnotation\n ? \"bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 font-medium\"\n : \"inset-x-0 bottom-3 text-center\",\n )}\n >\n {emptyHint}\n </p>\n )}\n {isAnnotation && status === \"recognized\" && resultText && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium text-md-on-surface shadow-md-1\"\n >\n “{resultText}”\n </span>\n )}\n {status === \"recognizing\" && (\n // A slow, low-contrast sheen while the ink is read; the ink stays visible beneath it.\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 animate-pulse bg-md-primary/[0.08] motion-reduce:animate-none\"\n />\n )}\n </div>\n )}\n\n {/* Reading — under the ink, never over it. */}\n {inputMode === \"draw\" && status === \"recognizing\" && (\n <div className=\"flex items-center gap-2 text-sm text-md-on-surface-variant\">\n <Md3LoadingIndicator size={24} aria-hidden=\"true\" />\n {statusText}\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"error\" && (\n <div className=\"flex flex-col gap-2 rounded-md-md bg-md-error-container px-3 py-2.5 text-md-on-error-container\">\n <p className=\"flex items-center gap-2 text-sm\">\n <AlertCircle className=\"size-[18px] shrink-0\" aria-hidden=\"true\" />\n {failureText} Your writing is kept.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Md3Button variant=\"filled\" icon={<RotateCcw aria-hidden=\"true\" />} onClick={() => void recognize()}>\n Retry\n </Md3Button>\n <Md3Button variant=\"text\" onClick={reset} className=\"text-md-on-error-container\">\n Rewrite\n </Md3Button>\n </div>\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"recognized\" && recognition && (\n <div\n id={resultId}\n className=\"flex flex-col gap-2 border-t border-md-outline-variant pt-3\"\n data-slot=\"handwriting-result\"\n >\n <span className=\"text-xs font-medium tracking-[0.5px] text-md-on-surface-variant\">\n {isAnnotation ? \"Read as an instruction\" : \"Recognised\"}\n </span>\n {unsettled && words ? (\n <>\n <div className=\"flex flex-wrap items-center gap-1 text-base text-md-on-surface\">\n {words.map((w, i) =>\n w.uncertain ? (\n <UncertainWord key={i} word={w} onChoose={(text) => settleWord(i, text)} />\n ) : (\n <span key={i} className=\"animate-nx-fade-in motion-reduce:animate-none\">\n {w.text}\n </span>\n ),\n )}\n </div>\n <p className=\"text-xs text-md-on-surface-variant\">\n Check the words marked “?” to add this to your message.{\" \"}\n <button\n type=\"button\"\n onClick={() => setEditedText(resultText)}\n className=\"rounded-md-xs font-medium text-md-primary underline-offset-2 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-md-primary\"\n >\n Edit text instead\n </button>\n </p>\n </>\n ) : (\n <Md3TextField\n ref={resultInputRef}\n label=\"Recognised text\"\n value={resultText}\n onChange={(e) => setEditedText(e.target.value)}\n disabled={disabled}\n />\n )}\n {!unsettled && recognition.alternatives && recognition.alternatives.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Other readings\">\n <span className=\"text-xs text-md-on-surface-variant\">Other readings:</span>\n {recognition.alternatives.map((alt) => (\n <Md3Chip key={alt} variant=\"filter\" selected={resultText === alt} onClick={() => setEditedText(alt)}>\n {alt}\n </Md3Chip>\n ))}\n </div>\n )}\n </div>\n )}\n\n <div className=\"flex flex-wrap items-center gap-1\">\n {inputMode === \"draw\" && (\n <>\n <Md3Button\n variant=\"text\"\n icon={<Undo2 aria-hidden=\"true\" />}\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Undo stroke\n </Md3Button>\n <Md3Button\n variant=\"text\"\n icon={<Eraser aria-hidden=\"true\" />}\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n >\n Clear\n </Md3Button>\n </>\n )}\n <Md3Button\n variant=\"text\"\n icon={inputMode === \"draw\" ? <Keyboard aria-hidden=\"true\" /> : <PenLine aria-hidden=\"true\" />}\n onClick={() => setInputMode(inputMode === \"draw\" ? \"type\" : \"draw\")}\n disabled={disabled}\n >\n {inputMode === \"draw\" ? \"Type instead\" : \"Write instead\"}\n </Md3Button>\n <span className=\"flex-1\" />\n {inputMode === \"draw\" && onRecognize && (status !== \"recognized\" || mode === \"review\") && (\n <Md3Button\n variant=\"tonal\"\n icon={<ScanText aria-hidden=\"true\" />}\n onClick={() => void recognize()}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Recognise\n </Md3Button>\n )}\n <Md3Button\n variant=\"filled\"\n onClick={accept}\n disabled={\n disabled ||\n (inputMode === \"type\" ? !typed.trim() : status !== \"recognized\" || unsettled || !resultText.trim())\n }\n aria-describedby={inputMode === \"draw\" && status === \"recognized\" ? resultId : undefined}\n >\n {acceptLabel}\n </Md3Button>\n </div>\n\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </div>\n );\n },\n);\nMd3HandwritingInput.displayName = \"Md3HandwritingInput\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Md3Button } from \"@nucleux/md3-button\";\nimport { Md3Chip } from \"@nucleux/md3-chip\";\nimport { Md3IconButton } from \"@nucleux/md3-icon-button\";\nimport { Md3LoadingIndicator } from \"@nucleux/md3-loading-indicator\";\nimport { Md3Menu, Md3MenuItem } from \"@nucleux/md3-menu\";\nimport { Md3TextField } from \"@nucleux/md3-text-field\";\nimport type {\n HandwritingInputMode,\n HandwritingInputProps,\n HandwritingInputStatus,\n HandwritingPoint,\n HandwritingRecognition,\n HandwritingStroke,\n HandwritingWord,\n} from \"@nucleux/handwriting\";\nimport { AlertCircle, Eraser, Keyboard, PenLine, RotateCcw, ScanText, Undo2, X } from \"lucide-react\";\n\n// Same API as the shadcn twin: the props and data shapes are the twin's own types.\nexport type Md3HandwritingInputProps = HandwritingInputProps;\nexport type {\n HandwritingInputVariant as Md3HandwritingInputVariant,\n HandwritingInputConvert as Md3HandwritingInputConvert,\n HandwritingInputMode as Md3HandwritingInputMode,\n HandwritingInputStatus as Md3HandwritingInputStatus,\n HandwritingPoint,\n HandwritingStroke,\n HandwritingWord,\n HandwritingRecognition,\n HandwritingRecognizeRequest,\n HandwritingAcceptDetail,\n} from \"@nucleux/handwriting\";\n\n// useLayoutEffect warns when rendered on the server; fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\nconst wordsText = (words: HandwritingWord[]) => words.map((w) => w.text).join(\" \");\n\n/** The “?” word: a button that opens its alternatives in an MD3 menu. */\nfunction UncertainWord({\n word,\n onChoose,\n}: {\n word: HandwritingWord;\n onChoose: (text: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLSpanElement>(null);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const menuRef = React.useRef<HTMLDivElement>(null);\n const menuId = React.useId();\n const choices = [word.text, ...(word.alternatives ?? [])].filter((t, j, all) => all.indexOf(t) === j);\n\n React.useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() => menuRef.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus());\n const onDown = (e: PointerEvent) => {\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", onDown);\n return () => document.removeEventListener(\"pointerdown\", onDown);\n }, [open]);\n\n const close = () => {\n setOpen(false);\n triggerRef.current?.focus();\n };\n\n const onMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const items = Array.from(menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []);\n const i = items.indexOf(document.activeElement as HTMLElement);\n if (e.key === \"Escape\" || e.key === \"Tab\") {\n if (e.key === \"Escape\") e.preventDefault();\n close();\n } else if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const step = e.key === \"ArrowDown\" ? 1 : -1;\n items[(i + step + items.length) % items.length]?.focus();\n } else if (e.key === \"Home\" || e.key === \"End\") {\n e.preventDefault();\n items[e.key === \"Home\" ? 0 : items.length - 1]?.focus();\n }\n };\n\n return (\n <span ref={wrapRef} className=\"relative inline-flex\">\n <button\n ref={triggerRef}\n type=\"button\"\n aria-label={`${word.text} — uncertain, choose the right word`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n className={cn(\n \"relative inline-flex h-8 items-center gap-0.5 overflow-hidden rounded-md-sm px-1.5 text-sm text-md-on-surface\",\n \"underline decoration-md-error decoration-dotted decoration-2 underline-offset-4\",\n \"before:absolute before:inset-0 before:bg-md-primary before:opacity-0 before:transition-opacity before:content-['']\",\n \"hover:before:opacity-[0.08] focus-visible:before:opacity-[0.12] active:before:opacity-[0.12]\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-md-primary\",\n \"transition-transform duration-200 active:scale-95 motion-reduce:transition-none\",\n )}\n >\n <span className=\"relative\">{word.text}</span>\n <span aria-hidden=\"true\" className=\"relative font-semibold text-md-error no-underline\">\n ?\n </span>\n </button>\n {open && (\n <Md3Menu\n ref={menuRef}\n id={menuId}\n aria-label=\"Did you write…\"\n onKeyDown={onMenuKeyDown}\n className=\"absolute left-0 top-full z-50 mt-1 animate-nx-fade-in motion-reduce:animate-none\"\n >\n <span aria-hidden=\"true\" className=\"block px-3 pb-1 pt-1 text-xs font-medium text-md-on-surface-variant\">\n Did you write…\n </span>\n {choices.map((alt) => (\n <Md3MenuItem\n key={alt}\n tabIndex={-1}\n onClick={() => {\n onChoose(alt);\n setOpen(false);\n }}\n >\n {alt}\n </Md3MenuItem>\n ))}\n </Md3Menu>\n )}\n </span>\n );\n}\n\n/**\n * Material 3 handwriting input: a pointer-driven writing pad (pen pressure\n * aware) whose ink the app's own recogniser (`onRecognize`) reads into text.\n * The reading appears under the ink, never over it; words the recogniser was\n * unsure of carry a dotted underline and a “?” in the error tone and must be\n * settled from their alternatives (an MD3 menu) before Add to message is\n * enabled, and the reading stays editable in an MD3 text field. Undo stroke,\n * Clear, Retry and a Type-instead fallback are always available, a slow sheen\n * crosses the pad while it is read (still under reduced motion), and nothing is\n * sent when writing finishes. Shares its API with `HandwritingInput` from\n * `@nucleux/handwriting`. Variants: draw-pad, live-ocr, annotation-stroke.\n */\nexport const Md3HandwritingInput = React.forwardRef<HTMLDivElement, Md3HandwritingInputProps>(\n (\n {\n variant = \"draw-pad\",\n onRecognize,\n convert,\n autoDelay = 900,\n onAccept,\n strokes: strokesProp,\n defaultStrokes,\n onStrokesChange,\n defaultRecognition,\n defaultMode = \"draw\",\n strokeWidth = variant === \"annotation-stroke\" ? 3 : 2.5,\n label = \"Handwriting pad\",\n placeholder,\n statusText = \"Recognising your writing…\",\n failureText = \"Couldn’t recognise this writing.\",\n acceptLabel = \"Add to message\",\n typingLabel = \"Type your request\",\n disabled = false,\n padLabel,\n compact = false,\n onClose,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const mode = convert ?? (variant === \"live-ocr\" ? \"auto\" : \"review\");\n const isAnnotation = variant === \"annotation-stroke\";\n\n const [internalStrokes, setInternalStrokes] = React.useState<HandwritingStroke[]>(defaultStrokes ?? []);\n const strokes = strokesProp ?? internalStrokes;\n const [inputMode, setInputMode] = React.useState<HandwritingInputMode>(defaultMode);\n const [status, setStatus] = React.useState<HandwritingInputStatus>(defaultRecognition ? \"recognized\" : \"idle\");\n const [recognition, setRecognition] = React.useState<HandwritingRecognition | null>(defaultRecognition ?? null);\n const [words, setWords] = React.useState<HandwritingWord[] | null>(defaultRecognition?.words ?? null);\n const [editedText, setEditedText] = React.useState<string | null>(null);\n const [typed, setTyped] = React.useState(\"\");\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const padRef = React.useRef<HTMLDivElement>(null);\n const drawing = React.useRef<HandwritingStroke | null>(null);\n const requestId = React.useRef(0);\n const strokesRef = React.useRef(strokes);\n strokesRef.current = strokes;\n const resultId = React.useId();\n const resultInputRef = React.useRef<HTMLInputElement>(null);\n\n const setStrokes = (next: HandwritingStroke[]) => {\n if (strokesProp === undefined) setInternalStrokes(next);\n onStrokesChange?.(next);\n };\n\n // ---- drawing (copied from @nucleux/handwriting, where it is internal) ---\n const widthFor = (stroke: HandwritingStroke, p: HandwritingPoint) =>\n stroke.pointerType === \"pen\" && p.pressure > 0 ? strokeWidth * (0.4 + p.pressure * 1.2) : strokeWidth;\n\n const noCanvas = React.useRef(false);\n const getContext = () => {\n const canvas = canvasRef.current;\n if (!canvas || noCanvas.current) return null;\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n ctx = canvas.getContext(\"2d\");\n } catch {\n ctx = null;\n }\n if (!ctx) {\n noCanvas.current = true; // e.g. a non-rendering environment\n return null;\n }\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n const color = typeof getComputedStyle === \"function\" ? getComputedStyle(canvas).color : \"\";\n ctx.strokeStyle = color || \"currentColor\";\n ctx.fillStyle = ctx.strokeStyle;\n return ctx;\n };\n\n const drawSegment = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, a: HandwritingPoint, b: HandwritingPoint) => {\n ctx.lineWidth = widthFor(stroke, b);\n ctx.beginPath();\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n ctx.stroke();\n };\n\n const drawDot = (ctx: CanvasRenderingContext2D, stroke: HandwritingStroke, p: HandwritingPoint) => {\n ctx.beginPath();\n ctx.arc(p.x, p.y, widthFor(stroke, p) / 2, 0, Math.PI * 2);\n ctx.fill();\n };\n\n const redraw = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = getContext();\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const stroke of strokesRef.current) {\n const pts = stroke.points;\n if (pts.length === 1) drawDot(ctx, stroke, pts[0]);\n for (let i = 1; i < pts.length; i++) drawSegment(ctx, stroke, pts[i - 1], pts[i]);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokeWidth]);\n\n // Keep the backing store matched to the pad size (crisp on HiDPI).\n React.useEffect(() => {\n const pad = padRef.current;\n const canvas = canvasRef.current;\n if (!pad || !canvas || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n const rect = pad.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const dpr = window.devicePixelRatio || 1;\n canvas.width = Math.round(rect.width * dpr);\n canvas.height = Math.round(rect.height * dpr);\n redraw();\n });\n ro.observe(pad);\n return () => ro.disconnect();\n }, [redraw, inputMode]);\n\n const hasDrawn = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (strokes.length === 0 && !hasDrawn.current) return;\n hasDrawn.current = true;\n redraw();\n }, [strokes, redraw]);\n\n const pointFrom = (e: React.PointerEvent<HTMLCanvasElement> | PointerEvent): HandwritingPoint => {\n const rect = canvasRef.current!.getBoundingClientRect();\n return {\n x: (e.clientX ?? 0) - rect.left,\n y: (e.clientY ?? 0) - rect.top,\n pressure: typeof e.pressure === \"number\" && e.pressure > 0 ? e.pressure : 0.5,\n t: e.timeStamp ?? Date.now(),\n };\n };\n\n const onPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (disabled || status === \"recognizing\") return;\n if (e.pointerType === \"mouse\" && e.button !== 0) return;\n e.preventDefault();\n e.currentTarget.setPointerCapture?.(e.pointerId);\n const stroke: HandwritingStroke = { pointerType: e.pointerType || \"mouse\", points: [pointFrom(e)] };\n drawing.current = stroke;\n const ctx = getContext();\n if (ctx) drawDot(ctx, stroke, stroke.points[0]);\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const stroke = drawing.current;\n if (!stroke) return;\n const native = e.nativeEvent as PointerEvent & { getCoalescedEvents?: () => PointerEvent[] };\n const events = native.getCoalescedEvents?.() ?? [];\n const ctx = getContext();\n for (const ev of events.length ? events : [native]) {\n const p = pointFrom(ev);\n const prev = stroke.points[stroke.points.length - 1];\n stroke.points.push(p);\n if (ctx) drawSegment(ctx, stroke, prev, p);\n }\n };\n\n const endStroke = () => {\n const stroke = drawing.current;\n if (!stroke) return;\n drawing.current = null;\n setStrokes([...strokesRef.current, stroke]);\n };\n\n // ---- recognition -------------------------------------------------------\n const toImage = (type = \"image/png\") =>\n new Promise<Blob | null>((resolve) => {\n const canvas = canvasRef.current;\n if (!canvas || typeof canvas.toBlob !== \"function\") return resolve(null);\n try {\n canvas.toBlob((blob) => resolve(blob), type);\n } catch {\n resolve(null);\n }\n });\n\n const applyRecognition = (result: HandwritingRecognition) => {\n setRecognition(result);\n setWords(result.words ?? null);\n setEditedText(null);\n setStatus(\"recognized\");\n const unsure = result.words?.filter((w) => w.uncertain).length ?? 0;\n setAnnouncement(\n `Recognised: ${result.words ? wordsText(result.words) : result.text}.` +\n (unsure ? ` ${unsure} ${unsure === 1 ? \"word needs\" : \"words need\"} checking.` : \"\"),\n );\n };\n\n const recognize = async () => {\n if (!onRecognize || strokesRef.current.length === 0) return;\n const id = ++requestId.current;\n setStatus(\"recognizing\");\n setAnnouncement(typeof statusText === \"string\" ? statusText : \"Recognising your writing…\");\n const rect = padRef.current?.getBoundingClientRect();\n try {\n const result = await onRecognize({\n strokes: strokesRef.current,\n width: rect?.width ?? 0,\n height: rect?.height ?? 0,\n toImage,\n });\n if (id !== requestId.current) return;\n applyRecognition(result);\n } catch {\n if (id !== requestId.current) return;\n setStatus(\"error\");\n setAnnouncement(typeof failureText === \"string\" ? failureText : \"Couldn’t recognise this writing.\");\n }\n };\n\n // New ink makes an old reading stale: auto mode re-reads after a pause,\n // review mode drops the reading until the person asks again.\n const prevStrokes = React.useRef(strokes);\n React.useEffect(() => {\n if (prevStrokes.current === strokes) return;\n prevStrokes.current = strokes;\n requestId.current += 1;\n if (strokes.length === 0) {\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n return;\n }\n if (mode === \"auto\" && onRecognize) {\n const timer = setTimeout(() => void recognize(), autoDelay);\n return () => clearTimeout(timer);\n }\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [strokes]);\n\n // ---- result ------------------------------------------------------------\n const unsettled = editedText === null && !!words?.some((w) => w.uncertain);\n const resultText = editedText ?? (words ? wordsText(words) : (recognition?.text ?? \"\"));\n\n const settleWord = (index: number, text: string) => {\n if (!words) return;\n const next = words.map((w, i) => (i === index ? { text, uncertain: false } : w));\n setWords(next);\n const left = next.filter((w) => w.uncertain).length;\n // The word buttons go away once everything is settled — keep focus in the reading.\n if (!left) requestAnimationFrame(() => resultInputRef.current?.focus());\n setAnnouncement(`“${text}” chosen.${left ? ` ${left} still to check.` : \" Ready to add.\"}`);\n };\n\n const reset = () => {\n requestId.current += 1;\n setStrokes([]);\n setStatus(\"idle\");\n setRecognition(null);\n setWords(null);\n setEditedText(null);\n };\n\n const accept = () => {\n if (inputMode === \"type\") {\n const text = typed.trim();\n if (!text) return;\n onAccept?.(text, { source: \"typed\", strokes: [] });\n setTyped(\"\");\n } else {\n const text = resultText.trim();\n if (!text || unsettled) return;\n onAccept?.(text, { source: \"handwriting\", strokes, recognition: recognition ?? undefined });\n reset();\n }\n setAnnouncement(\"Added to message.\");\n };\n\n const undoStroke = () => setStrokes(strokes.slice(0, -1));\n // Compact: once there is a reading, the one-line result carries the accept button.\n const banner =\n compact && inputMode === \"draw\" && status === \"recognized\" && !!recognition && !unsettled && editedText === null;\n const showToolbar = !banner;\n\n const setRef = (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n };\n\n const emptyHint =\n placeholder ?? (isAnnotation ? \"Draw on the content to mark what you mean\" : \"Draw or write…\");\n\n return (\n <div\n ref={setRef}\n role=\"group\"\n aria-label={isAnnotation ? \"Annotation input\" : \"Handwriting input\"}\n data-variant={variant}\n data-status={status}\n className={cn(\"flex flex-col gap-3 text-md-on-surface\", className)}\n {...props}\n >\n {(padLabel != null || (compact && (inputMode === \"draw\" || onClose))) && (\n <div className=\"-mb-1 flex items-center gap-2\">\n <PenLine aria-hidden=\"true\" className=\"size-5 shrink-0 text-md-primary\" />\n <p className=\"flex-1 text-sm font-medium tracking-[0.1px] text-md-on-surface-variant\">{padLabel}</p>\n {compact && inputMode === \"draw\" && (\n <>\n <Md3IconButton\n aria-label=\"Undo stroke\"\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n className=\"[&_svg]:size-5\"\n >\n <Undo2 aria-hidden=\"true\" />\n </Md3IconButton>\n <Md3IconButton\n aria-label=\"Clear\"\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n className=\"[&_svg]:size-5\"\n >\n <Eraser aria-hidden=\"true\" />\n </Md3IconButton>\n </>\n )}\n {compact && onClose && (\n <Md3IconButton aria-label=\"Close handwriting\" onClick={onClose} className=\"[&_svg]:size-5\">\n <X aria-hidden=\"true\" />\n </Md3IconButton>\n )}\n </div>\n )}\n\n {inputMode === \"type\" ? (\n <textarea\n aria-label={typingLabel}\n placeholder={typingLabel}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none rounded-md-xs border border-md-outline bg-transparent px-4 py-3 text-base text-md-on-surface outline-none transition-colors\",\n \"placeholder:text-md-on-surface-variant focus:border-2 focus:border-md-primary focus:px-[15px] focus:py-[11px]\",\n \"disabled:cursor-not-allowed disabled:opacity-[0.38]\",\n )}\n />\n ) : (\n <div\n ref={padRef}\n className={cn(\n \"relative overflow-hidden rounded-md-lg\",\n isAnnotation\n ? \"min-h-40 border border-md-outline-variant\"\n : compact\n ? \"h-28 rounded-b-md-xs border-b border-md-outline-variant bg-md-surface-container-low\"\n : \"h-44 border-[1.5px] border-dashed border-md-outline bg-md-surface-container-low\",\n variant === \"live-ocr\" && \"h-36 border border-solid border-md-outline-variant\",\n disabled && \"opacity-[0.38]\",\n )}\n aria-busy={status === \"recognizing\" || undefined}\n >\n {isAnnotation && children}\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={`${label}${strokes.length ? ` — ${strokes.length} ${strokes.length === 1 ? \"stroke\" : \"strokes\"}` : \" — empty\"}`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endStroke}\n onPointerCancel={endStroke}\n className={cn(\n \"absolute inset-0 size-full touch-none\",\n disabled ? \"cursor-not-allowed\" : \"cursor-crosshair\",\n isAnnotation ? \"text-md-error\" : \"text-md-on-surface\",\n )}\n />\n {compact && !isAnnotation && (\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute inset-x-0 top-[49%] border-t border-md-outline-variant\" />\n )}\n {strokes.length === 0 && (\n <p\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute text-md-on-surface-variant\",\n isAnnotation\n ? \"bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium\"\n : compact\n ? \"left-4 top-[23%] text-base\"\n : \"inset-x-0 bottom-3 text-center text-xs\",\n )}\n >\n {emptyHint}\n </p>\n )}\n {isAnnotation && status === \"recognized\" && resultText && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-2 right-2 rounded-full bg-md-surface-container-high px-2.5 py-1 text-xs font-medium text-md-on-surface shadow-md-1\"\n >\n “{resultText}”\n </span>\n )}\n {status === \"recognizing\" && (\n // A slow, low-contrast sheen while the ink is read; the ink stays visible beneath it.\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 animate-pulse bg-md-primary/[0.08] motion-reduce:animate-none\"\n />\n )}\n </div>\n )}\n\n {/* Reading — under the ink, never over it. */}\n {inputMode === \"draw\" && status === \"recognizing\" && (\n <div className=\"flex items-center gap-2 text-sm text-md-on-surface-variant\">\n <Md3LoadingIndicator size={24} aria-hidden=\"true\" />\n {statusText}\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"error\" && (\n <div className=\"flex flex-col gap-2 rounded-md-md bg-md-error-container px-3 py-2.5 text-md-on-error-container\">\n <p className=\"flex items-center gap-2 text-sm\">\n <AlertCircle className=\"size-[18px] shrink-0\" aria-hidden=\"true\" />\n {failureText} Your writing is kept.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Md3Button variant=\"filled\" icon={<RotateCcw aria-hidden=\"true\" />} onClick={() => void recognize()}>\n Retry\n </Md3Button>\n <Md3Button variant=\"text\" onClick={reset} className=\"text-md-on-error-container\">\n Rewrite\n </Md3Button>\n </div>\n </div>\n )}\n\n {banner && (\n <div\n id={resultId}\n data-slot=\"handwriting-result\"\n className=\"flex items-center gap-3 rounded-md-md bg-md-secondary-container py-2 pl-4 pr-2 text-md-on-secondary-container\"\n >\n <p className=\"min-w-0 flex-1 text-sm font-medium\">\n {isAnnotation ? \"Read as\" : \"Recognised\"}: “{resultText}”\n </p>\n <Md3Button variant=\"filled\" onClick={accept} disabled={disabled || !resultText.trim()}>\n {acceptLabel}\n </Md3Button>\n </div>\n )}\n\n {inputMode === \"draw\" && status === \"recognized\" && recognition && !banner && (\n <div\n id={resultId}\n className=\"flex flex-col gap-2 border-t border-md-outline-variant pt-3\"\n data-slot=\"handwriting-result\"\n >\n <span className=\"text-xs font-medium tracking-[0.5px] text-md-on-surface-variant\">\n {isAnnotation ? \"Read as an instruction\" : \"Recognised\"}\n </span>\n {unsettled && words ? (\n <>\n <div className=\"flex flex-wrap items-center gap-1 text-base text-md-on-surface\">\n {words.map((w, i) =>\n w.uncertain ? (\n <UncertainWord key={i} word={w} onChoose={(text) => settleWord(i, text)} />\n ) : (\n <span key={i} className=\"animate-nx-fade-in motion-reduce:animate-none\">\n {w.text}\n </span>\n ),\n )}\n </div>\n <p className=\"text-xs text-md-on-surface-variant\">\n Check the words marked “?” to add this to your message.{\" \"}\n <button\n type=\"button\"\n onClick={() => setEditedText(resultText)}\n className=\"rounded-md-xs font-medium text-md-primary underline-offset-2 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-md-primary\"\n >\n Edit text instead\n </button>\n </p>\n </>\n ) : (\n <Md3TextField\n ref={resultInputRef}\n label=\"Recognised text\"\n value={resultText}\n onChange={(e) => setEditedText(e.target.value)}\n disabled={disabled}\n />\n )}\n {!unsettled && recognition.alternatives && recognition.alternatives.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Other readings\">\n <span className=\"text-xs text-md-on-surface-variant\">Other readings:</span>\n {recognition.alternatives.map((alt) => (\n <Md3Chip key={alt} variant=\"filter\" selected={resultText === alt} onClick={() => setEditedText(alt)}>\n {alt}\n </Md3Chip>\n ))}\n </div>\n )}\n </div>\n )}\n\n {showToolbar && (\n <div className=\"flex flex-wrap items-center gap-1\">\n {inputMode === \"draw\" && !compact && (\n <>\n <Md3Button\n variant=\"text\"\n icon={<Undo2 aria-hidden=\"true\" />}\n onClick={undoStroke}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Undo stroke\n </Md3Button>\n <Md3Button\n variant=\"text\"\n icon={<Eraser aria-hidden=\"true\" />}\n onClick={reset}\n disabled={disabled || strokes.length === 0}\n >\n Clear\n </Md3Button>\n </>\n )}\n <Md3Button\n variant=\"text\"\n icon={inputMode === \"draw\" ? <Keyboard aria-hidden=\"true\" /> : <PenLine aria-hidden=\"true\" />}\n onClick={() => setInputMode(inputMode === \"draw\" ? \"type\" : \"draw\")}\n disabled={disabled}\n >\n {inputMode === \"draw\" ? \"Type instead\" : \"Write instead\"}\n </Md3Button>\n <span className=\"flex-1\" />\n {inputMode === \"draw\" && onRecognize && (status !== \"recognized\" || mode === \"review\") && (\n <Md3Button\n variant={compact ? \"filled\" : \"tonal\"}\n icon={<ScanText aria-hidden=\"true\" />}\n onClick={() => void recognize()}\n disabled={disabled || strokes.length === 0 || status === \"recognizing\"}\n >\n Recognise\n </Md3Button>\n )}\n {!(compact && inputMode === \"draw\" && status !== \"recognized\") && (\n <Md3Button\n variant=\"filled\"\n onClick={accept}\n disabled={\n disabled ||\n (inputMode === \"type\" ? !typed.trim() : status !== \"recognized\" || unsettled || !resultText.trim())\n }\n aria-describedby={inputMode === \"draw\" && status === \"recognized\" ? resultId : undefined}\n >\n {acceptLabel}\n </Md3Button>\n )}\n </div>\n )}\n\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </div>\n );\n },\n);\nMd3HandwritingInput.displayName = \"Md3HandwritingInput\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nucleux/md3-handwriting",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Material 3 Handwriting Input — write the request by hand, settle uncertain words, add it yourself — Nucleux agentic UI for React.",
|
|
@@ -39,13 +39,15 @@
|
|
|
39
39
|
"react-dom": ">=18"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@nucleux/
|
|
43
|
-
"@nucleux/md3-button": "0.
|
|
44
|
-
"@nucleux/
|
|
45
|
-
"@nucleux/md3-
|
|
46
|
-
"@nucleux/md3-
|
|
47
|
-
"@nucleux/md3-
|
|
48
|
-
"@nucleux/
|
|
42
|
+
"@nucleux/md3-open-input": "0.10.0",
|
|
43
|
+
"@nucleux/md3-icon-button": "0.10.0",
|
|
44
|
+
"@nucleux/handwriting": "0.10.0",
|
|
45
|
+
"@nucleux/md3-button": "0.10.0",
|
|
46
|
+
"@nucleux/md3-chip": "0.10.0",
|
|
47
|
+
"@nucleux/md3-loading-indicator": "0.10.0",
|
|
48
|
+
"@nucleux/md3-menu": "0.10.0",
|
|
49
|
+
"@nucleux/md3-text-field": "0.10.0",
|
|
50
|
+
"@nucleux/utils": "0.10.0",
|
|
49
51
|
"lucide-react": "^0.469.0"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|