UNPKG

@etsoo/react

Version:

TypeScript ReactJs UI Independent Framework

174 lines (173 loc) 5.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReactUtils = void 0; const shared_1 = require("@etsoo/shared"); /** * React utils */ var ReactUtils; (function (ReactUtils) { /** * Format input value * @param value Input value * @returns Formatted value */ function formatInputValue(value) { if (value === null) return undefined; if (typeof value === "number") return value; if (typeof value === "string") return value; if (Array.isArray(value)) return value; return String(value); } ReactUtils.formatInputValue = formatInputValue; /** * Is safe click * @param event Mouse event * @returns Result */ function isSafeClick(event) { // No target // HTMLElement <= Element, SVGElement <= Element if (!(event.target instanceof Element)) return true; // Outside of the currentTarget let target = event.target; if (!event.currentTarget.contains(target)) return false; while (target != null && target != event.currentTarget) { const nodeName = target.nodeName.toUpperCase(); if (nodeName === "INPUT" || nodeName === "BUTTON" || nodeName === "A" || target.hasAttribute("onClick")) return false; target = target.parentElement; } return true; } ReactUtils.isSafeClick = isSafeClick; /** * Trigger input change event * @param input Form input * @param value New value * @param cancelable Cancelable */ function triggerChange(input, value, cancelable = false) { // Radio type not supported if (input.type === "radio") return; // checked? const checked = input.type === "checkbox"; // Property name const property = checked ? "checked" : "value"; // input.value = newValue will not trigger the change event // input type = 'hidden' will also not trigger the event // https://coryrylan.com/blog/trigger-input-updates-with-react-controlled-inputs var nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, property)?.set; if (checked) { const checkedValue = input.value == value; nativeInputValueSetter?.call(input, checkedValue); const clickEvent = new Event("click", { bubbles: true, cancelable }); input.dispatchEvent(clickEvent); } else { nativeInputValueSetter?.call(input, value); const inputEvent = new Event("change", { bubbles: true, cancelable }); input.dispatchEvent(inputEvent); } } ReactUtils.triggerChange = triggerChange; /** * Update refs * @param refs Refs * @param data Data * @param callback Callback to update refs' value, return false continue to process */ function updateRefs(refs, data, callback) { const local = callback == null ? undefined : typeof callback === "function" ? callback : (item, value) => { item[callback] = value; }; let k; for (k in refs) { const ref = refs[k]; const item = ref?.current; if (item == null) continue; if (local && local(item, data[k]) !== false) { continue; } else if (item instanceof HTMLInputElement || item instanceof HTMLTextAreaElement || item instanceof HTMLSelectElement) { const value = shared_1.Utils.getNestedValue(data, item.name || k); const isDateTime = item.type === "datetime-local"; if (isDateTime || item.type === "date") { item.value = shared_1.DateUtils.formatForInput(value, isDateTime ? false : undefined) ?? ""; } else { item.value = `${value ?? ""}`; } } else { item.value = data[k]; } } } ReactUtils.updateRefs = updateRefs; /** * Update data with refs * @param refs Refs * @param data Data * @param callback Callback to return new value * @param ignoreEmpty Ignore empty string or not, default true */ function updateRefValues(refs, data, callback, ignoreEmpty = true) { const local = callback == null ? undefined : typeof callback === "function" ? callback : (item) => item[callback]; const formatValue = (value) => { if (ignoreEmpty && value === "") return null; return value; }; let k; for (k in refs) { const ref = refs[k]; const item = ref?.current; if (item == null) continue; if (local) { data[k] = local(item); } else if (item instanceof HTMLInputElement) { shared_1.Utils.setNestedValue(data, item.name || k, formatValue(shared_1.DomUtils.getInputValue(item)), true); } else if (item instanceof HTMLTextAreaElement || item instanceof HTMLSelectElement) { shared_1.Utils.setNestedValue(data, item.name || k, formatValue(item.value), true); } else { data[k] = item.value; } } } ReactUtils.updateRefValues = updateRefValues; })(ReactUtils || (exports.ReactUtils = ReactUtils = {}));