diff --git a/packages/ai/src/InputTemplate.tsx b/packages/ai/src/InputTemplate.tsx index 8c0030b7b45b..62e156849e57 100644 --- a/packages/ai/src/InputTemplate.tsx +++ b/packages/ai/src/InputTemplate.tsx @@ -45,7 +45,7 @@ export default function InputTemplate(this: Input, hooks?: { preContent: Templat inner-input-with-icon={!!this.icon.length} disabled={this.disabled} readonly={this._readonly || this.loading} - value={this._innerValue} + value={this.value} placeholder={this._placeholder} maxlength={this.maxlength} role={this.accInfo.role} diff --git a/packages/base/src/thirdparty/preact/preact.module.js b/packages/base/src/thirdparty/preact/preact.module.js index 683feda4b8a0..55dfeacfce3f 100644 --- a/packages/base/src/thirdparty/preact/preact.module.js +++ b/packages/base/src/thirdparty/preact/preact.module.js @@ -1 +1 @@ -var n,l,t,u,i,o,r,e,f,c,s,a,h,p={},v=[],y=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,d=Array.isArray;function w(n,l){for(var t in l)n[t]=l[t];return n}function _(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function g(l,t,u){var i,o,r,e={};for(r in t)"key"==r?i=t[r]:"ref"==r?o=t[r]:e[r]=t[r];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):u),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===e[r]&&(e[r]=l.defaultProps[r]);return m(l,e,i,o,null)}function m(n,u,i,o,r){var e={type:n,props:u,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==r?++t:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(e),e}function b(){return{current:null}}function k(n){return n.children}function x(n,l){this.props=n,this.context=l}function C(n,l){if(null==l)return n.__?C(n.__,n.__i+1):null;for(var t;lt&&i.sort(e));P.__r=0}function $(n,l,t,u,i,o,r,e,f,c,s){var a,h,y,d,w,_,g=u&&u.__k||v,m=l.length;for(f=I(t,l,g,f),a=0;a0?m(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):o).__=n,o.__b=n.__b+1,r=null,-1!==(f=o.__i=O(o,t,e,a))&&(a--,(r=t[f])&&(r.__u|=2)),null==r||null===r.__v?(-1==f&&h--,"function"!=typeof o.type&&(o.__u|=4)):f!==e&&(f==e-1?h--:f==e+1?h++:(f>e?h--:h++,o.__u|=4))):o=n.__k[i]=null;if(a)for(i=0;i(null!=f&&0==(2&f.__u)?1:0))for(;r>=0||e=0){if((f=l[r])&&0==(2&f.__u)&&i==f.key&&o===f.type)return r;r--}if(e2&&(f.children=arguments.length>3?n.call(arguments,2):u),m(l.type,f,i||l.key,o||l.ref,null)}function J(n,l){var t={__c:l="__cC"+h++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var t,u;return this.getChildContext||(t=new Set,(u={})[l]=this,this.getChildContext=function(){return u},this.componentWillUnmount=function(){t=null},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&t.forEach(function(n){n.__e=!0,M(n)})},this.sub=function(n){t.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){t&&t.delete(n),l&&l.call(n)}}),n.children}};return t.Provider.__=t.Consumer.contextType=t}n=v.slice,l={__e:function(n,l,t,u){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,u||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},t=0,u=function(n){return null!=n&&null==n.constructor},x.prototype.setState=function(n,l){var t;t=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=w({},this.state),"function"==typeof n&&(n=n(w({},t),this.props)),n&&w(t,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this))},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),M(this))},x.prototype.render=k,i=[],r="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},P.__r=0,f=/(PointerCapture)$|Capture$/i,c=0,s=A(!1),a=A(!0),h=0;export{x as Component,k as Fragment,G as cloneElement,J as createContext,g as createElement,b as createRef,g as h,E as hydrate,u as isValidElement,l as options,D as render,L as toChildArray}; +var n,l,t,u,i,o,r,e,f,c,s,a,h,p={},v=[],y=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,d=Array.isArray;function w(n,l){for(var t in l)n[t]=l[t];return n}function _(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function g(l,t,u){var i,o,r,e={};for(r in t)"key"==r?i=t[r]:"ref"==r?o=t[r]:e[r]=t[r];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):u),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===e[r]&&(e[r]=l.defaultProps[r]);return m(l,e,i,o,null)}function m(n,u,i,o,r){var e={type:n,props:u,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==r?++t:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(e),e}function b(){return{current:null}}function k(n){return n.children}function x(n,l){this.props=n,this.context=l}function C(n,l){if(null==l)return n.__?C(n.__,n.__i+1):null;for(var t;lt&&i.sort(e));P.__r=0}function $(n,l,t,u,i,o,r,e,f,c,s){var a,h,y,d,w,_,g=u&&u.__k||v,m=l.length;for(f=I(t,l,g,f),a=0;a0?m(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):o).__=n,o.__b=n.__b+1,r=null,-1!==(f=o.__i=O(o,t,e,a))&&(a--,(r=t[f])&&(r.__u|=2)),null==r||null===r.__v?(-1==f&&h--,"function"!=typeof o.type&&(o.__u|=4)):f!==e&&(f==e-1?h--:f==e+1?h++:(f>e?h--:h++,o.__u|=4))):o=n.__k[i]=null;if(a)for(i=0;i(null!=f&&0==(2&f.__u)?1:0))for(;r>=0||e=0){if((f=l[r])&&0==(2&f.__u)&&i==f.key&&o===f.type)return r;r--}if(e2&&(f.children=arguments.length>3?n.call(arguments,2):u),m(l.type,f,i||l.key,o||l.ref,null)}function J(n,l){var t={__c:l="__cC"+h++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var t,u;return this.getChildContext||(t=new Set,(u={})[l]=this,this.getChildContext=function(){return u},this.componentWillUnmount=function(){t=null},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&t.forEach(function(n){n.__e=!0,M(n)})},this.sub=function(n){t.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){t&&t.delete(n),l&&l.call(n)}}),n.children}};return t.Provider.__=t.Consumer.contextType=t}n=v.slice,l={__e:function(n,l,t,u){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,u||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},t=0,u=function(n){return null!=n&&null==n.constructor},x.prototype.setState=function(n,l){var t;t=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=w({},this.state),"function"==typeof n&&(n=n(w({},t),this.props)),n&&w(t,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this))},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),M(this))},x.prototype.render=k,i=[],r="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},P.__r=0,f=/(PointerCapture)$|Capture$/i,c=0,s=A(!1),a=A(!0),h=0;export{x as Component,k as Fragment,G as cloneElement,J as createContext,g as createElement,b as createRef,g as h,E as hydrate,u as isValidElement,l as options,D as render,L as toChildArray}; diff --git a/packages/main/src/ColorPicker.ts b/packages/main/src/ColorPicker.ts index c0d28ee5e943..fc3e00536044 100644 --- a/packages/main/src/ColorPicker.ts +++ b/packages/main/src/ColorPicker.ts @@ -159,6 +159,13 @@ class ColorPicker extends UI5Element implements IFormInputElement { @property({ type: Number }) _alpha = 1; + /** + * this is the alpha value in the input only while editing, since it can container invalid/empty values temporarily + * @private + */ + @property() + _alphaTemp?: string; + /** * @private */ @@ -303,6 +310,7 @@ class ColorPicker extends UI5Element implements IFormInputElement { _handleAlphaInput(e: UI5CustomEvent | UI5CustomEvent) { const aphaInputValue = String(e.currentTarget.value); + this._alphaTemp = aphaInputValue; this._alpha = parseFloat(aphaInputValue); if (Number.isNaN(this._alpha)) { this._alpha = 1; @@ -447,6 +455,14 @@ class ColorPicker extends UI5Element implements IFormInputElement { } _handleAlphaChange() { + // parse the input value if valid or fallback to default + this._alpha = this._alphaTemp ? parseFloat(this._alphaTemp) : 1; + if (Number.isNaN(this._alpha)) { + this._alpha = 1; + } + // reset input value so _alpha is rendered + this._alphaTemp = undefined; + // normalize range this._alpha = this._alpha < 0 ? 0 : this._alpha; this._alpha = this._alpha > 1 ? 1 : this._alpha; diff --git a/packages/main/src/ColorPickerTemplate.tsx b/packages/main/src/ColorPickerTemplate.tsx index c1276eae6852..cc9f78868ddc 100644 --- a/packages/main/src/ColorPickerTemplate.tsx +++ b/packages/main/src/ColorPickerTemplate.tsx @@ -112,7 +112,7 @@ export default function ColorPickerTemplate(this: ColorPicker) { id="alpha" disabled={this.inputsDisabled} class="ui5-color-channel-input" - value={String(this._alpha)} + value={this._alphaTemp ?? String(this._alpha)} accessibleName={this.alphaInputLabel} onChange={this._handleAlphaChange} onInput={this._handleAlphaInput} diff --git a/packages/main/src/Input.ts b/packages/main/src/Input.ts index bfc26327cf29..fa4450e55639 100644 --- a/packages/main/src/Input.ts +++ b/packages/main/src/Input.ts @@ -388,16 +388,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement @property() value = ""; - /** - * Defines the inner stored value of the component. - * - * **Note:** The property is updated upon typing. In some special cases the old value is kept (e.g. deleting the value after the dot in a float) - * @default "" - * @private - */ - @property({ noAttribute: true }) - _innerValue = ""; - /** * Defines the value state of the component. * @default "None" @@ -624,7 +614,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement lastConfirmedValue: string isTyping: boolean _handleResizeBound: ResizeObserverCallback; - _keepInnerValue: boolean; _shouldAutocomplete?: boolean; _enterKeyDown?: boolean; _isKeyNavigation?: boolean; @@ -714,7 +703,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement this._handleResizeBound = this._handleResize.bind(this); - this._keepInnerValue = false; this._focusedAfterClear = false; this._valueStateLinks = []; } @@ -741,10 +729,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement } onBeforeRendering() { - if (!this._keepInnerValue) { - this._innerValue = this.value === null ? "" : this.value; - } - if (this.showSuggestions) { this.enableSuggestions(); @@ -815,9 +799,9 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement if (this._performTextSelection) { // this is required to syncronize lit-html input's value and user's input // lit-html does not sync its stored value for the value property when the user is typing - if (innerInput.value !== this._innerValue) { - innerInput.value = this._innerValue; - } + // if (innerInput.value !== this._innerValue) { + // innerInput.value = this._innerValue; + // } if (this.typedInValue.length && this.value.length) { innerInput.setSelectionRange(this.typedInValue.length, this.value.length); @@ -1118,7 +1102,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement return; } - this._keepInnerValue = false; this.focused = false; // invalidating property this._isChangeTriggeredBySuggestion = false; if (this.showClearIcon && !this._effectiveShowClearIcon) { @@ -1238,9 +1221,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement _input(e: CustomEvent | InputEvent, eventType: string) { const inputDomRef = this.getInputDOMRefSync(); - const emptyValueFiredOnNumberInput = this.value && this.isTypeNumber && !inputDomRef!.value; - - this._keepInnerValue = false; const allowedEventTypes = [ "deleteWordBackward", @@ -1260,41 +1240,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement this._shouldAutocomplete = !allowedEventTypes.includes(eventType) && !this.noTypeahead; - if (e instanceof InputEvent) { - // ---- Special cases of numeric Input ---- - // ---------------- Start ----------------- - - // When the last character after the delimiter is removed. - // In such cases, we want to skip the re-rendering of the - // component as this leads to cursor repositioning and causes user experience issues. - - // There are few scenarios: - // Example: type "123.4" and press BACKSPACE - the native input is firing event with the whole part as value (123). - // Pressing BACKSPACE again will remove the delimiter and the native input will fire event with the whole part as value again (123). - // Example: type "123.456", select/mark "456" and press BACKSPACE - the native input is firing event with the whole part as value (123). - // Example: type "123.456", select/mark "123.456" and press BACKSPACE - the native input is firing event with empty value. - const delimiterCase = this.isTypeNumber - && (e.inputType === "deleteContentForward" || e.inputType === "deleteContentBackward") - && !(e.target as HTMLInputElement).value.includes(".") - && this.value.includes("."); - - // Handle special numeric notation with "e", example "12.5e12" - const eNotationCase = emptyValueFiredOnNumberInput && e.data === "e"; - - // Handle special numeric notation with "-", example "-3" - // When pressing BACKSPACE, the native input fires event with empty value - const minusRemovalCase = emptyValueFiredOnNumberInput - && this.value.startsWith("-") - && this.value.length === 2 - && (e.inputType === "deleteContentForward" || e.inputType === "deleteContentBackward"); - - if (delimiterCase || eNotationCase || minusRemovalCase) { - this.value = (e.target as HTMLInputElement).value; - this._keepInnerValue = true; - } - // ----------------- End ------------------ - } - if (e.target === inputDomRef) { this.focused = true; @@ -1340,7 +1285,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement _handleTypeAhead(item: IInputSuggestionItemSelectable) { const value = item.text ? item.text : ""; - this._innerValue = value; this.value = value; this._performTextSelection = true; diff --git a/packages/main/src/InputTemplate.tsx b/packages/main/src/InputTemplate.tsx index c9cf951217de..39d10ed5e413 100644 --- a/packages/main/src/InputTemplate.tsx +++ b/packages/main/src/InputTemplate.tsx @@ -33,8 +33,8 @@ export default function InputTemplate(this: Input, hooks?: { preContent: Templat inner-input-with-icon={!!this.icon.length} disabled={this.disabled} readonly={this._readonly} + value={this.value} required={this.required} - value={this._innerValue} placeholder={this._placeholder} maxlength={this.maxlength} role={this.accInfo.role} diff --git a/packages/main/src/RangeSlider.ts b/packages/main/src/RangeSlider.ts index 3fdd12d6d0cf..bf91664d3709 100644 --- a/packages/main/src/RangeSlider.ts +++ b/packages/main/src/RangeSlider.ts @@ -113,6 +113,9 @@ class RangeSlider extends SliderBase implements IFormInputElement { return this._startValue; } + @property() + startValueTemp?: string; + /** * Defines end point of a selection - position of a second handle on the slider. * @default 100 @@ -142,6 +145,9 @@ class RangeSlider extends SliderBase implements IFormInputElement { @property() tooltipEndValueState: `${ValueState}` = "None"; + @property() + endValueTemp?: string; + @property({ type: Boolean }) rangePressed = false; diff --git a/packages/main/test/pages/Input_old_value.html b/packages/main/test/pages/Input_old_value.html new file mode 100644 index 000000000000..a8cdf70c2b1a --- /dev/null +++ b/packages/main/test/pages/Input_old_value.html @@ -0,0 +1,42 @@ + + + + + + + ui5-input + + + + + + + + + + + + + + + + \ No newline at end of file