UNPKG

@zag-js/signature-pad

Version:

Core logic for the signature-pad widget implemented as a state machine

174 lines (172 loc) 5.61 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/signature-pad.machine.ts var signature_pad_machine_exports = {}; __export(signature_pad_machine_exports, { machine: () => machine }); module.exports = __toCommonJS(signature_pad_machine_exports); var import_core = require("@zag-js/core"); var import_dom_query = require("@zag-js/dom-query"); var import_perfect_freehand = __toESM(require("perfect-freehand")); var import_get_svg_path = require("./get-svg-path.js"); var dom = __toESM(require("./signature-pad.dom.js")); var machine = (0, import_core.createMachine)({ props({ props }) { return { defaultPaths: [], ...props, drawing: { size: 2, simulatePressure: false, thinning: 0.7, smoothing: 0.4, streamline: 0.6, ...props.drawing }, translations: { control: "signature pad", clearTrigger: "clear signature", ...props.translations } }; }, initialState() { return "idle"; }, context({ prop, bindable }) { return { paths: bindable(() => ({ defaultValue: prop("defaultPaths"), value: prop("paths"), sync: true, onChange(value) { prop("onDraw")?.({ paths: value }); } })), currentPoints: bindable(() => ({ defaultValue: [] })), currentPath: bindable(() => ({ defaultValue: null })) }; }, computed: { isInteractive: ({ prop }) => !(prop("disabled") || prop("readOnly")), isEmpty: ({ context }) => context.get("paths").length === 0 }, on: { CLEAR: { actions: ["clearPoints", "invokeOnDrawEnd", "focusCanvasEl"] } }, states: { idle: { on: { POINTER_DOWN: { target: "drawing", actions: ["addPoint"] } } }, drawing: { effects: ["trackPointerMove"], on: { POINTER_MOVE: { actions: ["addPoint", "invokeOnDraw"] }, POINTER_UP: { target: "idle", actions: ["endStroke", "invokeOnDrawEnd"] } } } }, implementations: { effects: { trackPointerMove({ scope, send }) { const doc = scope.getDoc(); return (0, import_dom_query.trackPointerMove)(doc, { onPointerMove({ event, point }) { const controlEl = dom.getControlEl(scope); if (!controlEl) return; const { offset } = (0, import_dom_query.getRelativePoint)(point, controlEl); send({ type: "POINTER_MOVE", point: offset, pressure: event.pressure }); }, onPointerUp() { send({ type: "POINTER_UP" }); } }); } }, actions: { addPoint({ context, event, prop }) { const nextPoints = [...context.get("currentPoints"), event.point]; context.set("currentPoints", nextPoints); const stroke = (0, import_perfect_freehand.default)(nextPoints, prop("drawing")); context.set("currentPath", (0, import_get_svg_path.getSvgPathFromStroke)(stroke)); }, endStroke({ context }) { const nextPaths = [...context.get("paths"), context.get("currentPath")]; context.set("paths", nextPaths); context.set("currentPoints", []); context.set("currentPath", null); }, clearPoints({ context }) { context.set("currentPoints", []); context.set("paths", []); context.set("currentPath", null); }, focusCanvasEl({ scope }) { queueMicrotask(() => { scope.getActiveElement()?.focus({ preventScroll: true }); }); }, invokeOnDraw({ context, prop }) { prop("onDraw")?.({ paths: [...context.get("paths"), context.get("currentPath")] }); }, invokeOnDrawEnd({ context, prop, scope, computed }) { prop("onDrawEnd")?.({ paths: [...context.get("paths")], getDataUrl(type, quality = 0.92) { if (computed("isEmpty")) return Promise.resolve(""); return dom.getDataUrl(scope, { type, quality }); } }); } } } }); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { machine });