API REFERENCE · UTILITIES
@dojo-ng/dojo-element
The base class for every Dojo NG component, plus shared helpers for building your own.
npm install @dojo-ng/dojo-element
Extend the base class, emit events with emit(), and register the tag with define().
import DojoElement from "@dojo-ng/dojo-element";
import { html } from "lit";
export class MyGreeting extends DojoElement {
static properties = { name: {} };
render() {
return html`<button @click=${() => this.emit("my-greet", { detail: { name: this.name } })}>
Hello, ${this.name}
</button>`;
}
}
MyGreeting.define("my-greeting");
DojoElement
- It extends
LitElement. Import it as the default export. emit(name, options)dispatches aCustomEventthat bubbles and crosses shadow boundaries (composed) by default.static define(tag)registers the element. Registering the same tag again does nothing. If the versions differ, it logs a warning instead of throwing an error.static dependencieslists child elements to register when the element is created.
Form controls
FormControl(DojoElement)is a mixin for form-associated controls.- A control inside a disabled
<fieldset>or form is disabled too. - State is restored after back and forward navigation and after autofill.
- Validity is mirrored onto the host as
data-dj-required,data-dj-valid,data-dj-invalid,data-dj-user-valid, anddata-dj-user-invalid. Theuser-states turn on only after the user has interacted with the control.
Helpers
- Focus:
trapTabKey,collectFocusables,firstFocusable,isFocusable,deepActiveElement,isFocusWithin, anddismissOnFocusOut. lockBodyScroll()stops the page from scrolling behind a modal and returns a function that unlocks it. Nested locks are counted.TokenFlagControllerreads a true or false flag from a--dj-*custom property. The value1means true.baseStylesandreducedMotionare shared styles for component shadow roots.
Examples
Style invalid fields
Form controls mirror their validity onto the host, so page CSS can react to it. Here a hint turns red after the user leaves the field invalid.
<style>
.field:has(dj-text-input[data-dj-user-invalid]) .hint {
color: var(--dj-color-danger-600);
}
</style>
<div class="field">
<dj-text-input label="Email" type="email" required></dj-text-input>
<p class="hint">Enter an address like name@example.com.</p>
</div>
Functions
collectFocusables
function collectFocusables(shadowRoot: ShadowRoot, host: HTMLElement): HTMLElement[];
deepActiveElement
function deepActiveElement(): Element | null;
dismissOnFocusOut
function dismissOnFocusOut(host: HTMLElement, onLeave: () => void): () => void;
firstFocusable
function firstFocusable(root: ParentNode): HTMLElement | null;
FormControl
function FormControl<T extends Constructor<DojoElement>>(Base: T): T & Constructor<FormControlMixinInterface>;
isFocusable
function isFocusable(el: Element): boolean;
isFocusWithin
function isFocusWithin(host: Element): boolean;
lockBodyScroll
function lockBodyScroll(): () => void;
trapTabKey
function trapTabKey(event: KeyboardEvent, focusables: HTMLElement[]): void;
Classes
TokenFlagController
class TokenFlagController implements ReactiveController {
value: boolean;
constructor(host: ReactiveControllerHost & HTMLElement, property: string);
hostConnected(): void;
hostDisconnected(): void;
refresh(): void;
}
Values
FOCUSABLE_SELECTOR
const FOCUSABLE_SELECTOR = "a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])";
NATIVE_FOCUSABLE_SELECTOR
const NATIVE_FOCUSABLE_SELECTOR = "a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])";
reducedMotion
const reducedMotion: import("lit").CSSResult;
Types
DojoFormControl
interface DojoFormControl extends DojoElement {
name: string;
value: unknown;
disabled?: boolean;
defaultValue?: unknown;
defaultChecked?: boolean;
form?: string;
pattern?: string;
min?: number | string | Date;
max?: number | string | Date;
step?: number | string | "any";
required?: boolean;
minlength?: number;
maxlength?: number;
readonly validity: ValidityState;
readonly validationMessage: string;
checkValidity: () => boolean;
getForm: () => HTMLFormElement | null;
reportValidity: () => boolean;
setCustomValidity: (message: string) => void;
}
FormControlMixinInterface
interface FormControlMixinInterface {
formDisabled: boolean;
readonly isDisabled: boolean;
formDisabledCallback(disabled: boolean): void;
formStateRestoreCallback(state: FormRestoreState, mode: string): void;
restoreFormState(state: FormRestoreState): void;
readonly validity: ValidityState | undefined;
readonly validationMessage: string;
checkValidity(): boolean;
reportValidity(): boolean;
}
FormRestoreState
type FormRestoreState = File | string | FormData | null;