@trackunit/react-components 1.4.129 → 1.4.133

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
@@ -2756,7 +2756,7 @@ const cvaKPI = cssClassVarianceUtilities.cvaMerge(["w-full", "px-4", "py-2", "fl
2756
2756
  },
2757
2757
  });
2758
2758
  const cvaKPITitleText = cssClassVarianceUtilities.cvaMerge(["truncate", "whitespace-nowrap"]);
2759
- const cvaKPIvalueText = cssClassVarianceUtilities.cvaMerge(["truncate", "whitespace-nowrap"], {
2759
+ const cvaKPIvalueText = cssClassVarianceUtilities.cvaMerge(["truncate", "whitespace-nowrap", "text-2xl", "font-medium"], {
2760
2760
  variants: {
2761
2761
  variant: {
2762
2762
  small: ["mt-0.5"],
@@ -3217,8 +3217,8 @@ const cvaPageContent = cssClassVarianceUtilities.cvaMerge(["overflow-auto", "pag
3217
3217
  variants: {
3218
3218
  layout: {
3219
3219
  content: "grid-rows-fr",
3220
- "v-min-fr": ["grid-rows-min-fr"],
3221
- "h-min-fr": ["grid-cols-min-fr", "sm:grid-cols-1", "sm:grid-rows-min-fr"],
3220
+ "cols-min-fr": ["grid-cols-min-fr"],
3221
+ "rows-min-fr": ["grid-rows-min-fr"],
3222
3222
  },
3223
3223
  },
3224
3224
  defaultVariants: {
@@ -3859,7 +3859,17 @@ const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors
3859
3859
  return (jsxRuntime.jsx("svg", { className: cvaValueBar({ size, className }), "data-testid": dataTestId, role: "img", children: jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("rect", { className: cvaValueBarProgress({ fill: "background", className }), "data-testid": "value-bar-svg-rect-0", rx: size === "extraSmall" ? "2" : "5", width: `${barWidth}%` }), jsxRuntime.jsx("rect", { className: cvaValueBarProgress(), "data-testid": "value-bar-svg-rect-1", fill: barFillColor, rx: size === "extraSmall" ? "2" : "5", width: `${score * barWidth}%` }), showValue && size === "large" ? (jsxRuntime.jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? "white", x: "12", y: "23", children: [Number(value.toFixed(1)), unit || ""] })) : null, showValue && size === "small" ? (jsxRuntime.jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? uiDesignTokens.color("NEUTRAL", 400, "CSS"), x: `${barWidth + 2}%`, y: "11", children: [Number(value.toFixed(1)), unit || ""] })) : null] }) }));
3860
3860
  };
3861
3861
 
3862
- const cvaVirtualizedListContainer = cssClassVarianceUtilities.cvaMerge(["h-full", "overflow-auto"]);
3862
+ const cvaVirtualizedListContainer = cssClassVarianceUtilities.cvaMerge(["h-full"], {
3863
+ variants: {
3864
+ parentControlledScrollable: {
3865
+ true: [""],
3866
+ false: ["overflow-auto"],
3867
+ },
3868
+ },
3869
+ defaultVariants: {
3870
+ parentControlledScrollable: false,
3871
+ },
3872
+ });
3863
3873
  const cvaVirtualizedList = cssClassVarianceUtilities.cvaMerge(["relative"]);
3864
3874
  const cvaVirtualizedListItem = cssClassVarianceUtilities.cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
3865
3875
  variants: {
@@ -3886,18 +3896,43 @@ const cvaVirtualizedListItem = cssClassVarianceUtilities.cvaMerge(["absolute", "
3886
3896
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
3887
3897
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
3888
3898
  */
3889
- const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = rowHeight + "px", onRowClick, }) => {
3899
+ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = rowHeight + "px", onRowClick, scrollRef, }) => {
3890
3900
  const containerRef = react.useRef(null);
3891
3901
  const listRef = react.useRef(null);
3892
- const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = reactTablePagination.useInfiniteScroll({
3893
- pagination: pagination || reactTablePagination.noPagination,
3894
- containerRef,
3895
- rowSize: pagination?.pageInfo?.hasNextPage && pagination.isLoading ? count + 1 : count,
3896
- rowHeight,
3897
- });
3898
- return (jsxRuntime.jsx("div", { className: cvaVirtualizedListContainer({ className }), "data-testid": dataTestId,
3899
- // eslint-disable-next-line local-rules/no-typescript-assertion
3900
- 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 => {
3902
+ const [scrollParent, setScrollParent] = react.useState(null);
3903
+ const [parentControlledScrollable, setParentControlledScrollable] = react.useState(false);
3904
+ react.useEffect(() => {
3905
+ if (scrollRef?.current) {
3906
+ setParentControlledScrollable(true);
3907
+ setScrollParent(scrollRef.current);
3908
+ }
3909
+ else {
3910
+ setParentControlledScrollable(false);
3911
+ setScrollParent(containerRef.current);
3912
+ }
3913
+ }, [scrollRef]);
3914
+ const infiniteScrollProps = react.useMemo(() => {
3915
+ return {
3916
+ pagination: pagination || reactTablePagination.noPagination,
3917
+ containerRef: { current: scrollParent },
3918
+ rowSize: pagination?.pageInfo?.hasNextPage && pagination.isLoading ? count + 1 : count,
3919
+ rowHeight,
3920
+ };
3921
+ }, [pagination, scrollParent, count, rowHeight]);
3922
+ const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = reactTablePagination.useInfiniteScroll(infiniteScrollProps);
3923
+ react.useEffect(() => {
3924
+ if (scrollParent) {
3925
+ const handleScroll = () => {
3926
+ fetchMoreOnBottomReached(scrollParent);
3927
+ };
3928
+ scrollParent.addEventListener("scroll", handleScroll);
3929
+ return () => {
3930
+ scrollParent.removeEventListener("scroll", handleScroll);
3931
+ };
3932
+ }
3933
+ return () => { };
3934
+ }, [scrollParent, fetchMoreOnBottomReached]);
3935
+ return (jsxRuntime.jsx("div", { className: cvaVirtualizedListContainer({ parentControlledScrollable, className }), "data-testid": dataTestId, ref: containerRef, children: jsxRuntime.jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
3901
3936
  const isLoaderRow = virtualRow.index > count - 1;
3902
3937
  return (jsxRuntime.jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
3903
3938
  transform: `translateY(${virtualRow.start}px)`,
package/index.esm.js CHANGED
@@ -17,7 +17,7 @@ import omit from 'lodash/omit';
17
17
  import { twMerge } from 'tailwind-merge';
18
18
  import { HelmetProvider, Helmet } from 'react-helmet-async';
19
19
  import { Trigger, Content, List, Root } from '@radix-ui/react-tabs';
20
- import { useInfiniteScroll, noPagination } from '@trackunit/react-table-pagination';
20
+ import { noPagination, useInfiniteScroll } from '@trackunit/react-table-pagination';
21
21
 
22
22
  const docs = {
23
23
  source: {
@@ -2754,7 +2754,7 @@ const cvaKPI = cvaMerge(["w-full", "px-4", "py-2", "flex", "flex-col", "gap-1"],
2754
2754
  },
2755
2755
  });
2756
2756
  const cvaKPITitleText = cvaMerge(["truncate", "whitespace-nowrap"]);
2757
- const cvaKPIvalueText = cvaMerge(["truncate", "whitespace-nowrap"], {
2757
+ const cvaKPIvalueText = cvaMerge(["truncate", "whitespace-nowrap", "text-2xl", "font-medium"], {
2758
2758
  variants: {
2759
2759
  variant: {
2760
2760
  small: ["mt-0.5"],
@@ -3215,8 +3215,8 @@ const cvaPageContent = cvaMerge(["overflow-auto", "page-content", "grid", "gap-r
3215
3215
  variants: {
3216
3216
  layout: {
3217
3217
  content: "grid-rows-fr",
3218
- "v-min-fr": ["grid-rows-min-fr"],
3219
- "h-min-fr": ["grid-cols-min-fr", "sm:grid-cols-1", "sm:grid-rows-min-fr"],
3218
+ "cols-min-fr": ["grid-cols-min-fr"],
3219
+ "rows-min-fr": ["grid-rows-min-fr"],
3220
3220
  },
3221
3221
  },
3222
3222
  defaultVariants: {
@@ -3857,7 +3857,17 @@ const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors
3857
3857
  return (jsx("svg", { className: cvaValueBar({ size, className }), "data-testid": dataTestId, role: "img", children: jsxs("g", { children: [jsx("rect", { className: cvaValueBarProgress({ fill: "background", className }), "data-testid": "value-bar-svg-rect-0", rx: size === "extraSmall" ? "2" : "5", width: `${barWidth}%` }), jsx("rect", { className: cvaValueBarProgress(), "data-testid": "value-bar-svg-rect-1", fill: barFillColor, rx: size === "extraSmall" ? "2" : "5", width: `${score * barWidth}%` }), showValue && size === "large" ? (jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? "white", x: "12", y: "23", children: [Number(value.toFixed(1)), unit || ""] })) : null, showValue && size === "small" ? (jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? color("NEUTRAL", 400, "CSS"), x: `${barWidth + 2}%`, y: "11", children: [Number(value.toFixed(1)), unit || ""] })) : null] }) }));
3858
3858
  };
3859
3859
 
3860
- const cvaVirtualizedListContainer = cvaMerge(["h-full", "overflow-auto"]);
3860
+ const cvaVirtualizedListContainer = cvaMerge(["h-full"], {
3861
+ variants: {
3862
+ parentControlledScrollable: {
3863
+ true: [""],
3864
+ false: ["overflow-auto"],
3865
+ },
3866
+ },
3867
+ defaultVariants: {
3868
+ parentControlledScrollable: false,
3869
+ },
3870
+ });
3861
3871
  const cvaVirtualizedList = cvaMerge(["relative"]);
3862
3872
  const cvaVirtualizedListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
3863
3873
  variants: {
@@ -3884,18 +3894,43 @@ const cvaVirtualizedListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"
3884
3894
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
3885
3895
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
3886
3896
  */
3887
- const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = rowHeight + "px", onRowClick, }) => {
3897
+ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = rowHeight + "px", onRowClick, scrollRef, }) => {
3888
3898
  const containerRef = useRef(null);
3889
3899
  const listRef = useRef(null);
3890
- const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = useInfiniteScroll({
3891
- pagination: pagination || noPagination,
3892
- containerRef,
3893
- rowSize: pagination?.pageInfo?.hasNextPage && pagination.isLoading ? count + 1 : count,
3894
- rowHeight,
3895
- });
3896
- return (jsx("div", { className: cvaVirtualizedListContainer({ className }), "data-testid": dataTestId,
3897
- // eslint-disable-next-line local-rules/no-typescript-assertion
3898
- onScroll: e => fetchMoreOnBottomReached(e.target), ref: containerRef, children: jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
3900
+ const [scrollParent, setScrollParent] = useState(null);
3901
+ const [parentControlledScrollable, setParentControlledScrollable] = useState(false);
3902
+ useEffect(() => {
3903
+ if (scrollRef?.current) {
3904
+ setParentControlledScrollable(true);
3905
+ setScrollParent(scrollRef.current);
3906
+ }
3907
+ else {
3908
+ setParentControlledScrollable(false);
3909
+ setScrollParent(containerRef.current);
3910
+ }
3911
+ }, [scrollRef]);
3912
+ const infiniteScrollProps = useMemo(() => {
3913
+ return {
3914
+ pagination: pagination || noPagination,
3915
+ containerRef: { current: scrollParent },
3916
+ rowSize: pagination?.pageInfo?.hasNextPage && pagination.isLoading ? count + 1 : count,
3917
+ rowHeight,
3918
+ };
3919
+ }, [pagination, scrollParent, count, rowHeight]);
3920
+ const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = useInfiniteScroll(infiniteScrollProps);
3921
+ useEffect(() => {
3922
+ if (scrollParent) {
3923
+ const handleScroll = () => {
3924
+ fetchMoreOnBottomReached(scrollParent);
3925
+ };
3926
+ scrollParent.addEventListener("scroll", handleScroll);
3927
+ return () => {
3928
+ scrollParent.removeEventListener("scroll", handleScroll);
3929
+ };
3930
+ }
3931
+ return () => { };
3932
+ }, [scrollParent, fetchMoreOnBottomReached]);
3933
+ return (jsx("div", { className: cvaVirtualizedListContainer({ parentControlledScrollable, className }), "data-testid": dataTestId, ref: containerRef, children: jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
3899
3934
  const isLoaderRow = virtualRow.index > count - 1;
3900
3935
  return (jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
3901
3936
  transform: `translateY(${virtualRow.start}px)`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.4.129",
3
+ "version": "1.4.133",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -18,11 +18,12 @@
18
18
  "@tanstack/react-router": "1.114.29",
19
19
  "string-ts": "^2.0.0",
20
20
  "tailwind-merge": "^2.0.0",
21
- "@trackunit/ui-design-tokens": "1.3.107",
22
- "@trackunit/css-class-variance-utilities": "1.3.107",
23
- "@trackunit/shared-utils": "1.5.107",
24
- "@trackunit/ui-icons": "1.3.109",
25
- "@trackunit/react-table-pagination": "1.3.108"
21
+ "@trackunit/ui-design-tokens": "1.3.110",
22
+ "@trackunit/css-class-variance-utilities": "1.3.110",
23
+ "@trackunit/shared-utils": "1.5.110",
24
+ "@trackunit/ui-icons": "1.3.112",
25
+ "@trackunit/react-table-pagination": "1.3.111",
26
+ "@trackunit/react-test-setup": "1.0.0"
26
27
  },
27
28
  "module": "./index.esm.js",
28
29
  "main": "./index.cjs.js",
@@ -2,5 +2,5 @@ export declare const cvaPage: (props?: ({
2
2
  layout?: "content" | "header-content" | "sidebar-content" | "none" | null | undefined;
3
3
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
4
  export declare const cvaPageContent: (props?: ({
5
- layout?: "content" | "v-min-fr" | "h-min-fr" | null | undefined;
5
+ layout?: "content" | "cols-min-fr" | "rows-min-fr" | null | undefined;
6
6
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
@@ -1,10 +1,16 @@
1
+ import { VariantProps } from "@trackunit/css-class-variance-utilities";
1
2
  import { ReactNode } from "react";
2
3
  import { CommonProps } from "../../common";
4
+ import { cvaPageContent } from "./Page.variants";
5
+ /**
6
+ * The layout of the page.
7
+ */
8
+ export type PageContentLayout = VariantProps<typeof cvaPageContent>["layout"];
3
9
  /**
4
10
  * The props for the page content component.
5
11
  */
6
12
  interface PageContentProps extends CommonProps {
7
- layout: "content" | "h-min-fr" | "v-min-fr";
13
+ layout: PageContentLayout;
8
14
  children?: ReactNode;
9
15
  }
10
16
  /**
@@ -1,6 +1,6 @@
1
1
  import { VariantProps } from "@trackunit/css-class-variance-utilities";
2
2
  import { RelayPagination } from "@trackunit/react-table-pagination";
3
- import { ReactElement } from "react";
3
+ import { ReactElement, RefObject } from "react";
4
4
  import { CommonProps } from "../../common/CommonProps";
5
5
  import { cvaVirtualizedListItem } from "./VirtualizedList.variants";
6
6
  type Separator = NonNullable<VariantProps<typeof cvaVirtualizedListItem>["separator"]>;
@@ -14,6 +14,10 @@ export interface VirtualizedListProps extends CommonProps {
14
14
  loadingIndicator?: LoadingIndicator;
15
15
  skeletonLinesHeight?: string;
16
16
  onRowClick?: (index: number) => void;
17
+ /**
18
+ * The ref for the scroll container, only provide if you want to use the scroll event to fetch more data, on a different container than the list itself
19
+ */
20
+ scrollRef?: RefObject<HTMLDivElement | null>;
17
21
  }
18
22
  /**
19
23
  * Render a performant virtualized list of items. Optionally with infinite scrolling.
@@ -26,5 +30,5 @@ export interface VirtualizedListProps extends CommonProps {
26
30
  * @property {loadingIndicator} [loadingIndicator="spinner"] - The type of loading indicator in the list.
27
31
  * @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
28
32
  */
29
- export declare const VirtualizedList: ({ count, rowHeight, pagination, children, className, dataTestId, separator, loadingIndicator, skeletonLinesHeight, onRowClick, }: VirtualizedListProps) => import("react/jsx-runtime").JSX.Element;
33
+ export declare const VirtualizedList: ({ count, rowHeight, pagination, children, className, dataTestId, separator, loadingIndicator, skeletonLinesHeight, onRowClick, scrollRef, }: VirtualizedListProps) => import("react/jsx-runtime").JSX.Element;
30
34
  export {};
@@ -1,4 +1,6 @@
1
- export declare const cvaVirtualizedListContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
1
+ export declare const cvaVirtualizedListContainer: (props?: ({
2
+ parentControlledScrollable?: boolean | null | undefined;
3
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
2
4
  export declare const cvaVirtualizedList: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
3
5
  export declare const cvaVirtualizedListItem: (props?: ({
4
6
  separator?: "alternating" | "line" | "none" | "space" | null | undefined;