@trackunit/react-components 0.1.362 → 0.1.363

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/index.cjs.js CHANGED
@@ -3686,6 +3686,7 @@ const cvaMenuItem = cssClassVarianceUtilities.cvaMerge([
3686
3686
  "select-none",
3687
3687
  "rounded",
3688
3688
  "hover:bg-slate-100",
3689
+ "focus-within:outline-native",
3689
3690
  ], {
3690
3691
  variants: {
3691
3692
  selected: {
@@ -3745,7 +3746,7 @@ const cvaMenuItemPrefix = cssClassVarianceUtilities.cvaMerge(["self-center", "fl
3745
3746
  * @param {MenuItemProps} props - The props for the MenuItem component
3746
3747
  * @returns {JSX.Element} MenuItem component
3747
3748
  */
3748
- const MenuItem = ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation = true, id, }) => {
3749
+ const MenuItem = ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, }) => {
3749
3750
  const containerProps = useContainerProps({ className, dataTestId: dataTestId || "menu-item" });
3750
3751
  return (jsxRuntime.jsxs("div", Object.assign({}, containerProps, { className: cvaMenuItem({
3751
3752
  selected,
@@ -3756,7 +3757,7 @@ const MenuItem = ({ className, dataTestId, label, size, children, selected, focu
3756
3757
  }), id: id, onClick: e => {
3757
3758
  stopPropagation && e.stopPropagation();
3758
3759
  onClick && onClick(e);
3759
- }, tabIndex: 0, children: [prefix ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsxRuntime.jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] })));
3760
+ }, tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsxRuntime.jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] })));
3760
3761
  };
3761
3762
 
3762
3763
  const cvaMenuList = cssClassVarianceUtilities.cvaMerge(["shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
@@ -4434,15 +4435,11 @@ const cvaVirtualizedListItem = cssClassVarianceUtilities.cvaMerge(["absolute", "
4434
4435
  alternating: ["even:bg-slate-100"],
4435
4436
  line: ["[&:not(:last-child)]:border-b", "border-gray-200"],
4436
4437
  none: "",
4437
- },
4438
- focused: {
4439
- true: ["rounded-lg", "outline", "outline-2", "outline-primary-600"],
4440
- false: "",
4438
+ space: "[&:not(:last-child)]:pb-0.5",
4441
4439
  },
4442
4440
  },
4443
4441
  defaultVariants: {
4444
4442
  separator: "none",
4445
- focused: false,
4446
4443
  },
4447
4444
  });
4448
4445
 
@@ -4456,72 +4453,24 @@ const cvaVirtualizedListItem = cssClassVarianceUtilities.cvaMerge(["absolute", "
4456
4453
  * @property {(index: number) => JSX.Element} children - A function that takes an index and returns the JSX element to be rendered at said index.
4457
4454
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
4458
4455
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
4459
- * @property {(index: number) => void} [onRowClick] - A function that is called when a row is clicked.
4460
- * @property {(index: number) => void} [onRowSelect] - A function that is called when a row is selected with spacebar.
4461
4456
  */
4462
- const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = "2rem", onRowClick, onRowSelectToggle: onRowSelect, }) => {
4457
+ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = "2rem", onRowClick, }) => {
4463
4458
  var _a;
4464
4459
  const containerRef = React.useRef(null);
4465
4460
  const listRef = React.useRef(null);
4466
- const [focusedIndex, setFocusedIndex] = React.useState(null);
4467
4461
  const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = reactTablePagination.useInfiniteScroll({
4468
4462
  pagination: pagination || reactTablePagination.noPagination,
4469
4463
  containerRef,
4470
4464
  rowSize: ((_a = pagination === null || pagination === void 0 ? void 0 : pagination.pageInfo) === null || _a === void 0 ? void 0 : _a.hasNextPage) && pagination.isLoading ? count + 1 : count,
4471
4465
  rowHeight,
4472
4466
  });
4473
- React.useEffect(() => {
4474
- const handleKeyDown = (event) => {
4475
- var _a;
4476
- const shiftKey = event.shiftKey;
4477
- const jumpCount = focusedIndex && shiftKey ? Math.min(5, count - focusedIndex - 1) : 1;
4478
- switch (event.code) {
4479
- case "ArrowDown":
4480
- event.preventDefault();
4481
- if (focusedIndex !== null && focusedIndex < count - 1) {
4482
- setFocusedIndex(focusedIndex + jumpCount);
4483
- }
4484
- else if (focusedIndex === null) {
4485
- setFocusedIndex(0);
4486
- }
4487
- break;
4488
- case "ArrowUp":
4489
- event.preventDefault();
4490
- if (focusedIndex !== null && focusedIndex > 0) {
4491
- setFocusedIndex(focusedIndex - jumpCount);
4492
- }
4493
- break;
4494
- case "Space":
4495
- if (onRowSelect && focusedIndex !== null) {
4496
- event.preventDefault();
4497
- onRowSelect(focusedIndex);
4498
- }
4499
- break;
4500
- }
4501
- // Auto-scroll focused item into view
4502
- const focusedElement = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(`[data-index="${focusedIndex}"]`);
4503
- if (focusedElement) {
4504
- focusedElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
4505
- }
4506
- };
4507
- const listElement = listRef.current;
4508
- if (listElement) {
4509
- listElement.addEventListener("keydown", handleKeyDown);
4510
- }
4511
- return () => {
4512
- if (listElement) {
4513
- listElement.removeEventListener("keydown", handleKeyDown);
4514
- }
4515
- };
4516
- }, [focusedIndex, count, onRowSelect]);
4517
4467
  return (jsxRuntime.jsx("div", { className: cvaVirtualizedListContainer({ className }), "data-testid": dataTestId,
4518
4468
  // eslint-disable-next-line local-rules/no-typescript-assertion
4519
- onScroll: e => fetchMoreOnBottomReached(e.target), ref: containerRef, children: jsxRuntime.jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, tabIndex: 0, children: getVirtualItems().map((virtualRow, index) => {
4469
+ onScroll: e => fetchMoreOnBottomReached(e.target), ref: containerRef, children: jsxRuntime.jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
4520
4470
  const isLoaderRow = virtualRow.index > count - 1;
4521
- const focused = focusedIndex === index;
4522
- return (jsxRuntime.jsx("li", { className: cvaVirtualizedListItem({ separator, focused }), "data-index": virtualRow.index, onClick: () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(virtualRow.index), ref: measureElement, style: {
4471
+ return (jsxRuntime.jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
4523
4472
  transform: `translateY(${virtualRow.start}px)`,
4524
- }, children: isLoaderRow ? ((pagination === null || pagination === void 0 ? void 0 : pagination.isLoading) ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [loadingIndicator === "spinner" && jsxRuntime.jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsxRuntime.jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
4473
+ }, tabIndex: -1, children: isLoaderRow ? ((pagination === null || pagination === void 0 ? void 0 : pagination.isLoading) ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [loadingIndicator === "spinner" && jsxRuntime.jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsxRuntime.jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
4525
4474
  }) }) }));
4526
4475
  };
4527
4476
 
package/index.esm.js CHANGED
@@ -3655,6 +3655,7 @@ const cvaMenuItem = cvaMerge([
3655
3655
  "select-none",
3656
3656
  "rounded",
3657
3657
  "hover:bg-slate-100",
3658
+ "focus-within:outline-native",
3658
3659
  ], {
3659
3660
  variants: {
3660
3661
  selected: {
@@ -3714,7 +3715,7 @@ const cvaMenuItemPrefix = cvaMerge(["self-center", "flex-grow-0", "text-slate-40
3714
3715
  * @param {MenuItemProps} props - The props for the MenuItem component
3715
3716
  * @returns {JSX.Element} MenuItem component
3716
3717
  */
3717
- const MenuItem = ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation = true, id, }) => {
3718
+ const MenuItem = ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, }) => {
3718
3719
  const containerProps = useContainerProps({ className, dataTestId: dataTestId || "menu-item" });
3719
3720
  return (jsxs("div", Object.assign({}, containerProps, { className: cvaMenuItem({
3720
3721
  selected,
@@ -3725,7 +3726,7 @@ const MenuItem = ({ className, dataTestId, label, size, children, selected, focu
3725
3726
  }), id: id, onClick: e => {
3726
3727
  stopPropagation && e.stopPropagation();
3727
3728
  onClick && onClick(e);
3728
- }, tabIndex: 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] })));
3729
+ }, tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] })));
3729
3730
  };
3730
3731
 
3731
3732
  const cvaMenuList = cvaMerge(["shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
@@ -4403,15 +4404,11 @@ const cvaVirtualizedListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"
4403
4404
  alternating: ["even:bg-slate-100"],
4404
4405
  line: ["[&:not(:last-child)]:border-b", "border-gray-200"],
4405
4406
  none: "",
4406
- },
4407
- focused: {
4408
- true: ["rounded-lg", "outline", "outline-2", "outline-primary-600"],
4409
- false: "",
4407
+ space: "[&:not(:last-child)]:pb-0.5",
4410
4408
  },
4411
4409
  },
4412
4410
  defaultVariants: {
4413
4411
  separator: "none",
4414
- focused: false,
4415
4412
  },
4416
4413
  });
4417
4414
 
@@ -4425,72 +4422,24 @@ const cvaVirtualizedListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"
4425
4422
  * @property {(index: number) => JSX.Element} children - A function that takes an index and returns the JSX element to be rendered at said index.
4426
4423
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
4427
4424
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
4428
- * @property {(index: number) => void} [onRowClick] - A function that is called when a row is clicked.
4429
- * @property {(index: number) => void} [onRowSelect] - A function that is called when a row is selected with spacebar.
4430
4425
  */
4431
- const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = "2rem", onRowClick, onRowSelectToggle: onRowSelect, }) => {
4426
+ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = "2rem", onRowClick, }) => {
4432
4427
  var _a;
4433
4428
  const containerRef = useRef(null);
4434
4429
  const listRef = useRef(null);
4435
- const [focusedIndex, setFocusedIndex] = useState(null);
4436
4430
  const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = useInfiniteScroll({
4437
4431
  pagination: pagination || noPagination,
4438
4432
  containerRef,
4439
4433
  rowSize: ((_a = pagination === null || pagination === void 0 ? void 0 : pagination.pageInfo) === null || _a === void 0 ? void 0 : _a.hasNextPage) && pagination.isLoading ? count + 1 : count,
4440
4434
  rowHeight,
4441
4435
  });
4442
- useEffect(() => {
4443
- const handleKeyDown = (event) => {
4444
- var _a;
4445
- const shiftKey = event.shiftKey;
4446
- const jumpCount = focusedIndex && shiftKey ? Math.min(5, count - focusedIndex - 1) : 1;
4447
- switch (event.code) {
4448
- case "ArrowDown":
4449
- event.preventDefault();
4450
- if (focusedIndex !== null && focusedIndex < count - 1) {
4451
- setFocusedIndex(focusedIndex + jumpCount);
4452
- }
4453
- else if (focusedIndex === null) {
4454
- setFocusedIndex(0);
4455
- }
4456
- break;
4457
- case "ArrowUp":
4458
- event.preventDefault();
4459
- if (focusedIndex !== null && focusedIndex > 0) {
4460
- setFocusedIndex(focusedIndex - jumpCount);
4461
- }
4462
- break;
4463
- case "Space":
4464
- if (onRowSelect && focusedIndex !== null) {
4465
- event.preventDefault();
4466
- onRowSelect(focusedIndex);
4467
- }
4468
- break;
4469
- }
4470
- // Auto-scroll focused item into view
4471
- const focusedElement = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(`[data-index="${focusedIndex}"]`);
4472
- if (focusedElement) {
4473
- focusedElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
4474
- }
4475
- };
4476
- const listElement = listRef.current;
4477
- if (listElement) {
4478
- listElement.addEventListener("keydown", handleKeyDown);
4479
- }
4480
- return () => {
4481
- if (listElement) {
4482
- listElement.removeEventListener("keydown", handleKeyDown);
4483
- }
4484
- };
4485
- }, [focusedIndex, count, onRowSelect]);
4486
4436
  return (jsx("div", { className: cvaVirtualizedListContainer({ className }), "data-testid": dataTestId,
4487
4437
  // eslint-disable-next-line local-rules/no-typescript-assertion
4488
- onScroll: e => fetchMoreOnBottomReached(e.target), ref: containerRef, children: jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, tabIndex: 0, children: getVirtualItems().map((virtualRow, index) => {
4438
+ onScroll: e => fetchMoreOnBottomReached(e.target), ref: containerRef, children: jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
4489
4439
  const isLoaderRow = virtualRow.index > count - 1;
4490
- const focused = focusedIndex === index;
4491
- return (jsx("li", { className: cvaVirtualizedListItem({ separator, focused }), "data-index": virtualRow.index, onClick: () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(virtualRow.index), ref: measureElement, style: {
4440
+ return (jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
4492
4441
  transform: `translateY(${virtualRow.start}px)`,
4493
- }, children: isLoaderRow ? ((pagination === null || pagination === void 0 ? void 0 : pagination.isLoading) ? (jsxs(Fragment, { children: [loadingIndicator === "spinner" && jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
4442
+ }, tabIndex: -1, children: isLoaderRow ? ((pagination === null || pagination === void 0 ? void 0 : pagination.isLoading) ? (jsxs(Fragment, { children: [loadingIndicator === "spinner" && jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
4494
4443
  }) }) }));
4495
4444
  };
4496
4445
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "0.1.362",
3
+ "version": "0.1.363",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -59,6 +59,7 @@ export interface MenuItemProps extends CommonProps {
59
59
  * used in Menu and Select components
60
60
  */
61
61
  stopPropagation?: boolean;
62
+ tabIndex?: number;
62
63
  }
63
64
  /**
64
65
  * The MenuItem component is used to display a menu, primarily meant to be used in a list form.
@@ -66,5 +67,5 @@ export interface MenuItemProps extends CommonProps {
66
67
  * @param {MenuItemProps} props - The props for the MenuItem component
67
68
  * @returns {JSX.Element} MenuItem component
68
69
  */
69
- export declare const MenuItem: ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation, id, }: MenuItemProps) => JSX.Element;
70
+ export declare const MenuItem: ({ className, dataTestId, label, size, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation, id, tabIndex, }: MenuItemProps) => JSX.Element;
70
71
  export {};
@@ -14,7 +14,6 @@ export interface VirtualizedListProps extends CommonProps {
14
14
  loadingIndicator?: LoadingIndicator;
15
15
  skeletonLinesHeight?: string;
16
16
  onRowClick?: (index: number) => void;
17
- onRowSelectToggle?: (index: number) => void;
18
17
  }
19
18
  /**
20
19
  * Render a performant virtualized list of items. Optionally with infinite scrolling.
@@ -26,8 +25,6 @@ export interface VirtualizedListProps extends CommonProps {
26
25
  * @property {(index: number) => JSX.Element} children - A function that takes an index and returns the JSX element to be rendered at said index.
27
26
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
28
27
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
29
- * @property {(index: number) => void} [onRowClick] - A function that is called when a row is clicked.
30
- * @property {(index: number) => void} [onRowSelect] - A function that is called when a row is selected with spacebar.
31
28
  */
32
- export declare const VirtualizedList: ({ count, rowHeight, pagination, children, className, dataTestId, separator, loadingIndicator, skeletonLinesHeight, onRowClick, onRowSelectToggle: onRowSelect, }: VirtualizedListProps) => JSX.Element;
29
+ export declare const VirtualizedList: ({ count, rowHeight, pagination, children, className, dataTestId, separator, loadingIndicator, skeletonLinesHeight, onRowClick, }: VirtualizedListProps) => JSX.Element;
33
30
  export {};
@@ -1,6 +1,5 @@
1
1
  export declare const cvaVirtualizedListContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
2
  export declare const cvaVirtualizedList: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
3
3
  export declare const cvaVirtualizedListItem: (props?: ({
4
- separator?: "alternating" | "line" | "none" | null | undefined;
5
- focused?: boolean | null | undefined;
4
+ separator?: "alternating" | "line" | "none" | "space" | null | undefined;
6
5
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;