@zag-js/form-utils
Version:
## Installation
85 lines (81 loc) • 2.89 kB
JavaScript
;
// src/input-event.ts
var getWindow = (el) => el.ownerDocument.defaultView || window;
function getDescriptor(el, options) {
const { type = "HTMLInputElement", property = "value" } = options;
const proto = getWindow(el)[type].prototype;
return Object.getOwnPropertyDescriptor(proto, property) ?? {};
}
function setElementValue(el, value, option = {}) {
const descriptor = getDescriptor(el, option);
descriptor.set?.call(el, value);
el.setAttribute("value", value);
}
function setElementChecked(el, checked) {
const descriptor = getDescriptor(el, { type: "HTMLInputElement", property: "checked" });
descriptor.set?.call(el, checked);
if (checked) el.setAttribute("checked", "");
else el.removeAttribute("checked");
}
function dispatchInputValueEvent(el, options) {
const { value, bubbles = true } = options;
if (!el) return;
const win = getWindow(el);
if (!(el instanceof win.HTMLInputElement)) return;
setElementValue(el, `${value}`);
el.dispatchEvent(new win.Event("input", { bubbles }));
}
function dispatchInputCheckedEvent(el, options) {
const { checked, bubbles = true } = options;
if (!el) return;
const win = getWindow(el);
if (!(el instanceof win.HTMLInputElement)) return;
setElementChecked(el, checked);
el.dispatchEvent(new win.Event("click", { bubbles }));
}
// src/form.ts
function getClosestForm(el) {
if (isFormElement(el)) return el.form;
else return el.closest("form");
}
function isFormElement(el) {
return el.matches("textarea, input, select, button");
}
function trackFormReset(el, callback) {
if (!el) return;
const form = getClosestForm(el);
form?.addEventListener("reset", callback, { passive: true });
return () => {
form?.removeEventListener("reset", callback);
};
}
function trackFieldsetDisabled(el, callback) {
const fieldset = el?.closest("fieldset");
if (!fieldset) return;
callback(fieldset.disabled);
const win = fieldset.ownerDocument.defaultView || window;
const obs = new win.MutationObserver(() => callback(fieldset.disabled));
obs.observe(fieldset, {
attributes: true,
attributeFilter: ["disabled"]
});
return () => obs.disconnect();
}
function isNativeDisabled(el) {
return el.matches(":disabled");
}
function trackFormControl(el, options) {
if (!el) return;
const { onFieldsetDisabledChange, onFormReset } = options;
const cleanups = [trackFormReset(el, onFormReset), trackFieldsetDisabled(el, onFieldsetDisabledChange)];
return () => {
cleanups.forEach((cleanup) => cleanup?.());
};
}
exports.dispatchInputCheckedEvent = dispatchInputCheckedEvent;
exports.dispatchInputValueEvent = dispatchInputValueEvent;
exports.getClosestForm = getClosestForm;
exports.isNativeDisabled = isNativeDisabled;
exports.setElementChecked = setElementChecked;
exports.setElementValue = setElementValue;
exports.trackFormControl = trackFormControl;