@azrico/reactgrid 1.4.0 → 1.5.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/.claude/settings.local.json +8 -0
- package/CHANGELOG.md +0 -651
- package/README.md +160 -194
- package/dist/index.d.ts +4 -2
- package/dist/index.js +48 -6
- package/dist/src/example.js +8 -2
- package/dist/src/func/func_a11y.d.ts +52 -0
- package/dist/src/func/func_a11y.js +139 -0
- package/dist/src/hooks/useGridEvents.js +44 -0
- package/dist/src/types/types.d.ts +14 -1
- package/dist/src/views/DataGrid.js +36 -6
- package/index.ts +4 -2
- package/package.json +67 -67
- package/src/example.tsx +184 -178
- package/src/func/func_a11y.ts +159 -0
- package/src/hooks/useGridEvents.ts +141 -96
- package/src/types/types.ts +12 -1
- package/src/views/DataGrid.tsx +37 -5
|
@@ -7,6 +7,7 @@ exports.useGridEvents = useGridEvents;
|
|
|
7
7
|
var _react = _interopRequireDefault(require("react"));
|
|
8
8
|
var _func_grid = require("../func/func_grid");
|
|
9
9
|
var _func_child = require("../func/func_child");
|
|
10
|
+
var _func_a11y = require("../func/func_a11y");
|
|
10
11
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
12
|
function useGridMenuRow() {
|
|
12
13
|
const [menuAnchorEl, set_menuAnchorEl] = _react.default.useState(null);
|
|
@@ -79,9 +80,52 @@ function useGridEvents(grid, props) {
|
|
|
79
80
|
return false;
|
|
80
81
|
}, []);
|
|
81
82
|
/* -------------------------------------------------------------------------- */
|
|
83
|
+
/* ------------------------------ Accessibility ----------------------------- */
|
|
84
|
+
const latestProps = _react.default.useRef(props);
|
|
85
|
+
latestProps.current = props;
|
|
86
|
+
const rootSyncFrame = _react.default.useRef(0);
|
|
87
|
+
// last applied root values, so row renders (e.g. while scrolling) don't re-apply them
|
|
88
|
+
const lastRoot = _react.default.useRef({
|
|
89
|
+
el: null,
|
|
90
|
+
key: ''
|
|
91
|
+
});
|
|
92
|
+
const getRootOptions = () => ({
|
|
93
|
+
ariaLabel: latestProps.current.ariaLabel,
|
|
94
|
+
editable: !!latestProps.current.editable
|
|
95
|
+
});
|
|
96
|
+
// root attributes are set on the DOM node, batched to once per frame
|
|
97
|
+
const scheduleRootSync = _react.default.useCallback(() => {
|
|
98
|
+
var _latestProps$current$;
|
|
99
|
+
if (rootSyncFrame.current || typeof requestAnimationFrame === 'undefined') return;
|
|
100
|
+
const grid = (_latestProps$current$ = latestProps.current.liveGridRef) === null || _latestProps$current$ === void 0 || (_latestProps$current$ = _latestProps$current$.current) === null || _latestProps$current$ === void 0 ? void 0 : _latestProps$current$.current;
|
|
101
|
+
const key = (0, _func_a11y.get_root_a11y_key)(grid, getRootOptions());
|
|
102
|
+
if (key && key === lastRoot.current.key && (0, _func_a11y.get_grid_root)(grid) === lastRoot.current.el) return;
|
|
103
|
+
rootSyncFrame.current = requestAnimationFrame(() => {
|
|
104
|
+
var _latestProps$current$2;
|
|
105
|
+
rootSyncFrame.current = 0;
|
|
106
|
+
const liveGrid = (_latestProps$current$2 = latestProps.current.liveGridRef) === null || _latestProps$current$2 === void 0 || (_latestProps$current$2 = _latestProps$current$2.current) === null || _latestProps$current$2 === void 0 ? void 0 : _latestProps$current$2.current;
|
|
107
|
+
const options = getRootOptions();
|
|
108
|
+
const el = (0, _func_a11y.apply_root_a11y)(liveGrid, options);
|
|
109
|
+
lastRoot.current = {
|
|
110
|
+
el,
|
|
111
|
+
key: el ? (0, _func_a11y.get_root_a11y_key)(liveGrid, options) : ''
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
}, []);
|
|
115
|
+
_react.default.useEffect(() => {
|
|
116
|
+
scheduleRootSync();
|
|
117
|
+
}, [scheduleRootSync, props.ariaLabel, props.editable, props.columns, props.dataSource]);
|
|
118
|
+
_react.default.useEffect(() => () => {
|
|
119
|
+
if (rootSyncFrame.current) cancelAnimationFrame(rootSyncFrame.current);
|
|
120
|
+
rootSyncFrame.current = 0;
|
|
121
|
+
}, []);
|
|
82
122
|
const onRenderRow = _react.default.useCallback(rowProps => {
|
|
123
|
+
var _latestProps$current$3;
|
|
83
124
|
// save the original handlers to be called later
|
|
84
125
|
rowProps['data-row-id'] = (0, _func_grid.get_row_id)(rowProps.data);
|
|
126
|
+
const liveGrid = (_latestProps$current$3 = latestProps.current.liveGridRef) === null || _latestProps$current$3 === void 0 || (_latestProps$current$3 = _latestProps$current$3.current) === null || _latestProps$current$3 === void 0 ? void 0 : _latestProps$current$3.current;
|
|
127
|
+
(0, _func_a11y.apply_row_a11y)(rowProps, !!(liveGrid !== null && liveGrid !== void 0 && liveGrid.computedRowSelectionEnabled));
|
|
128
|
+
scheduleRootSync();
|
|
85
129
|
}, []);
|
|
86
130
|
return {
|
|
87
131
|
onRowClick,
|
|
@@ -28,19 +28,30 @@ export type loose_column_fields = loose_column_names & {
|
|
|
28
28
|
title: string;
|
|
29
29
|
type: string;
|
|
30
30
|
items: any[];
|
|
31
|
+
/** accessible name for cells whose visible text isn't descriptive (icons, badges, ...), set as aria-label */
|
|
32
|
+
ariaLabel: (value: any, data: any) => string;
|
|
31
33
|
};
|
|
32
34
|
export type LooseColumnDefinition = Partial<loose_column_fields & ColumnDefinition>;
|
|
33
35
|
export type CustomColumnDefinition = {
|
|
34
36
|
name: string;
|
|
35
37
|
render: (cell: any, formatterParams: any, onRendered: any) => React.ReactNode | undefined | null;
|
|
36
38
|
};
|
|
37
|
-
export type AzGridOptions = Partial<TypeDataGridProps
|
|
39
|
+
export type AzGridOptions = Partial<TypeDataGridProps> & {
|
|
40
|
+
/** called for every rendered row, after the grid's own row attributes are set */
|
|
41
|
+
onRenderRow?: (rowProps: any) => void;
|
|
42
|
+
/** extra DOM props for the header row */
|
|
43
|
+
headerProps?: {
|
|
44
|
+
[key: string]: any;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
38
47
|
export type AzGridProps = {
|
|
39
48
|
dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
|
|
40
49
|
details_dataSource?: any[] | ((args: any) => any[] | Promise<any[] | any>);
|
|
41
50
|
details_columns?: LooseColumnDefinition[];
|
|
42
51
|
details_filter?: FilterValues;
|
|
43
52
|
licenseKey?: string;
|
|
53
|
+
/** accessible name of the grid, set as aria-label on the grid root */
|
|
54
|
+
ariaLabel?: string;
|
|
44
55
|
gridRef?: React.MutableRefObject<TypeComputedProps>;
|
|
45
56
|
gridOptions?: AzGridOptions;
|
|
46
57
|
columns?: LooseColumnDefinition[];
|
|
@@ -81,6 +92,8 @@ export type DataGridProps = ModifyFields<AzGridProps, {
|
|
|
81
92
|
export type GridType = TypeComputedProps;
|
|
82
93
|
export type DataGridWrapperProps = ModifyFields<DataGridProps, {
|
|
83
94
|
gridRef: React.MutableRefObject<TypeComputedProps>;
|
|
95
|
+
/** internal: inovua's live computed props ref (gridRef holds a snapshot) */
|
|
96
|
+
liveGridRef: React.MutableRefObject<React.MutableRefObject<TypeComputedProps> | null>;
|
|
84
97
|
static_gridOptions: AzGridOptions;
|
|
85
98
|
dynamic_gridOptions: AzGridOptions;
|
|
86
99
|
children?: React.ReactNode;
|
|
@@ -19,6 +19,7 @@ var _useGridEvents = require("../hooks/useGridEvents");
|
|
|
19
19
|
var _useColumnData = require("../hooks/useColumnData");
|
|
20
20
|
var _useDatasource = require("../hooks/useDatasource");
|
|
21
21
|
var _useGridSearch = require("../hooks/useGridSearch");
|
|
22
|
+
var _func_a11y = require("../func/func_a11y");
|
|
22
23
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
24
|
/* -------------------------------------------------------------------------- */
|
|
24
25
|
/* -------------------------------------------------------------------------- */
|
|
@@ -43,11 +44,15 @@ const dynamic_option_names = ['selected', 'cellSelection', 'loading', 'limit', '
|
|
|
43
44
|
function AzGrid(props) {
|
|
44
45
|
const gridRefBackup = _react.default.useRef(null);
|
|
45
46
|
const gridRef = props.gridRef || gridRefBackup;
|
|
47
|
+
const liveGridRef = _react.default.useRef(null);
|
|
46
48
|
/* -------------------------------------------------------------------------- */
|
|
47
49
|
/* Columns */
|
|
48
50
|
/* -------------------------------------------------------------------------- */
|
|
49
51
|
const cached_columns = (0, _useColumnData.useColumnData)(props);
|
|
50
52
|
const dataSource = (0, _useDatasource.useDataSource)(props.dataSource, props);
|
|
53
|
+
const a11y_columns = _react.default.useMemo(() => cached_columns.map(col => (0, _func_a11y.apply_column_a11y)(col, {
|
|
54
|
+
gridEditable: !!props.editable
|
|
55
|
+
})), [cached_columns, props.editable]);
|
|
51
56
|
/* -------------------------------------------------------------------------- */
|
|
52
57
|
/* Row changes */
|
|
53
58
|
/* -------------------------------------------------------------------------- */
|
|
@@ -93,9 +98,10 @@ function AzGrid(props) {
|
|
|
93
98
|
return _react.default.createElement(DataGridEventsWrapper, {
|
|
94
99
|
...props,
|
|
95
100
|
gridRef: gridRef,
|
|
101
|
+
liveGridRef: liveGridRef,
|
|
96
102
|
static_gridOptions: static_gridOptions,
|
|
97
103
|
dynamic_gridOptions: dynamic_gridOptions,
|
|
98
|
-
columns:
|
|
104
|
+
columns: a11y_columns,
|
|
99
105
|
dataSource: dataSource,
|
|
100
106
|
highlightedRow: props.highlightedRow
|
|
101
107
|
});
|
|
@@ -135,19 +141,42 @@ function DataGridEventsWrapper(props) {
|
|
|
135
141
|
* Merge click events into grid options
|
|
136
142
|
*/
|
|
137
143
|
const static_gridOptions = _react.default.useMemo(() => {
|
|
144
|
+
const opts = props.static_gridOptions || {};
|
|
138
145
|
const events = {
|
|
139
146
|
onRowClick: onRowClick,
|
|
140
147
|
onRowContextMenu: onRowContextMenu
|
|
141
148
|
};
|
|
149
|
+
// internal row attributes first, consumer's onRenderRow last so it can override them
|
|
150
|
+
const consumerOnRenderRow = opts.onRenderRow;
|
|
142
151
|
const renderProps = {
|
|
143
|
-
onRenderRow:
|
|
152
|
+
onRenderRow: consumerOnRenderRow ? rowProps => {
|
|
153
|
+
onRenderRow(rowProps);
|
|
154
|
+
consumerOnRenderRow(rowProps);
|
|
155
|
+
} : onRenderRow
|
|
144
156
|
};
|
|
157
|
+
const gridEditable = !!props.editable;
|
|
158
|
+
const a11yProps = {
|
|
159
|
+
headerProps: {
|
|
160
|
+
role: 'row',
|
|
161
|
+
'aria-rowindex': 1,
|
|
162
|
+
...opts.headerProps
|
|
163
|
+
},
|
|
164
|
+
rowIndexColumn: (0, _func_a11y.apply_column_a11y)(typeof opts.rowIndexColumn === 'object' ? opts.rowIndexColumn : {}, {
|
|
165
|
+
role: 'rowheader',
|
|
166
|
+
gridEditable
|
|
167
|
+
})
|
|
168
|
+
};
|
|
169
|
+
if (opts.checkboxColumn) a11yProps.checkboxColumn = (0, _func_a11y.apply_column_a11y)(typeof opts.checkboxColumn === 'object' ? opts.checkboxColumn : {}, {
|
|
170
|
+
gridEditable,
|
|
171
|
+
markReadonly: false
|
|
172
|
+
});
|
|
145
173
|
return {
|
|
146
|
-
...
|
|
174
|
+
...opts,
|
|
147
175
|
...events,
|
|
148
|
-
...renderProps
|
|
176
|
+
...renderProps,
|
|
177
|
+
...a11yProps
|
|
149
178
|
};
|
|
150
|
-
}, [props.static_gridOptions]);
|
|
179
|
+
}, [props.static_gridOptions, props.editable, onRowClick, onRowContextMenu, onRenderRow]);
|
|
151
180
|
/* -------------------------------------------------------------------------- */
|
|
152
181
|
//TODO ContextMenu not from mui...
|
|
153
182
|
return _react.default.createElement("div", {
|
|
@@ -257,9 +286,10 @@ function DataGridCore(props) {
|
|
|
257
286
|
}, _react.default.createElement(_reactdatagridEnterprise.default, {
|
|
258
287
|
...props.static_gridOptions,
|
|
259
288
|
...props.dynamic_gridOptions,
|
|
260
|
-
rowIndexColumn: true,
|
|
289
|
+
rowIndexColumn: props.static_gridOptions.rowIndexColumn || true,
|
|
261
290
|
handle: ref => {
|
|
262
291
|
if (ref) props.gridRef.current = ref.current;
|
|
292
|
+
if (props.liveGridRef) props.liveGridRef.current = ref;
|
|
263
293
|
},
|
|
264
294
|
theme: "default-light",
|
|
265
295
|
className: (0, _clsx.default)('azgrid azgrid-flexed', props.allowChildRows && 'azgrid-tree', `azgrid-theme-${(_props$theme3 = props.theme) !== null && _props$theme3 !== void 0 ? _props$theme3 : props.dark ? 'dark' : 'light'}`),
|
package/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export * from './src';
|
|
1
|
+
export * from './src/views/DataGrid';
|
|
2
|
+
export * from './src/types/types';
|
|
3
|
+
export { get_row_id, set_row_id, get_col_name, get_col_header } from './src/func/func_grid';
|
|
2
4
|
|
|
3
|
-
import { AzGrid } from './src';
|
|
5
|
+
import { AzGrid } from './src/views/DataGrid';
|
|
4
6
|
export default AzGrid;
|
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@azrico/reactgrid",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"main": "dist/index.js",
|
|
5
|
-
"description": "React Datagrid",
|
|
6
|
-
"author": "Azrideus <MehrdadTavangar@gmail.com>",
|
|
7
|
-
"homepage": ".",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"start": "react-scripts start",
|
|
10
|
-
"build": "tsc && yarn cp_themes && babel dist --out-dir dist",
|
|
11
|
-
"test": "rem",
|
|
12
|
-
"check:theme": "node config/check-theme.cjs",
|
|
13
|
-
"theme:generate": "node config/generate-theme.cjs",
|
|
14
|
-
"cp_themes": "copyfiles ./src/themes/* ./dist/"
|
|
15
|
-
},
|
|
16
|
-
"config-overrides-path": "../../config/config-overrides.js",
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@babel/cli": "^7.13.14",
|
|
19
|
-
"@babel/core": "^7.13.15",
|
|
20
|
-
"@babel/eslint-parser": "^7.12.17",
|
|
21
|
-
"@babel/node": "^7.13.13",
|
|
22
|
-
"@babel/plugin-proposal-class-properties": "^7.12.13",
|
|
23
|
-
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
|
|
24
|
-
"@babel/preset-env": "^7.13.15",
|
|
25
|
-
"@babel/preset-typescript": "^7.14.5",
|
|
26
|
-
"@mui/material": "*",
|
|
27
|
-
"@types/react": "^18.0.25",
|
|
28
|
-
"@types/react-dom": "^18.0.8",
|
|
29
|
-
"react-dom": "^18.2.0",
|
|
30
|
-
"react-scripts": "^5.0.1",
|
|
31
|
-
"typescript": "^4.8.4"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@azrico/controls": "1.6.1",
|
|
35
|
-
"@azrico/object": "^1.4.97",
|
|
36
|
-
"@emotion/react": "^11.9.3",
|
|
37
|
-
"@emotion/styled": "^11.9.3",
|
|
38
|
-
"@inovua/reactdatagrid-enterprise": "^5.10.2",
|
|
39
|
-
"clsx": "^2.0.0",
|
|
40
|
-
"lodash.debounce": "^4.0.8",
|
|
41
|
-
"react": "^18.2.0",
|
|
42
|
-
"react-use-size": "^3.0.1"
|
|
43
|
-
},
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
"@azrico/controls": ">=1.6.1",
|
|
46
|
-
"@azrico/object": ">=1.4.97",
|
|
47
|
-
"@emotion/react": ">=11.9.3",
|
|
48
|
-
"@emotion/styled": ">=11.9.3",
|
|
49
|
-
"@inovua/reactdatagrid-enterprise": ">=5.10.2",
|
|
50
|
-
"@mui/material": ">=5.0.0 <8.0.0",
|
|
51
|
-
"clsx": ">=1.2.1",
|
|
52
|
-
"react": ">=18.2.0",
|
|
53
|
-
"react-use-size": ">=3.0.1"
|
|
54
|
-
},
|
|
55
|
-
"browserslist": {
|
|
56
|
-
"production": [
|
|
57
|
-
">0.2%",
|
|
58
|
-
"not dead",
|
|
59
|
-
"not op_mini all"
|
|
60
|
-
],
|
|
61
|
-
"development": [
|
|
62
|
-
"last 1 chrome version",
|
|
63
|
-
"last 1 firefox version",
|
|
64
|
-
"last 1 safari version"
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
|
-
"packageManager": "yarn@4.10.2"
|
|
1
|
+
{
|
|
2
|
+
"name": "@azrico/reactgrid",
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"description": "React Datagrid",
|
|
6
|
+
"author": "Azrideus <MehrdadTavangar@gmail.com>",
|
|
7
|
+
"homepage": ".",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"start": "react-scripts start",
|
|
10
|
+
"build": "tsc && yarn cp_themes && babel dist --out-dir dist",
|
|
11
|
+
"test": "rem",
|
|
12
|
+
"check:theme": "node config/check-theme.cjs",
|
|
13
|
+
"theme:generate": "node config/generate-theme.cjs",
|
|
14
|
+
"cp_themes": "copyfiles ./src/themes/* ./dist/"
|
|
15
|
+
},
|
|
16
|
+
"config-overrides-path": "../../config/config-overrides.js",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@babel/cli": "^7.13.14",
|
|
19
|
+
"@babel/core": "^7.13.15",
|
|
20
|
+
"@babel/eslint-parser": "^7.12.17",
|
|
21
|
+
"@babel/node": "^7.13.13",
|
|
22
|
+
"@babel/plugin-proposal-class-properties": "^7.12.13",
|
|
23
|
+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
|
|
24
|
+
"@babel/preset-env": "^7.13.15",
|
|
25
|
+
"@babel/preset-typescript": "^7.14.5",
|
|
26
|
+
"@mui/material": "*",
|
|
27
|
+
"@types/react": "^18.0.25",
|
|
28
|
+
"@types/react-dom": "^18.0.8",
|
|
29
|
+
"react-dom": "^18.2.0",
|
|
30
|
+
"react-scripts": "^5.0.1",
|
|
31
|
+
"typescript": "^4.8.4"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@azrico/controls": "1.6.1",
|
|
35
|
+
"@azrico/object": "^1.4.97",
|
|
36
|
+
"@emotion/react": "^11.9.3",
|
|
37
|
+
"@emotion/styled": "^11.9.3",
|
|
38
|
+
"@inovua/reactdatagrid-enterprise": "^5.10.2",
|
|
39
|
+
"clsx": "^2.0.0",
|
|
40
|
+
"lodash.debounce": "^4.0.8",
|
|
41
|
+
"react": "^18.2.0",
|
|
42
|
+
"react-use-size": "^3.0.1"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@azrico/controls": ">=1.6.1",
|
|
46
|
+
"@azrico/object": ">=1.4.97",
|
|
47
|
+
"@emotion/react": ">=11.9.3",
|
|
48
|
+
"@emotion/styled": ">=11.9.3",
|
|
49
|
+
"@inovua/reactdatagrid-enterprise": ">=5.10.2",
|
|
50
|
+
"@mui/material": ">=5.0.0 <8.0.0",
|
|
51
|
+
"clsx": ">=1.2.1",
|
|
52
|
+
"react": ">=18.2.0",
|
|
53
|
+
"react-use-size": ">=3.0.1"
|
|
54
|
+
},
|
|
55
|
+
"browserslist": {
|
|
56
|
+
"production": [
|
|
57
|
+
">0.2%",
|
|
58
|
+
"not dead",
|
|
59
|
+
"not op_mini all"
|
|
60
|
+
],
|
|
61
|
+
"development": [
|
|
62
|
+
"last 1 chrome version",
|
|
63
|
+
"last 1 firefox version",
|
|
64
|
+
"last 1 safari version"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"packageManager": "yarn@4.10.2"
|
|
68
68
|
}
|