bits-ui
Version:
The headless components for Svelte.
339 lines (338 loc) • 12.7 kB
TypeScript
/**
* This logic is adapted from Radix UI ScrollArea component.
* https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/src/ScrollArea.tsx
* Credit to Jenna Smith (@jjenzz) for the original implementation.
* Incredible thought must have went into solving all the intricacies of this component.
*/
import { Context } from "runed";
import { DOMContext, type ReadableBoxedValues } from "svelte-toolbelt";
import type { ScrollAreaType } from "./types.js";
import type { BitsPointerEvent, RefAttachment, WithRefOpts } from "../../internal/types.js";
import { type Direction, type Orientation } from "../../shared/index.js";
import { StateMachine } from "../../internal/state-machine.js";
export declare const ScrollAreaRootContext: Context<ScrollAreaRootState>;
export declare const ScrollAreaScrollbarContext: Context<ScrollAreaScrollbarState>;
export declare const ScrollAreaScrollbarVisibleContext: Context<ScrollAreaScrollbarVisibleState>;
export declare const ScrollAreaScrollbarAxisContext: Context<ScrollbarAxis>;
export declare const ScrollAreaScrollbarSharedContext: Context<ScrollAreaScrollbarSharedState>;
interface Sizes {
content: number;
viewport: number;
scrollbar: {
size: number;
paddingStart: number;
paddingEnd: number;
};
}
interface ScrollAreaRootStateOpts extends WithRefOpts, ReadableBoxedValues<{
dir: Direction;
type: ScrollAreaType;
scrollHideDelay: number;
}> {
}
export declare class ScrollAreaRootState {
static create(opts: ScrollAreaRootStateOpts): ScrollAreaRootState;
readonly opts: ScrollAreaRootStateOpts;
readonly attachment: RefAttachment;
scrollAreaNode: HTMLElement | null;
viewportNode: HTMLElement | null;
contentNode: HTMLElement | null;
scrollbarXNode: HTMLElement | null;
scrollbarYNode: HTMLElement | null;
cornerWidth: number;
cornerHeight: number;
scrollbarXEnabled: boolean;
scrollbarYEnabled: boolean;
domContext: DOMContext;
constructor(opts: ScrollAreaRootStateOpts);
readonly props: {
readonly id: string;
readonly dir: Direction;
readonly style: {
readonly position: "relative";
readonly "--bits-scroll-area-corner-height": `${number}px`;
readonly "--bits-scroll-area-corner-width": `${number}px`;
};
};
}
interface ScrollAreaViewportStateOpts extends WithRefOpts {
}
export declare class ScrollAreaViewportState {
#private;
static create(opts: ScrollAreaViewportStateOpts): ScrollAreaViewportState;
readonly opts: ScrollAreaViewportStateOpts;
readonly root: ScrollAreaRootState;
readonly attachment: RefAttachment;
readonly contentAttachment: RefAttachment;
constructor(opts: ScrollAreaViewportStateOpts, root: ScrollAreaRootState);
readonly props: {
readonly id: string;
readonly style: {
readonly overflowX: "hidden" | "scroll";
readonly overflowY: "hidden" | "scroll";
};
};
readonly contentProps: {
readonly id: string;
readonly "data-scroll-area-content": "";
/**
* When horizontal scrollbar is visible: this element should be at least
* as wide as its children for size calculations to work correctly.
*
* When horizontal scrollbar is NOT visible: this element's width should
* be constrained by the parent container to enable `text-overflow: ellipsis`
*/
readonly style: {
readonly minWidth: "fit-content" | undefined;
};
};
}
interface ScrollAreaScrollbarStateOpts extends WithRefOpts, ReadableBoxedValues<{
orientation: Orientation;
}> {
}
export declare class ScrollAreaScrollbarState {
static create(opts: ScrollAreaScrollbarStateOpts): ScrollAreaScrollbarState;
readonly opts: ScrollAreaScrollbarStateOpts;
readonly root: ScrollAreaRootState;
readonly isHorizontal: boolean;
hasThumb: boolean;
constructor(opts: ScrollAreaScrollbarStateOpts, root: ScrollAreaRootState);
}
export declare class ScrollAreaScrollbarHoverState {
static create(): ScrollAreaScrollbarHoverState;
readonly scrollbar: ScrollAreaScrollbarState;
root: ScrollAreaRootState;
isVisible: boolean;
constructor(scrollbar: ScrollAreaScrollbarState);
readonly props: {
readonly "data-state": "hidden" | "visible";
};
}
export declare class ScrollAreaScrollbarScrollState {
static create(): ScrollAreaScrollbarScrollState;
readonly scrollbar: ScrollAreaScrollbarState;
readonly root: ScrollAreaRootState;
readonly machine: StateMachine<{
hidden: {
SCROLL: "scrolling";
};
scrolling: {
SCROLL_END: "idle";
POINTER_ENTER: "interacting";
};
interacting: {
SCROLL: "interacting";
POINTER_LEAVE: "idle";
};
idle: {
HIDE: "hidden";
SCROLL: "scrolling";
POINTER_ENTER: "interacting";
};
}>;
readonly isHidden: boolean;
constructor(scrollbar: ScrollAreaScrollbarState);
onpointerenter(_: BitsPointerEvent): void;
onpointerleave(_: BitsPointerEvent): void;
readonly props: {
readonly "data-state": "hidden" | "visible";
readonly onpointerenter: (_: BitsPointerEvent) => void;
readonly onpointerleave: (_: BitsPointerEvent) => void;
};
}
export declare class ScrollAreaScrollbarAutoState {
static create(): ScrollAreaScrollbarAutoState;
readonly scrollbar: ScrollAreaScrollbarState;
readonly root: ScrollAreaRootState;
isVisible: boolean;
constructor(scrollbar: ScrollAreaScrollbarState);
readonly props: {
readonly "data-state": "hidden" | "visible";
};
}
export declare class ScrollAreaScrollbarVisibleState {
static create(): ScrollAreaScrollbarVisibleState;
readonly scrollbar: ScrollAreaScrollbarState;
readonly root: ScrollAreaRootState;
thumbNode: HTMLElement | null;
pointerOffset: number;
sizes: Sizes;
readonly thumbRatio: number;
readonly hasThumb: boolean;
prevTransformStyle: string;
constructor(scrollbar: ScrollAreaScrollbarState);
setSizes(sizes: Sizes): void;
getScrollPosition(pointerPos: number, dir?: Direction): number;
onThumbPointerUp(): void;
onThumbPointerDown(pointerPos: number): void;
xOnThumbPositionChange(): void;
xOnWheelScroll(scrollPos: number): void;
xOnDragScroll(pointerPos: number): void;
yOnThumbPositionChange(): void;
yOnWheelScroll(scrollPos: number): void;
yOnDragScroll(pointerPos: number): void;
}
interface ScrollbarAxisStateOpts extends ReadableBoxedValues<{
mounted: boolean;
}> {
}
interface ScrollbarAxisState {
onThumbPointerDown: (pointerPos: {
x: number;
y: number;
}) => void;
onDragScroll: (pointerPos: {
x: number;
y: number;
}) => void;
onWheelScroll: (e: WheelEvent, maxScrollPos: number) => void;
onResize: () => void;
onThumbPositionChange: () => void;
onThumbPointerUp: () => void;
props: {
id: string;
"data-orientation": "horizontal" | "vertical";
style: Record<string, string | number | undefined>;
};
}
export declare class ScrollAreaScrollbarXState implements ScrollbarAxisState {
static create(opts: ScrollbarAxisStateOpts): ScrollbarAxis;
readonly opts: ScrollbarAxisStateOpts;
readonly scrollbarVis: ScrollAreaScrollbarVisibleState;
readonly root: ScrollAreaRootState;
readonly scrollbar: ScrollAreaScrollbarState;
readonly attachment: RefAttachment;
computedStyle: CSSStyleDeclaration | undefined;
constructor(opts: ScrollbarAxisStateOpts, scrollbarVis: ScrollAreaScrollbarVisibleState);
onThumbPointerDown: (pointerPos: {
x: number;
y: number;
}) => void;
onDragScroll: (pointerPos: {
x: number;
y: number;
}) => void;
onThumbPointerUp: () => void;
onThumbPositionChange: () => void;
onWheelScroll: (e: WheelEvent, maxScrollPos: number) => void;
onResize: () => void;
readonly thumbSize: number;
readonly props: {
readonly id: string;
readonly "data-orientation": "horizontal";
readonly style: {
readonly bottom: 0;
readonly left: 0 | "var(--bits-scroll-area-corner-width)";
readonly right: 0 | "var(--bits-scroll-area-corner-width)";
readonly "--bits-scroll-area-thumb-width": `${number}px`;
};
};
}
export declare class ScrollAreaScrollbarYState implements ScrollbarAxisState {
static create(opts: ScrollbarAxisStateOpts): ScrollbarAxis;
readonly opts: ScrollbarAxisStateOpts;
readonly scrollbarVis: ScrollAreaScrollbarVisibleState;
readonly root: ScrollAreaRootState;
readonly scrollbar: ScrollAreaScrollbarState;
readonly attachment: RefAttachment;
computedStyle: CSSStyleDeclaration | undefined;
constructor(opts: ScrollbarAxisStateOpts, scrollbarVis: ScrollAreaScrollbarVisibleState);
onThumbPointerDown(pointerPos: {
x: number;
y: number;
}): void;
onDragScroll(pointerPos: {
x: number;
y: number;
}): void;
onThumbPointerUp(): void;
onThumbPositionChange(): void;
onWheelScroll(e: WheelEvent, maxScrollPos: number): void;
onResize(): void;
readonly thumbSize: number;
readonly props: {
readonly id: string;
readonly "data-orientation": "vertical";
readonly style: {
readonly top: 0;
readonly right: 0 | undefined;
readonly left: 0 | undefined;
readonly bottom: "var(--bits-scroll-area-corner-height)";
readonly "--bits-scroll-area-thumb-height": `${number}px`;
};
};
}
type ScrollbarAxis = ScrollAreaScrollbarXState | ScrollAreaScrollbarYState;
export declare class ScrollAreaScrollbarSharedState {
static create(): ScrollAreaScrollbarSharedState;
readonly scrollbarState: ScrollbarAxis;
readonly root: ScrollAreaRootState;
readonly scrollbarVis: ScrollAreaScrollbarVisibleState;
readonly scrollbar: ScrollAreaScrollbarState;
rect: DOMRect | null;
prevWebkitUserSelect: string;
handleResize: () => void;
handleThumbPositionChange: () => void;
handleWheelScroll: (e: WheelEvent, maxScrollPos: number) => void;
handleThumbPointerDown: (pointerPos: {
x: number;
y: number;
}) => void;
handleThumbPointerUp: () => void;
readonly maxScrollPos: number;
constructor(scrollbarState: ScrollbarAxis);
handleDragScroll(e: PointerEvent): void;
onpointerdown(e: BitsPointerEvent): void;
onpointermove(e: BitsPointerEvent): void;
onpointerup(e: BitsPointerEvent): void;
readonly props: never;
}
interface ScrollAreaThumbImplStateOpts extends WithRefOpts, ReadableBoxedValues<{
mounted: boolean;
}> {
}
export declare class ScrollAreaThumbImplState {
#private;
static create(opts: ScrollAreaThumbImplStateOpts): ScrollAreaThumbImplState;
readonly opts: ScrollAreaThumbImplStateOpts;
readonly scrollbarState: ScrollAreaScrollbarSharedState;
readonly attachment: RefAttachment;
constructor(opts: ScrollAreaThumbImplStateOpts, scrollbarState: ScrollAreaScrollbarSharedState);
onpointerdowncapture(e: BitsPointerEvent): void;
onpointerup(_: BitsPointerEvent): void;
readonly props: {
readonly id: string;
readonly "data-state": "hidden" | "visible";
readonly style: {
readonly width: "var(--bits-scroll-area-thumb-width)";
readonly height: "var(--bits-scroll-area-thumb-height)";
readonly transform: string;
};
readonly onpointerdowncapture: (e: BitsPointerEvent) => void;
readonly onpointerup: (_: BitsPointerEvent) => void;
};
}
interface ScrollAreaCornerImplStateOpts extends WithRefOpts {
}
export declare class ScrollAreaCornerImplState {
#private;
static create(opts: ScrollAreaCornerImplStateOpts): ScrollAreaCornerImplState;
readonly opts: ScrollAreaCornerImplStateOpts;
readonly root: ScrollAreaRootState;
readonly attachment: RefAttachment;
readonly hasSize: boolean;
constructor(opts: ScrollAreaCornerImplStateOpts, root: ScrollAreaRootState);
readonly props: {
id: string;
style: {
width: number;
height: number;
position: string;
right: number | undefined;
left: number | undefined;
bottom: number;
};
};
}
export {};