import type { RefObject } from "react"; import { getElRefHelper } from "./react/getElRefHelper"; type TFormEl = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | HTMLButtonElement | HTMLFieldSetElement; const isReadOnly = ( el: TFormEl ): el is HTMLInputElement | HTMLTextAreaElement => { return ( el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement ); }; /** * Получает список полей формы, доступных для редактирования пользователем * @param formRef{HTMLFormElement | null} * @returns {HTMLElement[]} Возвращает массив доступных пользователю полей формы (без `hidden`, `file`, `button`, `disabled` и `readonly`). * @example * import { getUserControlledFields } from "@delement/ui/utils"; * * const form = document.querySelector("form"); * const fields = getUserControlledFields(form as HTMLFormElement); */ export const getUserControlledFields = (formRef: RefObject | HTMLFormElement | null): HTMLElement[] => { const form = getElRefHelper(formRef) as HTMLFormElement | null; if (form) { const elements = [ ...form.elements ] as TFormEl[]; const defaultFields = elements .filter((el) => { const { type, tagName, disabled, hidden, } = el; const readOnly = isReadOnly(el) ? el.readOnly : false; return type !== "hidden" && type !== "file" && tagName.toLowerCase() !== "button" && !disabled && !readOnly && !hidden; }); const customFields = elements.filter((el) => { const input = el as TFormEl; const readOnly = isReadOnly(input) ? input.readOnly : false; return input.hasAttribute("data-js-component-input") && !input.disabled && !readOnly; }); return [ ...new Set([ ...defaultFields, ...customFields ]) ]; } else { return []; } };