chore(coldwired): update utils
This commit is contained in:
parent
0f608444b5
commit
c93141d8bb
7 changed files with 53 additions and 188 deletions
|
@ -1,4 +1,4 @@
|
|||
import { isButtonElement } from '@utils';
|
||||
import { isButtonElement } from '@coldwired/utils';
|
||||
|
||||
import { ApplicationController } from './application_controller';
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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 }>) {
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue