@trackunit/react-components 1.17.33 → 1.17.35

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
@@ -2875,7 +2875,7 @@ function createGrid() {
2875
2875
  layout(config) {
2876
2876
  // At runtime, config properties are always valid arrays (error types only exist at compile-time)
2877
2877
  // We need to cast and copy readonly arrays to mutable arrays for storage
2878
- // eslint-disable-next-line local-rules/no-typescript-assertion -- Error tuple types only exist at compile-time; runtime values are always valid arrays
2878
+ // eslint-disable-next-line @trackunit/no-typescript-assertion -- Error tuple types only exist at compile-time; runtime values are always valid arrays
2879
2879
  const runtimeConfig = config;
2880
2880
  layouts.push({
2881
2881
  layout: runtimeConfig.layout.map(row => [...row]),
@@ -2987,7 +2987,7 @@ function GridAreas({ slots, css, containerProps, validationRef, className, child
2987
2987
  *
2988
2988
  * @see https://tailwindcss.com/docs/responsive-design#container-queries
2989
2989
  */
2990
- // eslint-disable-next-line local-rules/no-typescript-assertion
2990
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
2991
2991
  const CONTAINER_BREAKPOINTS = Object.fromEntries(Object.entries(uiDesignTokens.themeContainerSize).map(([key, value]) => [`@${key}`, value]));
2992
2992
 
2993
2993
  /**
@@ -3060,7 +3060,7 @@ function isContainerBreakpoint(value) {
3060
3060
  * Each slot contains a data-slot attribute and gridArea style.
3061
3061
  */
3062
3062
  function createSlots(areas) {
3063
- // eslint-disable-next-line local-rules/no-typescript-assertion -- Object.fromEntries loses key type information
3063
+ // eslint-disable-next-line @trackunit/no-typescript-assertion -- Object.fromEntries loses key type information
3064
3064
  return Object.fromEntries(areas.map(area => [area, { "data-slot": area, style: { gridArea: area } }]));
3065
3065
  }
3066
3066
  /**
@@ -6186,7 +6186,7 @@ const MenuItem = ({ className, "data-testid": dataTestId, label, children, selec
6186
6186
  if (stopPropagation) {
6187
6187
  e.stopPropagation();
6188
6188
  }
6189
- // eslint-disable-next-line local-rules/no-typescript-assertion
6189
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
6190
6190
  onClick(e);
6191
6191
  }
6192
6192
  };
@@ -8029,7 +8029,7 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
8029
8029
  setSlidingWidth(width);
8030
8030
  }, [validIndex]);
8031
8031
  return (jsxRuntime.jsx("div", { className: tailwindMerge.twMerge(cvaToggleGroup({ className }), cvaToggleGroupWithSlidingBackground({ isMounted })), "data-testid": dataTestId, ref: ref, style:
8032
- // eslint-disable-next-line local-rules/no-typescript-assertion
8032
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
8033
8033
  {
8034
8034
  "--sliding-left": `${slidingLeft}px`,
8035
8035
  "--sliding-width": `${slidingWidth}px`,
@@ -8065,7 +8065,7 @@ const ToggleButton = ({ title, size, children, "data-testid": dataTestId, classN
8065
8065
  return (jsxRuntime.jsx("button", { className: tailwindMerge.twMerge("flex items-center justify-center gap-1 self-stretch", paddingClasses, className), "data-testid": dataTestId, title: isIconOnly ? title : undefined, type: "button", ...rest, children: isIconOnly ? (icon) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconPrefix, children] })) }));
8066
8066
  };
8067
8067
 
8068
- const cvaSegmentedValueBar = cssClassVarianceUtilities.cvaMerge(["w-full", "overflow-hidden", "rounded", "bg-neutral-100", "flex"], {
8068
+ const cvaSegmentedValueBar = cssClassVarianceUtilities.cvaMerge(["flex-1", "overflow-hidden", "rounded", "bg-neutral-100", "flex"], {
8069
8069
  variants: {
8070
8070
  size: {
8071
8071
  extraSmall: "h-1",
@@ -8077,6 +8077,17 @@ const cvaSegmentedValueBar = cssClassVarianceUtilities.cvaMerge(["w-full", "over
8077
8077
  size: "small",
8078
8078
  },
8079
8079
  });
8080
+ const cvaSegmentedValueBarText = cssClassVarianceUtilities.cvaMerge(["whitespace-nowrap", "tabular-nums", "shrink-0"], {
8081
+ variants: {
8082
+ size: {
8083
+ small: "leading-xs text-xs font-medium text-neutral-600",
8084
+ large: "absolute pl-3 text-base text-white drop-shadow-lg",
8085
+ },
8086
+ },
8087
+ defaultVariants: {
8088
+ size: "small",
8089
+ },
8090
+ });
8080
8091
 
8081
8092
  /** Minimum fraction of the total a segment must occupy for value text to be overlaid inside it. */
8082
8093
  const MIN_RATIO_FOR_OVERLAY_ALIGNMENT = 0.2;
@@ -8114,18 +8125,18 @@ const getValueTextVariant = (size, sum, segments, total) => {
8114
8125
  * SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
8115
8126
  * Supports optional tooltips per segment, showing value and optionally a label.
8116
8127
  */
8117
- const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, className, "data-testid": dataTestId, }) => {
8128
+ const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, }) => {
8118
8129
  const computedSegments = computeSegments(segments, total);
8119
8130
  const sum = total > 0 ? computeSum(segments) : 0;
8120
8131
  const valueText = formatValue(displayValue ?? sum, unit);
8121
8132
  const canShowValue = showValue && size !== "extraSmall";
8122
- const valueTextClassName = cvaValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
8133
+ const valueTextClassName = cvaSegmentedValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
8123
8134
  return (jsxRuntime.jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, children: [jsxRuntime.jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
8124
8135
  const tooltipLabel = segment.label
8125
8136
  ? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
8126
8137
  : formatValue(segment.value, tooltipUnit ?? unit);
8127
8138
  return showTooltip ? (jsxRuntime.jsx(Tooltip, { label: tooltipLabel, placement: "top", children: jsxRuntime.jsx("div", { "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined, style: { backgroundColor: segment.color, width: `${segment.width}%`, height: "100%" } }) }, index)) : (jsxRuntime.jsx("div", { "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined, style: { backgroundColor: segment.color, width: `${segment.width}%`, height: "100%" } }, index));
8128
- }) }), canShowValue ? (jsxRuntime.jsx("span", { className: valueTextClassName, "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: jsxRuntime.jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
8139
+ }) }), canShowValue ? (jsxRuntime.jsx("span", { className: valueTextClassName, "data-testid": dataTestId ? `${dataTestId}-value` : undefined, style: valueWidth ? { width: valueWidth } : undefined, children: jsxRuntime.jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
8129
8140
  };
8130
8141
 
8131
8142
  /**
@@ -8414,7 +8425,7 @@ const useClickOutside = (el, options) => {
8414
8425
  const els = Array.isArray(el) ? el : [el];
8415
8426
  const active = options.active !== undefined ? options.active : true;
8416
8427
  const handler = (ev) => {
8417
- // eslint-disable-next-line local-rules/no-typescript-assertion
8428
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
8418
8429
  const target = ev.target;
8419
8430
  if (els.every(ref => !ref.current || !ref.current.contains(target))) {
8420
8431
  options.onClick(ev);
package/index.esm.js CHANGED
@@ -2873,7 +2873,7 @@ function createGrid() {
2873
2873
  layout(config) {
2874
2874
  // At runtime, config properties are always valid arrays (error types only exist at compile-time)
2875
2875
  // We need to cast and copy readonly arrays to mutable arrays for storage
2876
- // eslint-disable-next-line local-rules/no-typescript-assertion -- Error tuple types only exist at compile-time; runtime values are always valid arrays
2876
+ // eslint-disable-next-line @trackunit/no-typescript-assertion -- Error tuple types only exist at compile-time; runtime values are always valid arrays
2877
2877
  const runtimeConfig = config;
2878
2878
  layouts.push({
2879
2879
  layout: runtimeConfig.layout.map(row => [...row]),
@@ -2985,7 +2985,7 @@ function GridAreas({ slots, css, containerProps, validationRef, className, child
2985
2985
  *
2986
2986
  * @see https://tailwindcss.com/docs/responsive-design#container-queries
2987
2987
  */
2988
- // eslint-disable-next-line local-rules/no-typescript-assertion
2988
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
2989
2989
  const CONTAINER_BREAKPOINTS = Object.fromEntries(Object.entries(themeContainerSize).map(([key, value]) => [`@${key}`, value]));
2990
2990
 
2991
2991
  /**
@@ -3058,7 +3058,7 @@ function isContainerBreakpoint(value) {
3058
3058
  * Each slot contains a data-slot attribute and gridArea style.
3059
3059
  */
3060
3060
  function createSlots(areas) {
3061
- // eslint-disable-next-line local-rules/no-typescript-assertion -- Object.fromEntries loses key type information
3061
+ // eslint-disable-next-line @trackunit/no-typescript-assertion -- Object.fromEntries loses key type information
3062
3062
  return Object.fromEntries(areas.map(area => [area, { "data-slot": area, style: { gridArea: area } }]));
3063
3063
  }
3064
3064
  /**
@@ -6184,7 +6184,7 @@ const MenuItem = ({ className, "data-testid": dataTestId, label, children, selec
6184
6184
  if (stopPropagation) {
6185
6185
  e.stopPropagation();
6186
6186
  }
6187
- // eslint-disable-next-line local-rules/no-typescript-assertion
6187
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
6188
6188
  onClick(e);
6189
6189
  }
6190
6190
  };
@@ -8027,7 +8027,7 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
8027
8027
  setSlidingWidth(width);
8028
8028
  }, [validIndex]);
8029
8029
  return (jsx("div", { className: twMerge(cvaToggleGroup({ className }), cvaToggleGroupWithSlidingBackground({ isMounted })), "data-testid": dataTestId, ref: ref, style:
8030
- // eslint-disable-next-line local-rules/no-typescript-assertion
8030
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
8031
8031
  {
8032
8032
  "--sliding-left": `${slidingLeft}px`,
8033
8033
  "--sliding-width": `${slidingWidth}px`,
@@ -8063,7 +8063,7 @@ const ToggleButton = ({ title, size, children, "data-testid": dataTestId, classN
8063
8063
  return (jsx("button", { className: twMerge("flex items-center justify-center gap-1 self-stretch", paddingClasses, className), "data-testid": dataTestId, title: isIconOnly ? title : undefined, type: "button", ...rest, children: isIconOnly ? (icon) : (jsxs(Fragment$1, { children: [iconPrefix, children] })) }));
8064
8064
  };
8065
8065
 
8066
- const cvaSegmentedValueBar = cvaMerge(["w-full", "overflow-hidden", "rounded", "bg-neutral-100", "flex"], {
8066
+ const cvaSegmentedValueBar = cvaMerge(["flex-1", "overflow-hidden", "rounded", "bg-neutral-100", "flex"], {
8067
8067
  variants: {
8068
8068
  size: {
8069
8069
  extraSmall: "h-1",
@@ -8075,6 +8075,17 @@ const cvaSegmentedValueBar = cvaMerge(["w-full", "overflow-hidden", "rounded", "
8075
8075
  size: "small",
8076
8076
  },
8077
8077
  });
8078
+ const cvaSegmentedValueBarText = cvaMerge(["whitespace-nowrap", "tabular-nums", "shrink-0"], {
8079
+ variants: {
8080
+ size: {
8081
+ small: "leading-xs text-xs font-medium text-neutral-600",
8082
+ large: "absolute pl-3 text-base text-white drop-shadow-lg",
8083
+ },
8084
+ },
8085
+ defaultVariants: {
8086
+ size: "small",
8087
+ },
8088
+ });
8078
8089
 
8079
8090
  /** Minimum fraction of the total a segment must occupy for value text to be overlaid inside it. */
8080
8091
  const MIN_RATIO_FOR_OVERLAY_ALIGNMENT = 0.2;
@@ -8112,18 +8123,18 @@ const getValueTextVariant = (size, sum, segments, total) => {
8112
8123
  * SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
8113
8124
  * Supports optional tooltips per segment, showing value and optionally a label.
8114
8125
  */
8115
- const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, className, "data-testid": dataTestId, }) => {
8126
+ const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, }) => {
8116
8127
  const computedSegments = computeSegments(segments, total);
8117
8128
  const sum = total > 0 ? computeSum(segments) : 0;
8118
8129
  const valueText = formatValue(displayValue ?? sum, unit);
8119
8130
  const canShowValue = showValue && size !== "extraSmall";
8120
- const valueTextClassName = cvaValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
8131
+ const valueTextClassName = cvaSegmentedValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
8121
8132
  return (jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, children: [jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
8122
8133
  const tooltipLabel = segment.label
8123
8134
  ? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
8124
8135
  : formatValue(segment.value, tooltipUnit ?? unit);
8125
8136
  return showTooltip ? (jsx(Tooltip, { label: tooltipLabel, placement: "top", children: jsx("div", { "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined, style: { backgroundColor: segment.color, width: `${segment.width}%`, height: "100%" } }) }, index)) : (jsx("div", { "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined, style: { backgroundColor: segment.color, width: `${segment.width}%`, height: "100%" } }, index));
8126
- }) }), canShowValue ? (jsx("span", { className: valueTextClassName, "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
8137
+ }) }), canShowValue ? (jsx("span", { className: valueTextClassName, "data-testid": dataTestId ? `${dataTestId}-value` : undefined, style: valueWidth ? { width: valueWidth } : undefined, children: jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
8127
8138
  };
8128
8139
 
8129
8140
  /**
@@ -8412,7 +8423,7 @@ const useClickOutside = (el, options) => {
8412
8423
  const els = Array.isArray(el) ? el : [el];
8413
8424
  const active = options.active !== undefined ? options.active : true;
8414
8425
  const handler = (ev) => {
8415
- // eslint-disable-next-line local-rules/no-typescript-assertion
8426
+ // eslint-disable-next-line @trackunit/no-typescript-assertion
8416
8427
  const target = ev.target;
8417
8428
  if (els.every(ref => !ref.current || !ref.current.contains(target))) {
8418
8429
  options.onClick(ev);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.17.33",
3
+ "version": "1.17.35",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -14,10 +14,10 @@
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "string-ts": "^2.0.0",
16
16
  "tailwind-merge": "^2.0.0",
17
- "@trackunit/ui-design-tokens": "1.11.48",
18
- "@trackunit/css-class-variance-utilities": "1.11.48",
19
- "@trackunit/shared-utils": "1.13.48",
20
- "@trackunit/ui-icons": "1.11.47",
17
+ "@trackunit/ui-design-tokens": "1.11.50",
18
+ "@trackunit/css-class-variance-utilities": "1.11.50",
19
+ "@trackunit/shared-utils": "1.13.50",
20
+ "@trackunit/ui-icons": "1.11.49",
21
21
  "@tanstack/react-router": "1.114.29",
22
22
  "es-toolkit": "^1.39.10",
23
23
  "@tanstack/react-virtual": "3.13.12",
@@ -39,9 +39,14 @@ export interface SegmentedValueBarProps extends CommonProps {
39
39
  * Unit for tooltip values. Defaults to `unit`.
40
40
  */
41
41
  readonly tooltipUnit?: string;
42
+ /**
43
+ * Fixed width for the value text (e.g., "4ch", "50px"). Ensures consistent bar lengths
44
+ * when multiple SegmentedValueBars are displayed in a list or table with varying value lengths.
45
+ */
46
+ readonly valueWidth?: string;
42
47
  }
43
48
  /**
44
49
  * SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
45
50
  * Supports optional tooltips per segment, showing value and optionally a label.
46
51
  */
47
- export declare const SegmentedValueBar: ({ segments, total, size, showValue, displayValue, unit, valueColor, showTooltip, tooltipUnit, className, "data-testid": dataTestId, }: SegmentedValueBarProps) => ReactElement;
52
+ export declare const SegmentedValueBar: ({ segments, total, size, showValue, displayValue, unit, valueColor, showTooltip, tooltipUnit, valueWidth, className, "data-testid": dataTestId, }: SegmentedValueBarProps) => ReactElement;
@@ -1,3 +1,6 @@
1
1
  export declare const cvaSegmentedValueBar: (props?: ({
2
2
  size?: "extraSmall" | "small" | "large" | null | undefined;
3
3
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
+ export declare const cvaSegmentedValueBarText: (props?: ({
5
+ size?: "small" | "large" | null | undefined;
6
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;