Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ [#2] Implement types for several components #16

Merged
merged 6 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,18 @@ import {
PrefillConfig,
} from '@open-formulieren/types';
```

## Release flow

We don't let `npm` apply the git tags when releasing a new version, instead follow this process:

```bash
npm version --no-git-tag-version minor
git commit -am ":bookmark: Bump to version <newVersion>"
git tag "<newVersion>"
git push origin main --tags
```

If you have PGP keys set up, you can use them for the git tag operation.

The CI pipeline will then publish the new version to npmjs.
29 changes: 29 additions & 0 deletions src/formio/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {JSONObject} from '@/types';

import {ComponentTranslations} from './i18n';

/**
* @category Utilities
*/
export interface Option {
value: string;
label: string;
openForms?: {
translations: ComponentTranslations<'label'>;
};
}

/**
* @category Utilities
*/
export interface ManualValues {
dataSrc: 'manual';
}

/**
* @category Utilities
*/
export interface VariableValues {
dataSrc: 'variable';
itemsExpression: string | JSONObject;
}
16 changes: 16 additions & 0 deletions src/formio/components/checkbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {InputComponentSchema} from '..';

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

export type CheckboxInputSchema = InputComponentSchema<boolean, Validator, TranslatableKeys>;

/**
* @group Form.io components
* @category Concrete types
*/
export interface CheckboxComponentSchema
extends Omit<CheckboxInputSchema, 'hideLabel' | 'disabled'> {
type: 'checkbox';
defaultValue: boolean;
}
1 change: 1 addition & 0 deletions src/formio/components/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type EmailInputSchema = InputComponentSchema<string, Validator, Translata
*/
export interface BaseEmailComponentSchema extends Omit<EmailInputSchema, 'hideLabel' | 'disabled'> {
type: 'email';
validateOn: 'blur';
// additional properties
autocomplete?: string;
// OF custom properties
Expand Down
3 changes: 3 additions & 0 deletions src/formio/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export * from './postcode';
export * from './iban';
export * from './licenseplate';
export * from './number';
export * from './checkbox';
export * from './selectboxes';
export * from './file';
export * from './radio';

// Layout components
export * from './content';
42 changes: 42 additions & 0 deletions src/formio/components/radio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {InputComponentSchema} from '..';
import {OFExtensions} from '../base';
import {ManualValues, Option, VariableValues} from '../common';

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

export type RadioInputSchema = InputComponentSchema<string | null, Validator, TranslatableKeys>;

/**
* @group Form.io components
* @category Base types
*/
interface BaseRadioSchema {
type: 'radio';
defaultValue: string | null;
}

/**
* @group Form.io components
* @category Base types
*/
type RadioManualValuesSchema = Omit<RadioInputSchema, 'hideLabel' | 'disabled'> &
BaseRadioSchema & {
openForms: OFExtensions<TranslatableKeys>['openForms'] & ManualValues;
values: Option[];
};

/**
* @group Form.io components
* @category Base types
*/
type RadioVariableValuesSchema = Omit<RadioInputSchema, 'hideLabel' | 'disabled'> &
BaseRadioSchema & {
openForms: OFExtensions<TranslatableKeys>['openForms'] & VariableValues;
};

/**
* @group Form.io components
* @category Concrete types
*/
export type RadioComponentSchema = RadioManualValuesSchema | RadioVariableValuesSchema;
48 changes: 48 additions & 0 deletions src/formio/components/selectboxes.ts
Viicos marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {InputComponentSchema} from '..';
import {OFExtensions} from '../base';
import {ManualValues, Option, VariableValues} from '../common';

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

export type SelectboxesInputSchema = InputComponentSchema<
Record<string, boolean>,
Validator,
TranslatableKeys
>;

/**
* @group Form.io components
* @category Base types
*/
interface BaseSelectboxesSchema {
type: 'selectboxes';
defaultValue: Record<string, boolean>;
}

/**
* @group Form.io components
* @category Base types
*/
type SelectboxesManualValuesSchema = Omit<SelectboxesInputSchema, 'hideLabel' | 'disabled'> &
BaseSelectboxesSchema & {
openForms: OFExtensions<TranslatableKeys>['openForms'] & ManualValues;
values: Option[];
};

/**
* @group Form.io components
* @category Base types
*/
type SelectboxesVariableValuesSchema = Omit<SelectboxesInputSchema, 'hideLabel' | 'disabled'> &
BaseSelectboxesSchema & {
openForms: OFExtensions<TranslatableKeys>['openForms'] & VariableValues;
};

/**
* @group Form.io components
* @category Concrete types
*/
export type SelectboxesComponentSchema =
| SelectboxesManualValuesSchema
| SelectboxesVariableValuesSchema;
6 changes: 6 additions & 0 deletions src/formio/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
CheckboxComponentSchema,
ContentComponentSchema,
CurrencyComponentSchema,
DateComponentSchema,
Expand All @@ -10,6 +11,8 @@ import {
NumberComponentSchema,
PhoneNumberComponentSchema,
PostcodeComponentSchema,
RadioComponentSchema,
SelectboxesComponentSchema,
TextFieldComponentSchema,
TimeComponentSchema,
} from './components';
Expand Down Expand Up @@ -48,7 +51,10 @@ export type AnyComponentSchema =
| PostcodeComponentSchema
| FileComponentSchema
| NumberComponentSchema
| CheckboxComponentSchema
| SelectboxesComponentSchema
| CurrencyComponentSchema
| RadioComponentSchema
// special types
| IbanComponentSchema
| LicensePlateComponentSchema
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type JSONPrimitive = string | number | boolean | null;
export type JSONValue = JSONPrimitive | JSONObject | JSONArray;
export type JSONObject = {[member: string]: JSONValue};
export interface JSONArray extends Array<JSONValue> {}
74 changes: 74 additions & 0 deletions test-d/formio/components/checkbox.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {expectAssignable, expectNotAssignable} from 'tsd';

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

// minimal component schema
expectAssignable<CheckboxComponentSchema>({
id: 'yejak',
type: 'checkbox',
key: 'someCheckbox',
label: 'Some checkbox',
defaultValue: true,
});


// full, correct schema
expectAssignable<CheckboxComponentSchema>({
id: 'yejak',
type: 'checkbox',
// basic tab
label: 'Some checkbox',
key: 'someCheckbox',
description: '',
tooltip: 'A tooltip',
showInSummary: true,
showInEmail: false,
showInPDF: true,
hidden: false,
clearOnHide: true,
isSensitiveData: true,
defaultValue: false,
// Advanced tab
conditional: {
show: undefined,
when: '',
eq: '',
},
// Validation tab
validate: {
required: false,
plugins: [],
},
translatedErrors: {nl: {required: 'Geef checkbox.'}},
errors: {required: 'Geef checkbox.'},
// registration tab
registration: {
attribute: '',
},
// translations tab in builder form
openForms: {
translations: {
nl: {label: 'foo'},
},
},
// fixed but not editable
validateOn: 'blur',
});

// multiple not allowed
expectNotAssignable<CheckboxComponentSchema>({
id: 'yejak',
type: 'checkbox',
key: 'someCheckbox',
label: 'Some checkbox',
multiple: 'dummy',
});

// defaultValue not allowed
expectNotAssignable<CheckboxComponentSchema>({
id: 'yejak',
type: 'checkbox',
key: 'someCheckbox',
label: 'Some checkbox',
defaultValue: [true],
});
24 changes: 24 additions & 0 deletions test-d/formio/components/email.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ expectAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
});

// with additional, email-component specific properties
Expand All @@ -16,6 +17,7 @@ expectAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
autocomplete: 'email',
confirmationRecipient: false,
});
Expand All @@ -26,6 +28,7 @@ expectAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
multiple: false,
defaultValue: '',
});
Expand All @@ -36,6 +39,7 @@ expectAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
multiple: true,
defaultValue: [''],
});
Expand Down Expand Up @@ -86,12 +90,30 @@ expectAssignable<EmailComponentSchema>({
validateOn: 'blur',
});

// validateOn not `blur`
expectNotAssignable<EmailComponentSchema>({
id: 'yejak',
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'change',
});

// missing validateOn
expectNotAssignable<EmailComponentSchema>({
id: 'yejak',
type: 'email',
key: 'someEmail',
label: 'Some email',
});

// invalid, multiple true and non-array default value
expectNotAssignable<EmailComponentSchema>({
id: 'yejak',
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
multiple: true,
defaultValue: '',
});
Expand All @@ -102,6 +124,7 @@ expectNotAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
multiple: false,
defaultValue: [''],
});
Expand All @@ -112,6 +135,7 @@ expectNotAssignable<EmailComponentSchema>({
type: 'email',
key: 'someEmail',
label: 'Some email',
validateOn: 'blur',
multiple: true,
defaultValue: [0],
});
Loading