Files
automatic/ui/inputAccordion.ts
T
2026-05-20 18:08:10 +02:00

73 lines
2.8 KiB
TypeScript

import { gradioApp } from './script';
import { updateInput } from './ui';
type AccordionElement = HTMLElement & {
visibleCheckbox: HTMLInputElement;
onVisibleCheckboxChange: () => void;
onChecked: (checked: boolean) => void;
};
export function inputAccordionChecked(id: string, checked: boolean): void {
const accordion = gradioApp().getElementById(id);
if (!(accordion instanceof HTMLElement)) return;
const acc = accordion as AccordionElement;
acc.visibleCheckbox.checked = checked;
acc.onVisibleCheckboxChange();
}
function setupAccordion(accordion: Element): void {
if (!(accordion instanceof HTMLElement)) return;
const acc = accordion as AccordionElement;
const labelWrap = accordion.querySelector('.label-wrap');
const gradioCheckbox = gradioApp().querySelector(`#${accordion.id}-checkbox input`);
const extra = gradioApp().querySelector(`#${accordion.id}-extra`);
if (!(labelWrap instanceof HTMLElement) || !(gradioCheckbox instanceof HTMLInputElement)) return;
const span = labelWrap.querySelector('span');
if (!(span instanceof HTMLElement)) return;
let linked = true;
const isOpen = () => labelWrap.classList.contains('open');
const observerAccordionOpen = new MutationObserver((mutations) => {
mutations.forEach((mutationRecord) => {
accordion.classList.toggle('input-accordion-open', isOpen());
if (linked) {
acc.visibleCheckbox.checked = isOpen();
acc.onVisibleCheckboxChange();
}
});
});
observerAccordionOpen.observe(labelWrap, { attributes: true, attributeFilter: ['class'] });
if (extra instanceof Node) labelWrap.insertBefore(extra, labelWrap.lastElementChild);
acc.onChecked = (checked: boolean) => {
if (isOpen() !== checked) labelWrap.click();
};
const visibleCheckbox = document.createElement('INPUT');
visibleCheckbox.type = 'checkbox';
visibleCheckbox.checked = isOpen();
visibleCheckbox.id = `${accordion.id}-visible-checkbox`;
visibleCheckbox.className = `${gradioCheckbox.className} input-accordion-checkbox`;
span.insertBefore(visibleCheckbox, span.firstChild);
acc.visibleCheckbox = visibleCheckbox as any;
acc.onVisibleCheckboxChange = () => {
if (linked && isOpen() !== visibleCheckbox.checked) labelWrap.click();
gradioCheckbox.checked = visibleCheckbox.checked;
updateInput(gradioCheckbox);
};
visibleCheckbox.addEventListener('click', (event) => {
linked = false;
event.stopPropagation();
});
visibleCheckbox.addEventListener('input', acc.onVisibleCheckboxChange);
}
window.inputAccordionChecked = inputAccordionChecked;
// onUiLoaded(() => {
// for (const accordion of gradioApp().querySelectorAll('.input-accordion')) setupAccordion(accordion);
// });
export function initAccordions() {
for (const accordion of gradioApp().querySelectorAll('.input-accordion')) setupAccordion(accordion);
}