/** * Signature — a surface you sign with a finger, and a handle for getting the * result back out. * * ```tsx * const pad = useRef(null); * * * * ``` * * ## Why the stroke never reaches React * * A finger produces touch events far faster than a component tree can usefully * re-render, and a signature is exactly the case where the lag shows: the line * trails the fingertip and the whole thing feels like drawing through syrup. * * So the stroke being drawn lives in a shared value and is turned into an SVG * `d` string by a worklet on the UI thread — React is not involved in a single * frame of it. When the finger lifts, that one finished string crosses to * JavaScript once and becomes a static path. Committed strokes are ordinary * elements that never animate again, so the hundredth stroke costs what the * first one did. * * Points closer together than `minDistance` are dropped as they arrive. A slow * finger otherwise emits a point per frame in the same spot, which is a longer * path describing the same shape. * * ## Smoothing * * Raw touch points joined with straight lines look like a seismograph. Each * segment is drawn as a quadratic curve through the midpoint between two * points instead — the point itself becomes the control handle, the midpoints * become the anchors, and consecutive curves meet with a shared tangent. It * needs no lookahead, so a point can be appended to a stroke already on screen * without redrawing what came before it differently. * * ## Getting it out * * `toSVG()` is pure string building and always works. Writing a file needs * `expo-file-system`, and rasterising to PNG needs `react-native-view-shot` as * well; both are optional and both are resolved lazily, so a project that only * ever reads the SVG installs neither. Asking for something the missing * package provides throws with its name in the message rather than failing * somewhere further down. */ import { type ReactNode } from 'react'; import { type ViewProps } from 'react-native'; import { type VariantProps } from 'tailwind-variants'; import { type AnimatedPressableProps } from '../../primitives/animated-pressable.js'; /** True when a signature can be written to a file. */ export declare const hasSignatureFileSystem: boolean; /** True when a signature can be rasterised to PNG. */ export declare const hasSignatureRaster: boolean; declare const signatureVariants: import("tailwind-variants").TVReturnType<{ size: { sm: { root: string; }; md: { root: string; }; lg: { root: string; }; /** Fills whatever it is given — for a full-screen signing surface. */ full: { root: string; }; }; disabled: { true: { root: string; }; }; }, { root: string; pad: string; placeholder: string; guide: string; toolbar: string; }, undefined, { size: { sm: { root: string; }; md: { root: string; }; lg: { root: string; }; /** Fills whatever it is given — for a full-screen signing surface. */ full: { root: string; }; }; disabled: { true: { root: string; }; }; }, { root: string; pad: string; placeholder: string; guide: string; toolbar: string; }, import("tailwind-variants").TVReturnType<{ size: { sm: { root: string; }; md: { root: string; }; lg: { root: string; }; /** Fills whatever it is given — for a full-screen signing surface. */ full: { root: string; }; }; disabled: { true: { root: string; }; }; }, { root: string; pad: string; placeholder: string; guide: string; toolbar: string; }, undefined, unknown, unknown, undefined>>; type SignatureVariantProps = VariantProps; export interface SignatureProps extends Omit, Omit { className?: string; /** How tall the pad is. `full` fills its parent instead. */ size?: 'sm' | 'md' | 'lg' | 'full'; /** Ink colour. Defaults to the theme's foreground. */ strokeColor?: string; /** Ink width in points. */ strokeWidth?: number; /** * Points closer together than this are dropped as they arrive, so a finger * resting still does not add hundreds of points describing one spot. */ minDistance?: number; /** Draw the baseline and its ✕ mark, the way a paper form does. */ guideline?: boolean; /** Caption beside the baseline. Only shown with `guideline`. */ guidelineLabel?: string; /** Prompt shown over an empty pad. Pass `null` for none. */ placeholder?: ReactNode; /** Take no input. The strokes already there stay visible. */ disabled?: boolean; /** * Opens a product-provided non-drawing method, such as typing a legal name, * uploading an image, or asking for assisted signing. Exposed as a screen * reader action; provide the same choice as a visible control too. */ onRequestAlternative?: () => void; /** A stroke has started. */ onBegin?: () => void; /** A stroke has finished. */ onEnd?: () => void; /** * The number of committed strokes changed — by drawing, undoing, redoing or * clearing. The cheap way to enable a Save button only once something is * there to save. */ onChange?: (strokeCount: number) => void; /** Class on the drawing surface inside the border. */ padClassName?: string; /** Class on the empty-pad prompt. */ placeholderClassName?: string; /** Class on the baseline. */ guideClassName?: string; } export interface SignatureSaveOptions { /** * Directory to write into, as a `file://` URI. Defaults to the app's own * document directory, which survives restarts and is not visible to the user. */ directory?: string; /** Filename without an extension. Defaults to `signature-`. */ filename?: string; /** `svg` needs no extra packages; `png` rasterises the pad. */ format?: 'svg' | 'png'; /** PNG only — pixels per point. Higher is sharper and larger. */ scale?: number; } export interface SignatureFile { /** Where it was written, as a `file://` URI. */ uri: string; format: 'svg' | 'png'; /** The pad's size in points, which is the SVG's coordinate space. */ width: number; height: number; } export interface SignatureHandle { /** Drop every stroke. */ clear(): void; /** Remove the last stroke. Repeatable down to empty. */ undo(): void; /** Put back the last undone stroke. Drawing again discards the redo stack. */ redo(): void; /** True until the first stroke lands. */ isEmpty(): boolean; /** How many strokes are on the pad. */ strokeCount(): number; /** * The signature as a standalone SVG document, sized to the pad. Pure string * building — no optional package, no async, safe to call every render. */ toSVG(): string; /** * A `data:` URI. `svg` is always available; `png` needs * `react-native-view-shot` and throws by name without it. */ toDataURL(format?: 'svg' | 'png'): Promise; /** * Write the signature to a file and resolve where it went. Needs * `expo-file-system`, plus `react-native-view-shot` for `png`. */ save(options?: SignatureSaveOptions): Promise; } export interface SignatureToolbarProps extends ViewProps { className?: string; children?: ReactNode; } /** A row of controls under or over the pad. Purely layout. */ declare function SignatureToolbar({ className, ...props }: SignatureToolbarProps): import("react").JSX.Element; declare namespace SignatureToolbar { var displayName: string; } export interface SignatureButtonProps extends Omit { className?: string; /** Take no input, and dim to say so. */ disabled?: boolean; /** Replaces the default icon. */ children?: ReactNode; } export declare const Signature: import("react").ForwardRefExoticComponent> & { Toolbar: typeof SignatureToolbar; Undo: { ({ className, disabled, children, accessibilityLabel, ...props }: SignatureButtonProps): import("react").JSX.Element; displayName: string; }; Redo: { ({ className, disabled, children, accessibilityLabel, ...props }: SignatureButtonProps): import("react").JSX.Element; displayName: string; }; Clear: { ({ className, disabled, children, accessibilityLabel, ...props }: SignatureButtonProps): import("react").JSX.Element; displayName: string; }; }; export {}; //# sourceMappingURL=index.d.ts.map