Skip to content

Commit

Permalink
Merge pull request #36 from open-formulieren/feature/2-signature-type
Browse files Browse the repository at this point in the history
Implement types for signature component
  • Loading branch information
sergei-maertens authored Dec 7, 2023
2 parents 6919da9 + 384b621 commit 56d6edf
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/formio/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export * from './radio';
export * from './addressNL';
export * from './map';
export * from './editgrid';
export * from './signature';

// Layout components
export * from './content';
Expand Down
61 changes: 61 additions & 0 deletions src/formio/components/signature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {InputComponentSchema} from '..';

type Validator = 'required';
type TranslatableKeys = 'label' | 'description' | 'tooltip' | 'footer';

/**
* The value is base64 encoded binary (image) data, or unset and then it's a string.
*
* When a non-empty value is set, enforce that it is serialized as a data URI.
*/
export type SignatureValue = `data:image/png;base64,${string}`;

export type SignatureInputSchema = InputComponentSchema<
SignatureValue | '',
Validator,
TranslatableKeys
>;

/**
* The built-in Formio.js signature component type.
*
* Source code this is based on:
* https://github.com/formio/formio.js/blob/4.13.x/src/components/signature/Signature.js
*
* Note that we don't offer support for many properties through our form builder, like:
*
* - width
* - height
* - penColor
* - backgroundColor
* - minWidth
* - maxWidth
*
* Because of that, they are also not added to the type definitions (yet). That may
* change once we implement our own renderer.
*
* @group Form.io components
* @category Concrete types
*/
export interface SignatureComponentSchema
extends Omit<
SignatureInputSchema,
'hideLabel' | 'disabled' | 'placeholder' | 'validateOn' | 'multiple'
> {
type: 'signature';
/**
* The footer is a text displayed below the drawing canvas which may hint the user on
* what is expected of them.
*
* I'm not sure what the difference is with the 'description' field.
*/
footer?: string; // translatable instruction

/**
* The value type of the component. We don't support `multiple: true` in this component.
*
* Note that we use the `defaultValue` property to infer the value type, we do not
* support actually setting a component default value.
*/
defaultValue?: SignatureValue | '';
}
2 changes: 2 additions & 0 deletions src/formio/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
RadioComponentSchema,
SelectComponentSchema,
SelectboxesComponentSchema,
SignatureComponentSchema,
TextFieldComponentSchema,
TextareaComponentSchema,
TimeComponentSchema,
Expand Down Expand Up @@ -72,6 +73,7 @@ export type AnyComponentSchema =
| BsnComponentSchema
| AddressNLComponentSchema
| NpFamilyMembersComponentSchema
| SignatureComponentSchema
| MapComponentSchema
| EditGridComponentSchema
// layout
Expand Down
105 changes: 105 additions & 0 deletions test-d/formio/components/signature.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {expectAssignable, expectNotAssignable} from 'tsd';

import {SignatureComponentSchema} from '../../../lib/';

// minimal signature component schema
expectAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature',
key: 'someSignature',
label: 'Some signature',
});

// with additional, signature-component specific properties
expectAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature',
key: 'someSignature',
label: 'Some signature',
defaultValue: 'data:image/png;base64,dGhlIGdhbWU=',
footer: 'Please do not draw inappropriate images',
});

// full, correct schema
expectAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature',
// basic tab in builder form
label: 'Some signature',
key: 'someSignature',
description: 'A description',
tooltip: 'A tooltip',
showInSummary: true,
showInEmail: false,
showInPDF: true,
hidden: false,
clearOnHide: true,
isSensitiveData: false,
defaultValue: '',
// advanced tab in builder form
conditional: {
show: undefined,
when: undefined,
eq: undefined,
},
// validation tab in builder form
validate: {
required: false,
plugins: undefined,
},
translatedErrors: {
nl: {
required: 'Je moet een waarde opgeven!!!',
},
},
errors: {
// translatedErrors is converted into errors by the backend
required: 'Je moet een waarde opgeven!!!',
},
// registration tab in builder form
registration: {
attribute: '',
},
// translations tab in builder form
openForms: {
translations: {
nl: {
label: 'foo',
description: 'bar',
},
},
},
});

// different component type
expectNotAssignable<SignatureComponentSchema>({
type: 'fieldset' as const,
});

// using unsupported properties
expectNotAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature' as const,
key: 'someSignature',
label: 'Some signature',
hideLabel: true,
});

// bad value format
expectNotAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature' as const,
key: 'someSignature',
label: 'Some signature',
defaultValue: 'random string',
});

// multiple is not supported
expectNotAssignable<SignatureComponentSchema>({
id: 'yejak',
type: 'signature' as const,
key: 'someSignature',
label: 'Some signature',
multiple: true,
defaultValue: [],
});

0 comments on commit 56d6edf

Please sign in to comment.