@wallarm-org/claude-design 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/SETUP.md +35 -8
- package/dist/UPDATE.md +11 -9
- package/dist/project/README.md +49 -19
- package/dist/project/app-skeleton.dc.html +268 -0
- package/dist/project/components/AgentAvatar/README.md +5 -5
- package/dist/project/components/AgentGlyph/README.md +3 -3
- package/dist/project/components/AppShell/README.md +1 -1
- package/dist/project/components/AreaChart/README.md +3 -7
- package/dist/project/components/AreaChart/stories.js +1 -1
- package/dist/project/components/Attribute/README.md +1 -1
- package/dist/project/components/Avatar/README.md +1 -1
- package/dist/project/components/Badge/README.md +5 -31
- package/dist/project/components/BarList/README.md +0 -4
- package/dist/project/components/BarList/stories.js +1 -1
- package/dist/project/components/Calendar/README.md +6 -6
- package/dist/project/components/Chart/README.md +0 -4
- package/dist/project/components/Chart/stories.js +1 -1
- package/dist/project/components/Checkbox/README.md +3 -3
- package/dist/project/components/CodeEditor/README.md +8 -8
- package/dist/project/components/CodeEditor/stories.js +4 -4
- package/dist/project/components/CodeEditor/stories.md +0 -4
- package/dist/project/components/CodeSnippet/README.md +0 -8
- package/dist/project/components/CodeSnippet/stories.js +2 -2
- package/dist/project/components/ColumnChart/README.md +1 -5
- package/dist/project/components/ColumnChart/stories.js +1 -1
- package/dist/project/components/DateInput/README.md +6 -6
- package/dist/project/components/DateRangeInput/README.md +1 -1
- package/dist/project/components/Dialog/README.md +1 -1
- package/dist/project/components/Drawer/README.md +1 -1
- package/dist/project/components/DropdownMenu/README.md +4 -4
- package/dist/project/components/FeedbackPulse/README.md +1 -1
- package/dist/project/components/FileUpload/README.md +1 -1
- package/dist/project/components/FilterCascade/README.md +2 -2
- package/dist/project/components/FilterDropdown/README.md +7 -7
- package/dist/project/components/FilterInput/README.md +4 -4
- package/dist/project/components/HorizontalBarStack/README.md +1 -5
- package/dist/project/components/HorizontalBarStack/stories.js +1 -1
- package/dist/project/components/HttpMethod/README.md +1 -1
- package/dist/project/components/ImageCropper/README.md +1 -1
- package/dist/project/components/InlineEdit/README.md +3 -3
- package/dist/project/components/LineChart/README.md +2 -41
- package/dist/project/components/LineChart/stories.js +1 -1
- package/dist/project/components/List/README.md +1 -1
- package/dist/project/components/List/stories.js +1 -1
- package/dist/project/components/Logo/README.md +2 -2
- package/dist/project/components/Metric/README.md +0 -9
- package/dist/project/components/Metric/stories.js +1 -1
- package/dist/project/components/NotificationCenter/README.md +1 -1
- package/dist/project/components/NumberInput/README.md +3 -3
- package/dist/project/components/OverflowList/README.md +1 -1
- package/dist/project/components/OverflowTooltip/README.md +1 -1
- package/dist/project/components/Overview/README.md +0 -4
- package/dist/project/components/Overview/stories.js +1 -1
- package/dist/project/components/Pagination/README.md +3 -3
- package/dist/project/components/ParameterPath/README.md +2 -2
- package/dist/project/components/PasswordComplexity/README.md +1 -1
- package/dist/project/components/PieChart/README.md +1 -5
- package/dist/project/components/PieChart/stories.js +1 -1
- package/dist/project/components/Popover/README.md +2 -2
- package/dist/project/components/Progress/README.md +1 -1
- package/dist/project/components/RemoteShell/README.md +1 -1
- package/dist/project/components/ScrollArea/README.md +1 -1
- package/dist/project/components/Select/README.md +8 -8
- package/dist/project/components/Slider/README.md +1 -1
- package/dist/project/components/SplashScreen/README.md +2 -2
- package/dist/project/components/Stepper/README.md +3 -3
- package/dist/project/components/Switch/README.md +2 -2
- package/dist/project/components/Table/README.md +15 -15
- package/dist/project/components/Tabs/README.md +1 -1
- package/dist/project/components/TimeInput/README.md +6 -6
- package/dist/project/components/Toast/README.md +1 -1
- package/dist/project/components/Tooltip/README.md +2 -2
- package/dist/project/components/UTILITIES.md +3 -3
- package/dist/project/components/WallyAssistant/README.md +12 -12
- package/dist/project/components/WallyIcon/README.md +1 -1
- package/dist/project/components/bundle.css +15 -6
- package/dist/project/components/bundle.js +4 -4
- package/dist/project/components/index.d.ts +2 -2
- package/dist/project/design-system.json +4 -4
- package/dist/project/sampler.dc.html +5 -7
- package/dist/project/tokens.json +2 -2
- package/dist/wallarm-app.dc.html +269 -0
- package/dist/wallarm-sampler.dc.html +5 -7
- package/package.json +4 -4
|
@@ -17284,7 +17284,7 @@ export interface MetricValueProps extends HTMLAttributes<HTMLSpanElement> {
|
|
|
17284
17284
|
export declare const MetricValue: FC<MetricValueProps>;
|
|
17285
17285
|
|
|
17286
17286
|
// components/SimpleCharts/Metric/classes.d.ts
|
|
17287
|
-
export declare const metricRootClasses = "flex flex-col items-start px-16 py-8 w-full";
|
|
17287
|
+
export declare const metricRootClasses = "mt-auto flex flex-col items-start px-16 py-8 w-full";
|
|
17288
17288
|
export declare const metricHeaderClasses = "flex items-baseline gap-8";
|
|
17289
17289
|
export declare const metricValueClasses = "font-sans-display text-3xl font-medium leading-3xl text-text-primary";
|
|
17290
17290
|
export declare const metricTotalClasses = "-ml-2 flex items-baseline gap-6";
|
|
@@ -17292,7 +17292,7 @@ export declare const metricTotalValueClasses = "font-sans-display text-lg font-m
|
|
|
17292
17292
|
export declare const metricTotalWordClasses = "text-xs font-normal text-text-secondary";
|
|
17293
17293
|
export declare const metricCaptionClasses = "text-xs text-text-secondary";
|
|
17294
17294
|
export declare const metricSkeletonLineClasses = "w-full py-4";
|
|
17295
|
-
export declare const metricSparklineClasses = "
|
|
17295
|
+
export declare const metricSparklineClasses = "w-full px-px";
|
|
17296
17296
|
export declare const metricSparklinePlotClasses = "relative h-48";
|
|
17297
17297
|
export declare const metricSparklineRulerClasses = "pointer-events-none absolute top-0 h-full w-px -translate-x-1/2 overflow-visible";
|
|
17298
17298
|
export declare const metricSparklinePopoverClasses = "pointer-events-none fixed z-(--tooltip-z-index)";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"layout": "files",
|
|
4
4
|
"createdOnFiles": {
|
|
5
5
|
"v": 1,
|
|
6
|
-
"at": "2026-11-
|
|
6
|
+
"at": "2026-11-06T16:22:32Z"
|
|
7
7
|
},
|
|
8
8
|
"title": "Wallarm Design System",
|
|
9
9
|
"namespace": "WallarmDS",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"lastChange": {
|
|
30
30
|
"by": "Wallarm",
|
|
31
|
-
"at": "2026-11-
|
|
32
|
-
"via": "GitHub · wallarm/design-system@
|
|
33
|
-
"note": "v4.
|
|
31
|
+
"at": "2026-11-06T16:22:32Z",
|
|
32
|
+
"via": "GitHub · wallarm/design-system@79b1208b",
|
|
33
|
+
"note": "v4.10.0: 532 colors, 120 component guides, 582 icons."
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
</x-import>
|
|
53
53
|
</x-import>
|
|
54
54
|
<x-import component-from-global-scope="WallarmDS.PageContent">
|
|
55
|
-
<!-- Entity table: Table draws its own frame and padding;
|
|
55
|
+
<!-- Entity table: Table draws its own frame and padding; row actions live in the master cell. -->
|
|
56
56
|
<x-import component-from-global-scope="WallarmDS.Table" aria-label="Users" data="{{rows}}" columns="{{columns}}" get-row-id="{{getRowId}}" active-row-id="{{activeRowId}}">
|
|
57
57
|
<x-import component-from-global-scope="WallarmDS.TableEmptyState">
|
|
58
58
|
<!-- No results: collection-empty inside a table, a reset action, never a create action. -->
|
|
@@ -172,8 +172,9 @@ class Component extends DCLogic {
|
|
|
172
172
|
return (status === 'all' || user.status === status) &&
|
|
173
173
|
(user.name.toLowerCase().includes(needle) || user.email.toLowerCase().includes(needle));
|
|
174
174
|
});
|
|
175
|
-
//
|
|
176
|
-
var rowMenu = function (
|
|
175
|
+
// Row menu in the master cell: meta.renderMenuAction on the first column, never a trailing actions column.
|
|
176
|
+
var rowMenu = function (row) {
|
|
177
|
+
var user = row.original;
|
|
177
178
|
return h(DS.DropdownMenu, null,
|
|
178
179
|
h(DS.DropdownMenuTrigger, { asChild: true },
|
|
179
180
|
h(DS.Button, { variant: 'ghost', color: 'neutral', size: 'small', 'aria-label': 'Actions for ' + user.name },
|
|
@@ -189,7 +190,7 @@ class Component extends DCLogic {
|
|
|
189
190
|
return h(DS.Avatar, { size: 'md' },
|
|
190
191
|
h(DS.AvatarFallback, { name: user.name }),
|
|
191
192
|
h(DS.AvatarContent, null, h(DS.AvatarName, null, user.name), h(DS.AvatarDescription, null, user.email)));
|
|
192
|
-
} },
|
|
193
|
+
}, meta: { renderMenuAction: rowMenu } },
|
|
193
194
|
{ accessorKey: 'status', header: 'Status', size: 140, cell: function (ctx) {
|
|
194
195
|
var s = STATUS[ctx.row.original.status];
|
|
195
196
|
return h(DS.Badge, { variant: 'dotted', type: 'secondary', color: s.color }, s.label);
|
|
@@ -199,9 +200,6 @@ class Component extends DCLogic {
|
|
|
199
200
|
} },
|
|
200
201
|
{ accessorKey: 'lastActiveAt', header: 'Last active', size: 200, cell: function (ctx) {
|
|
201
202
|
return h(DS.FormatDateTime, { value: ctx.row.original.lastActiveAt, format: 'relative' });
|
|
202
|
-
} },
|
|
203
|
-
{ id: 'actions', header: '', size: 60, minSize: 60, enableHiding: false, enableSorting: false, cell: function (ctx) {
|
|
204
|
-
return rowMenu(ctx.row.original);
|
|
205
203
|
} }
|
|
206
204
|
];
|
|
207
205
|
return {
|
package/dist/project/tokens.json
CHANGED
|
@@ -5187,7 +5187,7 @@
|
|
|
5187
5187
|
"meta": {
|
|
5188
5188
|
"source": "github",
|
|
5189
5189
|
"repo": "wallarm/design-system",
|
|
5190
|
-
"ref": "mcp-v3.
|
|
5190
|
+
"ref": "mcp-v3.4.0@79b1208bdb9168e9a7d15dc19e8fc90c7256df5b",
|
|
5191
5191
|
"package": "packages/design-system",
|
|
5192
5192
|
"paths": {
|
|
5193
5193
|
"tokens": [
|
|
@@ -5230,6 +5230,6 @@
|
|
|
5230
5230
|
"src/theme/fonts/GeistMono-Variable.woff2"
|
|
5231
5231
|
]
|
|
5232
5232
|
},
|
|
5233
|
-
"synced": "2026-11-
|
|
5233
|
+
"synced": "2026-11-06T16:22:32Z"
|
|
5234
5234
|
}
|
|
5235
5235
|
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Wallarm app</title>
|
|
6
|
+
<script src="./support.js"></script>
|
|
7
|
+
<link rel="stylesheet" href="ds/wallarm-design-system/tokens.css">
|
|
8
|
+
<link rel="stylesheet" href="ds/wallarm-design-system/components/bundle.css">
|
|
9
|
+
<script src="ds/wallarm-design-system/components/bundle.js"></script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<!-- App skeleton: the console frame (AppShell) with a product's RemoteShell. Customize it by
|
|
13
|
+
editing only the APP object at the top of the script; design screens inside its Page. -->
|
|
14
|
+
<x-dc>
|
|
15
|
+
<x-import component-from-global-scope="WallarmDS.Root" theme="light">
|
|
16
|
+
<x-import component-from-global-scope="WallarmDS.AppShell">
|
|
17
|
+
<x-import component-from-global-scope="WallarmDS.AppShellHeader">
|
|
18
|
+
<x-import component-from-global-scope="WallarmDS.TopHeader">
|
|
19
|
+
<x-import component-from-global-scope="WallarmDS.TopHeaderLogo" href="/" on-click="{{onRailClick}}">
|
|
20
|
+
<x-import component-from-global-scope="WallarmDS.Logo" size="md"></x-import>
|
|
21
|
+
</x-import>
|
|
22
|
+
<!-- Header actions, in this order: search, separator, tenant, assistant, notifications, help. -->
|
|
23
|
+
<x-import component-from-global-scope="WallarmDS.TopHeaderActions">
|
|
24
|
+
<x-import component-from-global-scope="WallarmDS.Button" variant="ghost" color="neutral" size="small" aria-label="Search">
|
|
25
|
+
<x-import component-from-global-scope="WallarmDS.Icons.Search"></x-import>
|
|
26
|
+
</x-import>
|
|
27
|
+
<x-import component-from-global-scope="WallarmDS.TopHeaderSeparator"></x-import>
|
|
28
|
+
<x-import component-from-global-scope="WallarmDS.Button" variant="ghost" color="neutral" size="small" children="{{tenantLabel}}"></x-import>
|
|
29
|
+
<x-import component-from-global-scope="WallarmDS.ChatTrigger"></x-import>
|
|
30
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenter" data-testid="notifications">
|
|
31
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterTrigger" count="{{unreadCount}}"></x-import>
|
|
32
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterContent">
|
|
33
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterHeader">
|
|
34
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterTitle"></x-import>
|
|
35
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterHeaderActions">
|
|
36
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterHeaderAction">Mark all as read</x-import>
|
|
37
|
+
</x-import>
|
|
38
|
+
</x-import>
|
|
39
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterTabs" default-value="new">
|
|
40
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterTabsList">
|
|
41
|
+
<x-import component-from-global-scope="WallarmDS.TabsTrigger" value="new">New <x-import component-from-global-scope="WallarmDS.NumericBadge" size="small">2</x-import></x-import>
|
|
42
|
+
<x-import component-from-global-scope="WallarmDS.TabsTrigger" value="read">Read</x-import>
|
|
43
|
+
</x-import>
|
|
44
|
+
<x-import component-from-global-scope="WallarmDS.TabsContent" value="new">
|
|
45
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterBody">
|
|
46
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterList">
|
|
47
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItem" unread="{{yes}}">
|
|
48
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTitle">New attack detected on api.example.com</x-import>
|
|
49
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTime" value="{{sentAt1}}"></x-import>
|
|
50
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemDescription">214 SQL injection attempts from 12 IPs in the last 10 minutes.</x-import>
|
|
51
|
+
</x-import>
|
|
52
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItem" unread="{{yes}}">
|
|
53
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTitle">Node wallarm-node-3 is offline</x-import>
|
|
54
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTime" value="{{sentAt2}}"></x-import>
|
|
55
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemDescription">No heartbeat for 15 minutes. Traffic fails over to wallarm-node-1.</x-import>
|
|
56
|
+
</x-import>
|
|
57
|
+
</x-import>
|
|
58
|
+
</x-import>
|
|
59
|
+
</x-import>
|
|
60
|
+
<x-import component-from-global-scope="WallarmDS.TabsContent" value="read">
|
|
61
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterBody">
|
|
62
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterList">
|
|
63
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItem">
|
|
64
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTitle">Weekly API discovery report is ready</x-import>
|
|
65
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemTime" value="{{sentAt3}}"></x-import>
|
|
66
|
+
<x-import component-from-global-scope="WallarmDS.NotificationCenterItemDescription">38 new endpoints this week, 5 of them handling sensitive data.</x-import>
|
|
67
|
+
</x-import>
|
|
68
|
+
</x-import>
|
|
69
|
+
</x-import>
|
|
70
|
+
</x-import>
|
|
71
|
+
</x-import>
|
|
72
|
+
</x-import>
|
|
73
|
+
</x-import>
|
|
74
|
+
<x-import component-from-global-scope="WallarmDS.Button" variant="ghost" color="neutral" size="small" aria-label="Help">
|
|
75
|
+
<x-import component-from-global-scope="WallarmDS.Icons.CircleHelp"></x-import>
|
|
76
|
+
</x-import>
|
|
77
|
+
</x-import>
|
|
78
|
+
</x-import>
|
|
79
|
+
</x-import>
|
|
80
|
+
<x-import component-from-global-scope="WallarmDS.AppShellRail">
|
|
81
|
+
<x-import component-from-global-scope="WallarmDS.NavRail" data-testid="nav-rail">
|
|
82
|
+
<!-- Home, then the products from APP.rail; the one at APP.nav.productPath is active. -->
|
|
83
|
+
<x-import component-from-global-scope="WallarmDS.NavRailBody" children="{{railItems}}"></x-import>
|
|
84
|
+
<!-- Settings and the account menu always live in the rail footer. -->
|
|
85
|
+
<x-import component-from-global-scope="WallarmDS.NavRailFooter">
|
|
86
|
+
<x-import component-from-global-scope="WallarmDS.NavRailItem" href="/settings" icon="{{settingsIcon}}" label="Settings" on-click="{{onRailClick}}"></x-import>
|
|
87
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenu" positioning="{{accountMenuPositioning}}">
|
|
88
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuTrigger">
|
|
89
|
+
<x-import component-from-global-scope="WallarmDS.NavRailItem" icon="{{userIcon}}" label="{{userName}}" avatar="{{yes}}"></x-import>
|
|
90
|
+
</x-import>
|
|
91
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuContent" class-name="w-200">
|
|
92
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItem">
|
|
93
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItemIcon">
|
|
94
|
+
<x-import component-from-global-scope="WallarmDS.Icons.Settings"></x-import>
|
|
95
|
+
</x-import>
|
|
96
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItemText">Profile settings</x-import>
|
|
97
|
+
</x-import>
|
|
98
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuSeparator"></x-import>
|
|
99
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItem">
|
|
100
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItemIcon">
|
|
101
|
+
<x-import component-from-global-scope="WallarmDS.Icons.LogOut"></x-import>
|
|
102
|
+
</x-import>
|
|
103
|
+
<x-import component-from-global-scope="WallarmDS.DropdownMenuItemText">Sign out</x-import>
|
|
104
|
+
</x-import>
|
|
105
|
+
</x-import>
|
|
106
|
+
</x-import>
|
|
107
|
+
</x-import>
|
|
108
|
+
</x-import>
|
|
109
|
+
</x-import>
|
|
110
|
+
<x-import component-from-global-scope="WallarmDS.AppShellRemote">
|
|
111
|
+
<!-- The product: RemoteShell builds the panel and the trail from APP.nav; the URL is its only state. -->
|
|
112
|
+
<x-import component-from-global-scope="WallarmDS.RemoteShell" config="{{navConfig}}" base-path="{{productPath}}" pathname="{{pathname}}" on-navigate="{{onNavigate}}" data-testid="product-shell">
|
|
113
|
+
<x-import component-from-global-scope="WallarmDS.RemoteShellPanel"></x-import>
|
|
114
|
+
<x-import component-from-global-scope="WallarmDS.RemoteShellBreadcrumb"></x-import>
|
|
115
|
+
<x-import component-from-global-scope="WallarmDS.RemoteShellContent">
|
|
116
|
+
<!-- Design the requested screen here: keep PageHeader, add PageDescription and a PageToolbar before PageContent, fixed-height on a list, and replace PageContent's EmptyState. -->
|
|
117
|
+
<x-import component-from-global-scope="WallarmDS.Page" name="{{pageName}}" full-size="{{yes}}" data-testid="page">
|
|
118
|
+
<x-import component-from-global-scope="WallarmDS.PageHeader">
|
|
119
|
+
<x-import component-from-global-scope="WallarmDS.PageHeaderGroup">
|
|
120
|
+
<x-import component-from-global-scope="WallarmDS.PageTitle" children="{{pageTitle}}"></x-import>
|
|
121
|
+
</x-import>
|
|
122
|
+
<x-import component-from-global-scope="WallarmDS.PageActions" children="{{pageActions}}"></x-import>
|
|
123
|
+
</x-import>
|
|
124
|
+
<x-import component-from-global-scope="WallarmDS.PageContent">
|
|
125
|
+
<x-import component-from-global-scope="WallarmDS.EmptyState" type="collection-empty">
|
|
126
|
+
<x-import component-from-global-scope="WallarmDS.EmptyStateIllustration">
|
|
127
|
+
<x-import component-from-global-scope="WallarmDS.Icons.PenTool"></x-import>
|
|
128
|
+
</x-import>
|
|
129
|
+
<x-import component-from-global-scope="WallarmDS.EmptyStateMessage">
|
|
130
|
+
<x-import component-from-global-scope="WallarmDS.EmptyStateTitle">Ask Claude to design this screen</x-import>
|
|
131
|
+
<x-import component-from-global-scope="WallarmDS.EmptyStateDescription">Describe what this page shows and Claude builds it here, inside the app frame.</x-import>
|
|
132
|
+
</x-import>
|
|
133
|
+
</x-import>
|
|
134
|
+
</x-import>
|
|
135
|
+
</x-import>
|
|
136
|
+
</x-import>
|
|
137
|
+
</x-import>
|
|
138
|
+
</x-import>
|
|
139
|
+
</x-import>
|
|
140
|
+
</x-import>
|
|
141
|
+
</x-dc>
|
|
142
|
+
<script type="text/x-dc" data-dc-script data-props="{"$preview":{"width":1440,"height":900}}">
|
|
143
|
+
/* ===== APP: the person's product. Change the shell only here; everything below reads from it.
|
|
144
|
+
A screen's own data (rows, counts) goes in renderVals(), not here. =====
|
|
145
|
+
rail: the Wallarm products in the 1st rail (label, path, icon). The one whose path is
|
|
146
|
+
nav.productPath is active; Home and Settings are always there.
|
|
147
|
+
nav: the product's RemoteShell NavConfig. Node types: 'link' (id, label, path, icon?),
|
|
148
|
+
'group' (id, label, icon?, defaultExpanded?, children), 'section-header' (id, label),
|
|
149
|
+
'drill' only when asked. ids and paths are kebab-case; a path is one segment.
|
|
150
|
+
Icons are WallarmDS.Icons names as strings. A link may have `action`: the label of
|
|
151
|
+
its page's primary button.
|
|
152
|
+
start: the path of the link the board opens on: the first link, or the screen this board designs.
|
|
153
|
+
tenant, user: the header's tenant switcher and the account menu's name. */
|
|
154
|
+
var APP = {
|
|
155
|
+
tenant: 'Acme Bank',
|
|
156
|
+
user: 'Maria Lopez',
|
|
157
|
+
rail: [
|
|
158
|
+
{ label: 'API Security', path: '/api-security', icon: 'ShieldCheck' },
|
|
159
|
+
{ label: 'Edge', path: '/edge', icon: 'Cloud' },
|
|
160
|
+
{ label: 'Security Testing', path: '/security-testing', icon: 'FlaskConical' },
|
|
161
|
+
{ label: 'AI Hypervisor', path: '/ai-hypervisor', icon: 'Bot' }
|
|
162
|
+
],
|
|
163
|
+
nav: {
|
|
164
|
+
productLabel: 'API Security',
|
|
165
|
+
productPath: '/api-security',
|
|
166
|
+
items: [
|
|
167
|
+
{ type: 'link', id: 'overview', label: 'Overview', path: 'overview', icon: 'Activity' },
|
|
168
|
+
{ type: 'link', id: 'api-discovery', label: 'API Discovery', path: 'api-discovery', icon: 'Search' },
|
|
169
|
+
{ type: 'link', id: 'api-specifications', label: 'API Specifications', path: 'api-specifications', icon: 'Layers', action: 'Upload specification', dividerAfter: true },
|
|
170
|
+
{ type: 'section-header', id: 'detect', label: 'Detect & Respond' },
|
|
171
|
+
{ type: 'group', id: 'events', label: 'Events', icon: 'Zap', defaultExpanded: true, children: [
|
|
172
|
+
{ type: 'link', id: 'attacks', label: 'Attacks', path: 'attacks' },
|
|
173
|
+
{ type: 'link', id: 'incidents', label: 'Incidents', path: 'incidents' },
|
|
174
|
+
{ type: 'link', id: 'sessions', label: 'Sessions', path: 'sessions' }
|
|
175
|
+
] }
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
start: 'overview'
|
|
179
|
+
};
|
|
180
|
+
/* ===== End of APP. ===== */
|
|
181
|
+
|
|
182
|
+
var minutesAgo = function (minutes) { return new Date(Date.now() - minutes * 60000); };
|
|
183
|
+
var warned = {};
|
|
184
|
+
|
|
185
|
+
class Component extends DCLogic {
|
|
186
|
+
constructor(props) {
|
|
187
|
+
super(props);
|
|
188
|
+
this.state = { pathname: APP.nav.productPath + '/' + (APP.start || firstLink(APP.nav.items).path) };
|
|
189
|
+
}
|
|
190
|
+
renderVals() {
|
|
191
|
+
var h = React.createElement;
|
|
192
|
+
var DS = WallarmDS;
|
|
193
|
+
var self = this;
|
|
194
|
+
var icon = function (name) {
|
|
195
|
+
if (!name) return undefined;
|
|
196
|
+
if (!DS.Icons[name] && !warned[name]) {
|
|
197
|
+
warned[name] = true;
|
|
198
|
+
console.warn('[WallarmDS] icon "' + name + '" is not in WallarmDS.Icons; fix it in APP.');
|
|
199
|
+
}
|
|
200
|
+
return DS.Icons[name];
|
|
201
|
+
};
|
|
202
|
+
// NavConfig with icon names resolved; `action` stays out of the config.
|
|
203
|
+
var toNode = function (node) {
|
|
204
|
+
var out = {};
|
|
205
|
+
for (var key in node) if (key !== 'action') out[key] = node[key];
|
|
206
|
+
if (node.icon) out.icon = icon(node.icon);
|
|
207
|
+
if (node.children) out.children = node.children.map(toNode);
|
|
208
|
+
return out;
|
|
209
|
+
};
|
|
210
|
+
var segments = this.state.pathname.split('/').filter(Boolean);
|
|
211
|
+
var page = findLink(APP.nav.items, segments[segments.length - 1]) || firstLink(APP.nav.items);
|
|
212
|
+
var onRailClick = function (event) { event.preventDefault(); };
|
|
213
|
+
var railItems = [
|
|
214
|
+
h(DS.NavRailItem, { key: 'home', href: '/', icon: DS.Icons.Home, label: 'Home', onClick: onRailClick }),
|
|
215
|
+
h(DS.NavRailSeparator, { key: 'separator' })
|
|
216
|
+
].concat(APP.rail.map(function (product) {
|
|
217
|
+
return h(DS.NavRailItem, {
|
|
218
|
+
key: product.path,
|
|
219
|
+
href: product.path,
|
|
220
|
+
icon: icon(product.icon) || DS.Icons.Layers,
|
|
221
|
+
label: product.label,
|
|
222
|
+
active: product.path === APP.nav.productPath,
|
|
223
|
+
onClick: onRailClick
|
|
224
|
+
});
|
|
225
|
+
}));
|
|
226
|
+
return {
|
|
227
|
+
yes: true,
|
|
228
|
+
tenantLabel: [APP.tenant, h(DS.Icons.ChevronUpDown, { key: 'chevron' })],
|
|
229
|
+
unreadCount: 2,
|
|
230
|
+
sentAt1: minutesAgo(3),
|
|
231
|
+
sentAt2: minutesAgo(22),
|
|
232
|
+
sentAt3: minutesAgo(60 * 24),
|
|
233
|
+
railItems: railItems,
|
|
234
|
+
onRailClick: onRailClick,
|
|
235
|
+
settingsIcon: DS.Icons.Settings,
|
|
236
|
+
userIcon: DS.Icons.UserRound,
|
|
237
|
+
userName: APP.user,
|
|
238
|
+
accountMenuPositioning: { placement: 'right-end', gutter: 6, offset: { crossAxis: 12 } },
|
|
239
|
+
navConfig: { productLabel: APP.nav.productLabel, productPath: APP.nav.productPath, items: APP.nav.items.map(toNode) },
|
|
240
|
+
productPath: APP.nav.productPath,
|
|
241
|
+
pathname: this.state.pathname,
|
|
242
|
+
onNavigate: function (to) { self.setState({ pathname: to }); },
|
|
243
|
+
pageName: page.id,
|
|
244
|
+
pageTitle: page.label,
|
|
245
|
+
pageActions: page.action ? h(DS.Button, { size: 'medium' }, page.action) : null
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// The first link in menu order, and the link whose path is `path`, through groups and drills.
|
|
251
|
+
function firstLink(items) {
|
|
252
|
+
for (var i = 0; i < items.length; i++) {
|
|
253
|
+
if (items[i].type === 'link') return items[i];
|
|
254
|
+
var inner = items[i].children && firstLink(items[i].children);
|
|
255
|
+
if (inner) return inner;
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
function findLink(items, path) {
|
|
260
|
+
for (var i = 0; i < items.length; i++) {
|
|
261
|
+
if (items[i].type === 'link' && items[i].path === path) return items[i];
|
|
262
|
+
var inner = items[i].children && findLink(items[i].children, path);
|
|
263
|
+
if (inner) return inner;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
</script>
|
|
268
|
+
</body>
|
|
269
|
+
</html>
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
</x-import>
|
|
54
54
|
</x-import>
|
|
55
55
|
<x-import component-from-global-scope="WallarmDS.PageContent">
|
|
56
|
-
<!-- Entity table: Table draws its own frame and padding;
|
|
56
|
+
<!-- Entity table: Table draws its own frame and padding; row actions live in the master cell. -->
|
|
57
57
|
<x-import component-from-global-scope="WallarmDS.Table" aria-label="Users" data="{{rows}}" columns="{{columns}}" get-row-id="{{getRowId}}" active-row-id="{{activeRowId}}">
|
|
58
58
|
<x-import component-from-global-scope="WallarmDS.TableEmptyState">
|
|
59
59
|
<!-- No results: collection-empty inside a table, a reset action, never a create action. -->
|
|
@@ -173,8 +173,9 @@ class Component extends DCLogic {
|
|
|
173
173
|
return (status === 'all' || user.status === status) &&
|
|
174
174
|
(user.name.toLowerCase().includes(needle) || user.email.toLowerCase().includes(needle));
|
|
175
175
|
});
|
|
176
|
-
//
|
|
177
|
-
var rowMenu = function (
|
|
176
|
+
// Row menu in the master cell: meta.renderMenuAction on the first column, never a trailing actions column.
|
|
177
|
+
var rowMenu = function (row) {
|
|
178
|
+
var user = row.original;
|
|
178
179
|
return h(DS.DropdownMenu, null,
|
|
179
180
|
h(DS.DropdownMenuTrigger, { asChild: true },
|
|
180
181
|
h(DS.Button, { variant: 'ghost', color: 'neutral', size: 'small', 'aria-label': 'Actions for ' + user.name },
|
|
@@ -190,7 +191,7 @@ class Component extends DCLogic {
|
|
|
190
191
|
return h(DS.Avatar, { size: 'md' },
|
|
191
192
|
h(DS.AvatarFallback, { name: user.name }),
|
|
192
193
|
h(DS.AvatarContent, null, h(DS.AvatarName, null, user.name), h(DS.AvatarDescription, null, user.email)));
|
|
193
|
-
} },
|
|
194
|
+
}, meta: { renderMenuAction: rowMenu } },
|
|
194
195
|
{ accessorKey: 'status', header: 'Status', size: 140, cell: function (ctx) {
|
|
195
196
|
var s = STATUS[ctx.row.original.status];
|
|
196
197
|
return h(DS.Badge, { variant: 'dotted', type: 'secondary', color: s.color }, s.label);
|
|
@@ -200,9 +201,6 @@ class Component extends DCLogic {
|
|
|
200
201
|
} },
|
|
201
202
|
{ accessorKey: 'lastActiveAt', header: 'Last active', size: 200, cell: function (ctx) {
|
|
202
203
|
return h(DS.FormatDateTime, { value: ctx.row.original.lastActiveAt, format: 'relative' });
|
|
203
|
-
} },
|
|
204
|
-
{ id: 'actions', header: '', size: 60, minSize: 60, enableHiding: false, enableSorting: false, cell: function (ctx) {
|
|
205
|
-
return rowMenu(ctx.row.original);
|
|
206
204
|
} }
|
|
207
205
|
];
|
|
208
206
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wallarm-org/claude-design",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "Installs Wallarm Design System in Claude Design: `npx -y @wallarm-org/claude-design@latest export`",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"tsx": "4.23.15",
|
|
52
52
|
"tw-animate-css": "1.4.0",
|
|
53
53
|
"typescript": "7.0.2",
|
|
54
|
-
"@wallarm-org/design-system": "4.
|
|
55
|
-
"@wallarm-org/
|
|
56
|
-
"@wallarm-org/
|
|
54
|
+
"@wallarm-org/design-system": "4.10.0",
|
|
55
|
+
"@wallarm-org/mcp-core": "0.1.0",
|
|
56
|
+
"@wallarm-org/typescript-config": "0.0.0"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"export": "tsx src/build.ts",
|