feat(textarea): add types

This commit is contained in:
Joren Broekema 2020-09-30 17:47:12 +02:00 committed by Thomas Allmer
parent 06123918d0
commit 98fa7ad6b5
5 changed files with 55 additions and 8 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/textarea': minor
---
Add types for textarea package

View file

@ -33,6 +33,7 @@
"dependencies": {
"@lion/core": "0.12.0",
"@lion/form-core": "0.6.1",
"@types/autosize": "^3.0.7",
"autosize": "4.0.2"
},
"keywords": [

View file

@ -1,3 +1,4 @@
// @ts-expect-error https://github.com/jackmoore/autosize/pull/384 wait for this, then we can switch to just 'autosize'; and then types will work!
import autosize from 'autosize/src/autosize.js';
import { LionField } from '@lion/form-core';
import { css } from '@lion/core';
@ -8,6 +9,7 @@ import { css } from '@lion/core';
* @customElement lion-textarea
* @extends {LionField}
*/
// @ts-expect-error false positive for incompatible static get properties. Lit-element merges super properties already for you.
export class LionTextarea extends LionField {
static get properties() {
return {
@ -47,11 +49,23 @@ export class LionTextarea extends LionField {
};
}
/**
* Input node here is the textarea, which is not compatible with LionField _inputNode --> HTMLInputElement
* Therefore we do a full override and typecast to an intersection type that includes HTMLTextAreaElement
* @returns {HTMLTextAreaElement & HTMLInputElement}
*/
get _inputNode() {
return /** @type {HTMLTextAreaElement & HTMLInputElement} */ (Array.from(this.children).find(
el => el.slot === 'input',
));
}
constructor() {
super();
this.rows = 2;
this.maxRows = 6;
this.readOnly = false;
this.placeholder = '';
}
connectedCallback() {
@ -61,12 +75,11 @@ export class LionTextarea extends LionField {
}
disconnectedCallback() {
if (super.disconnectedCallback) {
super.disconnectedCallback();
}
super.disconnectedCallback();
autosize.destroy(this._inputNode);
}
/** @param {import('lit-element').PropertyValues } changedProperties */
updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('rows')) {
@ -121,7 +134,7 @@ export class LionTextarea extends LionField {
static get styles() {
return [
...super.styles,
super.styles,
css`
.input-group__container > .input-group__input ::slotted(.form-control) {
overflow-x: hidden; /* for FF adds height to the TextArea to reserve place for scroll-bars */
@ -142,6 +155,7 @@ export class LionTextarea extends LionField {
}
__initializeAutoresize() {
// @ts-ignore this property is added by webcomponentsjs polyfill for old browsers
if (this.__shady_native_contains) {
this.__textareaUpdateComplete = this.__waitForTextareaRenderedInRealDOM().then(() => {
this.__startAutoresize();
@ -154,6 +168,7 @@ export class LionTextarea extends LionField {
async __waitForTextareaRenderedInRealDOM() {
let count = 3; // max tasks to wait for
// @ts-ignore this property is added by webcomponentsjs polyfill for old browsers
while (count !== 0 && !this.__shady_native_contains(this._inputNode)) {
// eslint-disable-next-line no-await-in-loop
await new Promise(resolve => setTimeout(resolve));

View file

@ -1,6 +1,13 @@
import { expect, fixture, html } from '@open-wc/testing';
import { expect, fixture as _fixture, html } from '@open-wc/testing';
import '../lion-textarea.js';
/**
* @typedef {import('../src/LionTextarea').LionTextarea} LionTextarea
* @typedef {import('lit-html').TemplateResult} TemplateResult
*/
const fixture = /** @type {(arg: TemplateResult|string) => Promise<LionTextarea>} */ (_fixture);
function hasBrowserResizeSupport() {
const textarea = document.createElement('textarea');
return textarea.style.resize !== undefined;
@ -12,7 +19,7 @@ describe('<lion-textarea>', () => {
<lion-textarea></lion-textarea>
~~~`, async () => {
const el = await fixture(`<lion-textarea></lion-textarea>`);
expect(el.querySelector('textarea').nodeName).to.equal('TEXTAREA');
expect(el.querySelector('textarea')?.nodeName).to.equal('TEXTAREA');
});
it('has .rows=2 and .maxRows=6', async () => {
@ -42,7 +49,7 @@ describe('<lion-textarea>', () => {
it('sync readOnly to the native textarea', async () => {
const el = await fixture(`<lion-textarea readonly>foo</lion-textarea>`);
expect(el.readOnly).to.be.true;
expect(el.querySelector('textarea').readOnly).to.be.true;
expect(el.querySelector('textarea')?.readOnly).to.be.true;
});
it('disables user resize behavior', async () => {
@ -59,7 +66,7 @@ describe('<lion-textarea>', () => {
const el = await fixture(
html`<lion-textarea .modelValue="${'From value attribute'}"></lion-textarea>`,
);
expect(el.querySelector('textarea').value).to.equal('From value attribute');
expect(el.querySelector('textarea')?.value).to.equal('From value attribute');
});
it('adjusts height based on content', async () => {

View file

@ -2057,6 +2057,13 @@
dependencies:
"@types/node" "*"
"@types/autosize@^3.0.7":
version "3.0.7"
resolved "https://registry.yarnpkg.com/@types/autosize/-/autosize-3.0.7.tgz#f5da28d7ea4532c8b60573d67ec04fc866fa13db"
integrity sha512-D46m3aBNg81QKk9ZigmDFuhXUkD4IpBSrkGUKpYo2QBETbUjqEe8msXNCcECaXLXv1O4ppdMpizgFRzpfrgOxA==
dependencies:
"@types/jquery" "*"
"@types/babel__code-frame@^7.0.1":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@types/babel__code-frame/-/babel__code-frame-7.0.1.tgz#baf2529c4abbfb5e4008c845efcfe39a187e2f99"
@ -2253,6 +2260,13 @@
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==
"@types/jquery@*":
version "3.5.1"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.1.tgz#cebb057acf5071c40e439f30e840c57a30d406c3"
integrity sha512-Tyctjh56U7eX2b9udu3wG853ASYP0uagChJcQJXLUXEU6C/JiW5qt5dl8ao01VRj1i5pgXPAf8f1mq4+FDLRQg==
dependencies:
"@types/sizzle" "*"
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@ -2455,6 +2469,11 @@
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e"
integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==
"@types/sizzle@*":
version "2.3.2"
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
"@types/uglify-js@*":
version "3.9.3"
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.3.tgz#d94ed608e295bc5424c9600e6b8565407b6b4b6b"