@trackunit/react-components 1.14.17 → 1.14.19
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 +625 -10
- package/index.esm.js +628 -13
- package/package.json +5 -5
- package/src/components/Alert/Alert.d.ts +59 -1
- package/src/components/Badge/Badge.d.ts +21 -0
- package/src/components/Breadcrumb/Breadcrumb.d.ts +20 -0
- package/src/components/Card/Card.d.ts +41 -1
- package/src/components/Collapse/Collapse.d.ts +30 -1
- package/src/components/EmptyState/EmptyState.d.ts +40 -1
- package/src/components/EmptyState/states/index.d.ts +0 -1
- package/src/components/Indicator/Indicator.d.ts +26 -1
- package/src/components/KPI/KPI.d.ts +36 -1
- package/src/components/KPICard/KPICard.d.ts +47 -1
- package/src/components/Menu/MenuList/MenuList.d.ts +46 -1
- package/src/components/PageHeader/PageHeader.d.ts +39 -0
- package/src/components/Popover/Popover.d.ts +39 -0
- package/src/components/Sidebar/Sidebar.d.ts +21 -0
- package/src/components/Tabs/Tabs.d.ts +33 -0
- package/src/components/Tag/Tag.d.ts +27 -0
- package/src/components/Tooltip/Tooltip.d.ts +29 -0
- package/src/components/buttons/Button/Button.d.ts +32 -1
- package/src/components/buttons/IconButton/IconButton.d.ts +39 -0
- package/src/components/EmptyState/states/AnatomySVG.d.ts +0 -5
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 {
|
|
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 {
|
|
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,
|
|
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](
|
|
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
|
|
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 it
|
|
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. It
|
|
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
|
|
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
|
|
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
|
-
* - Don
|
|
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 }));
|