diff --git a/.changeset/many-cougars-sit.md b/.changeset/many-cougars-sit.md new file mode 100644 index 000000000..537603b81 --- /dev/null +++ b/.changeset/many-cougars-sit.md @@ -0,0 +1,5 @@ +--- +'@lion/textarea': patch +--- + +Added Intersection Observer to ensure textarea gets recalculated on visibility changes, e.g. when it is inside a dialog, tabs, or accordion when they are hidden initially. diff --git a/packages/textarea/README.md b/packages/textarea/README.md index 7321a0d6f..7e4a750c3 100644 --- a/packages/textarea/README.md +++ b/packages/textarea/README.md @@ -29,6 +29,7 @@ export const main = () => html` - `max-rows` attribute to set the amount of rows it should resize to, before it will scroll - `rows` attribute to set the minimum amount of rows - `readonly` attribute to prevent changing the content +- Uses Intersection Observer for detecting visibility change, making sure it resizes ## How to use @@ -120,3 +121,33 @@ export const validation = () => { `; }; ``` + +### Intersection Observer + +It could be that your textarea is inside a hidden container, for example for a dialog or accordion or tabs. +When it is hidden, the resizing is calculated based on the visible space of the text. +Therefore, an Intersection Observer observes visibility changes of the textarea relative to the viewport, and resizes the textarea when a visibility change happens. + +> For old browsers like old Edge or IE11, a [polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill) is required to be added on the application level for this to work. +> For most cases, the optimized default will suffice. + +In the demo below you can see that the textarea is correctly calculated to 4 maximum rows, whereas without the observer, it would be on 2 rows and only resize on user input. + +```js preview-story +export const hidden = () => html` +
+ +`; +``` diff --git a/packages/textarea/src/LionTextarea.js b/packages/textarea/src/LionTextarea.js index 7e1231ff5..e9f9e4417 100644 --- a/packages/textarea/src/LionTextarea.js +++ b/packages/textarea/src/LionTextarea.js @@ -73,6 +73,8 @@ export class LionTextarea extends NativeTextFieldMixin(LionFieldWithTextArea) { // eslint-disable-next-line wc/guard-super-call super.connectedCallback(); this.__initializeAutoresize(); + this.__intersectionObserver = new IntersectionObserver(() => this.resizeTextarea()); + this.__intersectionObserver.observe(this); } /** @param {import('lit-element').PropertyValues } changedProperties */ diff --git a/packages/textarea/test/lion-textarea.test.js b/packages/textarea/test/lion-textarea.test.js index 4b1be9a09..5abe4efcc 100644 --- a/packages/textarea/test/lion-textarea.test.js +++ b/packages/textarea/test/lion-textarea.test.js @@ -1,4 +1,5 @@ -import { expect, fixture as _fixture, html } from '@open-wc/testing'; +import { expect, fixture as _fixture, html, nextFrame } from '@open-wc/testing'; +import sinon from 'sinon'; import '../lion-textarea.js'; /** @@ -147,6 +148,21 @@ describe('