@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,328 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import type { ReactNode } from "react";
3
- import { Box } from "../Box";
4
- import { Card } from "../Card";
5
- import { Grid } from "../Grid";
6
- import { Link } from "../Link";
7
- import { Progress } from "../Progress";
8
- import { Stack } from "../Stack";
9
- import { Tabs } from "../Tabs";
10
- import { Text } from "../Text";
11
- import {
12
- ActionPanel,
13
- ActivityPanel,
14
- ActivityTable,
15
- AreasTable,
16
- CoverageHero,
17
- FindingsToolbar,
18
- MetricPanel,
19
- PrototypeShell,
20
- StatePanel,
21
- areas,
22
- } from "./DashboardLayoutPrototypes.shared";
23
- import styles from "./DashboardLayoutPrototypes.module.scss";
24
-
25
- const meta = {
26
- title: "Cloud/Prototypes/Dashboard",
27
- parameters: {
28
- layout: "fullscreen",
29
- backgrounds: { default: "dark" },
30
- docs: {
31
- description: {
32
- component:
33
- "Cloud dashboard layout prototypes for comparing governance-first product information architecture.",
34
- },
35
- },
36
- },
37
- } satisfies Meta;
38
-
39
- export default meta;
40
-
41
- type Story = StoryObj<typeof meta>;
42
- type AreaName = (typeof areas)[number]["area"];
43
-
44
- const driftSeries = {
45
- Checkout: [4, 3, 5, 3, 2, 3, 2, 2],
46
- Dashboard: [2, 4, 3, 5, 6, 4, 5, 4],
47
- Marketing: [5, 7, 8, 11, 9, 13, 12, 11],
48
- Admin: [3, 2, 2, 1, 2, 1, 1, 1],
49
- } satisfies Record<AreaName, number[]>;
50
-
51
- function buildAreaPath(values: number[]) {
52
- const width = 240;
53
- const height = 72;
54
- const max = Math.max(...values, 1);
55
- const points = values.map((value, index) => {
56
- const x = (index / (values.length - 1)) * width;
57
- const y = height - (value / max) * (height - 10) - 5;
58
- return [x, y] as const;
59
- });
60
- const line = points.map(([x, y], index) => `${index === 0 ? "M" : "L"} ${x} ${y}`).join(" ");
61
- const fill = `${line} L ${width} ${height} L 0 ${height} Z`;
62
- return { line, fill };
63
- }
64
-
65
- function DashboardSection({ title, children }: { title: string; children: ReactNode }) {
66
- return (
67
- <Stack as="section" gap="sm">
68
- <Stack direction="row" justify="between" align="center" gap="md" wrap>
69
- <Text as="h2" size="sm" weight="semibold">
70
- {title}
71
- </Text>
72
- <Text size="sm" weight="medium">
73
- <Link href="#" variant="muted" underline="none">
74
- View more
75
- </Link>
76
- </Text>
77
- </Stack>
78
- {children}
79
- </Stack>
80
- );
81
- }
82
-
83
- function AreaDriftCard({ area }: { area: (typeof areas)[number] }) {
84
- const values = driftSeries[area.area];
85
- const latest = values.at(-1) ?? 0;
86
- const first = values[0] ?? latest;
87
- const trendDelta = latest - first;
88
- const trend = trendDelta > 0 ? "up" : trendDelta < 0 ? "down" : "flat";
89
- const chart = buildAreaPath(values);
90
- const gradientId = `drift-${area.area.toLowerCase()}`;
91
-
92
- return (
93
- <Card variant="panel" padding="none" className={styles.areaDriftCard}>
94
- <Card.Body padding="none">
95
- <Stack gap="none">
96
- <Stack
97
- direction="row"
98
- justify="between"
99
- align="start"
100
- gap="md"
101
- className={styles.areaDriftSummary}
102
- >
103
- <Stack gap="xs" className={styles.minWidthZero}>
104
- <Text size="xs" color="tertiary">
105
- {area.owner}
106
- </Text>
107
- <Text size="sm" weight="semibold" tabularNums>
108
- {latest} open drift
109
- </Text>
110
- </Stack>
111
- <Text
112
- size="xs"
113
- color="secondary"
114
- className={styles.areaDelta}
115
- data-trend={trend}
116
- tabularNums
117
- >
118
- {trendDelta > 0 ? "+" : ""}
119
- {trendDelta} trend
120
- </Text>
121
- </Stack>
122
- <Box className={styles.chartWrap}>
123
- <svg
124
- className={styles.driftChart}
125
- data-trend={trend}
126
- viewBox="0 0 240 72"
127
- preserveAspectRatio="none"
128
- role="img"
129
- aria-label={`${area.area} drift over time`}
130
- >
131
- <title>{area.area} drift over time</title>
132
- <defs>
133
- <linearGradient id={gradientId} x1="0" x2="0" y1="0" y2="1">
134
- <stop offset="0%" stopColor="currentColor" stopOpacity="0.34" />
135
- <stop offset="100%" stopColor="currentColor" stopOpacity="0.03" />
136
- </linearGradient>
137
- </defs>
138
- <path d={chart.fill} fill={`url(#${gradientId})`} />
139
- <path d={chart.line} fill="none" stroke="currentColor" strokeWidth="3" />
140
- </svg>
141
- </Box>
142
- </Stack>
143
- </Card.Body>
144
- </Card>
145
- );
146
- }
147
-
148
- function AreaDriftCards() {
149
- return (
150
- <Grid columns="auto" minChildWidth="240px" gap="md">
151
- {areas.map((area) => (
152
- <AreaDriftCard key={area.area} area={area} />
153
- ))}
154
- </Grid>
155
- );
156
- }
157
-
158
- function BudgetPanel() {
159
- return (
160
- <Card variant="panel" padding="none">
161
- <Card.Header divided>
162
- <Card.Title>Area drift budgets</Card.Title>
163
- </Card.Header>
164
- <Card.Body padding="md">
165
- <Stack gap="md">
166
- {areas.map((area) => (
167
- <Stack key={area.area} gap="xs">
168
- <Stack direction="row" justify="between" align="center" gap="md">
169
- <Text size="sm" weight="medium">
170
- {area.area}
171
- </Text>
172
- <Text size="xs" color="secondary">
173
- {area.drift} open
174
- </Text>
175
- </Stack>
176
- <Progress
177
- value={Math.min(area.drift * 8, 100)}
178
- variant={area.variant === "error" ? "danger" : area.variant}
179
- size="sm"
180
- aria-label={`${area.area} drift budget`}
181
- />
182
- </Stack>
183
- ))}
184
- </Stack>
185
- </Card.Body>
186
- </Card>
187
- );
188
- }
189
-
190
- function InventoryPanel() {
191
- return (
192
- <Card variant="panel" padding="none">
193
- <Card.Header divided>
194
- <Card.Title>Inventory health</Card.Title>
195
- </Card.Header>
196
- <Card.Body padding="md">
197
- <Grid columns={{ base: 1, md: 2 }} gap="md">
198
- <MetricPanel label="Tracked components" value="128" progress={88} />
199
- <MetricPanel label="Tracked tokens" value="312" progress={94} />
200
- </Grid>
201
- </Card.Body>
202
- </Card>
203
- );
204
- }
205
-
206
- function TabbedFindings() {
207
- return (
208
- <Stack gap="sm" className={styles.minWidthZero}>
209
- <Tabs defaultValue="findings" variant="pills">
210
- <Tabs.List>
211
- <Tabs.Tab value="findings">Findings</Tabs.Tab>
212
- <Tabs.Tab value="prs">Pull requests</Tabs.Tab>
213
- <Tabs.Tab value="agents">Agents</Tabs.Tab>
214
- </Tabs.List>
215
- <Tabs.Panel value="findings" flush>
216
- <AreasTable title="Governance findings by area" />
217
- </Tabs.Panel>
218
- <Tabs.Panel value="prs" flush>
219
- <AreasTable title="Pull requests with drift" />
220
- </Tabs.Panel>
221
- <Tabs.Panel value="agents" flush>
222
- <AreasTable title="AI-generated code compliance" />
223
- </Tabs.Panel>
224
- </Tabs>
225
- </Stack>
226
- );
227
- }
228
-
229
- export const Layout1ExecutiveOverview: Story = {
230
- name: "Layout 1 · Executive overview",
231
- render: () => (
232
- <PrototypeShell title="Dashboard">
233
- <Box className={styles.heroActionGrid}>
234
- <CoverageHero className={styles.stretchCard} />
235
- <ActionPanel className={styles.stretchCard} />
236
- </Box>
237
- <DashboardSection title="Codebase by area">
238
- <AreaDriftCards />
239
- </DashboardSection>
240
- <DashboardSection title="Recent governance activity">
241
- <ActivityTable />
242
- </DashboardSection>
243
- </PrototypeShell>
244
- ),
245
- };
246
-
247
- export const Layout2OperationsCommandCenter: Story = {
248
- name: "Layout 2 · Operations command center",
249
- render: () => (
250
- <PrototypeShell eyebrow="Layout 2" title="Operations command center">
251
- <ActionPanel />
252
- <Grid columns="auto" minChildWidth="220px" gap="md">
253
- <MetricPanel label="Contract coverage" value="82%" progress={82} variant="success" />
254
- <MetricPanel label="New drift" value="24" progress={48} variant="warning" />
255
- <MetricPanel label="Blocked PRs" value="4" progress={16} variant="danger" />
256
- <MetricPanel label="Exceptions" value="9" progress={36} variant="warning" />
257
- </Grid>
258
- <Box className={styles.twoColumn}>
259
- <Stack gap="md" className={styles.minWidthZero}>
260
- <FindingsToolbar />
261
- <TabbedFindings />
262
- </Stack>
263
- <Stack gap="md">
264
- <BudgetPanel />
265
- <StatePanel />
266
- </Stack>
267
- </Box>
268
- </PrototypeShell>
269
- ),
270
- };
271
-
272
- export const Layout3AreaFirst: Story = {
273
- name: "Layout 3 · Area first",
274
- render: () => (
275
- <PrototypeShell eyebrow="Layout 3" title="Area-first dashboard">
276
- <Grid columns="auto" minChildWidth="220px" gap="md">
277
- <MetricPanel label="Overall coverage" value="82%" progress={82} variant="success" />
278
- <MetricPanel label="Worst area" value="68%" progress={68} variant="warning" />
279
- <MetricPanel label="New drift" value="24" progress={48} variant="warning" />
280
- <MetricPanel label="Owners needed" value="2" progress={20} variant="danger" />
281
- </Grid>
282
- <AreasTable title="Areas ranked by governance risk" />
283
- <Box className={styles.twoColumn}>
284
- <Card variant="panel" padding="none">
285
- <Card.Header divided>
286
- <Card.Title>Marketing area detail</Card.Title>
287
- </Card.Header>
288
- <Card.Body padding="md">
289
- <Stack gap="md">
290
- <Text size="sm" color="secondary">
291
- Public surfaces have low coverage, rising exception debt, and repeated color
292
- substitutions from generated code.
293
- </Text>
294
- <Progress value={68} variant="warning" aria-label="Marketing coverage" />
295
- </Stack>
296
- </Card.Body>
297
- </Card>
298
- <ActionPanel />
299
- </Box>
300
- <ActivityPanel />
301
- </PrototypeShell>
302
- ),
303
- };
304
-
305
- export const Layout4SplitGovernanceInventory: Story = {
306
- name: "Layout 4 · Governance and inventory",
307
- render: () => (
308
- <PrototypeShell eyebrow="Layout 4" title="Governance and inventory">
309
- <CoverageHero />
310
- <Grid columns="auto" minChildWidth="220px" gap="md">
311
- <MetricPanel label="Open findings" value="24" progress={48} variant="warning" />
312
- <MetricPanel label="Blocked releases" value="1" progress={10} variant="danger" />
313
- <MetricPanel label="Tracked components" value="128" progress={88} />
314
- <MetricPanel label="Tracked tokens" value="312" progress={94} />
315
- </Grid>
316
- <Box className={styles.twoColumn}>
317
- <Stack gap="md" className={styles.minWidthZero}>
318
- <AreasTable title="Governance risk" />
319
- <ActivityPanel />
320
- </Stack>
321
- <Stack gap="md">
322
- <InventoryPanel />
323
- <BudgetPanel />
324
- </Stack>
325
- </Box>
326
- </PrototypeShell>
327
- ),
328
- };
@@ -1,283 +0,0 @@
1
- import { GithubLogo, MagnifyingGlass } from "@phosphor-icons/react";
2
- import { Badge } from "../Badge";
3
- import { Box } from "../Box";
4
- import { Button } from "../Button";
5
- import { DataTable, type DataTableColumn } from "../DataTable";
6
- import { Input } from "../Input";
7
- import { Pagination } from "../Pagination";
8
- import { Select } from "../Select";
9
- import { Stack } from "../Stack";
10
- import { Text } from "../Text";
11
- import type { StateVariant } from "./DashboardLayoutPrototypes.shared";
12
- import styles from "./DashboardLayoutPrototypes.module.scss";
13
-
14
- type GateState = "Blocked" | "Review" | "Ready";
15
-
16
- type PullRequest = {
17
- number: number;
18
- title: string;
19
- author: string;
20
- branch: string;
21
- area: string;
22
- coverageDelta: string;
23
- findings: number;
24
- blocking: number;
25
- safeFixes: number;
26
- comments: number;
27
- updated: string;
28
- gate: GateState;
29
- variant: StateVariant;
30
- };
31
-
32
- const pullRequests: PullRequest[] = [
33
- {
34
- number: 248,
35
- title: "Refresh marketing campaign cards",
36
- author: "Maya Chen",
37
- branch: "feat/launch-pages",
38
- area: "Marketing",
39
- coverageDelta: "-7%",
40
- findings: 11,
41
- blocking: 3,
42
- safeFixes: 5,
43
- comments: 8,
44
- updated: "12m ago",
45
- gate: "Blocked",
46
- variant: "error",
47
- },
48
- {
49
- number: 246,
50
- title: "Checkout discount banner",
51
- author: "Jon Bell",
52
- branch: "feat/discount-banner",
53
- area: "Checkout",
54
- coverageDelta: "-1%",
55
- findings: 2,
56
- blocking: 0,
57
- safeFixes: 2,
58
- comments: 2,
59
- updated: "24m ago",
60
- gate: "Review",
61
- variant: "warning",
62
- },
63
- {
64
- number: 241,
65
- title: "Settings billing cleanup",
66
- author: "Priya Shah",
67
- branch: "fix/billing-states",
68
- area: "Admin",
69
- coverageDelta: "+2%",
70
- findings: 1,
71
- blocking: 0,
72
- safeFixes: 1,
73
- comments: 1,
74
- updated: "1h ago",
75
- gate: "Ready",
76
- variant: "success",
77
- },
78
- {
79
- number: 239,
80
- title: "Dashboard topology rollup",
81
- author: "Alex Kim",
82
- branch: "feat/topology-rollup",
83
- area: "Dashboard",
84
- coverageDelta: "+4%",
85
- findings: 4,
86
- blocking: 0,
87
- safeFixes: 3,
88
- comments: 3,
89
- updated: "2h ago",
90
- gate: "Review",
91
- variant: "info",
92
- },
93
- {
94
- number: 237,
95
- title: "Refactor onboarding form states",
96
- author: "Sam Reed",
97
- branch: "chore/onboarding-fields",
98
- area: "Dashboard",
99
- coverageDelta: "0%",
100
- findings: 0,
101
- blocking: 0,
102
- safeFixes: 0,
103
- comments: 0,
104
- updated: "3h ago",
105
- gate: "Ready",
106
- variant: "success",
107
- },
108
- ];
109
-
110
- const prColumns: DataTableColumn<PullRequest>[] = [
111
- {
112
- id: "pull-request",
113
- header: "Pull request",
114
- minSize: 320,
115
- cell: (context) => {
116
- const row = context.row.original as PullRequest;
117
- return (
118
- <Stack gap="none" className={styles.minWidthZero}>
119
- <Text size="sm" weight="semibold" truncate>
120
- {row.title}
121
- </Text>
122
- <Text size="xs" color="tertiary" truncate>
123
- #{row.number} · {row.branch} · {row.author}
124
- </Text>
125
- </Stack>
126
- );
127
- },
128
- },
129
- { accessorKey: "area", header: "Area", size: 128, truncate: true },
130
- { accessorKey: "coverageDelta", header: "Delta", size: 88, align: "right" },
131
- { accessorKey: "findings", header: "Findings", size: 88, align: "right" },
132
- { accessorKey: "comments", header: "Comments", size: 96, align: "right" },
133
- {
134
- accessorKey: "gate",
135
- header: "Gate",
136
- size: 104,
137
- cell: (context) => {
138
- const row = context.row.original as PullRequest;
139
- return (
140
- <Badge variant={row.variant} size="sm">
141
- {row.gate}
142
- </Badge>
143
- );
144
- },
145
- },
146
- { accessorKey: "updated", header: "Updated", size: 96, align: "right" },
147
- {
148
- id: "actions",
149
- header: "Actions",
150
- size: 96,
151
- align: "right",
152
- cell: (context) => {
153
- const row = context.row.original as PullRequest;
154
- return (
155
- <Box className={styles.prRowActions}>
156
- <Button
157
- as="a"
158
- href={`https://github.com/fragments-sdk/fragments/pull/${row.number}`}
159
- target="_blank"
160
- rel="noopener noreferrer"
161
- variant="outlined"
162
- size="xs"
163
- icon
164
- aria-label={`View pull request ${row.number} on GitHub`}
165
- >
166
- <GithubLogo size={14} weight="fill" />
167
- </Button>
168
- <Button
169
- as="a"
170
- href={`/pull-requests/${row.number}`}
171
- variant="secondary"
172
- size="xs"
173
- aria-label={`Open pull request ${row.number} in Fragments`}
174
- >
175
- Open
176
- </Button>
177
- </Box>
178
- );
179
- },
180
- },
181
- ];
182
-
183
- export function PrototypeActions() {
184
- return (
185
- <Stack direction="row" align="center" gap="sm" wrap>
186
- <Button variant="secondary" size="sm">
187
- Learn more
188
- </Button>
189
- </Stack>
190
- );
191
- }
192
-
193
- function PullRequestFilters() {
194
- return (
195
- <Stack gap="sm">
196
- <Box className={styles.prToolbar}>
197
- <Input
198
- aria-label="Search pull requests"
199
- placeholder="Search pull requests..."
200
- size="sm"
201
- startAdornment={<MagnifyingGlass size={16} />}
202
- shortcut="⌘K"
203
- withFieldWrapper={false}
204
- />
205
- <Select aria-label="Gate" defaultValue="open" size="sm">
206
- <Select.Trigger />
207
- <Select.Content>
208
- <Select.Item value="open">Open PRs</Select.Item>
209
- <Select.Item value="blocked">Blocked</Select.Item>
210
- <Select.Item value="ready">Ready</Select.Item>
211
- </Select.Content>
212
- </Select>
213
- <Select aria-label="Area" defaultValue="all" size="sm">
214
- <Select.Trigger />
215
- <Select.Content>
216
- <Select.Item value="all">All areas</Select.Item>
217
- <Select.Item value="marketing">Marketing</Select.Item>
218
- <Select.Item value="checkout">Checkout</Select.Item>
219
- <Select.Item value="dashboard">Dashboard</Select.Item>
220
- </Select.Content>
221
- </Select>
222
- <Select aria-label="Review status" defaultValue="all" size="sm">
223
- <Select.Trigger />
224
- <Select.Content>
225
- <Select.Item value="all">All reviews</Select.Item>
226
- <Select.Item value="comments">Has comments</Select.Item>
227
- <Select.Item value="safe-fixes">Safe fixes</Select.Item>
228
- </Select.Content>
229
- </Select>
230
- </Box>
231
- <Stack direction="row" gap="xs" wrap>
232
- <Badge variant="dim" size="md" active>
233
- Open
234
- </Badge>
235
- <Badge variant="dim" size="md">
236
- Blocking
237
- </Badge>
238
- <Badge variant="dim" size="md">
239
- Needs designer
240
- </Badge>
241
- <Badge variant="dim" size="md">
242
- Safe fixes
243
- </Badge>
244
- </Stack>
245
- </Stack>
246
- );
247
- }
248
-
249
- function PullRequestTable({ density = "condensed" }: { density?: "condensed" | "regular" }) {
250
- return (
251
- <Stack gap="sm">
252
- <DataTable
253
- columns={prColumns}
254
- data={pullRequests}
255
- getRowId={(row) => String(row.number)}
256
- density={density}
257
- bordered
258
- caption="Pull requests"
259
- captionHidden
260
- wrapperClassName={styles.prTable}
261
- />
262
- <Stack direction="row" justify="between" align="center" gap="md" wrap>
263
- <Text size="xs" color="tertiary">
264
- Showing 5 of 28 pull requests
265
- </Text>
266
- <Pagination totalPages={6} defaultPage={1} aria-label="Pull request pages">
267
- <Pagination.Previous />
268
- <Pagination.Items />
269
- <Pagination.Next />
270
- </Pagination>
271
- </Stack>
272
- </Stack>
273
- );
274
- }
275
-
276
- export function PullRequestInbox({ density = "condensed" }: { density?: "condensed" | "regular" }) {
277
- return (
278
- <Stack gap="md">
279
- <PullRequestFilters />
280
- <PullRequestTable density={density} />
281
- </Stack>
282
- );
283
- }