@trackunit/react-components 1.14.18 → 1.14.20

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.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
2
  import { objectKeys, uuidv4, parseTailwindArbitraryValue, objectEntries, nonNullable, objectValues, filterByMultiple } from '@trackunit/shared-utils';
3
3
  import { useRef, useMemo, useEffect, useState, useLayoutEffect, useCallback, createElement, forwardRef, Fragment, memo, useId, useReducer, Children, isValidElement, cloneElement, createContext, useContext } from 'react';
4
- import { intentPalette, generalPalette, criticalityPalette, activityPalette, utilizationPalette, sitesPalette, rentalStatusPalette, themeScreenSizeAsNumber, themeContainerSize, color } from '@trackunit/ui-design-tokens';
4
+ import { rentalStatusPalette, sitesPalette, utilizationPalette, activityPalette, criticalityPalette, generalPalette, intentPalette, themeScreenSizeAsNumber, themeContainerSize, color } from '@trackunit/ui-design-tokens';
5
5
  import { iconNames } from '@trackunit/ui-icons';
6
6
  import IconSpriteMicro from '@trackunit/ui-icons/icons-sprite-micro.svg';
7
7
  import IconSpriteMini from '@trackunit/ui-icons/icons-sprite-mini.svg';
@@ -9,11 +9,11 @@ import IconSpriteOutline from '@trackunit/ui-icons/icons-sprite-outline.svg';
9
9
  import IconSpriteSolid from '@trackunit/ui-icons/icons-sprite-solid.svg';
10
10
  import { snakeCase, titleCase } from 'string-ts';
11
11
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
12
- import { Slottable, Slot } from '@radix-ui/react-slot';
12
+ import { Slot, Slottable } from '@radix-ui/react-slot';
13
13
  import { Link, useBlocker } from '@tanstack/react-router';
14
14
  import { isEqual, omit } from 'es-toolkit';
15
15
  import { twMerge } from 'tailwind-merge';
16
- import { useFloating, autoUpdate, offset, flip, shift, size, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
16
+ import { useFloating, offset, flip, shift, size, autoUpdate, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
17
17
  import { useVirtualizer } from '@tanstack/react-virtual';
18
18
  import { HelmetProvider, Helmet } from 'react-helmet-async';
19
19
  import { Trigger, Content, List as List$1, Root } from '@radix-ui/react-tabs';
@@ -254,6 +254,33 @@ const TAG_TEXT_MIN_WIDTH_PX = parseTailwindArbitraryValue(TAG_TEXT_MIN_WIDTH_CLA
254
254
  * - Use a [Badge](https://design.iris.trackunit.com/?path=/docs/react-components-badge--docs) to indicate notifications or counts of applied elements, such as filters.
255
255
  * - Use a [Highlight](https://design.iris.trackunit.com/?path=/docs/react-components-highlight--docs) to draw attention to values in plain text that require special attention or have crossed a threshold.
256
256
  *
257
+ * @example Status tags with different colors
258
+ * ```tsx
259
+ * import { Tag } from "@trackunit/react-components";
260
+ *
261
+ * const AssetStatus = () => (
262
+ * <div className="flex gap-2">
263
+ * <Tag color="success">Active</Tag>
264
+ * <Tag color="warning">Idle</Tag>
265
+ * <Tag color="danger">Offline</Tag>
266
+ * <Tag color="info">Beta</Tag>
267
+ * </div>
268
+ * );
269
+ * ```
270
+ * @example Dismissible tag for selections
271
+ * ```tsx
272
+ * import { Tag, Icon } from "@trackunit/react-components";
273
+ *
274
+ * const SelectedFilter = ({ label, onRemove }: { label: string; onRemove: () => void }) => (
275
+ * <Tag
276
+ * color="primary"
277
+ * icon={<Icon name="Funnel" size="small" />}
278
+ * onClose={onRemove}
279
+ * >
280
+ * {label}
281
+ * </Tag>
282
+ * );
283
+ * ```
257
284
  * @param {TagProps} props - The props for the Tag component.
258
285
  * @returns {ReactElement} The rendered Tag component.
259
286
  */
@@ -771,8 +798,39 @@ const cvaIconButton = cvaMerge([], {
771
798
  * Use buttons to communicate actions users can take and to allow users to interact with the page. Each page should have one primary button, and any remaining calls to action should be represented as lower emphasis buttons.
772
799
  *
773
800
  * ### When not to use
774
- * Do not use buttons as navigational elements. Instead, use [Links](https://www.notion.so/Links-49638788b6c042698b40b94a318361f1?pvs=21) when the desired action is to take the user to a new page.
801
+ * Do not use buttons as navigational elements. Instead, use [Links](?path=/docs/components-link--docs) when the desired action is to take the user to a new page.
802
+ *
803
+ * @example Basic button with click handler
804
+ * ```tsx
805
+ * import { Button } from "@trackunit/react-components";
806
+ *
807
+ * const MyComponent = () => {
808
+ * return (
809
+ * <Button onClick={() => console.log('clicked')}>
810
+ * Click me
811
+ * </Button>
812
+ * );
813
+ * };
814
+ * ```
815
+ * @example Button variants and sizes
816
+ * ```tsx
817
+ * import { Button, Icon } from "@trackunit/react-components";
775
818
  *
819
+ * const ButtonExamples = () => {
820
+ * return (
821
+ * <div className="flex gap-2">
822
+ * <Button variant="primary">Primary</Button>
823
+ * <Button variant="secondary">Secondary</Button>
824
+ * <Button variant="ghost">Ghost</Button>
825
+ * <Button variant="primary-danger">Danger</Button>
826
+ * <Button size="small">Small</Button>
827
+ * <Button prefix={<Icon name="Plus" size="small" />}>With Icon</Button>
828
+ * <Button loading>Loading</Button>
829
+ * <Button disabled>Disabled</Button>
830
+ * </div>
831
+ * );
832
+ * };
833
+ * ```
776
834
  * @param {ButtonProps} props - The props for the Button component
777
835
  * @returns {ReactElement} Button component
778
836
  */
@@ -800,6 +858,45 @@ Button.displayName = "Button";
800
858
 
801
859
  /**
802
860
  * Buttons are clickable elements that are used to trigger actions. They communicate calls to action to the user and allow users to interact with pages in a variety of ways. The Icon Button is a version of the standard Button component without the text label.
861
+ *
862
+ * ### When to use
863
+ * Use icon buttons for actions that are well-understood through the icon alone, such as close, delete, or settings buttons. Always provide a `title` prop for accessibility.
864
+ *
865
+ * ### When not to use
866
+ * Do not use icon buttons when the action is not immediately clear from the icon. Use a regular Button with text instead.
867
+ *
868
+ * @example Basic icon button
869
+ * ```tsx
870
+ * import { IconButton, Icon } from "@trackunit/react-components";
871
+ *
872
+ * const MyComponent = () => {
873
+ * return (
874
+ * <IconButton
875
+ * icon={<Icon name="Trash" />}
876
+ * onClick={() => console.log('delete')}
877
+ * title="Delete item"
878
+ * />
879
+ * );
880
+ * };
881
+ * ```
882
+ * @example Icon button variants
883
+ * ```tsx
884
+ * import { IconButton, Icon } from "@trackunit/react-components";
885
+ *
886
+ * const IconButtonExamples = () => {
887
+ * return (
888
+ * <div className="flex gap-2">
889
+ * <IconButton icon={<Icon name="Plus" />} variant="primary" title="Add" />
890
+ * <IconButton icon={<Icon name="Cog" />} variant="secondary" title="Settings" />
891
+ * <IconButton icon={<Icon name="XMark" />} variant="ghost" title="Close" />
892
+ * <IconButton icon={<Icon name="Trash" />} variant="primary-danger" title="Delete" />
893
+ * <IconButton icon={<Icon name="Plus" />} size="small" title="Small add" />
894
+ * </div>
895
+ * );
896
+ * };
897
+ * ```
898
+ * @param {IconButtonProps} props - The props for the IconButton component
899
+ * @returns {ReactElement} IconButton component
803
900
  */
804
901
  const IconButton = ({ icon, size = "medium", square = true, loading = false, disabled = false, className, ref, ...rest }) => {
805
902
  return (jsx(Button, { className: cvaIconButton({ size: size, className }), disabled: disabled || loading, loading: loading, prefix: !loading ? icon : undefined, ref: ref, size: size, square: square, ...rest }));
@@ -901,8 +998,66 @@ const cvaAlertIconContainer = cvaMerge(["shrink-0", "grid", "w-min", "flex"], {
901
998
  });
902
999
 
903
1000
  /**
904
- * The Alert component should be used to inform the user of important information.
1001
+ * The Alert component should be used to inform the user of important information such as errors, warnings, success messages, or informational notices.
1002
+ *
1003
+ * ### When to use
1004
+ * Use alerts to communicate important information that requires user attention, such as form validation errors, action confirmations, or system status updates.
1005
+ *
1006
+ * ### When not to use
1007
+ * Do not use alerts for non-critical information or marketing messages. Use Notice component for less urgent communications.
905
1008
  *
1009
+ * @example Basic alert variants
1010
+ * ```tsx
1011
+ * import { Alert } from "@trackunit/react-components";
1012
+ *
1013
+ * const AlertExamples = () => {
1014
+ * return (
1015
+ * <div className="flex flex-col gap-4">
1016
+ * <Alert color="info" title="Information">
1017
+ * Your session will expire in 5 minutes.
1018
+ * </Alert>
1019
+ * <Alert color="success" title="Success">
1020
+ * Asset successfully updated.
1021
+ * </Alert>
1022
+ * <Alert color="warning" title="Warning">
1023
+ * Low battery detected on 3 assets.
1024
+ * </Alert>
1025
+ * <Alert color="danger" title="Error">
1026
+ * Failed to save changes. Please try again.
1027
+ * </Alert>
1028
+ * </div>
1029
+ * );
1030
+ * };
1031
+ * ```
1032
+ * @example Alert with actions and close button
1033
+ * ```tsx
1034
+ * import { Alert } from "@trackunit/react-components";
1035
+ * import { useState } from "react";
1036
+ *
1037
+ * const DismissibleAlert = () => {
1038
+ * const [visible, setVisible] = useState(true);
1039
+ *
1040
+ * if (!visible) return null;
1041
+ *
1042
+ * return (
1043
+ * <Alert
1044
+ * color="warning"
1045
+ * title="Unsaved Changes"
1046
+ * onClose={() => setVisible(false)}
1047
+ * primaryAction={{
1048
+ * label: "Save Now",
1049
+ * onClick: () => console.log("Saving..."),
1050
+ * }}
1051
+ * secondaryAction={{
1052
+ * label: "Discard",
1053
+ * onClick: () => setVisible(false),
1054
+ * }}
1055
+ * >
1056
+ * You have unsaved changes that will be lost if you leave this page.
1057
+ * </Alert>
1058
+ * );
1059
+ * };
1060
+ * ```
906
1061
  * @param {AlertProps} props - The props for the Alert component
907
1062
  * @returns {ReactElement} Alert component
908
1063
  */
@@ -1004,6 +1159,27 @@ const cvaBadge = cvaMerge([
1004
1159
  * - Use a Badge to indicate notifications or counts of applied elements.
1005
1160
  * - Use a [Tag](https://design.iris.trackunit.com/?path=/docs/react-components-tag--docs) for labeling statuses, categories, or selections.
1006
1161
  *
1162
+ * @example Badge with count and max value
1163
+ * ```tsx
1164
+ * import { Badge, Button } from "@trackunit/react-components";
1165
+ *
1166
+ * const NotificationButton = () => (
1167
+ * <Button variant="secondary">
1168
+ * Notifications <Badge count={15} max={9} color="danger" />
1169
+ * </Button>
1170
+ * );
1171
+ * ```
1172
+ * @example Compact badge as status dot
1173
+ * ```tsx
1174
+ * import { Badge } from "@trackunit/react-components";
1175
+ *
1176
+ * const OnlineStatus = () => (
1177
+ * <div className="flex items-center gap-2">
1178
+ * <Badge compact color="primary" />
1179
+ * <span>Online</span>
1180
+ * </div>
1181
+ * );
1182
+ * ```
1007
1183
  * @param {BadgeProps} props - The props for the Badge component
1008
1184
  * @returns {ReactElement} Badge component
1009
1185
  */
@@ -1195,6 +1371,26 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1195
1371
  * Do not use on the first hierarchal level, such as a home page or a main page, as there is no previous step the user can get to.
1196
1372
  * Avoid using breadcrumbs to indicate forthcoming steps. For processes with sequential steps, use a wizard flow instead.
1197
1373
  *
1374
+ * @example Basic breadcrumb navigation
1375
+ * ```tsx
1376
+ * import { Breadcrumb } from "@trackunit/react-components";
1377
+ * import { useNavigate } from "@tanstack/react-router";
1378
+ *
1379
+ * const AssetDetailBreadcrumb = () => {
1380
+ * const navigate = useNavigate();
1381
+ *
1382
+ * return (
1383
+ * <Breadcrumb
1384
+ * breadcrumbItems={[
1385
+ * { label: "Fleet", to: "/fleet" },
1386
+ * { label: "Assets", to: "/fleet/assets" },
1387
+ * { label: "Excavator 001", to: "/fleet/assets/123" },
1388
+ * ]}
1389
+ * back={() => navigate({ to: "/fleet/assets" })}
1390
+ * />
1391
+ * );
1392
+ * };
1393
+ * ```
1198
1394
  * @param {BreadcrumbProps} props - The props for the Breadcrumb component
1199
1395
  * @returns {ReactElement} Breadcrumb component
1200
1396
  */
@@ -1306,9 +1502,49 @@ const cvaCardBodyContainer = cvaMerge(["flex", "flex-grow", "overflow-auto"], {
1306
1502
 
1307
1503
  const ROLE_CARD = "region";
1308
1504
  /**
1309
- * The Card component is a container for UI elements, and is the main component of the modal.
1505
+ * The Card component is a container for UI elements that groups related content together with a visual boundary.
1310
1506
  * To get the most out of the Card, use it in combination with the CardHeader, CardBody and CardFooter.
1311
1507
  *
1508
+ * ### When to use
1509
+ * Use cards to group related information and actions, such as in dashboards, list items, or content previews.
1510
+ *
1511
+ * ### When not to use
1512
+ * Do not use cards for layout purposes only. Use standard containers or grid layouts instead.
1513
+ *
1514
+ * @example Basic card
1515
+ * ```tsx
1516
+ * import { Card, CardHeader, CardBody } from "@trackunit/react-components";
1517
+ *
1518
+ * const MyComponent = () => {
1519
+ * return (
1520
+ * <Card>
1521
+ * <CardHeader title="Asset Details" />
1522
+ * <CardBody>
1523
+ * <p>This card contains information about the asset.</p>
1524
+ * </CardBody>
1525
+ * </Card>
1526
+ * );
1527
+ * };
1528
+ * ```
1529
+ * @example Clickable card with full content
1530
+ * ```tsx
1531
+ * import { Card, CardHeader, CardBody, CardFooter, Button } from "@trackunit/react-components";
1532
+ *
1533
+ * const AssetCard = () => {
1534
+ * return (
1535
+ * <Card onClick={() => console.log("Card clicked")}>
1536
+ * <CardHeader title="Excavator #1234" subtitle="Last updated: 2 hours ago" />
1537
+ * <CardBody>
1538
+ * <p>Operating hours: 1,234</p>
1539
+ * <p>Status: Active</p>
1540
+ * </CardBody>
1541
+ * <CardFooter>
1542
+ * <Button variant="secondary" size="small">View Details</Button>
1543
+ * </CardFooter>
1544
+ * </Card>
1545
+ * );
1546
+ * };
1547
+ * ```
1312
1548
  * @param {CardProps} props - The props for the Card component
1313
1549
  * @returns {ReactElement} Card component
1314
1550
  */
@@ -1642,7 +1878,7 @@ const cvaChevronIcon = cvaMerge(["transition-transform"], {
1642
1878
  * The Collapse component is a container for additional information that adds context to various flows. It is used for displaying non-essential information that can be hidden away.
1643
1879
  *
1644
1880
  * ### When to use
1645
- * - To keep content off the screen to shorten pages and reduce scrolling, while its still only a tap away. Remember that the users might choose not to interact with the component and wont see the information within.
1881
+ * - To keep content off the screen to shorten pages and reduce scrolling, while it's still only a tap away. Remember that the users might choose not to interact with the component and won't see the information within.
1646
1882
  * - To display additional details that are not essential or necessary in the main flow/page.
1647
1883
  *
1648
1884
  * ### When not to use
@@ -1652,6 +1888,35 @@ const cvaChevronIcon = cvaMerge(["transition-transform"], {
1652
1888
  * - To hide errors or information that is relevant for a user within a flow.
1653
1889
  * - To creating hierarchy levels by nesting them within each other.
1654
1890
  *
1891
+ * @example Basic collapse section
1892
+ * ```tsx
1893
+ * import { Collapse, Text } from "@trackunit/react-components";
1894
+ *
1895
+ * const AdditionalDetails = () => (
1896
+ * <Collapse id="details" label="Additional Details">
1897
+ * <Text>
1898
+ * This content is hidden by default and can be expanded by clicking the header.
1899
+ * Use this for supplementary information that isn't critical to the main flow.
1900
+ * </Text>
1901
+ * </Collapse>
1902
+ * );
1903
+ * ```
1904
+ * @example Collapse with header addon and initial expanded state
1905
+ * ```tsx
1906
+ * import { Collapse, Badge } from "@trackunit/react-components";
1907
+ *
1908
+ * const NotificationsSection = () => (
1909
+ * <Collapse
1910
+ * id="notifications"
1911
+ * label="Notifications"
1912
+ * initialExpanded={true}
1913
+ * headerAddon={<Badge count={5} color="primary" />}
1914
+ * onToggle={(e, expanded) => console.log("Expanded:", expanded)}
1915
+ * >
1916
+ * <div>Notification list content here</div>
1917
+ * </Collapse>
1918
+ * );
1919
+ * ```
1655
1920
  * @param {CollapseProps} props - The props for the Collapse component
1656
1921
  * @returns {ReactElement} Collapse component
1657
1922
  */
@@ -2014,13 +2279,52 @@ WorkerWithSignSVG.displayName = "WorkerWithSignSVG";
2014
2279
 
2015
2280
  /**
2016
2281
  *
2017
- * Empty states serve as placeholders when there's no content to display in either a table or card. They guide users out of the empty state towards actionable steps, highlighting ways to progress. Its recommended to suggest simple actions that can help the users move out of the empty states towards the content that fits their goals.
2282
+ * Empty states serve as placeholders when there's no content to display in either a table or card. They guide users out of the empty state towards actionable steps, highlighting ways to progress. It's recommended to suggest simple actions that can help the users move out of the empty states towards the content that fits their goals.
2018
2283
  * ## **When to Use**
2019
2284
  * - When user actions yield no results (e.g., empty search results or unfilled data).
2020
2285
  * - To offer guidance on navigating out of the empty state.
2021
2286
  * - In cases of errors (e.g., failed content loading, unexpected errors).
2022
2287
  * - For guidance purposes (e.g., onboarding, adjusting filters, exploring alternative approaches).
2023
2288
  * - In celebratory instances (e.g., no new notifications, services up to date).
2289
+ *
2290
+ * @example Empty state with actions for no search results
2291
+ * ```tsx
2292
+ * import { EmptyState } from "@trackunit/react-components";
2293
+ *
2294
+ * const NoSearchResults = () => (
2295
+ * <EmptyState
2296
+ * image="SEARCH_DOCUMENT"
2297
+ * description="No assets match your search criteria"
2298
+ * primaryAction={{
2299
+ * title: "Clear filters",
2300
+ * onClick: () => console.log("Clear filters"),
2301
+ * }}
2302
+ * secondaryAction={{
2303
+ * title: "Add new asset",
2304
+ * onClick: () => console.log("Add asset"),
2305
+ * }}
2306
+ * />
2307
+ * );
2308
+ * ```
2309
+ * @example Empty state for error with help link
2310
+ * ```tsx
2311
+ * import { EmptyState } from "@trackunit/react-components";
2312
+ *
2313
+ * const ErrorState = () => (
2314
+ * <EmptyState
2315
+ * image="BUILDING_ERROR"
2316
+ * description="Something went wrong while loading your data"
2317
+ * primaryAction={{
2318
+ * title: "Try again",
2319
+ * onClick: () => window.location.reload(),
2320
+ * }}
2321
+ * additionalHelpAction={{
2322
+ * title: "Contact support",
2323
+ * to: { pathname: "https://support.trackunit.com", target: "_blank" },
2324
+ * }}
2325
+ * />
2326
+ * );
2327
+ * ```
2024
2328
  */
2025
2329
  const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customImageSrc, loading = false, "data-testid": dataTestId, className, primaryAction, secondaryAction, additionalHelpAction, }) => {
2026
2330
  const ImageSource = useMemo(() => {
@@ -3541,6 +3845,45 @@ const usePopoverContext = () => {
3541
3845
  *
3542
3846
  * To render the content of the popover, use the `<PopoverContent />` component.
3543
3847
  *
3848
+ * @example Basic popover with trigger
3849
+ * ```tsx
3850
+ * import { Popover, PopoverTrigger, PopoverContent, Button, Text } from "@trackunit/react-components";
3851
+ *
3852
+ * const InfoPopover = () => (
3853
+ * <Popover placement="bottom-start">
3854
+ * <PopoverTrigger>
3855
+ * <Button variant="secondary">Show Info</Button>
3856
+ * </PopoverTrigger>
3857
+ * <PopoverContent>
3858
+ * <div className="p-4 max-w-xs">
3859
+ * <Text weight="bold">Asset Information</Text>
3860
+ * <Text size="small">Additional details about this asset appear here.</Text>
3861
+ * </div>
3862
+ * </PopoverContent>
3863
+ * </Popover>
3864
+ * );
3865
+ * ```
3866
+ * @example Controlled popover with render prop
3867
+ * ```tsx
3868
+ * import { Popover, PopoverTrigger, PopoverContent, Button } from "@trackunit/react-components";
3869
+ *
3870
+ * const ControlledPopover = () => (
3871
+ * <Popover placement="right">
3872
+ * {({ isOpen, setIsOpen }) => (
3873
+ * <>
3874
+ * <PopoverTrigger>
3875
+ * <Button onClick={() => setIsOpen(!isOpen)}>
3876
+ * {isOpen ? "Close" : "Open"} Menu
3877
+ * </Button>
3878
+ * </PopoverTrigger>
3879
+ * <PopoverContent>
3880
+ * <div className="p-4">Popover content</div>
3881
+ * </PopoverContent>
3882
+ * </>
3883
+ * )}
3884
+ * </Popover>
3885
+ * );
3886
+ * ```
3544
3887
  * @param {PopoverProps} props The props for the popover
3545
3888
  * @returns {ReactElement} A Popover Context Provider containing the children
3546
3889
  */
@@ -3712,6 +4055,35 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
3712
4055
  *
3713
4056
  * **Do not use** tooltips to include information that is necessary for the user to complete their task. Use helper text that is always visible and accessible for vital information.
3714
4057
  *
4058
+ * @example Tooltip on an icon button
4059
+ * ```tsx
4060
+ * import { Tooltip, IconButton, Icon } from "@trackunit/react-components";
4061
+ *
4062
+ * const SettingsButton = () => (
4063
+ * <Tooltip label="Open settings" placement="bottom">
4064
+ * <IconButton
4065
+ * icon={<Icon name="Cog6Tooth" size="small" />}
4066
+ * variant="ghost-neutral"
4067
+ * onClick={() => console.log("Settings clicked")}
4068
+ * />
4069
+ * </Tooltip>
4070
+ * );
4071
+ * ```
4072
+ * @example Standalone tooltip icon for explanations
4073
+ * ```tsx
4074
+ * import { Tooltip } from "@trackunit/react-components";
4075
+ *
4076
+ * const FieldWithHelp = () => (
4077
+ * <div className="flex items-center gap-2">
4078
+ * <span>Utilization Rate</span>
4079
+ * <Tooltip
4080
+ * label="The percentage of time the asset was actively in use during the selected period"
4081
+ * placement="right"
4082
+ * mode="light"
4083
+ * />
4084
+ * </div>
4085
+ * );
4086
+ * ```
3715
4087
  * @param {TooltipProps} props - The props for the Tooltip component
3716
4088
  * @returns {ReactElement} Tooltip component
3717
4089
  */
@@ -3877,7 +4249,32 @@ const cvaIndicatorIconBackground = cvaMerge(["rounded-full", "items-center", "ju
3877
4249
  * _**Do use** indicators to communicate essential aspects of the state of an asset._
3878
4250
  *
3879
4251
  * _**Do not use** indicators for non-essential information, or to communicate information unrelated to the state of an asset._
3880
-
4252
+ *
4253
+ * @example Asset status indicator with icon
4254
+ * ```tsx
4255
+ * import { Indicator, Icon } from "@trackunit/react-components";
4256
+ *
4257
+ * const AssetStatusIndicator = () => (
4258
+ * <Indicator
4259
+ * icon={<Icon name="Bolt" size="small" />}
4260
+ * color="success"
4261
+ * label="Running"
4262
+ * />
4263
+ * );
4264
+ * ```
4265
+ * @example Pinging indicator for alerts
4266
+ * ```tsx
4267
+ * import { Indicator, Icon } from "@trackunit/react-components";
4268
+ *
4269
+ * const AlertIndicator = () => (
4270
+ * <Indicator
4271
+ * icon={<Icon name="ExclamationTriangle" size="small" />}
4272
+ * color="danger"
4273
+ * label="Critical Alert"
4274
+ * ping={true}
4275
+ * />
4276
+ * );
4277
+ * ```
3881
4278
  * @param {IndicatorProps} props - The props for the Indicator component
3882
4279
  * @returns {ReactElement} Indicator component
3883
4280
  */
@@ -3974,8 +4371,43 @@ const cvaKPITrendPercentage = cvaMerge([""], {
3974
4371
  });
3975
4372
 
3976
4373
  /**
3977
- * The KPI component is used to display KPIs.
4374
+ * The KPI component displays a key performance indicator with a title, value, and unit.
4375
+ * It's ideal for showing important metrics at a glance in dashboards and summary views.
4376
+ *
4377
+ * ### When to use
4378
+ * - To display important numeric metrics that users need to monitor
4379
+ * - In dashboard headers, cards, or page summaries
4380
+ * - When you need a compact way to show a labeled value with units
4381
+ *
4382
+ * ### When not to use
4383
+ * - For detailed data that requires charts or tables
4384
+ * - When the metric needs interactive elements (use KPICard instead)
4385
+ *
4386
+ * @example Basic KPI display
4387
+ * ```tsx
4388
+ * import { KPI } from "@trackunit/react-components";
4389
+ *
4390
+ * const FleetUtilization = () => (
4391
+ * <KPI
4392
+ * title="Fleet Utilization"
4393
+ * value={87}
4394
+ * unit="%"
4395
+ * tooltipLabel="Average utilization across all assets"
4396
+ * />
4397
+ * );
4398
+ * ```
4399
+ * @example KPI variants
4400
+ * ```tsx
4401
+ * import { KPI } from "@trackunit/react-components";
3978
4402
  *
4403
+ * const MetricsRow = () => (
4404
+ * <div className="flex gap-4">
4405
+ * <KPI title="Total Assets" value={156} unit="units" variant="default" />
4406
+ * <KPI title="Active" value={142} unit="" variant="small" />
4407
+ * <KPI title="Idle Time" value="2.5" unit="hrs" variant="condensed" />
4408
+ * </div>
4409
+ * );
4410
+ * ```
3979
4411
  * @param {KPIProps} props - The props for the KPI component
3980
4412
  * @returns {ReactElement} KPI component
3981
4413
  */
@@ -4332,8 +4764,54 @@ const cvaKPIIconContainer = cvaMerge(["flex", "items-center", "justify-center",
4332
4764
  });
4333
4765
 
4334
4766
  /**
4335
- * The KPICard component is used to display KPIs.
4767
+ * The KPICard component displays a key performance indicator in an interactive card format.
4768
+ * It extends the basic KPI with additional features like icons, trends, value bars, and notices.
4769
+ *
4770
+ * ### When to use
4771
+ * - When KPIs need to be clickable or selectable
4772
+ * - To show trends or progress alongside the metric value
4773
+ * - When you need a richer visual representation of a KPI
4774
+ *
4775
+ * ### When not to use
4776
+ * - For simple metric display without interaction (use KPI instead)
4777
+ * - When space is very limited
4336
4778
  *
4779
+ * @example KPI card with trend indicator
4780
+ * ```tsx
4781
+ * import { KPICard } from "@trackunit/react-components";
4782
+ *
4783
+ * const UtilizationCard = () => (
4784
+ * <KPICard
4785
+ * title="Utilization"
4786
+ * value={87}
4787
+ * unit="%"
4788
+ * iconName="ChartBar"
4789
+ * iconColor="success"
4790
+ * trends={[
4791
+ * { value: 5, direction: "up", label: "vs last week" },
4792
+ * ]}
4793
+ * onClick={() => console.log("Navigate to details")}
4794
+ * />
4795
+ * );
4796
+ * ```
4797
+ * @example KPI card with value bar and notice
4798
+ * ```tsx
4799
+ * import { KPICard } from "@trackunit/react-components";
4800
+ *
4801
+ * const StorageCard = () => (
4802
+ * <KPICard
4803
+ * title="Storage Used"
4804
+ * value={75}
4805
+ * unit="GB"
4806
+ * valueBar={{ value: 75, max: 100 }}
4807
+ * notice={{
4808
+ * label: "25 GB remaining",
4809
+ * iconName: "InformationCircle",
4810
+ * iconColor: "info",
4811
+ * }}
4812
+ * />
4813
+ * );
4814
+ * ```
4337
4815
  * @param {KPICardProps} props - The props for the KPICard component
4338
4816
  * @returns {ReactElement} KPICard component
4339
4817
  */
@@ -4425,7 +4903,6 @@ const cvaDetailsContainer = cvaMerge(["flex", "items-center", "gap-0.5", "text-n
4425
4903
  */
4426
4904
  const DEFAULT_SKELETON_LIST_ITEM_PROPS = {
4427
4905
  hasThumbnail: true,
4428
- thumbnailShape: "circle",
4429
4906
  hasDescription: true,
4430
4907
  hasMeta: false,
4431
4908
  hasDetails: false,
@@ -5191,8 +5668,53 @@ const MenuItem = ({ className, "data-testid": dataTestId, label, children, selec
5191
5668
  * **When to use**
5192
5669
  * - Use the MenuList if you have limited space and need to display overflow actions in a list.
5193
5670
  * - Use the MenuList for actions that are not essential to completing workflows.
5194
- * - Dont use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
5671
+ * - Don't use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
5672
+ *
5673
+ * @example MenuList with action items
5674
+ * ```tsx
5675
+ * import { MenuList, MenuItem, MoreMenu, Icon } from "@trackunit/react-components";
5676
+ *
5677
+ * const ActionsMenu = () => (
5678
+ * <MoreMenu>
5679
+ * {(close) => (
5680
+ * <MenuList onClick={close}>
5681
+ * <MenuItem id="edit" prefix={<Icon name="PencilSquare" size="small" />}>
5682
+ * Edit
5683
+ * </MenuItem>
5684
+ * <MenuItem id="duplicate" prefix={<Icon name="DocumentDuplicate" size="small" />}>
5685
+ * Duplicate
5686
+ * </MenuItem>
5687
+ * <MenuItem id="delete" prefix={<Icon name="Trash" size="small" />} destructive>
5688
+ * Delete
5689
+ * </MenuItem>
5690
+ * </MenuList>
5691
+ * )}
5692
+ * </MoreMenu>
5693
+ * );
5694
+ * ```
5695
+ * @example Multi-select MenuList
5696
+ * ```tsx
5697
+ * import { MenuList, MenuItem, MoreMenu } from "@trackunit/react-components";
5698
+ * import { useState } from "react";
5699
+ *
5700
+ * const FilterMenu = () => {
5701
+ * const [selected, setSelected] = useState<string[]>(["active"]);
5195
5702
  *
5703
+ * return (
5704
+ * <MoreMenu label="Filter by status">
5705
+ * <MenuList
5706
+ * isMulti
5707
+ * selectedItems={selected}
5708
+ * onSelectionChange={setSelected}
5709
+ * >
5710
+ * <MenuItem id="active">Active</MenuItem>
5711
+ * <MenuItem id="idle">Idle</MenuItem>
5712
+ * <MenuItem id="offline">Offline</MenuItem>
5713
+ * </MenuList>
5714
+ * </MoreMenu>
5715
+ * );
5716
+ * };
5717
+ * ```
5196
5718
  * @param {MenuListProps} props - The props for the MenuList component
5197
5719
  * @returns {ReactElement} MenuList component
5198
5720
  */
@@ -5519,6 +6041,45 @@ const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, }) => {
5519
6041
  * PageHeader can be used to highlight the page topic, display helpful information about the page, and carry the action items related to the current page.
5520
6042
  * Tabs can be added to the PageHeader to allow users to navigate between different sections of the page.
5521
6043
  *
6044
+ * @example Page header with actions
6045
+ * ```tsx
6046
+ * import { PageHeader } from "@trackunit/react-components";
6047
+ *
6048
+ * const AssetPage = () => (
6049
+ * <PageHeader
6050
+ * title="Asset Management"
6051
+ * description="Manage and monitor your fleet assets"
6052
+ * accessoryType="actions"
6053
+ * primaryAction={{
6054
+ * actionText: "Add Asset",
6055
+ * actionCallback: () => console.log("Add asset"),
6056
+ * prefixIconName: "Plus",
6057
+ * variant: "primary",
6058
+ * }}
6059
+ * secondaryActions={[
6060
+ * { actionText: "Export", actionCallback: () => {}, variant: "secondary" },
6061
+ * ]}
6062
+ * />
6063
+ * );
6064
+ * ```
6065
+ * @example Page header with KPI metrics
6066
+ * ```tsx
6067
+ * import { PageHeader } from "@trackunit/react-components";
6068
+ *
6069
+ * const DashboardHeader = () => (
6070
+ * <PageHeader
6071
+ * title="Fleet Overview"
6072
+ * tagLabel="Live"
6073
+ * tagColor="success"
6074
+ * accessoryType="kpi-metrics"
6075
+ * kpiMetrics={[
6076
+ * { header: "Total Assets", value: 156, unit: "" },
6077
+ * { header: "Active", value: 142, unit: "assets" },
6078
+ * { header: "Utilization", value: 87, unit: "%" },
6079
+ * ]}
6080
+ * />
6081
+ * );
6082
+ * ```
5522
6083
  * @param {PageHeaderProps} props - The props for the PageHeader component
5523
6084
  * @returns {ReactElement} PageHeader component
5524
6085
  */
@@ -6012,6 +6573,27 @@ const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id"
6012
6573
  *
6013
6574
  * When using this component make sure to add `setupIntersectionObserver();` to your jest.setup.ts file.
6014
6575
  *
6576
+ * @example Responsive sidebar with navigation items
6577
+ * ```tsx
6578
+ * import { Sidebar, Button } from "@trackunit/react-components";
6579
+ *
6580
+ * const NavigationSidebar = () => (
6581
+ * <Sidebar breakpoint="lg">
6582
+ * <Button id="overview" variant="ghost-neutral" className="min-w-[100px]">
6583
+ * Overview
6584
+ * </Button>
6585
+ * <Button id="assets" variant="ghost-neutral" className="min-w-[100px]">
6586
+ * Assets
6587
+ * </Button>
6588
+ * <Button id="reports" variant="ghost-neutral" className="min-w-[100px]">
6589
+ * Reports
6590
+ * </Button>
6591
+ * <Button id="settings" variant="ghost-neutral" className="min-w-[100px]">
6592
+ * Settings
6593
+ * </Button>
6594
+ * </Sidebar>
6595
+ * );
6596
+ * ```
6015
6597
  * @param {SidebarProps} props - The props for the Sidebar component
6016
6598
  * @returns {ReactElement} Sidebar component
6017
6599
  */
@@ -6165,6 +6747,39 @@ const TabList = ({ className, "data-testid": dataTestId, children, autoScrollToA
6165
6747
 
6166
6748
  /**
6167
6749
  * Tabs are used to group different but related content, allowing users to navigate views without leaving the page. They always contain at least two items and one tab is active at a time. Tabs can be used on full page layouts or in components such as modals or tables.
6750
+ *
6751
+ * @example Basic tabs with content panels
6752
+ * ```tsx
6753
+ * import { Tabs, TabList, Tab, TabContent } from "@trackunit/react-components";
6754
+ *
6755
+ * const MyTabs = () => (
6756
+ * <Tabs defaultValue="tab1">
6757
+ * <TabList>
6758
+ * <Tab value="tab1">Overview</Tab>
6759
+ * <Tab value="tab2">Details</Tab>
6760
+ * <Tab value="tab3">Settings</Tab>
6761
+ * </TabList>
6762
+ * <TabContent value="tab1">Overview content goes here</TabContent>
6763
+ * <TabContent value="tab2">Details content goes here</TabContent>
6764
+ * <TabContent value="tab3">Settings content goes here</TabContent>
6765
+ * </Tabs>
6766
+ * );
6767
+ * ```
6768
+ * @example Full width tabs with icons
6769
+ * ```tsx
6770
+ * import { Tabs, TabList, Tab, TabContent } from "@trackunit/react-components";
6771
+ *
6772
+ * const FullWidthTabs = () => (
6773
+ * <Tabs defaultValue="assets" fullWidth>
6774
+ * <TabList>
6775
+ * <Tab value="assets" iconName="Truck" isFullWidth>Assets</Tab>
6776
+ * <Tab value="sites" iconName="MapPin" isFullWidth>Sites</Tab>
6777
+ * </TabList>
6778
+ * <TabContent value="assets">Asset list</TabContent>
6779
+ * <TabContent value="sites">Site list</TabContent>
6780
+ * </Tabs>
6781
+ * );
6782
+ * ```
6168
6783
  */
6169
6784
  const Tabs = ({ children, forceRender, className, "data-testid": dataTestId, fullWidth, ...rest }) => {
6170
6785
  return (jsx(Root, { className: cvaTabsRoot({ className }), "data-testid": dataTestId, ...rest, children: children }));