@wallarm-org/design-system 1.22.0 → 1.22.1

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.
@@ -8,7 +8,7 @@ const SettingsHeaderBreadcrumbs = ({ ref, children, className, ...props })=>{
8
8
  ref: ref,
9
9
  "data-testid": testId,
10
10
  "data-slot": "settings-header-breadcrumbs",
11
- className: cn(className),
11
+ className: cn('ml-[-4px]', className),
12
12
  children: children
13
13
  });
14
14
  };
@@ -8,7 +8,7 @@ const SettingsHeaderHeading = ({ ref, children, className, ...props })=>{
8
8
  ref: ref,
9
9
  "data-testid": testId,
10
10
  "data-slot": "settings-header-heading",
11
- className: cn('flex items-start justify-between gap-16 w-full', className),
11
+ className: cn('flex items-center justify-between gap-16 w-full', className),
12
12
  children: children
13
13
  });
14
14
  };
@@ -21,7 +21,7 @@ const SwitchControl = ()=>{
21
21
  className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 text-white pointer-events-none z-0"
22
22
  }),
23
23
  /*#__PURE__*/ jsx(Switch.Thumb, {
24
- className: cn('w-16 h-12', 'bg-icon-primary-alt rounded-4 shadow-sm transition-all relative z-10', 'translate-x-4', 'data-[state=checked]:translate-x-14')
24
+ className: cn('w-16 h-12', 'bg-icon-primary-alt rounded-4 shadow-sm transition-all relative z-[9]', 'translate-x-4', 'data-[state=checked]:translate-x-14')
25
25
  })
26
26
  ]
27
27
  });
@@ -104,7 +104,7 @@ const StickyGroupParent = ({ tableWidth, headerHeight })=>{
104
104
  disablePinnedShadow: true
105
105
  }),
106
106
  dataCells.slice(1).map((cell)=>/*#__PURE__*/ jsx(Td, {
107
- className: cn('border-b border-border-primary-light bg-bg-surface-2 overlay', 'group-hover/row:overlay-states-primary-hover group-data-[selected]/row:overlay-states-primary-active'),
107
+ className: cn('border-b border-border-primary-light bg-bg-surface-2 overlay', 'group-hover/row:overlay-states-primary-hover group-data-[selected]/row:overlay-states-primary-active', 'group-data-[preview-active]/row:overlay-states-primary-hover group-has-[[data-state=open]]/row:overlay-states-primary-hover'),
108
108
  style: {
109
109
  width: cell.column.getSize()
110
110
  },
@@ -1,7 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../../utils/cn.js";
3
3
  const TableMasterCellActions = ({ children })=>/*#__PURE__*/ jsx("div", {
4
- className: cn('shrink-0 pl-4 pr-4 flex items-center gap-2', 'opacity-0 pointer-events-none', 'group-hover/row:opacity-100 group-hover/row:pointer-events-auto', 'group-data-[selected]/row:opacity-100 group-data-[selected]/row:pointer-events-auto', 'group-data-[preview-active]/row:opacity-100 group-data-[preview-active]/row:pointer-events-auto'),
4
+ "data-master-cell-action": "",
5
+ className: cn('shrink-0 pl-4 pr-4 flex items-center gap-2', 'opacity-0 pointer-events-none', 'group-hover/row:opacity-100 group-hover/row:pointer-events-auto', 'group-data-[selected]/row:opacity-100 group-data-[selected]/row:pointer-events-auto', 'group-data-[preview-active]/row:opacity-100 group-data-[preview-active]/row:pointer-events-auto', 'has-[[data-state=open]]:opacity-100 has-[[data-state=open]]:pointer-events-auto', '[&_[data-state=open]]:overlay [&_[data-state=open]]:overlay-states-primary-hover'),
5
6
  children: children
6
7
  });
7
8
  TableMasterCellActions.displayName = 'TableMasterCellActions';
@@ -71,7 +71,7 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
71
71
  lastRow: isLastRow
72
72
  }),
73
73
  dataCells.slice(1).map((cell)=>/*#__PURE__*/ jsx(Td, {
74
- className: cn('border-b border-border-primary-light bg-bg-surface-2 overlay', 'group-hover/row:overlay-states-primary-hover group-data-[selected]/row:overlay-states-primary-active', isLastRow && 'border-b-0'),
74
+ className: cn('border-b border-border-primary-light bg-bg-surface-2 overlay', 'group-hover/row:overlay-states-primary-hover group-data-[selected]/row:overlay-states-primary-active', 'group-data-[preview-active]/row:overlay-states-primary-hover group-has-[[data-state=open]]/row:overlay-states-primary-hover', isLastRow && 'border-b-0'),
75
75
  style: {
76
76
  width: cell.column.getSize()
77
77
  },
@@ -38,7 +38,7 @@ const tableHeadCellVariants = cva(cn(tableCellBase, 'pl-16 pr-4 py-4 text-xs fon
38
38
  dragging: false
39
39
  }
40
40
  });
41
- const tableBodyCellVariants = cva(cn(tableCellBase, 'px-16 py-8 text-sm text-text-primary', 'bg-bg-surface-2', 'align-top', 'group-hover/row:overlay-states-primary-hover', 'group-data-[selected]/row:overlay-states-primary-active', 'group-data-[selected]/row:group-hover/row:overlay-states-primary-hover', 'group-data-[preview-active]/row:overlay-states-primary-active', 'group-data-[preview-active]/row:group-hover/row:overlay-states-primary-hover', '[&:has([data-state=open][data-part=context-trigger])]:ring-2', '[&:has([data-state=open][data-part=context-trigger])]:ring-inset', '[&:has([data-state=open][data-part=context-trigger])]:ring-border-strong-brand', '[&:has([data-part=context-trigger])]:p-0', '[&_[data-part=context-trigger]]:w-full', '[&_[data-part=context-trigger]]:px-16 [&_[data-part=context-trigger]]:py-8', '[&_[data-part=context-trigger]]:text-left [&_[data-part=context-trigger]]:outline-none'), {
41
+ const tableBodyCellVariants = cva(cn(tableCellBase, 'px-16 py-8 text-sm text-text-primary', 'bg-bg-surface-2', 'align-top', 'group-hover/row:overlay-states-primary-hover', 'group-data-[selected]/row:overlay-states-primary-active', 'group-data-[selected]/row:group-hover/row:overlay-states-primary-hover', 'group-data-[preview-active]/row:overlay-states-primary-hover', 'group-has-[[data-state=open]]/row:overlay-states-primary-hover', '[&:has([data-state=open][data-part=context-trigger])]:ring-2', '[&:has([data-state=open][data-part=context-trigger])]:ring-inset', '[&:has([data-state=open][data-part=context-trigger])]:ring-border-strong-brand', '[&:has([data-part=context-trigger])]:p-0', '[&_[data-part=context-trigger]]:w-full', '[&_[data-part=context-trigger]]:px-16 [&_[data-part=context-trigger]]:py-8', '[&_[data-part=context-trigger]]:text-left [&_[data-part=context-trigger]]:outline-none'), {
42
42
  variants: {
43
43
  pinned: {
44
44
  true: 'sticky z-10',
@@ -1,3 +1,4 @@
1
+ import type { MouseEvent } from 'react';
1
2
  import type { RowData } from '@tanstack/react-table';
2
3
  /**
3
4
  * Encapsulates master cell click logic for a body cell.
@@ -7,7 +8,7 @@ export declare const useMasterCell: <T extends RowData>(columnId: string, rowId:
7
8
  /** Master cell click is enabled */
8
9
  isMasterTrigger: boolean;
9
10
  /** Fire master cell click for this row */
10
- handleClick: () => void;
11
+ handleClick: (e: MouseEvent) => void;
11
12
  /** Tooltip text for master cell hover */
12
13
  tooltipText: string | undefined;
13
14
  };
@@ -4,7 +4,8 @@ const useMasterCell = (columnId, rowId)=>{
4
4
  const { masterColumnId, onMasterCellClick } = useTableContext();
5
5
  const isMasterColumn = columnId === masterColumnId;
6
6
  const hasMasterClick = isMasterColumn && !!onMasterCellClick;
7
- const handleClick = useCallback(()=>{
7
+ const handleClick = useCallback((e)=>{
8
+ if (e.target.closest('[data-master-cell-action]')) return;
8
9
  onMasterCellClick?.(rowId);
9
10
  }, [
10
11
  onMasterCellClick,
@@ -17,6 +17,7 @@ export interface SecurityEvent {
17
17
  lastSeen: string;
18
18
  endpointMethod: HttpMethodName;
19
19
  endpointPath: string;
20
+ state: boolean;
20
21
  }
21
22
  export interface SecurityHeaderEntry {
22
23
  id: string;
@@ -12,6 +12,7 @@ import { Ip, IpAddress, IpCountry, IpProvider, sourceLabels } from "../Ip/index.
12
12
  import { Link } from "../Link/index.js";
13
13
  import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from "../OverflowTooltip/index.js";
14
14
  import { HStack, VStack } from "../Stack/index.js";
15
+ import { Switch, SwitchControl } from "../Switch/index.js";
15
16
  import { Text } from "../Text/index.js";
16
17
  import { createTableColumnHelper } from "./lib/index.js";
17
18
  const securityEvents = [
@@ -36,7 +37,8 @@ const securityEvents = [
36
37
  cweId: 'CWE-287',
37
38
  lastSeen: '5 days ago',
38
39
  endpointMethod: 'POST',
39
- endpointPath: '/api/v1/payments'
40
+ endpointPath: '/api/v1/payments',
41
+ state: true
40
42
  },
41
43
  {
42
44
  id: '2',
@@ -59,7 +61,8 @@ const securityEvents = [
59
61
  cweId: 'CWE-416',
60
62
  lastSeen: '6 days ago',
61
63
  endpointMethod: 'PUT',
62
- endpointPath: '/api/v1/users/profile'
64
+ endpointPath: '/api/v1/users/profile',
65
+ state: false
63
66
  },
64
67
  {
65
68
  id: '3',
@@ -82,7 +85,8 @@ const securityEvents = [
82
85
  cweId: 'CWE-89',
83
86
  lastSeen: '7 days ago',
84
87
  endpointMethod: 'GET',
85
- endpointPath: '/api/v1/users/:id'
88
+ endpointPath: '/api/v1/users/:id',
89
+ state: true
86
90
  },
87
91
  {
88
92
  id: '4',
@@ -105,7 +109,8 @@ const securityEvents = [
105
109
  cweId: 'CWE-22',
106
110
  lastSeen: '1 week ago',
107
111
  endpointMethod: 'GET',
108
- endpointPath: '/api/v1/errors/debug'
112
+ endpointPath: '/api/v1/errors/debug',
113
+ state: true
109
114
  },
110
115
  {
111
116
  id: '5',
@@ -128,7 +133,8 @@ const securityEvents = [
128
133
  cweId: 'CWE-200',
129
134
  lastSeen: '4 days ago',
130
135
  endpointMethod: 'POST',
131
- endpointPath: '/api/v1/auth/login'
136
+ endpointPath: '/api/v1/auth/login',
137
+ state: false
132
138
  },
133
139
  {
134
140
  id: '6',
@@ -151,7 +157,8 @@ const securityEvents = [
151
157
  cweId: 'CWE-352',
152
158
  lastSeen: '2 days ago',
153
159
  endpointMethod: 'POST',
154
- endpointPath: '/api/v1/files/upload'
160
+ endpointPath: '/api/v1/files/upload',
161
+ state: true
155
162
  },
156
163
  {
157
164
  id: '7',
@@ -174,7 +181,8 @@ const securityEvents = [
174
181
  cweId: 'CWE-125',
175
182
  lastSeen: '3 days ago',
176
183
  endpointMethod: 'GET',
177
- endpointPath: '/api/v1/images/proxy'
184
+ endpointPath: '/api/v1/images/proxy',
185
+ state: false
178
186
  },
179
187
  {
180
188
  id: '8',
@@ -197,7 +205,8 @@ const securityEvents = [
197
205
  cweId: 'CWE-134',
198
206
  lastSeen: '4 days ago',
199
207
  endpointMethod: 'GET',
200
- endpointPath: '/api/v1/auth/redirect'
208
+ endpointPath: '/api/v1/auth/redirect',
209
+ state: true
201
210
  },
202
211
  {
203
212
  id: '9',
@@ -220,7 +229,8 @@ const securityEvents = [
220
229
  cweId: 'CWE-79',
221
230
  lastSeen: '1 day ago',
222
231
  endpointMethod: 'DELETE',
223
- endpointPath: '/api/v1/users/:id'
232
+ endpointPath: '/api/v1/users/:id',
233
+ state: false
224
234
  },
225
235
  {
226
236
  id: '10',
@@ -243,7 +253,8 @@ const securityEvents = [
243
253
  cweId: 'CWE-89',
244
254
  lastSeen: '3 days ago',
245
255
  endpointMethod: 'PATCH',
246
- endpointPath: '/api/v1/content'
256
+ endpointPath: '/api/v1/content',
257
+ state: true
247
258
  }
248
259
  ];
249
260
  const securityColumnHelper = createTableColumnHelper();
@@ -274,6 +285,14 @@ const securityColumns = [
274
285
  ]
275
286
  })
276
287
  }),
288
+ securityColumnHelper.accessor('state', {
289
+ header: 'State',
290
+ size: 100,
291
+ cell: ({ getValue })=>/*#__PURE__*/ jsx(Switch, {
292
+ checked: getValue(),
293
+ children: /*#__PURE__*/ jsx(SwitchControl, {})
294
+ })
295
+ }),
277
296
  securityColumnHelper.accessor('requests', {
278
297
  header: 'Requests',
279
298
  size: 160,
@@ -671,6 +690,10 @@ const SecurityPreviewContent = ({ row })=>/*#__PURE__*/ jsxs(VStack, {
671
690
  size: "medium",
672
691
  children: row.original.status
673
692
  }),
693
+ /*#__PURE__*/ jsx(Switch, {
694
+ checked: row.original.state,
695
+ children: /*#__PURE__*/ jsx(SwitchControl, {})
696
+ }),
674
697
  /*#__PURE__*/ jsx(InlineCodeSnippet, {
675
698
  code: row.original.parameter,
676
699
  size: "sm",
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.21.0",
3
- "generatedAt": "2026-09-20T22:39:14.887Z",
2
+ "version": "1.22.0",
3
+ "generatedAt": "2026-09-22T02:19:24.344Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
@@ -65577,7 +65577,7 @@
65577
65577
  "examples": [
65578
65578
  {
65579
65579
  "name": "Full",
65580
- "code": "() => {\n const [search, setSearch] = useState('');\n\n return (\n <SettingsHeader>\n <SettingsHeaderBreadcrumbs>\n <Breadcrumbs>\n <BreadcrumbsItem href='/settings'>Settings</BreadcrumbsItem>\n <BreadcrumbsItem>Service accounts</BreadcrumbsItem>\n </Breadcrumbs>\n </SettingsHeaderBreadcrumbs>\n\n <SettingsHeaderHeading>\n <div className='flex flex-col'>\n <SettingsHeaderTitle>Service accounts</SettingsHeaderTitle>\n <SettingsHeaderDescription>\n Identities for automation and API access — they sign in with keys or tokens instead of a\n password.\n </SettingsHeaderDescription>\n </div>\n <SettingsHeaderActions>\n <Button variant='primary' color='brand'>\n Create service account\n </Button>\n </SettingsHeaderActions>\n </SettingsHeaderHeading>\n\n <SettingsHeaderFilters>\n <SearchInput\n value={search}\n onChange={setSearch}\n placeholder='Search name'\n className='w-[320px]'\n />\n <SegmentedTabs defaultValue='all'>\n <SegmentedTabsList>\n <SegmentedTabsTrigger value='all'>\n All <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n <SegmentedTabsTrigger value='active'>\n Active <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n <SegmentedTabsTrigger value='deactivated'>\n Deactivated <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n </SegmentedTabsList>\n </SegmentedTabs>\n </SettingsHeaderFilters>\n </SettingsHeader>\n );\n}",
65580
+ "code": "() => {\n const [search, setSearch] = useState('');\n\n return (\n <SettingsHeader>\n <SettingsHeaderBreadcrumbs>\n <Breadcrumbs>\n <BreadcrumbsItem href='/settings'>Settings</BreadcrumbsItem>\n <BreadcrumbsItem>Service accounts</BreadcrumbsItem>\n </Breadcrumbs>\n </SettingsHeaderBreadcrumbs>\n\n <SettingsHeaderHeading>\n <div className='flex flex-col'>\n <SettingsHeaderTitle>Service accounts</SettingsHeaderTitle>\n <SettingsHeaderDescription>\n Identities for automation and API access — they sign in with keys or tokens instead of a\n password.\n </SettingsHeaderDescription>\n </div>\n <SettingsHeaderActions>\n <Button size='medium' variant='primary' color='brand'>\n Create service account\n </Button>\n </SettingsHeaderActions>\n </SettingsHeaderHeading>\n\n <SettingsHeaderFilters>\n <SearchInput\n value={search}\n onChange={setSearch}\n placeholder='Search name'\n className='w-[320px]'\n />\n <SegmentedTabs defaultValue='all'>\n <SegmentedTabsList>\n <SegmentedTabsTrigger value='all'>\n All <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n <SegmentedTabsTrigger value='active'>\n Active <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n <SegmentedTabsTrigger value='deactivated'>\n Deactivated <NumericBadge>1</NumericBadge>\n </SegmentedTabsTrigger>\n </SegmentedTabsList>\n </SegmentedTabs>\n </SettingsHeaderFilters>\n </SettingsHeader>\n );\n}",
65581
65581
  "description": "All three rows: breadcrumbs, heading with description and action, and a filter bar with search and segmented tabs."
65582
65582
  },
65583
65583
  {
@@ -65587,7 +65587,7 @@
65587
65587
  },
65588
65588
  {
65589
65589
  "name": "WithBreadcrumbsAndActions",
65590
- "code": "() => (\n <SettingsHeader>\n <SettingsHeaderBreadcrumbs>\n <Breadcrumbs>\n <BreadcrumbsItem href='/settings'>Settings</BreadcrumbsItem>\n <BreadcrumbsItem>Integrations</BreadcrumbsItem>\n </Breadcrumbs>\n </SettingsHeaderBreadcrumbs>\n\n <SettingsHeaderHeading>\n <div className='flex flex-col'>\n <SettingsHeaderTitle>Integrations</SettingsHeaderTitle>\n <SettingsHeaderDescription>\n Connect third-party services to your workspace.\n </SettingsHeaderDescription>\n </div>\n <SettingsHeaderActions>\n <Button variant='secondary' color='neutral'>\n Export\n </Button>\n <Button variant='primary' color='brand'>\n Add integration\n </Button>\n </SettingsHeaderActions>\n </SettingsHeaderHeading>\n </SettingsHeader>\n)",
65590
+ "code": "() => (\n <SettingsHeader>\n <SettingsHeaderBreadcrumbs>\n <Breadcrumbs>\n <BreadcrumbsItem href='/settings'>Settings</BreadcrumbsItem>\n <BreadcrumbsItem>Integrations</BreadcrumbsItem>\n </Breadcrumbs>\n </SettingsHeaderBreadcrumbs>\n\n <SettingsHeaderHeading>\n <div className='flex flex-col'>\n <SettingsHeaderTitle>Integrations</SettingsHeaderTitle>\n <SettingsHeaderDescription>\n Connect third-party services to your workspace.\n </SettingsHeaderDescription>\n </div>\n <SettingsHeaderActions>\n <Button size='medium' variant='primary' color='brand'>\n Add integration\n </Button>\n </SettingsHeaderActions>\n </SettingsHeaderHeading>\n </SettingsHeader>\n)",
65591
65591
  "description": "Breadcrumbs, heading with multiple action buttons, no filter bar."
65592
65592
  },
65593
65593
  {
@@ -88889,6 +88889,11 @@
88889
88889
  "code": "() => {\n const [sorting, setSorting] = useState<TableSortingState>([]);\n const [activeRowId, setActiveRowId] = useState<string | null>(null);\n\n const data = useMemo(\n () =>\n Array.from({ length: 4 }, (_, batch) =>\n securityEvents.map(row => ({\n ...row,\n id: `${row.id}-${batch}`,\n objectName: batch === 0 ? row.objectName : `${row.objectName} (${batch + 1})`,\n })),\n ).flat(),\n [],\n );\n\n const columns = useMemo<TableColumnDef<SecurityEvent>[]>(\n () =>\n securityColumns.map((col, i) =>\n i === 0\n ? {\n ...col,\n cell: ({ row }: { row: { original: SecurityEvent } }) => (\n <Text size='xs'>{row.original.objectName}</Text>\n ),\n }\n : col,\n ),\n [],\n );\n\n const handleMasterCellClick = useCallback((rowId: string) => {\n setActiveRowId(prev => (prev === rowId ? null : rowId));\n }, []);\n\n const activeRow = useMemo(() => data.find(d => d.id === activeRowId), [data, activeRowId]);\n\n return (\n <>\n <Table\n className='max-w-920'\n data={data}\n columns={columns}\n getRowId={row => row.id}\n sorting={sorting}\n onSortingChange={setSorting}\n onMasterCellClick={handleMasterCellClick}\n activeRowId={activeRowId}\n />\n <Drawer\n open={!!activeRow}\n onOpenChange={open => {\n if (!open) setActiveRowId(null);\n }}\n modal={false}\n overlay={false}\n closeOnOutsideClick={false}\n width={960}\n >\n <DrawerContent>\n {activeRow ? (\n renderSecurityPreviewHeader({ original: activeRow })\n ) : (\n <DrawerHeader>\n <span />\n </DrawerHeader>\n )}\n <DrawerBody>\n {activeRow && renderSecurityPreviewContent({ original: activeRow })}\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n}",
88890
88890
  "description": "`onMasterCellClick` with `activeRowId`: the master cell opens a `Drawer` and the row it\nbelongs to stays marked while the panel is open."
88891
88891
  },
88892
+ {
88893
+ "name": "MasterCellWithActionsAndDrawer",
88894
+ "code": "() => {\n const [sorting, setSorting] = useState<TableSortingState>([]);\n const [activeRowId, setActiveRowId] = useState<string | null>(null);\n\n const data = useMemo(() => multiplySecurityEvents(), []);\n\n const columns = useMemo<TableColumnDef<SecurityEvent>[]>(\n () =>\n securityColumns.map((col, i) =>\n i === 0\n ? {\n ...col,\n cell: ({ row }: { row: { original: SecurityEvent } }) => (\n <Text size='xs'>{row.original.objectName}</Text>\n ),\n meta: {\n ...col.meta,\n resizeType: 'resize',\n renderMenuAction: (row: { original: SecurityEvent }) => (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant='ghost' color='neutral' size='small' aria-label='More'>\n <Ellipsis />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem\n onSelect={() => navigator.clipboard.writeText(row.original.objectName)}\n >\n <DropdownMenuItemIcon>\n <Copy />\n </DropdownMenuItemIcon>\n <DropdownMenuItemText>Copy name</DropdownMenuItemText>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onShowOnly(row.original.objectName)}>\n <DropdownMenuItemIcon>\n <Filter />\n </DropdownMenuItemIcon>\n <DropdownMenuItemText>Show only</DropdownMenuItemText>\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => onExclude(row.original.objectName)}>\n <DropdownMenuItemIcon>\n <FilterX />\n </DropdownMenuItemIcon>\n <DropdownMenuItemText>Exclude</DropdownMenuItemText>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ),\n },\n }\n : col,\n ),\n [],\n );\n\n const handleMasterCellClick = useCallback((rowId: string) => {\n setActiveRowId(prev => (prev === rowId ? null : rowId));\n }, []);\n\n const activeRow = useMemo(() => data.find(d => d.id === activeRowId), [data, activeRowId]);\n\n return (\n <>\n <Table\n className='max-w-920'\n data={data}\n columns={columns}\n getRowId={row => row.id}\n sorting={sorting}\n onSortingChange={setSorting}\n onMasterCellClick={handleMasterCellClick}\n activeRowId={activeRowId}\n />\n <Drawer\n open={!!activeRow}\n onOpenChange={open => {\n if (!open) setActiveRowId(null);\n }}\n modal={false}\n overlay={false}\n closeOnOutsideClick={false}\n width={960}\n >\n <DrawerContent>\n {activeRow ? (\n renderSecurityPreviewHeader({ original: activeRow })\n ) : (\n <DrawerHeader>\n <span />\n </DrawerHeader>\n )}\n <DrawerBody>\n {activeRow && renderSecurityPreviewContent({ original: activeRow })}\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n}",
88895
+ "description": "Master cell with both an action menu and a drawer:\nclicking the cell body opens the drawer, clicking the action button opens the menu\nwithout triggering the drawer."
88896
+ },
88892
88897
  {
88893
88898
  "name": "FullFeatured",
88894
88899
  "code": "() => {\n const data = useMemo(() => createLargeGroupedData(12, 50), []);\n\n const [sorting, setSorting] = useState<TableSortingState>([{ id: 'lastEdited', desc: true }]);\n const [rowSelection, setRowSelection] = useState<TableRowSelectionState>({});\n const [columnSizing, setColumnSizing] = useState<TableColumnSizingState>({});\n const [columnPinning, setColumnPinning] = useState<TableColumnPinningState>({\n left: ['objectName'],\n });\n const [columnOrder, setColumnOrder] = useState<string[]>([]);\n const [columnVisibility, setColumnVisibility] = useState<TableVisibilityState>({});\n const [expanded, setExpanded] = useState<TableExpandedState>({\n 'group-0': true,\n 'group-1': true,\n });\n\n return (\n <Table<SecurityHeaderEntry>\n className='h-500'\n data={data}\n columns={fullFeaturedColumns}\n getRowId={row => row.id}\n getSubRows={row => row.children}\n // Grouping\n expanded={expanded}\n onExpandedChange={setExpanded}\n // Sorting\n sorting={sorting}\n onSortingChange={setSorting}\n // Row selection\n rowSelection={rowSelection}\n onRowSelectionChange={setRowSelection}\n // Column resizing\n columnSizing={columnSizing}\n onColumnSizingChange={setColumnSizing}\n // Column pinning\n columnPinning={columnPinning}\n onColumnPinningChange={setColumnPinning}\n // Column DnD ordering\n columnOrder={columnOrder}\n onColumnOrderChange={setColumnOrder}\n // Column visibility + settings\n columnVisibility={columnVisibility}\n onColumnVisibilityChange={setColumnVisibility}\n defaultColumnVisibility={{}}\n defaultColumnOrder={headerColumnIds}\n // Virtual scrolling\n virtualized='container'\n >\n <TableActionBar>\n <Button variant='ghost' color='neutral-alt' onClick={onDuplicate}>\n <Copy /> Duplicate\n </Button>\n <Button color='brand' onClick={onDelete}>\n <Trash2 /> Delete\n </Button>\n </TableActionBar>\n </Table>\n );\n}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "1.22.0",
3
+ "version": "1.22.1",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",