@lion/form-core
Advanced tools
Comparing version 0.11.0 to 0.12.0
# Change Log | ||
## 0.12.0 | ||
### Minor Changes | ||
- 02e4f2cb: add simulator to demos | ||
- c6fbe920: support paste functionality in FormatMixin | ||
### Patch Changes | ||
- 11ec31c6: fixed css selector syntax for disabled [slot=input]' | ||
- 15146bf9: form groups support lazily rendered children | ||
- Updated dependencies [02e4f2cb] | ||
- @lion/core@0.17.0 | ||
- @lion/localize@0.19.0 | ||
## 0.11.0 | ||
@@ -4,0 +19,0 @@ |
@@ -7,4 +7,4 @@ # Systems >> Form >> Overview ||10 | ||
- Built in [validate](https://github.com/ing-bank/lion/blob/d65ffd3c04a456407df98b68b8ff860de5fe5cf8/docs/docs/systems/form/validate.md) for error/warning/info/success | ||
- Built in [validate](https://github.com/ing-bank/lion/blob/4bd5e4fc4dcadd802d0856c0e73e3af559f40537/docs/docs/systems/form/validate.md) for error/warning/info/success | ||
- Formatting of values | ||
- Accessible |
{ | ||
"name": "@lion/form-core", | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"description": "Form-core contains all essential building blocks for creating form fields and fieldsets", | ||
@@ -41,4 +41,4 @@ "license": "MIT", | ||
"dependencies": { | ||
"@lion/core": "0.16.0", | ||
"@lion/localize": "0.18.0" | ||
"@lion/core": "0.17.0", | ||
"@lion/localize": "0.19.0" | ||
}, | ||
@@ -45,0 +45,0 @@ "keywords": [ |
@@ -7,4 +7,4 @@ # Systems >> Form >> Overview ||10 | ||
- Built in [validate](https://github.com/ing-bank/lion/blob/d65ffd3c04a456407df98b68b8ff860de5fe5cf8/docs/docs/systems/form/validate.md) for error/warning/info/success | ||
- Built in [validate](https://github.com/ing-bank/lion/blob/4bd5e4fc4dcadd802d0856c0e73e3af559f40537/docs/docs/systems/form/validate.md) for error/warning/info/success | ||
- Formatting of values | ||
- Accessible |
@@ -151,2 +151,5 @@ import { dedupeMixin, html, SlotMixin, DisabledMixin } from '@lion/core'; | ||
this.__descriptionElementsInParentChain = new Set(); | ||
/** @type {{modelValue?:{[key:string]: any}, serializedValue?:{[key:string]: any}}} */ | ||
this.__pendingValues = { modelValue: {}, serializedValue: {} }; | ||
} | ||
@@ -353,2 +356,4 @@ | ||
this.formElements[name][property] = values[name]; | ||
} else { | ||
this.__pendingValues[property][name] = values[name]; | ||
} | ||
@@ -490,3 +495,3 @@ }); | ||
* On top of this, error messages of children are linked to their parents | ||
* @param {FormControl} child | ||
* @param {FormControl & {serializedValue:string|object}} child | ||
* @param {number} indexToInsertAt | ||
@@ -508,2 +513,12 @@ */ | ||
} | ||
if (!child.modelValue) { | ||
const pVals = this.__pendingValues; | ||
if (pVals.modelValue && pVals.modelValue[child.name]) { | ||
// eslint-disable-next-line no-param-reassign | ||
child.modelValue = pVals.modelValue[child.name]; | ||
} else if (pVals.serializedValue && pVals.serializedValue[child.name]) { | ||
// eslint-disable-next-line no-param-reassign | ||
child.serializedValue = pVals.serializedValue[child.name]; | ||
} | ||
} | ||
} | ||
@@ -510,0 +525,0 @@ |
@@ -132,3 +132,3 @@ /* eslint-disable class-methods-use-this */ | ||
// We don't delegate, because we want to preserve caret position via _setValueAndPreserveCaret | ||
/** @type {string} */ | ||
/** @param {string} value */ | ||
set value(value) { | ||
@@ -223,3 +223,3 @@ // if not yet connected to dom can't change the value | ||
} else if (source === 'formatted') { | ||
this.modelValue = this.__callParser(); | ||
this.modelValue = this._callParser(); | ||
} | ||
@@ -229,3 +229,3 @@ } | ||
/** @type {string} */ | ||
this.formattedValue = this.__callFormatter(); | ||
this.formattedValue = this._callFormatter(); | ||
} | ||
@@ -245,3 +245,3 @@ if (source !== 'serialized') { | ||
*/ | ||
__callParser(value = this.formattedValue) { | ||
_callParser(value = this.formattedValue) { | ||
// A) check if we need to parse at all | ||
@@ -284,3 +284,3 @@ | ||
*/ | ||
__callFormatter() { | ||
_callFormatter() { | ||
// - Why check for this.hasError? | ||
@@ -358,3 +358,12 @@ // We only want to format values that are considered valid. For best UX, | ||
} | ||
this.modelValue = this.__callParser(this.value); | ||
const prevFormatted = this.formattedValue; | ||
this.modelValue = this._callParser(this.value); | ||
// Sometimes, the formattedValue didn't change, but the viewValue did... | ||
// We need this check to support pasting values that need to be formatted right on paste | ||
if (prevFormatted === this.formattedValue && this.__prevViewValue !== this.value) { | ||
this._calculateValues(); | ||
} | ||
/** @type {string} */ | ||
this.__prevViewValue = this.value; | ||
} | ||
@@ -388,7 +397,9 @@ | ||
// This can be called whenever the view value should be updated. Dependent on component type | ||
// ("input" for <input> or "change" for <select>(mainly for IE)) a different event should be | ||
// used as source for the "user-input-changed" event (which can be seen as an abstraction | ||
// layer on top of other events (input, change, whatever)) | ||
/** @protected */ | ||
/** | ||
* This can be called whenever the view value should be updated. Dependent on component type | ||
* ("input" for <input> or "change" for <select>(mainly for IE)) a different event should be | ||
* used as source for the "user-input-changed" event (which can be seen as an abstraction | ||
* layer on top of other events (input, change, whatever)) | ||
* @protected | ||
*/ | ||
_proxyInputEvent() { | ||
@@ -429,6 +440,34 @@ this.dispatchEvent( | ||
this.formatOptions = /** @type {FormatOptions} */ ({}); | ||
/** | ||
* Whether the user is pasting content. Allows Subclassers to do this in their subclass: | ||
* @example | ||
* ```js | ||
* _reflectBackOn() { | ||
* return super._reflectBackOn() || this._isPasting; | ||
* } | ||
* ``` | ||
* @protected | ||
*/ | ||
this._isPasting = false; | ||
/** | ||
* @private | ||
* @type {string} | ||
*/ | ||
this.__prevViewValue = ''; | ||
this.__onCompositionEvent = this.__onCompositionEvent.bind(this); | ||
// This computes formattedValue | ||
this.addEventListener('user-input-changed', this._onUserInputChanged); | ||
// This sets the formatted viewValue after paste | ||
this.addEventListener('paste', this.__onPaste); | ||
} | ||
__onPaste() { | ||
this._isPasting = true; | ||
this.formatOptions.mode = 'pasted'; | ||
setTimeout(() => { | ||
this._isPasting = false; | ||
this.formatOptions.mode = 'auto'; | ||
}); | ||
} | ||
connectedCallback() { | ||
@@ -443,3 +482,3 @@ super.connectedCallback(); | ||
}; | ||
this.addEventListener('user-input-changed', this._onUserInputChanged); | ||
// Connect the value found in <input> to the formatting/parsing/serializing loop as a | ||
@@ -465,3 +504,2 @@ // fallback mechanism. Assume the user uses the value property of the | ||
super.disconnectedCallback(); | ||
this.removeEventListener('user-input-changed', this._onUserInputChanged); | ||
if (this._inputNode) { | ||
@@ -468,0 +506,0 @@ this._inputNode.removeEventListener('input', this._proxyInputEvent); |
@@ -687,3 +687,3 @@ import { css, dedupeMixin, html, nothing, SlotMixin, DisabledMixin } from '@lion/core'; | ||
/***** {state} :disabled *****/ | ||
:host([disabled]) .input-group ::slotted(slot='input') { | ||
:host([disabled]) .input-group ::slotted([slot='input']) { | ||
color: var(--disabled-text-color, #767676); | ||
@@ -690,0 +690,0 @@ } |
import { dedupeMixin } from '@lion/core'; | ||
import { FormControlMixin } from './FormControlMixin.js'; | ||
import { FocusMixin } from './FocusMixin.js'; | ||
import { FormatMixin } from './FormatMixin.js'; | ||
@@ -11,3 +12,3 @@ /** | ||
const NativeTextFieldMixinImplementation = superclass => | ||
class NativeTextFieldMixin extends FocusMixin(FormControlMixin(superclass)) { | ||
class NativeTextFieldMixin extends FormatMixin(FocusMixin(FormControlMixin(superclass))) { | ||
/** | ||
@@ -99,4 +100,18 @@ * @protected | ||
} | ||
/** | ||
* @override FormatMixin | ||
*/ | ||
_reflectBackFormattedValueToUser() { | ||
super._reflectBackFormattedValueToUser(); | ||
if (this._reflectBackOn() && this.focused) { | ||
try { | ||
// try/catch, because Safari is a bit sensitive here | ||
this._inputNode.selectionStart = this._inputNode.value.length; | ||
// eslint-disable-next-line no-empty | ||
} catch (_) {} | ||
} | ||
} | ||
}; | ||
export const NativeTextFieldMixin = dedupeMixin(NativeTextFieldMixinImplementation); |
import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import { LitElement } from '@lion/core'; | ||
import { BooleanAttributePart, LitElement } from '@lion/core'; | ||
import { FormatNumberOptions } from '@lion/localize/types/LocalizeMixinTypes'; | ||
@@ -21,2 +21,12 @@ import { ValidateHost } from './validate/ValidateMixinTypes'; | ||
protected _isHandlingUserInput: boolean; | ||
/** | ||
* Whether the user is pasting content. Allows Subclassers to do this in their subclass: | ||
* @example | ||
* ```js | ||
* _reflectBackFormattedValueToUser() { | ||
* return super._reflectBackFormattedValueToUser() || this._isPasting; | ||
* } | ||
* ``` | ||
*/ | ||
protected _isPasting: boolean; | ||
protected _calculateValues(opts: { source: 'model' | 'serialized' | 'formatted' | null }): void; | ||
@@ -31,6 +41,7 @@ protected _onModelValueChanged(arg: { modelValue: unknown }): void; | ||
protected _onUserInputChanged(): void; | ||
protected _callParser(value: string | undefined): object; | ||
protected _callFormatter(): string; | ||
private __preventRecursiveTrigger: boolean; | ||
private __callParser(value: string | undefined): object; | ||
private __callFormatter(): string; | ||
private __prevViewValue: string; | ||
} | ||
@@ -37,0 +48,0 @@ |
@@ -5,2 +5,3 @@ import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import { FormControlHost } from '@lion/form-core/types/FormControlMixinTypes'; | ||
import { FormatHost } from '@lion/form-core/types/FormatMixinTypes'; | ||
@@ -19,2 +20,4 @@ export declare class NativeTextFieldHost { | ||
Pick<typeof NativeTextFieldHost, keyof typeof NativeTextFieldHost> & | ||
Constructor<FormatHost> & | ||
Pick<typeof FormatHost, keyof typeof FormatHost> & | ||
Constructor<FocusHost> & | ||
@@ -21,0 +24,0 @@ Pick<typeof FocusHost, keyof typeof FocusHost> & |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
644045
19082
+ Added@lion/core@0.17.0(transitive)
+ Added@lion/localize@0.19.0(transitive)
+ Addedsingleton-manager@1.4.2(transitive)
- Removed@lion/core@0.16.0(transitive)
- Removed@lion/localize@0.18.0(transitive)
- Removedsingleton-manager@1.4.1(transitive)
Updated@lion/core@0.17.0
Updated@lion/localize@0.19.0