Mixins / foldkit-mixins-ui

SignaturePad

namespace · packages/mixins-ui/src/signaturePad.ts:1

export * as SignaturePad from './signaturePad.js'

In the guides

Members

SignaturePad.BASELINE

const · packages/mixins-ui/src/signaturePad.ts:276

const BASELINE: 0.72

Where the line is, as a share of the pad's height from its top; the recipe draws it there too.

SignaturePad.ExportPng

const · packages/mixins-ui/src/signaturePad.ts:304

const ExportPng: Command.CommandDefinitionWithArgs<
  'SignaturePad.ExportPng',
  {
    model: Schema.Struct<{
      readonly id: Schema.String
      readonly pen: Schema.Struct<{
        readonly size: Schema.Number
        readonly thinning: Schema.Number
        readonly smoothing: Schema.Number
      }>
      readonly space: Schema.OptionFromNullOr<
        Schema.Struct<{
          readonly width: Schema.Number
          readonly height: Schema.Number
        }>
      >
      readonly strokes: Schema.$Array<
        Schema.Struct<{
          readonly points: Schema.$Array<
            Schema.Struct<{
              readonly x: Schema.Number
              readonly y: Schema.Number
              readonly pressure: Schema.Number
            }>
          >
          readonly pressure: Schema.Boolean
        }>
      >
      readonly drawing: Schema.OptionFromNullOr<
        Schema.Struct<{
          readonly points: Schema.$Array<
            Schema.Struct<{
              readonly x: Schema.Number
              readonly y: Schema.Number
              readonly pressure: Schema.Number
            }>
          >
          readonly pressure: Schema.Boolean
        }>
      >
      readonly typed: Schema.String
    }>
    scale: Schema.Number
    background: Schema.OptionFromNullOr<Schema.String>
  },
  Effect.Effect<
    | { readonly _tag: 'FailedExport'; readonly reason: string }
    | {
        readonly _tag: 'ExportedPng'
        readonly url: string
        readonly width: number
        readonly height: number
      },
    never,
    never
  >
>

Draws the signature on a canvas scale times the pad's size, in the colour and face the pad shows it in (read from the elements the view drew, found by id), over background if given.

SignaturePad.init

function · packages/mixins-ui/src/signaturePad.ts:107

function init(options: {
  readonly id: string
  readonly pen?: Partial<Pen> | undefined
}): Model

SignaturePad.isEmpty

function · packages/mixins-ui/src/signaturePad.ts:120

function isEmpty(model: Model): boolean

Whether there is nothing to sign with: no stroke drawn and no name typed.

SignaturePad.Message

const · packages/mixins-ui/src/signaturePad.ts:126

const Message: MessageUnion<{
  readonly Measured: { width: Schema.Number; height: Schema.Number }
  readonly Began: {
    readonly point: Schema.Struct<{
      readonly x: Schema.Number
      readonly y: Schema.Number
      readonly pressure: Schema.Number
    }>
    readonly pen: Schema.Boolean
    readonly width: Schema.Number
    readonly height: Schema.Number
  }
  readonly Extended: {
    readonly points: Schema.$Array<
      Schema.Struct<{
        readonly x: Schema.Number
        readonly y: Schema.Number
        readonly pressure: Schema.Number
      }>
    >
    readonly width: Schema.Number
    readonly height: Schema.Number
  }
  readonly Ended: {}
  readonly Undid: {}
  readonly Cleared: {}
  readonly Typed: { readonly text: Schema.String }
  readonly RequestedPng: {
    readonly scale: Schema.Number
    readonly background: Schema.OptionFromNullOr<Schema.String>
  }
  readonly ExportedPng: {
    readonly url: Schema.String
    readonly width: Schema.Number
    readonly height: Schema.Number
  }
  readonly FailedExport: { readonly reason: Schema.String }
}>

SignaturePad.Model

const · packages/mixins-ui/src/signaturePad.ts:93

const Model: Schema.Struct<{
  readonly id: Schema.String
  readonly pen: Schema.Struct<{
    readonly size: Schema.Number
    readonly thinning: Schema.Number
    readonly smoothing: Schema.Number
  }>
  readonly space: Schema.OptionFromNullOr<
    Schema.Struct<{
      readonly width: Schema.Number
      readonly height: Schema.Number
    }>
  >
  readonly strokes: Schema.$Array<
    Schema.Struct<{
      readonly points: Schema.$Array<
        Schema.Struct<{
          readonly x: Schema.Number
          readonly y: Schema.Number
          readonly pressure: Schema.Number
        }>
      >
      readonly pressure: Schema.Boolean
    }>
  >
  readonly drawing: Schema.OptionFromNullOr<
    Schema.Struct<{
      readonly points: Schema.$Array<
        Schema.Struct<{
          readonly x: Schema.Number
          readonly y: Schema.Number
          readonly pressure: Schema.Number
        }>
      >
      readonly pressure: Schema.Boolean
    }>
  >
  readonly typed: Schema.String
}>

SignaturePad.pathOf

function · packages/mixins-ui/src/signaturePad.ts:260

function pathOf(stroke: Stroke, pen: Pen): string

A stroke's outline as SVG path data, to fill.

SignaturePad.Pen

const · packages/mixins-ui/src/signaturePad.ts:83

const Pen: Schema.Struct<{
  readonly size: Schema.Number
  readonly thinning: Schema.Number
  readonly smoothing: Schema.Number
}>

How strokes are drawn: their width, how much pressure thins them, and how much they are smoothed.

SignaturePad.Point

const · packages/mixins-ui/src/signaturePad.ts:72

const Point: Schema.Struct<{
  readonly x: Schema.Number
  readonly y: Schema.Number
  readonly pressure: Schema.Number
}>

A point of a stroke in the pad's coordinates, and the pen's pressure there, 0 to 1.

SignaturePad.SignaturePadLabels

interface · packages/mixins-ui/src/signaturePad.ts:461

interface SignaturePadLabels {
  readonly placeholder: string
  readonly undo: string
  readonly clear: string
  readonly fallback: string
  readonly empty: string
  readonly drawn: (strokes: number) => string
  readonly typed: (name: string) => string
}

The words a pad says; each has an English default.

SignaturePad.SignaturePadSlots

const · packages/mixins-ui/src/signaturePad.ts:33

const SignaturePadSlots: Slots.Contract<{ readonly root: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly [Attr.AttrToken<"role">], readonly Slot.RequirementName[], boolean>; readonly label: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly control: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly [Attr.AttrToken<"role">, Attr.AttrToken<"aria-label">], readonly Slot.RequirementName[], boolean>; readonly segments: Slot.UnnamedSlot<Capability.Capability<"Base", readonly []>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly stroke: Slot.UnnamedSlot<Capability.Capability<"Base", readonly []>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly guide: Slot.UnnamedSlot<Capability.Capability<"Base", readonly []>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly placeholder: Slot.UnnamedSlot<Capability.Capability<"Base", readonly []>, r …;

A signature pad after Zag's: strokes drawn with a pointer on a control above a dashed guide and a "Sign here" placeholder, undo and clear, and a text field where a name can be typed instead, for whoever cannot draw.

The strokes are data in a small Model of this module's: each a list of points with the pen's pressure, in the pad's own coordinates (its size when first measured; a pad drawn larger later scales what it is sent into them). A pen's pressure is used as the browser reports it; a mouse or a finger reports none worth reading, so the stroke thins as it speeds up instead. Each stroke is drawn as the outline of a variable-width line, smoothed, after perfect-freehand's method: pathOf gives its SVG path data, toSvg the whole drawing as an SVG document, and ExportPng draws it on a canvas as a PNG data URL.

The signature is the drawing, or, while nothing is drawn, the typed name, which the pad shows on its line in the recipe's script face and both exports write. The control is an image to assistive technology, named by what it holds; the typed field is the way to sign by keyboard.

SignaturePad.SignaturePadView

interface · packages/mixins-ui/src/signaturePad.ts:486

interface SignaturePadView<Message> {
  readonly model: Model
  readonly onMessage: (message: typeof Message.Type) => NoInfer<Message>
  readonly label: string
  readonly fallback?: boolean | undefined
  readonly labels?: Partial<SignaturePadLabels> | undefined
  readonly disabled?: boolean | undefined
  readonly style?: NamedStyle<typeof SignaturePadSlots> | undefined
  readonly mixins?: MixinList<Message> | undefined
}

SignaturePad.Stroke

const · packages/mixins-ui/src/signaturePad.ts:75

const Stroke: Schema.Struct<{
  readonly points: Schema.$Array<
    Schema.Struct<{
      readonly x: Schema.Number
      readonly y: Schema.Number
      readonly pressure: Schema.Number
    }>
  >
  readonly pressure: Schema.Boolean
}>

SignaturePad.toSvg

function · packages/mixins-ui/src/signaturePad.ts:283

function toSvg(
  model: Model,
  options?: {
    readonly color?: string | undefined
    readonly font?: string | undefined
  },
): Option.Option<string>

The signature as an SVG document in the pad's coordinates, its strokes filled with color (default black), or the typed name on the line in font's family; none while the pad is empty or unmeasured.

SignaturePad.update

function · packages/mixins-ui/src/signaturePad.ts:351

function update(model: Model, message: Message): Return<Model, Message>

The pad after message; the same Model when nothing changes.

SignaturePad.view

function · packages/mixins-ui/src/signaturePad.ts:502

function view<Outer>(
  options: SignaturePadView<Outer>,
  h: HtmlBuilder<Outer>,
): Html