Merge pull request #749 from ing-bank/chore/storybook-cleanup

Chore/storybook cleanup
This commit is contained in:
Joren Broekema 2020-06-04 17:17:35 +02:00 committed by GitHub
commit eb02b27010
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 6 additions and 276 deletions

View file

@ -5,6 +5,7 @@ module.exports = {
stories: [ stories: [
'../packages/*/README.md', '../packages/*/README.md',
'../packages/*/docs/*.md', '../packages/*/docs/*.md',
'../packages/*/docs/!(assets)**/*.md',
'../docs/README.md', '../docs/README.md',
'../docs/**/*.md', '../docs/**/*.md',
'../README.md', '../README.md',

View file

@ -57,6 +57,5 @@ Fieldsets are the basis for:
## Other Resources ## Other Resources
- [Form fundamentals](?path=/docs/forms-field-fundaments--page)
- [Formatting and parsing](?path=/docs/forms-field-formatting-and-parsing--page) - [Formatting and parsing](?path=/docs/forms-field-formatting-and-parsing--page)
- [Custom Fields](?path=/docs/forms-field-custom-fields-tutorial--page) - [Custom Fields](?path=/docs/forms-field-custom-fields-tutorial--page)

View file

@ -1,87 +0,0 @@
[//]: # 'AUTO INSERT HEADER PREPUBLISH'
# Creating a custom field
```js script
export default {
title: 'Forms/Field/Custom fields tutorial',
};
```
Custom fields can be created in just a few steps. All you need is an interaction element
(like for instance a slider, a listbox or a combobox) and connect it to the [Field](../README.md)
functionality.
## Prerequisite: an interaction element
An interaction element provides the means for the end user to enter a certain value, just like
native elements provide in this (think of `<input>`, `<textarea>` and `<select>`).
An example of a non native element is the [slider design pattern](https://www.w3.org/TR/2017/NOTE-wai-aria-practices-1.1-20171214/#slider) described here.
For this tutorial, we assume we have a component `<my-slider>` that exposes its value via property
`mySliderValue` and sends an event `my-slider-changed` on every value change. To make it focusable,
it has a tabindex=“0” applied.
## Connecting the interaction element to the field
Now we want to integrate the slider in our form framework to enrich the user interface, get
validation support and get all the other [benefits of LionField](?path=/docs/forms-field-overview--page).
We start of by creating a component `<lion-slider>` that extends from `LionField`.
Then we follow the steps below:
- ### 1. Add your interaction element as input slot'
Here you return the element the user interacts with. By configuring it as a slot, it will end up
in light DOM, ensuring the best accessibility for the end user.
- ### 2. Proxy event `my-slider-changed` to `user-input-changed` event
The `user-input-changed` event is listened to by the FormatMixin: it should be regarded as the
equivalent of the `input` event of the platform, but for custom built interaction elements.
- ### 3. Proxy property `<my-slider>.mySliderValue` to `<lion-slider>.value`
Every time the `user-input-changed` fires, the value of `<my-slider>` is synchronized with the
[`modelValue`](./modelValue.md) of `<my-slider>`. Now the cycle is complete: the modelValue connects
your interaction element to all logic inside the LionField.
Steps as described can be implemented with the following javascript:
```js
import { LionField } from '@lion/form-core';
import './my-slider.js';
export class LionSlider extends LionField {
// 1. Add your interaction element as input slot'
get slots() {
return {
...super.slots,
input: () => document.createElement(my-slider),
};
}
// 2. Proxy event `my-slider-changed` to `user-input-changed` event
connectedCallback() {
   super.connectedCallback();
   this.addEventListener('my-slider-changed', this._proxyChangeEvent);
}
_proxyChangeEvent() {
this._inputNode.dispatchEvent(
new CustomEvent('user-input-changed', { bubbles: true, composed: true }),
);
}
// 3. Proxy property `<my-slider>.mySliderValue` to `<lion-slider>.value`
get value() {
   return Array.from(this.children).find(child => child.slot === 'input').mySliderValue;
}
set value(newV) {
   Array.from(this.children).find(child => child.slot === 'input').mySliderValue = newV;
}
}
```
That was all. Now you can enhance your slider by writing custom validators for it
or by writing a parser to get a custom modelValue type.

View file

@ -1,65 +0,0 @@
[//]: # 'AUTO INSERT HEADER PREPUBLISH'
# Form Fundaments
```js script
export default {
title: 'Forms/Field/Fundaments',
};
```
`Form control`s are the most fundamental building block of the Forms. They are the basis of
both `field`s and `fieldset`s, and the `form` itself.
## Fields
Fields are the actual form controls the end user interacts with.
They extend the `Field`(), which on its turn uses the `FormControlMixin`.
Fields provide a normalized, predictable API for platform components and custom made form controls.
On top of this, they feature:
- data synchronization with models
- formatting of view values
- advanced validation possibilities
- creation of advanced user interaction scenarios via `interaction states`
- provision of labels and help texts in an easy, declarative manner
- better focus management
- accessibility out of the box
- advanced styling possibilities: map your own Design System to the internal HTML structure
### Platform fields (wrappers)
- [`LionInput`](../../input/), a wrapper for `<input>`
- [`LionTextarea`](../../textarea/), a wrapper for `<textarea>`
- [`LionSelect`](../../select/), a wrapper for `<select>`
- [`LionRadio`](../../radio/), a wrapper for `<input type="radio">`
- [`LionCheckbox`](../../checkbox/), a wrapper for `<input type="checkbox">`
### Custom fields (wrappers)
Whenever a native form control doesn't exist or is not sufficient, a custom form control should
be created. One could think of components like:
- slider
- combobox
- autocomplete
- etc...
## Fieldsets
Fieldsets are groups of fields. They can be considered fields on their own as well, since they
partly share the normalized api via `FormControlMixin`.
Fieldsets are the basis for:
- [`LionFieldset`](../../fieldset/)
- [`LionForm`](../../form/)
- [`LionRadioGroup`](../../radio-group/)
- [`LionCheckboxGroup`](../../checkbox-group/)
## Other Resources
- [Model Value](./modelValue.md)
- [Formatting and parsing](./FormattingAndParsing.md)
- [Interaction states](./InteractionStates.md)
- [Validation System](../../validate/docs/ValidationSystem.md)
- [FieldCustomMixin](./FieldCustomMixin.md)

View file

@ -1,118 +0,0 @@
[//]: # 'AUTO INSERT HEADER PREPUBLISH'
# Formatting and parsing
```js script
export default {
title: 'Forms/Field/Formatting and parsing',
};
```
The `FormatMixin` keeps track of the `modelValue`, `formattedValue` and `serializedValue`.
It is designed to work in conjunction with `LionField`.
## Concepts of different values
### modelValue
The model value is the result of the parser function.
It should be considered as the internal value used for validation and reasoning/logic.
The model value is 'ready for consumption' by the outside world (think of a Date object
or a float). The modelValue can (and is recommended to) be used as both input value and
output value of the `<lion-field>`.
Examples:
- For a date input: a String '20/01/1999' will be converted to new Date('1999/01/20')
- For a number input: a formatted String '1.234,56' will be converted to a Number: 1234.56
### formattedValue
The view value is the result of the formatter function (when available).
The result will be stored in the native \_inputNode (usually an input[type=text]).
Examples:
- For a date input, this would be '20/01/1999' (dependent on locale).
- For a number input, this could be '1,234.56' (a String representation of modelValue
1234.56).
A value will not get formatted if it is invalid, so the user won't get rewarded for a falsy input.
### serializedValue
The serialized version of the model value.
This value exists for maximal compatibility with the platform API.
The serialized value can be an interface in context where data binding is not supported
and a serialized string needs to be set.
Examples:
- For a date input, this would be the iso format of a date, e.g. '1999-01-20'.
- For a number input this would be the String representation of a float ('1234.56' instead
of 1234.56)
When no parser is available, the value is usually the same as the formattedValue (being \_inputNode.value)
## Formatters, parsers and (de)serializers
In order to create advanced user experiences (automatically formatting a user input or an input
set imperatively by an Application Developer).
Below some concrete examples can be found of implementations of formatters and parsers,
extrapolating the example of a date input.
### Formatters
A formatter should return a `formattedValue`:
```js
function formatDate(modelValue, options) {
if (!(modelValue instanceof Date)) {
return options.formattedValue;
}
return formatDateLocalized(modelValue, options);
}
```
Note: the options object holds a fallback value that shows what should be presented on
screen when the user input resulted in an invalid modelValue
### Parsers
A parser should return a `modelValue`:
```js
function parseDate(formattedValue, options) {
return formattedValue === '' ? undefined : parseDateLocalized(formattedValue);
}
```
Notice that when it's not possible to create a valid modelValue based on the formattedValue,
one should return `undefined`.
### Serializers and deserializers
A serializer should return a `serializedValue`:
```js
function serializeDate(modelValue, options) {
return modelValue.toISOString();
}
```
A deserializer should return a `modelValue`:
```js
function deserializeDate(serializeValue, options) {
return new Date(serializeValue);
}
```
## Flow diagram
The following flow diagram is based on both end user input and interaction programmed by the
developer. It shows how the 'computation loop' for modelValue, formattedValue and serializedValue
is triggered.
[Flow diagram](./formatterParserFlow.svg)

View file

@ -29,10 +29,10 @@ Our validation system is designed to:
- allow for advanced UX scenarios by updating validation state on every value change - allow for advanced UX scenarios by updating validation state on every value change
- provide a powerful way of writing validations via classes - provide a powerful way of writing validations via classes
Validation is applied by default to all [form controls](../form-core/docs/FormFundaments.md) via the Validation is applied by default to all [form controls](?path=/docs/forms-field-overview--page) via the
ValidateMixin. ValidateMixin.
For a detailed description of the validation system and the `ValidateMixin`, please see [ValidationSystem](./docs/ValidationSystem.md). For a detailed description of the validation system and the `ValidateMixin`, please see [ValidationSystem](?path=/docs/forms-validation-system--page).
## How to use ## How to use

View file

@ -119,7 +119,7 @@ On top of default validators, application developers can write their own by exte
### Localization ### Localization
The `ValidateMixin` supports localization out of the box via the [localize system](../../localize/). The `ValidateMixin` supports localization out of the box via the [localize system](?path=/docs/localize-intro--page).
All default validation messages are translated in the following languages (depicted by iso code): All default validation messages are translated in the following languages (depicted by iso code):
bg, cs, de, en, es, fr, hu, it, nl, pl, ro ,ru, sk, uk and zh. bg, cs, de, en, es, fr, hu, it, nl, pl, ro ,ru, sk, uk and zh.

View file

@ -30,8 +30,8 @@ export const main = () => {
## Features ## Features
- Based on [lion-input](?path=/docs/forms-system-overview--page) - Based on [lion-input](?path=/docs/forms-input--main#input)
- Makes use of [formatNumber](?path=/docs/localize-numbers) for formatting and parsing. - Makes use of [formatNumber](?path=/docs/localize-numbers--formatting#formatting) for formatting and parsing.
- Option to show currency as a suffix - Option to show currency as a suffix
- Option to override locale to change the formatting and parsing - Option to override locale to change the formatting and parsing
- Option to provide additional format options overrides - Option to provide additional format options overrides