@pebble-software/bonsai 0.2.1 → 0.4.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.
Files changed (34) hide show
  1. package/README.md +47 -5
  2. package/dist/ast.js +1 -1
  3. package/dist/chunks/{builder.meta-B7Y9M7Ab.js → builder.meta-DKq-ggkn.js} +3 -3
  4. package/dist/chunks/{builder.meta-B7Y9M7Ab.js.map → builder.meta-DKq-ggkn.js.map} +1 -1
  5. package/dist/chunks/class-names-CoKRVvWM.js +66 -0
  6. package/dist/chunks/class-names-CoKRVvWM.js.map +1 -0
  7. package/dist/chunks/{create-renderer-C4nV9RV6.js → create-renderer-CSFyNcqr.js} +55 -55
  8. package/dist/chunks/create-renderer-CSFyNcqr.js.map +1 -0
  9. package/dist/chunks/{index-CD5pykpk.js → index-df-PhUtD.js} +2 -2
  10. package/dist/chunks/{index-CD5pykpk.js.map → index-df-PhUtD.js.map} +1 -1
  11. package/dist/chunks/{render-shared-Cwb527d4.js → render-shared-DSYQFhTh.js} +3 -3
  12. package/dist/chunks/render-shared-DSYQFhTh.js.map +1 -0
  13. package/dist/classes.d.ts +51 -0
  14. package/dist/classes.js +27 -0
  15. package/dist/classes.js.map +1 -0
  16. package/dist/classes.json +1 -0
  17. package/dist/components/ui/signature-pad.d.ts +2 -2
  18. package/dist/constants.js +7 -2
  19. package/dist/constants.js.map +1 -1
  20. package/dist/core.js +3 -3
  21. package/dist/css.d.ts +42 -0
  22. package/dist/css.js +7483 -0
  23. package/dist/css.js.map +1 -0
  24. package/dist/index.js +120 -110
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/ast/class-names.d.ts +28 -0
  27. package/dist/library/constants/src/components.d.ts +1 -0
  28. package/dist/presets/signature.js +2 -2
  29. package/dist/presets/signature.js.map +1 -1
  30. package/dist/schemas.js +1 -1
  31. package/dist/styles/presets.json +2 -1
  32. package/package.json +13 -1
  33. package/dist/chunks/create-renderer-C4nV9RV6.js.map +0 -1
  34. package/dist/chunks/render-shared-Cwb527d4.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"signature.js","sources":["../../src/components/ui/tabs.tsx","../../src/components/ui/signature-pad.tsx","../../src/renderer/presets/signature.ts"],"sourcesContent":["\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\nimport { useHaptics, HAPTIC_TAB } from \"@/lib/haptics\";\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-orientation={orientation}\n className={cn(\n \"gap-2 group/tabs flex\",\n \"data-[orientation=horizontal]:flex-col\",\n \"data-[orientation=vertical]:w-full\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst tabsListVariants = cva(\n \"overflow-auto inline-flex bg-transparent w-fit items-start justify-start group-data-horizontal/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col\",\n {\n variants: {\n variant: {\n default:\n \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n ghost:\n \"gap-1 border-none rounded-none p-[calc(var(--trigger-translate)+6px)]\",\n icon: \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n contained:\n \"gap-0 border-0 rounded-md p-[calc(var(--trigger-translate)+2px)]\",\n },\n size: {\n sm: \"\",\n md: \"\",\n lg: \"\",\n xl: \"\",\n },\n extrude: {\n default:\n \"[--trigger-shadow:var(--shadow-none)] [--trigger-translate:0px] [--focus-trigger-translate:0px]\",\n xs: \"[--trigger-shadow:var(--shadow-min)] [--trigger-translate:1px] [--focus-trigger-shadow:var(--shadow-none)] [--focus-trigger-translate:0px]\",\n sm: \"[--trigger-shadow:var(--shadow-xs)] [--trigger-translate:2px] [--focus-trigger-shadow:var(--shadow-min)] [--focus-trigger-translate:1px]\",\n md: \"[--trigger-shadow:var(--shadow-sm)] [--trigger-translate:3px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n lg: \"[--trigger-shadow:var(--shadow-md)] [--trigger-translate:4px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n xl: \"[--trigger-shadow:var(--shadow-lg)] [--trigger-translate:5px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n extrude: \"default\",\n },\n },\n);\n\nfunction TabsList({\n className,\n variant = \"default\",\n size = \"md\",\n extrude = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n data-size={size}\n className={cn(\n tabsListVariants({ variant, size, extrude }),\n \"group/tabs-list\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TabsTrigger({\n label,\n description,\n children,\n className,\n onClick,\n ...props\n}: TabsPrimitive.Tab.Props & {\n label?: React.ReactNode;\n description?: React.ReactNode;\n}) {\n const { trigger } = useHaptics();\n return (\n <TabsPrimitive.Tab\n data-slot=\"tabs-trigger\"\n aria-label={props.value ?? \"tabs-trigger\"}\n className={cn(\n \"group/tabs-trigger neo-base relative inline-flex flex-1 items-center justify-center overflow-hidden cursor-pointer rounded-base border-2 py-1\",\n \"bg-surface data-active:bg-main\",\n \"font-medium h-[calc(100%-1px)] whitespace-nowrap [&_svg]:shrink-0\",\n \"transition-[translate,box-shadow,border,color] duration-200\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none aria-disabled:translate-0\",\n \"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start\",\n\n \"active:shadow-none active:translate-0\",\n \"data-active:shadow-(--trigger-shadow) data-active:-translate-(--trigger-translate)\",\n \"hover:shadow-(--trigger-shadow) hover:-translate-(--trigger-translate)\",\n \"focus-visible:shadow-(--focus-trigger-shadow) focus-visible:-translate-(--focus-trigger-translate)\",\n \"focus-visible:hover:-translate-(--focus-trigger-translate) focus-visible:**:font-semibold\",\n\n \"group-data-[size=xl]/tabs-list:min-h-12\",\n\n \"group-data-[size=sm]/tabs-list:[&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[size=md]/tabs-list:[&_svg:not([class*='size-'])]:size-5\",\n \"group-data-[size=lg]/tabs-list:[&_svg:not([class*='size-'])]:size-6\",\n \"group-data-[size=xl]/tabs-list:[&_svg:not([class*='size-'])]:size-7\",\n\n \"group-data-[variant=default]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[variant=ghost]/tabs-list:border-none\",\n \"group-data-[variant=ghost]/tabs-list:data-active:bg-transparent group-data-[variant=ghost]/tabs-list:shadow-none\",\n\n \"group-data-[variant=icon]/tabs-list:group-data-[size=sm]/tabs-list:px-1.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=md]/tabs-list:px-2\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=lg]/tabs-list:px-2.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=xl]/tabs-list:px-3\",\n \"group-data-[variant=icon]/tabs-list:m-auto group-data-[variant=icon]/tabs-list:max-w-fit group-data-[variant=icon]/tabs-list:aspect-square group-data-[variant=icon]/tabs-list:items-center group-data-[variant=icon]/tabs-list:justify-center group-data-[variant=icon]/tabs-list:hover:border-foreground group-data-[variant=icon]/tabs-list:border-transparent group-data-[variant=icon]/tabs-list:data-active:border-border\",\n\n \"group-data-[variant=contained]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-r-none group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-l-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-b-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-t-none group-data-[variant=contained]/tabs-list:-m-px\",\n\n children ? \"gap-1.5\" : \"flex-col gap-0.5\",\n className,\n )}\n onClick={(event) => {\n trigger(HAPTIC_TAB);\n onClick?.(event);\n }}\n {...props}\n >\n {label && (\n <span\n data-slot=\"tabs-trigger-label\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 font-medium font-heading\",\n \"group-data-[size=sm]/tabs-list:text-sm\",\n \"group-data-[size=md]/tabs-list:text-base\",\n \"group-data-[size=lg]/tabs-list:text-lg\",\n \"group-data-[size=xl]/tabs-list:text-2xl\",\n )}\n >\n {label}\n </span>\n )}\n {description && (\n <span\n data-slot=\"tabs-trigger-description\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 whitespace-normal\",\n \"group-data-[size=sm]/tabs-list:text-xs\",\n \"group-data-[size=md]/tabs-list:text-sm\",\n \"group-data-[size=lg]/tabs-list:text-base\",\n \"group-data-[size=xl]/tabs-list:text-lg\",\n )}\n >\n {description}\n </span>\n )}\n {children}\n <div\n data-slot=\"tabs-trigger-indicator\"\n className={cn(\n \"pointer-events-none h-[3px] rounded-full bg-foreground absolute hidden bottom-0 left-1 right-1\",\n \"group-data-[variant=ghost]/tabs-list:group-data-active/tabs-trigger:block\",\n )}\n />\n </TabsPrimitive.Tab>\n );\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n <TabsPrimitive.Panel\n data-slot=\"tabs-content\"\n className={cn(\n \"text-sm flex-1 neo-base border-l-2 border-l-transparent focus-visible:border-l-border -ml-0.5 pl-0.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Button } from \"./button\";\nimport { Tabs, TabsList, TabsTrigger } from \"./tabs\";\nimport SignatureCanvas from \"react-signature-canvas\";\nimport type { ChangeEvent } from \"react\";\nimport { IconEraser, IconWriting, IconTextSize } from \"@tabler/icons-react\";\nimport { InputGroup, InputGroupAddon, InputGroupInput } from \"./input-group\";\nimport { cn } from \"@/lib/utils\";\nimport { useBonsaiRenderMode } from \"../core/bonsai\";\n\nexport type SignatureProps = {\n value?: string | null;\n onChange?: (value: string | null) => void;\n canvasClassname?: string;\n imageType?: \"image/png\" | \"image/jpeg\" | \"image/webp\";\n};\n\nconst FONT_FAMILY = '\"Great Vibes\", cursive';\nconst FONT_SIZE_MAX = 64;\nconst FONT_SIZE_MIN = 24;\nconst TEXT_PADDING_X = 20;\n\nfunction renderTypedSignature({\n canvas,\n text,\n width,\n height,\n ratio,\n}: {\n canvas: HTMLCanvasElement;\n text: string;\n width: number;\n height: number;\n ratio: number;\n}) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return false;\n\n const displayWidth = Math.max(1, Math.floor(width));\n const displayHeight = Math.max(1, Math.floor(height));\n const pixelRatio = Math.max(ratio || 1, 1);\n\n canvas.width = Math.max(1, Math.floor(displayWidth * pixelRatio));\n canvas.height = Math.max(1, Math.floor(displayHeight * pixelRatio));\n ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n ctx.clearRect(0, 0, displayWidth, displayHeight);\n\n const value = text.trim();\n if (!value) return false;\n\n const maxTextWidth = Math.max(1, displayWidth - TEXT_PADDING_X * 2);\n\n ctx.fillStyle = \"#000\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n let fontSize = FONT_SIZE_MAX;\n while (fontSize > FONT_SIZE_MIN) {\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n if (ctx.measureText(value).width <= maxTextWidth) break;\n fontSize -= 1;\n }\n\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n ctx.fillText(value, displayWidth / 2, displayHeight / 2, maxTextWidth);\n\n return true;\n}\n\nexport function Signature({\n value,\n onChange,\n canvasClassname,\n imageType = \"image/png\",\n}: SignatureProps) {\n const renderMode = useBonsaiRenderMode();\n const [mode, setMode] = useState<\"sign\" | \"type\">(\"sign\");\n const [text, setText] = useState(\"\");\n\n const signature = useRef<SignatureCanvas | null>(null);\n const textCanvas = useRef<HTMLCanvasElement | null>(null);\n const onChangeRef = useRef(onChange);\n const lastEmittedValue = useRef<string | null>(value ?? null);\n const initialized = useRef(false);\n const textCanvasSizeRef = useRef({ width: 0, height: 0 });\n\n const emitChange = useCallback((nextValue: string | null) => {\n if (lastEmittedValue.current === nextValue) return;\n lastEmittedValue.current = nextValue;\n onChangeRef.current?.(nextValue);\n }, []);\n\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n lastEmittedValue.current = value ?? null;\n }, [value]);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n if (!value || mode !== \"sign\") return;\n const instance = signature.current;\n if (!instance) return;\n\n try {\n instance.fromDataURL(value);\n } catch {\n instance.clear();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- seeds the canvas from the initial value once, on mount\n }, []);\n\n useEffect(() => {\n if (mode !== \"type\") return;\n\n const canvas = textCanvas.current;\n if (!canvas) return;\n\n if (textCanvasSizeRef.current.width === 0) {\n const rect = canvas.getBoundingClientRect();\n textCanvasSizeRef.current = {\n width: Math.max(1, Math.floor(rect.width)),\n height: Math.max(1, Math.floor(rect.height)),\n };\n }\n\n const size = textCanvasSizeRef.current;\n if (!size.width || !size.height) return;\n\n const ratio = window.devicePixelRatio || 1;\n const hasText = renderTypedSignature({\n canvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n if (!hasText) {\n emitChange(null);\n return;\n }\n\n const exportCanvas = document.createElement(\"canvas\");\n renderTypedSignature({\n canvas: exportCanvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n emitChange(exportCanvas.toDataURL(imageType));\n }, [mode, text, imageType, emitChange]);\n\n const clearSignature = () => {\n signature.current?.clear();\n setText(\"\");\n emitChange(null);\n };\n\n const handleDrawEnd = () => {\n if (mode !== \"sign\") return;\n const data = signature.current?.toDataURL(imageType) ?? null;\n emitChange(data);\n };\n\n const handleModeChange = (next: \"sign\" | \"type\") => {\n if (next === mode) return;\n clearSignature();\n setMode(next);\n };\n\n const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {\n setText(event.target.value);\n };\n\n // In a non-interactive document there is no client JS to draw a canvas, so\n // the captured value (a base64 data URI baked in at capture time) is shown as\n // a plain image, and an unsigned pad as an empty signature line — never the\n // interactive control, which would render as a blank grid with a toolbar.\n if (renderMode === \"pdf\") {\n return (\n <div id=\"signature\" className=\"w-full\">\n {value ? (\n <img\n src={value}\n alt=\"Signature\"\n className={cn(\n \"w-full h-[256px] object-contain\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassname,\n )}\n />\n ) : (\n <div\n aria-label=\"Unsigned\"\n className={cn(\n \"w-full h-[256px] flex items-end\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassname,\n )}\n >\n <div className=\"w-full border-t-2 border-dashed border-border mx-6 mb-8 pb-1 text-center text-sm text-muted-foreground\">\n Signature\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div id=\"signature\">\n <InputGroup\n className={cn(\n mode === \"type\" ? \"max-h-84\" : \"max-h-69\",\n \"overflow-hidden transition-[max-height] duration-300 has-[>[data-align=block-start]]:p-2 gap-2\",\n )}\n >\n <InputGroupAddon align=\"block-start\" className=\"p-0!\">\n <div className=\"relative w-full rounded-base\">\n <div className=\"absolute top-4 left-4 right-3 bg-transparent flex flex-row items-start justify-between gap-3\">\n <Tabs\n value={mode}\n onValueChange={(next) =>\n handleModeChange(next as \"sign\" | \"type\")\n }\n className=\"-mt-1\"\n >\n <TabsList variant=\"contained\" extrude=\"sm\" size=\"md\">\n <TabsTrigger value=\"sign\">\n <IconWriting />\n <span className=\"hidden sm:flex\">Draw</span>\n </TabsTrigger>\n <TabsTrigger value=\"type\">\n <IconTextSize />\n <span className=\"hidden sm:flex\">Type</span>\n </TabsTrigger>\n </TabsList>\n </Tabs>\n <Button\n size=\"sm\"\n raised=\"xs\"\n variant=\"outline\"\n onClick={clearSignature}\n >\n <IconEraser />\n <span className=\"hidden sm:flex\">Clear</span>\n </Button>\n </div>\n {mode === \"sign\" ? (\n <SignatureCanvas\n ref={signature}\n onEnd={handleDrawEnd}\n canvasProps={{\n className:\n canvasClassname ??\n cn(\n \"w-full h-[256px]\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n \"cursor-crosshair\",\n ),\n }}\n />\n ) : (\n <canvas\n ref={textCanvas}\n className={cn(\n \"w-full h-64\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n )}\n />\n )}\n </div>\n </InputGroupAddon>\n <InputGroupInput\n disabled={mode !== \"type\"}\n className={cn(\n mode === \"type\"\n ? \"animate-in zoom-in-0 spin-in-20 scale-100\"\n : \"animate-out zoom-out-0 spin-out-20 scale-0\",\n \"py-2 text-lg font-medium transition-[scale,translate,box-shadow] duration-300 origin-bottom-left\",\n )}\n placeholder=\"Enter Full Name\"\n value={text}\n onChange={handleTextChange}\n />\n </InputGroup>\n </div>\n );\n}\n","import { COMPONENT } from \"@bonsai/constants\";\n\nimport { Signature } from \"../../components/ui/signature-pad\";\nimport type { BonsaiPreset } from \"../core-registry\";\n\n/** Opt-in `signature` component. Pulls in react-signature-canvas. */\nexport const signaturePreset: BonsaiPreset = {\n components: {\n [COMPONENT.SIGNATURE]: Signature,\n },\n controlledInputs: {\n [COMPONENT.SIGNATURE]: {\n valueProp: \"value\",\n changeProp: \"onChange\",\n extractor: (val: string | null) => val,\n },\n },\n};\n\nexport { Signature };\nexport type { SignatureProps } from \"../../components/ui/signature-pad\";\n"],"names":["Tabs","className","orientation","props","jsx","TabsPrimitive","cn","tabsListVariants","cva","TabsList","variant","size","extrude","TabsTrigger","label","description","children","onClick","trigger","useHaptics","jsxs","event","HAPTIC_TAB","FONT_FAMILY","FONT_SIZE_MAX","FONT_SIZE_MIN","TEXT_PADDING_X","renderTypedSignature","canvas","text","width","height","ratio","ctx","displayWidth","displayHeight","pixelRatio","value","maxTextWidth","fontSize","Signature","onChange","canvasClassname","imageType","renderMode","useBonsaiRenderMode","mode","setMode","useState","setText","signature","useRef","textCanvas","onChangeRef","lastEmittedValue","initialized","textCanvasSizeRef","emitChange","useCallback","nextValue","useEffect","instance","rect","exportCanvas","clearSignature","handleDrawEnd","data","handleModeChange","next","handleTextChange","InputGroup","InputGroupAddon","IconWriting","IconTextSize","Button","IconEraser","SignatureCanvas","InputGroupInput","signaturePreset","COMPONENT","val"],"mappings":";;;;;;;;;;AAOA,SAASA,EAAK;AAAA,EACZ,WAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,GAAGC;AACL,GAA6B;AAC3B,SACE,gBAAAC;AAAA,IAACC,EAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,oBAAkBH;AAAA,MAClB,WAAWI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACAL;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,MAAMI,IAAmBC;AAAA,EACvB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,OACE;AAAA,QACF,MAAM;AAAA,QACN,WACE;AAAA,MAAA;AAAA,MAEJ,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,MAEN,SAAS;AAAA,QACP,SACE;AAAA,QACF,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;AAEA,SAASC,EAAS;AAAA,EAChB,WAAAR;AAAA,EACA,SAAAS,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,GAAGT;AACL,GAAqE;AACnE,SACE,gBAAAC;AAAA,IAACC,EAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,gBAAcK;AAAA,MACd,aAAWC;AAAA,MACX,WAAWL;AAAA,QACTC,EAAiB,EAAE,SAAAG,GAAS,MAAAC,GAAM,SAAAC,GAAS;AAAA,QAC3C;AAAA,QACAX;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASU,EAAY;AAAA,EACnB,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAf;AAAA,EACA,SAAAgB;AAAA,EACA,GAAGd;AACL,GAGG;AACD,QAAM,EAAE,SAAAe,EAAA,IAAYC,EAAA;AACpB,SACE,gBAAAC;AAAA,IAACf,EAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,cAAYF,EAAM,SAAS;AAAA,MAC3B,WAAWG;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEAU,IAAW,YAAY;AAAA,QACvBf;AAAA,MAAA;AAAA,MAEF,SAAS,CAACoB,MAAU;AAClB,QAAAH,EAAQI,CAAU,GAClBL,IAAUI,CAAK;AAAA,MACjB;AAAA,MACC,GAAGlB;AAAA,MAEH,UAAA;AAAA,QAAAW,KACC,gBAAAV;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAWE;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,YAGD,UAAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJC,KACC,gBAAAX;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAWE;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,YAGD,UAAAS;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJC;AAAA,QACD,gBAAAZ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAWE;AAAA,cACT;AAAA,cACA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;AC/KA,MAAMiB,IAAc,0BACdC,IAAgB,IAChBC,IAAgB,IAChBC,KAAiB;AAEvB,SAASC,EAAqB;AAAA,EAC5B,QAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC;AACF,GAMG;AACD,QAAMC,IAAML,EAAO,WAAW,IAAI;AAClC,MAAI,CAACK,EAAK,QAAO;AAEjB,QAAMC,IAAe,KAAK,IAAI,GAAG,KAAK,MAAMJ,CAAK,CAAC,GAC5CK,IAAgB,KAAK,IAAI,GAAG,KAAK,MAAMJ,CAAM,CAAC,GAC9CK,IAAa,KAAK,IAAIJ,KAAS,GAAG,CAAC;AAEzC,EAAAJ,EAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAMM,IAAeE,CAAU,CAAC,GAChER,EAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAMO,IAAgBC,CAAU,CAAC,GAClEH,EAAI,aAAaG,GAAY,GAAG,GAAGA,GAAY,GAAG,CAAC,GACnDH,EAAI,UAAU,GAAG,GAAGC,GAAcC,CAAa;AAE/C,QAAME,IAAQR,EAAK,KAAA;AACnB,MAAI,CAACQ,EAAO,QAAO;AAEnB,QAAMC,IAAe,KAAK,IAAI,GAAGJ,IAAeR,KAAiB,CAAC;AAElE,EAAAO,EAAI,YAAY,QAChBA,EAAI,YAAY,UAChBA,EAAI,eAAe;AAEnB,MAAIM,IAAWf;AACf,SAAOe,IAAWd,MAChBQ,EAAI,OAAO,GAAGM,CAAQ,MAAMhB,CAAW,IACnC,EAAAU,EAAI,YAAYI,CAAK,EAAE,SAASC;AACpC,IAAAC,KAAY;AAGd,SAAAN,EAAI,OAAO,GAAGM,CAAQ,MAAMhB,CAAW,IACvCU,EAAI,SAASI,GAAOH,IAAe,GAAGC,IAAgB,GAAGG,CAAY,GAE9D;AACT;AAEO,SAASE,GAAU;AAAA,EACxB,OAAAH;AAAA,EACA,UAAAI;AAAA,EACA,iBAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAmB;AACjB,QAAMC,IAAaC,EAAA,GACb,CAACC,GAAMC,CAAO,IAAIC,EAA0B,MAAM,GAClD,CAACnB,GAAMoB,CAAO,IAAID,EAAS,EAAE,GAE7BE,IAAYC,EAA+B,IAAI,GAC/CC,IAAaD,EAAiC,IAAI,GAClDE,IAAcF,EAAOV,CAAQ,GAC7Ba,IAAmBH,EAAsBd,KAAS,IAAI,GACtDkB,IAAcJ,EAAO,EAAK,GAC1BK,IAAoBL,EAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,GAElDM,IAAaC,EAAY,CAACC,MAA6B;AAC3D,IAAIL,EAAiB,YAAYK,MACjCL,EAAiB,UAAUK,GAC3BN,EAAY,UAAUM,CAAS;AAAA,EACjC,GAAG,CAAA,CAAE;AAEL,EAAAC,EAAU,MAAM;AACd,IAAAP,EAAY,UAAUZ;AAAA,EACxB,GAAG,CAACA,CAAQ,CAAC,GAEbmB,EAAU,MAAM;AACd,IAAAN,EAAiB,UAAUjB,KAAS;AAAA,EACtC,GAAG,CAACA,CAAK,CAAC,GAEVuB,EAAU,MAAM;AAId,QAHIL,EAAY,YAChBA,EAAY,UAAU,IAElB,CAAClB,KAASS,MAAS,QAAQ;AAC/B,UAAMe,IAAWX,EAAU;AAC3B,QAAKW;AAEL,UAAI;AACF,QAAAA,EAAS,YAAYxB,CAAK;AAAA,MAC5B,QAAQ;AACN,QAAAwB,EAAS,MAAA;AAAA,MACX;AAAA,EAEF,GAAG,CAAA,CAAE,GAELD,EAAU,MAAM;AACd,QAAId,MAAS,OAAQ;AAErB,UAAMlB,IAASwB,EAAW;AAC1B,QAAI,CAACxB,EAAQ;AAEb,QAAI4B,EAAkB,QAAQ,UAAU,GAAG;AACzC,YAAMM,IAAOlC,EAAO,sBAAA;AACpB,MAAA4B,EAAkB,UAAU;AAAA,QAC1B,OAAO,KAAK,IAAI,GAAG,KAAK,MAAMM,EAAK,KAAK,CAAC;AAAA,QACzC,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAMA,EAAK,MAAM,CAAC;AAAA,MAAA;AAAA,IAE/C;AAEA,UAAMnD,IAAO6C,EAAkB;AAC/B,QAAI,CAAC7C,EAAK,SAAS,CAACA,EAAK,OAAQ;AAEjC,UAAMqB,IAAQ,OAAO,oBAAoB;AASzC,QAAI,CARYL,EAAqB;AAAA,MACnC,QAAAC;AAAA,MACA,MAAAC;AAAA,MACA,OAAOlB,EAAK;AAAA,MACZ,QAAQA,EAAK;AAAA,MACb,OAAAqB;AAAA,IAAA,CACD,GAEa;AACZ,MAAAyB,EAAW,IAAI;AACf;AAAA,IACF;AAEA,UAAMM,IAAe,SAAS,cAAc,QAAQ;AACpD,IAAApC,EAAqB;AAAA,MACnB,QAAQoC;AAAA,MACR,MAAAlC;AAAA,MACA,OAAOlB,EAAK;AAAA,MACZ,QAAQA,EAAK;AAAA,MACb,OAAAqB;AAAA,IAAA,CACD,GAEDyB,EAAWM,EAAa,UAAUpB,CAAS,CAAC;AAAA,EAC9C,GAAG,CAACG,GAAMjB,GAAMc,GAAWc,CAAU,CAAC;AAEtC,QAAMO,IAAiB,MAAM;AAC3B,IAAAd,EAAU,SAAS,MAAA,GACnBD,EAAQ,EAAE,GACVQ,EAAW,IAAI;AAAA,EACjB,GAEMQ,IAAgB,MAAM;AAC1B,QAAInB,MAAS,OAAQ;AACrB,UAAMoB,IAAOhB,EAAU,SAAS,UAAUP,CAAS,KAAK;AACxD,IAAAc,EAAWS,CAAI;AAAA,EACjB,GAEMC,IAAmB,CAACC,MAA0B;AAClD,IAAIA,MAAStB,MACbkB,EAAA,GACAjB,EAAQqB,CAAI;AAAA,EACd,GAEMC,IAAmB,CAAChD,MAAyC;AACjE,IAAA4B,EAAQ5B,EAAM,OAAO,KAAK;AAAA,EAC5B;AAMA,SAAIuB,MAAe,0BAEd,OAAA,EAAI,IAAG,aAAY,WAAU,UAC3B,UAAAP,IACC,gBAAAjC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKiC;AAAA,MACL,KAAI;AAAA,MACJ,WAAW/B;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAoC;AAAA,MAAA;AAAA,IACF;AAAA,EAAA,IAGF,gBAAAtC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAW;AAAA,MACX,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAoC;AAAA,MAAA;AAAA,MAGF,UAAA,gBAAAtC,EAAC,OAAA,EAAI,WAAU,0GAAyG,UAAA,YAAA,CAExH;AAAA,IAAA;AAAA,EAAA,GAGN,IAKF,gBAAAA,EAAC,OAAA,EAAI,IAAG,aACN,UAAA,gBAAAgB;AAAA,IAACkD;AAAA,IAAA;AAAA,MACC,WAAWhE;AAAA,QACTwC,MAAS,SAAS,aAAa;AAAA,QAC/B;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,gBAAA1C,EAACmE,GAAA,EAAgB,OAAM,eAAc,WAAU,QAC7C,UAAA,gBAAAnD,EAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gGACb,UAAA;AAAA,YAAA,gBAAAhB;AAAA,cAACJ;AAAA,cAAA;AAAA,gBACC,OAAO8C;AAAA,gBACP,eAAe,CAACsB,MACdD,EAAiBC,CAAuB;AAAA,gBAE1C,WAAU;AAAA,gBAEV,4BAAC3D,GAAA,EAAS,SAAQ,aAAY,SAAQ,MAAK,MAAK,MAC9C,UAAA;AAAA,kBAAA,gBAAAW,EAACP,GAAA,EAAY,OAAM,QACjB,UAAA;AAAA,oBAAA,gBAAAT,EAACoE,GAAA,EAAY;AAAA,oBACb,gBAAApE,EAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,OAAA,CAAI;AAAA,kBAAA,GACvC;AAAA,kBACA,gBAAAgB,EAACP,GAAA,EAAY,OAAM,QACjB,UAAA;AAAA,oBAAA,gBAAAT,EAACqE,GAAA,EAAa;AAAA,oBACd,gBAAArE,EAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,OAAA,CAAI;AAAA,kBAAA,EAAA,CACvC;AAAA,gBAAA,EAAA,CACF;AAAA,cAAA;AAAA,YAAA;AAAA,YAEF,gBAAAgB;AAAA,cAACsD;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR,SAASV;AAAA,gBAET,UAAA;AAAA,kBAAA,gBAAA5D,EAACuE,GAAA,EAAW;AAAA,kBACZ,gBAAAvE,EAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,QAAA,CAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACxC,GACF;AAAA,UACC0C,MAAS,SACR,gBAAA1C;AAAA,YAACwE;AAAA,YAAA;AAAA,cACC,KAAK1B;AAAA,cACL,OAAOe;AAAA,cACP,aAAa;AAAA,gBACX,WACEvB,KACApC;AAAA,kBACE;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBAAA;AAAA,cACF;AAAA,YACJ;AAAA,UAAA,IAGF,gBAAAF;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKgD;AAAA,cACL,WAAW9C;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QACF,EAAA,CAEJ,EAAA,CACF;AAAA,QACA,gBAAAF;AAAA,UAACyE;AAAA,UAAA;AAAA,YACC,UAAU/B,MAAS;AAAA,YACnB,WAAWxC;AAAA,cACTwC,MAAS,SACL,8CACA;AAAA,cACJ;AAAA,YAAA;AAAA,YAEF,aAAY;AAAA,YACZ,OAAOjB;AAAA,YACP,UAAUwC;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;AC7SO,MAAMS,KAAgC;AAAA,EAC3C,YAAY;AAAA,IACV,CAACC,EAAU,SAAS,GAAGvC;AAAA,EAAA;AAAA,EAEzB,kBAAkB;AAAA,IAChB,CAACuC,EAAU,SAAS,GAAG;AAAA,MACrB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW,CAACC,MAAuBA;AAAA,IAAA;AAAA,EACrC;AAEJ;"}
1
+ {"version":3,"file":"signature.js","sources":["../../src/components/ui/tabs.tsx","../../src/components/ui/signature-pad.tsx","../../src/renderer/presets/signature.ts"],"sourcesContent":["\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\nimport { useHaptics, HAPTIC_TAB } from \"@/lib/haptics\";\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-orientation={orientation}\n className={cn(\n \"gap-2 group/tabs flex\",\n \"data-[orientation=horizontal]:flex-col\",\n \"data-[orientation=vertical]:w-full\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst tabsListVariants = cva(\n \"overflow-auto inline-flex bg-transparent w-fit items-start justify-start group-data-horizontal/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col\",\n {\n variants: {\n variant: {\n default:\n \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n ghost:\n \"gap-1 border-none rounded-none p-[calc(var(--trigger-translate)+6px)]\",\n icon: \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n contained:\n \"gap-0 border-0 rounded-md p-[calc(var(--trigger-translate)+2px)]\",\n },\n size: {\n sm: \"\",\n md: \"\",\n lg: \"\",\n xl: \"\",\n },\n extrude: {\n default:\n \"[--trigger-shadow:var(--shadow-none)] [--trigger-translate:0px] [--focus-trigger-translate:0px]\",\n xs: \"[--trigger-shadow:var(--shadow-min)] [--trigger-translate:1px] [--focus-trigger-shadow:var(--shadow-none)] [--focus-trigger-translate:0px]\",\n sm: \"[--trigger-shadow:var(--shadow-xs)] [--trigger-translate:2px] [--focus-trigger-shadow:var(--shadow-min)] [--focus-trigger-translate:1px]\",\n md: \"[--trigger-shadow:var(--shadow-sm)] [--trigger-translate:3px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n lg: \"[--trigger-shadow:var(--shadow-md)] [--trigger-translate:4px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n xl: \"[--trigger-shadow:var(--shadow-lg)] [--trigger-translate:5px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n extrude: \"default\",\n },\n },\n);\n\nfunction TabsList({\n className,\n variant = \"default\",\n size = \"md\",\n extrude = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n data-size={size}\n className={cn(\n tabsListVariants({ variant, size, extrude }),\n \"group/tabs-list\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TabsTrigger({\n label,\n description,\n children,\n className,\n onClick,\n ...props\n}: TabsPrimitive.Tab.Props & {\n label?: React.ReactNode;\n description?: React.ReactNode;\n}) {\n const { trigger } = useHaptics();\n return (\n <TabsPrimitive.Tab\n data-slot=\"tabs-trigger\"\n aria-label={props.value ?? \"tabs-trigger\"}\n className={cn(\n \"group/tabs-trigger neo-base relative inline-flex flex-1 items-center justify-center overflow-hidden cursor-pointer rounded-base border-2 py-1\",\n \"bg-surface data-active:bg-main\",\n \"font-medium h-[calc(100%-1px)] whitespace-nowrap [&_svg]:shrink-0\",\n \"transition-[translate,box-shadow,border,color] duration-200\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none aria-disabled:translate-0\",\n \"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start\",\n\n \"active:shadow-none active:translate-0\",\n \"data-active:shadow-(--trigger-shadow) data-active:-translate-(--trigger-translate)\",\n \"hover:shadow-(--trigger-shadow) hover:-translate-(--trigger-translate)\",\n \"focus-visible:shadow-(--focus-trigger-shadow) focus-visible:-translate-(--focus-trigger-translate)\",\n \"focus-visible:hover:-translate-(--focus-trigger-translate) focus-visible:**:font-semibold\",\n\n \"group-data-[size=xl]/tabs-list:min-h-12\",\n\n \"group-data-[size=sm]/tabs-list:[&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[size=md]/tabs-list:[&_svg:not([class*='size-'])]:size-5\",\n \"group-data-[size=lg]/tabs-list:[&_svg:not([class*='size-'])]:size-6\",\n \"group-data-[size=xl]/tabs-list:[&_svg:not([class*='size-'])]:size-7\",\n\n \"group-data-[variant=default]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[variant=ghost]/tabs-list:border-none\",\n \"group-data-[variant=ghost]/tabs-list:data-active:bg-transparent group-data-[variant=ghost]/tabs-list:shadow-none\",\n\n \"group-data-[variant=icon]/tabs-list:group-data-[size=sm]/tabs-list:px-1.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=md]/tabs-list:px-2\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=lg]/tabs-list:px-2.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=xl]/tabs-list:px-3\",\n \"group-data-[variant=icon]/tabs-list:m-auto group-data-[variant=icon]/tabs-list:max-w-fit group-data-[variant=icon]/tabs-list:aspect-square group-data-[variant=icon]/tabs-list:items-center group-data-[variant=icon]/tabs-list:justify-center group-data-[variant=icon]/tabs-list:hover:border-foreground group-data-[variant=icon]/tabs-list:border-transparent group-data-[variant=icon]/tabs-list:data-active:border-border\",\n\n \"group-data-[variant=contained]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-r-none group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-l-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-b-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-t-none group-data-[variant=contained]/tabs-list:-m-px\",\n\n children ? \"gap-1.5\" : \"flex-col gap-0.5\",\n className,\n )}\n onClick={(event) => {\n trigger(HAPTIC_TAB);\n onClick?.(event);\n }}\n {...props}\n >\n {label && (\n <span\n data-slot=\"tabs-trigger-label\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 font-medium font-heading\",\n \"group-data-[size=sm]/tabs-list:text-sm\",\n \"group-data-[size=md]/tabs-list:text-base\",\n \"group-data-[size=lg]/tabs-list:text-lg\",\n \"group-data-[size=xl]/tabs-list:text-2xl\",\n )}\n >\n {label}\n </span>\n )}\n {description && (\n <span\n data-slot=\"tabs-trigger-description\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 whitespace-normal\",\n \"group-data-[size=sm]/tabs-list:text-xs\",\n \"group-data-[size=md]/tabs-list:text-sm\",\n \"group-data-[size=lg]/tabs-list:text-base\",\n \"group-data-[size=xl]/tabs-list:text-lg\",\n )}\n >\n {description}\n </span>\n )}\n {children}\n <div\n data-slot=\"tabs-trigger-indicator\"\n className={cn(\n \"pointer-events-none h-[3px] rounded-full bg-foreground absolute hidden bottom-0 left-1 right-1\",\n \"group-data-[variant=ghost]/tabs-list:group-data-active/tabs-trigger:block\",\n )}\n />\n </TabsPrimitive.Tab>\n );\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n <TabsPrimitive.Panel\n data-slot=\"tabs-content\"\n className={cn(\n \"text-sm flex-1 neo-base border-l-2 border-l-transparent focus-visible:border-l-border -ml-0.5 pl-0.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Button } from \"./button\";\nimport { Tabs, TabsList, TabsTrigger } from \"./tabs\";\nimport SignatureCanvas from \"react-signature-canvas\";\nimport type { ChangeEvent } from \"react\";\nimport { IconEraser, IconWriting, IconTextSize } from \"@tabler/icons-react\";\nimport { InputGroup, InputGroupAddon, InputGroupInput } from \"./input-group\";\nimport { cn } from \"@/lib/utils\";\nimport { useBonsaiRenderMode } from \"../core/bonsai\";\n\nexport type SignatureProps = {\n value?: string | null;\n onChange?: (value: string | null) => void;\n canvasClassName?: string;\n imageType?: \"image/png\" | \"image/jpeg\" | \"image/webp\";\n};\n\nconst FONT_FAMILY = '\"Great Vibes\", cursive';\nconst FONT_SIZE_MAX = 64;\nconst FONT_SIZE_MIN = 24;\nconst TEXT_PADDING_X = 20;\n\nfunction renderTypedSignature({\n canvas,\n text,\n width,\n height,\n ratio,\n}: {\n canvas: HTMLCanvasElement;\n text: string;\n width: number;\n height: number;\n ratio: number;\n}) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return false;\n\n const displayWidth = Math.max(1, Math.floor(width));\n const displayHeight = Math.max(1, Math.floor(height));\n const pixelRatio = Math.max(ratio || 1, 1);\n\n canvas.width = Math.max(1, Math.floor(displayWidth * pixelRatio));\n canvas.height = Math.max(1, Math.floor(displayHeight * pixelRatio));\n ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n ctx.clearRect(0, 0, displayWidth, displayHeight);\n\n const value = text.trim();\n if (!value) return false;\n\n const maxTextWidth = Math.max(1, displayWidth - TEXT_PADDING_X * 2);\n\n ctx.fillStyle = \"#000\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n let fontSize = FONT_SIZE_MAX;\n while (fontSize > FONT_SIZE_MIN) {\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n if (ctx.measureText(value).width <= maxTextWidth) break;\n fontSize -= 1;\n }\n\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n ctx.fillText(value, displayWidth / 2, displayHeight / 2, maxTextWidth);\n\n return true;\n}\n\nexport function Signature({\n value,\n onChange,\n canvasClassName,\n imageType = \"image/png\",\n}: SignatureProps) {\n const renderMode = useBonsaiRenderMode();\n const [mode, setMode] = useState<\"sign\" | \"type\">(\"sign\");\n const [text, setText] = useState(\"\");\n\n const signature = useRef<SignatureCanvas | null>(null);\n const textCanvas = useRef<HTMLCanvasElement | null>(null);\n const onChangeRef = useRef(onChange);\n const lastEmittedValue = useRef<string | null>(value ?? null);\n const initialized = useRef(false);\n const textCanvasSizeRef = useRef({ width: 0, height: 0 });\n\n const emitChange = useCallback((nextValue: string | null) => {\n if (lastEmittedValue.current === nextValue) return;\n lastEmittedValue.current = nextValue;\n onChangeRef.current?.(nextValue);\n }, []);\n\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n lastEmittedValue.current = value ?? null;\n }, [value]);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n if (!value || mode !== \"sign\") return;\n const instance = signature.current;\n if (!instance) return;\n\n try {\n instance.fromDataURL(value);\n } catch {\n instance.clear();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- seeds the canvas from the initial value once, on mount\n }, []);\n\n useEffect(() => {\n if (mode !== \"type\") return;\n\n const canvas = textCanvas.current;\n if (!canvas) return;\n\n if (textCanvasSizeRef.current.width === 0) {\n const rect = canvas.getBoundingClientRect();\n textCanvasSizeRef.current = {\n width: Math.max(1, Math.floor(rect.width)),\n height: Math.max(1, Math.floor(rect.height)),\n };\n }\n\n const size = textCanvasSizeRef.current;\n if (!size.width || !size.height) return;\n\n const ratio = window.devicePixelRatio || 1;\n const hasText = renderTypedSignature({\n canvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n if (!hasText) {\n emitChange(null);\n return;\n }\n\n const exportCanvas = document.createElement(\"canvas\");\n renderTypedSignature({\n canvas: exportCanvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n emitChange(exportCanvas.toDataURL(imageType));\n }, [mode, text, imageType, emitChange]);\n\n const clearSignature = () => {\n signature.current?.clear();\n setText(\"\");\n emitChange(null);\n };\n\n const handleDrawEnd = () => {\n if (mode !== \"sign\") return;\n const data = signature.current?.toDataURL(imageType) ?? null;\n emitChange(data);\n };\n\n const handleModeChange = (next: \"sign\" | \"type\") => {\n if (next === mode) return;\n clearSignature();\n setMode(next);\n };\n\n const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {\n setText(event.target.value);\n };\n\n // In a non-interactive document there is no client JS to draw a canvas, so\n // the captured value (a base64 data URI baked in at capture time) is shown as\n // a plain image, and an unsigned pad as an empty signature line — never the\n // interactive control, which would render as a blank grid with a toolbar.\n if (renderMode === \"pdf\") {\n return (\n <div id=\"signature\" className=\"w-full\">\n {value ? (\n <img\n src={value}\n alt=\"Signature\"\n className={cn(\n \"w-full h-[256px] object-contain\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassName,\n )}\n />\n ) : (\n <div\n aria-label=\"Unsigned\"\n className={cn(\n \"w-full h-[256px] flex items-end\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassName,\n )}\n >\n <div className=\"w-full border-t-2 border-dashed border-border mx-6 mb-8 pb-1 text-center text-sm text-muted-foreground\">\n Signature\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div id=\"signature\">\n <InputGroup\n className={cn(\n mode === \"type\" ? \"max-h-84\" : \"max-h-69\",\n \"overflow-hidden transition-[max-height] duration-300 has-[>[data-align=block-start]]:p-2 gap-2\",\n )}\n >\n <InputGroupAddon align=\"block-start\" className=\"p-0!\">\n <div className=\"relative w-full rounded-base\">\n <div className=\"absolute top-4 left-4 right-3 bg-transparent flex flex-row items-start justify-between gap-3\">\n <Tabs\n value={mode}\n onValueChange={(next) =>\n handleModeChange(next as \"sign\" | \"type\")\n }\n className=\"-mt-1\"\n >\n <TabsList variant=\"contained\" extrude=\"sm\" size=\"md\">\n <TabsTrigger value=\"sign\">\n <IconWriting />\n <span className=\"hidden sm:flex\">Draw</span>\n </TabsTrigger>\n <TabsTrigger value=\"type\">\n <IconTextSize />\n <span className=\"hidden sm:flex\">Type</span>\n </TabsTrigger>\n </TabsList>\n </Tabs>\n <Button\n size=\"sm\"\n raised=\"xs\"\n variant=\"outline\"\n onClick={clearSignature}\n >\n <IconEraser />\n <span className=\"hidden sm:flex\">Clear</span>\n </Button>\n </div>\n {mode === \"sign\" ? (\n <SignatureCanvas\n ref={signature}\n onEnd={handleDrawEnd}\n canvasProps={{\n className:\n canvasClassName ??\n cn(\n \"w-full h-[256px]\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n \"cursor-crosshair\",\n ),\n }}\n />\n ) : (\n <canvas\n ref={textCanvas}\n className={cn(\n \"w-full h-64\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n )}\n />\n )}\n </div>\n </InputGroupAddon>\n <InputGroupInput\n disabled={mode !== \"type\"}\n className={cn(\n mode === \"type\"\n ? \"animate-in zoom-in-0 spin-in-20 scale-100\"\n : \"animate-out zoom-out-0 spin-out-20 scale-0\",\n \"py-2 text-lg font-medium transition-[scale,translate,box-shadow] duration-300 origin-bottom-left\",\n )}\n placeholder=\"Enter Full Name\"\n value={text}\n onChange={handleTextChange}\n />\n </InputGroup>\n </div>\n );\n}\n","import { COMPONENT } from \"@bonsai/constants\";\n\nimport { Signature } from \"../../components/ui/signature-pad\";\nimport type { BonsaiPreset } from \"../core-registry\";\n\n/** Opt-in `signature` component. Pulls in react-signature-canvas. */\nexport const signaturePreset: BonsaiPreset = {\n components: {\n [COMPONENT.SIGNATURE]: Signature,\n },\n controlledInputs: {\n [COMPONENT.SIGNATURE]: {\n valueProp: \"value\",\n changeProp: \"onChange\",\n extractor: (val: string | null) => val,\n },\n },\n};\n\nexport { Signature };\nexport type { SignatureProps } from \"../../components/ui/signature-pad\";\n"],"names":["Tabs","className","orientation","props","jsx","TabsPrimitive","cn","tabsListVariants","cva","TabsList","variant","size","extrude","TabsTrigger","label","description","children","onClick","trigger","useHaptics","jsxs","event","HAPTIC_TAB","FONT_FAMILY","FONT_SIZE_MAX","FONT_SIZE_MIN","TEXT_PADDING_X","renderTypedSignature","canvas","text","width","height","ratio","ctx","displayWidth","displayHeight","pixelRatio","value","maxTextWidth","fontSize","Signature","onChange","canvasClassName","imageType","renderMode","useBonsaiRenderMode","mode","setMode","useState","setText","signature","useRef","textCanvas","onChangeRef","lastEmittedValue","initialized","textCanvasSizeRef","emitChange","useCallback","nextValue","useEffect","instance","rect","exportCanvas","clearSignature","handleDrawEnd","data","handleModeChange","next","handleTextChange","InputGroup","InputGroupAddon","IconWriting","IconTextSize","Button","IconEraser","SignatureCanvas","InputGroupInput","signaturePreset","COMPONENT","val"],"mappings":"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"}
package/dist/schemas.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as s, a as o, N as t, P as m, c as n, f as N, g as c, b as d, n as g } from "./chunks/builder.meta-B7Y9M7Ab.js";
1
+ import { C as s, a as o, N as t, P as m, c as n, f as N, g as c, b as d, n as g } from "./chunks/builder.meta-DKq-ggkn.js";
2
2
  export {
3
3
  s as ComponentNode,
4
4
  o as Config,
@@ -11,7 +11,8 @@
11
11
  },
12
12
  "presets": {
13
13
  "core": ["tailwind", "theme", "base"],
14
- "full": ["tailwind", "tw-animate", "fonts", "theme", "base", "utilities", "overrides"]
14
+ "full": ["tailwind", "tw-animate", "fonts", "theme", "base", "utilities", "overrides"],
15
+ "pdf": ["tailwind", "tw-animate", "theme", "base", "utilities", "overrides"]
15
16
  },
16
17
  "vendor": {
17
18
  "tw-animate-css": "vendor/tw-animate.css",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pebble-software/bonsai",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css"
@@ -63,6 +63,17 @@
63
63
  "import": "./dist/ast.js",
64
64
  "default": "./dist/ast.js"
65
65
  },
66
+ "./classes": {
67
+ "types": "./dist/classes.d.ts",
68
+ "import": "./dist/classes.js",
69
+ "default": "./dist/classes.js"
70
+ },
71
+ "./classes.json": "./dist/classes.json",
72
+ "./css": {
73
+ "types": "./dist/css.d.ts",
74
+ "import": "./dist/css.js",
75
+ "default": "./dist/css.js"
76
+ },
66
77
  "./index.css": {
67
78
  "style": "./dist/index.css",
68
79
  "import": "./dist/index.css",
@@ -88,6 +99,7 @@
88
99
  "@bonsai/constants": "workspace:*",
89
100
  "@bonsai/schemas": "workspace:*",
90
101
  "@eslint/js": "^10.0.1",
102
+ "@tailwindcss/oxide": "^4.1.11",
91
103
  "@tailwindcss/vite": "^4.1.11",
92
104
  "@testing-library/jest-dom": "^6.9.1",
93
105
  "@testing-library/react": "^16.3.2",
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-renderer-C4nV9RV6.js","sources":["../../src/components/core/render-tree-server.tsx","../../src/components/core/render-tree-client.tsx","../../src/components/core/bonsai.tsx","../../src/renderer/create-renderer.tsx"],"sourcesContent":["import { createElement, memo, useCallback } from \"react\";\nimport { type CompiledNode } from \"../../lib/renderer/compile-template\";\nimport { compileTemplate } from \"../../lib/renderer/compile-template\";\nimport {\n BonsaiRoot,\n useBonsaiRegistry,\n buildDataSlice,\n getValue,\n resolveWrapper,\n renderCompiledNode,\n type GlobalData,\n type NodeCtx,\n type RenderStrategy,\n type BonsaiProps,\n} from \"./render-shared\";\n\ninterface RenderTreeServerProps {\n // Precompiled metadata for this node; `node.source` is the raw template node.\n node: CompiledNode;\n index?: number;\n path?: string;\n data: GlobalData;\n // Alias -> real store path prefix set by an ancestor `each` (e.g. { applicant: \"applicants.3\" }); SSR-only.\n scope?: Record<string, string>;\n}\n\n// SSR ctx is the prop-drilled global data object plus the current `each` scope.\ninterface ServerCtx extends NodeCtx {\n data: GlobalData;\n}\n\nconst SERVER_MODE: RenderStrategy<ServerCtx> = {\n dataSlice(node, _ctx, globalData) {\n return buildDataSlice(node.dynamicKeys, (key) => {\n if (key in globalData && key !== \"data\") return globalData[key];\n return getValue(globalData.data ?? globalData, key);\n });\n },\n rowCtx(ctx, globalData, item, i, each, realItemsPath) {\n const { as, indexAlias } = each;\n const rowData = {\n ...globalData,\n data: {\n ...(globalData.data ?? globalData),\n [as]: item,\n ...(indexAlias ? { [indexAlias]: i } : {}),\n },\n };\n const rowScope = realItemsPath\n ? { ...ctx.scope, [as]: `${realItemsPath}.${i}` }\n : ctx.scope;\n return { data: rowData, scope: rowScope };\n },\n renderChild(child, i, path, ctx, key) {\n return (\n <RenderTreeServer\n key={key}\n node={child}\n index={i}\n path={path}\n data={ctx.data}\n scope={ctx.scope}\n />\n );\n },\n};\n\n// SSR: single-pass render over a plain, prop-drilled object — no store, no snapshots.\nconst RenderTreeServer = memo(\n ({ node, index = 0, path = \"root\", data, scope }: RenderTreeServerProps) => {\n const registry = useBonsaiRegistry();\n const updateData = useCallback(() => {\n // Attached for the controlled-component contract but never invoked during SSR.\n }, []);\n\n return renderCompiledNode(\n node,\n index,\n path,\n { data, scope },\n data,\n registry,\n updateData,\n SERVER_MODE,\n );\n },\n);\n\nexport function BonsaiServer({\n template,\n expiry,\n data,\n status = \"pending\",\n render = \"web\",\n as,\n registry,\n}: BonsaiProps) {\n const ctx = {\n data: data ?? {},\n expiry: expiry ?? \"\",\n status,\n submitting: false,\n };\n\n // Cached by template identity, so N instances of the same template compile once.\n const root = compileTemplate(template).root;\n const Wrapper = resolveWrapper(render, as);\n\n return (\n <BonsaiRoot registry={registry} render={render}>\n {createElement(\n Wrapper,\n {\n \"data-mode\": render,\n className: `group bonsai-root${render === \"pdf\" ? \" w-full\" : \"\"}`,\n },\n <RenderTreeServer node={root} index={0} path=\"root\" data={ctx} />,\n )}\n </BonsaiRoot>\n );\n}\n","import {\n createContext,\n createElement,\n memo,\n useCallback,\n useContext,\n useEffect,\n useEffectEvent,\n useLayoutEffect,\n useRef,\n useState,\n type SubmitEvent,\n} from \"react\";\nimport { proxy, snapshot, subscribe, useSnapshot } from \"valtio\";\nimport { type CompiledNode } from \"../../lib/renderer/compile-template\";\nimport { compileTemplate } from \"../../lib/renderer/compile-template\";\nimport {\n BonsaiRoot,\n useBonsaiRegistry,\n VOID_ELEMENTS,\n getKey,\n getValue,\n setValue,\n resolveScopedPath,\n pathRoot,\n buildDataSlice,\n resolveElementType,\n prepareState,\n resolveWrapper,\n cloneData,\n renderCompiledNode,\n type GlobalData,\n type NodeCtx,\n type RenderStrategy,\n type BonsaiProps,\n} from \"./render-shared\";\n\n// scope/indexScope/valueScope are the only things an `each` row hands its children on the live path —\n// store data is never prop-drilled (valueScope carries only computed-row items, which have no store path).\ninterface RenderTreeClientProps {\n node: CompiledNode;\n index?: number;\n path?: string;\n scope?: Record<string, string>;\n indexScope?: Record<string, number>;\n valueScope?: Record<string, unknown>;\n}\n\ntype BonsaiState = {\n status: string;\n expiry: string;\n data: Record<string, unknown>;\n submitting: boolean;\n};\n\nconst BonsaiContext = createContext<ReturnType<\n typeof proxy<BonsaiState>\n> | null>(null);\n\nfunction useBonsaiStore(): ReturnType<typeof proxy<BonsaiState>> {\n const store = useContext(BonsaiContext);\n if (!store) {\n throw new Error(\"useBonsaiStore must be used within a <Bonsai> component\");\n }\n return store;\n}\n\nexport function useUpdateData() {\n const store = useBonsaiStore();\n return useCallback(\n (path: string, value: unknown) => setValue(store.data, path, value),\n [store],\n );\n}\n\n// Live-path lookup: resolves each-scoped aliases at read time against a fresh snapshot.\nfunction resolveKeyValue(\n key: string,\n globalData: GlobalData,\n scope: Record<string, string> | undefined,\n indexScope: Record<string, number> | undefined,\n valueScope: Record<string, unknown> | undefined,\n): unknown {\n const root = pathRoot(key);\n\n if (indexScope && root in indexScope) {\n return key === root ? indexScope[root] : undefined;\n }\n\n if (scope && root in scope) {\n return getValue(globalData.data ?? globalData, resolveScopedPath(key, scope));\n }\n\n if (valueScope && Object.hasOwn(valueScope, root)) {\n return getValue(valueScope, key);\n }\n\n if (key in globalData && key !== \"data\") {\n return globalData[key];\n }\n\n return getValue(globalData.data ?? globalData, key);\n}\n\n// Children still go through `renderClientNode`, so a binding nested inside an unbound wrapper stays reactive.\nconst StaticNode = memo(\n ({ node, index = 0, path = \"root\", scope, indexScope, valueScope }: RenderTreeClientProps) => {\n const registry = useBonsaiRegistry();\n const tree = node.source;\n\n if (!tree) return null;\n if (node.isText) {\n // `isStatic` guarantees this has no `{{...}}` binding to evaluate.\n return tree as unknown as string;\n }\n\n try {\n const type = node.type;\n const ElementType = resolveElementType(registry, type);\n const key = getKey(node, index, path);\n const props = prepareState(node, {}, key);\n\n if (node.isImage && (props.src === \"\" || props.src == null)) {\n return null;\n }\n\n const childNodes =\n node.children.length > 0\n ? node.children.map((branch: CompiledNode, i: number) =>\n renderClientNode(\n branch,\n i,\n `${path}-${index}`,\n scope,\n indexScope,\n valueScope,\n getKey(node, i, `${path}-${index}`),\n ),\n )\n : undefined;\n\n const safeChildNodes =\n typeof ElementType === \"string\" && VOID_ELEMENTS.has(ElementType)\n ? undefined\n : childNodes;\n\n if (safeChildNodes !== undefined) {\n return createElement(ElementType, props, safeChildNodes);\n }\n return createElement(ElementType, props);\n } catch (error) {\n console.error(`Error at ${path}-${index}:`, error);\n return null;\n }\n },\n);\n\n// A plain function, not a hook, since it decides which component type to mount — always a safe conditional.\nfunction renderClientNode(\n node: CompiledNode,\n index: number,\n path: string,\n scope: Record<string, string> | undefined,\n indexScope: Record<string, number> | undefined,\n valueScope: Record<string, unknown> | undefined,\n key: string,\n): React.ReactNode {\n return node.isStatic ? (\n <StaticNode\n key={key}\n node={node}\n index={index}\n path={path}\n scope={scope}\n indexScope={indexScope}\n valueScope={valueScope}\n />\n ) : (\n <RenderTreeClient\n key={key}\n node={node}\n index={index}\n path={path}\n scope={scope}\n indexScope={indexScope}\n valueScope={valueScope}\n />\n );\n}\n\n// Client ctx carries only what an `each` row hands its children on this path — no data is prop-drilled.\ninterface ClientCtx extends NodeCtx {\n indexScope?: Record<string, number>;\n}\n\nfunction omitKey<T>(\n obj: Record<string, T> | undefined,\n key: string,\n): Record<string, T> | undefined {\n if (!obj || !Object.hasOwn(obj, key)) return obj;\n const rest = { ...obj };\n delete rest[key];\n return rest;\n}\n\nconst CLIENT_MODE: RenderStrategy<ClientCtx> = {\n dataSlice(node, ctx, globalData) {\n return buildDataSlice(node.dynamicKeys, (key) =>\n resolveKeyValue(key, globalData, ctx.scope, ctx.indexScope, ctx.valueScope),\n );\n },\n rowCtx(ctx, _globalData, item, i, each, realItemsPath) {\n const { as, indexAlias } = each;\n const rowIndexScope = indexAlias\n ? { ...ctx.indexScope, [indexAlias]: i }\n : ctx.indexScope;\n // A plain-path row resolves its alias against the store; a computed row has no store path, so it\n // carries the item itself. Each clears the alias from the other map so an inner alias shadows an outer one.\n if (realItemsPath) {\n return {\n scope: { ...ctx.scope, [as]: `${realItemsPath}.${i}` },\n indexScope: rowIndexScope,\n valueScope: omitKey(ctx.valueScope, as),\n };\n }\n return {\n scope: omitKey(ctx.scope, as),\n indexScope: rowIndexScope,\n valueScope: { ...ctx.valueScope, [as]: item },\n };\n },\n renderChild(child, i, path, ctx, key) {\n return renderClientNode(child, i, path, ctx.scope, ctx.indexScope, ctx.valueScope, key);\n },\n};\n\n// Client: every node calls useSnapshot itself, so it only re-renders when a path it actually reads changes.\nconst RenderTreeClient = memo(\n ({ node, index = 0, path = \"root\", scope, indexScope, valueScope }: RenderTreeClientProps) => {\n const registry = useBonsaiRegistry();\n const store = useBonsaiStore();\n // sync: true keeps the store write and its re-render in the same event, avoiding a one-tick display lag.\n const globalData = useSnapshot(store, { sync: true });\n const updateData = useUpdateData();\n\n return renderCompiledNode(\n node,\n index,\n path,\n { scope, indexScope, valueScope },\n globalData,\n registry,\n updateData,\n CLIENT_MODE,\n );\n },\n);\n\nexport function BonsaiClient({\n captureUrl,\n template,\n render = \"web\",\n as,\n onSubmit,\n onError,\n registry,\n}: BonsaiProps) {\n const store = useBonsaiStore();\n\n const submit = async (e: SubmitEvent) => {\n e.preventDefault();\n // Already captured/completed/revoked: nothing to send, and the lifecycle flags stay as they are.\n if (store.status !== \"pending\") return;\n // Display-only instance: nothing to submit to, so don't touch the lifecycle.\n if (!onSubmit && !captureUrl) return;\n\n // eslint-disable-next-line react-hooks/immutability -- the store is a valtio proxy, mutated by design\n store.submitting = true;\n try {\n if (onSubmit) {\n await onSubmit(snapshot(store.data) as Record<string, unknown>);\n } else {\n const res = await fetch(captureUrl!, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n data: store.data,\n }),\n });\n // fetch only rejects on network failure; an error status must not count as captured.\n if (!res.ok) {\n throw new Error(`Capture failed: ${res.status} ${res.statusText}`.trim());\n }\n }\n\n store.status = \"captured\";\n } catch (error) {\n // Without an `onError`, this keeps the pre-existing behaviour of letting\n // the failure propagate out of the submit handler.\n if (!onError) throw error;\n onError(error);\n } finally {\n store.submitting = false;\n }\n };\n\n // Cached by template identity, so N instances of the same template compile once.\n const root = compileTemplate(template).root;\n const Wrapper = resolveWrapper(render, as);\n\n return (\n <BonsaiRoot registry={registry} render={render}>\n {createElement(\n Wrapper,\n {\n \"data-mode\": render,\n className: `group bonsai-root${render === \"pdf\" ? \" w-full\" : \"\"}`,\n ...(Wrapper === \"form\" ? { onSubmit: submit } : {}),\n },\n renderClientNode(root, 0, \"root\", undefined, undefined, undefined, \"root-0\"),\n )}\n </BonsaiRoot>\n );\n}\n\nexport function BonsaiProvider(props: BonsaiProps) {\n const [store] = useState(() =>\n proxy<BonsaiState>({\n status: props.status ?? \"pending\",\n expiry: props.expiry ?? \"\",\n data: cloneData(props.data ?? {}),\n submitting: false,\n }),\n );\n // The `data` object identity this store was last seeded from.\n const seenDataRef = useRef<BonsaiProps[\"data\"]>(props.data);\n // Set while the provider itself writes to the store, so a parent-driven\n // resync isn't echoed back out through `onDataChange`.\n const resyncingRef = useRef(false);\n const onDataChange = useEffectEvent((next: Record<string, unknown>) => {\n props.onDataChange?.(next);\n });\n\n useLayoutEffect(() => {\n // A new `data` object arrived from the parent — adopt it before paint.\n // Same-reference renders (including in-place mutations) are deliberately ignored.\n if (Object.is(seenDataRef.current, props.data)) return;\n seenDataRef.current = props.data;\n resyncingRef.current = true;\n try {\n store.data = cloneData(props.data ?? {});\n } finally {\n resyncingRef.current = false;\n }\n }, [store, props.data]);\n\n useEffect(() => {\n // valtio only populates subscription `ops` when the (unstable) op tracking\n // is switched on globally, so changes are detected by snapshot identity\n // instead: `snapshot` is memoised per version, so an unchanged `data`\n // subtree returns the very same object and is filtered out here.\n //\n // Notify in sync: the resync flag below is only reliable if the callback\n // runs inside the write, not on a later microtask.\n let previous = snapshot(store.data);\n return subscribe(\n store,\n () => {\n const next = snapshot(store.data);\n if (next === previous) return;\n previous = next;\n // A parent-driven resync isn't a user edit — don't echo it back.\n if (resyncingRef.current) return;\n onDataChange(next as Record<string, unknown>);\n },\n true,\n );\n }, [store]);\n\n return (\n <BonsaiContext.Provider value={store}>\n <BonsaiClient {...props} />\n </BonsaiContext.Provider>\n );\n}\n","import { BonsaiServer } from \"./render-tree-server\";\nimport { BonsaiProvider } from \"./render-tree-client\";\nimport type { BonsaiProps } from \"./render-shared\";\n\nexport {\n BonsaiRegistryContext,\n getValue,\n setValue,\n useBonsaiRenderMode,\n type BonsaiProps,\n type RenderMode,\n} from \"./render-shared\";\nexport { useUpdateData, BonsaiClient, BonsaiProvider } from \"./render-tree-client\";\nexport { BonsaiServer } from \"./render-tree-server\";\n\nexport function Bonsai(props: BonsaiProps) {\n if (typeof window === \"undefined\") {\n return <BonsaiServer {...props} />;\n }\n\n return <BonsaiProvider {...props} />;\n}\n","import {\n Bonsai as BonsaiRenderer,\n BonsaiRegistryContext,\n type BonsaiProps,\n} from \"../components/core/bonsai\";\nimport {\n coreRegistry,\n extendRegistry,\n type ComponentRegistry,\n type ControlledInputRegistry,\n} from \"./core-registry\";\nimport type { BonsaiRegistry } from \"../lib/registry/types\";\n\nexport interface BonsaiRendererOptions {\n /** Base registry. Defaults to the lightweight core registry. */\n registry?: BonsaiRegistry;\n /** Extra components layered over `registry` (they win on key collision). */\n components?: Partial<ComponentRegistry>;\n controlledInputs?: Partial<ControlledInputRegistry>;\n}\n\nexport interface BonsaiRendererInstance {\n Bonsai: React.ComponentType<BonsaiProps>;\n}\n\n/**\n * Builds a renderer bound to its own component registry.\n *\n * The registry is `options.registry` (the lightweight core set by default)\n * plus whatever components the caller supplies (caller entries win on key\n * collision); a `registry` prop on an individual `<Bonsai>` still overrides it. It is captured in a React context at\n * this call, so registries never leak between renderer instances and consumers\n * never have to mutate the exported `componentMap`.\n *\n * Heavy built-ins are opt-in via the presets in `renderer/presets/*`:\n *\n * ```ts\n * import { createBonsaiRenderer } from \"@pebble-software/bonsai/core\";\n * import { calendarPreset } from \"@pebble-software/bonsai/presets/calendar\";\n *\n * const { Bonsai } = createBonsaiRenderer({\n * components: { ...calendarPreset.components, rating: Rating },\n * controlledInputs: { ...calendarPreset.controlledInputs },\n * });\n * ```\n *\n * Call this at module scope: each call returns a fresh component type, so\n * calling it during render would remount the whole tree every time.\n */\nexport function createBonsaiRenderer(\n options: BonsaiRendererOptions = {},\n): BonsaiRendererInstance {\n // Cast: a `Partial<...>` widens values to `| undefined`, but it only ever\n // holds keys the caller actually supplied.\n const registry = extendRegistry(options.registry ?? coreRegistry, {\n components: options.components as ComponentRegistry | undefined,\n controlledInputs: options.controlledInputs as ControlledInputRegistry | undefined,\n });\n\n function Bonsai(props: BonsaiProps) {\n return (\n <BonsaiRegistryContext.Provider value={registry}>\n <BonsaiRenderer {...props} />\n </BonsaiRegistryContext.Provider>\n );\n }\n Bonsai.displayName = \"Bonsai\";\n\n return { Bonsai };\n}\n"],"names":["SERVER_MODE","node","_ctx","globalData","buildDataSlice","key","getValue","ctx","item","i","each","realItemsPath","as","indexAlias","rowData","rowScope","child","path","jsx","RenderTreeServer","memo","index","data","scope","registry","useBonsaiRegistry","updateData","useCallback","renderCompiledNode","BonsaiServer","template","expiry","status","render","root","compileTemplate","Wrapper","resolveWrapper","BonsaiRoot","createElement","BonsaiContext","createContext","useBonsaiStore","store","useContext","useUpdateData","value","setValue","resolveKeyValue","indexScope","valueScope","pathRoot","resolveScopedPath","StaticNode","tree","type","ElementType","resolveElementType","getKey","props","prepareState","childNodes","branch","renderClientNode","safeChildNodes","VOID_ELEMENTS","error","RenderTreeClient","omitKey","obj","rest","CLIENT_MODE","_globalData","rowIndexScope","useSnapshot","BonsaiClient","captureUrl","onSubmit","onError","submit","e","snapshot","res","BonsaiProvider","useState","proxy","cloneData","seenDataRef","useRef","resyncingRef","onDataChange","useEffectEvent","next","useLayoutEffect","useEffect","previous","subscribe","Bonsai","createBonsaiRenderer","options","extendRegistry","coreRegistry","BonsaiRegistryContext","BonsaiRenderer"],"mappings":"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"}