@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 +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.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](
|
|
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
|
|
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 it
|
|
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. It
|
|
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
|
|
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
|
|
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
|
-
* - Don
|
|
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 }));
|