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