Sand Signature Dialog

A responsive canvas signature pad with animated sand particle effects when a signature is cleared.

Installation

  1. 1

    Install the component:

    npx shadcn@latest add https://ui.amines.fun/r/sand-signature-dialog.json
  2. 2

    Usage:

    jsx

    app/page.jsx

    <SandSignatureDialog onSave={(dataUrl) => console.log("Signature:", dataUrl)} />

Props

PropTypeDefaultDescription
openbooleantrueShow or hide the signature dialog.
onClose() => voidundefinedCalled by the close button or when Escape is pressed while the dialog is open.
onSave(dataUrl: string) => voidundefinedAdds a Save button and receives the completed signature as a PNG data URL.
onSignatureChange(dataUrl: string | null) => voidundefinedCalled after a stroke finishes or the signature is cleared, with a PNG data URL when available.
onClear(event: { animation: ClearAnimation }) => voidundefinedCalled when the Clear action starts and receives the active animation preset.
clearAnimation"thanos" | "gravity" | "vortex" | "fade" | "implode"undefined (uses internal animation state)Controlled clear animation preset. When omitted, the component manages the active preset internally.
defaultClearAnimation"thanos" | "gravity" | "vortex" | "fade" | "implode""thanos"Initial clear animation when the preset is uncontrolled.
onClearAnimationChange(animation: ClearAnimation) => voidundefinedCalled when the footer animation picker selects another preset.
animationOptionsArray<ClearAnimation | { value: ClearAnimation; label: string }>Five built-in presets: thanos, gravity, vortex, fade, and implodePresets available in the footer picker. Each value may be a preset string or an object with a custom label.
showAnimationPickerbooleantrueShow the footer control for cycling through clear animation presets.
clearAnimationDurationnumber1250Duration of the particle clear effect, in milliseconds.
maxParticlesnumber2200Maximum number of sand particles generated for a clear effect (the implementation enforces a minimum of 100).
particleSizenumber1.15Base sand particle radius in CSS pixels (the implementation enforces a minimum of 0.35).
heightnumber | string250Signing surface height. Numbers are converted to pixels; strings are used as CSS height values.
widthnumber | string420Dialog width. Numbers are converted to pixels; strings are used as CSS width values, with a 100% max width.
titlestring"Sign the contract"Heading displayed above the signing surface and used as the dialog's accessible label.
clearLabelstring"Clear"Text displayed on the Clear action.
saveLabelstring"Save"Text displayed on the Save action when onSave is provided.
strokeColorstring"#292929"CSS color used to draw the signature ink.
strokeWidthnumber2.1Signature ink width in CSS pixels.
padBackgroundstring"#FAFAFA"CSS background color of the signing surface.
exportBackgroundstringundefined (transparent PNG)Optional CSS color painted behind the signature when exporting. Omit it to export a transparent PNG.
disabledbooleanfalsePrevent drawing and clear/save actions, and dim the signing surface.
readOnlybooleanfalsePrevent drawing and clearing while leaving an existing signature available to save.
dismissOnEscapebooleantrueCall onClose when Escape is pressed while the dialog is open.
classNamestring""Additional classes applied to the dialog card.
padClassNamestring""Additional classes applied to the signing surface wrapper.
canvasClassNamestring""Additional classes applied to the signature drawing canvas.
styleReact.CSSPropertiesundefinedInline styles applied to the dialog card; these can override its computed width.
padStyleReact.CSSPropertiesundefinedInline styles applied to the signing surface, including overrides for its size and background.