Konnorrogers/fix value as number 2 (#1385)

* fix: garbage collected valueAs*

* weird....

* prettier and tests
pull/1392/head
Konnor Rogers 2023-06-20 15:22:13 -04:00 zatwierdzone przez GitHub
rodzic 441a957432
commit d7145f1f84
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
2 zmienionych plików z 62 dodań i 19 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
// eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { elementUpdated, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { getFormControls, serialize } from '../../../dist/shoelace.js';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
import { sendKeys } from '@web/test-runner-commands'; // must come from the same module
@ -66,21 +66,69 @@ describe('<sl-input>', () => {
describe('value methods', () => {
it('should set the value as a date when using valueAsDate', async () => {
const el = await fixture<SlInput>(html` <sl-input type="date"></sl-input> `);
const el = document.createElement(`sl-input`);
el.type = 'date';
const today = new Date();
el.valueAsDate = today;
// Test before we render in the dom
expect(el.value).to.equal(today.toISOString().split('T')[0]);
expect(el.valueAsDate.toISOString().split('T')[0]).to.equal(today.toISOString().split('T')[0]);
document.body.appendChild(el);
await elementUpdated(el);
// Update valueAsDate after we render to make sure it reflects properly
el.valueAsDate = null;
await elementUpdated(el);
expect(el.value).to.equal('');
expect(el.valueAsDate).to.equal(null);
// Update again with a real date to make sure it works
el.valueAsDate = today;
await elementUpdated(el);
expect(el.value).to.equal(today.toISOString().split('T')[0]);
expect(el.valueAsDate.toISOString().split('T')[0]).to.equal(today.toISOString().split('T')[0]);
el.remove();
});
it('should set the value as a number when using valueAsNumber', async () => {
const el = await fixture<SlInput>(html` <sl-input type="number"></sl-input> `);
const el = document.createElement(`sl-input`);
el.type = 'number';
const num = 12345;
el.valueAsNumber = num;
expect(el.value).to.equal(num.toString());
expect(el.valueAsNumber).to.equal(num);
document.body.appendChild(el);
await elementUpdated(el);
// Wait for render, then update the value
const otherNum = 4567;
el.valueAsNumber = otherNum;
await elementUpdated(el);
expect(el.value).to.equal(otherNum.toString());
expect(el.valueAsNumber).to.equal(otherNum);
// Re-set valueAsNumber and make sure it updates.
el.valueAsNumber = num;
await elementUpdated(el);
expect(el.value).to.equal(num.toString());
expect(el.valueAsNumber).to.equal(num);
el.remove();
});
});

Wyświetl plik

@ -63,6 +63,9 @@ 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' });
/**
* The type of input. Works the same as a native `<input>` element, but only a subset of types are supported. Defaults
* to `text`.
@ -197,32 +200,24 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
/** Gets or sets the current value as a `Date` object. Returns `null` if the value can't be converted. */
get valueAsDate() {
const input = document.createElement('input');
input.type = 'date';
input.value = this.value;
return input.valueAsDate;
this.__dateInput.value = this.value;
return this.input?.valueAsDate || this.__dateInput.valueAsDate;
}
set valueAsDate(newValue: Date | null) {
const input = document.createElement('input');
input.type = 'date';
input.valueAsDate = newValue;
this.value = input.value;
this.__dateInput.valueAsDate = newValue;
this.value = this.__dateInput.value;
}
/** Gets or sets the current value as a number. Returns `NaN` if the value can't be converted. */
get valueAsNumber() {
const input = document.createElement('input');
input.type = 'number';
input.value = this.value;
return input.valueAsNumber;
this.__numberInput.value = this.value;
return this.input?.valueAsNumber || this.__numberInput.valueAsNumber;
}
set valueAsNumber(newValue: number) {
const input = document.createElement('input');
input.type = 'number';
input.valueAsNumber = newValue;
this.value = input.value;
this.__numberInput.valueAsNumber = newValue;
this.value = this.__numberInput.value;
}
/** Gets the validity state object */