@furystack/shades-common-components
Version:
84 lines • 3.9 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Injectable } from '@furystack/inject';
import { Shade, attachProps, createComponent } from '@furystack/shades';
import { ObservableValue } from '@furystack/utils';
let FormService = class FormService {
validatedFormData = new ObservableValue(null);
rawFormData = new ObservableValue(null);
validationResult = new ObservableValue({ isValid: null });
fieldErrors = new ObservableValue({});
inputs = new Set();
setFieldState = (key, validationResult, validity) => {
this.fieldErrors.setValue({ ...this.fieldErrors.getValue(), [key]: { validationResult, validity } });
};
[Symbol.dispose]() {
this.validatedFormData[Symbol.dispose]();
this.rawFormData[Symbol.dispose]();
this.validationResult[Symbol.dispose]();
}
};
FormService = __decorate([
Injectable({ lifetime: 'scoped' })
], FormService);
export { FormService };
export const Form = Shade({
shadowDomName: 'shade-form',
elementBase: HTMLFormElement,
elementBaseName: 'form',
render: ({ props, children, useDisposable, element, injector }) => {
const formInjector = useDisposable('formInjector', () => injector.createChild({ owner: element }));
element.injector = formInjector;
const formService = new FormService();
formInjector.setExplicitInstance(formService);
const changeHandler = (ev, shouldSubmit) => {
formService.inputs.forEach((i) => {
const e = document.createEvent('FocusEvent');
e.initEvent('blur', true, true);
i.dispatchEvent(e);
});
const formData = Object.fromEntries(new FormData(ev.currentTarget).entries());
formService.rawFormData.setValue(formData);
const currentFieldErrors = formService.fieldErrors.getValue();
if (Object.values(currentFieldErrors).some((v) => v?.validationResult.isValid === false) ||
[...formService.inputs].some((input) => !input.validity.valid)) {
formService.validationResult.setValue({ isValid: false, reason: 'input-validation-failed' });
}
else if (props.validate(formData)) {
formService.validationResult.setValue({ isValid: true });
formService.validatedFormData.setValue(formData);
if (shouldSubmit) {
props.onSubmit(formData);
}
}
else {
formService.validationResult.setValue({ isValid: false, reason: 'validation-failed' });
}
};
attachProps(element, {
injector: formInjector,
...props,
oninvalid: (ev) => {
changeHandler(ev);
},
onsubmit: (ev) => {
ev.preventDefault();
changeHandler(ev, true);
},
onchange: (ev) => {
changeHandler(ev);
},
onreset: () => {
formService.rawFormData.setValue(null);
formService.validationResult.setValue({ isValid: null });
formService.validatedFormData.setValue(null);
},
});
return createComponent(createComponent, null, children);
},
});
//# sourceMappingURL=form.js.map