@wallarm-org/design-system 0.76.1 → 0.76.2
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/dist/components/Table/TableActionBar/TableActionBarAnchor.js +3 -0
- package/dist/components/Table/TableActionBar/TableActionBarAnchorRefContext.d.ts +10 -0
- package/dist/components/Table/TableActionBar/TableActionBarAnchorRefContext.js +8 -0
- package/dist/components/Table/TableActionBar/TableActionBarProvider.d.ts +1 -1
- package/dist/components/Table/TableActionBar/TableActionBarProvider.js +36 -17
- package/dist/metadata/components.json +6 -2
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { Popover } from "@ark-ui/react/popover";
|
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { cn } from "../../../utils/cn.js";
|
|
5
5
|
import { useTableContext } from "../TableContext/index.js";
|
|
6
|
+
import { useTableActionBarAnchorRef } from "./TableActionBarAnchorRefContext.js";
|
|
6
7
|
const tableActionBarAnchorVariants = cva(cn('w-full relative outline-none'), {
|
|
7
8
|
variants: {
|
|
8
9
|
virtualized: {
|
|
@@ -13,7 +14,9 @@ const tableActionBarAnchorVariants = cva(cn('w-full relative outline-none'), {
|
|
|
13
14
|
});
|
|
14
15
|
const TableActionBarAnchor = ({ className, 'data-testid': testId, children })=>{
|
|
15
16
|
const { virtualized } = useTableContext();
|
|
17
|
+
const anchorRef = useTableActionBarAnchorRef();
|
|
16
18
|
return /*#__PURE__*/ jsx(Popover.Anchor, {
|
|
19
|
+
ref: anchorRef,
|
|
17
20
|
"data-testid": testId,
|
|
18
21
|
className: cn(tableActionBarAnchorVariants({
|
|
19
22
|
virtualized
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Shares the DOM node rendered by `TableActionBarAnchor` with
|
|
4
|
+
* `TableActionBarProvider`, which sits above it in the tree (as a parent of
|
|
5
|
+
* `children`, not a direct renderer) and needs the anchor's live
|
|
6
|
+
* `getBoundingClientRect()` to horizontally align the action bar with the
|
|
7
|
+
* table.
|
|
8
|
+
*/
|
|
9
|
+
export declare const TableActionBarAnchorRefContext: import("react").Context<RefObject<HTMLDivElement | null> | null>;
|
|
10
|
+
export declare const useTableActionBarAnchorRef: () => RefObject<HTMLDivElement | null>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
const TableActionBarAnchorRefContext = createContext(null);
|
|
3
|
+
const useTableActionBarAnchorRef = ()=>{
|
|
4
|
+
const ref = useContext(TableActionBarAnchorRefContext);
|
|
5
|
+
if (!ref) throw new Error('useTableActionBarAnchorRef must be used within a TableActionBarProvider');
|
|
6
|
+
return ref;
|
|
7
|
+
};
|
|
8
|
+
export { TableActionBarAnchorRefContext, useTableActionBarAnchorRef };
|
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useRef } from "react";
|
|
2
3
|
import { Popover } from "@ark-ui/react/popover";
|
|
3
4
|
import { useTableContext } from "../TableContext/index.js";
|
|
4
|
-
|
|
5
|
+
import { TableActionBarAnchorRefContext } from "./TableActionBarAnchorRefContext.js";
|
|
5
6
|
const TABLE_ACTION_BAR_OFFSET = 32;
|
|
6
|
-
const TABLE_ACTION_BAR_POSITIONING = Object.freeze({
|
|
7
|
-
strategy: 'absolute',
|
|
8
|
-
placement: 'bottom',
|
|
9
|
-
gutter: 32,
|
|
10
|
-
overlap: true,
|
|
11
|
-
flip: false,
|
|
12
|
-
offset: {
|
|
13
|
-
mainAxis: -(TABLE_ACTION_BAR_HEIGHT + TABLE_ACTION_BAR_OFFSET)
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
7
|
const TableActionBarProvider = ({ children })=>{
|
|
17
8
|
const { table, selectionEnabled } = useTableContext();
|
|
9
|
+
const anchorRef = useRef(null);
|
|
18
10
|
const selectedCount = selectionEnabled ? Object.keys(table.getState().rowSelection).length : 0;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
const positioning = useMemo(()=>{
|
|
12
|
+
const anchor = {
|
|
13
|
+
getBoundingClientRect: ()=>{
|
|
14
|
+
const rect = anchorRef.current?.getBoundingClientRect();
|
|
15
|
+
return DOMRect.fromRect({
|
|
16
|
+
x: rect?.left ?? 0,
|
|
17
|
+
y: window.innerHeight,
|
|
18
|
+
width: rect?.width ?? 0,
|
|
19
|
+
height: 0
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
strategy: 'fixed',
|
|
25
|
+
placement: 'top',
|
|
26
|
+
gutter: TABLE_ACTION_BAR_OFFSET,
|
|
27
|
+
flip: false,
|
|
28
|
+
getAnchorElement: ()=>anchor
|
|
29
|
+
};
|
|
30
|
+
}, []);
|
|
31
|
+
const handleEscapeKeyDown = ()=>{
|
|
32
|
+
if (selectionEnabled) table.resetRowSelection();
|
|
33
|
+
};
|
|
34
|
+
return /*#__PURE__*/ jsx(TableActionBarAnchorRefContext.Provider, {
|
|
35
|
+
value: anchorRef,
|
|
36
|
+
children: /*#__PURE__*/ jsx(Popover.Root, {
|
|
37
|
+
open: selectedCount > 0,
|
|
38
|
+
closeOnInteractOutside: false,
|
|
39
|
+
portalled: false,
|
|
40
|
+
positioning: positioning,
|
|
41
|
+
onEscapeKeyDown: handleEscapeKeyDown,
|
|
42
|
+
children: children
|
|
43
|
+
})
|
|
25
44
|
});
|
|
26
45
|
};
|
|
27
46
|
export { TableActionBarProvider };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.76.
|
|
3
|
-
"generatedAt": "2026-07-
|
|
2
|
+
"version": "0.76.1",
|
|
3
|
+
"generatedAt": "2026-07-16T11:30:32.825Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -76843,6 +76843,10 @@
|
|
|
76843
76843
|
"name": "RowSelection",
|
|
76844
76844
|
"code": "() => {\n const [rowSelection, setRowSelection] = useState<TableRowSelectionState>({});\n\n return (\n <Table\n data={securityEvents}\n columns={securityColumns}\n getRowId={row => row.id}\n rowSelection={rowSelection}\n onRowSelectionChange={setRowSelection}\n >\n <TableActionBar>\n <Button variant='ghost' color='neutral-alt' onClick={() => alert('Copy clicked')}>\n <Copy /> Duplicate\n </Button>\n <Button color='brand' onClick={() => alert('Delete clicked')}>\n <Trash2 /> Delete\n </Button>\n </TableActionBar>\n </Table>\n );\n}"
|
|
76845
76845
|
},
|
|
76846
|
+
{
|
|
76847
|
+
"name": "RowSelectionWindowScroll",
|
|
76848
|
+
"code": "() => {\n const largeData = useMemo(() => createLargeSecurityEvents(100), []);\n const [rowSelection, setRowSelection] = useState<TableRowSelectionState>({});\n\n return (\n <>\n <Table\n data-testid='row-selection-window-scroll-table'\n data={largeData}\n columns={securityColumns}\n getRowId={row => row.id}\n virtualized='window'\n rowSelection={rowSelection}\n onRowSelectionChange={setRowSelection}\n >\n <TableActionBar>\n <Button variant='ghost' color='neutral-alt' onClick={() => alert('Copy clicked')}>\n <Copy /> Duplicate\n </Button>\n <Button color='brand' onClick={() => alert('Delete clicked')}>\n <Trash2 /> Delete\n </Button>\n </TableActionBar>\n </Table>\n {/* Filler so the e2e suite can scroll the table fully out of view while a\n selection stays active — this story's only content otherwise fills\n exactly to the table's own height, so max scroll would always leave\n the table's tail in view. Generous margin over the viewport height\n (800px in the e2e config) so the anchor is unambiguously out of view\n at max scroll, not just mostly. */}\n <div style={{ height: 3000 }} />\n </>\n );\n}"
|
|
76849
|
+
},
|
|
76846
76850
|
{
|
|
76847
76851
|
"name": "RowGrouping",
|
|
76848
76852
|
"code": "() => {\n const [expanded, setExpanded] = useState<TableExpandedState>({ 'group-cto': true });\n const [sorting, setSorting] = useState<TableSortingState>([{ id: 'lastEdited', desc: true }]);\n const [rowSelection, setRowSelection] = useState<TableRowSelectionState>({});\n\n return (\n <Table<SecurityHeaderEntry>\n data={groupedHeaderData}\n columns={headerColumns}\n getRowId={row => row.id}\n getSubRows={row => row.children}\n expanded={expanded}\n onExpandedChange={setExpanded}\n sorting={sorting}\n onSortingChange={setSorting}\n rowSelection={rowSelection}\n onRowSelectionChange={setRowSelection}\n />\n );\n}"
|