* Long content that needs scrolling...
*
* ```
*/
import { html, unsafeCSS } from "lit";
import { BaseElement } from "../../core/base-element.ts";
import { scrollAreaStyles } from "./styles.ts";
export type ScrollOrientation = "vertical" | "horizontal" | "both";
/**
* CFScrollArea provides a customizable scrollable container with styled scrollbars.
*
* @tag cf-scroll-area
* @extends BaseElement
*
* @property {ScrollOrientation} orientation - Scroll direction ("vertical" | "horizontal" | "both")
*
* @attribute {string} orientation - Sets which directions can be scrolled
*
* @slot default - Scrollable content
*
* @csspart root - The root container element
* @csspart viewport - The scrollable viewport container
* @csspart content - The content wrapper element
* @csspart scrollbar-vertical - The vertical scrollbar track
* @csspart scrollbar-horizontal - The horizontal scrollbar track
* @csspart thumb-vertical - The vertical scrollbar thumb
* @csspart thumb-horizontal - The horizontal scrollbar thumb
*
* @note Scrollbars appear on hover and during scrolling with smooth fade animations
*/
export class CFScrollArea extends BaseElement {
static override styles = unsafeCSS(scrollAreaStyles);
static override properties = {
orientation: { type: String },
_isDraggingVertical: { type: Boolean, state: true },
_isDraggingHorizontal: { type: Boolean, state: true },
};
declare orientation: ScrollOrientation;
declare private _isDraggingVertical: boolean;
declare private _isDraggingHorizontal: boolean;
private _scrollContainer: HTMLElement | null = null;
private _verticalScrollbar: HTMLElement | null = null;
private _horizontalScrollbar: HTMLElement | null = null;
private _verticalThumb: HTMLElement | null = null;
private _horizontalThumb: HTMLElement | null = null;
constructor() {
super();
this.orientation = "vertical";
this._isDraggingVertical = false;
this._isDraggingHorizontal = false;
}
get scrollContainer(): HTMLElement | null {
if (!this._scrollContainer) {
this._scrollContainer =
this.shadowRoot?.querySelector(".scroll-container") as HTMLElement ||
null;
}
return this._scrollContainer;
}
get verticalScrollbar(): HTMLElement | null {
if (!this._verticalScrollbar) {
this._verticalScrollbar =
this.shadowRoot?.querySelector(".scrollbar-vertical") as HTMLElement ||
null;
}
return this._verticalScrollbar;
}
get horizontalScrollbar(): HTMLElement | null {
if (!this._horizontalScrollbar) {
this._horizontalScrollbar = this.shadowRoot?.querySelector(
".scrollbar-horizontal",
) as HTMLElement || null;
}
return this._horizontalScrollbar;
}
get verticalThumb(): HTMLElement | null {
if (!this._verticalThumb) {
this._verticalThumb = this.shadowRoot?.querySelector(
".scrollbar-thumb-vertical",
) as HTMLElement || null;
}
return this._verticalThumb;
}
get horizontalThumb(): HTMLElement | null {
if (!this._horizontalThumb) {
this._horizontalThumb = this.shadowRoot?.querySelector(
".scrollbar-thumb-horizontal",
) as HTMLElement || null;
}
return this._horizontalThumb;
}
private _dragStartY = 0;
private _dragStartX = 0;
private _scrollStartY = 0;
private _scrollStartX = 0;
private _rafId: number | null = null;
private _hideTimeoutId: ReturnType