@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
149 lines (148 loc) • 6.72 kB
TypeScript
import { ESLBaseElement } from '../../esl-base-element/core';
import type { DelegatedEvent, ESLIntersectionEvent } from '../../esl-event-listener/core';
import type { ESLAnchornavHierarchyBuilder } from './esl-anchornav.hierarchy';
/** {@link ESLAnchornav} item renderer */
export type ESLAnchornavRender = (data: ESLAnchorData, index: number, anchornav: ESLAnchornav) => string | Element;
/** {@link ESLAnchornav} anchor data interface */
export interface ESLAnchorData {
id: string;
title: string;
data: Record<string, unknown>;
$anchor: HTMLElement;
parent?: string | null;
children?: ESLAnchorData[];
}
/**
* ESLAnchornav
* @author Dmytro Shovchko
*
* ESLAnchornav is a component that collects content anchors from the page and provides anchor navigation
*/
export declare class ESLAnchornav extends ESLBaseElement {
static is: string;
static _renderers: Map<string, ESLAnchornavRender>;
static _hierarchyBuilders: Map<string, ESLAnchornavHierarchyBuilder>;
/** Gets renderer by name */
static getRenderer(name: string): ESLAnchornavRender | undefined;
/** Sets renderer */
static setRenderer(renderer: ESLAnchornavRender): void;
static setRenderer(name: string, renderer: ESLAnchornavRender): void;
/** Gets hierarchy builder by name */
static getHierarchyBuilder(name: string): ESLAnchornavHierarchyBuilder | undefined;
/** Sets hierarchy builder */
static setHierarchyBuilder(builder: ESLAnchornavHierarchyBuilder): void;
static setHierarchyBuilder(name: string, builder: ESLAnchornavHierarchyBuilder): void;
ACTIVECHANGED_EVENT: string;
UPDATED_EVENT: string;
protected INTERSECTION_THRESHOLD: number[];
/** Item renderer which is used to build inner markup */
rendererName: string;
/** CSS classes to set on active item */
activeClass: string;
/** CSS classes to set on container when there are no anchors */
emptyClass: string;
/** Selector (ESLTraversingQuery) to find the container to apply empty class marker. Defaults to the component itself */
emptyClassTarget: string;
/** Selector (ESLTraversingQuery) to find anchor elements */
anchorSelector: string;
/** Grouping mode for building hierarchy: 'level' to group by the parsed `level` value from `esl-anchor` data, empty string for flat list */
groupBy: string;
protected _active: ESLAnchorData;
protected _anchors: ESLAnchorData[];
protected _flatAnchors: ESLAnchorData[];
protected _items: Map<string, Element>;
protected _offset: number;
/** Active anchor */
get active(): ESLAnchorData;
set active(value: ESLAnchorData);
/** Indicates whether the component has no anchors to display */
get empty(): boolean;
/** Anchors list (flattened for intersection observation) */
protected get $anchors(): HTMLElement[];
/** Anchornav offset */
get offset(): number;
set offset(value: number);
/** Anchornav items container */
protected get $itemsArea(): HTMLElement;
/** Anchornav viewport (root element for IntersectionObservers checking visibility) */
protected get $viewport(): Element | undefined;
/** Permanent anchors to prepend to the list */
protected get anchorsToPrepend(): ESLAnchorData[];
/** Permanent anchors to append to the list */
protected get anchorsToAppend(): ESLAnchorData[];
/**
* Finds anchor elements.
* Uses {@link ESLTraversingQuery} syntax via {@link ESLBaseElement.$$findAll}.
*/
protected findAnchors(): HTMLElement[];
protected connectedCallback(): void;
/**
* Updates the component.
* Performs a full refresh cycle: recollects anchors list and updates the UI state.
* Use this method when the set/order of anchors may have changed.
*/
update(): void;
/** Builds the component anchors list markup */
protected rerender(): void;
/** Renders the component anchors list */
protected renderAnchors(): Element[];
/**
* Renders a single anchor item using the specified or default renderer.
* Registers the rendered element in the internal items map.
* Use this method when rendering nested items to ensure proper registration.
* @param data - anchor data to render
* @param index - anchor index (optional)
* @param renderer - custom renderer function (optional, uses rendererName by default)
* @returns rendered element
*/
renderItem(data: ESLAnchorData, index?: number, renderer?: ESLAnchornavRender): Element | undefined;
/**
* Gets anchor data from the anchor element
* If resolved data is missing required fields (e.g., id), the anchor will be ignored.
*/
protected getDataFrom($anchor: HTMLElement, index: number): ESLAnchorData | undefined;
/**
* Builds hierarchy from flat anchors list based on groupBy mode.
* Override this method to implement custom hierarchy logic.
* @param flatAnchors - flat list of anchors in DOM order
* @returns hierarchical anchors list (roots only) or flat list if groupBy is empty
*/
protected buildHierarchy(flatAnchors: ESLAnchorData[]): ESLAnchorData[];
/**
* Flattens hierarchical anchors list to a flat array in depth-first order.
* @param anchors - hierarchical anchors list
* @returns flat list of all anchors
*/
protected flattenAnchors(anchors: ESLAnchorData[]): ESLAnchorData[];
/** Gets initial active anchor */
protected getInitialActive(): ESLAnchorData;
/** Updates the active anchor */
protected updateActiveAnchor(): void;
/**
* Updates active classes on navigation items.
* Resets all active classes and sets the active class on the current item.
* Override this method to implement custom active state logic (e.g., parent activation).
* @param active - the active anchor
*/
protected updateActiveClasses(active: ESLAnchorData): void;
/**
* Updates the container state based on whether anchors are present.
* Sets the `empty` attribute on the component and applies `emptyClass` to the target element.
*/
protected updateContainer(): void;
/** Handles changing the active anchor */
protected _onActiveChange(): void;
/** Handles updating the component */
protected _onUpdateEvent(): void;
protected _onAnchornavRequest(): void;
protected _onAnchorIntersection(e: ESLIntersectionEvent): void;
protected _onAnchorClick(event: DelegatedEvent<MouseEvent>): void;
}
declare global {
export interface ESLLibrary {
Anchornav: typeof ESLAnchornav;
}
export interface HTMLElementTagNameMap {
'esl-anchornav': ESLAnchornav;
}
}