import XNode, { constructorNeedsArgumentsSymbol, IElementAttributes } from "@web-atoms/core/dist/core/XNode"; import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl"; import IElement from "./IElement"; import "./ButtonBar.global.css"; declare global { namespace JSX { interface IntrinsicElements { "button-bar": IElementAttributes; } } } let nid = 1; const labelPathSetter = AtomControl.registerProperty("data-button-bar-items", "label", (ctrl, element, value) => { element["labelPath"] = value; }); const valuePathSetter = AtomControl.registerProperty("data-button-bar-items", "value", (ctrl, element, value) => { element["valuePath"] = value; }); const namePathSetter = AtomControl.registerProperty("data-button-bar-items", "name", (ctrl, element, value) => { element["namePath"] = value; }); const itemRendererSetter = AtomControl.registerProperty("data-button-bar-items", "renderer", (ctrl, element, value) => { element["itemRenderer"] = value; }); const refreshItems = (element: HTMLElement, items?: any[]) => { items ??= element["items"]; const lp = element["labelPath"] ?? ((item) => item?.label ?? item); const vp = element["valuePath"] ?? ((item) => item?.value ?? item); const ir = element["itemRenderer"] ?? ((item) =>
); const name = element["namePath"]; let i = 0; const all = Array.from(element.querySelectorAll(`label`)); for (const element of all) { element.remove(); } const control = AtomControl.from(element); const hidden = element.querySelector(`input.hidden`) as HTMLInputElement; const cv = hidden.value; if(items?.length) { for (const iterator of items) { const item = document.createElement("label"); const labelName = name + i; const value = vp(iterator); let checked = false; if(cv !== void 0) { if (cv == value) { checked = true; } } item.setAttribute("for", labelName); element.appendChild(item); // @ts-expect-error control.render(
{ ir(iterator) }
, item, control); i++; } } }; const itemsSetter = AtomControl.registerProperty("data-items", "value", (ctrl, element: HTMLSelectElement, value) => { element["items"] = value; ctrl.runAfterInit(() => setTimeout(refreshItems, 1, element, value)); }); const changeTracker = (e: CustomEvent) => { if (e.detail) { return; } const target = e.currentTarget as HTMLElement; const hidden = target.querySelector(`input.hidden`) as HTMLInputElement; const buttons = target.querySelectorAll(`input[type="radio"]`); for (let index = 0; index < buttons.length; index++) { const element = buttons[index] as HTMLInputElement; if (element.checked) { hidden.value = element.value; hidden.dispatchEvent(new CustomEvent("input", { detail: element.value, bubbles: true })); break; } } }; export interface IButtonBar extends IElement { items: any[]; labelPath?: (item) => any; valuePath?: (item) => any; itemRenderer?: (item) => XNode; value?: any; name?: string; } export default function ButtonBar({ items, labelPath, valuePath, itemRenderer = (x) =>
, value, name = `button-bar-${nid++}`, ... a }: IButtonBar) { a[labelPathSetter.property] = labelPath; a[valuePathSetter.property] = valuePath; a[itemsSetter.property] = items; a[itemRendererSetter.property] = itemRenderer; a[namePathSetter.property] = name; a["event-change"] = changeTracker; return ; }