@juspay/blend-design-system 0.0.19 → 0.0.20-beta

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.
@@ -1,4 +1,4 @@
1
- import { NewNestedDataPoint, FlattenedDataPoint, AxisType, XAxisConfig } from './types';
1
+ import { NewNestedDataPoint, FlattenedDataPoint, AxisConfig } from './types';
2
2
  export declare function transformNestedData(data: NewNestedDataPoint[], selectedKeys?: string[]): FlattenedDataPoint[];
3
3
  export declare function transformScatterData(data: NewNestedDataPoint[], selectedKeys?: string[]): Array<{
4
4
  name: string;
@@ -9,7 +9,94 @@ export declare function transformScatterData(data: NewNestedDataPoint[], selecte
9
9
  export declare function lightenHexColor(hex: string, amount?: number): string;
10
10
  export declare const formatNumber: (value: number | string) => string;
11
11
  export declare const capitaliseCamelCase: (text: string) => string;
12
- export declare const createSmartDateTimeFormatter: (timeZone?: string, hour12?: boolean, showYear?: boolean) => ((value: string | number) => string);
13
- export declare const getAxisFormatterWithConfig: (axisType: AxisType, dateOnly?: boolean, smart?: boolean, timeZone?: string, hour12?: boolean, showYear?: boolean, forTooltip?: boolean) => ((value: string | number) => string);
14
- export declare const createStableSmartFormatter: (xAxisConfig: XAxisConfig, flattenedData: FlattenedDataPoint[]) => ((value: string | number) => string) | undefined;
15
- export declare const getAxisFormatter: (axisType: AxisType, timeZone?: string, hour12?: boolean) => ((value: string | number) => string);
12
+ export type DateTimeFormatterOptions = {
13
+ useUTC?: boolean;
14
+ formatString?: string;
15
+ dateOnly?: boolean;
16
+ timeOnly?: boolean;
17
+ showYear?: boolean;
18
+ smartDateTimeFormat?: boolean;
19
+ };
20
+ /**
21
+ * Creates a DateTime formatter with custom options
22
+ * @param options - Configuration options for the formatter
23
+ * @param options.useUTC - Whether to use UTC timezone (default: true)
24
+ * @param options.formatString - Optional custom format string
25
+ * @param options.dateOnly - Show only dates (e.g., "1. Oct", "2. Oct")
26
+ * @param options.timeOnly - Show only times (e.g., "12:00", "13:00")
27
+ * @param options.showYear - Include year in the output (works with dateOnly and default mode)
28
+ * @param options.smartDateTimeFormat - Alternates between date and time like Highcharts
29
+ * @returns A formatter function that handles timestamps from any timezone
30
+ *
31
+ * @example
32
+ * // Date only without year: "1. Oct" "2. Oct" "3. Oct"
33
+ * createDateTimeFormatter({ dateOnly: true, showYear: false })
34
+ *
35
+ * @example
36
+ * // Date only with year: "1. Oct 2024" "2. Oct 2024"
37
+ * createDateTimeFormatter({ dateOnly: true, showYear: true })
38
+ *
39
+ * @example
40
+ * // Time only: "00:00" "06:00" "12:00"
41
+ * createDateTimeFormatter({ timeOnly: true })
42
+ *
43
+ * @example
44
+ * // Smart format (alternates): "1. Oct" "12:00" "2. Oct" "12:00"
45
+ * createDateTimeFormatter({ smartDateTimeFormat: true })
46
+ *
47
+ * @example
48
+ * // Default with year: "1 Oct 2024, 12:00"
49
+ * createDateTimeFormatter({ showYear: true })
50
+ */
51
+ export declare const createDateTimeFormatter: (options?: DateTimeFormatterOptions) => ((value: string | number) => string);
52
+ /**
53
+ * Get a formatter function based on axis type with optional DateTime customization
54
+ * @param axisType - The type of axis (DATE_TIME, CURRENCY, PERCENTAGE, NUMBER)
55
+ * @param dateTimeOptions - Options for DateTime formatting (only used when axisType is DATE_TIME)
56
+ * @returns A formatter function for the specified axis type
57
+ *
58
+ * @example
59
+ * // Simple usage with default UTC
60
+ * getAxisFormatter(AxisType.DATE_TIME)
61
+ *
62
+ * @example
63
+ * // Date only without year
64
+ * getAxisFormatter(AxisType.DATE_TIME, { dateOnly: true })
65
+ *
66
+ * @example
67
+ * // Date only with year
68
+ * getAxisFormatter(AxisType.DATE_TIME, { dateOnly: true, showYear: true })
69
+ *
70
+ * @example
71
+ * // Time only
72
+ * getAxisFormatter(AxisType.DATE_TIME, { timeOnly: true })
73
+ *
74
+ * @example
75
+ * // Local timezone instead of UTC
76
+ * getAxisFormatter(AxisType.DATE_TIME, { useUTC: false })
77
+ */
78
+ export declare const getAxisFormatter: (finalAxis: AxisConfig) => ((value: string | number) => string);
79
+ /**
80
+ * Suggests an optimal tick interval based on the data range
81
+ * Automatically determines whether to use minutes, hours, days, etc.
82
+ */
83
+ export declare function getSuggestedTickInterval(data: NewNestedDataPoint[], maxTicks?: number): {
84
+ interval: number;
85
+ description: string;
86
+ unit: string;
87
+ };
88
+ /**
89
+ * Generates consistent, evenly-spaced tick values for datetime axes
90
+ * This mimics Highcharts behavior where ticks are at regular intervals
91
+ *
92
+ * @param data - Chart data with timestamps in 'name' field
93
+ * @param options - Configuration options
94
+ * @returns Object containing tick array (as strings to match data format) and formatter function
95
+ */
96
+ export declare function generateConsistentDateTimeTicks(data: NewNestedDataPoint[], options?: DateTimeFormatterOptions & {
97
+ maxTicks?: number;
98
+ customInterval?: number;
99
+ }): {
100
+ ticks: string[];
101
+ formatter: (value: string | number) => string;
102
+ };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Highcharts-style DateTime Formatter Utility for Charts (Functional)
3
+ *
4
+ * This utility provides Highcharts-compatible datetime formatting for charts.
5
+ * It intelligently formats timestamps based on the data range and supports
6
+ * custom format strings similar to Highcharts' dateTimeLabelFormats.
7
+ */
8
+ export declare const TIME_UNITS: {
9
+ readonly millisecond: 1;
10
+ readonly second: 1000;
11
+ readonly minute: 60000;
12
+ readonly hour: 3600000;
13
+ readonly day: 86400000;
14
+ readonly week: 604800000;
15
+ readonly month: 2592000000;
16
+ readonly year: 31536000000;
17
+ };
18
+ export type TimeUnit = keyof typeof TIME_UNITS;
19
+ export declare const DEFAULT_DATE_TIME_FORMATS: Record<TimeUnit, string>;
20
+ export interface DateTimeFormatterConfig {
21
+ useUTC?: boolean;
22
+ customFormats?: Partial<Record<TimeUnit, string>>;
23
+ startOfWeek?: number;
24
+ }
25
+ /**
26
+ * Parse and validate a timestamp value
27
+ * Handles: numbers, numeric strings, ISO strings, seconds vs milliseconds
28
+ */
29
+ export declare function parseTimestamp(value: string | number): number | null;
30
+ /**
31
+ * Determines the most appropriate time unit based on data range
32
+ */
33
+ export declare function getTimeUnit(dataRange: number): TimeUnit;
34
+ /**
35
+ * Get time unit from an array of timestamps
36
+ */
37
+ export declare function getTimeUnitFromData(timestamps: number[]): TimeUnit;
38
+ /**
39
+ * Normalize timestamp to the nearest time unit boundary
40
+ * This ensures consistent tick positioning like Highcharts
41
+ */
42
+ export declare function normalizeTimestamp(timestamp: number, timeUnit: TimeUnit, config?: DateTimeFormatterConfig): number;
43
+ /**
44
+ * Formats a timestamp according to a format string (Highcharts-style)
45
+ *
46
+ * Format tokens:
47
+ * - %Y: 4-digit year (2024)
48
+ * - %y: 2-digit year (24)
49
+ * - %m: 2-digit month (01-12)
50
+ * - %b: Short month name (Jan)
51
+ * - %B: Full month name (January)
52
+ * - %d: 2-digit day (01-31)
53
+ * - %e: Day without leading zero (1-31)
54
+ * - %H: 2-digit hour 24h (00-23)
55
+ * - %I: 2-digit hour 12h (01-12)
56
+ * - %M: 2-digit minute (00-59)
57
+ * - %S: 2-digit second (00-59)
58
+ * - %L: Milliseconds (000-999)
59
+ * - %p: AM/PM
60
+ * - %A: Full weekday name (Monday)
61
+ * - %a: Short weekday name (Mon)
62
+ * - %%: Literal % character
63
+ */
64
+ export declare function dateFormat(formatString: string, timestamp: number, config?: DateTimeFormatterConfig): string;
65
+ /**
66
+ * Get the appropriate date format for a given time unit
67
+ */
68
+ export declare function getDateFormat(timeUnit: TimeUnit, config?: DateTimeFormatterConfig): string;
69
+ /**
70
+ * Get optimal tick interval to prevent cluttered axes
71
+ * Returns recommended number of milliseconds between ticks
72
+ */
73
+ export declare function getOptimalTickInterval(dataRange: number, maxTicks?: number): {
74
+ interval: number;
75
+ unit: TimeUnit;
76
+ };
77
+ /**
78
+ * Generate evenly spaced tick values for a time range
79
+ * This prevents cluttered axes by ensuring consistent spacing
80
+ */
81
+ export declare function generateTickValues(minTimestamp: number, maxTimestamp: number, maxTicks?: number, config?: DateTimeFormatterConfig): number[];
82
+ /**
83
+ * Generate ticks at a custom interval (in milliseconds)
84
+ * Useful for forcing specific tick spacing (e.g., every 6 hours)
85
+ */
86
+ export declare function generateTicksAtInterval(minTimestamp: number, maxTimestamp: number, intervalMs: number, timeUnit?: TimeUnit, config?: DateTimeFormatterConfig): number[];
87
+ /**
88
+ * Create a basic formatter function for a specific time unit
89
+ */
90
+ export declare function createFormatter(timeUnit: TimeUnit, config?: DateTimeFormatterConfig): (value: number) => string;
91
+ /**
92
+ * Create a formatter function for chart axes with auto time unit detection
93
+ */
94
+ export declare function createAxisFormatter(timestamps: number[], config?: DateTimeFormatterConfig): (value: number) => string;
95
+ /**
96
+ * Create a smart formatter that shows date on day change, time otherwise
97
+ * Similar to Highcharts' smart datetime formatting
98
+ */
99
+ export declare function createSmartFormatter(timestamps: number[], showYear?: boolean, config?: DateTimeFormatterConfig): (value: number) => string;
100
+ /**
101
+ * Create an alternating date/time formatter
102
+ * Shows date on even ticks, time on odd ticks (e.g., "1 Oct", "12:00", "2 Oct", "12:00")
103
+ */
104
+ export declare function createAlternatingFormatter(ticks: number[], dateFormatStr?: string, timeFormatStr?: string, config?: DateTimeFormatterConfig): (value: number) => string;
105
+ /**
106
+ * Format multiple timestamps
107
+ */
108
+ export declare function formatMultiple(timestamps: number[], timeUnit?: TimeUnit, config?: DateTimeFormatterConfig): string[];
109
+ /**
110
+ * Generate date-only ticks (for Charts dateOnly mode)
111
+ * Returns ticks at day boundaries with date-only labels
112
+ */
113
+ export declare function createDateOnlyTicksAndFormatter(minTimestamp: number, maxTimestamp: number, maxTicks?: number, showYear?: boolean, config?: DateTimeFormatterConfig): {
114
+ ticks: number[];
115
+ formatter: (value: number) => string;
116
+ };
117
+ /**
118
+ * Generate time-only ticks spanning the entire data range
119
+ * Shows times at regular intervals (e.g., every 15 minutes, 1 hour, etc.)
120
+ */
121
+ export declare function createTimeOnlyTicksAndFormatter(minTimestamp: number, maxTimestamp: number, intervalMinutes?: number, maxTicks?: number, config?: DateTimeFormatterConfig): {
122
+ ticks: number[];
123
+ formatter: (value: number) => string;
124
+ };
125
+ /**
126
+ * Generate ticks with alternating date and time labels
127
+ * Pattern: Date, Time, Date, Time, etc.
128
+ */
129
+ export declare function createDateTimeAlternatingTicksAndFormatter(minTimestamp: number, maxTimestamp: number, intervalMs?: number, showYear?: boolean, maxTicks?: number, config?: DateTimeFormatterConfig): {
130
+ ticks: number[];
131
+ formatter: (value: number) => string;
132
+ };
133
+ /**
134
+ * All-in-one helper: Generate ticks and create alternating formatter
135
+ */
136
+ export declare function createAlternatingTicksAndFormatter(minTimestamp: number, maxTimestamp: number, intervalMs: number, options?: {
137
+ timeUnit?: TimeUnit;
138
+ dateFormat?: string;
139
+ timeFormat?: string;
140
+ }, config?: DateTimeFormatterConfig): {
141
+ ticks: number[];
142
+ formatter: (value: number) => string;
143
+ };
144
+ /**
145
+ * Create a dynamic tick generator that adapts to available width
146
+ * This prevents tick collision by adjusting density based on chart width
147
+ */
148
+ export declare function createResponsiveTicksAndFormatter(minTimestamp: number, maxTimestamp: number, chartWidthPx: number, avgLabelWidthPx?: number, mode?: 'dateOnly' | 'timeOnly' | 'alternating' | 'smart', showYear?: boolean, config?: DateTimeFormatterConfig): {
149
+ ticks: number[];
150
+ formatter: (value: number) => string;
151
+ };
@@ -67,10 +67,14 @@ export type AxisConfig = {
67
67
  tickFormatter?: (value: string | number) => string;
68
68
  customTick?: React.ComponentType<TickProps>;
69
69
  dateOnly?: boolean;
70
- smart?: boolean;
71
- timeZone?: string;
72
- hour12?: boolean;
70
+ useUTC?: boolean;
71
+ formatString?: string;
72
+ timeOnly?: boolean;
73
73
  showYear?: boolean;
74
+ ticks?: (number | string)[];
75
+ autoConsistentTicks?: boolean;
76
+ maxTicks?: number;
77
+ smartDateTimeFormat?: boolean;
74
78
  };
75
79
  export type XAxisConfig = AxisConfig;
76
80
  export type YAxisConfig = AxisConfig;
@@ -2,7 +2,7 @@ import { CSSObject } from 'styled-components';
2
2
  import { MenuV2Props } from './types';
3
3
  export declare const contentBaseStyle: CSSObject;
4
4
  declare const Menu: {
5
- ({ trigger, items, asModal, alignment, side, sideOffset, alignOffset, collisonBoundaryRef, maxHeight, enableSearch, searchPlaceholder, minWidth, maxWidth, open, onOpenChange, }: MenuV2Props): import("react/jsx-runtime").JSX.Element;
5
+ ({ trigger, items, asModal, alignment, side, sideOffset, alignOffset, collisonBoundaryRef, maxHeight, enableSearch, searchPlaceholder, minWidth, maxWidth, open, onOpenChange, enableVirtualScrolling, virtualItemHeight, virtualOverscan, virtualScrollThreshold, }: MenuV2Props): import("react/jsx-runtime").JSX.Element;
6
6
  displayName: string;
7
7
  };
8
8
  export default Menu;
@@ -19,6 +19,10 @@ export type MenuV2Props = {
19
19
  minWidth?: number;
20
20
  enableSearch?: boolean;
21
21
  searchPlaceholder?: string;
22
+ enableVirtualScrolling?: boolean;
23
+ virtualItemHeight?: number | ((item: MenuItemV2Type, index: number) => number);
24
+ virtualOverscan?: number;
25
+ virtualScrollThreshold?: number;
22
26
  open?: boolean;
23
27
  onOpenChange?: (open: boolean) => void;
24
28
  asModal?: boolean;
@@ -1,3 +1,3 @@
1
1
  import { MultiSelectProps } from './types';
2
- declare const MultiSelect: ({ selectedValues, onChange, items, label, sublabel, disabled, helpIconHintText, name, required, variant, selectionTagType, slot, hintText, placeholder, size, enableSearch, searchPlaceholder, enableSelectAll, selectAllText, maxSelections, customTrigger, useDrawerOnMobile, minMenuWidth, maxMenuWidth, maxMenuHeight, alignment, side, sideOffset, alignOffset, inline, onBlur, onFocus, error, errorMessage, showActionButtons, primaryAction, secondaryAction, showItemDividers, showHeaderBorder, fullWidth, }: MultiSelectProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const MultiSelect: ({ selectedValues, onChange, items, label, sublabel, disabled, helpIconHintText, name, required, variant, selectionTagType, slot, hintText, placeholder, size, enableSearch, searchPlaceholder, enableSelectAll, selectAllText, maxSelections, customTrigger, useDrawerOnMobile, minMenuWidth, maxMenuWidth, maxMenuHeight, alignment, side, sideOffset, alignOffset, inline, onBlur, onFocus, error, errorMessage, showActionButtons, primaryAction, secondaryAction, showItemDividers, showHeaderBorder, fullWidth, enableVirtualization, virtualListItemHeight, virtualListOverscan, itemsToRender, onEndReached, endReachedThreshold, hasMore, loadingComponent, }: MultiSelectProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default MultiSelect;
@@ -1,3 +1,3 @@
1
1
  import { MultiSelectMenuProps } from './types';
2
- declare const MultiSelectMenu: ({ items, selected, onSelect, trigger, minMenuWidth, maxMenuWidth, maxMenuHeight, disabled, enableSearch, searchPlaceholder, enableSelectAll, selectAllText, maxSelections, onSelectAll, alignment, side, sideOffset, alignOffset, open, onOpenChange, showActionButtons, primaryAction, secondaryAction, }: MultiSelectMenuProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const MultiSelectMenu: ({ items, selected, onSelect, trigger, minMenuWidth, maxMenuWidth, maxMenuHeight, disabled, enableSearch, searchPlaceholder, enableSelectAll, selectAllText, maxSelections, onSelectAll, alignment, side, sideOffset, alignOffset, open, onOpenChange, showActionButtons, primaryAction, secondaryAction, enableVirtualization, virtualListItemHeight, virtualListOverscan, itemsToRender, onEndReached, endReachedThreshold, hasMore, loadingComponent, }: MultiSelectMenuProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default MultiSelectMenu;
@@ -104,6 +104,14 @@ export type MultiSelectProps = {
104
104
  showItemDividers?: boolean;
105
105
  showHeaderBorder?: boolean;
106
106
  fullWidth?: boolean;
107
+ enableVirtualization?: boolean;
108
+ virtualListItemHeight?: number;
109
+ virtualListOverscan?: number;
110
+ itemsToRender?: number;
111
+ onEndReached?: () => void;
112
+ endReachedThreshold?: number;
113
+ hasMore?: boolean;
114
+ loadingComponent?: React.ReactNode;
107
115
  };
108
116
  export type MultiSelectMenuProps = {
109
117
  items: MultiSelectMenuGroupType[];
@@ -139,4 +147,12 @@ export type MultiSelectMenuProps = {
139
147
  disabled?: boolean;
140
148
  loading?: boolean;
141
149
  };
150
+ enableVirtualization?: boolean;
151
+ virtualListItemHeight?: number;
152
+ virtualListOverscan?: number;
153
+ itemsToRender?: number;
154
+ onEndReached?: () => void;
155
+ endReachedThreshold?: number;
156
+ hasMore?: boolean;
157
+ loadingComponent?: React.ReactNode;
142
158
  };
@@ -1,3 +1,3 @@
1
1
  import { SingleSelectProps } from './types';
2
- declare const SingleSelect: ({ label, subLabel, hintText, required, helpIconText, placeholder, error, errorMessage, size, items, name, variant, disabled, selected, onSelect, enableSearch, searchPlaceholder, slot, customTrigger, useDrawerOnMobile, alignment, side, sideOffset, alignOffset, minMenuWidth, maxMenuWidth, maxMenuHeight, onBlur, onFocus, inline, fullWidth, }: SingleSelectProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const SingleSelect: ({ label, subLabel, hintText, required, helpIconText, placeholder, error, errorMessage, size, items, name, variant, disabled, selected, onSelect, enableSearch, searchPlaceholder, slot, customTrigger, useDrawerOnMobile, alignment, side, sideOffset, alignOffset, minMenuWidth, maxMenuWidth, maxMenuHeight, onBlur, onFocus, inline, fullWidth, enableVirtualization, virtualListItemHeight, virtualListOverscan, itemsToRender, onEndReached, endReachedThreshold, hasMore, loadingComponent, }: SingleSelectProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default SingleSelect;
@@ -17,6 +17,14 @@ type SingleSelectMenuProps = {
17
17
  alignOffset?: number;
18
18
  open: boolean;
19
19
  onOpenChange: (open: boolean) => void;
20
+ enableVirtualization?: boolean;
21
+ virtualListItemHeight?: number;
22
+ virtualListOverscan?: number;
23
+ itemsToRender?: number;
24
+ onEndReached?: () => void;
25
+ endReachedThreshold?: number;
26
+ hasMore?: boolean;
27
+ loadingComponent?: React.ReactNode;
20
28
  };
21
- declare const SingleSelectMenu: ({ items, selected, onSelect, trigger, minMenuWidth, maxMenuWidth, maxMenuHeight, enableSearch, searchPlaceholder, disabled, alignment, side, sideOffset, alignOffset, open, onOpenChange, }: SingleSelectMenuProps) => import("react/jsx-runtime").JSX.Element;
29
+ declare const SingleSelectMenu: ({ items, selected, onSelect, trigger, minMenuWidth, maxMenuWidth, maxMenuHeight, enableSearch, searchPlaceholder, disabled, alignment, side, sideOffset, alignOffset, open, onOpenChange, enableVirtualization, virtualListItemHeight, virtualListOverscan, itemsToRender, onEndReached, endReachedThreshold, hasMore, loadingComponent, }: SingleSelectMenuProps) => import("react/jsx-runtime").JSX.Element;
22
30
  export default SingleSelectMenu;
@@ -95,4 +95,12 @@ export type SingleSelectProps = {
95
95
  error?: boolean;
96
96
  errorMessage?: string;
97
97
  fullWidth?: boolean;
98
+ enableVirtualization?: boolean;
99
+ virtualListItemHeight?: number;
100
+ virtualListOverscan?: number;
101
+ itemsToRender?: number;
102
+ onEndReached?: () => void;
103
+ endReachedThreshold?: number;
104
+ hasMore?: boolean;
105
+ loadingComponent?: React.ReactNode;
98
106
  };
@@ -24,9 +24,11 @@ export type StatCardAxisConfig = {
24
24
  type?: AxisType;
25
25
  tickFormatter?: (value: string | number) => string;
26
26
  dateOnly?: boolean;
27
- smart?: boolean;
28
- timeZone?: string;
29
- hour12?: boolean;
27
+ useUTC?: boolean;
28
+ formatString?: string;
29
+ timeOnly?: boolean;
30
+ showYear?: boolean;
31
+ smartDateTimeFormat?: boolean;
30
32
  };
31
33
  export type StatCardProps = {
32
34
  title: string;
@@ -1,3 +1,3 @@
1
1
  import { TooltipProps } from './types';
2
- export declare const Tooltip: ({ children: trigger, content, side, align, showArrow, size, slot, slotDirection, delayDuration, offset, open, }: TooltipProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const Tooltip: ({ children: trigger, content, side, align, showArrow, size, slot, slotDirection, delayDuration, offset, open, maxWidth, }: TooltipProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default Tooltip;
@@ -30,4 +30,5 @@ export type TooltipProps = {
30
30
  slotDirection?: TooltipSlotDirection;
31
31
  delayDuration?: number;
32
32
  offset?: number;
33
+ maxWidth?: string;
33
34
  };
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { VirtualListProps, VirtualListRef, VirtualListItem } from './types';
3
+ declare const VirtualList: React.ForwardRefExoticComponent<VirtualListProps<VirtualListItem> & React.RefAttributes<VirtualListRef>>;
4
+ export default VirtualList;
@@ -0,0 +1,3 @@
1
+ export { default as VirtualList } from './VirtualList';
2
+ export { useVirtualList } from './utils';
3
+ export type { VirtualListItem, VirtualListProps, VirtualListRef, VirtualListRenderParams, UseVirtualListParams, UseVirtualListReturn, } from './types';
@@ -0,0 +1,79 @@
1
+ import { default as React } from 'react';
2
+ export type VirtualListItem = {
3
+ id: string | number;
4
+ height?: number;
5
+ data?: Record<string, unknown>;
6
+ };
7
+ export type VirtualListRenderParams<T extends VirtualListItem> = {
8
+ item: T;
9
+ index: number;
10
+ style: React.CSSProperties;
11
+ };
12
+ export type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';
13
+ export type VisibleRange = {
14
+ startIndex: number;
15
+ endIndex: number;
16
+ };
17
+ export type VirtualListProps<T extends VirtualListItem> = {
18
+ items: T[];
19
+ itemHeight?: number | ((item: T, index: number) => number);
20
+ containerHeight?: number;
21
+ overscan?: number;
22
+ onScroll?: (scrollTop: number) => void;
23
+ renderItem: (params: VirtualListRenderParams<T>) => React.ReactNode;
24
+ className?: string;
25
+ style?: React.CSSProperties;
26
+ getItemHeight?: (item: T, index: number) => number;
27
+ dynamicHeight?: boolean;
28
+ estimatedItemHeight?: number;
29
+ ssrMode?: boolean;
30
+ ariaRole?: 'listbox' | 'menu' | 'table' | 'list';
31
+ onKeyDown?: (event: React.KeyboardEvent) => void;
32
+ emptyState?: React.ReactNode;
33
+ throttleScrollMs?: number;
34
+ onEndReached?: () => void;
35
+ endReachedThreshold?: number;
36
+ isLoading?: boolean;
37
+ loadingComponent?: React.ReactNode;
38
+ hasMore?: boolean;
39
+ onRangeChange?: (range: VisibleRange) => void;
40
+ initialScrollOffset?: number;
41
+ initialScrollIndex?: number;
42
+ scrollAlignment?: ScrollAlignment;
43
+ itemsToRender?: number;
44
+ minHeight?: number;
45
+ maxHeight?: number;
46
+ maintainScrollPosition?: boolean;
47
+ };
48
+ export type VirtualListRef = {
49
+ scrollTo: (scrollTop: number, smooth?: boolean) => void;
50
+ scrollToIndex: (index: number, alignment?: ScrollAlignment, smooth?: boolean) => void;
51
+ getScrollOffset: () => number;
52
+ recalculateHeights: () => void;
53
+ getVisibleRange: () => VisibleRange;
54
+ measureItem: (index: number) => void;
55
+ };
56
+ export type UseVirtualListParams<T extends VirtualListItem> = {
57
+ items: T[];
58
+ itemHeight?: number | ((item: T, index: number) => number);
59
+ containerHeight: number;
60
+ overscan?: number;
61
+ getItemHeight?: (item: T, index: number) => number;
62
+ dynamicHeight?: boolean;
63
+ ssrMode?: boolean;
64
+ estimatedItemHeight?: number;
65
+ itemsToRender?: number;
66
+ minHeight?: number;
67
+ maxHeight?: number;
68
+ };
69
+ export type UseVirtualListReturn = {
70
+ scrollTop: number;
71
+ setScrollTop: React.Dispatch<React.SetStateAction<number>>;
72
+ totalHeight: number;
73
+ itemOffsets: number[];
74
+ itemHeights: number[];
75
+ recalculateHeights: () => void;
76
+ startIndex: number;
77
+ endIndex: number;
78
+ measureItem: (index: number, height: number) => void;
79
+ };
@@ -0,0 +1,30 @@
1
+ import { VirtualListItem, UseVirtualListParams, UseVirtualListReturn, ScrollAlignment } from './types';
2
+ export declare function throttle<T extends (...args: unknown[]) => unknown>(func: T, wait: number): (...args: Parameters<T>) => void;
3
+ export declare const isBrowser: boolean;
4
+ export declare const findEndIndexBinarySearch: (startIndex: number, viewportBottom: number, itemOffsets: number[], itemsLength: number, overscan: number) => number;
5
+ export declare const calculateFixedHeightRange: (scrollTop: number, containerHeight: number, itemHeight: number, itemsLength: number, overscan: number, itemsToRender?: number) => {
6
+ startIndex: number;
7
+ endIndex: number;
8
+ };
9
+ export declare const calculateDynamicHeightRange: (scrollTop: number, containerHeight: number, itemOffsets: number[], itemsLength: number, overscan: number, itemsToRender?: number) => {
10
+ startIndex: number;
11
+ endIndex: number;
12
+ };
13
+ export declare const calculateItemHeights: <T extends VirtualListItem>(items: T[], itemHeight?: number | ((item: T, index: number) => number), getItemHeight?: (item: T, index: number) => number, estimatedItemHeight?: number, minHeight?: number, maxHeight?: number, measuredHeights?: Map<number, number>) => number[];
14
+ export declare const constrainHeight: (height: number, minHeight?: number, maxHeight?: number) => number;
15
+ export declare const calculateItemOffsets: (itemHeights: number[]) => {
16
+ totalHeight: number;
17
+ itemOffsets: number[];
18
+ };
19
+ export declare function useVirtualList<T extends VirtualListItem>({ items, itemHeight, containerHeight, overscan, getItemHeight, ssrMode, estimatedItemHeight, itemsToRender, minHeight, maxHeight, }: UseVirtualListParams<T>): UseVirtualListReturn;
20
+ export declare const handleVirtualListKeyDown: (e: React.KeyboardEvent<HTMLDivElement>, ariaRole: string, totalHeight: number, containerRef: React.RefObject<HTMLDivElement | null>, onKeyDown?: (event: React.KeyboardEvent) => void) => void;
21
+ export declare const calculateScrollForAlignment: (index: number, alignment: ScrollAlignment, containerHeight: number, itemOffsets: number[], itemHeights: number[], itemsLength: number) => number;
22
+ export declare const scrollToPosition: (containerRef: React.RefObject<HTMLDivElement | null>, scrollTop: number, smooth?: boolean) => void;
23
+ export declare const scrollToIndex: (containerRef: React.RefObject<HTMLDivElement | null>, index: number, itemOffsets: number[], itemHeights: number[], itemsLength: number, containerHeight: number, alignment?: ScrollAlignment, smooth?: boolean) => void;
24
+ export declare const createVirtualItemStyle: (top: number, height: number, useAbsolute?: boolean) => React.CSSProperties;
25
+ export declare const setupResizeObserver: (dynamicHeight: boolean, isMounted: boolean, containerRef: React.RefObject<HTMLDivElement | null>, measureItem: (index: number, height: number) => void) => (() => void) | undefined;
26
+ export declare const checkEndReached: (scrollTop: number, totalHeight: number, containerHeight: number, threshold: number) => boolean;
27
+ export declare const usePreviousRange: (startIndex: number, endIndex: number, onRangeChange?: (range: {
28
+ startIndex: number;
29
+ endIndex: number;
30
+ }) => void) => void;
package/dist/main.d.ts CHANGED
@@ -31,6 +31,7 @@ export * from './components/ProgressBar';
31
31
  export * from './components/Drawer';
32
32
  export * from './components/Skeleton';
33
33
  export * from './components/KeyValuePair';
34
+ export * from './components/VirtualList';
34
35
  export * from './components/ButtonGroup';
35
36
  export * from './components/Button';
36
37
  export * from './context';