diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index ce82d41c..86b5104e 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -14,6 +14,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next +- `` now lazily evaluates and shares hidden date / number inputs across components to improve performance. [#1978] - Fixed a bug in `` that caused it not to recalculate it's position when going from being `display: none;` to its original display value. [#1942] - Fixed a bug in `` where when it showed it would cause a layout shift. [#1967] - Fixed a bug in `` that allowed unwanted text properties to leak in [#1947] diff --git a/src/components/input/input.component.ts b/src/components/input/input.component.ts index a672a8e0..d4fafa5f 100644 --- a/src/components/input/input.component.ts +++ b/src/components/input/input.component.ts @@ -54,6 +54,9 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont static styles: CSSResultGroup = [componentStyles, formControlStyles, styles]; static dependencies = { 'sl-icon': SlIcon }; + // Protected to make TS happy. + protected static __sharedInput: null | HTMLInputElement = null; + private readonly formControlController = new FormControlController(this, { assumeInteractionOn: ['sl-blur', 'sl-input'] }); @@ -65,8 +68,23 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont @state() private hasFocus = false; @property() title = ''; // make reactive to pass through - private __numberInput = Object.assign(document.createElement('input'), { type: 'number' }); - private __dateInput = Object.assign(document.createElement('input'), { type: 'date' }); + private get __numberInput() { + const ctor = this.constructor as unknown as typeof SlInput; + if (ctor.__sharedInput === null) ctor.__sharedInput = document.createElement('input'); + + const input = ctor.__sharedInput; + input.type = 'number'; + return input; + } + + private get __dateInput() { + const ctor = this.constructor as unknown as typeof SlInput; + if (ctor.__sharedInput === null) ctor.__sharedInput = document.createElement('input'); + + const input = ctor.__sharedInput; + input.type = 'date'; + return input; + } /** * The type of input. Works the same as a native `` element, but only a subset of types are supported. Defaults