@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.65.1 → 0.5.0-beta.67.1
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 +84 -37
- package/dist/components/composed/ProcessFlow/ProcessFlow.cjs +2 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.cjs.map +1 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.js +543 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.js.map +1 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.utils.cjs +2 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.utils.cjs.map +1 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.utils.js +84 -0
- package/dist/components/composed/ProcessFlow/ProcessFlow.utils.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +99 -0
- package/dist/index.js +605 -601
- package/dist/index.js.map +1 -1
- package/dist/index.tailwind.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,9 +25,9 @@ This library provides:
|
|
|
25
25
|
## Compatibility
|
|
26
26
|
|
|
27
27
|
| Library version | React | Node.js | TDP (server utilities) |
|
|
28
|
-
|
|
|
29
|
-
| v0.5.x
|
|
30
|
-
| v0.4.x
|
|
28
|
+
| --------------- | ----- | ------- | ---------------------- |
|
|
29
|
+
| v0.5.x | 19+ | 18+ | v4.x+ |
|
|
30
|
+
| v0.4.x | 19+ | 18+ | v4.x+ |
|
|
31
31
|
|
|
32
32
|
> **Note:** The client-side components have no TDP version dependency.
|
|
33
33
|
> The `/server` utilities (JWT auth, provider helpers) require a running TDP instance of v4.x or later.
|
|
@@ -43,10 +43,10 @@ yarn add @tetrascience-npm/tetrascience-react-ui
|
|
|
43
43
|
|
|
44
44
|
```tsx
|
|
45
45
|
// 1. Import the CSS once at your app root (required)
|
|
46
|
-
import
|
|
46
|
+
import "@tetrascience-npm/tetrascience-react-ui/index.css";
|
|
47
47
|
|
|
48
48
|
// 2. Import components
|
|
49
|
-
import { Button, Card, CardHeader, CardContent } from
|
|
49
|
+
import { Button, Card, CardHeader, CardContent } from "@tetrascience-npm/tetrascience-react-ui";
|
|
50
50
|
|
|
51
51
|
function App() {
|
|
52
52
|
return (
|
|
@@ -67,9 +67,9 @@ This library uses **Tailwind CSS 4** with design tokens defined as CSS custom pr
|
|
|
67
67
|
|
|
68
68
|
### CSS Import Options
|
|
69
69
|
|
|
70
|
-
| Import path
|
|
71
|
-
|
|
|
72
|
-
| `@tetrascience-npm/tetrascience-react-ui/index.css`
|
|
70
|
+
| Import path | Use case |
|
|
71
|
+
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
|
|
72
|
+
| `@tetrascience-npm/tetrascience-react-ui/index.css` | **Pre-built CSS** — use this for most apps. Import once at your app root. |
|
|
73
73
|
| `@tetrascience-npm/tetrascience-react-ui/index.tailwind.css` | **Tailwind source** — for apps that run their own Tailwind build and want to extend/override tokens. |
|
|
74
74
|
|
|
75
75
|
Most consumers only need `index.css`:
|
|
@@ -100,7 +100,58 @@ Accordion, Alert, AlertDialog, AspectRatio, Avatar, Badge, Breadcrumb, Button, B
|
|
|
100
100
|
|
|
101
101
|
TetraScience-specific compositions built from UI primitives:
|
|
102
102
|
|
|
103
|
-
AppHeader, AppLayout, AssistantModal, CodeScriptEditorButton, LaunchContent, Main, Navbar, ProtocolConfiguration, ProtocolYamlCard, PythonEditorModal, Sidebar, TdpLink, TdpSearch, TdpUrl
|
|
103
|
+
AppHeader, AppLayout, AssistantModal, CodeScriptEditorButton, LaunchContent, Main, Navbar, ProcessFlow, ProtocolConfiguration, ProtocolYamlCard, PythonEditorModal, Sidebar, TdpLink, TdpSearch, TdpUrl
|
|
104
|
+
|
|
105
|
+
#### ProcessFlow
|
|
106
|
+
|
|
107
|
+
Use `ProcessFlow` to render parent-owned multi-step workflow state such as uploads, validation pipelines, review flows, processing stages, and setup sequences. Import it from the package and keep all workflow transitions and side effects in the consuming app.
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import {
|
|
111
|
+
PROCESS_FLOW_STEP_STATUSES,
|
|
112
|
+
ProcessFlow,
|
|
113
|
+
type ProcessFlowStep,
|
|
114
|
+
type ProcessFlowStepStatus,
|
|
115
|
+
} from "@tetrascience-npm/tetrascience-react-ui";
|
|
116
|
+
|
|
117
|
+
const steps: ProcessFlowStep[] = [
|
|
118
|
+
{ id: "upload", label: "Upload", description: "Choose source files", status: "completed" },
|
|
119
|
+
{ id: "validate", label: "Validate", description: "Check schema and lineage", status: "active" },
|
|
120
|
+
{ id: "publish", label: "Publish", description: "Send downstream", status: "pending" },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
function WorkflowProgress() {
|
|
124
|
+
return (
|
|
125
|
+
<ProcessFlow
|
|
126
|
+
steps={steps}
|
|
127
|
+
selectedStepId="validate"
|
|
128
|
+
onStepSelect={(step, details) => {
|
|
129
|
+
console.log(step.id, details.status);
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const allStatuses: readonly ProcessFlowStepStatus[] = PROCESS_FLOW_STEP_STATUSES;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Expected contract:
|
|
139
|
+
|
|
140
|
+
- `status` is independently controlled per step: `pending`, `active`, `completed`, `error`, or `disabled`.
|
|
141
|
+
- `selectedStepId` means the step the user is viewing or has clicked; it is separate from the `active` workflow state.
|
|
142
|
+
- `onStepSelect` emits user selection only. It does not mean a workflow step completed.
|
|
143
|
+
- Parent workflow code owns completion, error handling, retries, analytics, and other side effects.
|
|
144
|
+
- `description` is shown by default. Pass `showDescriptions={false}` to hide all descriptions.
|
|
145
|
+
- Descriptions auto-hide at narrow container widths (≤40rem) for mobile layouts.
|
|
146
|
+
- The component fills 100% of its container width — size it by controlling the container.
|
|
147
|
+
- Selected completed steps render with a green label; selected active steps render with a blue label.
|
|
148
|
+
- Use `connections` and per-step `position` only for simple branching/configurable flows.
|
|
149
|
+
|
|
150
|
+
For AI-assisted consuming apps, add a short instruction like this to the app's `AGENTS.md` or `CLAUDE.md`:
|
|
151
|
+
|
|
152
|
+
```md
|
|
153
|
+
Use `ProcessFlow` from `@tetrascience-npm/tetrascience-react-ui` for multi-step workflow visualization. Do not build a custom stepper for upload, validation, review, approval, processing, or setup flows. Parent components own the workflow state and pass `steps: ProcessFlowStep[]`; each step status must be one of `PROCESS_FLOW_STEP_STATUSES`. Use `selectedStepId` only for the viewed/selected step. Keep completion/error side effects in the parent workflow code, not inside `ProcessFlow`.
|
|
154
|
+
```
|
|
104
155
|
|
|
105
156
|
### Charts (`charts/`)
|
|
106
157
|
|
|
@@ -117,7 +168,7 @@ Beyond UI components, this library includes server-side helper functions for bui
|
|
|
117
168
|
**JWT Token Manager** - Manages JWT token retrieval for data apps:
|
|
118
169
|
|
|
119
170
|
```typescript
|
|
120
|
-
import { jwtManager } from
|
|
171
|
+
import { jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
|
|
121
172
|
|
|
122
173
|
// In Express middleware
|
|
123
174
|
app.use(async (req, res, next) => {
|
|
@@ -146,12 +197,8 @@ TypeScript equivalents of the Python helpers from `ts-lib-ui-kit-streamlit` for
|
|
|
146
197
|
**Getting Provider Configurations:**
|
|
147
198
|
|
|
148
199
|
```typescript
|
|
149
|
-
import { TDPClient } from
|
|
150
|
-
import {
|
|
151
|
-
getProviderConfigurations,
|
|
152
|
-
buildProvider,
|
|
153
|
-
jwtManager,
|
|
154
|
-
} from '@tetrascience-npm/tetrascience-react-ui/server';
|
|
200
|
+
import { TDPClient } from "@tetrascience-npm/ts-connectors-sdk";
|
|
201
|
+
import { getProviderConfigurations, buildProvider, jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
|
|
155
202
|
|
|
156
203
|
// Get user's auth token from request (e.g., in Express middleware)
|
|
157
204
|
const userToken = await jwtManager.getTokenFromExpressRequest(req);
|
|
@@ -160,7 +207,7 @@ const userToken = await jwtManager.getTokenFromExpressRequest(req);
|
|
|
160
207
|
// Other fields (tdpEndpoint, connectorId, orgSlug) are read from environment variables
|
|
161
208
|
const client = new TDPClient({
|
|
162
209
|
authToken: userToken,
|
|
163
|
-
artifactType:
|
|
210
|
+
artifactType: "data-app",
|
|
164
211
|
});
|
|
165
212
|
await client.init();
|
|
166
213
|
|
|
@@ -172,7 +219,7 @@ for (const config of providers) {
|
|
|
172
219
|
|
|
173
220
|
// Build a database connection from the config
|
|
174
221
|
const provider = await buildProvider(config);
|
|
175
|
-
const results = await provider.query(
|
|
222
|
+
const results = await provider.query("SELECT * FROM my_table LIMIT 10");
|
|
176
223
|
await provider.close();
|
|
177
224
|
}
|
|
178
225
|
```
|
|
@@ -185,21 +232,21 @@ import {
|
|
|
185
232
|
buildDatabricksProvider,
|
|
186
233
|
getTdpAthenaProvider,
|
|
187
234
|
type ProviderConfiguration,
|
|
188
|
-
} from
|
|
235
|
+
} from "@tetrascience-npm/tetrascience-react-ui/server";
|
|
189
236
|
|
|
190
237
|
// Snowflake
|
|
191
238
|
const snowflakeProvider = await buildSnowflakeProvider(config);
|
|
192
|
-
const data = await snowflakeProvider.query(
|
|
239
|
+
const data = await snowflakeProvider.query("SELECT * FROM users");
|
|
193
240
|
await snowflakeProvider.close();
|
|
194
241
|
|
|
195
242
|
// Databricks
|
|
196
243
|
const databricksProvider = await buildDatabricksProvider(config);
|
|
197
|
-
const data = await databricksProvider.query(
|
|
244
|
+
const data = await databricksProvider.query("SELECT * FROM events");
|
|
198
245
|
await databricksProvider.close();
|
|
199
246
|
|
|
200
247
|
// TDP Athena (uses environment configuration)
|
|
201
248
|
const athenaProvider = await getTdpAthenaProvider();
|
|
202
|
-
const data = await athenaProvider.query(
|
|
249
|
+
const data = await athenaProvider.query("SELECT * FROM files");
|
|
203
250
|
await athenaProvider.close();
|
|
204
251
|
```
|
|
205
252
|
|
|
@@ -211,15 +258,15 @@ import {
|
|
|
211
258
|
MissingTableError,
|
|
212
259
|
ProviderConnectionError,
|
|
213
260
|
InvalidProviderConfigurationError,
|
|
214
|
-
} from
|
|
261
|
+
} from "@tetrascience-npm/tetrascience-react-ui/server";
|
|
215
262
|
|
|
216
263
|
try {
|
|
217
|
-
const results = await provider.query(
|
|
264
|
+
const results = await provider.query("SELECT * FROM missing_table");
|
|
218
265
|
} catch (error) {
|
|
219
266
|
if (error instanceof MissingTableError) {
|
|
220
|
-
console.error(
|
|
267
|
+
console.error("Table not found:", error.message);
|
|
221
268
|
} else if (error instanceof QueryError) {
|
|
222
|
-
console.error(
|
|
269
|
+
console.error("Query failed:", error.message);
|
|
223
270
|
}
|
|
224
271
|
}
|
|
225
272
|
```
|
|
@@ -242,20 +289,20 @@ The TDP connector key/value store lets data apps persist small pieces of state (
|
|
|
242
289
|
**Reading and writing values with the user's JWT token:**
|
|
243
290
|
|
|
244
291
|
```typescript
|
|
245
|
-
import { TDPClient } from
|
|
246
|
-
import { jwtManager } from
|
|
292
|
+
import { TDPClient } from "@tetrascience-npm/ts-connectors-sdk";
|
|
293
|
+
import { jwtManager } from "@tetrascience-npm/tetrascience-react-ui/server";
|
|
247
294
|
|
|
248
295
|
// In an Express route handler:
|
|
249
|
-
app.get(
|
|
296
|
+
app.get("/api/kv/:key", async (req, res) => {
|
|
250
297
|
// 1. Get the user's JWT from request cookies
|
|
251
298
|
const userToken = await jwtManager.getTokenFromExpressRequest(req);
|
|
252
|
-
if (!userToken) return res.status(401).json({ error:
|
|
299
|
+
if (!userToken) return res.status(401).json({ error: "Not authenticated" });
|
|
253
300
|
|
|
254
301
|
// 2. Create a TDPClient authenticated as the user
|
|
255
302
|
// (CONNECTOR_ID, TDP_ENDPOINT, ORG_SLUG are read from env vars)
|
|
256
303
|
const client = new TDPClient({
|
|
257
304
|
authToken: userToken,
|
|
258
|
-
artifactType:
|
|
305
|
+
artifactType: "data-app",
|
|
259
306
|
});
|
|
260
307
|
await client.init();
|
|
261
308
|
|
|
@@ -264,13 +311,13 @@ app.get('/api/kv/:key', async (req, res) => {
|
|
|
264
311
|
res.json({ key: req.params.key, value });
|
|
265
312
|
});
|
|
266
313
|
|
|
267
|
-
app.put(
|
|
314
|
+
app.put("/api/kv/:key", async (req, res) => {
|
|
268
315
|
const userToken = await jwtManager.getTokenFromExpressRequest(req);
|
|
269
|
-
if (!userToken) return res.status(401).json({ error:
|
|
316
|
+
if (!userToken) return res.status(401).json({ error: "Not authenticated" });
|
|
270
317
|
|
|
271
318
|
const client = new TDPClient({
|
|
272
319
|
authToken: userToken,
|
|
273
|
-
artifactType:
|
|
320
|
+
artifactType: "data-app",
|
|
274
321
|
});
|
|
275
322
|
await client.init();
|
|
276
323
|
|
|
@@ -283,7 +330,7 @@ app.put('/api/kv/:key', async (req, res) => {
|
|
|
283
330
|
**Reading multiple values at once:**
|
|
284
331
|
|
|
285
332
|
```typescript
|
|
286
|
-
const values = await client.getValues([
|
|
333
|
+
const values = await client.getValues(["theme", "locale", "last-run"]);
|
|
287
334
|
// values[0] → theme, values[1] → locale, values[2] → last-run
|
|
288
335
|
```
|
|
289
336
|
|
|
@@ -315,8 +362,8 @@ Frontend: use `<TdpSearch columns={...} />` with default `apiEndpoint="/api/sear
|
|
|
315
362
|
Full TypeScript support with exported types:
|
|
316
363
|
|
|
317
364
|
```tsx
|
|
318
|
-
import { Button } from
|
|
319
|
-
import type { ButtonProps, BarGraphProps, BarDataSeries } from
|
|
365
|
+
import { Button } from "@tetrascience-npm/tetrascience-react-ui";
|
|
366
|
+
import type { ButtonProps, BarGraphProps, BarDataSeries } from "@tetrascience-npm/tetrascience-react-ui";
|
|
320
367
|
```
|
|
321
368
|
|
|
322
369
|
## Examples
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),x=require("lucide-react"),m=require("./ProcessFlow.utils.cjs"),f=require("../../../lib/utils.cjs"),H={pending:"text-muted-foreground",active:"text-foreground",completed:"text-foreground",error:"text-destructive",disabled:"text-muted-foreground"},L={pending:"border-border bg-background text-muted-foreground",active:"border-primary bg-primary text-primary-foreground",completed:"border-positive bg-positive text-background",error:"border-destructive bg-destructive text-background",disabled:"border-border bg-muted text-muted-foreground"},q={pending:"stroke-muted-foreground/35",active:"stroke-primary",completed:"stroke-positive",error:"stroke-destructive",disabled:"stroke-border"},A={default:"11rem",compact:"8.5rem"},P={default:"8rem",compact:"7rem"},M={default:"5.5rem",compact:"4.75rem"},O={default:"2.75rem",compact:"2.5rem"},E={default:"7.5rem",compact:"5.75rem"},N={default:"6.5rem",compact:"5rem"},k={default:"4.5rem",compact:"3.75rem"},y={default:"3.5rem",compact:"3rem"},G={default:"1.25rem",compact:"0.75rem"},V={default:"0.875rem",compact:"0.625rem"},U={default:"0.5rem",compact:"0.375rem"},W={default:"0.375rem",compact:"0.25rem"},I={default:"2.5rem",compact:"1.75rem"},j={default:"2rem",compact:"1.5rem"},R={default:"1.5rem",compact:"1.25rem"},T={default:"1.25rem",compact:"1.125rem"};function F(r,a){return r==="completed"?s.jsx(x.CheckIcon,{"aria-hidden":"true"}):r==="error"?s.jsx(x.TriangleAlertIcon,{"aria-hidden":"true"}):r==="disabled"?s.jsx(x.LockIcon,{"aria-hidden":"true"}):r==="active"?s.jsx(x.DotIcon,{"aria-hidden":"true"}):a}function Z(r,a){return{left:`calc(${(r+.5)/a*100}% + (var(--process-flow-marker-size) / 2))`,width:`calc(${1/a*100}% - var(--process-flow-marker-size))`}}function z(r,a){return{height:`calc(${1/a*100}% - var(--process-flow-marker-size))`,top:`calc(${(r+.5)/a*100}% + (var(--process-flow-marker-size) / 2))`}}function K(){const r="calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))";return{left:r,right:r}}function Q(){const r="calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))";return{bottom:r,top:r}}function $({contentLayout:r,onStepSelect:a,isDisabled:l,size:t,status:n}){return f.cn("flex w-full min-w-0 border-0 bg-transparent p-0 text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",r==="inline"&&"flex-row items-center gap-3 text-left",r==="stacked"&&"flex-col items-center gap-2 text-center",r==="anchored"&&"relative h-full flex-col items-center justify-center text-center",t==="compact"&&(r==="inline"?"gap-2":"gap-1.5"),a&&!l&&f.cn("cursor-pointer hover:text-foreground",r!=="anchored"&&"hover:-translate-y-px"),a&&l&&"cursor-not-allowed",H[n])}function B({isSelected:r,size:a,status:l}){return f.cn("flex size-[var(--process-flow-marker-size)] shrink-0 items-center justify-center rounded-full border text-xs font-semibold tabular-nums transition-colors [&_svg]:size-4",a==="compact"&&"text-[0.7rem] [&_svg]:size-3","shadow-[0_0_0_0.25rem_var(--background)]",r&&"ring-4 ring-primary/20",L[l])}function J({layout:r,isSelected:a,status:l}){return f.cn("block max-w-full truncate font-medium text-current",r==="linear"&&a&&l==="completed"&&"text-positive",r==="linear"&&a&&l!=="completed"&&l!=="error"&&"text-primary")}function C({item:r,isSelected:a,onStepSelect:l,descriptionVisibility:t,size:n,layout:o,contentLayout:p}){const{step:d,stepIndex:u,status:e}=r,c=e==="disabled"||d.selectable===!1,v=m.getStepAccessibleLabel(d,e,u+1),w=t==="visible"?"visible":"auto",g=$({contentLayout:p,onStepSelect:l,isDisabled:c,size:n,status:e}),h=s.jsx("span",{"aria-hidden":"true",className:B({isSelected:a,size:n,status:e}),"data-slot":"process-flow-marker",children:F(e,u+1)}),_=s.jsxs("span",{"data-slot":"process-flow-text","data-text-visibility":w,className:f.cn("flex min-w-0 flex-col gap-0.5",p==="stacked"&&"w-full items-center",p==="anchored"&&"pointer-events-none absolute left-1/2 top-[calc(50%+var(--process-flow-marker-size)/2+0.375rem)] w-max max-w-[calc(var(--process-flow-step-min-width)-0.5rem)] -translate-x-1/2 items-center px-1"),children:[s.jsx("span",{className:J({layout:o,isSelected:a,status:e}),"data-slot":"process-flow-label",children:d.label}),t!=="hidden"&&d.description?s.jsx("span",{className:"line-clamp-2 text-xs leading-snug text-muted-foreground","data-description-visibility":t,"data-slot":"process-flow-description",children:d.description}):null,s.jsxs("span",{className:"sr-only",children:["Status: ",m.STATUS_LABELS[e]]})]}),b=s.jsxs(s.Fragment,{children:[h,_]});return l?s.jsx("button",{type:"button","aria-current":e==="active"?"step":void 0,"aria-invalid":e==="error"||void 0,"aria-label":v,"aria-pressed":a,className:g,"data-selected":a||void 0,"data-status":e,disabled:c,onClick:S=>l(d,{nativeEvent:S,status:e,stepIndex:u}),children:b}):s.jsx("div",{"aria-current":e==="active"?"step":void 0,"aria-disabled":c||void 0,"aria-invalid":e==="error"||void 0,"aria-label":v,className:g,"data-selected":a||void 0,"data-status":e,children:b})}function X({steps:r,selectedStepId:a,onStepSelect:l,size:t,showDescriptions:n}){const o=r.map((e,c)=>m.positionStep(e,c,"horizontal")),p=m.resolveConnections(o),d=m.getDescriptionVisibility(n),u={"--process-flow-count":r.length,"--process-flow-step-min-width-base":A[t],"--process-flow-step-min-width-responsive":P[t],"--process-flow-step-min-width-squeezed":M[t],"--process-flow-step-min-width-mini":O[t],"--process-flow-row-min-height-base":E[t],"--process-flow-row-min-height-responsive":N[t],"--process-flow-row-min-height-squeezed":k[t],"--process-flow-row-min-height-mini":y[t],"--process-flow-marker-size-base":I[t],"--process-flow-marker-size-responsive":j[t],"--process-flow-marker-size-squeezed":R[t],"--process-flow-marker-size-mini":T[t]};return s.jsx("div",{className:"overflow-hidden px-3 py-4","data-slot":"process-flow-viewport",style:u,children:s.jsxs("ol",{className:"relative grid min-w-0 min-h-[var(--process-flow-row-min-height)] list-none p-0","data-slot":"process-flow-list",style:{gridTemplateColumns:"repeat(var(--process-flow-count), minmax(0, 1fr))"},children:[r.length>1?s.jsx("li",{"aria-hidden":"true",className:"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full bg-muted",style:K()}):null,p.map((e,c)=>s.jsx("li",{"aria-hidden":"true",className:f.cn("absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full transition-colors",e.status==="completed"&&"bg-positive",e.status==="active"&&"bg-primary",e.status==="error"&&"bg-destructive",e.status==="pending"&&"bg-muted",e.status==="disabled"&&"bg-border"),style:Z(c,r.length)},e.id)),o.map(e=>s.jsx("li",{className:"relative z-[1] flex min-w-0 items-start justify-center","data-slot":"process-flow-item",children:s.jsx(C,{item:e,contentLayout:"stacked",descriptionVisibility:d,isSelected:a===e.step.id,layout:"linear",onStepSelect:l,size:t})},e.step.id))]})})}function Y({steps:r,selectedStepId:a,onStepSelect:l,size:t,showDescriptions:n}){const o=r.map((e,c)=>m.positionStep(e,c,"vertical")),p=m.resolveConnections(o),d=m.getDescriptionVisibility(n),u={"--process-flow-count":r.length,"--process-flow-row-min-height-base":E[t],"--process-flow-row-min-height-responsive":N[t],"--process-flow-row-min-height-squeezed":k[t],"--process-flow-row-min-height-mini":y[t],"--process-flow-marker-size-base":I[t],"--process-flow-marker-size-responsive":j[t],"--process-flow-marker-size-squeezed":R[t],"--process-flow-marker-size-mini":T[t]};return s.jsx("div",{className:"overflow-x-auto px-3 py-3","data-slot":"process-flow-viewport",style:u,children:s.jsxs("ol",{className:"relative grid min-h-[calc(var(--process-flow-count)*var(--process-flow-row-min-height))] min-w-72 list-none p-0","data-slot":"process-flow-list",style:{gridTemplateRows:"repeat(var(--process-flow-count), minmax(var(--process-flow-row-min-height), auto))"},children:[r.length>1?s.jsx("li",{"aria-hidden":"true",className:"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full bg-muted",style:Q()}):null,p.map((e,c)=>s.jsx("li",{"aria-hidden":"true",className:f.cn("absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full transition-colors",e.status==="completed"&&"bg-positive",e.status==="active"&&"bg-primary",e.status==="error"&&"bg-destructive",e.status==="pending"&&"bg-muted",e.status==="disabled"&&"bg-border"),style:z(c,r.length)},e.id)),o.map(e=>s.jsx("li",{className:"relative z-[1] flex min-w-0 items-center","data-slot":"process-flow-item",children:s.jsx(C,{item:e,contentLayout:"inline",descriptionVisibility:d,isSelected:a===e.step.id,layout:"linear",onStepSelect:l,size:t})},e.step.id))]})})}function ee({steps:r,connections:a,selectedStepId:l,onStepSelect:t,orientation:n="horizontal",size:o="default",showDescriptions:p,className:d,style:u,"aria-label":e="Process flow",...c}){if(r.length===0)return null;const v=a||m.hasCustomStepLayout(r)?"branching":"linear";if(v==="linear"&&n==="horizontal")return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx(X,{steps:r,selectedStepId:l,onStepSelect:t,showDescriptions:p,size:o})});if(v==="linear"&&n==="vertical")return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx(Y,{steps:r,selectedStepId:l,onStepSelect:t,showDescriptions:p,size:o})});const w=r.map((i,D)=>m.positionStep(i,D,n)),g=Math.max(...w.map(i=>i.row+1),1),h=Math.max(...w.map(i=>i.column+1),1),_=m.resolveConnections(w,a),b=m.getDescriptionVisibility(p),S={"--process-flow-columns":h,"--process-flow-rows":g,"--process-flow-step-min-width-base":A[o],"--process-flow-step-min-width-responsive":P[o],"--process-flow-step-min-width-squeezed":M[o],"--process-flow-step-min-width-mini":O[o],"--process-flow-row-min-height-base":E[o],"--process-flow-row-min-height-responsive":N[o],"--process-flow-row-min-height-squeezed":k[o],"--process-flow-row-min-height-mini":y[o],"--process-flow-gap-base":G[o],"--process-flow-gap-responsive":V[o],"--process-flow-gap-squeezed":U[o],"--process-flow-gap-mini":W[o],"--process-flow-marker-size-base":I[o],"--process-flow-marker-size-responsive":j[o],"--process-flow-marker-size-squeezed":R[o],"--process-flow-marker-size-mini":T[o]};return s.jsx("nav",{"aria-label":e,className:f.cn("w-full min-w-0",d),"data-orientation":n,"data-slot":"process-flow","data-size":o,style:u,...c,children:s.jsx("div",{className:"overflow-x-auto py-2","data-slot":"process-flow-viewport",style:S,children:s.jsxs("div",{className:"relative min-w-[calc(var(--process-flow-columns)*var(--process-flow-step-min-width))] min-h-[calc(var(--process-flow-rows)*var(--process-flow-row-min-height))]","data-slot":"process-flow-canvas",children:[s.jsx("svg",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 z-0 size-full overflow-visible",preserveAspectRatio:"none",viewBox:"0 0 100 100",children:_.map(i=>s.jsx("path",{className:f.cn("fill-none stroke-2 transition-colors",q[i.status],i.status==="disabled"&&"opacity-60"),d:m.getConnectionPath(i,g,h),"data-status":i.status,strokeLinecap:"round",vectorEffect:"non-scaling-stroke"},i.id))}),s.jsx("ol",{className:"relative z-[1] grid min-h-[inherit] list-none p-0","data-slot":"process-flow-list",style:{gap:"var(--process-flow-gap)",gridTemplateColumns:"repeat(var(--process-flow-columns), minmax(var(--process-flow-step-min-width), 1fr))",gridTemplateRows:"repeat(var(--process-flow-rows), minmax(var(--process-flow-row-min-height), auto))"},children:w.map(i=>s.jsx("li",{className:"flex min-w-0 items-center justify-center","data-slot":"process-flow-item",style:{gridColumn:i.column+1,gridRow:i.row+1},children:s.jsx(C,{item:i,contentLayout:"anchored",descriptionVisibility:b,isSelected:l===i.step.id,layout:"branching",onStepSelect:t,size:o})},i.step.id))})]})})})}exports.PROCESS_FLOW_STEP_STATUSES=m.PROCESS_FLOW_STEP_STATUSES;exports.ProcessFlow=ee;
|
|
2
|
+
//# sourceMappingURL=ProcessFlow.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessFlow.cjs","sources":["../../../../src/components/composed/ProcessFlow/ProcessFlow.tsx"],"sourcesContent":["import { CheckIcon, DotIcon, LockIcon, TriangleAlertIcon } from \"lucide-react\";\n\nimport {\n getConnectionPath,\n getDescriptionVisibility,\n getStepAccessibleLabel,\n hasCustomStepLayout,\n positionStep,\n resolveConnections,\n STATUS_LABELS,\n type PositionedStep,\n type ProcessFlowConnection,\n type ProcessFlowDescriptionVisibility,\n type ProcessFlowOrientation,\n type ProcessFlowSize,\n type ProcessFlowStep,\n type ProcessFlowStepStatus,\n} from \"./ProcessFlow.utils\";\n\nimport type { ComponentPropsWithoutRef, CSSProperties, MouseEvent } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport { PROCESS_FLOW_STEP_STATUSES } from \"./ProcessFlow.utils\";\nexport type {\n ProcessFlowConnection,\n ProcessFlowOrientation,\n ProcessFlowSize,\n ProcessFlowStep,\n ProcessFlowStepConfig,\n ProcessFlowStepPosition,\n ProcessFlowStepStatus,\n ProcessStep,\n ProcessStepStatus,\n} from \"./ProcessFlow.utils\";\n\ntype ProcessFlowLayout = \"linear\" | \"branching\";\ntype ProcessFlowStepContentLayout = \"stacked\" | \"inline\" | \"anchored\";\n\nexport interface ProcessFlowStepSelectDetails {\n /** Zero-based index of the selected step in the steps prop. */\n stepIndex: number;\n /** Current visual status of the selected step. */\n status: ProcessFlowStepStatus;\n nativeEvent: MouseEvent<HTMLButtonElement>;\n}\n\n/**\n * Presentational process flow.\n *\n * ProcessFlow is fully controlled by props. It visualizes parent-owned workflow state and emits user selection through\n * onStepSelect. It intentionally does not own status transitions or fire completion/error side effects.\n */\nexport interface ProcessFlowProps extends Omit<ComponentPropsWithoutRef<\"nav\">, \"onSelect\"> {\n /** Ordered list of steps to render. Each step controls its own visual status. */\n steps: ProcessFlowStep[];\n /** Optional explicit connections for branching/configurable flows. */\n connections?: ProcessFlowConnection[];\n /** Selected/viewed step id. This is separate from the active workflow status. */\n selectedStepId?: string;\n /** Called when a selectable step is clicked. Disabled and non-selectable steps do not call this. */\n onStepSelect?: (step: ProcessFlowStep, details: ProcessFlowStepSelectDetails) => void;\n orientation?: ProcessFlowOrientation;\n size?: ProcessFlowSize;\n /** Defaults to true. Set to false to hide step descriptions. */\n showDescriptions?: boolean;\n}\n\ninterface StepControlClassOptions {\n layout: ProcessFlowLayout;\n contentLayout: ProcessFlowStepContentLayout;\n onStepSelect?: ProcessFlowProps[\"onStepSelect\"];\n isDisabled: boolean;\n isSelected: boolean;\n size: ProcessFlowSize;\n status: ProcessFlowStepStatus;\n}\n\nconst LINEAR_STEP_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"text-muted-foreground\",\n active: \"text-foreground\",\n completed: \"text-foreground\",\n error: \"text-destructive\",\n disabled: \"text-muted-foreground\",\n};\n\nconst MARKER_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"border-border bg-background text-muted-foreground\",\n active: \"border-primary bg-primary text-primary-foreground\",\n completed: \"border-positive bg-positive text-background\",\n error: \"border-destructive bg-destructive text-background\",\n disabled: \"border-border bg-muted text-muted-foreground\",\n};\n\nconst CONNECTION_STATUS_CLASSES: Record<ProcessFlowStepStatus, string> = {\n pending: \"stroke-muted-foreground/35\",\n active: \"stroke-primary\",\n completed: \"stroke-positive\",\n error: \"stroke-destructive\",\n disabled: \"stroke-border\",\n};\n\nconst STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"11rem\",\n compact: \"8.5rem\",\n};\n\nconst RESPONSIVE_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"8rem\",\n compact: \"7rem\",\n};\n\nconst SQUEEZED_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"5.5rem\",\n compact: \"4.75rem\",\n};\n\nconst MINI_STEP_MIN_WIDTH: Record<ProcessFlowSize, string> = {\n default: \"2.75rem\",\n compact: \"2.5rem\",\n};\n\nconst ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"7.5rem\",\n compact: \"5.75rem\",\n};\n\nconst RESPONSIVE_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"6.5rem\",\n compact: \"5rem\",\n};\n\nconst SQUEEZED_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"4.5rem\",\n compact: \"3.75rem\",\n};\n\nconst MINI_ROW_MIN_HEIGHT: Record<ProcessFlowSize, string> = {\n default: \"3.5rem\",\n compact: \"3rem\",\n};\n\nconst GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"1.25rem\",\n compact: \"0.75rem\",\n};\n\nconst RESPONSIVE_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.875rem\",\n compact: \"0.625rem\",\n};\n\nconst SQUEEZED_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.5rem\",\n compact: \"0.375rem\",\n};\n\nconst MINI_GRID_GAP: Record<ProcessFlowSize, string> = {\n default: \"0.375rem\",\n compact: \"0.25rem\",\n};\n\nconst LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"2.5rem\",\n compact: \"1.75rem\",\n};\n\nconst RESPONSIVE_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"2rem\",\n compact: \"1.5rem\",\n};\n\nconst SQUEEZED_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"1.5rem\",\n compact: \"1.25rem\",\n};\n\nconst MINI_LINEAR_MARKER_SIZE: Record<ProcessFlowSize, string> = {\n default: \"1.25rem\",\n compact: \"1.125rem\",\n};\n\nfunction getMarkerContent(status: ProcessFlowStepStatus, stepNumber: number) {\n if (status === \"completed\") {\n return <CheckIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"error\") {\n return <TriangleAlertIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"disabled\") {\n return <LockIcon aria-hidden=\"true\" />;\n }\n\n if (status === \"active\") {\n return <DotIcon aria-hidden=\"true\" />;\n }\n\n return stepNumber;\n}\n\nfunction getLinearSegmentStyle(index: number, count: number): CSSProperties {\n return {\n left: `calc(${((index + 0.5) / count) * 100}% + (var(--process-flow-marker-size) / 2))`,\n width: `calc(${(1 / count) * 100}% - var(--process-flow-marker-size))`,\n };\n}\n\nfunction getVerticalSegmentStyle(index: number, count: number): CSSProperties {\n return {\n height: `calc(${(1 / count) * 100}% - var(--process-flow-marker-size))`,\n top: `calc(${((index + 0.5) / count) * 100}% + (var(--process-flow-marker-size) / 2))`,\n };\n}\n\nfunction getHorizontalRailStyle(): CSSProperties {\n const inset = \"calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))\";\n\n return {\n left: inset,\n right: inset,\n };\n}\n\nfunction getVerticalRailStyle(): CSSProperties {\n const inset = \"calc(((100% / var(--process-flow-count)) / 2) + (var(--process-flow-marker-size) / 2))\";\n\n return {\n bottom: inset,\n top: inset,\n };\n}\n\nfunction getStepControlClassName({ contentLayout, onStepSelect, isDisabled, size, status }: StepControlClassOptions) {\n return cn(\n \"flex w-full min-w-0 border-0 bg-transparent p-0 text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50\",\n contentLayout === \"inline\" && \"flex-row items-center gap-3 text-left\",\n contentLayout === \"stacked\" && \"flex-col items-center gap-2 text-center\",\n contentLayout === \"anchored\" && \"relative h-full flex-col items-center justify-center text-center\",\n size === \"compact\" && (contentLayout === \"inline\" ? \"gap-2\" : \"gap-1.5\"),\n onStepSelect &&\n !isDisabled &&\n cn(\"cursor-pointer hover:text-foreground\", contentLayout !== \"anchored\" && \"hover:-translate-y-px\"),\n onStepSelect && isDisabled && \"cursor-not-allowed\",\n LINEAR_STEP_STATUS_CLASSES[status],\n );\n}\n\nfunction getMarkerClassName({\n isSelected,\n size,\n status,\n}: Pick<StepControlClassOptions, \"isSelected\" | \"size\" | \"status\">) {\n return cn(\n \"flex size-[var(--process-flow-marker-size)] shrink-0 items-center justify-center rounded-full border text-xs font-semibold tabular-nums transition-colors [&_svg]:size-4\",\n size === \"compact\" && \"text-[0.7rem] [&_svg]:size-3\",\n \"shadow-[0_0_0_0.25rem_var(--background)]\",\n isSelected && \"ring-4 ring-primary/20\",\n MARKER_STATUS_CLASSES[status],\n );\n}\n\nfunction getLabelClassName({\n layout,\n isSelected,\n status,\n}: Pick<StepControlClassOptions, \"layout\" | \"isSelected\" | \"status\">) {\n return cn(\n \"block max-w-full truncate font-medium text-current\",\n layout === \"linear\" && isSelected && status === \"completed\" && \"text-positive\",\n layout === \"linear\" && isSelected && status !== \"completed\" && status !== \"error\" && \"text-primary\",\n );\n}\n\nfunction ProcessFlowStepControl({\n item,\n isSelected,\n onStepSelect,\n descriptionVisibility,\n size,\n layout,\n contentLayout,\n}: {\n item: PositionedStep;\n isSelected: boolean;\n onStepSelect?: ProcessFlowProps[\"onStepSelect\"];\n descriptionVisibility: ProcessFlowDescriptionVisibility;\n size: ProcessFlowSize;\n layout: ProcessFlowLayout;\n contentLayout: ProcessFlowStepContentLayout;\n}) {\n const { step, stepIndex, status } = item;\n const isDisabled = status === \"disabled\" || step.selectable === false;\n const accessibleLabel = getStepAccessibleLabel(step, status, stepIndex + 1);\n const textVisibility = descriptionVisibility === \"visible\" ? \"visible\" : \"auto\";\n const controlClassName = getStepControlClassName({\n layout,\n contentLayout,\n onStepSelect,\n isDisabled,\n isSelected,\n size,\n status,\n });\n const markerContent = (\n <span\n aria-hidden=\"true\"\n className={getMarkerClassName({\n isSelected,\n size,\n status,\n })}\n data-slot=\"process-flow-marker\"\n >\n {getMarkerContent(status, stepIndex + 1)}\n </span>\n );\n const textContent = (\n <span\n data-slot=\"process-flow-text\"\n data-text-visibility={textVisibility}\n className={cn(\n \"flex min-w-0 flex-col gap-0.5\",\n contentLayout === \"stacked\" && \"w-full items-center\",\n contentLayout === \"anchored\" &&\n \"pointer-events-none absolute left-1/2 top-[calc(50%+var(--process-flow-marker-size)/2+0.375rem)] w-max max-w-[calc(var(--process-flow-step-min-width)-0.5rem)] -translate-x-1/2 items-center px-1\",\n )}\n >\n <span className={getLabelClassName({ layout, isSelected, status })} data-slot=\"process-flow-label\">\n {step.label}\n </span>\n {descriptionVisibility !== \"hidden\" && step.description ? (\n <span\n className=\"line-clamp-2 text-xs leading-snug text-muted-foreground\"\n data-description-visibility={descriptionVisibility}\n data-slot=\"process-flow-description\"\n >\n {step.description}\n </span>\n ) : null}\n <span className=\"sr-only\">Status: {STATUS_LABELS[status]}</span>\n </span>\n );\n const content = (\n <>\n {markerContent}\n {textContent}\n </>\n );\n\n if (!onStepSelect) {\n return (\n <div\n aria-current={status === \"active\" ? \"step\" : undefined}\n aria-disabled={isDisabled || undefined}\n aria-invalid={status === \"error\" || undefined}\n aria-label={accessibleLabel}\n className={controlClassName}\n data-selected={isSelected || undefined}\n data-status={status}\n >\n {content}\n </div>\n );\n }\n\n return (\n <button\n type=\"button\"\n aria-current={status === \"active\" ? \"step\" : undefined}\n aria-invalid={status === \"error\" || undefined}\n aria-label={accessibleLabel}\n aria-pressed={isSelected}\n className={controlClassName}\n data-selected={isSelected || undefined}\n data-status={status}\n disabled={isDisabled}\n onClick={(nativeEvent) =>\n onStepSelect(step, {\n nativeEvent,\n status,\n stepIndex,\n })\n }\n >\n {content}\n </button>\n );\n}\n\nfunction HorizontalProcessFlow({\n steps,\n selectedStepId,\n onStepSelect,\n size,\n showDescriptions,\n}: Pick<ProcessFlowProps, \"steps\" | \"selectedStepId\" | \"onStepSelect\" | \"showDescriptions\"> & {\n size: ProcessFlowSize;\n}) {\n const positionedSteps = steps.map((step, index) => positionStep(step, index, \"horizontal\"));\n const resolvedConnections = resolveConnections(positionedSteps);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-count\": steps.length,\n \"--process-flow-step-min-width-base\": STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-responsive\": RESPONSIVE_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-squeezed\": SQUEEZED_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-mini\": MINI_STEP_MIN_WIDTH[size],\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <div className=\"overflow-hidden px-3 py-4\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <ol\n className=\"relative grid min-w-0 min-h-[var(--process-flow-row-min-height)] list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gridTemplateColumns: \"repeat(var(--process-flow-count), minmax(0, 1fr))\",\n }}\n >\n {steps.length > 1 ? (\n <li\n aria-hidden=\"true\"\n className=\"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full bg-muted\"\n style={getHorizontalRailStyle()}\n />\n ) : null}\n {resolvedConnections.map((connection, index) => (\n <li\n key={connection.id}\n aria-hidden=\"true\"\n className={cn(\n \"absolute top-[calc(var(--process-flow-marker-size)/2)] h-0.5 -translate-y-1/2 rounded-full transition-colors\",\n connection.status === \"completed\" && \"bg-positive\",\n connection.status === \"active\" && \"bg-primary\",\n connection.status === \"error\" && \"bg-destructive\",\n connection.status === \"pending\" && \"bg-muted\",\n connection.status === \"disabled\" && \"bg-border\",\n )}\n style={getLinearSegmentStyle(index, steps.length)}\n />\n ))}\n {positionedSteps.map((item) => (\n <li\n key={item.step.id}\n className=\"relative z-[1] flex min-w-0 items-start justify-center\"\n data-slot=\"process-flow-item\"\n >\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"stacked\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"linear\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n );\n}\n\nfunction VerticalProcessFlow({\n steps,\n selectedStepId,\n onStepSelect,\n size,\n showDescriptions,\n}: Pick<ProcessFlowProps, \"steps\" | \"selectedStepId\" | \"onStepSelect\" | \"showDescriptions\"> & {\n size: ProcessFlowSize;\n}) {\n const positionedSteps = steps.map((step, index) => positionStep(step, index, \"vertical\"));\n const resolvedConnections = resolveConnections(positionedSteps);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-count\": steps.length,\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <div className=\"overflow-x-auto px-3 py-3\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <ol\n className=\"relative grid min-h-[calc(var(--process-flow-count)*var(--process-flow-row-min-height))] min-w-72 list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gridTemplateRows: \"repeat(var(--process-flow-count), minmax(var(--process-flow-row-min-height), auto))\",\n }}\n >\n {steps.length > 1 ? (\n <li\n aria-hidden=\"true\"\n className=\"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full bg-muted\"\n style={getVerticalRailStyle()}\n />\n ) : null}\n {resolvedConnections.map((connection, index) => (\n <li\n key={connection.id}\n aria-hidden=\"true\"\n className={cn(\n \"absolute left-[calc(var(--process-flow-marker-size)/2)] w-0.5 -translate-x-1/2 rounded-full transition-colors\",\n connection.status === \"completed\" && \"bg-positive\",\n connection.status === \"active\" && \"bg-primary\",\n connection.status === \"error\" && \"bg-destructive\",\n connection.status === \"pending\" && \"bg-muted\",\n connection.status === \"disabled\" && \"bg-border\",\n )}\n style={getVerticalSegmentStyle(index, steps.length)}\n />\n ))}\n {positionedSteps.map((item) => (\n <li key={item.step.id} className=\"relative z-[1] flex min-w-0 items-center\" data-slot=\"process-flow-item\">\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"inline\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"linear\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n );\n}\n\nexport function ProcessFlow({\n steps,\n connections,\n selectedStepId,\n onStepSelect,\n orientation = \"horizontal\",\n size = \"default\",\n showDescriptions,\n className,\n style,\n \"aria-label\": ariaLabel = \"Process flow\",\n ...props\n}: ProcessFlowProps) {\n if (steps.length === 0) {\n return null;\n }\n\n const layout: ProcessFlowLayout = connections || hasCustomStepLayout(steps) ? \"branching\" : \"linear\";\n\n if (layout === \"linear\" && orientation === \"horizontal\") {\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <HorizontalProcessFlow\n steps={steps}\n selectedStepId={selectedStepId}\n onStepSelect={onStepSelect}\n showDescriptions={showDescriptions}\n size={size}\n />\n </nav>\n );\n }\n\n if (layout === \"linear\" && orientation === \"vertical\") {\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <VerticalProcessFlow\n steps={steps}\n selectedStepId={selectedStepId}\n onStepSelect={onStepSelect}\n showDescriptions={showDescriptions}\n size={size}\n />\n </nav>\n );\n }\n\n const positionedSteps = steps.map((step, index) => positionStep(step, index, orientation));\n const rowCount = Math.max(...positionedSteps.map((step) => step.row + 1), 1);\n const columnCount = Math.max(...positionedSteps.map((step) => step.column + 1), 1);\n const resolvedConnections = resolveConnections(positionedSteps, connections);\n const descriptionVisibility = getDescriptionVisibility(showDescriptions);\n const flowStyle = {\n \"--process-flow-columns\": columnCount,\n \"--process-flow-rows\": rowCount,\n \"--process-flow-step-min-width-base\": STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-responsive\": RESPONSIVE_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-squeezed\": SQUEEZED_STEP_MIN_WIDTH[size],\n \"--process-flow-step-min-width-mini\": MINI_STEP_MIN_WIDTH[size],\n \"--process-flow-row-min-height-base\": ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-responsive\": RESPONSIVE_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-squeezed\": SQUEEZED_ROW_MIN_HEIGHT[size],\n \"--process-flow-row-min-height-mini\": MINI_ROW_MIN_HEIGHT[size],\n \"--process-flow-gap-base\": GRID_GAP[size],\n \"--process-flow-gap-responsive\": RESPONSIVE_GRID_GAP[size],\n \"--process-flow-gap-squeezed\": SQUEEZED_GRID_GAP[size],\n \"--process-flow-gap-mini\": MINI_GRID_GAP[size],\n \"--process-flow-marker-size-base\": LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-responsive\": RESPONSIVE_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-squeezed\": SQUEEZED_LINEAR_MARKER_SIZE[size],\n \"--process-flow-marker-size-mini\": MINI_LINEAR_MARKER_SIZE[size],\n } as CSSProperties;\n\n return (\n <nav\n aria-label={ariaLabel}\n className={cn(\"w-full min-w-0\", className)}\n data-orientation={orientation}\n data-slot=\"process-flow\"\n data-size={size}\n style={style}\n {...props}\n >\n <div className=\"overflow-x-auto py-2\" data-slot=\"process-flow-viewport\" style={flowStyle}>\n <div\n className=\"relative min-w-[calc(var(--process-flow-columns)*var(--process-flow-step-min-width))] min-h-[calc(var(--process-flow-rows)*var(--process-flow-row-min-height))]\"\n data-slot=\"process-flow-canvas\"\n >\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-0 size-full overflow-visible\"\n preserveAspectRatio=\"none\"\n viewBox=\"0 0 100 100\"\n >\n {resolvedConnections.map((connection) => (\n <path\n key={connection.id}\n className={cn(\n \"fill-none stroke-2 transition-colors\",\n CONNECTION_STATUS_CLASSES[connection.status],\n connection.status === \"disabled\" && \"opacity-60\",\n )}\n d={getConnectionPath(connection, rowCount, columnCount)}\n data-status={connection.status}\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n />\n ))}\n </svg>\n\n <ol\n className=\"relative z-[1] grid min-h-[inherit] list-none p-0\"\n data-slot=\"process-flow-list\"\n style={{\n gap: \"var(--process-flow-gap)\",\n gridTemplateColumns:\n \"repeat(var(--process-flow-columns), minmax(var(--process-flow-step-min-width), 1fr))\",\n gridTemplateRows: \"repeat(var(--process-flow-rows), minmax(var(--process-flow-row-min-height), auto))\",\n }}\n >\n {positionedSteps.map((item) => (\n <li\n key={item.step.id}\n className=\"flex min-w-0 items-center justify-center\"\n data-slot=\"process-flow-item\"\n style={{\n gridColumn: item.column + 1,\n gridRow: item.row + 1,\n }}\n >\n <ProcessFlowStepControl\n item={item}\n contentLayout=\"anchored\"\n descriptionVisibility={descriptionVisibility}\n isSelected={selectedStepId === item.step.id}\n layout=\"branching\"\n onStepSelect={onStepSelect}\n size={size}\n />\n </li>\n ))}\n </ol>\n </div>\n </div>\n </nav>\n );\n}\n"],"names":["LINEAR_STEP_STATUS_CLASSES","MARKER_STATUS_CLASSES","CONNECTION_STATUS_CLASSES","STEP_MIN_WIDTH","RESPONSIVE_STEP_MIN_WIDTH","SQUEEZED_STEP_MIN_WIDTH","MINI_STEP_MIN_WIDTH","ROW_MIN_HEIGHT","RESPONSIVE_ROW_MIN_HEIGHT","SQUEEZED_ROW_MIN_HEIGHT","MINI_ROW_MIN_HEIGHT","GRID_GAP","RESPONSIVE_GRID_GAP","SQUEEZED_GRID_GAP","MINI_GRID_GAP","LINEAR_MARKER_SIZE","RESPONSIVE_LINEAR_MARKER_SIZE","SQUEEZED_LINEAR_MARKER_SIZE","MINI_LINEAR_MARKER_SIZE","getMarkerContent","status","stepNumber","jsx","CheckIcon","TriangleAlertIcon","LockIcon","DotIcon","getLinearSegmentStyle","index","count","getVerticalSegmentStyle","getHorizontalRailStyle","inset","getVerticalRailStyle","getStepControlClassName","contentLayout","onStepSelect","isDisabled","size","cn","getMarkerClassName","isSelected","getLabelClassName","layout","ProcessFlowStepControl","item","descriptionVisibility","step","stepIndex","accessibleLabel","getStepAccessibleLabel","textVisibility","controlClassName","markerContent","textContent","jsxs","STATUS_LABELS","content","Fragment","nativeEvent","HorizontalProcessFlow","steps","selectedStepId","showDescriptions","positionedSteps","positionStep","resolvedConnections","resolveConnections","getDescriptionVisibility","flowStyle","connection","VerticalProcessFlow","ProcessFlow","connections","orientation","className","style","ariaLabel","props","hasCustomStepLayout","rowCount","columnCount","getConnectionPath"],"mappings":"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"}
|