react-status-tracker 1.0.0

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/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # React Status Tracker
2
+
3
+ **React Status Tracker** is a reusable **status / step / workflow tracker** component for React applications.
4
+ It supports both **horizontal and vertical layouts** and is built using **Material UI (MUI)**.
5
+
6
+ This component can be used for:
7
+ - Workflow tracking
8
+ - Order or shipment status
9
+ - Approval pipelines
10
+ - Process steps
11
+ - Progress visualization
12
+
13
+ It supports **active and inactive steps**, an optional **flagged (error) state**, full **TypeScript support**, and extensive **customization options** for colors and sizes.
14
+ The component is **lightweight**, **production-ready**, and **compatible with MUI v5**.
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install react-status-tracker
22
+ ```
23
+
24
+ ### Peer Dependencies
25
+
26
+ ```bash
27
+ npm install @mui/material @mui/system @mui/utils @emotion/react @emotion/styled
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Usage Example
33
+
34
+ ```tsx
35
+ import { Box } from "@mui/material";
36
+ import StatusTracker from "react-status-tracker";
37
+
38
+ const steps = [
39
+ "TESTING",
40
+ "TESTING COMPLETE",
41
+ "TESTING REVIEW",
42
+ "TESTING APPROVED",
43
+ ];
44
+
45
+ export default function Example() {
46
+ return (
47
+ <Box sx={{ p: 4 }}>
48
+ <StatusTracker steps={steps} currentStatus="TESTING REVIEW" />
49
+ </Box>
50
+ );
51
+ }
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Vertical Layout Example
57
+
58
+ ```tsx
59
+ <StatusTracker
60
+ steps={steps}
61
+ currentStatus="TESTING REVIEW"
62
+ orientation="vertical"
63
+ />
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Flagged (Error) State Example
69
+
70
+ ```tsx
71
+ <StatusTracker
72
+ steps={steps}
73
+ currentStatus="TESTING REVIEW"
74
+ flagged
75
+ />
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Custom Styling Example
81
+
82
+ ```tsx
83
+ <StatusTracker
84
+ steps={steps}
85
+ currentStatus="TESTING REVIEW"
86
+ activeColor="#2e7d32"
87
+ inactiveColor="#e0e0e0"
88
+ circleSize={24}
89
+ lineThickness={3}
90
+ />
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Props
96
+
97
+ | Prop Name | Type | Description | Default |
98
+ |------------------|------------------------------|-------------------------------------------|----------------|
99
+ | steps | string[] | Ordered list of step labels | Required |
100
+ | currentStatus | string | Current active step | Required |
101
+ | orientation | horizontal \| vertical | Layout direction | horizontal |
102
+ | flagged | boolean | Error or alert state | false |
103
+ | activeColor | string | Active step color | - |
104
+ | inactiveColor | string | Inactive step color | #ccc |
105
+ | circleSize | number | Step indicator size | 20 |
106
+ | lineThickness | number | Connector thickness | 2 |
107
+
108
+ ---
109
+
110
+ ## Behavior Notes
111
+
112
+ - All steps before and including the current status are marked active
113
+ - Connector lines leading into the current step are active
114
+ - If the provided currentStatus does not exist in the steps array, the first step is selected
115
+ - Text labels never affect alignment
116
+
117
+ ---
118
+
119
+ ## TypeScript Support
120
+
121
+ ```ts
122
+ import type { StatusTrackerProps } from "react-status-tracker";
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Compatibility
128
+
129
+ - React 18+
130
+ - React 19+
131
+ - Material UI v5.x
132
+ - Emotion v11
133
+
134
+ ---
135
+
136
+ ## Common Use Cases
137
+
138
+ - Order tracking
139
+ - Shipment workflows
140
+ - Approval pipelines
141
+ - Task progression
142
+ - Multi-step form indicators
143
+
144
+ ---
145
+
146
+ ## Planned Enhancements
147
+
148
+ - Animated progress
149
+ - Icons inside steps
150
+ - Clickable steps
151
+ - Tooltip support
152
+ - SVG-based rendering option
153
+
154
+ ---
155
+
156
+ **Developed by Mohamed Ruwaid**
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ export type Orientation = "horizontal" | "vertical";
3
+ export interface StatusTrackerProps {
4
+ steps: string[];
5
+ currentStatus: string;
6
+ flagged?: boolean;
7
+ orientation?: Orientation;
8
+ activeColor?: string;
9
+ inactiveColor?: string;
10
+ circleSize?: number;
11
+ lineThickness?: number;
12
+ }
13
+ declare const StatusTracker: React.FC<StatusTrackerProps>;
14
+ export default StatusTracker;
@@ -0,0 +1,94 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var material = require('@mui/material');
5
+
6
+ var StatusTracker = function (_a) {
7
+ var steps = _a.steps, currentStatus = _a.currentStatus, _b = _a.flagged, flagged = _b === void 0 ? false : _b, _c = _a.orientation, orientation = _c === void 0 ? "horizontal" : _c, activeColor = _a.activeColor, _d = _a.inactiveColor, inactiveColor = _d === void 0 ? "#ccc" : _d, _e = _a.circleSize, circleSize = _e === void 0 ? 20 : _e, _f = _a.lineThickness, lineThickness = _f === void 0 ? 2 : _f;
8
+ var currentIndex = steps.indexOf(currentStatus);
9
+ var safeIndex = currentIndex === -1 ? 0 : currentIndex;
10
+ var resolvedActiveColor = activeColor !== null && activeColor !== void 0 ? activeColor : (flagged ? "#D32F2F" : "#1976D2");
11
+ var isVertical = orientation === "vertical";
12
+ return (jsxRuntime.jsx(material.Card, { sx: { borderRadius: 2, boxShadow: 2 }, children: jsxRuntime.jsx(material.CardContent, { sx: { p: 3 }, children: jsxRuntime.jsx(material.Box, { sx: {
13
+ boxSizing: "border-box",
14
+ isolation: "isolate",
15
+ display: "flex",
16
+ flexDirection: isVertical ? "column" : "row",
17
+ gap: isVertical ? 3 : 0,
18
+ }, children: steps.map(function (step, index) {
19
+ var isActive = index <= safeIndex;
20
+ /* =======================
21
+ VERTICAL MODE
22
+ ======================= */
23
+ if (isVertical) {
24
+ return (jsxRuntime.jsxs(material.Box, { sx: {
25
+ display: "flex",
26
+ alignItems: "flex-start",
27
+ }, children: [jsxRuntime.jsxs(material.Box, { sx: {
28
+ width: circleSize,
29
+ display: "flex",
30
+ flexDirection: "column",
31
+ alignItems: "center",
32
+ position: "relative",
33
+ }, children: [index > 0 && (jsxRuntime.jsx(material.Box, { sx: {
34
+ position: "absolute",
35
+ top: -24,
36
+ width: lineThickness,
37
+ height: 24,
38
+ bgcolor: isActive ? resolvedActiveColor : inactiveColor
39
+ } })), jsxRuntime.jsx(material.Box, { sx: {
40
+ width: circleSize,
41
+ height: circleSize,
42
+ borderRadius: "50%",
43
+ bgcolor: isActive
44
+ ? resolvedActiveColor
45
+ : inactiveColor,
46
+ zIndex: 1,
47
+ } })] }), jsxRuntime.jsx(material.Typography, { sx: {
48
+ ml: 2,
49
+ mt: "2px",
50
+ fontSize: "10px",
51
+ textTransform: "uppercase",
52
+ letterSpacing: "0.5px",
53
+ fontWeight: isActive ? "bold" : "normal",
54
+ color: "text.primary",
55
+ }, children: step })] }, step));
56
+ }
57
+ /* =======================
58
+ HORIZONTAL MODE
59
+ ======================= */
60
+ return (jsxRuntime.jsxs(material.Box, { sx: {
61
+ display: "flex",
62
+ flexDirection: "column",
63
+ alignItems: "center",
64
+ flex: 1,
65
+ position: "relative",
66
+ }, children: [index > 0 && (jsxRuntime.jsx(material.Box, { sx: {
67
+ position: "absolute",
68
+ left: "calc(-50% + ".concat(circleSize / 2, "px)"),
69
+ top: circleSize / 2 - lineThickness / 2,
70
+ width: "calc(100% - ".concat(circleSize, "px)"),
71
+ height: lineThickness,
72
+ bgcolor: isActive ? resolvedActiveColor : inactiveColor
73
+ } })), jsxRuntime.jsx(material.Box, { sx: {
74
+ width: circleSize,
75
+ height: circleSize,
76
+ borderRadius: "50%",
77
+ bgcolor: isActive
78
+ ? resolvedActiveColor
79
+ : inactiveColor,
80
+ zIndex: 1,
81
+ } }), jsxRuntime.jsx(material.Typography, { sx: {
82
+ mt: 1.5,
83
+ fontSize: "10px",
84
+ textTransform: "uppercase",
85
+ letterSpacing: "0.5px",
86
+ fontWeight: isActive ? "bold" : "normal",
87
+ textAlign: "center",
88
+ minWidth: 80,
89
+ }, children: step })] }, step));
90
+ }) }) }) }));
91
+ };
92
+
93
+ exports.StatusTracker = StatusTracker;
94
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/StatusTracker.tsx"],"sourcesContent":["import React from \"react\";\r\nimport { Card, CardContent, Box, Typography } from \"@mui/material\";\r\n\r\nexport type Orientation = \"horizontal\" | \"vertical\";\r\n\r\nexport interface StatusTrackerProps {\r\n steps: string[];\r\n currentStatus: string;\r\n flagged?: boolean;\r\n orientation?: Orientation;\r\n activeColor?: string;\r\n inactiveColor?: string;\r\n circleSize?: number;\r\n lineThickness?: number;\r\n}\r\n\r\nconst StatusTracker: React.FC<StatusTrackerProps> = ({\r\n steps,\r\n currentStatus,\r\n flagged = false,\r\n orientation = \"horizontal\",\r\n activeColor,\r\n inactiveColor = \"#ccc\",\r\n circleSize = 20,\r\n lineThickness = 2,\r\n}) => {\r\n const currentIndex = steps.indexOf(currentStatus);\r\n const safeIndex = currentIndex === -1 ? 0 : currentIndex;\r\n\r\n const resolvedActiveColor = activeColor ?? (flagged ? \"#D32F2F\" : \"#1976D2\");\r\n const isVertical = orientation === \"vertical\";\r\n\r\n return (\r\n <Card sx={{ borderRadius: 2, boxShadow: 2 }}>\r\n <CardContent sx={{ p: 3 }}>\r\n <Box\r\n sx={{\r\n boxSizing: \"border-box\",\r\n isolation: \"isolate\",\r\n display: \"flex\",\r\n flexDirection: isVertical ? \"column\" : \"row\",\r\n gap: isVertical ? 3 : 0,\r\n }}\r\n >\r\n\r\n {steps.map((step, index) => {\r\n const isActive = index <= safeIndex;\r\n\r\n /* =======================\r\n VERTICAL MODE\r\n ======================= */\r\n if (isVertical) {\r\n return (\r\n <Box\r\n key={step}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n }}\r\n >\r\n {/* LEFT COLUMN — geometry */}\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n position: \"relative\",\r\n }}\r\n >\r\n {index > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n top: -24,\r\n width: lineThickness,\r\n height: 24,\r\n bgcolor: isActive ? resolvedActiveColor : inactiveColor\r\n }}\r\n />\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n height: circleSize,\r\n borderRadius: \"50%\",\r\n bgcolor: isActive\r\n ? resolvedActiveColor\r\n : inactiveColor,\r\n zIndex: 1,\r\n }}\r\n />\r\n </Box>\r\n\r\n {/* RIGHT COLUMN — label */}\r\n <Typography\r\n sx={{\r\n ml: 2,\r\n mt: \"2px\",\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n letterSpacing: \"0.5px\",\r\n fontWeight: isActive ? \"bold\" : \"normal\",\r\n color: \"text.primary\",\r\n }}\r\n >\r\n {step}\r\n </Typography>\r\n </Box>\r\n );\r\n }\r\n\r\n /* =======================\r\n HORIZONTAL MODE\r\n ======================= */\r\n return (\r\n <Box\r\n key={step}\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n flex: 1,\r\n position: \"relative\",\r\n }}\r\n >\r\n {index > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: `calc(-50% + ${circleSize / 2}px)`,\r\n top: circleSize / 2 - lineThickness / 2,\r\n width: `calc(100% - ${circleSize}px)`,\r\n height: lineThickness,\r\n bgcolor: isActive ? resolvedActiveColor : inactiveColor\r\n }}\r\n />\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n height: circleSize,\r\n borderRadius: \"50%\",\r\n bgcolor: isActive\r\n ? resolvedActiveColor\r\n : inactiveColor,\r\n zIndex: 1,\r\n }}\r\n />\r\n\r\n <Typography\r\n sx={{\r\n mt: 1.5,\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n letterSpacing: \"0.5px\",\r\n fontWeight: isActive ? \"bold\" : \"normal\",\r\n textAlign: \"center\",\r\n minWidth: 80,\r\n }}\r\n >\r\n {step}\r\n </Typography>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </CardContent>\r\n </Card>\r\n );\r\n};\r\n\r\nexport default StatusTracker;\r\n"],"names":["_jsx","Card","CardContent","Box","_jsxs","Typography"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { default as StatusTracker } from "./StatusTracker";
2
+ export type { StatusTrackerProps, Orientation } from "./StatusTracker";
@@ -0,0 +1,92 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Card, CardContent, Box, Typography } from '@mui/material';
3
+
4
+ var StatusTracker = function (_a) {
5
+ var steps = _a.steps, currentStatus = _a.currentStatus, _b = _a.flagged, flagged = _b === void 0 ? false : _b, _c = _a.orientation, orientation = _c === void 0 ? "horizontal" : _c, activeColor = _a.activeColor, _d = _a.inactiveColor, inactiveColor = _d === void 0 ? "#ccc" : _d, _e = _a.circleSize, circleSize = _e === void 0 ? 20 : _e, _f = _a.lineThickness, lineThickness = _f === void 0 ? 2 : _f;
6
+ var currentIndex = steps.indexOf(currentStatus);
7
+ var safeIndex = currentIndex === -1 ? 0 : currentIndex;
8
+ var resolvedActiveColor = activeColor !== null && activeColor !== void 0 ? activeColor : (flagged ? "#D32F2F" : "#1976D2");
9
+ var isVertical = orientation === "vertical";
10
+ return (jsx(Card, { sx: { borderRadius: 2, boxShadow: 2 }, children: jsx(CardContent, { sx: { p: 3 }, children: jsx(Box, { sx: {
11
+ boxSizing: "border-box",
12
+ isolation: "isolate",
13
+ display: "flex",
14
+ flexDirection: isVertical ? "column" : "row",
15
+ gap: isVertical ? 3 : 0,
16
+ }, children: steps.map(function (step, index) {
17
+ var isActive = index <= safeIndex;
18
+ /* =======================
19
+ VERTICAL MODE
20
+ ======================= */
21
+ if (isVertical) {
22
+ return (jsxs(Box, { sx: {
23
+ display: "flex",
24
+ alignItems: "flex-start",
25
+ }, children: [jsxs(Box, { sx: {
26
+ width: circleSize,
27
+ display: "flex",
28
+ flexDirection: "column",
29
+ alignItems: "center",
30
+ position: "relative",
31
+ }, children: [index > 0 && (jsx(Box, { sx: {
32
+ position: "absolute",
33
+ top: -24,
34
+ width: lineThickness,
35
+ height: 24,
36
+ bgcolor: isActive ? resolvedActiveColor : inactiveColor
37
+ } })), jsx(Box, { sx: {
38
+ width: circleSize,
39
+ height: circleSize,
40
+ borderRadius: "50%",
41
+ bgcolor: isActive
42
+ ? resolvedActiveColor
43
+ : inactiveColor,
44
+ zIndex: 1,
45
+ } })] }), jsx(Typography, { sx: {
46
+ ml: 2,
47
+ mt: "2px",
48
+ fontSize: "10px",
49
+ textTransform: "uppercase",
50
+ letterSpacing: "0.5px",
51
+ fontWeight: isActive ? "bold" : "normal",
52
+ color: "text.primary",
53
+ }, children: step })] }, step));
54
+ }
55
+ /* =======================
56
+ HORIZONTAL MODE
57
+ ======================= */
58
+ return (jsxs(Box, { sx: {
59
+ display: "flex",
60
+ flexDirection: "column",
61
+ alignItems: "center",
62
+ flex: 1,
63
+ position: "relative",
64
+ }, children: [index > 0 && (jsx(Box, { sx: {
65
+ position: "absolute",
66
+ left: "calc(-50% + ".concat(circleSize / 2, "px)"),
67
+ top: circleSize / 2 - lineThickness / 2,
68
+ width: "calc(100% - ".concat(circleSize, "px)"),
69
+ height: lineThickness,
70
+ bgcolor: isActive ? resolvedActiveColor : inactiveColor
71
+ } })), jsx(Box, { sx: {
72
+ width: circleSize,
73
+ height: circleSize,
74
+ borderRadius: "50%",
75
+ bgcolor: isActive
76
+ ? resolvedActiveColor
77
+ : inactiveColor,
78
+ zIndex: 1,
79
+ } }), jsx(Typography, { sx: {
80
+ mt: 1.5,
81
+ fontSize: "10px",
82
+ textTransform: "uppercase",
83
+ letterSpacing: "0.5px",
84
+ fontWeight: isActive ? "bold" : "normal",
85
+ textAlign: "center",
86
+ minWidth: 80,
87
+ }, children: step })] }, step));
88
+ }) }) }) }));
89
+ };
90
+
91
+ export { StatusTracker };
92
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/StatusTracker.tsx"],"sourcesContent":["import React from \"react\";\r\nimport { Card, CardContent, Box, Typography } from \"@mui/material\";\r\n\r\nexport type Orientation = \"horizontal\" | \"vertical\";\r\n\r\nexport interface StatusTrackerProps {\r\n steps: string[];\r\n currentStatus: string;\r\n flagged?: boolean;\r\n orientation?: Orientation;\r\n activeColor?: string;\r\n inactiveColor?: string;\r\n circleSize?: number;\r\n lineThickness?: number;\r\n}\r\n\r\nconst StatusTracker: React.FC<StatusTrackerProps> = ({\r\n steps,\r\n currentStatus,\r\n flagged = false,\r\n orientation = \"horizontal\",\r\n activeColor,\r\n inactiveColor = \"#ccc\",\r\n circleSize = 20,\r\n lineThickness = 2,\r\n}) => {\r\n const currentIndex = steps.indexOf(currentStatus);\r\n const safeIndex = currentIndex === -1 ? 0 : currentIndex;\r\n\r\n const resolvedActiveColor = activeColor ?? (flagged ? \"#D32F2F\" : \"#1976D2\");\r\n const isVertical = orientation === \"vertical\";\r\n\r\n return (\r\n <Card sx={{ borderRadius: 2, boxShadow: 2 }}>\r\n <CardContent sx={{ p: 3 }}>\r\n <Box\r\n sx={{\r\n boxSizing: \"border-box\",\r\n isolation: \"isolate\",\r\n display: \"flex\",\r\n flexDirection: isVertical ? \"column\" : \"row\",\r\n gap: isVertical ? 3 : 0,\r\n }}\r\n >\r\n\r\n {steps.map((step, index) => {\r\n const isActive = index <= safeIndex;\r\n\r\n /* =======================\r\n VERTICAL MODE\r\n ======================= */\r\n if (isVertical) {\r\n return (\r\n <Box\r\n key={step}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n }}\r\n >\r\n {/* LEFT COLUMN — geometry */}\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n position: \"relative\",\r\n }}\r\n >\r\n {index > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n top: -24,\r\n width: lineThickness,\r\n height: 24,\r\n bgcolor: isActive ? resolvedActiveColor : inactiveColor\r\n }}\r\n />\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n height: circleSize,\r\n borderRadius: \"50%\",\r\n bgcolor: isActive\r\n ? resolvedActiveColor\r\n : inactiveColor,\r\n zIndex: 1,\r\n }}\r\n />\r\n </Box>\r\n\r\n {/* RIGHT COLUMN — label */}\r\n <Typography\r\n sx={{\r\n ml: 2,\r\n mt: \"2px\",\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n letterSpacing: \"0.5px\",\r\n fontWeight: isActive ? \"bold\" : \"normal\",\r\n color: \"text.primary\",\r\n }}\r\n >\r\n {step}\r\n </Typography>\r\n </Box>\r\n );\r\n }\r\n\r\n /* =======================\r\n HORIZONTAL MODE\r\n ======================= */\r\n return (\r\n <Box\r\n key={step}\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n flex: 1,\r\n position: \"relative\",\r\n }}\r\n >\r\n {index > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: `calc(-50% + ${circleSize / 2}px)`,\r\n top: circleSize / 2 - lineThickness / 2,\r\n width: `calc(100% - ${circleSize}px)`,\r\n height: lineThickness,\r\n bgcolor: isActive ? resolvedActiveColor : inactiveColor\r\n }}\r\n />\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: circleSize,\r\n height: circleSize,\r\n borderRadius: \"50%\",\r\n bgcolor: isActive\r\n ? resolvedActiveColor\r\n : inactiveColor,\r\n zIndex: 1,\r\n }}\r\n />\r\n\r\n <Typography\r\n sx={{\r\n mt: 1.5,\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n letterSpacing: \"0.5px\",\r\n fontWeight: isActive ? \"bold\" : \"normal\",\r\n textAlign: \"center\",\r\n minWidth: 80,\r\n }}\r\n >\r\n {step}\r\n </Typography>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </CardContent>\r\n </Card>\r\n );\r\n};\r\n\r\nexport default StatusTracker;\r\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "react-status-tracker",
3
+ "version": "1.0.0",
4
+ "description": "A reusable status tracker component for React with horizontal and vertical modes",
5
+ "license": "MIT",
6
+
7
+ "main": "dist/index.cjs.js",
8
+ "module": "dist/index.esm.js",
9
+ "types": "dist/index.d.ts",
10
+
11
+ "files": ["dist"],
12
+
13
+ "scripts": {
14
+ "build": "rollup -c",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+
18
+ "peerDependencies": {
19
+ "react": "^18 || ^19",
20
+ "react-dom": "^18 || ^19",
21
+
22
+ "@mui/material": "^5.15.0",
23
+ "@mui/system": "^5.15.0",
24
+ "@mui/utils": "^5.15.0",
25
+
26
+ "@emotion/react": "^11.11.0",
27
+ "@emotion/styled": "^11.11.0"
28
+ },
29
+
30
+ "devDependencies": {
31
+ "react": "^18.2.0",
32
+ "react-dom": "^18.2.0",
33
+
34
+ "@mui/material": "^5.15.0",
35
+ "@mui/system": "^5.15.0",
36
+ "@mui/utils": "^5.15.0",
37
+
38
+ "@emotion/react": "^11.11.0",
39
+ "@emotion/styled": "^11.11.0",
40
+
41
+ "@rollup/plugin-typescript": "^12.3.0",
42
+ "@types/react": "^18.2.45",
43
+ "@types/react-dom": "^18.2.18",
44
+ "rollup": "^4.54.0",
45
+ "rollup-plugin-peer-deps-external": "^2.2.4",
46
+ "tslib": "^2.8.1",
47
+ "typescript": "^5.9.3"
48
+ },
49
+
50
+ "keywords": [
51
+ "react",
52
+ "status-tracker",
53
+ "mui",
54
+ "stepper",
55
+ "workflow"
56
+ ]
57
+ }