@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.
Files changed (85) hide show
  1. package/README.md +6 -5
  2. package/dist/SETUP.md +35 -8
  3. package/dist/UPDATE.md +11 -9
  4. package/dist/project/README.md +49 -19
  5. package/dist/project/app-skeleton.dc.html +268 -0
  6. package/dist/project/components/AgentAvatar/README.md +5 -5
  7. package/dist/project/components/AgentGlyph/README.md +3 -3
  8. package/dist/project/components/AppShell/README.md +1 -1
  9. package/dist/project/components/AreaChart/README.md +3 -7
  10. package/dist/project/components/AreaChart/stories.js +1 -1
  11. package/dist/project/components/Attribute/README.md +1 -1
  12. package/dist/project/components/Avatar/README.md +1 -1
  13. package/dist/project/components/Badge/README.md +5 -31
  14. package/dist/project/components/BarList/README.md +0 -4
  15. package/dist/project/components/BarList/stories.js +1 -1
  16. package/dist/project/components/Calendar/README.md +6 -6
  17. package/dist/project/components/Chart/README.md +0 -4
  18. package/dist/project/components/Chart/stories.js +1 -1
  19. package/dist/project/components/Checkbox/README.md +3 -3
  20. package/dist/project/components/CodeEditor/README.md +8 -8
  21. package/dist/project/components/CodeEditor/stories.js +4 -4
  22. package/dist/project/components/CodeEditor/stories.md +0 -4
  23. package/dist/project/components/CodeSnippet/README.md +0 -8
  24. package/dist/project/components/CodeSnippet/stories.js +2 -2
  25. package/dist/project/components/ColumnChart/README.md +1 -5
  26. package/dist/project/components/ColumnChart/stories.js +1 -1
  27. package/dist/project/components/DateInput/README.md +6 -6
  28. package/dist/project/components/DateRangeInput/README.md +1 -1
  29. package/dist/project/components/Dialog/README.md +1 -1
  30. package/dist/project/components/Drawer/README.md +1 -1
  31. package/dist/project/components/DropdownMenu/README.md +4 -4
  32. package/dist/project/components/FeedbackPulse/README.md +1 -1
  33. package/dist/project/components/FileUpload/README.md +1 -1
  34. package/dist/project/components/FilterCascade/README.md +2 -2
  35. package/dist/project/components/FilterDropdown/README.md +7 -7
  36. package/dist/project/components/FilterInput/README.md +4 -4
  37. package/dist/project/components/HorizontalBarStack/README.md +1 -5
  38. package/dist/project/components/HorizontalBarStack/stories.js +1 -1
  39. package/dist/project/components/HttpMethod/README.md +1 -1
  40. package/dist/project/components/ImageCropper/README.md +1 -1
  41. package/dist/project/components/InlineEdit/README.md +3 -3
  42. package/dist/project/components/LineChart/README.md +2 -41
  43. package/dist/project/components/LineChart/stories.js +1 -1
  44. package/dist/project/components/List/README.md +1 -1
  45. package/dist/project/components/List/stories.js +1 -1
  46. package/dist/project/components/Logo/README.md +2 -2
  47. package/dist/project/components/Metric/README.md +0 -9
  48. package/dist/project/components/Metric/stories.js +1 -1
  49. package/dist/project/components/NotificationCenter/README.md +1 -1
  50. package/dist/project/components/NumberInput/README.md +3 -3
  51. package/dist/project/components/OverflowList/README.md +1 -1
  52. package/dist/project/components/OverflowTooltip/README.md +1 -1
  53. package/dist/project/components/Overview/README.md +0 -4
  54. package/dist/project/components/Overview/stories.js +1 -1
  55. package/dist/project/components/Pagination/README.md +3 -3
  56. package/dist/project/components/ParameterPath/README.md +2 -2
  57. package/dist/project/components/PasswordComplexity/README.md +1 -1
  58. package/dist/project/components/PieChart/README.md +1 -5
  59. package/dist/project/components/PieChart/stories.js +1 -1
  60. package/dist/project/components/Popover/README.md +2 -2
  61. package/dist/project/components/Progress/README.md +1 -1
  62. package/dist/project/components/RemoteShell/README.md +1 -1
  63. package/dist/project/components/ScrollArea/README.md +1 -1
  64. package/dist/project/components/Select/README.md +8 -8
  65. package/dist/project/components/Slider/README.md +1 -1
  66. package/dist/project/components/SplashScreen/README.md +2 -2
  67. package/dist/project/components/Stepper/README.md +3 -3
  68. package/dist/project/components/Switch/README.md +2 -2
  69. package/dist/project/components/Table/README.md +15 -15
  70. package/dist/project/components/Tabs/README.md +1 -1
  71. package/dist/project/components/TimeInput/README.md +6 -6
  72. package/dist/project/components/Toast/README.md +1 -1
  73. package/dist/project/components/Tooltip/README.md +2 -2
  74. package/dist/project/components/UTILITIES.md +3 -3
  75. package/dist/project/components/WallyAssistant/README.md +12 -12
  76. package/dist/project/components/WallyIcon/README.md +1 -1
  77. package/dist/project/components/bundle.css +15 -6
  78. package/dist/project/components/bundle.js +4 -4
  79. package/dist/project/components/index.d.ts +2 -2
  80. package/dist/project/design-system.json +4 -4
  81. package/dist/project/sampler.dc.html +5 -7
  82. package/dist/project/tokens.json +2 -2
  83. package/dist/wallarm-app.dc.html +269 -0
  84. package/dist/wallarm-sampler.dc.html +5 -7
  85. 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 = "mt-auto w-full px-px";
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-05T18:34:22Z"
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-05T18:34:22Z",
32
- "via": "GitHub · wallarm/design-system@19a4e1b8",
33
- "note": "v4.8.0: 532 colors, 120 component guides, 582 icons."
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; the actions column is always visible. -->
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
- // Always-visible row menu: a trailing display column, not meta.renderMenuAction.
176
- var rowMenu = function (user) {
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 {
@@ -5187,7 +5187,7 @@
5187
5187
  "meta": {
5188
5188
  "source": "github",
5189
5189
  "repo": "wallarm/design-system",
5190
- "ref": "mcp-v3.3.0@19a4e1b839f762f4f3147a144988f041e2960cba",
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-05T18:34:22Z"
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="{&quot;$preview&quot;:{&quot;width&quot;:1440,&quot;height&quot;: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; the actions column is always visible. -->
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
- // Always-visible row menu: a trailing display column, not meta.renderMenuAction.
177
- var rowMenu = function (user) {
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.8.0",
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.8.0",
55
- "@wallarm-org/typescript-config": "0.0.0",
56
- "@wallarm-org/mcp-core": "0.1.0"
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",