Skip to content

Commit

Permalink
Merge pull request #104 from TRIPTYK/feature/tk-ui-58
Browse files Browse the repository at this point in the history
Feature/tk UI 58
  • Loading branch information
remadex authored Dec 2, 2024
2 parents 5e4f543 + 57a9286 commit 5afe192
Show file tree
Hide file tree
Showing 24 changed files with 647 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { tracked } from '@glimmer/tracking';
import type { Owner } from '@ember/test-helpers/build-owner';

export default class DocsEmberInputValidationPrefabsDatepickerController extends Controller {
@tracked changeset = new ImmerChangeset({
changeset = new ImmerChangeset({
birthday: null,
disabled: null,
error: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import Controller from '@ember/controller';
import { ImmerChangeset } from 'ember-immer-changeset';
import { tracked } from '@glimmer/tracking';
import type Owner from '@ember/owner';

export default class DocsEmberInputValidationPrefabsTimepickerController extends Controller {
constructor(owner: Owner) {
super(owner);
this.changeset.addError({
message: 'This is an error message',
value: '',
originalValue: '',
key: 'error',
});
}
changeset = new ImmerChangeset({
time: undefined,
time: null,
disabled: null,
error: null,
});
}
13 changes: 13 additions & 0 deletions doc-app/app/controllers/docs/ember-input-validation/prefabs/vat.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import Controller from '@ember/controller';
import { ImmerChangeset } from 'ember-immer-changeset';
import { tracked } from '@glimmer/tracking';
import type Owner from '@ember/owner';

export default class DocsEmberInputValidationPrefabsVATController extends Controller {
constructor(owner: Owner) {
super(owner);
this.changeset.addError({
message: 'This is an error message',
value: '',
originalValue: '',
key: 'error',
});
}

changeset = new ImmerChangeset({
vat: '',
disabled: '',
error: '',
});
}
25 changes: 24 additions & 1 deletion doc-app/app/controllers/docs/ember-input-validation/tpk-form.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Controller from '@ember/controller';
import ImmerChangeset from 'ember-immer-changeset';
import { object, string, array } from 'yup';
import { object, string, array, date, boolean, number } from 'yup';
import { action } from '@ember/object';

// BEGIN-SNIPPET tpk-form-controller.js
Expand All @@ -9,12 +9,35 @@ export default class TpkFormController extends Controller {
firstName: '',
lastName: '',
languages: ['French', 'English'],
birthday: null,
email: '',
phone: '',
nationalNumber: '',
vat: '',
bic: '',
iban: '',
status: '',
isFree: false,
time: null,
availableMoney: 0,
});
options = ['French', 'English', 'Spanish', 'German', 'Italian'];
validationSchema = object().shape({
firstName: string().required().min(3),
lastName: string().required().min(3),
languages: array().min(2),
birthday: date().required(),
email: string().email().required(),
phone: string().required(),
nationalNumber: string().optional(),
vat: string().optional(),
bic: string().optional(),
iban: string().optional(),
status: string().optional(),
isFree: boolean().required(),
time: date().required(),
password: string().required(),
availableMoney: number().required(),
});

@action
Expand Down
1 change: 1 addition & 0 deletions doc-app/app/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@import url("@eonasdan/tempus-dominus/dist/css/tempus-dominus.css");
@import url("ember-power-select/vendor/ember-power-select.css");
@import url("@triptyk/ember-input-validation/dist/app.css");
@import url("ember-input-validation/form.css");

.next,
.previous {
Expand Down
15 changes: 15 additions & 0 deletions doc-app/app/styles/ember-input-validation/form.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.form-doc .button {
@apply btn btn-primary;
}

.form-content {
@apply grid grid-cols-12 gap-4;
}

.form-content > * {
@apply col-span-4;
}

.form-content > .tpk-mobile-container {
@apply col-span-8;
}
1 change: 1 addition & 0 deletions doc-app/app/styles/ember-input-validation/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
@import url("checkbox.css");
@import url("loading.css");
@import url("radio.css");
@import url("form.css");
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ This component provides a timepicker with built-in validation.
@validationField="time"
class="tpk-input"
/>
<Prefabs::TpkValidationTimepicker
@label="Disabled"
@changeset={{this.changeset}}
@validationField="disabled"
@disabled=true
/>
<Prefabs::TpkValidationTimepicker
@label="Error"
@changeset={{this.changeset}}
@validationField="error"
/>
</demo.example>
<demo.snippet @name="tpk-timepicker.hbs" />
</DocsDemo>
Expand Down
31 changes: 31 additions & 0 deletions doc-app/app/templates/docs/ember-input-validation/prefabs/vat.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,38 @@ If the country is not supported, the input value will be blocked after 2 upperca
@changeset={{this.changeset}}
@validationField="vat"
/>
<Prefabs::TpkValidationVat
@label="Disabled"
@placeholder="Enter vat"
@disabled={{true}}
@changeset={{this.changeset}}
@validationField="disabled"
/>
<Prefabs::TpkValidationVat
@label="Error"
@placeholder="Enter vat"
@changeset={{this.changeset}}
@validationField="error"
/>
</demo.example>
<demo.snippet @name="tpk-vat.hbs"/>
</DocsDemo>

## Usage

The `TpkValidationVat` component is used for a vat input.

## Mandatory properties

- `@validationField`: The field name in the changeset for validation.
- `@changeset`: The changeset object for form validation.

## Optional properties

- `@label`: The label for the input field.
- `@placeholder`: The placeholder text for the input field.
- `@mandatory`: Whether the textarea field is mandatory.
- `@disabled`: Whether the input field is disabled.
- `@onChange`: The action to be called when the selection changes.
- `@changeEvent`: The event to trigger the onChange action.

155 changes: 122 additions & 33 deletions doc-app/app/templates/docs/ember-input-validation/tpk-form.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# TpkForm

> Looking for a complete example? [Jump to the complete example](#complete-example-of-using-tpkform)
The `TpkForm` component is a form component that uses the `ember-immer-changeset` and `yup` libraries to provide a simple way to create forms with validation. The form yields each component from ember-input-validation as a block component.

By default, the changeset is [executed](https://triptyk.github.io/ember-immer-changeset/classes/ImmerChangeset.html#execute) if the form submitted is valid.
Expand All @@ -9,6 +11,8 @@ By default, the changeset is [executed](https://triptyk.github.io/ember-immer-ch
@changeset={{this.changeset}}
@onSubmit={{this.success}}
@validationSchema={{this.validationSchema}}
@autoScrollOnError={{false}}
class="form-doc"
as |F|>
<F.TpkInput @label="First Name" @validationField="firstName" as |I|>
<I.Label/>
Expand All @@ -22,7 +26,7 @@ By default, the changeset is [executed](https://triptyk.github.io/ember-immer-ch
<F.TpkInputPrefab @label="Last Name" @validationField="lastName" />
<F.TpkSelectPrefab @label="languages" @validationField="languages" @multiple={{true}} @options={{this.options}} />
<br/>
<input class="mt-12" type="submit" value="Submit">
<button class="button" type="submit">Submit</button>
</TpkForm>
</demo.example>
<demo.snippet @name="tpk-form.hbs"/>
Expand All @@ -46,43 +50,49 @@ By default, the changeset is [executed](https://triptyk.github.io/ember-immer-ch
## Yielded Components

The `TpkForm` component yields the following components:
<DocsLink @route="docs.ember-input-validation.input">
- TpkValidationInput yielded as TpkInput
</DocsLink>
<DocsLink @route="docs.ember-input-validation.prefabs.input">
- TpkValidationInputPrefab yielded as TpkInputPrefab
</DocsLink>
<DocsLink @route="docs.ember-input-validation.checkbox">
- TpkValidationCheckbox yielded as TpkCheckbox
</DocsLink>
<DocsLink @route="docs.ember-input-validation.prefabs.checkbox">
- TpkValidationCheckboxPrefab yielded as TpkCheckboxPrefab
</DocsLink>
<DocsLink @route="docs.ember-input-validation.datepicker">
- TpkValidationDatePicker yielded as TpkDatePicker
</DocsLink>
<DocsLink @route="docs.ember-input-validation.file">
- TpkValidationFile yielded as TpkFile
</DocsLink>
<DocsLink @route="docs.ember-input-validation.radio">
- TpkValidationRadio yielded as TpkRadio
</DocsLink>
<DocsLink @route="docs.ember-input-validation.select">
- TpkValidationSelect yielded as TpkSelect
</DocsLink>
<DocsLink @route="docs.ember-input-validation.textarea">
- TpkValidationTextarea yielded as TpkTextarea
</DocsLink>
<DocsLink @route="docs.ember-input-validation.textarea">
- TpkValidationTextareaPrefab yielded as TpkTextarea
</DocsLink>

### Base Components
- TpkValidationInput yielded as `TpkInput`
- TpkValidationTextarea yielded as `TpkTextarea`
- TpkValidationSelect yielded as `TpkSelect`
- TpkValidationCheckbox yielded as `TpkCheckbox`
- TpkValidationRadio yielded as `TpkRadio`
- TpkValidationRadioGroup yielded as `TpkRadioGroup`
- TpkValidationFile yielded as `TpkFile`
- TpkValidationDatePicker yielded as `TpkDatepicker`

### Prefab Components
- TpkValidationInputPrefab yielded as `TpkInputPrefab`
- TpkValidationTextareaPrefab yielded as `TpkTextareaPrefab`
- TpkValidationSelectPrefab yielded as `TpkSelectPrefab`
- TpkValidationSelectCreatePrefab yielded as `TpkSelectCreatePrefab`
- TpkValidationSelectSearchPrefab yielded as `TpkSelectSearchPrefab`
- TpkValidationCheckboxPrefab yielded as `TpkCheckboxPrefab`
- TpkValidationRadioPrefab yielded as `TpkRadioPrefab`
- TpkValidationRadioGroupPrefab yielded as `TpkRadioGroupPrefab`
- TpkValidationDatepickerPrefab yielded as `TpkDatepickerPrefab`
- TpkValidationDatepickerRangePrefab yielded as `TpkDatepickerRangePrefab`
- TpkValidationTimepickerPrefab yielded as `TpkTimepickerPrefab`

### Specialized Input Prefabs
- TpkValidationPasswordPrefab yielded as `TpkPasswordPrefab`
- TpkValidationEmailPrefab yielded as `TpkEmailPrefab`
- TpkValidationIBANPrefab yielded as `TpkIbanPrefab`
- TpkValidationBicPrefab yielded as `TpkBicPrefab`
- TpkValidationVATPrefab yielded as `TpkVatPrefab`
- TpkValidationNationalNumberPrefab yielded as `TpkNationalNumberPrefab`
- TpkValidationCurrencyPrefab yielded as `TpkCurrencyPrefab`
- TpkValidationIntegerPrefab yielded as `TpkIntegerPrefab`
- TpkValidationNumberPrefab yielded as `TpkNumberPrefab`
- TpkValidationMobilePrefab yielded as `TpkMobilePrefab`

## Yielded values

The `TpkForm` component yields the following values:
| Value | Type | Description |
| --- | --- | --- |
| changesetGet | Function | The [get](https://triptyk.github.io/ember-immer-changeset/classes/ImmerChangeset.html#get) function of the changeset. It is just a shortcut to avoid repeating the @changeset argument. |
| requiredFields | Array | An array of the required fields.

## Changing the default components

Expand All @@ -93,11 +103,90 @@ let tpkFormService = this.owner.lookup(
'service:tpk-form',
) as TpkFormService;

// Base Components
tpkFormService.TpkInput = DummyInput;
tpkFormService.TpkTextarea = DummyTextarea;
tpkFormService.TpkSelect = DummySelect;
tpkFormService.TpkCheckbox = DummyCheckbox;
tpkFormService.TpkRadio = DummyRadio;
tpkFormService.TpkTextarea = DummyTextarea;
tpkFormService.TpkDatePicker = DummyDatepicker;
tpkFormService.TpkRadioGroup = DummyRadioGroup;
tpkFormService.TpkFile = DummyFile;
tpkFormService.TpkDatepicker = DummyDatepicker;

// Prefab Components
tpkFormService.TpkInputPrefab = DummyInputPrefab;
tpkFormService.TpkTextareaPrefab = DummyTextareaPrefab;
tpkFormService.TpkSelectPrefab = DummySelectPrefab;
tpkFormService.TpkSelectCreatePrefab = DummySelectCreatePrefab;
tpkFormService.TpkSelectSearchPrefab = DummySelectSearchPrefab;
tpkFormService.TpkCheckboxPrefab = DummyCheckboxPrefab;
tpkFormService.TpkRadioPrefab = DummyRadioPrefab;
tpkFormService.TpkRadioGroupPrefab = DummyRadioGroupPrefab;
tpkFormService.TpkDatepickerPrefab = DummyDatepickerPrefab;
tpkFormService.TpkDatepickerRangePrefab = DummyDatepickerRangePrefab;
tpkFormService.TpkTimepickerPrefab = DummyTimepickerPrefab;

// Specialized Input Prefabs
tpkFormService.TpkPasswordPrefab = DummyPasswordPrefab;
tpkFormService.TpkEmailPrefab = DummyEmailPrefab;
tpkFormService.TpkIbanPrefab = DummyIbanPrefab;
tpkFormService.TpkBicPrefab = DummyBicPrefab;
tpkFormService.TpkVatPrefab = DummyVatPrefab;
tpkFormService.TpkNationalNumberPrefab = DummyNationalNumberPrefab;
tpkFormService.TpkCurrencyPrefab = DummyCurrencyPrefab;
tpkFormService.TpkIntegerPrefab = DummyIntegerPrefab;
tpkFormService.TpkNumberPrefab = DummyNumberPrefab;
tpkFormService.TpkMobilePrefab = DummyMobilePrefab;
```

## Validation Behavior

The form handles validation in two ways:
- On submit: The entire form is validated when submitted
- On field change: If `@reactive={{true}}` (default), fields are validated individually when their values change

When validation errors occur:
- If `@autoScrollOnError={{true}}` (default), the form will automatically scroll to the first error
- If `@removeErrorsOnSubmit={{true}}` (default), existing errors are cleared before new validation on submit

## Complete example of using TpkForm

<DocsDemo as |demo|>
<demo.example @name="tpk-form-complete.hbs">
<TpkForm
@changeset={{this.changeset}}
@onSubmit={{this.success}}
@validationSchema={{this.validationSchema}}
class="form-doc"
as |F|>
<div class="form-content">
<F.TpkInputPrefab @label="First Name" @validationField="firstName" />
<F.TpkInputPrefab @label="Last Name" @validationField="lastName" />
<F.TpkEmailPrefab @label="Email" @validationField="email" />
<F.TpkMobilePrefab @label="Phone" @validationField="phone" />
<F.TpkDatepickerPrefab @label="Birthdate" @validationField="birthday" />
<F.TpkSelectPrefab @label="Languages" @validationField="languages" @multiple={{true}} @options={{this.options}} />
<F.TpkTimepickerPrefab @label="Time" @validationField="time" />
<F.TpkCurrencyPrefab @label="Available money ?" @validationField="availableMoney" />
<F.TpkVatPrefab @label="VAT" @validationField="vat" />
<F.TpkBicPrefab @label="BIC" @validationField="bic" />
<F.TpkIbanPrefab @label="IBAN" @validationField="iban" />
<F.TpkRadioGroupPrefab
@validationField="status"
@mandatory={{false}}
@groupLabel="Status"
@mandatory={{true}}
as |Radio|>
<Radio @value="pending" @label="Pending" @selected="pending" />
<Radio @value="complete" @label="Complete" />
</F.TpkRadioGroupPrefab>
<F.TpkPasswordPrefab @label="Password" @validationField="password" />
<F.TpkCheckboxPrefab @label="Is free ?" @validationField="isFree" />
</div>
<br/>
<button class="button" type="submit">Submit</button>
</TpkForm>
</demo.example>
<demo.snippet @name="tpk-form-complete.hbs"/>
<demo.snippet @name="tpk-form-controller.js" />
</DocsDemo>
Loading

0 comments on commit 5afe192

Please sign in to comment.