A comprehensive DOM manipulation library providing type-safe, functional utilities for elements, events, properties, and selections.
npx @tessl/cli install tessl/npm-ephox--sugar@9.3.0@ephox/sugar is a comprehensive DOM manipulation library that provides a type-safe, functional API for working with DOM elements, events, properties, and selections. Built around the core SugarElement<T> wrapper type, it offers 150+ utility functions organized into 8 distinct packages for modular DOM operations.
npm install @ephox/sugarimport {
SugarElement,
Insert, Remove, Focus,
DomEvent, Class, Css,
Traverse, Selectors,
SimSelection, WindowSelection
} from "@ephox/sugar";For CommonJS:
const {
SugarElement,
Insert, Remove, Focus,
DomEvent, Class, Css
} = require("@ephox/sugar");import { SugarElement, Insert, Class, DomEvent } from "@ephox/sugar";
// Create elements
const container = SugarElement.fromTag('div');
const button = SugarElement.fromTag('button');
// Manipulate DOM
Insert.append(container, button);
Class.add(button, 'primary-btn');
// Handle events
const unbind = DomEvent.bind(button, 'click', (evt) => {
console.log('Button clicked!');
evt.prevent(); // Prevent default
});
// Access native DOM when needed
const nativeDiv = container.dom; // HTMLDivElement@ephox/sugar is built around several key architectural principles:
SugarElement<T> which wraps native DOM nodes while preserving type informationOptional<T>Core DOM operations including insertion, removal, cloning, and structural modifications. Provides type-safe alternatives to native DOM manipulation.
// Insert operations
function append(parent: SugarElement<Node>, element: SugarElement<Node>): void;
function prepend(parent: SugarElement<Node>, element: SugarElement<Node>): void;
function before(marker: SugarElement<Node>, element: SugarElement<Node>): void;
function after(marker: SugarElement<Node>, element: SugarElement<Node>): void;
// Remove operations
function remove(element: SugarElement<Node>): void;
function empty(element: SugarElement<Node>): void;
function unwrap(wrapper: SugarElement<Node>): void;Comprehensive event management with type-safe event binding, custom event objects, and specialized mouse/keyboard event handling.
interface EventArgs<E = Event, T extends Node | Window = Node> {
readonly target: SugarElement<T>;
readonly x: E extends { clientX: number } ? number : undefined;
readonly y: E extends { clientY: number } ? number : undefined;
readonly stop: () => void;
readonly prevent: () => void;
readonly kill: () => void;
readonly raw: E;
}
type EventHandler<E = Event, T extends Node | Window = Node> = (evt: EventArgs<E, T>) => void;
function bind<K extends keyof HTMLElementEventMap>(
element: SugarElement<EventTarget>,
event: K,
handler: EventHandler<HTMLElementEventMap[K]>
): EventUnbinder;Element creation, type checking, and node manipulation utilities. Includes factory methods and type guards for working with different node types.
interface SugarElement<T = any> {
readonly dom: T;
}
// Factory methods
function fromTag<K extends keyof HTMLElementFullTagNameMap>(
tag: K,
scope?: Document | null
): SugarElement<HTMLElementFullTagNameMap[K]>;
function fromHtml<E extends Node = Node & ChildNode>(
html: string,
scope?: Document | null
): SugarElement<E>;
function fromText(text: string, scope?: Document | null): SugarElement<Text>;
function fromDom<T extends Node | Window>(node: T): SugarElement<T>;
function fromPoint(docElm: SugarElement<Document>, x: number, y: number): Optional<SugarElement<Element>>;
// Type guards
function isElement(element: SugarElement<Node>): element is SugarElement<Element>;
function isText(element: SugarElement<Node>): element is SugarElement<Text>;CSS styling, HTML attributes, and class management with type-safe property operations and computed style access.
// CSS operations
function set(element: SugarElement<Node>, property: string, value: string): void;
function get(element: SugarElement<Element>, property: string): string;
function remove(element: SugarElement<Node>, property: string): void;
// Class operations
function add(element: SugarElement<Element>, clazz: string): void;
function remove(element: SugarElement<Element>, clazz: string): void;
function toggle(element: SugarElement<Element>, clazz: string): boolean;
// Attribute operations
function set(element: SugarElement<Element>, key: string, value: string | boolean | number): void;
function get(element: SugarElement<Element>, key: string): undefined | string;Tree traversal, element querying, and hierarchical navigation with type-safe parent/child relationships and CSS selector support.
// Traversal operations
function parent(element: SugarElement<Node>): Optional<SugarElement<Node & ParentNode>>;
function children(element: SugarElement<Node>): SugarElement<Node & ChildNode>[];
function siblings(element: SugarElement<Node>): SugarElement<Node>[];
function nextSibling(element: SugarElement<Node>): Optional<SugarElement<Node & ChildNode>>;
// Search operations
function ancestor(element: SugarElement<Node>, predicate: (e: SugarElement<Node>) => boolean): Optional<SugarElement<Node>>;
function descendant(scope: SugarElement<Node>, predicate: (e: SugarElement<Node>) => boolean): Optional<SugarElement<Node>>;Text selection, range management, and cursor positioning with cross-browser selection handling and position calculations.
interface SimRange {
readonly start: SugarElement<Node>;
readonly soffset: number;
readonly finish: SugarElement<Node>;
readonly foffset: number;
}
interface SimSelection {
fold: <U>(
domRange: (rng: Range) => U,
relative: (startSitu: Situ, finishSitu: Situ) => U,
exact: (start: SugarElement<Node>, soffset: number, finish: SugarElement<Node>, foffset: number) => U
) => U;
}
// Selection operations
function get(win: SugarElement<Window>): Optional<SimSelection>;
function set(win: SugarElement<Window>, selection: SimSelection): void;Utilities for working with specific HTML elements like select, option, and form controls with type-safe accessors.
// Option element utilities
function getValue(element: SugarElement<HTMLOptionElement>): string;
function isSelected(element: SugarElement<HTMLOptionElement>): boolean;
function setSelected(element: SugarElement<HTMLOptionElement>, state: boolean): void;
// Select element utilities
function getValue(element: SugarElement<HTMLSelectElement>): string;
function setValue(element: SugarElement<HTMLSelectElement>, value: string): void;Viewport calculations, element dimensions, scroll position management, and coordinate system utilities for responsive layouts.
interface SugarPosition {
readonly left: number;
readonly top: number;
readonly translate: (x: number, y: number) => SugarPosition;
}
// Dimension operations
function getInner(element: SugarElement<HTMLElement>): number;
function getOuter(element: SugarElement<HTMLElement>): number;
// Position operations
function absolute(element: SugarElement<HTMLElement>): SugarPosition;
function relative(element: SugarElement<HTMLElement>, target: SugarElement<HTMLElement>): SugarPosition;// Primary wrapper interface
interface SugarElement<T = any> {
readonly dom: T;
}
// Event system types
interface EventUnbinder {
unbind: () => void;
}
type EventHandler<E = Event, T extends Node | Window = Node> = (evt: EventArgs<E, T>) => void;
// Optional type from @ephox/katamari
interface Optional<T> {
isSome(): boolean;
isNone(): boolean;
getOr<U>(def: U): T | U;
map<U>(f: (t: T) => U): Optional<U>;
bind<U>(f: (t: T) => Optional<U>): Optional<U>;
}
// Root node type for Shadow DOM support
type RootNode = SugarElement<Document | ShadowRoot>;