@usefragments/ui 1.1.1 → 1.2.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.
Files changed (141) hide show
  1. package/dist/assets/ui.css +327 -274
  2. package/dist/components/Checkbox/Checkbox.module.scss.cjs +11 -11
  3. package/dist/components/Checkbox/Checkbox.module.scss.js +11 -11
  4. package/dist/components/Chip/Chip.module.scss.cjs +15 -15
  5. package/dist/components/Chip/Chip.module.scss.js +15 -15
  6. package/dist/components/Combobox/index.cjs +106 -9
  7. package/dist/components/Combobox/index.d.ts.map +1 -1
  8. package/dist/components/Combobox/index.js +106 -9
  9. package/dist/components/DataTable/DataTable.module.scss.cjs +37 -34
  10. package/dist/components/DataTable/DataTable.module.scss.js +37 -34
  11. package/dist/components/Main/Main.module.scss.cjs +26 -0
  12. package/dist/components/Main/Main.module.scss.js +26 -0
  13. package/dist/components/Main/index.cjs +128 -0
  14. package/dist/components/Main/index.d.ts +22 -0
  15. package/dist/components/Main/index.d.ts.map +1 -0
  16. package/dist/components/Main/index.js +111 -0
  17. package/dist/components/Table/Table.module.scss.cjs +19 -19
  18. package/dist/components/Table/Table.module.scss.js +19 -19
  19. package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +15 -15
  20. package/dist/components/TableOfContents/TableOfContents.module.scss.js +15 -15
  21. package/dist/components/TableOfContents/index.cjs +22 -42
  22. package/dist/components/TableOfContents/index.d.ts +3 -3
  23. package/dist/components/TableOfContents/index.d.ts.map +1 -1
  24. package/dist/components/TableOfContents/index.js +22 -42
  25. package/dist/index.cjs +87 -85
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -0
  29. package/fragments.json +1 -1
  30. package/package.json +7 -2
  31. package/src/components/Checkbox/Checkbox.contract.json +5 -24
  32. package/src/components/Checkbox/Checkbox.module.scss +4 -2
  33. package/src/components/Chip/Chip.contract.json +11 -28
  34. package/src/components/Chip/Chip.module.scss +21 -45
  35. package/src/components/Combobox/Combobox.contract.json +6 -24
  36. package/src/components/Combobox/index.tsx +132 -6
  37. package/src/components/DataTable/DataTable.module.scss +31 -8
  38. package/src/components/Main/Main.contract.json +79 -0
  39. package/src/components/Main/Main.module.scss +31 -0
  40. package/src/components/Main/index.tsx +124 -0
  41. package/src/components/Table/Table.module.scss +22 -5
  42. package/src/components/TableOfContents/TableOfContents.contract.json +6 -16
  43. package/src/components/TableOfContents/TableOfContents.module.scss +10 -13
  44. package/src/components/TableOfContents/index.tsx +27 -38
  45. package/src/index.ts +3 -0
  46. package/src/tokens/_component-properties.scss +1 -0
  47. package/dist/components/Cloud/DashboardLayoutPrototypes.shared.d.ts +0 -33
  48. package/dist/components/Cloud/DashboardLayoutPrototypes.shared.d.ts.map +0 -1
  49. package/dist/components/Cloud/DashboardLayoutPrototypes.shell.d.ts +0 -11
  50. package/dist/components/Cloud/DashboardLayoutPrototypes.shell.d.ts.map +0 -1
  51. package/dist/components/Cloud/PullRequestsPrototypes.content.d.ts +0 -5
  52. package/dist/components/Cloud/PullRequestsPrototypes.content.d.ts.map +0 -1
  53. package/dist/components/Cloud/PullRequestsPrototypes.detail-panels.d.ts +0 -4
  54. package/dist/components/Cloud/PullRequestsPrototypes.detail-panels.d.ts.map +0 -1
  55. package/dist/components/Cloud/PullRequestsPrototypes.detail.d.ts +0 -3
  56. package/dist/components/Cloud/PullRequestsPrototypes.detail.d.ts.map +0 -1
  57. package/dist/components/Cloud/PullRequestsPrototypes.id-data.d.ts +0 -86
  58. package/dist/components/Cloud/PullRequestsPrototypes.id-data.d.ts.map +0 -1
  59. package/dist/components/Cloud/PullRequestsPrototypes.id-page.d.ts +0 -2
  60. package/dist/components/Cloud/PullRequestsPrototypes.id-page.d.ts.map +0 -1
  61. package/src/components/Accordion/Accordion.stories.tsx +0 -106
  62. package/src/components/Alert/Alert.stories.tsx +0 -119
  63. package/src/components/AppShell/AppShell.stories.tsx +0 -156
  64. package/src/components/Avatar/Avatar.stories.tsx +0 -74
  65. package/src/components/Badge/Badge.stories.tsx +0 -92
  66. package/src/components/BentoGrid/BentoGrid.stories.tsx +0 -98
  67. package/src/components/Box/Box.stories.tsx +0 -150
  68. package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +0 -87
  69. package/src/components/Button/Button.stories.tsx +0 -103
  70. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -97
  71. package/src/components/Card/Card.stories.tsx +0 -144
  72. package/src/components/Chart/Chart.stories.tsx +0 -119
  73. package/src/components/Checkbox/Checkbox.stories.tsx +0 -68
  74. package/src/components/Chip/Chip.stories.tsx +0 -70
  75. package/src/components/Cloud/CloudGovernanceShell.module.scss +0 -88
  76. package/src/components/Cloud/CloudGovernanceShell.stories.tsx +0 -446
  77. package/src/components/Cloud/ControlSizing.module.scss +0 -49
  78. package/src/components/Cloud/ControlSizing.stories.tsx +0 -238
  79. package/src/components/Cloud/DashboardLayoutPrototypes.module.scss +0 -462
  80. package/src/components/Cloud/DashboardLayoutPrototypes.shared.tsx +0 -375
  81. package/src/components/Cloud/DashboardLayoutPrototypes.shell.tsx +0 -147
  82. package/src/components/Cloud/DashboardLayoutPrototypes.stories.tsx +0 -328
  83. package/src/components/Cloud/PullRequestsPrototypes.content.tsx +0 -283
  84. package/src/components/Cloud/PullRequestsPrototypes.detail-panels.tsx +0 -381
  85. package/src/components/Cloud/PullRequestsPrototypes.detail.tsx +0 -204
  86. package/src/components/Cloud/PullRequestsPrototypes.id-data.ts +0 -395
  87. package/src/components/Cloud/PullRequestsPrototypes.id-page.tsx +0 -349
  88. package/src/components/Cloud/PullRequestsPrototypes.stories.tsx +0 -81
  89. package/src/components/CodeBlock/CodeBlock.stories.tsx +0 -147
  90. package/src/components/Collapsible/Collapsible.stories.tsx +0 -94
  91. package/src/components/ColorPicker/ColorPicker.stories.tsx +0 -74
  92. package/src/components/Combobox/Combobox.stories.tsx +0 -133
  93. package/src/components/Command/Command.stories.tsx +0 -102
  94. package/src/components/ConversationList/ConversationList.stories.tsx +0 -93
  95. package/src/components/DataTable/DataTable.stories.tsx +0 -129
  96. package/src/components/DatePicker/DatePicker.stories.tsx +0 -129
  97. package/src/components/Dialog/Dialog.stories.tsx +0 -154
  98. package/src/components/Drawer/Drawer.stories.tsx +0 -144
  99. package/src/components/Editor/Editor.stories.tsx +0 -99
  100. package/src/components/EmptyState/EmptyState.stories.tsx +0 -97
  101. package/src/components/Field/Field.stories.tsx +0 -109
  102. package/src/components/Fieldset/Fieldset.stories.tsx +0 -116
  103. package/src/components/Form/Form.stories.tsx +0 -142
  104. package/src/components/Grid/Grid.stories.tsx +0 -125
  105. package/src/components/Header/Header.stories.tsx +0 -133
  106. package/src/components/Icon/Icon.stories.tsx +0 -80
  107. package/src/components/IconButton/IconButton.stories.tsx +0 -78
  108. package/src/components/Image/Image.stories.tsx +0 -109
  109. package/src/components/Input/Input.stories.tsx +0 -104
  110. package/src/components/Link/Link.stories.tsx +0 -67
  111. package/src/components/List/List.stories.tsx +0 -95
  112. package/src/components/Listbox/Listbox.stories.tsx +0 -81
  113. package/src/components/Loading/Loading.stories.tsx +0 -69
  114. package/src/components/Markdown/Markdown.stories.tsx +0 -75
  115. package/src/components/Menu/Menu.stories.tsx +0 -113
  116. package/src/components/Message/Message.stories.tsx +0 -85
  117. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -161
  118. package/src/components/Pagination/Pagination.stories.tsx +0 -81
  119. package/src/components/Popover/Popover.stories.tsx +0 -152
  120. package/src/components/Progress/Progress.stories.tsx +0 -64
  121. package/src/components/Prompt/Prompt.stories.tsx +0 -93
  122. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -107
  123. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -97
  124. package/src/components/Select/Select.stories.tsx +0 -127
  125. package/src/components/Separator/Separator.stories.tsx +0 -84
  126. package/src/components/Sidebar/Sidebar.stories.tsx +0 -122
  127. package/src/components/Skeleton/Skeleton.stories.tsx +0 -80
  128. package/src/components/Slider/Slider.stories.tsx +0 -73
  129. package/src/components/Stack/Stack.stories.tsx +0 -73
  130. package/src/components/Switch/Switch.stories.tsx +0 -59
  131. package/src/components/Table/Table.stories.tsx +0 -219
  132. package/src/components/TableOfContents/TableOfContents.stories.tsx +0 -120
  133. package/src/components/Tabs/Tabs.stories.tsx +0 -136
  134. package/src/components/Text/Text.stories.tsx +0 -133
  135. package/src/components/Textarea/Textarea.stories.tsx +0 -107
  136. package/src/components/Theme/Theme.stories.tsx +0 -95
  137. package/src/components/ThinkingIndicator/ThinkingIndicator.stories.tsx +0 -85
  138. package/src/components/Toast/Toast.stories.tsx +0 -91
  139. package/src/components/ToggleGroup/ToggleGroup.stories.tsx +0 -114
  140. package/src/components/Tooltip/Tooltip.stories.tsx +0 -95
  141. package/src/components/VisuallyHidden/VisuallyHidden.stories.tsx +0 -78
@@ -1,375 +0,0 @@
1
- import { ArrowRight, MagnifyingGlass } from "@phosphor-icons/react";
2
- import { Badge } from "../Badge";
3
- import { Box } from "../Box";
4
- import { Button } from "../Button";
5
- import { Card } from "../Card";
6
- import { DataTable, type DataTableColumn } from "../DataTable";
7
- import { Input } from "../Input";
8
- import { Progress, type ProgressProps } from "../Progress";
9
- import { Select } from "../Select";
10
- import { Separator } from "../Separator";
11
- import { Stack } from "../Stack";
12
- import { Text } from "../Text";
13
- export { PrototypeShell } from "./DashboardLayoutPrototypes.shell";
14
- import styles from "./DashboardLayoutPrototypes.module.scss";
15
-
16
- export type StateVariant = "success" | "warning" | "error" | "info";
17
-
18
- export type AreaRow = {
19
- area: string;
20
- owner: string;
21
- coverage: number;
22
- drift: number;
23
- criticality: string;
24
- state: "Healthy" | "Watching" | "Blocked" | "Review";
25
- variant: StateVariant;
26
- };
27
-
28
- type Activity = {
29
- title: string;
30
- detail: string;
31
- status: string;
32
- time: string;
33
- variant: StateVariant;
34
- };
35
-
36
- export const areas: AreaRow[] = [
37
- {
38
- area: "Checkout",
39
- owner: "Revenue systems",
40
- coverage: 91,
41
- drift: 2,
42
- criticality: "Revenue",
43
- state: "Watching",
44
- variant: "warning",
45
- },
46
- {
47
- area: "Dashboard",
48
- owner: "Cloud product",
49
- coverage: 84,
50
- drift: 4,
51
- criticality: "Core app",
52
- state: "Review",
53
- variant: "info",
54
- },
55
- {
56
- area: "Marketing",
57
- owner: "Growth",
58
- coverage: 68,
59
- drift: 11,
60
- criticality: "Public",
61
- state: "Blocked",
62
- variant: "error",
63
- },
64
- {
65
- area: "Admin",
66
- owner: "Platform",
67
- coverage: 96,
68
- drift: 1,
69
- criticality: "Internal",
70
- state: "Healthy",
71
- variant: "success",
72
- },
73
- ];
74
-
75
- const activity: Activity[] = [
76
- {
77
- title: "Governance scan completed",
78
- detail: "21 findings resolved, 4 new color drift reports opened.",
79
- status: "Completed",
80
- time: "2m ago",
81
- variant: "success",
82
- },
83
- {
84
- title: "Checkout exceeded drift budget",
85
- detail: "Spacing and danger color tokens need review before release.",
86
- status: "Attention",
87
- time: "14m ago",
88
- variant: "warning",
89
- },
90
- {
91
- title: "Setup PR merged",
92
- detail: "fragments/cloud now reports CI findings into Cloud.",
93
- status: "Merged",
94
- time: "1h ago",
95
- variant: "info",
96
- },
97
- ];
98
-
99
- const areaColumns: DataTableColumn<AreaRow>[] = [
100
- { accessorKey: "area", header: "Area", size: 148, truncate: true },
101
- { accessorKey: "owner", header: "Owner", truncate: true },
102
- {
103
- accessorKey: "coverage",
104
- header: "Coverage",
105
- size: 112,
106
- cell: (context) => `${(context.row.original as AreaRow).coverage}%`,
107
- },
108
- {
109
- accessorKey: "drift",
110
- header: "Drift",
111
- size: 84,
112
- align: "right",
113
- },
114
- {
115
- accessorKey: "state",
116
- header: "State",
117
- size: 112,
118
- cell: (context) => {
119
- const row = context.row.original as AreaRow;
120
- return (
121
- <Badge variant={row.variant} size="sm">
122
- {row.state}
123
- </Badge>
124
- );
125
- },
126
- },
127
- ];
128
-
129
- const activityColumns: DataTableColumn<Activity>[] = [
130
- {
131
- accessorKey: "title",
132
- header: "Event",
133
- size: 240,
134
- truncate: true,
135
- },
136
- {
137
- accessorKey: "detail",
138
- header: "Detail",
139
- truncate: true,
140
- },
141
- {
142
- accessorKey: "status",
143
- header: "Status",
144
- size: 116,
145
- cell: (context) => {
146
- const row = context.row.original as Activity;
147
- return (
148
- <Badge variant={row.variant} size="sm">
149
- {row.status}
150
- </Badge>
151
- );
152
- },
153
- },
154
- {
155
- accessorKey: "time",
156
- header: "Time",
157
- size: 96,
158
- align: "right",
159
- },
160
- ];
161
-
162
- export function MetricPanel({
163
- label,
164
- value,
165
- progress,
166
- variant = "default",
167
- }: {
168
- label: string;
169
- value: string;
170
- progress: number;
171
- variant?: ProgressProps["variant"];
172
- }) {
173
- return (
174
- <Card variant="panel" padding="none">
175
- <Card.Header divided>
176
- <Card.Title>{label}</Card.Title>
177
- </Card.Header>
178
- <Card.Body padding="md">
179
- <Stack gap="sm">
180
- <Text size="sm" weight="semibold" tabularNums>
181
- {value}
182
- </Text>
183
- <Progress value={progress} variant={variant} size="sm" aria-label={label} />
184
- </Stack>
185
- </Card.Body>
186
- </Card>
187
- );
188
- }
189
-
190
- export function CoverageHero({ className }: { className?: string } = {}) {
191
- return (
192
- <Card variant="panel" padding="none" className={className}>
193
- <Card.Body padding="none" className={styles.stretchBody}>
194
- <Stack gap="none" className={styles.coverageBody}>
195
- <Stack
196
- direction="row"
197
- justify="between"
198
- align="start"
199
- gap="md"
200
- className={styles.coverageSummary}
201
- >
202
- <Stack gap="xs" className={styles.minWidthZero}>
203
- <Text size="xs" color="tertiary">
204
- Design contract coverage
205
- </Text>
206
- <Text size="lg" weight="semibold" tabularNums>
207
- 82% covered evidence
208
- </Text>
209
- </Stack>
210
- <Text size="xs" color="secondary" className={styles.coverageDelta}>
211
- +8 trend
212
- </Text>
213
- </Stack>
214
- <Box className={styles.coverageChartWrap}>
215
- <svg
216
- className={styles.coverageTrendChart}
217
- viewBox="0 0 240 72"
218
- preserveAspectRatio="none"
219
- role="img"
220
- aria-label="Design contract coverage over time"
221
- >
222
- <defs>
223
- <linearGradient id="coverage-trend" x1="0" x2="0" y1="0" y2="1">
224
- <stop offset="0%" stopColor="currentColor" stopOpacity="0.34" />
225
- <stop offset="100%" stopColor="currentColor" stopOpacity="0.03" />
226
- </linearGradient>
227
- </defs>
228
- <path
229
- d="M 0 56 L 34 50 L 69 45 L 103 47 L 137 35 L 171 31 L 206 23 L 240 20 L 240 72 L 0 72 Z"
230
- fill="url(#coverage-trend)"
231
- />
232
- <path
233
- d="M 0 56 L 34 50 L 69 45 L 103 47 L 137 35 L 171 31 L 206 23 L 240 20"
234
- fill="none"
235
- stroke="currentColor"
236
- strokeWidth="2"
237
- />
238
- </svg>
239
- </Box>
240
- </Stack>
241
- </Card.Body>
242
- </Card>
243
- );
244
- }
245
-
246
- export function AreasTable({ title = "Areas at risk" }: { title?: string }) {
247
- return (
248
- <Card variant="panel" padding="none" className={styles.minWidthZero}>
249
- <Card.Header divided>
250
- <Stack direction="row" justify="between" align="center" gap="md" className={styles.full}>
251
- <Card.Title>{title}</Card.Title>
252
- <Badge variant="warning" size="sm">
253
- 3 need attention
254
- </Badge>
255
- </Stack>
256
- </Card.Header>
257
- <Card.Body padding="sm">
258
- <DataTable
259
- columns={areaColumns}
260
- data={areas}
261
- getRowId={(row) => row.area}
262
- density="condensed"
263
- bordered
264
- caption={title}
265
- captionHidden
266
- />
267
- </Card.Body>
268
- </Card>
269
- );
270
- }
271
-
272
- export function ActionPanel({ className }: { className?: string } = {}) {
273
- return (
274
- <Card variant="panel" padding="none" className={className}>
275
- <Card.Header divided>
276
- <Card.Title>Recommended action</Card.Title>
277
- </Card.Header>
278
- <Card.Body padding="md" className={styles.actionPanelBody}>
279
- <Stack gap="md" justify="between" className={styles.actionPanelContent}>
280
- <Stack gap="xs">
281
- <Text size="sm" weight="semibold">
282
- Review Marketing color drift before release.
283
- </Text>
284
- <Text size="sm" color="secondary">
285
- 11 new findings came from public pages with low contract coverage.
286
- </Text>
287
- </Stack>
288
- <Button variant="primary" size="sm" className={styles.actionButton}>
289
- Open findings <ArrowRight size={14} weight="bold" />
290
- </Button>
291
- </Stack>
292
- </Card.Body>
293
- </Card>
294
- );
295
- }
296
-
297
- export function ActivityPanel() {
298
- return (
299
- <Card variant="panel" padding="none">
300
- <Card.Header divided>
301
- <Card.Title>Recent governance activity</Card.Title>
302
- </Card.Header>
303
- <Card.Body padding="sm">
304
- <ActivityTable />
305
- </Card.Body>
306
- </Card>
307
- );
308
- }
309
-
310
- export function ActivityTable() {
311
- return (
312
- <DataTable
313
- columns={activityColumns}
314
- data={activity}
315
- getRowId={(row) => row.title}
316
- density="condensed"
317
- bordered
318
- caption="Recent governance activity"
319
- captionHidden
320
- />
321
- );
322
- }
323
-
324
- export function StatePanel() {
325
- return (
326
- <Card variant="panel" padding="none">
327
- <Card.Header divided>
328
- <Card.Title>System status</Card.Title>
329
- </Card.Header>
330
- <Card.Body>
331
- <Stack gap="none" separator={<Separator soft />}>
332
- {[
333
- ["CI ingestion", "Live", "success"],
334
- ["GitHub App", "Connected", "success"],
335
- ["Exception debt", "Watching", "warning"],
336
- ["Release gate", "Blocked", "error"],
337
- ].map(([label, value, variant]) => (
338
- <Box key={label} paddingX="md" paddingY="sm">
339
- <Stack direction="row" justify="between" align="center" gap="md">
340
- <Text size="sm" color="secondary">
341
- {label}
342
- </Text>
343
- <Badge variant={variant as StateVariant} size="sm">
344
- {value}
345
- </Badge>
346
- </Stack>
347
- </Box>
348
- ))}
349
- </Stack>
350
- </Card.Body>
351
- </Card>
352
- );
353
- }
354
-
355
- export function FindingsToolbar() {
356
- return (
357
- <Box className={styles.toolbar}>
358
- <Input
359
- aria-label="Search dashboard evidence"
360
- placeholder="Search evidence..."
361
- size="sm"
362
- startAdornment={<MagnifyingGlass size={16} />}
363
- shortcut="⌘K"
364
- withFieldWrapper={false}
365
- />
366
- <Select aria-label="Time range" defaultValue="7d" size="sm">
367
- <Select.Trigger />
368
- <Select.Content>
369
- <Select.Item value="7d">Last 7 days</Select.Item>
370
- <Select.Item value="30d">Last 30 days</Select.Item>
371
- </Select.Content>
372
- </Select>
373
- </Box>
374
- );
375
- }
@@ -1,147 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import {
3
- Clock,
4
- Gear,
5
- GitBranch,
6
- GitPullRequest,
7
- House,
8
- ListChecks,
9
- ShieldCheck,
10
- } from "@phosphor-icons/react";
11
- import { AppShell } from "../AppShell";
12
- import { Avatar } from "../Avatar";
13
- import { Box } from "../Box";
14
- import { Button } from "../Button";
15
- import { Sidebar } from "../Sidebar";
16
- import { Stack } from "../Stack";
17
- import { Text } from "../Text";
18
- import styles from "./DashboardLayoutPrototypes.module.scss";
19
-
20
- export type CloudNavLabel =
21
- | "Dashboard"
22
- | "Pull Requests"
23
- | "Backlog"
24
- | "Governance"
25
- | "Developer setup"
26
- | "Settings";
27
-
28
- function SidebarBrand() {
29
- return (
30
- <Stack direction="row" align="center" gap="sm">
31
- <Box as="span" className={styles.brandMark}>
32
- <GitBranch size={16} weight="bold" />
33
- </Box>
34
- <Stack gap="none" className={styles.truncate}>
35
- <Text variant="section-label" color="tertiary" truncate>
36
- Active repository
37
- </Text>
38
- <Text size="sm" weight="semibold" truncate>
39
- fragments-sdk/ui
40
- </Text>
41
- </Stack>
42
- </Stack>
43
- );
44
- }
45
-
46
- function CloudSidebar({ activeNav }: { activeNav: CloudNavLabel }) {
47
- return (
48
- <>
49
- <Sidebar.Header>
50
- <SidebarBrand />
51
- </Sidebar.Header>
52
- <Sidebar.Nav>
53
- <Sidebar.Section>
54
- <Sidebar.Item icon={<House size={18} />} active={activeNav === "Dashboard"}>
55
- Dashboard
56
- </Sidebar.Item>
57
- <Sidebar.Item icon={<GitPullRequest size={18} />} active={activeNav === "Pull Requests"}>
58
- Pull Requests
59
- </Sidebar.Item>
60
- <Sidebar.Item icon={<ListChecks size={18} />} active={activeNav === "Backlog"} badge={7}>
61
- Backlog
62
- </Sidebar.Item>
63
- <Sidebar.Item icon={<ShieldCheck size={18} />} active={activeNav === "Governance"}>
64
- Governance
65
- </Sidebar.Item>
66
- </Sidebar.Section>
67
- <Sidebar.Section label="Setup">
68
- <Sidebar.Item icon={<Clock size={18} />} active={activeNav === "Developer setup"}>
69
- Developer setup
70
- </Sidebar.Item>
71
- <Sidebar.Item icon={<Gear size={18} />} active={activeNav === "Settings"}>
72
- Settings
73
- </Sidebar.Item>
74
- </Sidebar.Section>
75
- </Sidebar.Nav>
76
- <Sidebar.Footer>
77
- <Stack direction="row" align="center" gap="sm">
78
- <Avatar initials="T" name="Test User" size="md" />
79
- <Stack gap="none" className={styles.truncate}>
80
- <Text size="sm" weight="semibold" truncate>
81
- Test User
82
- </Text>
83
- <Text size="2xs" color="tertiary" truncate>
84
- dev_test@app.usefragments.com
85
- </Text>
86
- </Stack>
87
- </Stack>
88
- </Sidebar.Footer>
89
- </>
90
- );
91
- }
92
-
93
- export function PrototypeShell({
94
- activeNav = "Dashboard",
95
- eyebrow,
96
- title,
97
- description = "Design contract coverage, drift budgets, and release readiness.",
98
- actions,
99
- children,
100
- }: {
101
- activeNav?: CloudNavLabel;
102
- eyebrow?: string;
103
- title: string;
104
- description?: string;
105
- actions?: ReactNode;
106
- children: ReactNode;
107
- }) {
108
- return (
109
- <Box className={styles.frame}>
110
- <AppShell layout="sidebar" bg="var(--fui-app-canvas-bg)" className={styles.shell}>
111
- <AppShell.Sidebar width="260px" collapsible="offcanvas">
112
- <CloudSidebar activeNav={activeNav} />
113
- </AppShell.Sidebar>
114
- <AppShell.Main padding="none" className={styles.main}>
115
- <Stack as="main" gap="lg" className={styles.page}>
116
- <Stack direction="row" justify="between" align="start" gap="md" wrap>
117
- <Stack gap="xs" className={styles.heading}>
118
- {eyebrow ? (
119
- <Text variant="section-label" color="tertiary">
120
- {eyebrow}
121
- </Text>
122
- ) : null}
123
- <Text as="h1" size="xl" weight="bold">
124
- {title}
125
- </Text>
126
- <Text as="p" size="sm" color="secondary">
127
- {description}
128
- </Text>
129
- </Stack>
130
- {actions ?? (
131
- <Stack direction="row" gap="sm" wrap>
132
- <Button variant="outlined" size="sm">
133
- View reports
134
- </Button>
135
- <Button variant="secondary" size="sm">
136
- Learn more
137
- </Button>
138
- </Stack>
139
- )}
140
- </Stack>
141
- {children}
142
- </Stack>
143
- </AppShell.Main>
144
- </AppShell>
145
- </Box>
146
- );
147
- }