@servicetitan/anvil2 2.9.4 → 2.9.5

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,13 +1,13 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, useRef, useMemo, useState, useLayoutEffect } from 'react';
2
+ import { forwardRef, useState, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
3
3
  import { d as BreakpointSm } from './primitive-C3RFDRA8.js';
4
4
  import { S as SrOnly } from './SrOnly-eUpYGpAT.js';
5
5
  import { c as cx } from './index-De1g9FRV.js';
6
6
  import { B as ButtonToggle } from './ButtonToggle-DaFQ3DBG.js';
7
7
  import { S as SvgMoreHoriz } from './more_horiz-DJgdQiy0.js';
8
+ import { B as Button } from './Button-BdrrhBTI.js';
8
9
  import { M as Menu } from './Menu-CCavGohP.js';
9
10
  import { S as SvgKeyboardArrowDown } from './keyboard_arrow_down-C8WQ38p1.js';
10
- import { B as Button } from './Button-BdrrhBTI.js';
11
11
  import { F as Flex } from './Flex-WyyZm1bf.js';
12
12
  import { T as Text } from './Text-3Tbp9SGi.js';
13
13
  import { S as SvgKeyboardArrowLeft, a as SvgKeyboardArrowRight } from './keyboard_arrow_right-DZWNVytH.js';
@@ -47,31 +47,177 @@ const styles$5 = {
47
47
  "pagination-item-overflow-menu-content": "_pagination-item-overflow-menu-content_ainsh_7"
48
48
  };
49
49
 
50
+ const SCROLLER_MAX_HEIGHT = 200;
51
+ const ITEM_HEIGHT = 32;
52
+ const OVERSCAN = 5;
50
53
  const PaginationOverflowMenu = forwardRef((props, ref) => {
51
- const { startPage, endPage, length, onItemClick, ...rest } = props;
54
+ const { startPage, endPage, length, currentPage, onItemClick, ...rest } = props;
55
+ const [scrollTop, setScrollTop] = useState(0);
56
+ const [pendingFocusPage, setPendingFocusPage] = useState(null);
57
+ const scrollerRef = useRef(null);
58
+ const getInitialFocusPage = useCallback(() => {
59
+ return Math.min(endPage, Math.max(startPage, currentPage));
60
+ }, [currentPage, endPage, startPage]);
61
+ const getScrollTopForIndex = useCallback(
62
+ (index, currentScrollTop) => {
63
+ const itemTop = index * ITEM_HEIGHT;
64
+ const itemBottom = itemTop + ITEM_HEIGHT;
65
+ const viewportBottom = currentScrollTop + SCROLLER_MAX_HEIGHT;
66
+ if (itemTop < currentScrollTop) {
67
+ return itemTop;
68
+ }
69
+ if (itemBottom > viewportBottom) {
70
+ return itemBottom - SCROLLER_MAX_HEIGHT;
71
+ }
72
+ return currentScrollTop;
73
+ },
74
+ []
75
+ );
76
+ const syncScrollTop = useCallback((nextScrollTop) => {
77
+ setScrollTop(nextScrollTop);
78
+ if (scrollerRef.current && scrollerRef.current.scrollTop !== nextScrollTop) {
79
+ scrollerRef.current.scrollTop = nextScrollTop;
80
+ }
81
+ }, []);
82
+ const focusLogicalPage = useCallback(
83
+ (pageNumber) => {
84
+ const targetIndex = pageNumber - startPage;
85
+ const nextScrollTop = getScrollTopForIndex(targetIndex, scrollTop);
86
+ if (nextScrollTop !== scrollTop) {
87
+ syncScrollTop(nextScrollTop);
88
+ }
89
+ setPendingFocusPage(pageNumber);
90
+ },
91
+ [getScrollTopForIndex, scrollTop, startPage, syncScrollTop]
92
+ );
93
+ const handleScroll = useCallback((event) => {
94
+ setScrollTop(event.currentTarget.scrollTop);
95
+ }, []);
96
+ const handleItemKeyDown = useCallback(
97
+ (event, pageNumber) => {
98
+ if (event.code !== "ArrowDown" && event.code !== "ArrowUp") {
99
+ return;
100
+ }
101
+ event.preventDefault();
102
+ event.stopPropagation();
103
+ const nextPage = event.code === "ArrowDown" ? pageNumber === endPage ? startPage : pageNumber + 1 : pageNumber === startPage ? endPage : pageNumber - 1;
104
+ focusLogicalPage(nextPage);
105
+ },
106
+ [endPage, focusLogicalPage, startPage]
107
+ );
108
+ const visibleCount = Math.ceil(SCROLLER_MAX_HEIGHT / ITEM_HEIGHT);
109
+ const startIndex = Math.max(
110
+ 0,
111
+ Math.floor(scrollTop / ITEM_HEIGHT) - OVERSCAN
112
+ );
113
+ const endIndex = Math.min(length, startIndex + visibleCount + OVERSCAN * 2);
114
+ const totalSize = length * ITEM_HEIGHT;
115
+ const visibleIndices = useMemo(() => {
116
+ const indices = [];
117
+ for (let i = startIndex; i < endIndex; i++) {
118
+ indices.push(i);
119
+ }
120
+ return indices;
121
+ }, [endIndex, startIndex]);
122
+ useLayoutEffect(() => {
123
+ if (pendingFocusPage === null) {
124
+ return;
125
+ }
126
+ const targetElement = document.querySelector(
127
+ `[data-pagination-page="${pendingFocusPage}"]`
128
+ );
129
+ if (!targetElement) {
130
+ return;
131
+ }
132
+ targetElement.focus();
133
+ setPendingFocusPage(null);
134
+ }, [pendingFocusPage, visibleIndices]);
52
135
  return /* @__PURE__ */ jsx("li", { className: styles$5["pagination-item-overflow-menu"], ref, ...rest, children: /* @__PURE__ */ jsx(
53
136
  Menu,
54
137
  {
55
- icon: SvgMoreHoriz,
56
- size: "small",
57
- appearance: "ghost",
58
- maxHeight: 200,
138
+ trigger: (triggerProps) => {
139
+ const isOpen = triggerProps["aria-expanded"] === true;
140
+ return /* @__PURE__ */ jsx(
141
+ Button,
142
+ {
143
+ ref: triggerProps.ref,
144
+ onClick: () => {
145
+ if (!isOpen) {
146
+ focusLogicalPage(getInitialFocusPage());
147
+ }
148
+ triggerProps.onClick?.();
149
+ },
150
+ onKeyDown: (event) => {
151
+ if (!isOpen && (event.code === "ArrowDown" || event.code === "ArrowUp")) {
152
+ event.preventDefault();
153
+ event.stopPropagation();
154
+ focusLogicalPage(getInitialFocusPage());
155
+ triggerProps.onClick?.();
156
+ return;
157
+ }
158
+ triggerProps.onKeyDown?.(event);
159
+ },
160
+ "aria-haspopup": triggerProps["aria-haspopup"],
161
+ "aria-controls": triggerProps["aria-controls"],
162
+ "aria-expanded": triggerProps["aria-expanded"],
163
+ "data-state": triggerProps["data-state"],
164
+ icon: SvgMoreHoriz,
165
+ size: "small",
166
+ appearance: "ghost",
167
+ "aria-label": "More pages"
168
+ }
169
+ );
170
+ },
59
171
  contentClassName: styles$5["pagination-item-overflow-menu-content"],
60
172
  "aria-label": "More pages",
61
- children: Array.from({ length }).map((_, index) => /* @__PURE__ */ jsx(
62
- Menu.Item,
173
+ children: /* @__PURE__ */ jsx(
174
+ "div",
63
175
  {
64
- label: `${startPage + index}`,
65
- onClick: () => {
66
- const selectedPage = startPage + index;
67
- onItemClick(selectedPage);
68
- setTimeout(() => {
69
- document.querySelector('[aria-current="page"]')?.focus();
70
- }, 100);
71
- }
72
- },
73
- index
74
- ))
176
+ ref: scrollerRef,
177
+ onScroll: handleScroll,
178
+ style: {
179
+ maxHeight: SCROLLER_MAX_HEIGHT,
180
+ overflowY: "auto",
181
+ position: "relative"
182
+ },
183
+ children: /* @__PURE__ */ jsx(
184
+ "div",
185
+ {
186
+ style: {
187
+ height: totalSize,
188
+ position: "relative",
189
+ width: "100%"
190
+ },
191
+ children: visibleIndices.map((index) => {
192
+ const pageNumber = startPage + index;
193
+ return /* @__PURE__ */ jsx(
194
+ Menu.Item,
195
+ {
196
+ "data-pagination-page": pageNumber,
197
+ label: `${pageNumber}`,
198
+ onKeyDown: (event) => handleItemKeyDown(event, pageNumber),
199
+ onClick: () => {
200
+ onItemClick(pageNumber);
201
+ setTimeout(() => {
202
+ document.querySelector('[aria-current="page"]')?.focus();
203
+ }, 100);
204
+ },
205
+ style: {
206
+ position: "absolute",
207
+ top: 0,
208
+ left: 0,
209
+ right: 0,
210
+ transform: `translateY(${index * ITEM_HEIGHT}px)`,
211
+ height: ITEM_HEIGHT
212
+ }
213
+ },
214
+ pageNumber
215
+ );
216
+ })
217
+ }
218
+ )
219
+ }
220
+ )
75
221
  },
76
222
  `${startPage}-${endPage}`
77
223
  ) });
@@ -417,6 +563,7 @@ const Pagination = forwardRef(
417
563
  startPage: item.startPage,
418
564
  endPage: item.endPage,
419
565
  length: item.length,
566
+ currentPage: page,
420
567
  onItemClick: (item2) => onPageChange?.(item2)
421
568
  },
422
569
  item.startPage
@@ -452,4 +599,4 @@ const Pagination = forwardRef(
452
599
  Pagination.displayName = "Pagination";
453
600
 
454
601
  export { Pagination as P };
455
- //# sourceMappingURL=Pagination-5YcocErj.js.map
602
+ //# sourceMappingURL=Pagination-YO69lIlZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination-YO69lIlZ.js","sources":["../src/components/Pagination/internal/PaginationItem.tsx","../src/components/Pagination/internal/PaginationOverflowMenu.tsx","../src/components/Pagination/internal/PaginationItemsPerPageMenu.tsx","../src/components/Pagination/internal/PaginationList.tsx","../src/components/Pagination/internal/PaginationTotalCount.tsx","../src/components/Pagination/internal/Pagination.tsx","../src/components/Pagination/internal/usePaginationArray.ts","../src/components/Pagination/Pagination.tsx"],"sourcesContent":["import { ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport cx from \"classnames\";\n\nimport { ButtonToggle } from \"../../ButtonToggle\";\n\nimport styles from \"./PaginationItem.module.scss\";\n\n/**\n * Props for the PaginationItem component\n * @extends ComponentPropsWithoutRef<\"li\">\n */\nexport type PaginationItemProps = ComponentPropsWithoutRef<\"li\"> & {\n /**\n * The page number to display.\n */\n page: number;\n /**\n * Whether this page item is currently active/selected.\n * @default false\n */\n isActive?: boolean;\n /**\n * Callback function called when the page item is clicked.\n */\n onClick?: () => void;\n};\n\n/**\n * PaginationItem component for displaying individual page numbers in pagination.\n *\n * Features:\n * - Displays page number as a toggle button\n * - Supports active state styling\n * - Fully accessible with proper ARIA attributes\n * - Integrates with pagination navigation system\n * - Consistent styling with design system\n *\n * @example\n * <PaginationItem\n * page={3}\n * isActive={true}\n * onClick={() => console.log('Page 3 clicked')}\n * />\n */\nexport const PaginationItem = forwardRef<HTMLLIElement, PaginationItemProps>(\n (props, ref) => {\n const { page, isActive, onClick, className, ...rest } = props;\n\n const paginationClassName = cx(styles[\"pagination-item\"], className);\n const paginationButtonClassName = cx(styles[\"pagination-item-button\"], {\n [styles.active]: isActive,\n });\n return (\n <li ref={ref} {...rest} className={paginationClassName}>\n <ButtonToggle\n className={paginationButtonClassName}\n size=\"small\"\n onClick={onClick}\n aria-current={isActive ? \"page\" : undefined}\n aria-label={\n isActive ? `Current page, page ${page}` : `Go to page ${page}`\n }\n checked={isActive}\n >\n {page}\n </ButtonToggle>\n </li>\n );\n },\n);\n\nPaginationItem.displayName = \"PaginationItem\";\n","import {\n ComponentPropsWithoutRef,\n KeyboardEvent,\n UIEvent,\n forwardRef,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport IconMoreHoriz from \"@servicetitan/hammer-icon/mdi/round/more_horiz.svg\";\n\nimport { Button } from \"../../Button\";\nimport { Menu } from \"../../Menu\";\n\nimport styles from \"./PaginationOverflowMenu.module.scss\";\n\n// Visible scroller dimensions used to compute the windowed slice. Match the\n// previous `maxHeight={200}` behavior so popover sizing is unchanged.\n// `ITEM_HEIGHT` is conservative — slightly under the actual `Menu.Item`\n// height — so the rendered window slightly exceeds what's actually visible\n// and there's no flash of blank rows during scroll.\nconst SCROLLER_MAX_HEIGHT = 200;\nconst ITEM_HEIGHT = 32;\nconst OVERSCAN = 5;\n\n/**\n * Props for the PaginationOverflowMenu component\n * @extends ComponentPropsWithoutRef<\"li\">\n */\nexport type PaginationOverflowMenuProps = ComponentPropsWithoutRef<\"li\"> & {\n /**\n * The starting page number for the overflow range.\n */\n startPage: number;\n /**\n * The ending page number for the overflow range.\n */\n endPage: number;\n /**\n * The number of pages in the overflow range.\n */\n length: number;\n /**\n * The current active page in the parent pagination.\n */\n currentPage: number;\n /**\n * Callback function called when a page in the overflow menu is selected.\n * @param page The selected page number\n */\n onItemClick: (page: number) => void;\n};\n\n/**\n * PaginationOverflowMenu component for displaying overflow pages in pagination.\n *\n * Features:\n * - Displays ellipsis menu for large page ranges\n * - Renders the page items as a virtualized window — only the slice visible\n * in the scroller is in the DOM at any time, keeping pagination cheap\n * even when the overflow spans tens of thousands of pages\n * - Integrates with pagination navigation system\n * - Fully accessible with proper ARIA labels\n * - Consistent styling with design system\n *\n * @example\n * <PaginationOverflowMenu\n * startPage={4}\n * endPage={8}\n * length={5}\n * currentPage={4}\n * onItemClick={(page) => console.log('Page selected:', page)}\n * />\n */\nexport const PaginationOverflowMenu = forwardRef<\n HTMLLIElement,\n PaginationOverflowMenuProps\n>((props, ref) => {\n const { startPage, endPage, length, currentPage, onItemClick, ...rest } =\n props;\n\n // Layout-independent window: derive the visible slice from `scrollTop`\n // and the fixed `SCROLLER_MAX_HEIGHT`/`ITEM_HEIGHT` constants. This is\n // sturdier than `tanstack/react-virtual` here because (a) we don't need\n // dynamic measurement — every item is the same size — and (b) the\n // calculation works in jsdom where layout is unresolved.\n const [scrollTop, setScrollTop] = useState(0);\n const [pendingFocusPage, setPendingFocusPage] = useState<number | null>(null);\n const scrollerRef = useRef<HTMLDivElement>(null);\n\n const getInitialFocusPage = useCallback(() => {\n return Math.min(endPage, Math.max(startPage, currentPage));\n }, [currentPage, endPage, startPage]);\n\n const getScrollTopForIndex = useCallback(\n (index: number, currentScrollTop: number) => {\n const itemTop = index * ITEM_HEIGHT;\n const itemBottom = itemTop + ITEM_HEIGHT;\n const viewportBottom = currentScrollTop + SCROLLER_MAX_HEIGHT;\n\n if (itemTop < currentScrollTop) {\n return itemTop;\n }\n\n if (itemBottom > viewportBottom) {\n return itemBottom - SCROLLER_MAX_HEIGHT;\n }\n\n return currentScrollTop;\n },\n [],\n );\n\n const syncScrollTop = useCallback((nextScrollTop: number) => {\n setScrollTop(nextScrollTop);\n\n if (\n scrollerRef.current &&\n scrollerRef.current.scrollTop !== nextScrollTop\n ) {\n scrollerRef.current.scrollTop = nextScrollTop;\n }\n }, []);\n\n const focusLogicalPage = useCallback(\n (pageNumber: number) => {\n const targetIndex = pageNumber - startPage;\n const nextScrollTop = getScrollTopForIndex(targetIndex, scrollTop);\n\n if (nextScrollTop !== scrollTop) {\n syncScrollTop(nextScrollTop);\n }\n\n setPendingFocusPage(pageNumber);\n },\n [getScrollTopForIndex, scrollTop, startPage, syncScrollTop],\n );\n\n const handleScroll = useCallback((event: UIEvent<HTMLDivElement>) => {\n setScrollTop(event.currentTarget.scrollTop);\n }, []);\n\n const handleItemKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, pageNumber: number) => {\n if (event.code !== \"ArrowDown\" && event.code !== \"ArrowUp\") {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const nextPage =\n event.code === \"ArrowDown\"\n ? pageNumber === endPage\n ? startPage\n : pageNumber + 1\n : pageNumber === startPage\n ? endPage\n : pageNumber - 1;\n\n focusLogicalPage(nextPage);\n },\n [endPage, focusLogicalPage, startPage],\n );\n\n const visibleCount = Math.ceil(SCROLLER_MAX_HEIGHT / ITEM_HEIGHT);\n const startIndex = Math.max(\n 0,\n Math.floor(scrollTop / ITEM_HEIGHT) - OVERSCAN,\n );\n const endIndex = Math.min(length, startIndex + visibleCount + OVERSCAN * 2);\n const totalSize = length * ITEM_HEIGHT;\n\n const visibleIndices = useMemo(() => {\n const indices: number[] = [];\n for (let i = startIndex; i < endIndex; i++) {\n indices.push(i);\n }\n return indices;\n }, [endIndex, startIndex]);\n\n useLayoutEffect(() => {\n if (pendingFocusPage === null) {\n return;\n }\n\n const targetElement = document.querySelector<HTMLElement>(\n `[data-pagination-page=\"${pendingFocusPage}\"]`,\n );\n\n if (!targetElement) {\n return;\n }\n\n targetElement.focus();\n setPendingFocusPage(null);\n }, [pendingFocusPage, visibleIndices]);\n\n return (\n <li className={styles[\"pagination-item-overflow-menu\"]} ref={ref} {...rest}>\n <Menu\n trigger={(triggerProps) => {\n const isOpen = triggerProps[\"aria-expanded\"] === true;\n\n return (\n <Button\n ref={triggerProps.ref}\n onClick={() => {\n if (!isOpen) {\n focusLogicalPage(getInitialFocusPage());\n }\n triggerProps.onClick?.();\n }}\n onKeyDown={(event) => {\n if (\n !isOpen &&\n (event.code === \"ArrowDown\" || event.code === \"ArrowUp\")\n ) {\n event.preventDefault();\n event.stopPropagation();\n focusLogicalPage(getInitialFocusPage());\n triggerProps.onClick?.();\n return;\n }\n\n triggerProps.onKeyDown?.(event);\n }}\n aria-haspopup={triggerProps[\"aria-haspopup\"]}\n aria-controls={triggerProps[\"aria-controls\"]}\n aria-expanded={triggerProps[\"aria-expanded\"]}\n data-state={triggerProps[\"data-state\"]}\n icon={IconMoreHoriz}\n size=\"small\"\n appearance=\"ghost\"\n aria-label=\"More pages\"\n />\n );\n }}\n // Menu's built-in scroller is bypassed: we render our own\n // windowed scroller below and need the popover to wrap it\n // without imposing its own height clipping.\n key={`${startPage}-${endPage}`}\n contentClassName={styles[\"pagination-item-overflow-menu-content\"]}\n aria-label=\"More pages\"\n >\n <div\n ref={scrollerRef}\n onScroll={handleScroll}\n style={{\n maxHeight: SCROLLER_MAX_HEIGHT,\n overflowY: \"auto\",\n position: \"relative\",\n }}\n >\n <div\n style={{\n height: totalSize,\n position: \"relative\",\n width: \"100%\",\n }}\n >\n {visibleIndices.map((index) => {\n const pageNumber = startPage + index;\n return (\n <Menu.Item\n key={pageNumber}\n data-pagination-page={pageNumber}\n label={`${pageNumber}`}\n onKeyDown={(event) => handleItemKeyDown(event, pageNumber)}\n onClick={() => {\n onItemClick(pageNumber);\n // Re-focus the active page button after selection.\n // Overflow menus re-render in different DOM positions\n // across pagination state changes, so we look the\n // active page up by aria-current rather than holding\n // a ref.\n setTimeout(() => {\n document\n .querySelector<HTMLElement>('[aria-current=\"page\"]')\n ?.focus();\n }, 100);\n }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n transform: `translateY(${index * ITEM_HEIGHT}px)`,\n height: ITEM_HEIGHT,\n }}\n />\n );\n })}\n </div>\n </div>\n </Menu>\n </li>\n );\n});\n\nPaginationOverflowMenu.displayName = \"PaginationOverflowMenu\";\n","import { forwardRef, KeyboardEvent } from \"react\";\nimport IconKeyboardArrowDown from \"@servicetitan/hammer-icon/mdi/round/keyboard_arrow_down.svg\";\n\nimport { Button } from \"../../Button\";\nimport { Flex } from \"../../Flex\";\nimport { Menu } from \"../../Menu\";\nimport { Text } from \"../../Text\";\n\nimport styles from \"./PaginationItemsPerPageMenu.module.scss\";\n\n/**\n * Props for the PaginationItemsPerPageMenu component\n */\nexport type PaginationItemsPerPageMenuProps = {\n /**\n * The currently selected number of items per page.\n */\n itemsPerPage: number;\n /**\n * Array of available options for items per page.\n */\n itemsPerPageOptions: number[];\n /**\n * Callback function called when the items per page selection changes.\n * @param itemsPerPage The new number of items per page\n */\n onItemsPerPageChange: (itemsPerPage: number) => void;\n /**\n * Custom label displayed before the items-per-page selector.\n * @default \"Rows per page\"\n */\n itemsPerPageLabel?: string;\n};\n\n/**\n * PaginationItemsPerPageMenu component for selecting the number of items per page.\n *\n * Features:\n * - Displays current items per page selection\n * - Provides dropdown menu with available options\n * - Integrates with pagination system\n * - Shows \"Rows per page\" label for clarity\n * - Fully accessible with proper ARIA attributes\n * - Consistent styling with design system\n *\n * @example\n * <PaginationItemsPerPageMenu\n * itemsPerPage={10}\n * itemsPerPageOptions={[5, 10, 25, 50]}\n * onItemsPerPageChange={(itemsPerPage) => console.log('Items per page:', itemsPerPage)}\n * />\n */\nexport const PaginationItemsPerPageMenu = forwardRef<\n HTMLDivElement,\n PaginationItemsPerPageMenuProps\n>((props, ref) => {\n const {\n itemsPerPage,\n itemsPerPageOptions,\n onItemsPerPageChange,\n itemsPerPageLabel = \"Rows per page\",\n } = props;\n\n // This is a workaround to focus the first item in the menu when the arrow keys are pressed with the custom menu trigger\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.code === \"ArrowDown\" || e.code === \"ArrowUp\") {\n e.preventDefault();\n const menuId = e.currentTarget.getAttribute(\"aria-controls\");\n\n setTimeout(() => {\n const menu = menuId ? document.getElementById(menuId) : null;\n const menuItems =\n menu?.querySelectorAll('[data-anv=\"menu-item\"]') ||\n document.querySelectorAll('[data-anv=\"menu-item\"]');\n\n (menuItems[0] as HTMLElement)?.focus();\n }, 100);\n }\n };\n\n return (\n <Flex alignItems=\"center\" gap=\"2\" ref={ref}>\n <Text size=\"small\">{itemsPerPageLabel}</Text>\n <Menu\n trigger={({ ref, ...rest }) => {\n return (\n <Button\n ref={ref}\n {...rest}\n onKeyDown={handleKeyDown}\n className={styles[\"pagination-items-per-page-button\"]}\n appearance=\"ghost\"\n icon={{ after: IconKeyboardArrowDown }}\n size=\"small\"\n >\n {itemsPerPage}\n </Button>\n );\n }}\n >\n {itemsPerPageOptions.map((option) => (\n <Menu.Item\n key={option}\n label={option}\n onClick={() => {\n onItemsPerPageChange?.(option);\n }}\n />\n ))}\n </Menu>\n </Flex>\n );\n});\n\nPaginationItemsPerPageMenu.displayName = \"PaginationItemsPerPageMenu\";\n","import { forwardRef } from \"react\";\nimport IconKeyboardArrowLeft from \"@servicetitan/hammer-icon/mdi/round/keyboard_arrow_left.svg\";\nimport IconKeyboardArrowRight from \"@servicetitan/hammer-icon/mdi/round/keyboard_arrow_right.svg\";\n\nimport { Button } from \"../../Button\";\n\nimport cx from \"classnames\";\nimport itemStyles from \"./PaginationItem.module.scss\";\nimport styles from \"./PaginationList.module.scss\";\n\ntype PaginationListProps = {\n page: number;\n totalPages: number;\n hasTotalItemCount?: boolean;\n onPageChange: (page: number) => void;\n children: React.ReactNode;\n className?: string;\n};\n\nexport const PaginationList = forwardRef<HTMLUListElement, PaginationListProps>(\n (props, ref) => {\n const {\n page,\n totalPages,\n hasTotalItemCount,\n children,\n onPageChange,\n className,\n } = props;\n\n const paginationListClassName = cx(styles[\"pagination-list\"], className);\n\n return (\n <ul ref={ref} className={paginationListClassName}>\n <li className={itemStyles[\"pagination-item\"]}>\n <Button\n appearance=\"ghost\"\n icon={IconKeyboardArrowLeft}\n size=\"small\"\n aria-label=\"Previous page\"\n disabled={page === 1}\n onClick={() => {\n if (page > 1) {\n onPageChange?.(page - 1);\n }\n }}\n />\n </li>\n {children}\n <li className={itemStyles[\"pagination-item\"]}>\n <Button\n appearance=\"ghost\"\n icon={IconKeyboardArrowRight}\n size=\"small\"\n aria-label=\"Next page\"\n disabled={\n hasTotalItemCount !== false &&\n (totalPages === 0 || page === totalPages)\n }\n onClick={() => {\n if (totalPages === 0 || page < totalPages) {\n onPageChange?.(page + 1);\n }\n }}\n />\n </li>\n </ul>\n );\n },\n);\n\nPaginationList.displayName = \"PaginationList\";\n","import cx from \"classnames\";\n\nimport { Text } from \"../../Text\";\n\nimport styles from \"./PaginationTotalCount.module.scss\";\n\nexport const PaginationTotalCount = ({\n itemRangeText,\n className,\n}: {\n itemRangeText: string;\n className?: string;\n}) => {\n const paginationTotalCountClassName = cx(\n styles[\"pagination-total-count\"],\n className,\n );\n return (\n <Text\n size=\"small\"\n className={paginationTotalCountClassName}\n aria-hidden=\"true\"\n >\n {itemRangeText}\n </Text>\n );\n};\n","import { ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport cx from \"classnames\";\n\nimport { PaginationItem } from \"./PaginationItem\";\nimport { PaginationOverflowMenu } from \"./PaginationOverflowMenu\";\nimport { PaginationItemsPerPageMenu } from \"./PaginationItemsPerPageMenu\";\nimport { PaginationList } from \"./PaginationList\";\nimport { PaginationTotalCount } from \"./PaginationTotalCount\";\n\nimport styles from \"./Pagination.module.scss\";\n\n/**\n * Props for the Pagination component\n * @extends ComponentPropsWithoutRef<\"nav\">\n */\nexport type PaginationProps = ComponentPropsWithoutRef<\"nav\">;\n\n/**\n * Pagination component for navigating through paginated content.\n *\n * Features:\n * - Provides navigation controls for paginated data\n * - Supports compound components for flexible pagination layouts\n * - Includes list, items, overflow menu, items per page menu, and total count\n * - Accessible navigation with proper ARIA roles\n * - Customizable styling and layout\n *\n * @example\n * <Pagination>\n * <Pagination.List>\n * <Pagination.Item>1</Pagination.Item>\n * <Pagination.Item>2</Pagination.Item>\n * <Pagination.OverflowMenu />\n * <Pagination.Item>10</Pagination.Item>\n * </Pagination.List>\n * <Pagination.ItemsPerPageMenu />\n * <Pagination.TotalCount />\n * </Pagination>\n */\nexport const Pagination = Object.assign(\n forwardRef<HTMLElement, PaginationProps>(\n function PaginationInner(props, ref) {\n const { className, children, ...rest } = props;\n\n const paginationClassName = cx(styles.pagination, className);\n\n return (\n <nav ref={ref} className={paginationClassName} {...rest}>\n {children}\n </nav>\n );\n },\n ),\n {\n List: PaginationList,\n Item: PaginationItem,\n OverflowMenu: PaginationOverflowMenu,\n ItemsPerPageMenu: PaginationItemsPerPageMenu,\n TotalCount: PaginationTotalCount,\n },\n);\nPagination.displayName = \"Pagination\";\n","import { useMemo, useRef } from \"react\";\n\nexport type PageArrayItem =\n | { type: \"page\"; page: number }\n | { type: \"overflow\"; startPage: number; endPage: number; length: number };\n\n/**\n * Custom hook for managing pagination array state and generation.\n *\n * Features:\n * - Automatically generates pagination array based on current page and total pages\n * - Avoids unnecessary regeneration if the current page is already visible\n * - Updates array when page or total pages change and the visible set must change\n * - Handles jumps to first/last page with overflow between current and target\n * - Provides stable reference for the current pagination array\n *\n * @param page The currently selected page\n * @param totalPages Total number of pages\n * @param maxArrayLength Maximum length of the pagination array (including overflows)\n * @returns The current pagination array\n *\n * @example\n * const pageArray = usePaginationArray({\n * page: 5,\n * totalPages: 10,\n * maxArrayLength: 7\n * });\n */\nexport const usePaginationArray = ({\n page,\n totalPages,\n maxArrayLength = 7,\n}: {\n page: number;\n totalPages: number;\n maxArrayLength?: number;\n}): PageArrayItem[] => {\n const prevRef = useRef<{\n array: PageArrayItem[];\n totalPages: number;\n maxArrayLength: number;\n prevPage: number;\n } | null>(null);\n\n return useMemo(() => {\n const maxPagesToShow = maxArrayLength - 2;\n let result: PageArrayItem[] = [];\n const addRange = (start: number, end: number) => {\n const count = end - start + 1;\n if (count === 1) {\n result.push({ type: \"page\", page: start });\n } else if (count >= 2) {\n result.push({\n type: \"overflow\",\n startPage: start,\n endPage: end,\n length: count,\n });\n }\n };\n\n if (totalPages <= maxArrayLength) {\n result = Array.from({ length: totalPages }, (_, i) => ({\n type: \"page\" as const,\n page: i + 1,\n }));\n } else if (page <= maxPagesToShow) {\n // Leading section\n for (let i = 1; i <= maxPagesToShow; i++) {\n result.push({ type: \"page\", page: i });\n }\n addRange(maxArrayLength - 1, totalPages - 1);\n result.push({ type: \"page\", page: totalPages });\n } else if (page >= totalPages - maxPagesToShow + 1) {\n // Trailing section\n result.push({ type: \"page\", page: 1 });\n addRange(2, totalPages - maxPagesToShow);\n for (let i = totalPages - (maxPagesToShow - 1); i <= totalPages; i++) {\n result.push({ type: \"page\", page: i });\n }\n } else {\n // Middle section\n result.push({ type: \"page\", page: 1 });\n addRange(2, page - 2);\n result.push({ type: \"page\", page: page - 1 });\n result.push({ type: \"page\", page: page });\n result.push({ type: \"page\", page: page + 1 });\n addRange(page + 2, totalPages - 1);\n result.push({ type: \"page\", page: totalPages });\n }\n\n const prev = prevRef.current;\n\n // Check if we should remake array due to overflow between pages or new page being in overflow\n let shouldRemakeForJump = false;\n if (\n prev &&\n prev.totalPages === totalPages &&\n prev.maxArrayLength === maxArrayLength\n ) {\n // Check if there is overflow between the new page and the current page\n const start = Math.min(prev.prevPage, page);\n const end = Math.max(prev.prevPage, page);\n const hasOverflowBetween = prev.array.some(\n (item) =>\n item.type === \"overflow\" &&\n // Check if overflow intersects with the range (not completely covers)\n !(item.endPage < start || item.startPage > end),\n );\n\n // Check if the new page is part of an overflow\n const newPageInOverflow = prev.array.some(\n (item) =>\n item.type === \"overflow\" &&\n item.startPage <= page &&\n item.endPage >= page,\n );\n\n shouldRemakeForJump = hasOverflowBetween || newPageInOverflow;\n }\n\n // If we should remake for jump, always return the new array\n if (shouldRemakeForJump) {\n prevRef.current = {\n array: result,\n totalPages,\n maxArrayLength,\n prevPage: page,\n };\n return result;\n }\n\n // Optimization: if the new page is already present in the previous array, reuse the array\n if (\n prev &&\n prev.totalPages === totalPages &&\n prev.maxArrayLength === maxArrayLength &&\n prev.array.some((item) => item.type === \"page\" && item.page === page)\n ) {\n return prev.array;\n }\n\n prevRef.current = {\n array: result,\n totalPages,\n maxArrayLength,\n prevPage: page,\n };\n return result;\n }, [page, totalPages, maxArrayLength]);\n};\n","import { forwardRef, useLayoutEffect, useRef, useState } from \"react\";\nimport { core } from \"@servicetitan/hammer-token\";\n\nimport { DataTrackingId } from \"../../types\";\nimport { SrOnly } from \"../SrOnly\";\nimport { useTrackingId, useMergeRefs } from \"../../hooks\";\n\nimport {\n Pagination as BasePagination,\n type PaginationProps as BasePaginationProps,\n} from \"./internal/Pagination\";\nimport { usePaginationArray } from \"./internal/usePaginationArray\";\n\nimport cx from \"classnames\";\nimport styles from \"./Pagination.module.scss\";\n\n/**\n * Props for the Pagination component\n * @property {number} page - The current page number\n * @property {number} itemsPerPage - Number of items displayed per page\n * @property {number[]} [itemsPerPageOptions] - Available options for items per page selection\n * @property {number} [totalItemCount] - Total number of items across all pages\n * @property {boolean} [showCount] - Whether to display the item count information\n * @property {(page: number) => void} [onPageChange] - Callback when page changes\n * @property {(itemsPerPage: number) => void} [onItemsPerPageChange] - Callback when items per page changes\n * @property {string} [itemsPerPageLabel] - Custom label displayed before the items-per-page selector. Defaults to \"Rows per page\"\n * @extends Omit<BasePaginationProps, \"children\">\n * @extends DataTrackingId\n */\nexport type PaginationProps = Omit<BasePaginationProps, \"children\"> &\n DataTrackingId & {\n page: number;\n itemsPerPage: number;\n itemsPerPageOptions?: number[];\n totalItemCount?: number;\n showCount?: boolean;\n onPageChange?: (page: number) => void;\n onItemsPerPageChange?: (itemsPerPage: number) => void;\n itemsPerPageLabel?: string;\n };\n\n/**\n * Pagination component for navigating through paginated content with automatic page array generation.\n *\n * Features:\n * - Automatic page array generation with overflow handling\n * - Supports items per page selection with customizable options\n * - Displays item count information with screen reader support\n * - Handles edge cases like invalid page numbers\n * - Includes previous/next navigation buttons\n * - Supports overflow menus for large page ranges\n * - Fully accessible with proper ARIA attributes\n * - Automatic tracking ID generation for analytics\n *\n * @example\n * <Pagination\n * page={1}\n * itemsPerPage={10}\n * totalItemCount={100}\n * itemsPerPageOptions={[10, 20, 50]}\n * showCount={true}\n * onPageChange={(page) => console.log('Page changed to:', page)}\n * onItemsPerPageChange={(itemsPerPage) => console.log('Items per page:', itemsPerPage)}\n * />\n */\nexport const Pagination = forwardRef<HTMLDivElement, PaginationProps>(\n (props, ref) => {\n const {\n \"aria-label\": ariaLabel,\n page,\n itemsPerPage,\n itemsPerPageOptions,\n totalItemCount: totalItemCountProp,\n showCount,\n onPageChange,\n onItemsPerPageChange,\n itemsPerPageLabel,\n className,\n ...rest\n } = props;\n\n const data = {\n \"aria-label\": ariaLabel,\n };\n\n const trackingId = useTrackingId({\n name: \"Pagination\",\n data,\n hasOverride: !!rest[\"data-tracking-id\"],\n });\n const totalItemCount = totalItemCountProp ?? 0;\n const totalPages = Math.ceil(totalItemCount / itemsPerPage);\n const elRef = useRef<HTMLDivElement>(null);\n const combinedRef = useMergeRefs([elRef, ref]);\n const [isNarrow, setIsNarrow] = useState(false);\n\n const pageArray = usePaginationArray({\n page,\n totalPages,\n maxArrayLength: 7,\n });\n\n // Check if current page is available in the pageArray, fallback to page 1 if not\n const isPageAvailable = pageArray.some(\n (item) => item.type === \"page\" && item.page === page,\n );\n\n if (!isPageAvailable && page !== 1 && totalPages > 0) {\n // Use requestAnimationFrame to avoid calling onPageChange during render\n requestAnimationFrame(() => {\n onPageChange?.(1);\n });\n }\n\n const firstItem = totalItemCount > 0 ? 1 + (page - 1) * itemsPerPage : 0;\n const lastItem = Math.min(firstItem - 1 + itemsPerPage, totalItemCount);\n const itemRangeText =\n totalItemCountProp === 0\n ? \"0 items\"\n : `${firstItem} - ${lastItem} of ${totalItemCount} items`;\n\n useLayoutEffect(() => {\n const resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) {\n setIsNarrow(\n entry.contentRect.width <\n Number(core.primitive.BreakpointSm.value.replace(\"px\", \"\")),\n );\n }\n });\n if (elRef.current) {\n resizeObserver.observe(elRef.current);\n }\n return () => {\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <BasePagination\n ref={combinedRef}\n data-tracking-id={trackingId}\n className={cx(styles.pagination, className)}\n aria-label={ariaLabel || \"Pagination navigation\"}\n {...rest}\n >\n <BasePagination.List\n page={page}\n totalPages={totalPages}\n hasTotalItemCount={totalItemCountProp !== undefined}\n onPageChange={(page) => onPageChange?.(page)}\n >\n {pageArray.map((item) => {\n if (item.type === \"page\") {\n return (\n <BasePagination.Item\n key={item.page}\n page={item.page}\n isActive={item.page === page}\n onClick={() => onPageChange?.(item.page)}\n />\n );\n }\n return (\n <BasePagination.OverflowMenu\n key={item.startPage}\n startPage={item.startPage}\n endPage={item.endPage}\n length={item.length}\n currentPage={page}\n onItemClick={(item) => onPageChange?.(item)}\n />\n );\n })}\n </BasePagination.List>\n {isNarrow === false && (\n <>\n {itemsPerPageOptions && (\n <BasePagination.ItemsPerPageMenu\n itemsPerPage={itemsPerPage}\n itemsPerPageOptions={itemsPerPageOptions}\n onItemsPerPageChange={(itemsPerPage) =>\n onItemsPerPageChange?.(itemsPerPage)\n }\n itemsPerPageLabel={itemsPerPageLabel}\n />\n )}\n {showCount && totalItemCountProp !== undefined && (\n <BasePagination.TotalCount itemRangeText={itemRangeText} />\n )}\n </>\n )}\n <SrOnly aria-live=\"polite\" aria-atomic=\"true\">\n Page {page} of {totalPages}, {itemRangeText}\n </SrOnly>\n </BasePagination>\n );\n },\n);\n\nPagination.displayName = \"Pagination\";\n"],"names":["styles","IconMoreHoriz","ref","IconKeyboardArrowDown","IconKeyboardArrowLeft","IconKeyboardArrowRight","Pagination","core.primitive.BreakpointSm","BasePagination","page","item","itemsPerPage"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { P as Pagination, P as default } from './Pagination-5YcocErj.js';
1
+ export { P as Pagination, P as default } from './Pagination-YO69lIlZ.js';
2
2
  //# sourceMappingURL=Pagination.js.map
package/dist/Table.js CHANGED
@@ -1,2 +1,2 @@
1
- export { C as COLUMN_TYPE_DEFAULTS, D as DataTable, b as booleanFormatter, a as chipsFormatter, c as createColumnHelper, d as currencyFormatter, i as dateFormatPresets, e as dateFormatter, f as dateTimeFormatter, g as getColumnTypeDefaults, h as htmlFormatter, m as markdownFormatter, n as numberFormatter, p as percentFormatter, r as resolveColumnTypeConfig, t as timeFormatPresets, j as timeFormatter, y as yearlessDateFormatter } from './DataTable-BPonNWnU.js';
1
+ export { C as COLUMN_TYPE_DEFAULTS, D as DataTable, b as booleanFormatter, a as chipsFormatter, c as createColumnHelper, d as currencyFormatter, i as dateFormatPresets, e as dateFormatter, f as dateTimeFormatter, g as getColumnTypeDefaults, h as htmlFormatter, m as markdownFormatter, n as numberFormatter, p as percentFormatter, r as resolveColumnTypeConfig, t as timeFormatPresets, j as timeFormatter, y as yearlessDateFormatter } from './DataTable-CbHaFuj2.js';
2
2
  //# sourceMappingURL=Table.js.map
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path transform="scale(1.5)" d="M11.363 8.722V4.275l1.772 1.665a.672.672 0 0 0 1.09-.216.66.66 0 0 0-.144-.724L11.17 2.195a.663.663 0 0 0-.94 0L7.195 5a.665.665 0 1 0 .94.94l1.894-1.665v4.447c0 .366.3.666.667.666s.667-.3.667-.666M4.914 7.667v4.446l-1.772-1.665a.672.672 0 0 0-1.091.216.66.66 0 0 0 .144.724l2.912 2.805a.663.663 0 0 0 .94 0l3.035-2.805a.665.665 0 1 0-.94-.94l-1.895 1.665V7.667c0-.367-.3-.667-.667-.667-.366 0-.666.3-.666.667"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.045 13.083v-6.67l2.657 2.497a1.008 1.008 0 0 0 1.635-.324.99.99 0 0 0-.215-1.086l-4.367-4.208a.995.995 0 0 0-1.41 0L10.793 7.5a.998.998 0 1 0 1.41 1.41l2.84-2.497v6.67c0 .549.45.999 1.001.999s1-.45 1-.999M7.371 11.5v6.67l-2.658-2.498a1.008 1.008 0 0 0-1.637.324.99.99 0 0 0 .216 1.086l4.369 4.207a.995.995 0 0 0 1.41 0l4.552-4.207a.998.998 0 1 0-1.41-1.41L9.37 18.169V11.5c0-.55-.45-1-1-1-.549 0-.999.45-.999 1"/></svg>
@@ -1,10 +1,9 @@
1
- import { ComponentPropsWithoutRef, Ref, ReactNode } from 'react';
1
+ import { ComponentPropsWithoutRef, forwardRef, Ref, ReactNode } from 'react';
2
2
  import { LayoutUtilProps } from '../../../../types';
3
3
  import { ColumnDef, CustomTableFooterCellProps, TableRow } from '../types';
4
4
  import { DataTableCacheOptions, DataTableEmptyState, DataTablePaginationConfig, DataTableRef, SortedColumn } from './types';
5
5
  export type { DataTableCacheOptions, DataTableRef, DataTableEmptyState, SortedColumn, };
6
- type DataTableCellValue = object | string | number | boolean | bigint | symbol | null | undefined;
7
- export type DataTableRowData = Record<PropertyKey, DataTableCellValue>;
6
+ export type DataTableRowData = object;
8
7
  /**
9
8
  * Props for the DataTable component
10
9
  * @extends LayoutUtilProps
@@ -205,7 +204,6 @@ declare function DataTableInner<T extends DataTableRowData>(props: DataTableProp
205
204
  * }}
206
205
  * />
207
206
  */
208
- type DataTableComponent = <T extends DataTableRowData>(props: DataTableProps<T> & {
207
+ export declare const DataTable: (<T extends DataTableRowData>(props: DataTableProps<T> & {
209
208
  ref?: Ref<DataTableRef>;
210
- }) => ReturnType<typeof DataTableInner>;
211
- export declare const DataTable: DataTableComponent;
209
+ }) => ReturnType<typeof DataTableInner>) & Pick<ReturnType<typeof forwardRef<DataTableRef, DataTableProps<DataTableRowData>>>, "$$typeof">;
@@ -3,6 +3,11 @@ import { TableRow } from '../../types';
3
3
  import { useColumnOrder } from './useColumnOrder';
4
4
  export type DataTableBodyRowProps<T> = {
5
5
  columnOrder: ReturnType<typeof useColumnOrder>["columnOrder"];
6
+ /**
7
+ * O(1) lookup of leaf-column-index → visual position. Replaces
8
+ * `columnOrder.indexOf(...)` per cell to keep large-table renders cheap.
9
+ */
10
+ columnIndexMap: ReturnType<typeof useColumnOrder>["columnIndexMap"];
6
11
  row: Row<T>;
7
12
  rowIndex: number;
8
13
  tableHasSubRows: boolean;
@@ -38,6 +43,6 @@ export type DataTableBodyRowProps<T> = {
38
43
  */
39
44
  getRowVersion?: (row: T) => unknown;
40
45
  };
41
- declare function DataTableBodyRowInner<T>({ columnOrder, row, rowIndex, tableHasSubRows, isExpanded, canExpand, depth, parentRowCanExpand, isActivatable, isActive, isTopMostActive, isReadOnly, onToggleActive, }: DataTableBodyRowProps<T>): import("react/jsx-runtime").JSX.Element;
46
+ declare function DataTableBodyRowInner<T>({ columnOrder: _columnOrder, columnIndexMap, row, rowIndex, tableHasSubRows, isExpanded, canExpand, depth, parentRowCanExpand, isActivatable, isActive, isTopMostActive, isReadOnly, onToggleActive, }: DataTableBodyRowProps<T>): import("react/jsx-runtime").JSX.Element;
42
47
  export declare const DataTableBodyRow: typeof DataTableBodyRowInner;
43
48
  export {};
@@ -8,10 +8,6 @@ export type DTFocusState = {
8
8
  * The last focused cell when the table was blurred or { rowIndex: 0, columnIndex: 0 } if never focused
9
9
  */
10
10
  focusRestorePoint: CellPosition;
11
- /**
12
- * Whether the focus has been disrupted by a sub component
13
- */
14
- hasFocusBeenDisrupted: boolean;
15
11
  };
16
12
  export type DTFocusStateContextValue = {
17
13
  getFocusedCell: () => CellPosition | null;
@@ -46,12 +42,6 @@ export type DTFocusCellManuallyAction = {
46
42
  export type DTBlurAction = {
47
43
  type: "BLUR";
48
44
  };
49
- export type DTFocusSubComponentAction = {
50
- type: "FOCUS_SUB_COMPONENT";
51
- };
52
- export type DTFocusSubComponentBlurAction = {
53
- type: "BLUR_SUB_COMPONENT";
54
- };
55
- export type DTFocusAction = DTFocusCellAction | DTFocusTableAction | DTFocusMoveAction | DTFocusJumpAction | DTBlurAction | DTFocusSubComponentAction | DTFocusSubComponentBlurAction | DTFocusCellManuallyAction;
45
+ export type DTFocusAction = DTFocusCellAction | DTFocusTableAction | DTFocusMoveAction | DTFocusJumpAction | DTBlurAction | DTFocusCellManuallyAction;
56
46
  export declare const DTFocusStateContext: import('react').Context<DTFocusStateContextValue>;
57
47
  export declare const DTFocusDispatchContext: import('react').Context<import('react').Dispatch<DTFocusAction>>;
@@ -5,7 +5,5 @@ export declare function useDTFocusDispatchContext(): {
5
5
  moveFocus: (direction: "up" | "down" | "left" | "right") => void;
6
6
  jumpFocus: (direction: "up" | "down" | "left" | "right") => void;
7
7
  blur: () => void;
8
- focusSubComponent: () => void;
9
- blurSubComponent: () => void;
10
8
  dispatch: import('react').Dispatch<import('./DTFocusContext').DTFocusAction>;
11
9
  };
@@ -7,4 +7,5 @@ export declare const useColumnOrder: <T>({ table }: {
7
7
  table: TanstackTable<T>;
8
8
  }) => {
9
9
  columnOrder: number[];
10
+ columnIndexMap: Map<number, number>;
10
11
  };
package/dist/beta.js CHANGED
@@ -1,4 +1,4 @@
1
- export { C as COLUMN_TYPE_DEFAULTS, D as DataTable, b as booleanFormatter, a as chipsFormatter, c as createColumnHelper, d as currencyFormatter, i as dateFormatPresets, e as dateFormatter, f as dateTimeFormatter, g as getColumnTypeDefaults, h as htmlFormatter, m as markdownFormatter, n as numberFormatter, p as percentFormatter, r as resolveColumnTypeConfig, t as timeFormatPresets, j as timeFormatter, y as yearlessDateFormatter } from './DataTable-BPonNWnU.js';
1
+ export { C as COLUMN_TYPE_DEFAULTS, D as DataTable, b as booleanFormatter, a as chipsFormatter, c as createColumnHelper, d as currencyFormatter, i as dateFormatPresets, e as dateFormatter, f as dateTimeFormatter, g as getColumnTypeDefaults, h as htmlFormatter, m as markdownFormatter, n as numberFormatter, p as percentFormatter, r as resolveColumnTypeConfig, t as timeFormatPresets, j as timeFormatter, y as yearlessDateFormatter } from './DataTable-CbHaFuj2.js';
2
2
  export { T as Toolbar, a as ToolbarButton, c as ToolbarButtonLink, b as ToolbarButtonToggle, e as ToolbarControlGroup, g as ToolbarElement, f as ToolbarSearchField, d as ToolbarSelect } from './Toolbar-V14Z3yMP.js';
3
3
  export { u as useCalendarBetaProps } from './Calendar-C7QP11uk.js';
4
4
  export { C as Calendar } from './Calendar-rjAph002.js';
@@ -44,6 +44,7 @@ export declare const Pagination: import('react').ForwardRefExoticComponent<Omit<
44
44
  startPage: number;
45
45
  endPage: number;
46
46
  length: number;
47
+ currentPage: number;
47
48
  onItemClick: (page: number) => void;
48
49
  } & import('react').RefAttributes<HTMLLIElement>>;
49
50
  ItemsPerPageMenu: import('react').ForwardRefExoticComponent<import('./PaginationItemsPerPageMenu').PaginationItemsPerPageMenuProps & import('react').RefAttributes<HTMLDivElement>>;
@@ -16,6 +16,10 @@ export type PaginationOverflowMenuProps = ComponentPropsWithoutRef<"li"> & {
16
16
  * The number of pages in the overflow range.
17
17
  */
18
18
  length: number;
19
+ /**
20
+ * The current active page in the parent pagination.
21
+ */
22
+ currentPage: number;
19
23
  /**
20
24
  * Callback function called when a page in the overflow menu is selected.
21
25
  * @param page The selected page number
@@ -27,7 +31,9 @@ export type PaginationOverflowMenuProps = ComponentPropsWithoutRef<"li"> & {
27
31
  *
28
32
  * Features:
29
33
  * - Displays ellipsis menu for large page ranges
30
- * - Shows all pages in the overflow range as menu items
34
+ * - Renders the page items as a virtualized window only the slice visible
35
+ * in the scroller is in the DOM at any time, keeping pagination cheap
36
+ * even when the overflow spans tens of thousands of pages
31
37
  * - Integrates with pagination navigation system
32
38
  * - Fully accessible with proper ARIA labels
33
39
  * - Consistent styling with design system
@@ -37,6 +43,7 @@ export type PaginationOverflowMenuProps = ComponentPropsWithoutRef<"li"> & {
37
43
  * startPage={4}
38
44
  * endPage={8}
39
45
  * length={5}
46
+ * currentPage={4}
40
47
  * onItemClick={(page) => console.log('Page selected:', page)}
41
48
  * />
42
49
  */
@@ -53,6 +60,10 @@ export declare const PaginationOverflowMenu: import('react').ForwardRefExoticCom
53
60
  * The number of pages in the overflow range.
54
61
  */
55
62
  length: number;
63
+ /**
64
+ * The current active page in the parent pagination.
65
+ */
66
+ currentPage: number;
56
67
  /**
57
68
  * Callback function called when a page in the overflow menu is selected.
58
69
  * @param page The selected page number
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ export { M as Menu } from './Menu-CCavGohP.js';
46
46
  export { N as NumberField } from './NumberField-CE_6UnsG.js';
47
47
  export { Overflow, OverflowText } from './Overflow.js';
48
48
  export { P as Page } from './Page-D6iAbBGj.js';
49
- export { P as Pagination } from './Pagination-5YcocErj.js';
49
+ export { P as Pagination } from './Pagination-YO69lIlZ.js';
50
50
  export { P as Popover } from './Popover-BbqTZw-1.js';
51
51
  export { P as ProgressBar } from './ProgressBar-Cygv2ii1.js';
52
52
  export { R as Radio } from './Radio-CGFmTxJ1.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/anvil2",
3
- "version": "2.9.4",
3
+ "version": "2.9.5",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",
@@ -59,8 +59,8 @@
59
59
  "tabbable": "^6.2.0",
60
60
  "tinycolor2": "^1.6.0",
61
61
  "uuid": "^10.0.0",
62
- "@servicetitan/hammer-token": "2.5.2",
63
- "@servicetitan/hammer-icon": "1.2.0"
62
+ "@servicetitan/hammer-icon": "1.2.0",
63
+ "@servicetitan/hammer-token": "2.5.2"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "@types/react": "^18 || ^19",