@tailor-platform/app-shell 1.14.0 → 1.16.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/LICENSE.md +21 -0
- package/dist/app-shell-core.css +1 -1
- package/dist/app-shell.d.ts +1203 -316
- package/dist/app-shell.js +4562 -3307
- package/dist/{appshell-CtS8Y3LW.js → appshell-B0wh5Lq0.js} +850 -549
- package/dist/style-entry.d.ts +118 -98
- package/dist/testing.d.ts +118 -98
- package/dist/testing.js +1 -1
- package/dist/themes/_template.css +1 -1
- package/dist/vite-plugin.d.ts +118 -98
- package/package.json +13 -13
- package/skills/app-shell-patterns/SKILL.md +108 -24
- package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
- package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
- package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
- package/skills/app-shell-patterns/references/api/define-module.md +247 -0
- package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
- package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
- package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
- package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
- package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
- package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
- package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
- package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
- package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-config.md +126 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +146 -0
- package/skills/app-shell-patterns/references/api/use-app-shell.md +143 -0
- package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
- package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
- package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
- package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
- package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
- package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
- package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
- package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
- package/skills/app-shell-patterns/references/api/use-toast.md +107 -0
- package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
- package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
- package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
- package/skills/app-shell-patterns/references/components/alert.md +202 -0
- package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
- package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
- package/skills/app-shell-patterns/references/components/attachment.md +138 -0
- package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
- package/skills/app-shell-patterns/references/components/avatar.md +80 -0
- package/skills/app-shell-patterns/references/components/badge.md +309 -0
- package/skills/app-shell-patterns/references/components/button.md +164 -0
- package/skills/app-shell-patterns/references/components/card.md +109 -0
- package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
- package/skills/app-shell-patterns/references/components/combobox.md +318 -0
- package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
- package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
- package/skills/app-shell-patterns/references/components/data-table.md +953 -0
- package/skills/app-shell-patterns/references/components/date-picker.md +248 -0
- package/skills/app-shell-patterns/references/components/default-header.md +75 -0
- package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
- package/skills/app-shell-patterns/references/components/description-card.md +569 -0
- package/skills/app-shell-patterns/references/components/dialog.md +164 -0
- package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
- package/skills/app-shell-patterns/references/components/form.md +378 -0
- package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
- package/skills/app-shell-patterns/references/components/grid.md +184 -0
- package/skills/app-shell-patterns/references/components/input.md +83 -0
- package/skills/app-shell-patterns/references/components/layout.md +539 -0
- package/skills/app-shell-patterns/references/components/menu.md +218 -0
- package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
- package/skills/app-shell-patterns/references/components/select.md +283 -0
- package/skills/app-shell-patterns/references/components/sheet.md +237 -0
- package/skills/app-shell-patterns/references/components/sidebar-group.md +466 -0
- package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
- package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
- package/skills/app-shell-patterns/references/components/spinner.md +81 -0
- package/skills/app-shell-patterns/references/components/table.md +188 -0
- package/skills/app-shell-patterns/references/components/tabs.md +158 -0
- package/skills/app-shell-patterns/references/components/textarea.md +122 -0
- package/skills/app-shell-patterns/references/components/timeline.md +317 -0
- package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
- package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
- package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
- package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
- package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
- package/skills/app-shell-patterns/references/concepts/file-based-routing.md +350 -0
- package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +11 -4
- package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +387 -0
- package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +388 -0
- package/skills/app-shell-patterns/references/{fundamental/design-system.md → concepts/styling-theming.md} +260 -105
- package/skills/app-shell-patterns/references/migrations.md +34 -0
- package/skills/app-shell-patterns/references/pages/document-detail.md +1125 -0
- package/skills/app-shell-patterns/references/patterns/form-composer.md +44 -46
- package/skills/app-shell-patterns/references/patterns/form-modal.md +39 -100
- package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
- package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
- package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
- package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
- package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +14 -28
- package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
- package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +11 -86
- package/skills/app-shell-patterns/references/fundamental/components.md +0 -981
- package/skills/app-shell-patterns/references/patterns/detail-hero-with-actions.md +0 -201
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dialog
|
|
3
|
+
description: Modal dialog with a compound component API
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/components/dialog.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# Dialog
|
|
9
|
+
|
|
10
|
+
The `Dialog` component provides a modal dialog with a compound component API. It is backed by Base UI's Dialog primitive.
|
|
11
|
+
|
|
12
|
+
## Import
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { Dialog } from "@tailor-platform/app-shell";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Basic Usage
|
|
19
|
+
|
|
20
|
+
<example-preview name="basic-usage"></example-preview>
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
function BasicUsage() {
|
|
24
|
+
return (
|
|
25
|
+
<Dialog.Root>
|
|
26
|
+
<Dialog.Trigger render={<Button />}>Open</Dialog.Trigger>
|
|
27
|
+
<Dialog.Content>
|
|
28
|
+
<Dialog.Header>
|
|
29
|
+
<Dialog.Title>Confirm Action</Dialog.Title>
|
|
30
|
+
<Dialog.Description>Are you sure you want to proceed?</Dialog.Description>
|
|
31
|
+
</Dialog.Header>
|
|
32
|
+
<Dialog.Footer>
|
|
33
|
+
<Dialog.Close render={<Button variant="outline" />}>Cancel</Dialog.Close>
|
|
34
|
+
<Button>Confirm</Button>
|
|
35
|
+
</Dialog.Footer>
|
|
36
|
+
</Dialog.Content>
|
|
37
|
+
</Dialog.Root>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Sub-components
|
|
43
|
+
|
|
44
|
+
| Sub-component | Description |
|
|
45
|
+
| -------------------- | ----------------------------------------------------------------------- |
|
|
46
|
+
| `Dialog.Root` | Manages open/close state |
|
|
47
|
+
| `Dialog.Trigger` | Element that opens the dialog when clicked |
|
|
48
|
+
| `Dialog.Content` | The main dialog panel (includes overlay and close button automatically) |
|
|
49
|
+
| `Dialog.Header` | Layout wrapper for title and description |
|
|
50
|
+
| `Dialog.Footer` | Layout wrapper for action buttons |
|
|
51
|
+
| `Dialog.Title` | Dialog title (announced by screen readers) |
|
|
52
|
+
| `Dialog.Description` | Additional context below the title |
|
|
53
|
+
| `Dialog.Close` | Button that closes the dialog |
|
|
54
|
+
|
|
55
|
+
## Props
|
|
56
|
+
|
|
57
|
+
### Dialog.Root Props
|
|
58
|
+
|
|
59
|
+
| Prop | Type | Default | Description |
|
|
60
|
+
| -------------- | ------------------------- | ------- | --------------------------------- |
|
|
61
|
+
| `open` | `boolean` | - | Controlled open state |
|
|
62
|
+
| `defaultOpen` | `boolean` | `false` | Initial open state (uncontrolled) |
|
|
63
|
+
| `onOpenChange` | `(open: boolean) => void` | - | Callback when open state changes |
|
|
64
|
+
| `modal` | `boolean` | `true` | Whether the dialog is modal |
|
|
65
|
+
| `children` | `React.ReactNode` | - | Dialog sub-components |
|
|
66
|
+
|
|
67
|
+
### Dialog.Content Props
|
|
68
|
+
|
|
69
|
+
Accepts `className` and all standard HTML `<div>` props.
|
|
70
|
+
|
|
71
|
+
### Dialog.Trigger / Dialog.Close Props
|
|
72
|
+
|
|
73
|
+
Accept a `render` prop for custom element rendering (Base UI render pattern), plus standard button props.
|
|
74
|
+
|
|
75
|
+
## Controlled Usage
|
|
76
|
+
|
|
77
|
+
<example-preview name="controlled"></example-preview>
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
function Controlled() {
|
|
81
|
+
const [open, setOpen] = useState(false);
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
<Button variant="outline" onClick={() => setOpen(true)}>
|
|
85
|
+
Open Dialog
|
|
86
|
+
</Button>
|
|
87
|
+
<Dialog.Root open={open} onOpenChange={setOpen}>
|
|
88
|
+
<Dialog.Content>
|
|
89
|
+
<Dialog.Header>
|
|
90
|
+
<Dialog.Title>Settings</Dialog.Title>
|
|
91
|
+
</Dialog.Header>
|
|
92
|
+
<Dialog.Footer>
|
|
93
|
+
<Button onClick={() => setOpen(false)}>Done</Button>
|
|
94
|
+
</Dialog.Footer>
|
|
95
|
+
</Dialog.Content>
|
|
96
|
+
</Dialog.Root>
|
|
97
|
+
</>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Examples
|
|
103
|
+
|
|
104
|
+
### Delete Confirmation
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
function DeleteConfirmation({ onDelete }: { onDelete: () => void }) {
|
|
108
|
+
return (
|
|
109
|
+
<Dialog.Root>
|
|
110
|
+
<Dialog.Trigger render={<Button variant="destructive" />}>Delete</Dialog.Trigger>
|
|
111
|
+
<Dialog.Content>
|
|
112
|
+
<Dialog.Header>
|
|
113
|
+
<Dialog.Title>Delete Order</Dialog.Title>
|
|
114
|
+
<Dialog.Description>
|
|
115
|
+
This action cannot be undone. The order will be permanently deleted.
|
|
116
|
+
</Dialog.Description>
|
|
117
|
+
</Dialog.Header>
|
|
118
|
+
<Dialog.Footer>
|
|
119
|
+
<Dialog.Close render={<Button variant="outline" />}>Cancel</Dialog.Close>
|
|
120
|
+
<Button variant="destructive" onClick={onDelete}>
|
|
121
|
+
Delete
|
|
122
|
+
</Button>
|
|
123
|
+
</Dialog.Footer>
|
|
124
|
+
</Dialog.Content>
|
|
125
|
+
</Dialog.Root>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Form Dialog
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
function EditDialog({ item }: { item: Item }) {
|
|
134
|
+
const [name, setName] = useState(item.name);
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<Dialog.Root>
|
|
138
|
+
<Dialog.Trigger render={<Button variant="outline" />}>Edit</Dialog.Trigger>
|
|
139
|
+
<Dialog.Content>
|
|
140
|
+
<Dialog.Header>
|
|
141
|
+
<Dialog.Title>Edit Item</Dialog.Title>
|
|
142
|
+
</Dialog.Header>
|
|
143
|
+
<Input value={name} onChange={(e) => setName(e.target.value)} />
|
|
144
|
+
<Dialog.Footer>
|
|
145
|
+
<Dialog.Close render={<Button variant="outline" />}>Cancel</Dialog.Close>
|
|
146
|
+
<Button onClick={() => handleSave(name)}>Save</Button>
|
|
147
|
+
</Dialog.Footer>
|
|
148
|
+
</Dialog.Content>
|
|
149
|
+
</Dialog.Root>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Accessibility
|
|
155
|
+
|
|
156
|
+
- Dialog title is announced by screen readers via `Dialog.Title`
|
|
157
|
+
- Focus is trapped inside the dialog while open
|
|
158
|
+
- Pressing `Escape` closes the dialog
|
|
159
|
+
- The close button is always present inside `Dialog.Content`
|
|
160
|
+
|
|
161
|
+
## Related Components
|
|
162
|
+
|
|
163
|
+
- [Sheet](./sheet.md) - Slide-in panel alternative for non-modal workflows
|
|
164
|
+
- [Button](./button.md) - Use as trigger and action buttons
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DocumentProgressCard
|
|
3
|
+
description: Generic card visualising a document's lifecycle state — optional percentage, stacked progress bar, and status legend
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/components/document-progress-card.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# DocumentProgressCard
|
|
9
|
+
|
|
10
|
+
`DocumentProgressCard` is a generic, presentational card for communicating the lifecycle/fulfilment state of a document in a record detail right rail. It shows an optional completion percentage, a stacked progress bar, and a legend — driven by an arbitrary set of status `segments`.
|
|
11
|
+
|
|
12
|
+
It is view-only and domain-agnostic: pass the segments and an explicit `percent`. Any domain-specific math — deriving the percentage, or decomposing overlapping buckets into bar segments — lives in the consumer. See [Example: purchase-order fulfilment](#example-purchase-order-fulfilment) for a complete, copyable pattern.
|
|
13
|
+
|
|
14
|
+
## Import
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { DocumentProgressCard } from "@tailor-platform/app-shell";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Basic Usage
|
|
21
|
+
|
|
22
|
+
<example-preview name="basic-usage"></example-preview>
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
function BasicUsage() {
|
|
26
|
+
return (
|
|
27
|
+
<DocumentProgressCard
|
|
28
|
+
title="Shipment status"
|
|
29
|
+
percent={60}
|
|
30
|
+
segments={[
|
|
31
|
+
{ label: "Shipped", value: 30, color: "green" },
|
|
32
|
+
{ label: "Returned", value: 3, color: "red" },
|
|
33
|
+
{ label: "Pending", value: 17, color: "neutral" },
|
|
34
|
+
]}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
_Generated from the type surface — first-party props only._
|
|
43
|
+
|
|
44
|
+
### DocumentProgressCardProps
|
|
45
|
+
|
|
46
|
+
| Prop | Type | Default | Description |
|
|
47
|
+
| ------------ | --------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
48
|
+
| `className?` | `string` | - | Additional CSS classes for the card root. |
|
|
49
|
+
| `legend?` | `DocumentProgressSegment[]` | - | Legend rows. Defaults to `segments`. Provide this only when the legend should differ from the bar (e.g. overlapping buckets shown distinctly). |
|
|
50
|
+
| `percent?` | `number` | - | Headline percentage shown top-right (0–100). Optional and explicit — the generic card has no notion of "complete", so the consumer supplies it. |
|
|
51
|
+
| `segments` | `DocumentProgressSegment[]` | - | Status segments rendered as a single stacked bar (and, by default, the legend). |
|
|
52
|
+
| `title?` | `ReactNode` | - | Optional card title shown top-left. |
|
|
53
|
+
| `total?` | `number` | - | Denominator used to size the bar. Defaults to the sum of segment values (the bar is fully tiled). A larger value leaves an unfilled track remainder. |
|
|
54
|
+
|
|
55
|
+
## Exports
|
|
56
|
+
|
|
57
|
+
- `DocumentProgressCard` — function
|
|
58
|
+
- `DocumentProgressCardProps` — interface
|
|
59
|
+
|
|
60
|
+
### `DocumentProgressSegment`
|
|
61
|
+
|
|
62
|
+
| Field | Type | Description |
|
|
63
|
+
| ------- | ----------------------- | ------------------------------------------------------ |
|
|
64
|
+
| `label` | `string` | Legend label. |
|
|
65
|
+
| `value` | `number` | Amount — shown in the legend and used to size the bar. |
|
|
66
|
+
| `color` | `DocumentProgressColor` | Bar / marker color (required). |
|
|
67
|
+
|
|
68
|
+
`DocumentProgressColor` is one of: `"indigo"`, `"pink"`, `"green"`, `"amber"`, `"red"`, `"blue"`, `"neutral"`.
|
|
69
|
+
|
|
70
|
+
## Progress Bar
|
|
71
|
+
|
|
72
|
+
The bar tiles `segments` left-to-right, each sized as `value / (total ?? sum of values)`. When `total` exceeds the segment sum, the shortfall renders as an empty `bg-muted` track — useful for a "remaining" portion you don't want as a colored segment. A `"neutral"` segment reads as a muted/track-like fill.
|
|
73
|
+
|
|
74
|
+
## Legend
|
|
75
|
+
|
|
76
|
+
By default the legend mirrors `segments`. Pass `legend` to render different rows — for example when buckets overlap and the bar shows a decomposition while the legend shows the raw figures:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<DocumentProgressCard
|
|
80
|
+
percent={30}
|
|
81
|
+
total={40}
|
|
82
|
+
segments={[
|
|
83
|
+
{ label: "Net received", value: 10, color: "indigo" },
|
|
84
|
+
{ label: "Returned", value: 2, color: "pink" },
|
|
85
|
+
]}
|
|
86
|
+
legend={[
|
|
87
|
+
{ label: "Received items", value: 12, color: "indigo" },
|
|
88
|
+
{ label: "Returned items", value: 2, color: "pink" },
|
|
89
|
+
{ label: "Yet to receive", value: 28, color: "neutral" },
|
|
90
|
+
]}
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Example: purchase-order fulfilment
|
|
95
|
+
|
|
96
|
+
A common use is communicating a purchase order's receiving state — **received**, **returned**, and **yet to receive**. `DocumentProgressCard` stays generic, so derive the percentage and the bar breakdown in your component and pass them in. This recipe reproduces the recommended look (labels, indigo/pink/neutral colors, and a bar that decomposes received into "kept" + "returned" against the ordered total):
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
function PurchaseOrderFulfilment({
|
|
100
|
+
received,
|
|
101
|
+
returned,
|
|
102
|
+
yetToReceive,
|
|
103
|
+
// Whether returned items still count as fulfilled. Set false to subtract them.
|
|
104
|
+
returnedCountsAsComplete = true,
|
|
105
|
+
}: {
|
|
106
|
+
received: number;
|
|
107
|
+
returned: number;
|
|
108
|
+
yetToReceive: number;
|
|
109
|
+
returnedCountsAsComplete?: boolean;
|
|
110
|
+
}) {
|
|
111
|
+
// Returned is a subset of received; clamp so the breakdown can't exceed it.
|
|
112
|
+
const effectiveReturned = Math.min(Math.max(returned, 0), Math.max(received, 0));
|
|
113
|
+
const total = Math.max(received, 0) + Math.max(yetToReceive, 0); // the ordered quantity
|
|
114
|
+
const complete = returnedCountsAsComplete ? received : received - effectiveReturned;
|
|
115
|
+
const percent = total > 0 ? Math.round((complete / total) * 100) : 0;
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<DocumentProgressCard
|
|
119
|
+
title="Fulfilment rate"
|
|
120
|
+
percent={percent}
|
|
121
|
+
total={total} // ordered quantity — the shortfall renders as the "yet to receive" track
|
|
122
|
+
// Bar: net received (kept) + returned. Yet-to-receive is the unfilled remainder.
|
|
123
|
+
segments={[
|
|
124
|
+
{ label: "Received items", value: received - effectiveReturned, color: "indigo" },
|
|
125
|
+
{ label: "Returned items", value: effectiveReturned, color: "pink" },
|
|
126
|
+
]}
|
|
127
|
+
// Legend: the three buckets as-is, so "Received items" shows the full amount.
|
|
128
|
+
legend={[
|
|
129
|
+
{ label: "Received items", value: received, color: "indigo" },
|
|
130
|
+
{ label: "Returned items", value: returned, color: "pink" },
|
|
131
|
+
{ label: "Yet to receive", value: yetToReceive, color: "neutral" },
|
|
132
|
+
]}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// <PurchaseOrderFulfilment received={12} returned={2} yetToReceive={28} /> → 30%
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Notes for adapting it:
|
|
141
|
+
|
|
142
|
+
- **Colors:** `indigo` (received), `pink` (returned), `neutral` (yet to receive) is the recommended set; swap any of the seven palette colors to fit your domain.
|
|
143
|
+
- **Bar vs. legend:** the bar uses `received − returned` so the two colored segments don't double-count the returned items, while the `legend` override keeps "Received items" showing the full received figure.
|
|
144
|
+
- **`total`:** pass the ordered quantity so the unfilled portion of the bar represents "yet to receive". Omit it (or use the segment sum) if you want a fully-tiled bar instead.
|
|
145
|
+
- **Percentage policy:** flip `returnedCountsAsComplete` to decide whether returned items count toward completion.
|
|
146
|
+
|
|
147
|
+
## Input handling
|
|
148
|
+
|
|
149
|
+
Segment values are expected to be non-negative numbers. Non-finite or negative values are coerced to `0`, and `percent` is rounded and clamped to `[0, 100]`.
|
|
150
|
+
|
|
151
|
+
## Related
|
|
152
|
+
|
|
153
|
+
- [MetricCard](./metric-card.md) — Compact KPI summary card.
|
|
154
|
+
- [Card](./card.md) — The underlying card primitive.
|