beautiful-grid 1.0.13 → 1.0.15

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 (50) hide show
  1. package/README.md +121 -6
  2. package/cjs/BGrid.js +388 -44
  3. package/cjs/components/CellNavigationDomSync.js +8 -0
  4. package/cjs/components/CellTextEditorGateway.js +13 -9
  5. package/cjs/components/ColResizer.js +13 -7
  6. package/cjs/components/MasterDetailCell.js +145 -0
  7. package/cjs/components/MasterDetailContext.js +42 -0
  8. package/cjs/components/Table.js +162 -52
  9. package/cjs/components/TableBody.js +7 -3
  10. package/cjs/components/TableBodyCell.js +2 -1
  11. package/cjs/components/TableSummary.js +25 -34
  12. package/cjs/components/TableSummaryFronzen.js +36 -34
  13. package/cjs/store/createAppStore.js +2 -0
  14. package/cjs/utils/cellSelectionGeometry.js +32 -6
  15. package/cjs/utils/columnVisibility.js +17 -14
  16. package/cjs/utils/index.js +1 -0
  17. package/cjs/utils/rowHeightMetrics.js +47 -6
  18. package/cjs/utils/summary.js +55 -0
  19. package/cjs/utils/useRowReorderController.js +5 -1
  20. package/esm/BGrid.js +387 -72
  21. package/esm/components/CellNavigationDomSync.js +8 -0
  22. package/esm/components/CellTextEditorGateway.js +12 -9
  23. package/esm/components/ColResizer.js +8 -2
  24. package/esm/components/MasterDetailCell.js +101 -0
  25. package/esm/components/MasterDetailContext.js +5 -0
  26. package/esm/components/Table.js +151 -42
  27. package/esm/components/TableBody.js +6 -2
  28. package/esm/components/TableBodyCell.js +2 -1
  29. package/esm/components/TableSummary.js +26 -29
  30. package/esm/components/TableSummaryFronzen.js +26 -29
  31. package/esm/store/createAppStore.js +2 -0
  32. package/esm/utils/cellSelectionGeometry.js +31 -5
  33. package/esm/utils/columnVisibility.js +21 -18
  34. package/esm/utils/index.js +1 -0
  35. package/esm/utils/rowHeightMetrics.js +46 -6
  36. package/esm/utils/summary.js +35 -0
  37. package/esm/utils/useRowReorderController.js +5 -1
  38. package/package.json +1 -1
  39. package/style.css +164 -14
  40. package/types/BGrid.d.ts +1 -1
  41. package/types/components/MasterDetailCell.d.ts +21 -0
  42. package/types/components/MasterDetailContext.d.ts +20 -0
  43. package/types/components/Table.d.ts +1 -0
  44. package/types/components/TableBody.d.ts +2 -1
  45. package/types/store/createAppStore.d.ts +1 -1
  46. package/types/types.d.ts +70 -4
  47. package/types/utils/cellSelectionGeometry.d.ts +3 -1
  48. package/types/utils/index.d.ts +1 -0
  49. package/types/utils/rowHeightMetrics.d.ts +15 -1
  50. package/types/utils/summary.d.ts +13 -0
@@ -205,14 +205,14 @@ function CellTextEditorGateway(_a) {
205
205
  input.style.removeProperty('text-align');
206
206
  return;
207
207
  }
208
- var target = container.querySelector("td[data-bgrid-cell=\"true\"][data-row-index=\"".concat(cellEditSession.hostCell.rowIndex, "\"][data-column-index=\"").concat(cellEditSession.hostCell.columnIndex, "\"]"));
208
+ var target = Array.from(container.querySelectorAll("td[data-bgrid-cell=\"true\"][data-row-index=\"".concat(cellEditSession.hostCell.rowIndex, "\"][data-column-index=\"").concat(cellEditSession.hostCell.columnIndex, "\"]"))).find(function (el) { return el.closest('[role="grid"], [role="treegrid"]') === container; });
209
209
  if (!(target instanceof HTMLElement)) {
210
210
  input.style.visibility = 'hidden';
211
211
  return;
212
212
  }
213
213
  var containerRect = container.getBoundingClientRect();
214
214
  var targetRect = target.getBoundingClientRect();
215
- var bodyViewport = container.querySelector('.bgrid-body-viewport');
215
+ var bodyViewport = Array.from(container.querySelectorAll('.bgrid-body-viewport')).find(function (el) { return el.closest('[role="grid"], [role="treegrid"]') === container; });
216
216
  var bodyViewportRect = bodyViewport instanceof HTMLElement ? bodyViewport.getBoundingClientRect() : containerRect;
217
217
  var editorBox = resolveVisibleTextEditorVerticalBox({
218
218
  targetTop: targetRect.top,
@@ -225,9 +225,12 @@ function CellTextEditorGateway(_a) {
225
225
  input.style.visibility = 'hidden';
226
226
  return;
227
227
  }
228
- input.style.transform = "translate(".concat(targetRect.left - containerRect.left - container.clientLeft, "px, ").concat(editorBox.top - containerRect.top - container.clientTop, "px)");
229
- input.style.width = "".concat(targetRect.width, "px");
230
- input.style.height = "".concat(editorBox.height, "px");
228
+ // Convert viewport pixels back to local pixels during modal scale animations.
229
+ var scaleX = container.offsetWidth && containerRect.width ? containerRect.width / container.offsetWidth : 1;
230
+ var scaleY = container.offsetHeight && containerRect.height ? containerRect.height / container.offsetHeight : 1;
231
+ input.style.transform = "translate(".concat((targetRect.left - containerRect.left) / scaleX - container.clientLeft, "px, ").concat((editorBox.top - containerRect.top) / scaleY - container.clientTop, "px)");
232
+ input.style.width = "".concat(targetRect.width / scaleX, "px");
233
+ input.style.height = "".concat(editorBox.height / scaleY, "px");
231
234
  if (column === null || column === void 0 ? void 0 : column.align) {
232
235
  input.style.textAlign = column.align;
233
236
  }
@@ -334,11 +337,12 @@ function CellTextEditorGateway(_a) {
334
337
  return;
335
338
  endCellEdit(cellEditSession.id);
336
339
  }, [cellEditSession, endCellEdit]);
337
- var startReplace = React.useCallback(function () {
338
- if (!activeCell || !canStartText || cellEditSession)
340
+ var startReplace = React.useCallback(function (preserveInput) {
341
+ if (preserveInput === void 0) { preserveInput = false; }
342
+ if (!activeCell || !canStartText || cellEditSession || nativeStartRef.current)
339
343
  return;
340
344
  nativeStartRef.current = true;
341
- if (inputRef.current)
345
+ if (inputRef.current && !preserveInput)
342
346
  inputRef.current.value = '';
343
347
  beginCellEdit(activeCell, 'replace');
344
348
  }, [activeCell, beginCellEdit, canStartText, cellEditSession]);
@@ -351,7 +355,7 @@ function CellTextEditorGateway(_a) {
351
355
  : '셀 텍스트 편집'
352
356
  : (_e = textEditor.ariaLabel) !== null && _e !== void 0 ? _e : "\uD589 ".concat(cell.rowIndex + 1, ", \uC5F4 ").concat(cell.columnIndex + 1, " \uD14D\uC2A4\uD2B8 \uD3B8\uC9D1")
353
357
  : 'DataGrid 키보드 탐색';
354
- return (React.createElement("input", __assign({ ref: inputRef, "data-bgrid-text-editor-gateway": 'true', className: isTextEditing ? 'bgrid-text-editor-gateway bgrid-text-editor-active' : 'bgrid-text-editor-gateway', "aria-label": ariaLabel, "aria-invalid": invalid || undefined, readOnly: !canStartText && !isTextEditing }, inputProps, { onBeforeInput: function () { return startReplace(); }, onInput: function () { return startReplace(); }, onCompositionStart: function () {
358
+ return (React.createElement("input", __assign({ ref: inputRef, "data-bgrid-text-editor-gateway": 'true', className: isTextEditing ? 'bgrid-text-editor-gateway bgrid-text-editor-active' : 'bgrid-text-editor-gateway', "aria-label": ariaLabel, "aria-invalid": invalid || undefined, readOnly: !canStartText && !isTextEditing }, inputProps, { onBeforeInput: function () { return startReplace(); }, onInput: function () { return startReplace(true); }, onCompositionStart: function () {
355
359
  composingRef.current = true;
356
360
  startReplace();
357
361
  }, onCompositionEnd: function () {
@@ -107,9 +107,9 @@ function ColResizer(_a) {
107
107
  }, [container, disabled, endCellEdit, setColumnResizing, setColumnWidth]);
108
108
  var onMouseDoubleClick = React.useCallback(function (evt, columnIndex) { return __awaiter(_this, void 0, void 0, function () {
109
109
  var headFrozenHTML, headHTML, bodyFrozenHTML, bodyHTML, targetDiv, bodyTarget, targetTd;
110
- var _a, _b, _c, _d, _e;
111
- return __generator(this, function (_f) {
112
- switch (_f.label) {
110
+ var _a, _b, _c, _d;
111
+ return __generator(this, function (_e) {
112
+ switch (_e.label) {
113
113
  case 0:
114
114
  if (disabled)
115
115
  return [2 /*return*/];
@@ -125,18 +125,24 @@ function ColResizer(_a) {
125
125
  targetDiv.style.position = 'fixed';
126
126
  targetDiv.style.top = '-9999px';
127
127
  targetDiv.innerHTML = "<table><thead>".concat(headFrozenHTML, "</thead><tbody>").concat(bodyFrozenHTML, "</tbody></table>\n<table><thead>").concat(headHTML, "</thead><tbody>").concat(bodyHTML, "</tbody></table>");
128
- bodyTarget = (_e = document.getElementById('root')) !== null && _e !== void 0 ? _e : document.body;
128
+ // Measure with the grid's inherited font and real header/body padding.
129
+ targetDiv.querySelectorAll('table').forEach(function (table) {
130
+ table.className = 'bgrid-head-table bgrid-body-table';
131
+ table.style.tableLayout = 'auto';
132
+ table.style.width = 'max-content';
133
+ });
134
+ bodyTarget = container.current;
129
135
  bodyTarget.append(targetDiv);
130
136
  return [4 /*yield*/, (0, utils_1.delay)(30)];
131
137
  case 1:
132
- _f.sent();
138
+ _e.sent();
133
139
  targetTd = targetDiv.querySelector("tr td.bgrid-head-cell[data-column-index=\"".concat(columnIndex, "\"]"));
134
140
  if (targetTd) {
135
- setColumnWidth(columnIndex, { width: targetTd.getBoundingClientRect().width });
141
+ setColumnWidth(columnIndex, { width: Math.ceil(targetTd.offsetWidth) + 1 });
136
142
  setColumnWidth(columnIndex, { updateColumns: true });
137
143
  }
138
144
  targetDiv.remove();
139
- _f.label = 2;
145
+ _e.label = 2;
140
146
  case 2: return [2 /*return*/];
141
147
  }
142
148
  });
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MasterDetailCell = MasterDetailCell;
37
+ exports.MasterDetailRow = MasterDetailRow;
38
+ var React = __importStar(require("react"));
39
+ var utils_1 = require("../utils");
40
+ var MasterDetailContext_1 = require("./MasterDetailContext");
41
+ function MasterDetailCell(_a) {
42
+ var _b, _c, _d, _e;
43
+ var column = _a.column, item = _a.item, sourceIndex = _a.sourceIndex, children = _a.children;
44
+ var masterDetail = (0, MasterDetailContext_1.useMasterDetailContext)();
45
+ if (!masterDetail || (0, utils_1.getColumnId)(column) !== masterDetail.expandColumnId) {
46
+ return React.createElement(React.Fragment, null, children);
47
+ }
48
+ var rowKey = masterDetail.getRowKey(item.values);
49
+ if (rowKey === undefined || rowKey === null) {
50
+ return React.createElement(React.Fragment, null, children);
51
+ }
52
+ var isExpandable = masterDetail.hasDetail(item, sourceIndex);
53
+ var expanded = masterDetail.expandedKeysSet.has(rowKey);
54
+ var toggleId = masterDetail.getToggleElementId(rowKey);
55
+ var detailId = masterDetail.getDetailElementId(rowKey);
56
+ return (React.createElement("span", { className: 'bgrid-master-detail-cell' },
57
+ isExpandable ? (React.createElement("button", { type: 'button', id: toggleId, className: 'bgrid-master-detail-toggle', "aria-expanded": expanded, "aria-controls": expanded ? detailId : undefined, "aria-label": expanded ? masterDetail.collapseAriaLabel : masterDetail.expandAriaLabel, disabled: masterDetail.disabled, onClick: function (event) {
58
+ event.stopPropagation();
59
+ masterDetail.toggle(rowKey, item, sourceIndex);
60
+ }, onKeyDown: function (event) {
61
+ // Prevent master grid cell navigation from capturing Space or Enter on the toggle button
62
+ if (event.key === ' ' || event.key === 'Enter') {
63
+ event.stopPropagation();
64
+ }
65
+ } },
66
+ React.createElement("span", { className: 'bgrid-master-detail-icon', "aria-hidden": 'true' }, expanded ? (_c = (_b = masterDetail.icons) === null || _b === void 0 ? void 0 : _b.expanded) !== null && _c !== void 0 ? _c : '⌄' : (_e = (_d = masterDetail.icons) === null || _d === void 0 ? void 0 : _d.collapsed) !== null && _e !== void 0 ? _e : '›'))) : (React.createElement("span", { className: 'bgrid-master-detail-toggle-spacer', "aria-hidden": 'true' })),
67
+ React.createElement("span", { className: 'bgrid-master-detail-cell-content' }, children)));
68
+ }
69
+ function MasterDetailRow(_a) {
70
+ var _b, _c;
71
+ var item = _a.item, sourceIndex = _a.sourceIndex, visibleIndex = _a.visibleIndex, detailHeight = _a.detailHeight, isLeftRegion = _a.isLeftRegion, viewportWidth = _a.viewportWidth, colSpan = _a.colSpan, frozenColumnsWidth = _a.frozenColumnsWidth;
72
+ var masterDetail = (0, MasterDetailContext_1.useMasterDetailContext)();
73
+ if (!masterDetail)
74
+ return null;
75
+ var rowKey = masterDetail.getRowKey(item.values);
76
+ if (rowKey === undefined || rowKey === null || !masterDetail.expandedKeysSet.has(rowKey)) {
77
+ return null;
78
+ }
79
+ var toggleId = masterDetail.getToggleElementId(rowKey);
80
+ var detailId = masterDetail.getDetailElementId(rowKey);
81
+ if (isLeftRegion) {
82
+ return (React.createElement("tr", { className: 'bgrid-detail-frozen-row', "aria-hidden": 'true', "data-detail-ri": visibleIndex, style: (_b = {
83
+ height: detailHeight
84
+ },
85
+ _b['--bgrid-item-cell-height'] = "".concat(detailHeight, "px"),
86
+ _b) },
87
+ React.createElement("td", { colSpan: colSpan, style: {
88
+ height: detailHeight,
89
+ maxHeight: 'none',
90
+ padding: 0,
91
+ margin: 0,
92
+ } })));
93
+ }
94
+ return (React.createElement("tr", { className: 'bgrid-detail-row', "data-bgrid-detail-owner": 'true', "data-detail-ri": visibleIndex, style: (_c = {
95
+ height: detailHeight
96
+ },
97
+ _c['--bgrid-item-cell-height'] = "".concat(detailHeight, "px"),
98
+ _c) },
99
+ React.createElement("td", { colSpan: colSpan, className: 'bgrid-detail-cell', style: {
100
+ height: detailHeight,
101
+ maxHeight: 'none',
102
+ padding: 0,
103
+ margin: 0,
104
+ verticalAlign: 'top',
105
+ } },
106
+ React.createElement(DetailPanelContent, { item: item, rowKey: rowKey, sourceIndex: sourceIndex, visibleIndex: visibleIndex, detailHeight: detailHeight, viewportWidth: viewportWidth, frozenColumnsWidth: frozenColumnsWidth, toggleId: toggleId, detailId: detailId, detailRender: masterDetail.detailRender, collapse: function () { return masterDetail.collapse(rowKey); } })),
107
+ React.createElement("td", { "data-none": 'true' })));
108
+ }
109
+ function DetailPanelContent(_a) {
110
+ var item = _a.item, rowKey = _a.rowKey, sourceIndex = _a.sourceIndex, visibleIndex = _a.visibleIndex, detailHeight = _a.detailHeight, viewportWidth = _a.viewportWidth, frozenColumnsWidth = _a.frozenColumnsWidth, toggleId = _a.toggleId, detailId = _a.detailId, detailRender = _a.detailRender, collapse = _a.collapse;
111
+ var panelRef = React.useRef(null);
112
+ React.useEffect(function () {
113
+ var panel = panelRef.current;
114
+ return function () {
115
+ var active = document.activeElement;
116
+ if (active && panel && panel.contains(active)) {
117
+ var toggle = document.getElementById(toggleId);
118
+ toggle === null || toggle === void 0 ? void 0 : toggle.focus();
119
+ }
120
+ };
121
+ }, [toggleId]);
122
+ var contentHeight = Math.max(detailHeight - 1, 0);
123
+ return (React.createElement("div", { ref: panelRef, id: detailId, role: 'region', "aria-labelledby": toggleId, className: 'bgrid-master-detail-panel', "data-bgrid-detail-owner": 'true', "data-visible-index": visibleIndex, "data-source-index": sourceIndex, style: {
124
+ position: 'sticky',
125
+ left: frozenColumnsWidth !== null && frozenColumnsWidth !== void 0 ? frozenColumnsWidth : 0,
126
+ width: viewportWidth > 0 ? viewportWidth : undefined,
127
+ maxWidth: '100%',
128
+ height: contentHeight,
129
+ minHeight: contentHeight,
130
+ maxHeight: contentHeight,
131
+ boxSizing: 'border-box',
132
+ overflow: 'auto',
133
+ }, onPointerDown: function (e) {
134
+ e.stopPropagation();
135
+ }, onContextMenu: function (e) {
136
+ e.stopPropagation();
137
+ } }, detailRender({
138
+ item: item,
139
+ rowKey: rowKey,
140
+ sourceIndex: sourceIndex,
141
+ visibleIndex: visibleIndex,
142
+ expanded: true,
143
+ collapse: collapse,
144
+ })));
145
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MasterDetailContext = void 0;
37
+ exports.useMasterDetailContext = useMasterDetailContext;
38
+ var React = __importStar(require("react"));
39
+ exports.MasterDetailContext = React.createContext(undefined);
40
+ function useMasterDetailContext() {
41
+ return React.useContext(exports.MasterDetailContext);
42
+ }