import '../nui-heading/nui-heading.js'; import '../nui-icon/nui-icon.js'; import { html, nothing, type TemplateResult } from 'lit'; import type { NuiType } from '../../types/nui-type.js'; import { isPanelOpen } from './accordion-value.js'; import type { AccordionPanel, AccordionValue } from './types.js'; export interface NuiAccordionViewState { panels: AccordionPanel[]; value: AccordionValue; multiple: boolean; lazy: boolean; lazyOpened: Set; expandIcon: string; collapseIcon: string; tabindex: number; accordionClass: string; nuiType: NuiType; } export interface AccordionRenderHandlers { onHeaderClick: (panelValue: AccordionPanel['index'], event: Event) => void; onHeaderFocus: (panelValue: AccordionPanel['index'], event: Event) => void; } export function getAccordionClass(accordionClass: string): string { return ['nui-accordion', accordionClass].filter(Boolean).join(' '); } function shouldRenderPanelContent( state: NuiAccordionViewState, panelValue: AccordionPanel['index'], expanded: boolean, ): boolean { if (!state.lazy) { return true; } const key = String(panelValue); return expanded || state.lazyOpened.has(key); } export function renderAccordion( state: NuiAccordionViewState, handlers: AccordionRenderHandlers, ): TemplateResult { return html`
${state.panels.map((panel) => { const expanded = isPanelOpen(state.value, panel.index, state.multiple); const icon = expanded ? state.collapseIcon || state.expandIcon : state.expandIcon; const contentId = `accordion-content-${String(panel.index)}`; const headerId = `accordion-header-${String(panel.index)}`; const renderContent = shouldRenderPanelContent( state, panel.index, expanded, ); return html`
${ renderContent ? html`
${panel.answer}
` : nothing }
`; })}
`; }