@trackunit/react-components 1.9.7 → 1.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.9.7",
3
+ "version": "1.9.9",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -16,12 +16,12 @@
16
16
  "@floating-ui/react": "^0.26.25",
17
17
  "string-ts": "^2.0.0",
18
18
  "tailwind-merge": "^2.0.0",
19
- "@trackunit/ui-design-tokens": "1.7.5",
20
- "@trackunit/css-class-variance-utilities": "1.7.5",
21
- "@trackunit/shared-utils": "1.9.5",
22
- "@trackunit/ui-icons": "1.7.6",
23
- "@trackunit/react-table-pagination": "1.7.5",
24
- "@trackunit/react-test-setup": "1.4.5",
19
+ "@trackunit/ui-design-tokens": "1.7.6",
20
+ "@trackunit/css-class-variance-utilities": "1.7.6",
21
+ "@trackunit/shared-utils": "1.9.6",
22
+ "@trackunit/ui-icons": "1.7.8",
23
+ "@trackunit/react-table-pagination": "1.7.6",
24
+ "@trackunit/react-test-setup": "1.4.6",
25
25
  "@tanstack/react-router": "1.114.29",
26
26
  "es-toolkit": "^1.39.10"
27
27
  },
@@ -0,0 +1,3 @@
1
+ export type Styleable = {
2
+ style?: React.CSSProperties;
3
+ };
@@ -4,3 +4,4 @@ export * from "./CommonProps";
4
4
  export * from "./Density";
5
5
  export * from "./Size";
6
6
  export * from "./StorybookProps";
7
+ export * from "./Styleable";
@@ -0,0 +1,21 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ import { CommonProps } from "../../common/CommonProps";
3
+ import { Styleable } from "../../common/Styleable";
4
+ export interface HorizontalOverflowScrollerProps extends CommonProps, Styleable {
5
+ children: ReactNode;
6
+ /**
7
+ * Callback fired when scroll state changes (scrollable, at edges, etc.)
8
+ */
9
+ onScrollStateChange?: (state: {
10
+ isScrollable: boolean;
11
+ isAtBeginning: boolean;
12
+ isAtEnd: boolean;
13
+ }) => void;
14
+ }
15
+ /**
16
+ * Container for displaying components in a horizontal layout with overflow detection
17
+ *
18
+ * @param {HorizontalOverflowScrollerProps} props - The props for the component
19
+ * @returns {Element} HorizontalOverflowScroller component
20
+ */
21
+ export declare const HorizontalOverflowScroller: ({ className, dataTestId, children, onScrollStateChange, }: HorizontalOverflowScrollerProps) => ReactElement;
@@ -0,0 +1,2 @@
1
+ export declare const cvaHorizontalOverflowScroller: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaHorizontalOverflowScrollerAndIndicatorsContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,22 @@
1
+ import { ReactElement } from "react";
2
+ import { CommonProps } from "../../common/CommonProps";
3
+ type OverflowDirection = "left" | "right";
4
+ export interface OverflowIndicatorProps extends CommonProps {
5
+ /**
6
+ * Direction of the overflow indicator
7
+ */
8
+ direction: OverflowDirection;
9
+ /**
10
+ * Callback function to handle scroll action
11
+ */
12
+ onClickScroll?: (event: React.MouseEvent<HTMLElement>) => void;
13
+ }
14
+ /**
15
+ * Overflow indicator component that shows visual cues when content extends beyond visible area
16
+ * Shows a scroll button on hover to navigate in the specified direction
17
+ *
18
+ * @param {OverflowIndicatorProps} props - The props for the component
19
+ * @returns {ReactElement} OverflowIndicator component
20
+ */
21
+ export declare const OverflowIndicator: ({ className, dataTestId, direction, onClickScroll, }: OverflowIndicatorProps) => ReactElement;
22
+ export {};
@@ -0,0 +1,8 @@
1
+ export declare const cvaOverflowIndicatorContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaOverflowIndicatorGradient: (props?: ({
3
+ direction?: "left" | "right" | null | undefined;
4
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
5
+ export declare const cvaJustificationContainer: (props?: ({
6
+ direction?: "left" | "right" | null | undefined;
7
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
8
+ export declare const cvaOverflowIndicatorButton: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -1,6 +1,6 @@
1
1
  import { ReactElement } from "react";
2
- import { CommonProps } from "../../common";
3
- export interface KPIProps extends CommonProps {
2
+ import { CommonProps, Styleable } from "../../common";
3
+ export interface KPIProps extends CommonProps, Styleable {
4
4
  /**
5
5
  * The title of the KPI
6
6
  */
@@ -58,4 +58,4 @@ export interface KPIProps extends CommonProps {
58
58
  * @param {KPIProps} props - The props for the KPI component
59
59
  * @returns {ReactElement} KPI component
60
60
  */
61
- export declare const KPI: ({ title, value, loading, unit, className, dataTestId, tooltipLabel, variant, trend, ...rest }: KPIProps) => ReactElement;
61
+ export declare const KPI: ({ title, value, loading, unit, className, dataTestId, tooltipLabel, variant, trend, style, ...rest }: KPIProps) => ReactElement;
@@ -1,34 +1,124 @@
1
1
  import { VariantProps } from "@trackunit/css-class-variance-utilities";
2
2
  import { RelayPagination } from "@trackunit/react-table-pagination";
3
- import { ReactElement, RefObject } from "react";
3
+ import { CSSProperties, ReactElement, Ref } from "react";
4
4
  import { CommonProps } from "../../common/CommonProps";
5
5
  import { cvaListItem } from "./List.variants";
6
+ import { ListLoadingIndicatorProps } from "./ListLoadingIndicator";
6
7
  type Separator = NonNullable<VariantProps<typeof cvaListItem>["separator"]>;
7
- type LoadingIndicator = "spinner" | "skeletonLines";
8
- export interface ListProps extends CommonProps {
8
+ /**
9
+ * Props that must be spread onto list items for proper virtualization.
10
+ * These handle positioning, measurement, accessibility, and interaction.
11
+ *
12
+ * **Important**: Consumers must add a `key` prop to their list items using the index parameter.
13
+ */ export interface VirtualizationListItemProps {
14
+ /** CSS classes for list styling and separators */
15
+ className: string;
16
+ /** Critical positioning styles for virtual scrolling */
17
+ style: CSSProperties;
18
+ /** Element ref for virtualization measurement */
19
+ ref?: Ref<any>;
20
+ /** Click handler for row-level interactions */
21
+ onClick?: () => void;
22
+ /** Data attribute for accessibility and debugging */
23
+ "data-index": number;
24
+ /** Tab index for keyboard navigation */
25
+ tabIndex: number;
26
+ }
27
+ export interface ListProps<TItem = unknown> extends CommonProps {
28
+ /**
29
+ * Number of items in the list (excluding header if provided).
30
+ */
9
31
  count: number;
10
- rowHeight?: number;
32
+ /**
33
+ * Pagination configuration for infinite scrolling.
34
+ */
11
35
  pagination?: RelayPagination;
12
- children: (index: number) => ReactElement | null;
36
+ /**
37
+ * Optional header element displayed at the top of the list.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * <List header={<KPI title="Total" value={42} />} ... />
42
+ * ```
43
+ */
44
+ header?: ReactElement;
45
+ /**
46
+ * Function that returns the item data for a given index.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * getItem={index => items[index]}
51
+ * ```
52
+ */
53
+ getItem: (index: number) => TItem;
54
+ /**
55
+ * Function that renders each list item. Must spread `listItemProps` onto your element and apply a `key` prop.
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * {(listItemProps, item, index) => (
60
+ * <ListItem key={index} {...listItemProps} title={item.name} />
61
+ * )}
62
+ * ```
63
+ */
64
+ children: (listItemProps: VirtualizationListItemProps, item: TItem, index: number) => ReactElement | null;
65
+ /**
66
+ * Separator style between list items.
67
+ */
13
68
  separator?: Separator;
14
- loadingIndicator?: LoadingIndicator;
15
- skeletonLinesHeight?: string;
16
- onRowClick?: (index: number) => void;
17
69
  /**
18
- * The ref for the scroll container, only provide if you want to use the scroll event to fetch more data, on a different container than the list itself
70
+ * Loading indicator configuration for pagination loading.
71
+ */
72
+ loadingIndicator?: ListLoadingIndicatorProps;
73
+ /**
74
+ * Callback fired when a row is clicked.
75
+ */
76
+ onRowClick?: (item: TItem, index: number) => void;
77
+ /**
78
+ * Callback for scroll state changes.
19
79
  */
20
- scrollRef?: RefObject<HTMLDivElement | null>;
80
+ onScrollStateChange?: (scrollOffset: number, isScrolling: boolean) => void;
81
+ /**
82
+ * Show a top separator when the list is scrolled.
83
+ */
84
+ topSeparatorOnScroll?: boolean;
85
+ /**
86
+ * Function to estimate item height for scroll performance.
87
+ *
88
+ * **Best Practice:** Always provide this function, even for fixed-height items.
89
+ * Measure the actual height in browser DevTools and return that value for optimal scrolling.
90
+ *
91
+ * The virtualizer uses these estimates for scroll calculations and viewport positioning.
92
+ * More accurate estimates result in smoother scrolling.
93
+ *
94
+ * @example Fixed height
95
+ * ```tsx
96
+ * estimateItemSize={() => 61} // Measured ListItem height
97
+ * ```
98
+ * @example Variable height
99
+ * ```tsx
100
+ * estimateItemSize={(index) => items[index]?.hasDescription ? 80 : 50}
101
+ * ```
102
+ */
103
+ estimateItemSize?: (index: number) => number;
21
104
  }
22
105
  /**
23
- * Render a performant virtualized list of items. Optionally with infinite scrolling.
106
+ * A performant virtualized list component with infinite scrolling support.
107
+ *
108
+ * ⚠️ **Important**: Requires a container with defined height to work properly.
109
+ *
110
+ * Features:
111
+ * - Virtualized rendering using TanStack Virtual for performance with large datasets
112
+ * - Automatic infinite scroll loading when approaching the end of the list
113
+ * - Optional header support (automatically managed, scrolls with content)
114
+ * - Built-in pagination with relay-style cursor support
115
+ * - Configurable loading indicators (skeleton, spinner, or custom)
116
+ * - Scroll state detection and callbacks
117
+ * - Variable-height item support via `estimateItemSize`
24
118
  *
25
- * @property {number} count - The total number of items in the list.
26
- * @property {number} [rowHeight="40"] - The estimated height of each row in the list.
27
- * @property {RelayPagination | undefined} pagination - Pagination configuration for the list.
28
- * @property {separator} [separator="line"] - The separator style between items in the list.
29
- * @property {(index: number) =>ReactElement} children - A function that takes an index and returns the JSX element to be rendered at said index.
30
- * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
31
- * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
119
+ * The component automatically loads more data when:
120
+ * - User scrolls to the last visible item
121
+ * - Content height is insufficient to fill the container
32
122
  */
33
- export declare const List: ({ count, rowHeight, pagination, children, className, dataTestId, separator, loadingIndicator, skeletonLinesHeight, onRowClick, scrollRef, }: ListProps) => ReactElement;
123
+ export declare const List: <TItem = unknown>({ count, pagination, children, className, dataTestId, separator, loadingIndicator, onRowClick, onScrollStateChange, topSeparatorOnScroll, estimateItemSize, header, getItem, }: ListProps<TItem>) => ReactElement;
34
124
  export {};
@@ -1,7 +1,7 @@
1
1
  export declare const cvaListContainer: (props?: ({
2
- parentControlledScrollable?: boolean | null | undefined;
2
+ withTopSeparator?: boolean | null | undefined;
3
3
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
4
  export declare const cvaList: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
5
5
  export declare const cvaListItem: (props?: ({
6
- separator?: "alternating" | "line" | "none" | "space" | null | undefined;
6
+ separator?: "line" | "none" | null | undefined;
7
7
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
@@ -0,0 +1,71 @@
1
+ import { ReactElement } from "react";
2
+ type NoneLoadingIndicator = {
3
+ type: "none";
4
+ component?: never;
5
+ initialLoadingCount?: never;
6
+ scrollLoadingCount?: never;
7
+ hasThumbnail?: never;
8
+ thumbnailShape?: never;
9
+ hasDescription?: never;
10
+ hasMeta?: never;
11
+ hasDetails?: never;
12
+ };
13
+ type SpinnerLoadingIndicator = {
14
+ type: "spinner";
15
+ component?: never;
16
+ initialLoadingCount?: never;
17
+ scrollLoadingCount?: never;
18
+ hasThumbnail?: never;
19
+ thumbnailShape?: never;
20
+ hasDescription?: never;
21
+ hasMeta?: never;
22
+ hasDetails?: never;
23
+ };
24
+ type CustomLoadingIndicator = {
25
+ type: "custom";
26
+ component: ReactElement;
27
+ /**
28
+ * Number of loading indicators to show on initial load
29
+ *
30
+ * @default 3
31
+ */
32
+ initialLoadingCount?: number;
33
+ /**
34
+ * Number of loading indicators to show when loading more items during scroll
35
+ *
36
+ * @default 10
37
+ */
38
+ scrollLoadingCount?: number;
39
+ hasThumbnail?: never;
40
+ thumbnailShape?: never;
41
+ hasDescription?: never;
42
+ hasMeta?: never;
43
+ hasDetails?: never;
44
+ };
45
+ type SkeletonLoadingIndicator = {
46
+ type: "skeleton";
47
+ component?: never;
48
+ hasThumbnail?: boolean;
49
+ thumbnailShape?: "circle" | "square";
50
+ hasDescription?: boolean;
51
+ hasMeta?: boolean;
52
+ hasDetails?: boolean;
53
+ /**
54
+ * Number of loading indicators to show on initial load
55
+ *
56
+ * @default 3
57
+ */
58
+ initialLoadingCount?: number;
59
+ /**
60
+ * Number of loading indicators to show when loading more items during scroll
61
+ *
62
+ * @default 10
63
+ */
64
+ scrollLoadingCount?: number;
65
+ };
66
+ export type ListLoadingIndicatorProps = NoneLoadingIndicator | SpinnerLoadingIndicator | CustomLoadingIndicator | SkeletonLoadingIndicator;
67
+ /**
68
+ *
69
+ */
70
+ export declare const ListLoadingIndicator: ({ type, hasThumbnail, thumbnailShape, hasDescription, component, hasMeta, hasDetails, }: ListLoadingIndicatorProps) => ReactElement | null;
71
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { VariantProps } from "@trackunit/css-class-variance-utilities";
2
2
  import { MappedOmit } from "@trackunit/shared-utils";
3
3
  import { tailwindPalette, ThemeColors } from "@trackunit/ui-design-tokens";
4
- import { MouseEventHandler, ReactElement, ReactNode } from "react";
4
+ import { CSSProperties, MouseEventHandler, ReactElement, ReactNode, Ref } from "react";
5
5
  import { CommonProps } from "../../common/CommonProps";
6
6
  import { cvaListItem } from "./ListItem.variants";
7
7
  type ThemeColorShades = `${keyof (typeof tailwindPalette)[keyof typeof tailwindPalette]}`;
@@ -15,7 +15,7 @@ export interface ListItemProps extends CommonProps, MappedOmit<VariantProps<type
15
15
  /**Optional thumbnail for the ListItem. Can be used to display an image or icon. */
16
16
  thumbnail?: ReactElement;
17
17
  /**Makes the items interactive. Can be used to navigate to a different page when an item is clicked. */
18
- onClick?: MouseEventHandler<HTMLDivElement>;
18
+ onClick?: MouseEventHandler<HTMLElement>;
19
19
  /**Details can be used to nest a component on the right side of the ListItem (can be used to display a tag, icon, highlight, text, etc.) */
20
20
  details?: ReactNode;
21
21
  /**If an icon is chosen as thumbnail, use this to set the color of the icon. */
@@ -24,6 +24,14 @@ export interface ListItemProps extends CommonProps, MappedOmit<VariantProps<type
24
24
  * If asset image is chosen as thumbnail, make the thumbnailBackground "white".
25
25
  */
26
26
  thumbnailBackground?: `${ThemeColors}-${ThemeColorShades}` | `${ThemeColors}`;
27
+ /** @internal */
28
+ style?: CSSProperties;
29
+ /** @internal */
30
+ ref?: Ref<HTMLLIElement>;
31
+ /** @internal */
32
+ tabIndex?: number;
33
+ /** @internal */
34
+ "data-index"?: number;
27
35
  }
28
36
  /**
29
37
  * The ListItem is designed to present a concise set of items for quick scanning and navigation. It supports multiple content types and actions, and its flexible layout allows for customization based on the type of data being shown - assets, events, users, etc.
@@ -31,5 +39,5 @@ export interface ListItemProps extends CommonProps, MappedOmit<VariantProps<type
31
39
  * @param { ListItemProps} props - The props for the ListItem component
32
40
  * @returns {Element} ListItem component
33
41
  */
34
- export declare const ListItem: ({ className, dataTestId, onClick, details, title, description, meta, thumbnail, thumbnailColor, thumbnailBackground, }: ListItemProps) => ReactElement;
42
+ export declare const ListItem: ({ className, dataTestId, onClick, details, title, description, meta, thumbnail, thumbnailColor, thumbnailBackground, ...rest }: ListItemProps) => ReactElement;
35
43
  export {};
@@ -0,0 +1,25 @@
1
+ import { ReactElement } from "react";
2
+ export declare const DEFAULT_SKELETON_LIST_ITEM_PROPS: {
3
+ readonly hasThumbnail: true;
4
+ readonly thumbnailShape: "circle";
5
+ readonly hasDescription: true;
6
+ readonly hasMeta: false;
7
+ readonly hasDetails: false;
8
+ };
9
+ export interface ListItemSkeletonProps {
10
+ /** Whether to show a thumbnail skeleton */
11
+ hasThumbnail?: boolean;
12
+ /** Shape of the thumbnail when present */
13
+ thumbnailShape?: "circle" | "square";
14
+ /** Whether to show a description line */
15
+ hasDescription?: boolean;
16
+ /** Whether to show a meta line */
17
+ hasMeta?: boolean;
18
+ /** Whether to show details on the right side */
19
+ hasDetails?: boolean;
20
+ }
21
+ /**
22
+ * Skeleton loading indicator that mimics the ListItem component structure.
23
+ * Uses the same layout, spacing, and visual hierarchy as ListItem.
24
+ */
25
+ export declare const ListItemSkeleton: ({ hasThumbnail, thumbnailShape, hasDescription, hasMeta, hasDetails, }: ListItemSkeletonProps) => ReactElement;
@@ -1,24 +1,25 @@
1
- import { ReactElement } from "react";
2
1
  import { CommonProps } from "../../common/CommonProps";
2
+ type SkeletonDimension = number | string | Array<number | string>;
3
3
  export interface SkeletonLinesProps extends CommonProps {
4
4
  /**
5
5
  * The number of lines to display.
6
6
  */
7
7
  lines?: number;
8
8
  /**
9
- * The height of lines. Can be a number or an array of numbers or string.
9
+ * The height of lines. Can be a number, string, or an array of numbers/strings.
10
10
  */
11
- height?: number | Array<number> | string;
11
+ height?: SkeletonDimension;
12
12
  /**
13
- * The width of each line. Can be a number or an array of numbers or string.
13
+ * The width of each line. Can be a number, string, or an array of numbers/strings.
14
14
  */
15
- width?: number | Array<number> | string;
15
+ width?: SkeletonDimension;
16
16
  /**
17
- * Margin of lines.
17
+ * Gap between skeleton lines in pixels.
18
18
  */
19
- margin?: string;
19
+ margin?: number | string;
20
20
  }
21
21
  /**
22
22
  * Display placeholder lines before the data gets loaded to reduce load-time frustration.
23
23
  */
24
- export declare const SkeletonLines: import("react").MemoExoticComponent<({ margin, lines, height, width, className, dataTestId, }: SkeletonLinesProps) => ReactElement>;
24
+ export declare const SkeletonLines: import("react").NamedExoticComponent<SkeletonLinesProps>;
25
+ export {};
@@ -1 +1,2 @@
1
+ export declare const cvaSkeletonContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
1
2
  export declare const cvaSkeletonLine: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -1 +1,2 @@
1
+ export * from "./skeleton-utils";
1
2
  export * from "./SkeletonLines";
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generates a random width percentage string for skeleton loading components.
3
+ *
4
+ * @param {object} params - The parameter object
5
+ * @param {number} params.min - Minimum percentage value (e.g., 30 for 30%)
6
+ * @param {number} params.max - Maximum percentage value (e.g., 80 for 80%)
7
+ * @returns {string} A percentage string (e.g., "65%")
8
+ */
9
+ export declare const getResponsiveRandomWidthPercentage: ({ min, max }: {
10
+ min: number;
11
+ max: number;
12
+ }) => string;
@@ -1,9 +1,9 @@
1
1
  import { Placement } from "@floating-ui/react";
2
2
  import { ReactElement, ReactNode } from "react";
3
- import { CommonProps } from "../../common";
3
+ import { CommonProps, Styleable } from "../../common";
4
4
  import { IconProps } from "../Icon/Icon";
5
5
  export type TooltipPlacement = Placement | "auto";
6
- export interface TooltipProps extends CommonProps {
6
+ export interface TooltipProps extends CommonProps, Styleable {
7
7
  /**
8
8
  * The text to be displayed in the tooltip.
9
9
  */
@@ -45,4 +45,4 @@ export interface TooltipProps extends CommonProps {
45
45
  * @param {TooltipProps} props - The props for the Tooltip component
46
46
  * @returns {ReactElement} Tooltip component
47
47
  */
48
- export declare const Tooltip: ({ children, dataTestId, disabled, className, label, placement, mode, iconProps, id, }: TooltipProps) => ReactElement;
48
+ export declare const Tooltip: ({ children, dataTestId, disabled, className, label, placement, mode, iconProps, id, style, }: TooltipProps) => ReactElement;
@@ -13,6 +13,7 @@ export * from "./EmptyValue/EmptyValue";
13
13
  export * from "./ExternalLink/ExternalLink";
14
14
  export * from "./Heading";
15
15
  export * from "./Highlight/Highlight";
16
+ export * from "./HorizontalOverflowScroller/HorizontalOverflowScroller";
16
17
  export * from "./Icon/Icon";
17
18
  export * from "./Indicator";
18
19
  export * from "./KPI/KPI";
@@ -14,6 +14,7 @@ export * from "./useModifierKey";
14
14
  export * from "./useResize";
15
15
  export * from "./useScrollDetection";
16
16
  export * from "./useSelfUpdatingRef";
17
+ export * from "./useStable";
17
18
  export * from "./useTimeout";
18
19
  export * from "./useViewportBreakpoints";
19
20
  export * from "./useWatch";
@@ -1,9 +1,12 @@
1
1
  import { RefObject } from "react";
2
+ interface UseGeometryOptions {
3
+ skip?: boolean;
4
+ }
2
5
  /**
3
6
  * Custom hook to get the geometry of an element.
4
7
  * Size and position of the element relative to the viewport.
5
8
  */
6
- export declare const useGeometry: (ref: RefObject<HTMLElement | null>) => {
9
+ export declare const useGeometry: (ref: RefObject<HTMLElement | null>, { skip }?: UseGeometryOptions) => {
7
10
  width: number;
8
11
  height: number;
9
12
  top: number;
@@ -13,3 +16,4 @@ export declare const useGeometry: (ref: RefObject<HTMLElement | null>) => {
13
16
  x: number;
14
17
  y: number;
15
18
  };
19
+ export {};
@@ -2,9 +2,14 @@ export interface WindowSize {
2
2
  height: number;
3
3
  width: number;
4
4
  }
5
+ interface UseResizeOptions {
6
+ skip?: boolean;
7
+ }
5
8
  /**
6
9
  * Custom hook to handle window resize events and provide the current window size.
7
10
  *
11
+ * @param {UseResizeOptions} options - Options for the hook.
8
12
  * @returns {WindowSize} An object containing the current window height and width.
9
13
  */
10
- export declare const useResize: () => WindowSize;
14
+ export declare const useResize: ({ skip }?: UseResizeOptions) => WindowSize;
15
+ export {};
@@ -1,16 +1,24 @@
1
1
  import { type RefObject } from "react";
2
- /**
3
- * Hook for getting detecting scroll values.
4
- *
5
- * @param {useRef} elementRef - Ref hook holding the element that needs to be observed during scrolling
6
- * @returns {object} An object containing if the element is scrollable, is at the top, is at the bottom, and its current scroll position.
7
- */
8
- export declare const useScrollDetection: (elementRef?: RefObject<HTMLElement | null>) => {
2
+ type ScrollDirection = "horizontal" | "vertical";
3
+ type ScrollState = {
9
4
  isScrollable: boolean;
10
- isAtTop: boolean;
11
- isAtBottom: boolean;
5
+ isAtBeginning: boolean;
6
+ isAtEnd: boolean;
12
7
  scrollPosition: {
13
- top: number;
14
- bottom: number;
8
+ start: number;
9
+ end: number;
15
10
  };
16
11
  };
12
+ type UseScrollDetectionOptions = {
13
+ direction?: ScrollDirection;
14
+ onScrollStateChange?: (state: ScrollState) => void;
15
+ };
16
+ /**
17
+ * Hook for detecting scroll values in horizontal or vertical direction.
18
+ *
19
+ * @param {useRef} elementRef - Ref hook holding the element that needs to be observed during scrolling
20
+ * @param {object} options - Options object containing direction and onScrollStateChange callback
21
+ * @returns {object} An object containing if the element is scrollable, is at the beginning, is at the end, and its current scroll position.
22
+ */
23
+ export declare const useScrollDetection: (elementRef?: RefObject<HTMLElement | null>, options?: UseScrollDetectionOptions) => ScrollState;
24
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The useStable hook ensures that a value is computed only once and remains stable across renders.
3
+ * This is useful for expensive computations or when you need a value to never change after initial creation.
4
+ * Perfect for generating stable random values, creating stable object references, or any one-time computation.
5
+ *
6
+ * @example
7
+ * // Stable random ID that never changes
8
+ * const stableId = useStable(() => Math.random().toString(36));
9
+ * @example
10
+ * // Stable configuration object
11
+ * const config = useStable(() => ({
12
+ * apiKey: generateApiKey(),
13
+ * timestamp: Date.now()
14
+ * }));
15
+ * @example
16
+ * // Stable random widths for skeleton loading
17
+ * const lineWidths = useStable(() => ({
18
+ * title: Math.floor(Math.random() * 100) + 120,
19
+ * description: Math.floor(Math.random() * 80) + 80
20
+ * }));
21
+ */
22
+ export declare const useStable: <TValue>(factory: () => TValue) => TValue;