@trackunit/react-components 1.1.52 → 1.1.54

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
@@ -1147,6 +1147,21 @@ function getDevicePixelRatio(options) {
1147
1147
  return Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);
1148
1148
  }
1149
1149
 
1150
+ /**
1151
+ * Use this hook if you want to optionally elevate the reducer state of a component.
1152
+ * Useful when you _want_ to be able to control the reducer state of a component
1153
+ * from a parent component but keep the simplicity of not _having_ to.
1154
+ *
1155
+ * If no custom reducer state is provided, the fallback reducer state will be used and it works like a normal useReducer hook.
1156
+ *
1157
+ * @example
1158
+ * const [state, dispatch] = useElevatedReducer(reducer, initialState, elevatedReducerState);
1159
+ */
1160
+ const useElevatedReducer = (reducer, initialState, customState) => {
1161
+ const fallbackState = react.useReducer(reducer, initialState);
1162
+ return customState ?? fallbackState;
1163
+ };
1164
+
1150
1165
  /**
1151
1166
  * Use this hook if you want to optionally elevate the state of a component.
1152
1167
  * Useful when you _want_ to be able to control the state of a component
@@ -1454,6 +1469,31 @@ const useViewportBreakpoints = () => {
1454
1469
  return viewportSize;
1455
1470
  };
1456
1471
 
1472
+ const UNINITIALIZED = Symbol("UNINITIALIZED");
1473
+ /**
1474
+ * Hook to watch for changes in a value and react to them.
1475
+ *
1476
+ * @param props - The hook properties
1477
+ * @param props.value - The value to watch for changes
1478
+ * @param props.onChange - Function to call when the value changes
1479
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
1480
+ * @param props.isEqual - Custom equality function to determine if value has changed. Defaults to stringified equality.
1481
+ */
1482
+ const useWatch = ({ value, onChange, immediate = false, isEqual }) => {
1483
+ const prevValue = react.useRef(UNINITIALIZED);
1484
+ react.useEffect(() => {
1485
+ const prev = prevValue.current;
1486
+ const hasChanged = prev === UNINITIALIZED ? false : isEqual ? !isEqual(value, prev) : JSON.stringify(value) !== JSON.stringify(prev);
1487
+ if (immediate && prev === UNINITIALIZED) {
1488
+ onChange(value, null);
1489
+ }
1490
+ else if (hasChanged && prev !== UNINITIALIZED) {
1491
+ onChange(value, prev);
1492
+ }
1493
+ prevValue.current = value;
1494
+ }, [value, onChange, immediate, isEqual]);
1495
+ };
1496
+
1457
1497
  const hasFocus = () => typeof document !== "undefined" && document.hasFocus();
1458
1498
  /**
1459
1499
  * Use this hook to disable functionality while the tab is hidden within the browser or to react to focus or blur events
@@ -3946,6 +3986,7 @@ exports.useContainerBreakpoints = useContainerBreakpoints;
3946
3986
  exports.useContinuousTimeout = useContinuousTimeout;
3947
3987
  exports.useDebounce = useDebounce;
3948
3988
  exports.useDevicePixelRatio = useDevicePixelRatio;
3989
+ exports.useElevatedReducer = useElevatedReducer;
3949
3990
  exports.useElevatedState = useElevatedState;
3950
3991
  exports.useGeometry = useGeometry;
3951
3992
  exports.useHover = useHover;
@@ -3960,4 +4001,5 @@ exports.useScrollDetection = useScrollDetection;
3960
4001
  exports.useSelfUpdatingRef = useSelfUpdatingRef;
3961
4002
  exports.useTimeout = useTimeout;
3962
4003
  exports.useViewportBreakpoints = useViewportBreakpoints;
4004
+ exports.useWatch = useWatch;
3963
4005
  exports.useWindowActivity = useWindowActivity;
package/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useRef, useMemo, useEffect, forwardRef, useState, useCallback, createElement, memo, createContext, useContext, isValidElement, cloneElement, Children } from 'react';
2
+ import { useRef, useMemo, useEffect, forwardRef, useState, useCallback, createElement, useReducer, memo, createContext, useContext, isValidElement, cloneElement, Children } from 'react';
3
3
  import { objectKeys, uuidv4, objectEntries, objectValues } from '@trackunit/shared-utils';
4
4
  import { rentalStatusPalette, intentPalette, generalPalette, criticalityPalette, activityPalette, utilizationPalette, sitesPalette, themeScreenSizeAsNumber, color } from '@trackunit/ui-design-tokens';
5
5
  import { iconNames } from '@trackunit/ui-icons';
@@ -1145,6 +1145,21 @@ function getDevicePixelRatio(options) {
1145
1145
  return Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);
1146
1146
  }
1147
1147
 
1148
+ /**
1149
+ * Use this hook if you want to optionally elevate the reducer state of a component.
1150
+ * Useful when you _want_ to be able to control the reducer state of a component
1151
+ * from a parent component but keep the simplicity of not _having_ to.
1152
+ *
1153
+ * If no custom reducer state is provided, the fallback reducer state will be used and it works like a normal useReducer hook.
1154
+ *
1155
+ * @example
1156
+ * const [state, dispatch] = useElevatedReducer(reducer, initialState, elevatedReducerState);
1157
+ */
1158
+ const useElevatedReducer = (reducer, initialState, customState) => {
1159
+ const fallbackState = useReducer(reducer, initialState);
1160
+ return customState ?? fallbackState;
1161
+ };
1162
+
1148
1163
  /**
1149
1164
  * Use this hook if you want to optionally elevate the state of a component.
1150
1165
  * Useful when you _want_ to be able to control the state of a component
@@ -1452,6 +1467,31 @@ const useViewportBreakpoints = () => {
1452
1467
  return viewportSize;
1453
1468
  };
1454
1469
 
1470
+ const UNINITIALIZED = Symbol("UNINITIALIZED");
1471
+ /**
1472
+ * Hook to watch for changes in a value and react to them.
1473
+ *
1474
+ * @param props - The hook properties
1475
+ * @param props.value - The value to watch for changes
1476
+ * @param props.onChange - Function to call when the value changes
1477
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
1478
+ * @param props.isEqual - Custom equality function to determine if value has changed. Defaults to stringified equality.
1479
+ */
1480
+ const useWatch = ({ value, onChange, immediate = false, isEqual }) => {
1481
+ const prevValue = useRef(UNINITIALIZED);
1482
+ useEffect(() => {
1483
+ const prev = prevValue.current;
1484
+ const hasChanged = prev === UNINITIALIZED ? false : isEqual ? !isEqual(value, prev) : JSON.stringify(value) !== JSON.stringify(prev);
1485
+ if (immediate && prev === UNINITIALIZED) {
1486
+ onChange(value, null);
1487
+ }
1488
+ else if (hasChanged && prev !== UNINITIALIZED) {
1489
+ onChange(value, prev);
1490
+ }
1491
+ prevValue.current = value;
1492
+ }, [value, onChange, immediate, isEqual]);
1493
+ };
1494
+
1455
1495
  const hasFocus = () => typeof document !== "undefined" && document.hasFocus();
1456
1496
  /**
1457
1497
  * Use this hook to disable functionality while the tab is hidden within the browser or to react to focus or blur events
@@ -3843,4 +3883,4 @@ const cvaClickable = cvaMerge([
3843
3883
  },
3844
3884
  });
3845
3885
 
3846
- export { ActionRenderer, Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, PageHeaderKpiMetrics, PageHeaderSecondaryActions, PageHeaderTitle, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, ZStack, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaContainerStyles, cvaIconButton, cvaImgStyles, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, cvaPageHeader, cvaPageHeaderContainer, cvaPageHeaderHeading, cvaToggleGroup, cvaToggleItem, cvaToggleItemText, cvaVirtualizedList, cvaVirtualizedListContainer, cvaVirtualizedListItem, cvaZStackContainer, cvaZStackItem, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useDebounce, useDevicePixelRatio, useElevatedState, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextTruncated, useOverflowItems, usePopoverContext, usePrompt, useResize, useScrollDetection, useSelfUpdatingRef, useTimeout, useViewportBreakpoints, useWindowActivity };
3886
+ export { ActionRenderer, Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, PageHeaderKpiMetrics, PageHeaderSecondaryActions, PageHeaderTitle, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, ZStack, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaContainerStyles, cvaIconButton, cvaImgStyles, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, cvaPageHeader, cvaPageHeaderContainer, cvaPageHeaderHeading, cvaToggleGroup, cvaToggleItem, cvaToggleItemText, cvaVirtualizedList, cvaVirtualizedListContainer, cvaVirtualizedListItem, cvaZStackContainer, cvaZStackItem, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useDebounce, useDevicePixelRatio, useElevatedReducer, useElevatedState, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextTruncated, useOverflowItems, usePopoverContext, usePrompt, useResize, useScrollDetection, useSelfUpdatingRef, useTimeout, useViewportBreakpoints, useWatch, useWindowActivity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.1.52",
3
+ "version": "1.1.54",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -19,11 +19,11 @@
19
19
  "@tanstack/react-router": "1.47.1",
20
20
  "string-ts": "^2.0.0",
21
21
  "tailwind-merge": "^2.0.0",
22
- "@trackunit/ui-design-tokens": "1.0.45",
23
- "@trackunit/css-class-variance-utilities": "1.0.44",
24
- "@trackunit/shared-utils": "1.2.41",
25
- "@trackunit/ui-icons": "1.0.49",
26
- "@trackunit/react-table-pagination": "1.0.45"
22
+ "@trackunit/ui-design-tokens": "1.0.46",
23
+ "@trackunit/css-class-variance-utilities": "1.0.45",
24
+ "@trackunit/shared-utils": "1.2.43",
25
+ "@trackunit/ui-icons": "1.0.50",
26
+ "@trackunit/react-table-pagination": "1.0.46"
27
27
  },
28
28
  "module": "./index.esm.js",
29
29
  "main": "./index.cjs.js",
@@ -3,6 +3,7 @@ export * from "./useContainerBreakpoints";
3
3
  export * from "./useContinuousTimeout";
4
4
  export * from "./useDebounce";
5
5
  export * from "./useDevicePixelRatio";
6
+ export * from "./useElevatedReducer";
6
7
  export * from "./useElevatedState";
7
8
  export * from "./useGeometry";
8
9
  export * from "./useHover";
@@ -14,4 +15,5 @@ export * from "./useScrollDetection";
14
15
  export * from "./useSelfUpdatingRef";
15
16
  export * from "./useTimeout";
16
17
  export * from "./useViewportBreakpoints";
18
+ export * from "./useWatch";
17
19
  export * from "./useWindowActivity";
@@ -0,0 +1,12 @@
1
+ import { Dispatch, Reducer } from "react";
2
+ /**
3
+ * Use this hook if you want to optionally elevate the reducer state of a component.
4
+ * Useful when you _want_ to be able to control the reducer state of a component
5
+ * from a parent component but keep the simplicity of not _having_ to.
6
+ *
7
+ * If no custom reducer state is provided, the fallback reducer state will be used and it works like a normal useReducer hook.
8
+ *
9
+ * @example
10
+ * const [state, dispatch] = useElevatedReducer(reducer, initialState, elevatedReducerState);
11
+ */
12
+ export declare const useElevatedReducer: <TState, TAction>(reducer: Reducer<TState, TAction>, initialState: TState, customState?: [TState, Dispatch<TAction>]) => [TState, Dispatch<TAction>];
@@ -0,0 +1,19 @@
1
+ interface UseWatchOptions<TValue> {
2
+ immediate?: boolean;
3
+ isEqual?: (prev: TValue, next: TValue) => boolean;
4
+ }
5
+ interface UseWatchProps<TValue> extends UseWatchOptions<TValue> {
6
+ value: TValue;
7
+ onChange: (value: TValue, prevValue: TValue | null) => void;
8
+ }
9
+ /**
10
+ * Hook to watch for changes in a value and react to them.
11
+ *
12
+ * @param props - The hook properties
13
+ * @param props.value - The value to watch for changes
14
+ * @param props.onChange - Function to call when the value changes
15
+ * @param props.immediate - Whether to run the callback immediately on mount (default: false)
16
+ * @param props.isEqual - Custom equality function to determine if value has changed. Defaults to stringified equality.
17
+ */
18
+ export declare const useWatch: <TValue>({ value, onChange, immediate, isEqual }: UseWatchProps<TValue>) => void;
19
+ export {};