341 lines
12 KiB
TypeScript
341 lines
12 KiB
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: "scroll" | "hidden";
|
|
readonly overflowY: "scroll" | "hidden";
|
|
};
|
|
};
|
|
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 {
|
|
#private;
|
|
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;
|
|
onlostpointercapture(_: 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 {};
|