chore(coldwired): update utils

This commit is contained in:
Paul Chavard 2023-10-26 16:01:15 +02:00
parent 0f608444b5
commit c93141d8bb
7 changed files with 53 additions and 188 deletions

View file

@ -1,4 +1,4 @@
import { isButtonElement } from '@utils';
import { isButtonElement } from '@coldwired/utils';
import { ApplicationController } from './application_controller';

View file

@ -1,10 +1,4 @@
import {
isSelectElement,
isCheckboxOrRadioInputElement,
isTextInputElement,
isDateInputElement
} from '@utils';
import { isFormInputElement } from '@coldwired/utils';
import { isFormInputElement, matchInputElement } from '@coldwired/utils';
import { ApplicationController } from './application_controller';
@ -28,14 +22,9 @@ export class AutosubmitController extends ApplicationController {
private onChange(event: Event) {
const target = this.findTargetElement(event);
if (!target) return;
if (
isSelectElement(target) ||
isCheckboxOrRadioInputElement(target) ||
isTextInputElement(target)
) {
if (isDateInputElement(target)) {
matchInputElement(target, {
date: (target) => {
if (target.value.trim() == '' || !isNaN(Date.parse(target.value))) {
this.#dateTimeChangedInputs.add(target);
this.debounce(this.submit, AUTOSUBMIT_DATE_DEBOUNCE_DELAY);
@ -43,34 +32,34 @@ export class AutosubmitController extends ApplicationController {
this.#dateTimeChangedInputs.delete(target);
this.cancelDebounce(this.submit);
}
} else {
this.cancelDebounce(this.submit);
this.submit();
}
}
},
text: () => this.submitNow(),
changeable: () => this.submitNow()
});
}
private onInput(event: Event) {
const target = this.findTargetElement(event);
if (!target) return;
if (!isDateInputElement(target) && isTextInputElement(target)) {
this.debounce(this.submit, AUTOSUBMIT_DEBOUNCE_DELAY);
}
matchInputElement(target, {
date: () => {},
inputable: () => this.debounce(this.submit, AUTOSUBMIT_DEBOUNCE_DELAY)
});
}
private onBlur(event: Event) {
const target = this.findTargetElement(event);
if (!target) return;
if (isDateInputElement(target)) {
Promise.resolve().then(() => {
if (this.#dateTimeChangedInputs.has(target)) {
this.cancelDebounce(this.submit);
this.submit();
}
});
}
matchInputElement(target, {
date: () => {
Promise.resolve().then(() => {
if (this.#dateTimeChangedInputs.has(target)) {
this.submitNow();
}
});
}
});
}
private findTargetElement(event: Event) {
@ -111,6 +100,11 @@ export class AutosubmitController extends ApplicationController {
return eventTypes.length == 0 ? true : eventTypes;
}
private submitNow() {
this.cancelDebounce(this.submit);
this.submit();
}
private submit() {
const submitter = this.hasSubmitterTarget ? this.submitterTarget : null;
const form =

View file

@ -1,12 +1,8 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { ActionEvent } from '@hotwired/stimulus';
import {
httpRequest,
isSelectElement,
isCheckboxOrRadioInputElement,
isTextInputElement,
getConfig
} from '@utils';
import { httpRequest, getConfig } from '@utils';
import { matchInputElement } from '@coldwired/utils';
import { AutoUpload } from '../shared/activestorage/auto-upload';
import { ApplicationController } from './application_controller';
@ -59,29 +55,26 @@ export class TypeDeChampEditorController extends ApplicationController {
}
private onChange(event: Event) {
const target = event.target as HTMLElement & { form?: HTMLFormElement };
if (
target.form &&
(isSelectElement(target) || isCheckboxOrRadioInputElement(target))
) {
this.save(target.form);
}
matchInputElement(event.target, {
file: (target) => {
if (target.files?.length) {
const autoupload = new AutoUpload(target, target.files[0]);
autoupload.start();
}
},
changeable: (target) => this.save(target.form)
});
}
private onInput(event: Event) {
const target = event.target as HTMLInputElement;
// mark input as touched so we know to not overwrite it's value with next re-render
target.setAttribute('data-touched', 'true');
if (target.form && isTextInputElement(target)) {
this.#dirtyForms.add(target.form);
this.debounce(this.save, AUTOSAVE_DEBOUNCE_DELAY);
} else if (target.form && target.type == 'file' && target.files?.length) {
const autoupload = new AutoUpload(target, target.files[0]);
autoupload.start();
}
matchInputElement(event.target, {
inputable: (target) => {
if (target.form) {
this.#dirtyForms.add(target.form);
this.debounce(this.save, AUTOSAVE_DEBOUNCE_DELAY);
}
}
});
}
private onSortableEnd(event: CustomEvent<{ position: number }>) {

View file

@ -1,14 +1,6 @@
import { suite, test, expect } from 'vitest';
import {
show,
hide,
toggle,
toggleExpandIcon,
isSelectElement,
isTextInputElement,
isCheckboxOrRadioInputElement
} from './utils';
import { show, hide, toggle, toggleExpandIcon } from './utils';
suite('@utils', () => {
test('show', () => {
@ -46,79 +38,4 @@ suite('@utils', () => {
expect(icon.classList.contains('fr-icon-arrow-down-s-line')).toBeTruthy();
expect(icon.classList.contains('fr-icon-arrow-up-s-line')).toBeFalsy();
});
test('isSelectElement', () => {
const select = document.createElement('select');
const input = document.createElement('input');
const textarea = document.createElement('textarea');
expect(isSelectElement(select)).toBeTruthy();
expect(isSelectElement(input)).toBeFalsy();
expect(isSelectElement(textarea)).toBeFalsy();
input.type = 'text';
expect(isSelectElement(input)).toBeFalsy();
input.type = 'email';
expect(isSelectElement(input)).toBeFalsy();
input.type = 'checkbox';
expect(isSelectElement(input)).toBeFalsy();
input.type = 'radio';
expect(isSelectElement(input)).toBeFalsy();
input.type = 'file';
expect(isSelectElement(input)).toBeFalsy();
});
test('isTextInputElement', () => {
const select = document.createElement('select');
const input = document.createElement('input');
const textarea = document.createElement('textarea');
expect(isTextInputElement(select)).toBeFalsy();
expect(isTextInputElement(input)).toBeTruthy();
expect(isTextInputElement(textarea)).toBeTruthy();
input.type = 'text';
expect(isTextInputElement(input)).toBeTruthy();
input.type = 'email';
expect(isTextInputElement(input)).toBeTruthy();
input.type = 'checkbox';
expect(isTextInputElement(input)).toBeFalsy();
input.type = 'radio';
expect(isTextInputElement(input)).toBeFalsy();
input.type = 'file';
expect(isTextInputElement(input)).toBeFalsy();
});
test('isCheckboxOrRadioInputElement', () => {
const select = document.createElement('select');
const input = document.createElement('input');
const textarea = document.createElement('textarea');
expect(isCheckboxOrRadioInputElement(select)).toBeFalsy();
expect(isCheckboxOrRadioInputElement(input)).toBeFalsy();
expect(isCheckboxOrRadioInputElement(textarea)).toBeFalsy();
input.type = 'text';
expect(isCheckboxOrRadioInputElement(input)).toBeFalsy();
input.type = 'email';
expect(isCheckboxOrRadioInputElement(input)).toBeFalsy();
input.type = 'checkbox';
expect(isCheckboxOrRadioInputElement(input)).toBeTruthy();
input.type = 'radio';
expect(isCheckboxOrRadioInputElement(input)).toBeTruthy();
input.type = 'file';
expect(isCheckboxOrRadioInputElement(input)).toBeFalsy();
});
});

View file

@ -269,50 +269,6 @@ export function isNumeric(s: string) {
return !isNaN(n) && isFinite(n);
}
export function isButtonElement(
element: Element
): element is HTMLButtonElement {
return (
element.tagName == 'BUTTON' ||
(element.tagName == 'INPUT' &&
(element as HTMLInputElement).type == 'submit')
);
}
export function isSelectElement(
element: HTMLElement
): element is HTMLSelectElement {
return element.tagName == 'SELECT';
}
export function isCheckboxOrRadioInputElement(
element: HTMLElement & { type?: string }
): element is HTMLInputElement {
return (
element.tagName == 'INPUT' &&
(element.type == 'checkbox' || element.type == 'radio')
);
}
export function isDateInputElement(
element: HTMLElement & { type?: string }
): element is HTMLInputElement {
return (
element.tagName == 'INPUT' &&
(element.type == 'date' || element.type == 'datetime-local')
);
}
export function isTextInputElement(
element: HTMLElement & { type?: string }
): element is HTMLInputElement {
return (
['INPUT', 'TEXTAREA'].includes(element.tagName) &&
typeof element.type == 'string' &&
!['checkbox', 'radio', 'file'].includes(element.type)
);
}
export function fire<T>(obj: EventTarget, name: string, data?: T) {
const event = new CustomEvent(name, {
bubbles: true,

View file

@ -2,7 +2,7 @@
"dependencies": {
"@coldwired/actions": "^0.11.2",
"@coldwired/turbo-stream": "^0.11.1",
"@coldwired/utils": "^0.11.1",
"@coldwired/utils": "^0.11.4",
"@gouvfr/dsfr": "^1.10.1",
"@graphiql/plugin-explorer": "^0.3.4",
"@graphiql/toolkit": "^0.9.1",

View file

@ -1218,6 +1218,11 @@
resolved "https://registry.yarnpkg.com/@coldwired/utils/-/utils-0.11.1.tgz#d126246ab66591467e9e4c765769f133f6236ddb"
integrity sha512-vuW1hVhD5U4NX/0dl+fT4RL92T5fEITwc9l/DnaBoP5SAuCAVRnHCWcdyROGz55E4WvSXFqAHD6qkxRwOKG2og==
"@coldwired/utils@^0.11.4":
version "0.11.4"
resolved "https://registry.yarnpkg.com/@coldwired/utils/-/utils-0.11.4.tgz#4889103dc73c1d86eff7d21574a0bde37b1f3c03"
integrity sha512-JvYosEc++zcuZmyfHAKG1cZ/jEIBM8ciJsD2ZcgFdzjSla1wtG+p6GOYiIVXZpCKO2oWGR4EmiYFYpBNIy3WDw==
"@emotion/is-prop-valid@^0.8.2":
version "0.8.8"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"