365 lines
15 KiB
TypeScript
365 lines
15 KiB
TypeScript
/**
|
|
* Based on Radix UI's Navigation Menu
|
|
* https://www.radix-ui.com/docs/primitives/components/navigation-menu
|
|
*/
|
|
import { type AnyFn, type ReadableBox, type ReadableBoxedValues, type WithRefProps, type WritableBox, type WritableBoxedValues, DOMContext } from "svelte-toolbelt";
|
|
import { Context } from "runed";
|
|
import { type Snippet } from "svelte";
|
|
import { SvelteMap } from "svelte/reactivity";
|
|
import { type Direction, type Orientation } from "../../shared/index.js";
|
|
import type { BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, RefAttachment } from "../../internal/types.js";
|
|
import type { FocusEventHandler, KeyboardEventHandler, MouseEventHandler, PointerEventHandler } from "svelte/elements";
|
|
import { RovingFocusGroup } from "../../internal/roving-focus-group.js";
|
|
export declare const NavigationMenuItemContext: Context<NavigationMenuItemState>;
|
|
interface NavigationMenuProviderStateOpts extends ReadableBoxedValues<{
|
|
dir: Direction;
|
|
orientation: Orientation;
|
|
}>, WritableBoxedValues<{
|
|
rootNavigationMenuRef: HTMLElement | null;
|
|
value: string;
|
|
previousValue: string;
|
|
}> {
|
|
isRootMenu: boolean;
|
|
onTriggerEnter: (itemValue: string, itemState: NavigationMenuItemState | null) => void;
|
|
onTriggerLeave?: () => void;
|
|
onContentEnter?: () => void;
|
|
onContentLeave?: () => void;
|
|
onItemSelect: (itemValue: string, itemState: NavigationMenuItemState | null) => void;
|
|
onItemDismiss: () => void;
|
|
}
|
|
declare class NavigationMenuProviderState {
|
|
static create(opts: NavigationMenuProviderStateOpts): NavigationMenuProviderState;
|
|
readonly opts: NavigationMenuProviderStateOpts;
|
|
indicatorTrackRef: WritableBox<HTMLElement | null>;
|
|
viewportRef: WritableBox<HTMLElement | null>;
|
|
viewportContent: SvelteMap<string, NavigationMenuItemState>;
|
|
onTriggerEnter: NavigationMenuProviderStateOpts["onTriggerEnter"];
|
|
onTriggerLeave: () => void;
|
|
onContentEnter: () => void;
|
|
onContentLeave: () => void;
|
|
onItemSelect: NavigationMenuProviderStateOpts["onItemSelect"];
|
|
onItemDismiss: NavigationMenuProviderStateOpts["onItemDismiss"];
|
|
activeItem: NavigationMenuItemState | null;
|
|
prevActiveItem: NavigationMenuItemState | null;
|
|
constructor(opts: NavigationMenuProviderStateOpts);
|
|
setActiveItem: (item: NavigationMenuItemState | null) => void;
|
|
}
|
|
interface NavigationMenuRootStateOpts extends WithRefProps, WritableBoxedValues<{
|
|
value: string;
|
|
}>, ReadableBoxedValues<{
|
|
dir: Direction;
|
|
orientation: Orientation;
|
|
delayDuration: number;
|
|
skipDelayDuration: number;
|
|
}> {
|
|
}
|
|
export declare class NavigationMenuRootState {
|
|
#private;
|
|
static create(opts: NavigationMenuRootStateOpts): NavigationMenuRootState;
|
|
readonly opts: NavigationMenuRootStateOpts;
|
|
readonly attachment: RefAttachment;
|
|
provider: NavigationMenuProviderState;
|
|
previousValue: WritableBox<string>;
|
|
isDelaySkipped: WritableBox<boolean>;
|
|
constructor(opts: NavigationMenuRootStateOpts);
|
|
setValue: (newValue: string, itemState: NavigationMenuItemState | null) => void;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-orientation": Orientation;
|
|
readonly dir: Direction;
|
|
};
|
|
}
|
|
interface NavigationMenuSubStateOpts extends WithRefProps, WritableBoxedValues<{
|
|
value: string;
|
|
}>, ReadableBoxedValues<{
|
|
orientation: Orientation;
|
|
}> {
|
|
}
|
|
export declare class NavigationMenuSubState {
|
|
static create(opts: NavigationMenuSubStateOpts): NavigationMenuSubState;
|
|
readonly opts: NavigationMenuSubStateOpts;
|
|
readonly context: NavigationMenuProviderState;
|
|
previousValue: WritableBox<string>;
|
|
readonly subProvider: NavigationMenuProviderState;
|
|
readonly attachment: RefAttachment;
|
|
constructor(opts: NavigationMenuSubStateOpts, context: NavigationMenuProviderState);
|
|
setValue: (newValue: string, itemState: NavigationMenuItemState | null) => void;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-orientation": Orientation;
|
|
};
|
|
}
|
|
interface NavigationMenuListStateOpts extends WithRefProps {
|
|
}
|
|
export declare class NavigationMenuListState {
|
|
static create(opts: NavigationMenuListStateOpts): NavigationMenuListState;
|
|
wrapperId: WritableBox<string>;
|
|
wrapperRef: WritableBox<HTMLElement | null>;
|
|
readonly opts: NavigationMenuListStateOpts;
|
|
readonly context: NavigationMenuProviderState;
|
|
readonly attachment: RefAttachment;
|
|
readonly wrapperAttachment: RefAttachment;
|
|
listTriggers: HTMLElement[];
|
|
readonly rovingFocusGroup: RovingFocusGroup;
|
|
wrapperMounted: boolean;
|
|
constructor(opts: NavigationMenuListStateOpts, context: NavigationMenuProviderState);
|
|
registerTrigger(trigger: HTMLElement | null): () => void;
|
|
readonly wrapperProps: {
|
|
readonly id: string;
|
|
};
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-orientation": Orientation;
|
|
};
|
|
}
|
|
interface NavigationMenuItemStateOpts extends WithRefProps, ReadableBoxedValues<{
|
|
value: string;
|
|
openOnHover: boolean;
|
|
}> {
|
|
}
|
|
export declare class NavigationMenuItemState {
|
|
#private;
|
|
static create(opts: NavigationMenuItemStateOpts): NavigationMenuItemState;
|
|
readonly opts: NavigationMenuItemStateOpts;
|
|
readonly attachment: RefAttachment;
|
|
readonly listContext: NavigationMenuListState;
|
|
contentNode: HTMLElement | null;
|
|
triggerNode: HTMLElement | null;
|
|
focusProxyNode: HTMLElement | null;
|
|
restoreContentTabOrder: AnyFn;
|
|
wasEscapeClose: boolean;
|
|
readonly contentId: string | undefined;
|
|
readonly triggerId: string | undefined;
|
|
contentChildren: ReadableBox<Snippet | undefined>;
|
|
contentChild: ReadableBox<Snippet<[{
|
|
props: Record<string, unknown>;
|
|
}]> | undefined>;
|
|
contentProps: ReadableBox<Record<string, unknown>>;
|
|
domContext: DOMContext;
|
|
constructor(opts: NavigationMenuItemStateOpts, listContext: NavigationMenuListState);
|
|
onEntryKeydown: (side?: "start" | "end") => void;
|
|
onFocusProxyEnter: (side?: "start" | "end") => void;
|
|
onRootContentClose: () => void;
|
|
onContentFocusOutside: () => void;
|
|
props: {
|
|
readonly id: string;
|
|
};
|
|
}
|
|
interface NavigationMenuTriggerStateOpts extends WithRefProps, ReadableBoxedValues<{
|
|
disabled: boolean | null | undefined;
|
|
}> {
|
|
}
|
|
export declare class NavigationMenuTriggerState {
|
|
static create(opts: NavigationMenuTriggerStateOpts): NavigationMenuTriggerState;
|
|
readonly opts: NavigationMenuTriggerStateOpts;
|
|
readonly attachment: RefAttachment;
|
|
focusProxyId: WritableBox<string>;
|
|
focusProxyRef: WritableBox<HTMLElement | null>;
|
|
readonly focusProxyAttachment: RefAttachment;
|
|
context: NavigationMenuProviderState;
|
|
itemContext: NavigationMenuItemState;
|
|
listContext: NavigationMenuListState;
|
|
hasPointerMoveOpened: WritableBox<boolean>;
|
|
wasClickClose: boolean;
|
|
focusProxyMounted: boolean;
|
|
readonly open: boolean;
|
|
constructor(opts: NavigationMenuTriggerStateOpts, context: {
|
|
provider: NavigationMenuProviderState;
|
|
item: NavigationMenuItemState;
|
|
list: NavigationMenuListState;
|
|
sub: NavigationMenuSubState | null;
|
|
});
|
|
onpointerenter: (_: BitsPointerEvent<HTMLButtonElement>) => void;
|
|
onpointermove: PointerEventHandler<HTMLElement>;
|
|
onpointerleave: PointerEventHandler<HTMLElement>;
|
|
onclick: MouseEventHandler<HTMLButtonElement>;
|
|
onkeydown: KeyboardEventHandler<HTMLButtonElement>;
|
|
focusProxyOnFocus: FocusEventHandler<HTMLElement>;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly disabled: boolean | null | undefined;
|
|
readonly "data-disabled": "" | undefined;
|
|
readonly "data-state": "open" | "closed";
|
|
readonly "data-value": string;
|
|
readonly "aria-expanded": "true" | "false";
|
|
readonly "aria-controls": string | undefined;
|
|
readonly onpointermove: PointerEventHandler<HTMLElement>;
|
|
readonly onpointerleave: PointerEventHandler<HTMLElement>;
|
|
readonly onpointerenter: (_: BitsPointerEvent<HTMLButtonElement>) => void;
|
|
readonly onclick: MouseEventHandler<HTMLButtonElement>;
|
|
readonly onkeydown: KeyboardEventHandler<HTMLButtonElement>;
|
|
};
|
|
readonly focusProxyProps: {
|
|
readonly id: string;
|
|
readonly tabindex: 0;
|
|
readonly onfocus: FocusEventHandler<HTMLElement>;
|
|
};
|
|
}
|
|
interface NavigationMenuLinkStateOpts extends WithRefProps, ReadableBoxedValues<{
|
|
active: boolean;
|
|
onSelect: (e: Event) => void;
|
|
}> {
|
|
}
|
|
export declare class NavigationMenuLinkState {
|
|
#private;
|
|
static create(opts: NavigationMenuLinkStateOpts): NavigationMenuLinkState;
|
|
readonly opts: NavigationMenuLinkStateOpts;
|
|
readonly context: {
|
|
provider: NavigationMenuProviderState;
|
|
item: NavigationMenuItemState;
|
|
};
|
|
readonly attachment: RefAttachment;
|
|
isFocused: boolean;
|
|
constructor(opts: NavigationMenuLinkStateOpts, context: {
|
|
provider: NavigationMenuProviderState;
|
|
item: NavigationMenuItemState;
|
|
});
|
|
onclick: (e: BitsMouseEvent<HTMLAnchorElement>) => void;
|
|
onkeydown: (e: BitsKeyboardEvent) => void;
|
|
onfocus: (_: BitsFocusEvent) => void;
|
|
onblur: (_: BitsFocusEvent) => void;
|
|
onpointerenter: PointerEventHandler<HTMLAnchorElement>;
|
|
onpointermove: PointerEventHandler<HTMLElement>;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-active": "" | undefined;
|
|
readonly "aria-current": "page" | undefined;
|
|
readonly "data-focused": "" | undefined;
|
|
readonly onclick: (e: BitsMouseEvent<HTMLAnchorElement>) => void;
|
|
readonly onkeydown: (e: BitsKeyboardEvent) => void;
|
|
readonly onfocus: (_: BitsFocusEvent) => void;
|
|
readonly onblur: (_: BitsFocusEvent) => void;
|
|
readonly onpointerenter: PointerEventHandler<HTMLAnchorElement>;
|
|
readonly onpointermove: PointerEventHandler<HTMLElement>;
|
|
};
|
|
}
|
|
interface NavigationMenuIndicatorStateOpts extends WithRefProps {
|
|
}
|
|
export declare class NavigationMenuIndicatorState {
|
|
static create(): NavigationMenuIndicatorState;
|
|
readonly context: NavigationMenuProviderState;
|
|
readonly isVisible: boolean;
|
|
constructor(context: NavigationMenuProviderState);
|
|
}
|
|
export declare class NavigationMenuIndicatorImplState {
|
|
static create(opts: NavigationMenuIndicatorStateOpts): NavigationMenuIndicatorImplState;
|
|
readonly opts: NavigationMenuIndicatorStateOpts;
|
|
readonly attachment: RefAttachment;
|
|
context: NavigationMenuProviderState;
|
|
listContext: NavigationMenuListState;
|
|
position: {
|
|
size: number;
|
|
offset: number;
|
|
} | null;
|
|
readonly isHorizontal: boolean;
|
|
readonly isVisible: boolean;
|
|
readonly activeTrigger: HTMLElement | null;
|
|
readonly shouldRender: boolean;
|
|
constructor(opts: NavigationMenuIndicatorStateOpts, context: {
|
|
provider: NavigationMenuProviderState;
|
|
list: NavigationMenuListState;
|
|
});
|
|
handlePositionChange: () => void;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-state": "hidden" | "visible";
|
|
readonly "data-orientation": Orientation;
|
|
readonly style: {
|
|
readonly left: number;
|
|
readonly width: string;
|
|
readonly transform: string;
|
|
readonly position: "absolute";
|
|
} | {
|
|
readonly top: number;
|
|
readonly height: string;
|
|
readonly transform: string;
|
|
readonly position: "absolute";
|
|
};
|
|
};
|
|
}
|
|
interface NavigationMenuContentStateOpts extends WithRefProps {
|
|
}
|
|
export declare class NavigationMenuContentState {
|
|
static create(opts: NavigationMenuContentStateOpts): NavigationMenuContentState;
|
|
readonly opts: NavigationMenuContentStateOpts;
|
|
readonly context: NavigationMenuProviderState;
|
|
readonly itemContext: NavigationMenuItemState;
|
|
readonly listContext: NavigationMenuListState;
|
|
readonly attachment: RefAttachment;
|
|
mounted: boolean;
|
|
readonly open: boolean;
|
|
readonly value: string;
|
|
readonly isLastActiveValue: boolean;
|
|
constructor(opts: NavigationMenuContentStateOpts, context: {
|
|
provider: NavigationMenuProviderState;
|
|
item: NavigationMenuItemState;
|
|
list: NavigationMenuListState;
|
|
});
|
|
onpointerenter: (_: BitsPointerEvent) => void;
|
|
onpointerleave: PointerEventHandler<HTMLElement>;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly onpointerenter: (_: BitsPointerEvent) => void;
|
|
readonly onpointerleave: PointerEventHandler<HTMLElement>;
|
|
};
|
|
}
|
|
type MotionAttribute = "to-start" | "to-end" | "from-start" | "from-end";
|
|
interface NavigationMenuContentImplStateOpts extends WithRefProps {
|
|
}
|
|
export declare class NavigationMenuContentImplState {
|
|
static create(opts: NavigationMenuContentImplStateOpts, itemState?: NavigationMenuItemState): NavigationMenuContentImplState;
|
|
readonly opts: NavigationMenuContentImplStateOpts;
|
|
readonly itemContext: NavigationMenuItemState;
|
|
readonly context: NavigationMenuProviderState;
|
|
readonly listContext: NavigationMenuListState;
|
|
readonly attachment: RefAttachment;
|
|
prevMotionAttribute: MotionAttribute | null;
|
|
readonly motionAttribute: MotionAttribute | null;
|
|
domContext: DOMContext;
|
|
constructor(opts: NavigationMenuContentImplStateOpts, itemContext: NavigationMenuItemState);
|
|
onFocusOutside: (e: Event) => void;
|
|
onInteractOutside: (e: PointerEvent) => void;
|
|
onkeydown: (e: BitsKeyboardEvent) => void;
|
|
onEscapeKeydown: (_: KeyboardEvent) => void;
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "aria-labelledby": string | undefined;
|
|
readonly "data-motion": MotionAttribute | undefined;
|
|
readonly "data-orientation": Orientation;
|
|
readonly "data-state": "open" | "closed";
|
|
readonly onkeydown: (e: BitsKeyboardEvent) => void;
|
|
};
|
|
}
|
|
interface NavigationMenuViewportStateOpts extends WithRefProps {
|
|
}
|
|
export declare class NavigationMenuViewportState {
|
|
static create(opts: NavigationMenuViewportStateOpts): NavigationMenuViewportState;
|
|
readonly opts: NavigationMenuViewportStateOpts;
|
|
readonly context: NavigationMenuProviderState;
|
|
readonly attachment: RefAttachment;
|
|
readonly open: boolean;
|
|
readonly viewportWidth: string | undefined;
|
|
readonly viewportHeight: string | undefined;
|
|
readonly activeContentValue: string;
|
|
size: {
|
|
width: number;
|
|
height: number;
|
|
} | null;
|
|
contentNode: HTMLElement | null;
|
|
mounted: boolean;
|
|
constructor(opts: NavigationMenuViewportStateOpts, context: NavigationMenuProviderState);
|
|
readonly props: {
|
|
readonly id: string;
|
|
readonly "data-state": "open" | "closed";
|
|
readonly "data-orientation": Orientation;
|
|
readonly style: {
|
|
readonly pointerEvents: "none" | undefined;
|
|
readonly "--bits-navigation-menu-viewport-width": string | undefined;
|
|
readonly "--bits-navigation-menu-viewport-height": string | undefined;
|
|
};
|
|
readonly onpointerenter: () => void;
|
|
readonly onpointerleave: () => void;
|
|
};
|
|
}
|
|
export {};
|