@particle-academy/fancy-sheets 0.3.1 → 0.4.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.
- package/dist/index.cjs +189 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +190 -78
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -130,6 +130,8 @@ interface SpreadsheetContextValue {
|
|
|
130
130
|
getColumnWidth: (col: number) => number;
|
|
131
131
|
isCellSelected: (address: string) => boolean;
|
|
132
132
|
isCellActive: (address: string) => boolean;
|
|
133
|
+
/** @internal drag-to-select state */
|
|
134
|
+
_isDragging: React.RefObject<boolean>;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
interface SpreadsheetGridProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -130,6 +130,8 @@ interface SpreadsheetContextValue {
|
|
|
130
130
|
getColumnWidth: (col: number) => number;
|
|
131
131
|
isCellSelected: (address: string) => boolean;
|
|
132
132
|
isCellActive: (address: string) => boolean;
|
|
133
|
+
/** @internal drag-to-select state */
|
|
134
|
+
_isDragging: React.RefObject<boolean>;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
interface SpreadsheetGridProps {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, memo, useCallback, useContext, useRef, useEffect, useMemo, useState, useReducer } from 'react';
|
|
2
|
-
import { cn } from '@particle-academy/react-fancy';
|
|
2
|
+
import { cn, ContextMenu } from '@particle-academy/react-fancy';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
// src/components/Spreadsheet/Spreadsheet.tsx
|
|
@@ -1599,15 +1599,36 @@ function ColumnResizeHandle({ colIndex }) {
|
|
|
1599
1599
|
}
|
|
1600
1600
|
ColumnResizeHandle.displayName = "ColumnResizeHandle";
|
|
1601
1601
|
function ColumnHeaders() {
|
|
1602
|
-
const { columnCount, rowCount, rowHeight, getColumnWidth, selectRange } = useSpreadsheet();
|
|
1603
|
-
const
|
|
1602
|
+
const { columnCount, rowCount, rowHeight, getColumnWidth, selection, selectRange, _isDragging } = useSpreadsheet();
|
|
1603
|
+
const handleColumnMouseDown = useCallback(
|
|
1604
|
+
(colIdx, e) => {
|
|
1605
|
+
if (e.button !== 0) return;
|
|
1606
|
+
if (e.shiftKey) {
|
|
1607
|
+
const activeCol = parseAddress(selection.activeCell).col;
|
|
1608
|
+
const minCol = Math.min(activeCol, colIdx);
|
|
1609
|
+
const maxCol = Math.max(activeCol, colIdx);
|
|
1610
|
+
selectRange(toAddress(0, minCol), toAddress(rowCount - 1, maxCol));
|
|
1611
|
+
} else {
|
|
1612
|
+
selectRange(toAddress(0, colIdx), toAddress(rowCount - 1, colIdx));
|
|
1613
|
+
}
|
|
1614
|
+
_isDragging.current = true;
|
|
1615
|
+
},
|
|
1616
|
+
[rowCount, selectRange, selection.activeCell, _isDragging]
|
|
1617
|
+
);
|
|
1618
|
+
const handleColumnMouseEnter = useCallback(
|
|
1604
1619
|
(colIdx) => {
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1620
|
+
if (_isDragging.current) {
|
|
1621
|
+
const activeCol = parseAddress(selection.activeCell).col;
|
|
1622
|
+
const minCol = Math.min(activeCol, colIdx);
|
|
1623
|
+
const maxCol = Math.max(activeCol, colIdx);
|
|
1624
|
+
selectRange(toAddress(0, minCol), toAddress(rowCount - 1, maxCol));
|
|
1625
|
+
}
|
|
1608
1626
|
},
|
|
1609
|
-
[rowCount, selectRange]
|
|
1627
|
+
[rowCount, selection.activeCell, selectRange, _isDragging]
|
|
1610
1628
|
);
|
|
1629
|
+
const handleMouseUp = useCallback(() => {
|
|
1630
|
+
_isDragging.current = false;
|
|
1631
|
+
}, [_isDragging]);
|
|
1611
1632
|
return /* @__PURE__ */ jsxs(
|
|
1612
1633
|
"div",
|
|
1613
1634
|
{
|
|
@@ -1627,7 +1648,9 @@ function ColumnHeaders() {
|
|
|
1627
1648
|
{
|
|
1628
1649
|
className: "relative flex shrink-0 cursor-pointer items-center justify-center border-r border-zinc-300 text-[11px] font-medium text-zinc-500 select-none hover:bg-zinc-200 dark:border-zinc-600 dark:text-zinc-400 dark:hover:bg-zinc-700",
|
|
1629
1650
|
style: { width: getColumnWidth(i), minWidth: getColumnWidth(i) },
|
|
1630
|
-
|
|
1651
|
+
onMouseDown: (e) => handleColumnMouseDown(i, e),
|
|
1652
|
+
onMouseEnter: () => handleColumnMouseEnter(i),
|
|
1653
|
+
onMouseUp: handleMouseUp,
|
|
1631
1654
|
children: [
|
|
1632
1655
|
columnToLetter(i),
|
|
1633
1656
|
/* @__PURE__ */ jsx(ColumnResizeHandle, { colIndex: i })
|
|
@@ -1641,19 +1664,42 @@ function ColumnHeaders() {
|
|
|
1641
1664
|
}
|
|
1642
1665
|
ColumnHeaders.displayName = "ColumnHeaders";
|
|
1643
1666
|
function RowHeader({ rowIndex }) {
|
|
1644
|
-
const { rowHeight, columnCount, selectRange } = useSpreadsheet();
|
|
1645
|
-
const
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1667
|
+
const { rowHeight, columnCount, selection, selectRange, _isDragging } = useSpreadsheet();
|
|
1668
|
+
const handleMouseDown = useCallback(
|
|
1669
|
+
(e) => {
|
|
1670
|
+
if (e.button !== 0) return;
|
|
1671
|
+
if (e.shiftKey) {
|
|
1672
|
+
const activeRow = parseAddress(selection.activeCell).row;
|
|
1673
|
+
const minRow = Math.min(activeRow, rowIndex);
|
|
1674
|
+
const maxRow = Math.max(activeRow, rowIndex);
|
|
1675
|
+
selectRange(toAddress(minRow, 0), toAddress(maxRow, columnCount - 1));
|
|
1676
|
+
} else {
|
|
1677
|
+
selectRange(toAddress(rowIndex, 0), toAddress(rowIndex, columnCount - 1));
|
|
1678
|
+
}
|
|
1679
|
+
_isDragging.current = true;
|
|
1680
|
+
},
|
|
1681
|
+
[rowIndex, columnCount, selectRange, selection.activeCell, _isDragging]
|
|
1682
|
+
);
|
|
1683
|
+
const handleMouseEnter = useCallback(() => {
|
|
1684
|
+
if (_isDragging.current) {
|
|
1685
|
+
const activeRow = parseAddress(selection.activeCell).row;
|
|
1686
|
+
const minRow = Math.min(activeRow, rowIndex);
|
|
1687
|
+
const maxRow = Math.max(activeRow, rowIndex);
|
|
1688
|
+
selectRange(toAddress(minRow, 0), toAddress(maxRow, columnCount - 1));
|
|
1689
|
+
}
|
|
1690
|
+
}, [rowIndex, columnCount, selection.activeCell, selectRange, _isDragging]);
|
|
1691
|
+
const handleMouseUp = useCallback(() => {
|
|
1692
|
+
_isDragging.current = false;
|
|
1693
|
+
}, [_isDragging]);
|
|
1650
1694
|
return /* @__PURE__ */ jsx(
|
|
1651
1695
|
"div",
|
|
1652
1696
|
{
|
|
1653
1697
|
"data-fancy-sheets-row-header": "",
|
|
1654
1698
|
className: "flex shrink-0 cursor-pointer items-center justify-center border-r border-b border-zinc-300 bg-zinc-100 text-[11px] font-medium text-zinc-500 select-none hover:bg-zinc-200 dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-400 dark:hover:bg-zinc-700",
|
|
1655
1699
|
style: { width: 48, minWidth: 48, height: rowHeight },
|
|
1656
|
-
|
|
1700
|
+
onMouseDown: handleMouseDown,
|
|
1701
|
+
onMouseEnter: handleMouseEnter,
|
|
1702
|
+
onMouseUp: handleMouseUp,
|
|
1657
1703
|
children: rowIndex + 1
|
|
1658
1704
|
}
|
|
1659
1705
|
);
|
|
@@ -1716,7 +1762,8 @@ var Cell = memo(function Cell2({ address, row, col }) {
|
|
|
1716
1762
|
rowHeight,
|
|
1717
1763
|
getColumnWidth,
|
|
1718
1764
|
isCellSelected,
|
|
1719
|
-
isCellActive
|
|
1765
|
+
isCellActive,
|
|
1766
|
+
_isDragging
|
|
1720
1767
|
} = useSpreadsheet();
|
|
1721
1768
|
const cell = activeSheet.cells[address];
|
|
1722
1769
|
const isActive = isCellActive(address);
|
|
@@ -1726,6 +1773,7 @@ var Cell = memo(function Cell2({ address, row, col }) {
|
|
|
1726
1773
|
const width = getColumnWidth(col);
|
|
1727
1774
|
const handleMouseDown = useCallback(
|
|
1728
1775
|
(e) => {
|
|
1776
|
+
if (e.button !== 0) return;
|
|
1729
1777
|
if (e.shiftKey) {
|
|
1730
1778
|
extendSelection(address);
|
|
1731
1779
|
} else if (e.ctrlKey || e.metaKey) {
|
|
@@ -1733,9 +1781,18 @@ var Cell = memo(function Cell2({ address, row, col }) {
|
|
|
1733
1781
|
} else {
|
|
1734
1782
|
setSelection(address);
|
|
1735
1783
|
}
|
|
1784
|
+
_isDragging.current = true;
|
|
1736
1785
|
},
|
|
1737
|
-
[address, setSelection, extendSelection, addSelection]
|
|
1786
|
+
[address, setSelection, extendSelection, addSelection, _isDragging]
|
|
1738
1787
|
);
|
|
1788
|
+
const handleMouseEnter = useCallback(() => {
|
|
1789
|
+
if (_isDragging.current) {
|
|
1790
|
+
extendSelection(address);
|
|
1791
|
+
}
|
|
1792
|
+
}, [address, extendSelection, _isDragging]);
|
|
1793
|
+
const handleMouseUp = useCallback(() => {
|
|
1794
|
+
_isDragging.current = false;
|
|
1795
|
+
}, [_isDragging]);
|
|
1739
1796
|
const handleDoubleClick = useCallback(() => {
|
|
1740
1797
|
if (readOnly) return;
|
|
1741
1798
|
startEdit();
|
|
@@ -1752,12 +1809,14 @@ var Cell = memo(function Cell2({ address, row, col }) {
|
|
|
1752
1809
|
"data-active": isActive || void 0,
|
|
1753
1810
|
role: "gridcell",
|
|
1754
1811
|
className: cn(
|
|
1755
|
-
"relative flex items-center truncate border-r border-b border-zinc-200 px-1.5 text-[13px] dark:border-zinc-700",
|
|
1812
|
+
"relative flex items-center truncate border-r border-b border-zinc-200 bg-white px-1.5 text-[13px] select-none dark:border-zinc-700 dark:bg-zinc-900",
|
|
1756
1813
|
isActive && "ring-2 ring-inset ring-blue-500",
|
|
1757
|
-
isSelected && !isActive && "bg-blue-
|
|
1814
|
+
isSelected && !isActive && "bg-blue-50 dark:bg-blue-950/40"
|
|
1758
1815
|
),
|
|
1759
1816
|
style: { width, minWidth: width, height: rowHeight, ...formatStyle },
|
|
1760
1817
|
onMouseDown: handleMouseDown,
|
|
1818
|
+
onMouseEnter: handleMouseEnter,
|
|
1819
|
+
onMouseUp: handleMouseUp,
|
|
1761
1820
|
onDoubleClick: handleDoubleClick,
|
|
1762
1821
|
children: !isEditing && /* @__PURE__ */ jsx("span", { className: "truncate", children: displayValue })
|
|
1763
1822
|
}
|
|
@@ -1897,6 +1956,9 @@ function SpreadsheetGrid({ className }) {
|
|
|
1897
1956
|
confirmEdit,
|
|
1898
1957
|
cancelEdit,
|
|
1899
1958
|
setCellValue,
|
|
1959
|
+
setFrozenRows,
|
|
1960
|
+
setFrozenCols,
|
|
1961
|
+
extendSelection,
|
|
1900
1962
|
undo,
|
|
1901
1963
|
redo
|
|
1902
1964
|
} = useSpreadsheet();
|
|
@@ -1986,66 +2048,114 @@ function SpreadsheetGrid({ className }) {
|
|
|
1986
2048
|
const top = row * rowHeight;
|
|
1987
2049
|
return { left, top };
|
|
1988
2050
|
})() : null;
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
{
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2051
|
+
const handleCopy = useCallback(() => {
|
|
2052
|
+
const range = selection.ranges[0];
|
|
2053
|
+
if (range) {
|
|
2054
|
+
const tsv = cellsToTSV(activeSheet.cells, range);
|
|
2055
|
+
navigator.clipboard.writeText(tsv);
|
|
2056
|
+
}
|
|
2057
|
+
}, [selection, activeSheet]);
|
|
2058
|
+
const handlePaste = useCallback(() => {
|
|
2059
|
+
navigator.clipboard.readText().then((text) => {
|
|
2060
|
+
if (!text) return;
|
|
2061
|
+
const { values } = tsvToCells(text);
|
|
2062
|
+
const { row: startRow, col: startCol } = parseAddress(selection.activeCell);
|
|
2063
|
+
for (let r = 0; r < values.length; r++) {
|
|
2064
|
+
for (let c = 0; c < values[r].length; c++) {
|
|
2065
|
+
setCellValue(toAddress(startRow + r, startCol + c), values[r][c]);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
}, [selection, setCellValue]);
|
|
2070
|
+
const handleClearSelection = useCallback(() => {
|
|
2071
|
+
const range = selection.ranges[0];
|
|
2072
|
+
if (!range) return;
|
|
2073
|
+
const { start, end } = range;
|
|
2074
|
+
const s = parseAddress(start);
|
|
2075
|
+
const e = parseAddress(end);
|
|
2076
|
+
const minR = Math.min(s.row, e.row), maxR = Math.max(s.row, e.row);
|
|
2077
|
+
const minC = Math.min(s.col, e.col), maxC = Math.max(s.col, e.col);
|
|
2078
|
+
for (let r = minR; r <= maxR; r++) {
|
|
2079
|
+
for (let c = minC; c <= maxC; c++) {
|
|
2080
|
+
setCellValue(toAddress(r, c), "");
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
}, [selection, setCellValue]);
|
|
2084
|
+
return /* @__PURE__ */ jsxs(ContextMenu, { children: [
|
|
2085
|
+
/* @__PURE__ */ jsx(ContextMenu.Trigger, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxs(
|
|
2086
|
+
"div",
|
|
2087
|
+
{
|
|
2088
|
+
ref: containerRef,
|
|
2089
|
+
"data-fancy-sheets-grid": "",
|
|
2090
|
+
className: cn("relative h-full overflow-auto bg-white focus:outline-none dark:bg-zinc-900", className),
|
|
2091
|
+
tabIndex: 0,
|
|
2092
|
+
onKeyDown: handleKeyDown,
|
|
2093
|
+
children: [
|
|
2094
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsx(ColumnHeaders, {}) }),
|
|
2095
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2096
|
+
Array.from({ length: rowCount }, (_, rowIdx) => {
|
|
2097
|
+
const isFrozenRow = rowIdx < activeSheet.frozenRows;
|
|
2098
|
+
return /* @__PURE__ */ jsxs(
|
|
2099
|
+
"div",
|
|
2100
|
+
{
|
|
2101
|
+
className: "flex",
|
|
2102
|
+
style: isFrozenRow ? {
|
|
2103
|
+
position: "sticky",
|
|
2104
|
+
top: rowHeight + rowIdx * rowHeight,
|
|
2105
|
+
zIndex: 8
|
|
2106
|
+
} : void 0,
|
|
2107
|
+
children: [
|
|
2108
|
+
/* @__PURE__ */ jsx("div", { className: "sticky left-0 z-[5]", children: /* @__PURE__ */ jsx(RowHeader, { rowIndex: rowIdx }) }),
|
|
2109
|
+
Array.from({ length: columnCount }, (_2, colIdx) => {
|
|
2110
|
+
const addr = toAddress(rowIdx, colIdx);
|
|
2111
|
+
const isFrozenCol = colIdx < activeSheet.frozenCols;
|
|
2112
|
+
return /* @__PURE__ */ jsx(
|
|
2113
|
+
"div",
|
|
2114
|
+
{
|
|
2115
|
+
style: isFrozenCol ? {
|
|
2116
|
+
position: "sticky",
|
|
2117
|
+
left: 48 + Array.from({ length: colIdx }, (_3, c) => getColumnWidth(c)).reduce((a, b) => a + b, 0),
|
|
2118
|
+
zIndex: isFrozenRow ? 9 : 6
|
|
2119
|
+
} : void 0,
|
|
2120
|
+
children: /* @__PURE__ */ jsx(Cell, { address: addr, row: rowIdx, col: colIdx })
|
|
2121
|
+
},
|
|
2122
|
+
addr
|
|
2123
|
+
);
|
|
2124
|
+
})
|
|
2125
|
+
]
|
|
2126
|
+
},
|
|
2127
|
+
rowIdx
|
|
2128
|
+
);
|
|
2129
|
+
}),
|
|
2130
|
+
/* @__PURE__ */ jsx(SelectionOverlay, {}),
|
|
2131
|
+
editorPosition && /* @__PURE__ */ jsx(
|
|
2003
2132
|
"div",
|
|
2004
2133
|
{
|
|
2005
|
-
className: "
|
|
2006
|
-
style:
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
})
|
|
2031
|
-
]
|
|
2032
|
-
},
|
|
2033
|
-
rowIdx
|
|
2034
|
-
);
|
|
2035
|
-
}),
|
|
2036
|
-
/* @__PURE__ */ jsx(SelectionOverlay, {}),
|
|
2037
|
-
editorPosition && /* @__PURE__ */ jsx(
|
|
2038
|
-
"div",
|
|
2039
|
-
{
|
|
2040
|
-
className: "absolute z-20",
|
|
2041
|
-
style: { left: editorPosition.left, top: editorPosition.top },
|
|
2042
|
-
children: /* @__PURE__ */ jsx(CellEditor, {})
|
|
2043
|
-
}
|
|
2044
|
-
)
|
|
2045
|
-
] })
|
|
2046
|
-
]
|
|
2047
|
-
}
|
|
2048
|
-
);
|
|
2134
|
+
className: "absolute z-20",
|
|
2135
|
+
style: { left: editorPosition.left, top: editorPosition.top },
|
|
2136
|
+
children: /* @__PURE__ */ jsx(CellEditor, {})
|
|
2137
|
+
}
|
|
2138
|
+
)
|
|
2139
|
+
] })
|
|
2140
|
+
]
|
|
2141
|
+
}
|
|
2142
|
+
) }),
|
|
2143
|
+
/* @__PURE__ */ jsxs(ContextMenu.Content, { children: [
|
|
2144
|
+
/* @__PURE__ */ jsx(ContextMenu.Item, { onClick: handleCopy, children: "Copy" }),
|
|
2145
|
+
/* @__PURE__ */ jsx(ContextMenu.Item, { onClick: handlePaste, disabled: readOnly, children: "Paste" }),
|
|
2146
|
+
/* @__PURE__ */ jsx(ContextMenu.Separator, {}),
|
|
2147
|
+
/* @__PURE__ */ jsx(ContextMenu.Item, { onClick: handleClearSelection, disabled: readOnly, children: "Clear cells" }),
|
|
2148
|
+
/* @__PURE__ */ jsx(ContextMenu.Separator, {}),
|
|
2149
|
+
/* @__PURE__ */ jsx(ContextMenu.Item, { onClick: () => {
|
|
2150
|
+
const row = parseAddress(selection.activeCell).row;
|
|
2151
|
+
setFrozenRows(activeSheet.frozenRows > 0 ? 0 : row);
|
|
2152
|
+
}, disabled: readOnly, children: activeSheet.frozenRows > 0 ? "Unfreeze rows" : "Freeze rows above" }),
|
|
2153
|
+
/* @__PURE__ */ jsx(ContextMenu.Item, { onClick: () => {
|
|
2154
|
+
const col = parseAddress(selection.activeCell).col;
|
|
2155
|
+
setFrozenCols(activeSheet.frozenCols > 0 ? 0 : col);
|
|
2156
|
+
}, disabled: readOnly, children: activeSheet.frozenCols > 0 ? "Unfreeze columns" : "Freeze columns left" })
|
|
2157
|
+
] })
|
|
2158
|
+
] });
|
|
2049
2159
|
}
|
|
2050
2160
|
SpreadsheetGrid.displayName = "SpreadsheetGrid";
|
|
2051
2161
|
var btnClass = "inline-flex items-center justify-center rounded px-2 py-1 text-[12px] font-medium text-zinc-600 transition-colors hover:bg-zinc-100 disabled:opacity-40 dark:text-zinc-300 dark:hover:bg-zinc-800";
|
|
@@ -2346,6 +2456,7 @@ function SpreadsheetRoot({
|
|
|
2346
2456
|
(address) => state.selection.activeCell === address,
|
|
2347
2457
|
[state.selection.activeCell]
|
|
2348
2458
|
);
|
|
2459
|
+
const isDraggingRef = useRef(false);
|
|
2349
2460
|
const ctx = useMemo(
|
|
2350
2461
|
() => ({
|
|
2351
2462
|
workbook: state.workbook,
|
|
@@ -2363,7 +2474,8 @@ function SpreadsheetRoot({
|
|
|
2363
2474
|
canRedo: state.redoStack.length > 0,
|
|
2364
2475
|
getColumnWidth,
|
|
2365
2476
|
isCellSelected,
|
|
2366
|
-
isCellActive
|
|
2477
|
+
isCellActive,
|
|
2478
|
+
_isDragging: isDraggingRef
|
|
2367
2479
|
}),
|
|
2368
2480
|
[state, activeSheet, columnCount, rowCount, defaultColumnWidth, rowHeight, readOnly, actions, getColumnWidth, isCellSelected, isCellActive]
|
|
2369
2481
|
);
|