react-open-source-grid 1.7.24 → 1.7.25

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.
@@ -2832,6 +2832,7 @@ var GridBody = ({
2832
2832
  }
2833
2833
  const isSelected = selectedRows.has(row.id);
2834
2834
  const isFocused = (focusState == null ? void 0 : focusState.rowIndex) === rowIndex;
2835
+ const isRowEditing = editState.rowId === row.id;
2835
2836
  const isLoadingRow = row._loading === true;
2836
2837
  const isDragEnabled = (dragRowConfig == null ? void 0 : dragRowConfig.enabled) && !isLoadingRow;
2837
2838
  const showDragHandle = isDragEnabled && dragRowConfig.showDragHandle !== false;
@@ -2851,7 +2852,8 @@ var GridBody = ({
2851
2852
  borderBottom: "var(--grid-border-width, 1px) solid var(--grid-border)",
2852
2853
  backgroundColor: isLoadingRow ? "var(--grid-bg-alt)" : isSelected ? "var(--grid-selected)" : isFocused ? "var(--grid-active)" : "var(--grid-bg)",
2853
2854
  cursor: isLoadingRow ? "wait" : isDragEnabled ? "grab" : "pointer",
2854
- transition: "background-color 0.15s ease"
2855
+ transition: "background-color 0.15s ease",
2856
+ ...isRowEditing ? { position: "relative", zIndex: 100 } : {}
2855
2857
  },
2856
2858
  onMouseEnter: (e) => !isSelected && !isLoadingRow && (e.currentTarget.style.backgroundColor = "var(--grid-hover)"),
2857
2859
  onMouseLeave: (e) => !isSelected && !isLoadingRow && (e.currentTarget.style.backgroundColor = "var(--grid-bg)"),
@@ -2937,7 +2939,8 @@ var GridBody = ({
2937
2939
  flexShrink: 0,
2938
2940
  outline: isCellFocused ? "2px solid var(--grid-primary)" : "none",
2939
2941
  outlineOffset: "-2px",
2940
- color: "var(--grid-text)"
2942
+ color: "var(--grid-text)",
2943
+ ...isEditing ? { position: "relative", zIndex: 1e3 } : {}
2941
2944
  },
2942
2945
  onDoubleClick: () => handleCellDoubleClick(row, field, cellValue),
2943
2946
  onContextMenu: (e) => onContextMenu == null ? void 0 : onContextMenu(e, row, column, rowIndex, columnIndex),
@@ -4276,6 +4279,7 @@ var ExportMenu = ({
4276
4279
 
4277
4280
  // src/components/DataGrid/ColumnFilters.tsx
4278
4281
  var import_react15 = __toESM(require("react"), 1);
4282
+ var import_react_dom2 = __toESM(require("react-dom"), 1);
4279
4283
 
4280
4284
  // src/components/DataGrid/AdvancedFilterBuilder.tsx
4281
4285
  var import_react14 = __toESM(require("react"), 1);
@@ -4594,7 +4598,7 @@ var AdvancedFilterBuilder = ({
4594
4598
  borderRadius: "var(--grid-border-radius, 8px)",
4595
4599
  border: "1px solid var(--grid-border)",
4596
4600
  padding: "16px",
4597
- zIndex: 1001,
4601
+ zIndex: 10001,
4598
4602
  display: "flex",
4599
4603
  flexDirection: "column",
4600
4604
  overflowY: "auto"
@@ -4850,7 +4854,7 @@ var TextFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdvan
4850
4854
  borderRadius: "var(--grid-border-radius, 8px)",
4851
4855
  border: "var(--grid-border-width, 1px) solid var(--grid-border)",
4852
4856
  padding: "16px",
4853
- zIndex: 1e3
4857
+ zIndex: 1e4
4854
4858
  },
4855
4859
  onClick: (e) => e.stopPropagation()
4856
4860
  },
@@ -4972,7 +4976,7 @@ var NumberFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdv
4972
4976
  borderRadius: "var(--grid-border-radius, 8px)",
4973
4977
  border: "1px solid var(--grid-border)",
4974
4978
  padding: "16px",
4975
- zIndex: 1e3
4979
+ zIndex: 1e4
4976
4980
  },
4977
4981
  onClick: (e) => e.stopPropagation()
4978
4982
  },
@@ -5088,7 +5092,7 @@ var DateFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdvan
5088
5092
  borderRadius: "var(--grid-border-radius, 8px)",
5089
5093
  border: "1px solid var(--grid-border)",
5090
5094
  padding: "16px",
5091
- zIndex: 1e3
5095
+ zIndex: 1e4
5092
5096
  },
5093
5097
  onClick: (e) => e.stopPropagation()
5094
5098
  },
@@ -5213,7 +5217,7 @@ var SetFilterMenu = ({ column, filterValue, onApplyFilter, onClose, rows, anchor
5213
5217
  borderRadius: "var(--grid-border-radius, 8px)",
5214
5218
  border: "1px solid var(--grid-border)",
5215
5219
  padding: "16px",
5216
- zIndex: 1e3,
5220
+ zIndex: 1e4,
5217
5221
  display: "flex",
5218
5222
  flexDirection: "column"
5219
5223
  },
@@ -5569,8 +5573,8 @@ var ColumnFilters = ({
5569
5573
  )
5570
5574
  )
5571
5575
  ),
5572
- openFilterMenu === field && renderFilterMenu(column),
5573
- advancedFilterField === field && renderAdvancedFilterMenu(column)
5576
+ openFilterMenu === field && import_react_dom2.default.createPortal(renderFilterMenu(column), document.body),
5577
+ advancedFilterField === field && import_react_dom2.default.createPortal(renderAdvancedFilterMenu(column), document.body)
5574
5578
  );
5575
5579
  })));
5576
5580
  };
@@ -6518,7 +6522,7 @@ var useContextMenu = ({
6518
6522
 
6519
6523
  // src/components/DataGrid/Tooltip.tsx
6520
6524
  var import_react19 = __toESM(require("react"), 1);
6521
- var import_react_dom2 = require("react-dom");
6525
+ var import_react_dom3 = require("react-dom");
6522
6526
  var Tooltip = ({
6523
6527
  state,
6524
6528
  maxWidth = 300,
@@ -6689,7 +6693,7 @@ var Tooltip = ({
6689
6693
  }
6690
6694
  )
6691
6695
  );
6692
- return (0, import_react_dom2.createPortal)(tooltipElement, document.body);
6696
+ return (0, import_react_dom3.createPortal)(tooltipElement, document.body);
6693
6697
  };
6694
6698
 
6695
6699
  // src/components/DataGrid/useTooltip.tsx
@@ -13041,20 +13045,20 @@ function usePopupPosition(anchorRef, popupRef, isOpen, placement = "auto") {
13041
13045
  }
13042
13046
  switch (actualPlacement) {
13043
13047
  case "bottom":
13044
- top = anchorRect.bottom + window.scrollY;
13045
- left = anchorRect.left + window.scrollX;
13048
+ top = anchorRect.bottom;
13049
+ left = anchorRect.left;
13046
13050
  break;
13047
13051
  case "top":
13048
- top = anchorRect.top + window.scrollY - popupRect.height;
13049
- left = anchorRect.left + window.scrollX;
13052
+ top = anchorRect.top - popupRect.height;
13053
+ left = anchorRect.left;
13050
13054
  break;
13051
13055
  case "right":
13052
- top = anchorRect.top + window.scrollY;
13053
- left = anchorRect.right + window.scrollX;
13056
+ top = anchorRect.top;
13057
+ left = anchorRect.right;
13054
13058
  break;
13055
13059
  case "left":
13056
- top = anchorRect.top + window.scrollY;
13057
- left = anchorRect.left + window.scrollX - popupRect.width;
13060
+ top = anchorRect.top;
13061
+ left = anchorRect.left - popupRect.width;
13058
13062
  break;
13059
13063
  }
13060
13064
  const margin = 8;
@@ -13064,11 +13068,11 @@ function usePopupPosition(anchorRef, popupRef, isOpen, placement = "auto") {
13064
13068
  if (left < margin) {
13065
13069
  left = margin;
13066
13070
  }
13067
- if (top + popupRect.height > viewportHeight + window.scrollY) {
13068
- top = viewportHeight + window.scrollY - popupRect.height - margin;
13071
+ if (top + popupRect.height > viewportHeight) {
13072
+ top = viewportHeight - popupRect.height - margin;
13069
13073
  }
13070
- if (top < window.scrollY + margin) {
13071
- top = window.scrollY + margin;
13074
+ if (top < margin) {
13075
+ top = margin;
13072
13076
  }
13073
13077
  popup.style.top = `${top}px`;
13074
13078
  popup.style.left = `${left}px`;
@@ -13113,6 +13117,7 @@ function filterOptions(options, searchQuery) {
13113
13117
 
13114
13118
  // src/editors/RichSelectEditor.tsx
13115
13119
  var import_react37 = __toESM(require("react"), 1);
13120
+ var import_react_dom4 = __toESM(require("react-dom"), 1);
13116
13121
  function RichSelectEditor(props) {
13117
13122
  const {
13118
13123
  value,
@@ -13269,31 +13274,34 @@ function RichSelectEditor(props) {
13269
13274
  },
13270
13275
  "\xD7"
13271
13276
  ), /* @__PURE__ */ import_react37.default.createElement("span", { className: "editor-dropdown-icon", "aria-hidden": "true" }, "\u25BC"))),
13272
- isOpen && /* @__PURE__ */ import_react37.default.createElement(
13273
- "div",
13274
- {
13275
- ref: dropdownRef,
13276
- id: "richselect-dropdown",
13277
- className: "editor-dropdown",
13278
- role: "listbox",
13279
- style: { maxHeight: maxDropdownHeight }
13280
- },
13281
- filteredOptions.length === 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => /* @__PURE__ */ import_react37.default.createElement(
13277
+ isOpen && import_react_dom4.default.createPortal(
13278
+ /* @__PURE__ */ import_react37.default.createElement(
13282
13279
  "div",
13283
13280
  {
13284
- key: option.value,
13285
- ref: (el) => {
13286
- optionRefs.current[index] = el;
13287
- },
13288
- className: `editor-dropdown-option ${option.value === value ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13289
- role: "option",
13290
- "aria-selected": option.value === value,
13291
- "aria-disabled": option.disabled,
13292
- onClick: () => handleSelectOption(option),
13293
- onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13281
+ ref: dropdownRef,
13282
+ id: "richselect-dropdown",
13283
+ className: "editor-dropdown",
13284
+ role: "listbox",
13285
+ style: { maxHeight: maxDropdownHeight }
13294
13286
  },
13295
- renderLabel(option)
13296
- ))
13287
+ filteredOptions.length === 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => /* @__PURE__ */ import_react37.default.createElement(
13288
+ "div",
13289
+ {
13290
+ key: option.value,
13291
+ ref: (el) => {
13292
+ optionRefs.current[index] = el;
13293
+ },
13294
+ className: `editor-dropdown-option ${option.value === value ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13295
+ role: "option",
13296
+ "aria-selected": option.value === value,
13297
+ "aria-disabled": option.disabled,
13298
+ onClick: () => handleSelectOption(option),
13299
+ onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13300
+ },
13301
+ renderLabel(option)
13302
+ ))
13303
+ ),
13304
+ document.body
13297
13305
  )
13298
13306
  );
13299
13307
  }
@@ -13301,6 +13309,7 @@ RichSelectEditor.displayName = "RichSelectEditor";
13301
13309
 
13302
13310
  // src/editors/DateEditor.tsx
13303
13311
  var import_react38 = __toESM(require("react"), 1);
13312
+ var import_react_dom5 = __toESM(require("react-dom"), 1);
13304
13313
  function DateEditor(props) {
13305
13314
  const {
13306
13315
  value,
@@ -13420,53 +13429,56 @@ function DateEditor(props) {
13420
13429
  autoComplete: "off"
13421
13430
  }
13422
13431
  ), /* @__PURE__ */ import_react38.default.createElement("span", { className: "editor-calendar-icon", "aria-hidden": "true" }, "\u{1F4C5}")),
13423
- isOpen && /* @__PURE__ */ import_react38.default.createElement("div", { ref: calendarRef, className: "editor-dropdown editor-calendar" }, /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-header" }, /* @__PURE__ */ import_react38.default.createElement(
13424
- "button",
13425
- {
13426
- type: "button",
13427
- className: "editor-calendar-nav",
13428
- onClick: handlePrevMonth,
13429
- "aria-label": "Previous month"
13430
- },
13431
- "\u2039"
13432
- ), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-title" }, viewDate.toLocaleDateString("en-US", {
13433
- month: "long",
13434
- year: "numeric"
13435
- })), /* @__PURE__ */ import_react38.default.createElement(
13436
- "button",
13437
- {
13438
- type: "button",
13439
- className: "editor-calendar-nav",
13440
- onClick: handleNextMonth,
13441
- "aria-label": "Next month"
13442
- },
13443
- "\u203A"
13444
- )), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-weekdays" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ import_react38.default.createElement("div", { key: day, className: "editor-calendar-weekday" }, day))), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-days" }, calendarDays.map((day, index) => /* @__PURE__ */ import_react38.default.createElement(
13445
- "button",
13446
- {
13447
- key: index,
13448
- type: "button",
13449
- className: `editor-calendar-day ${day.className}`,
13450
- onClick: () => day.date && handleSelectDate(day.date),
13451
- disabled: day.disabled,
13452
- "aria-label": day.date ? day.date.toDateString() : ""
13453
- },
13454
- day.label
13455
- ))), showTime && /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-time" }, /* @__PURE__ */ import_react38.default.createElement(
13456
- "input",
13457
- {
13458
- type: "time",
13459
- className: "editor-time-input",
13460
- value: parsedValue ? `${String(parsedValue.getHours()).padStart(2, "0")}:${String(
13461
- parsedValue.getMinutes()
13462
- ).padStart(2, "0")}` : "00:00",
13463
- onChange: (e) => {
13464
- const [hours, minutes] = e.target.value.split(":").map(Number);
13465
- handleTimeChange(hours, minutes);
13432
+ isOpen && import_react_dom5.default.createPortal(
13433
+ /* @__PURE__ */ import_react38.default.createElement("div", { ref: calendarRef, className: "editor-dropdown editor-calendar" }, /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-header" }, /* @__PURE__ */ import_react38.default.createElement(
13434
+ "button",
13435
+ {
13436
+ type: "button",
13437
+ className: "editor-calendar-nav",
13438
+ onClick: handlePrevMonth,
13439
+ "aria-label": "Previous month"
13466
13440
  },
13467
- "aria-label": "Time input"
13468
- }
13469
- )))
13441
+ "\u2039"
13442
+ ), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-title" }, viewDate.toLocaleDateString("en-US", {
13443
+ month: "long",
13444
+ year: "numeric"
13445
+ })), /* @__PURE__ */ import_react38.default.createElement(
13446
+ "button",
13447
+ {
13448
+ type: "button",
13449
+ className: "editor-calendar-nav",
13450
+ onClick: handleNextMonth,
13451
+ "aria-label": "Next month"
13452
+ },
13453
+ "\u203A"
13454
+ )), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-weekdays" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ import_react38.default.createElement("div", { key: day, className: "editor-calendar-weekday" }, day))), /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-days" }, calendarDays.map((day, index) => /* @__PURE__ */ import_react38.default.createElement(
13455
+ "button",
13456
+ {
13457
+ key: index,
13458
+ type: "button",
13459
+ className: `editor-calendar-day ${day.className}`,
13460
+ onClick: () => day.date && handleSelectDate(day.date),
13461
+ disabled: day.disabled,
13462
+ "aria-label": day.date ? day.date.toDateString() : ""
13463
+ },
13464
+ day.label
13465
+ ))), showTime && /* @__PURE__ */ import_react38.default.createElement("div", { className: "editor-calendar-time" }, /* @__PURE__ */ import_react38.default.createElement(
13466
+ "input",
13467
+ {
13468
+ type: "time",
13469
+ className: "editor-time-input",
13470
+ value: parsedValue ? `${String(parsedValue.getHours()).padStart(2, "0")}:${String(
13471
+ parsedValue.getMinutes()
13472
+ ).padStart(2, "0")}` : "00:00",
13473
+ onChange: (e) => {
13474
+ const [hours, minutes] = e.target.value.split(":").map(Number);
13475
+ handleTimeChange(hours, minutes);
13476
+ },
13477
+ "aria-label": "Time input"
13478
+ }
13479
+ ))),
13480
+ document.body
13481
+ )
13470
13482
  );
13471
13483
  }
13472
13484
  DateEditor.displayName = "DateEditor";
@@ -13723,6 +13735,7 @@ NumericEditor.displayName = "NumericEditor";
13723
13735
 
13724
13736
  // src/editors/MultiSelectEditor.tsx
13725
13737
  var import_react40 = __toESM(require("react"), 1);
13738
+ var import_react_dom6 = __toESM(require("react-dom"), 1);
13726
13739
  function MultiSelectEditor(props) {
13727
13740
  const {
13728
13741
  value = [],
@@ -13890,45 +13903,48 @@ function MultiSelectEditor(props) {
13890
13903
  ),
13891
13904
  /* @__PURE__ */ import_react40.default.createElement("span", { className: "editor-dropdown-icon", "aria-hidden": "true" }, "\u25BC")
13892
13905
  ),
13893
- isOpen && /* @__PURE__ */ import_react40.default.createElement(
13894
- "div",
13895
- {
13896
- ref: dropdownRef,
13897
- id: "multiselect-dropdown",
13898
- className: "editor-dropdown",
13899
- role: "listbox",
13900
- "aria-multiselectable": "true",
13901
- style: { maxHeight: maxDropdownHeight }
13902
- },
13903
- filteredOptions.length === 0 ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => {
13904
- const isSelected = selectedValues.includes(option.value);
13905
- return /* @__PURE__ */ import_react40.default.createElement(
13906
- "div",
13907
- {
13908
- key: option.value,
13909
- className: `editor-dropdown-option editor-multiselect-option ${isSelected ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13910
- role: "option",
13911
- "aria-selected": isSelected,
13912
- "aria-disabled": option.disabled,
13913
- onClick: () => handleToggleOption(option),
13914
- onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13915
- },
13916
- /* @__PURE__ */ import_react40.default.createElement(
13917
- "input",
13906
+ isOpen && import_react_dom6.default.createPortal(
13907
+ /* @__PURE__ */ import_react40.default.createElement(
13908
+ "div",
13909
+ {
13910
+ ref: dropdownRef,
13911
+ id: "multiselect-dropdown",
13912
+ className: "editor-dropdown",
13913
+ role: "listbox",
13914
+ "aria-multiselectable": "true",
13915
+ style: { maxHeight: maxDropdownHeight }
13916
+ },
13917
+ filteredOptions.length === 0 ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => {
13918
+ const isSelected = selectedValues.includes(option.value);
13919
+ return /* @__PURE__ */ import_react40.default.createElement(
13920
+ "div",
13918
13921
  {
13919
- type: "checkbox",
13920
- className: "editor-multiselect-checkbox",
13921
- checked: isSelected,
13922
- onChange: () => {
13923
- },
13924
- disabled: option.disabled,
13925
- tabIndex: -1,
13926
- "aria-hidden": "true"
13927
- }
13928
- ),
13929
- /* @__PURE__ */ import_react40.default.createElement("div", { className: "editor-option-content" }, option.icon && /* @__PURE__ */ import_react40.default.createElement("span", { className: "editor-option-icon" }, option.icon), /* @__PURE__ */ import_react40.default.createElement("span", { className: "editor-option-label" }, option.label))
13930
- );
13931
- })
13922
+ key: option.value,
13923
+ className: `editor-dropdown-option editor-multiselect-option ${isSelected ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13924
+ role: "option",
13925
+ "aria-selected": isSelected,
13926
+ "aria-disabled": option.disabled,
13927
+ onClick: () => handleToggleOption(option),
13928
+ onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13929
+ },
13930
+ /* @__PURE__ */ import_react40.default.createElement(
13931
+ "input",
13932
+ {
13933
+ type: "checkbox",
13934
+ className: "editor-multiselect-checkbox",
13935
+ checked: isSelected,
13936
+ onChange: () => {
13937
+ },
13938
+ disabled: option.disabled,
13939
+ tabIndex: -1,
13940
+ "aria-hidden": "true"
13941
+ }
13942
+ ),
13943
+ /* @__PURE__ */ import_react40.default.createElement("div", { className: "editor-option-content" }, option.icon && /* @__PURE__ */ import_react40.default.createElement("span", { className: "editor-option-icon" }, option.icon), /* @__PURE__ */ import_react40.default.createElement("span", { className: "editor-option-label" }, option.label))
13944
+ );
13945
+ })
13946
+ ),
13947
+ document.body
13932
13948
  )
13933
13949
  );
13934
13950
  }
package/dist/lib/index.js CHANGED
@@ -2410,6 +2410,7 @@ var GridBody = ({
2410
2410
  }
2411
2411
  const isSelected = selectedRows.has(row.id);
2412
2412
  const isFocused = (focusState == null ? void 0 : focusState.rowIndex) === rowIndex;
2413
+ const isRowEditing = editState.rowId === row.id;
2413
2414
  const isLoadingRow = row._loading === true;
2414
2415
  const isDragEnabled = (dragRowConfig == null ? void 0 : dragRowConfig.enabled) && !isLoadingRow;
2415
2416
  const showDragHandle = isDragEnabled && dragRowConfig.showDragHandle !== false;
@@ -2429,7 +2430,8 @@ var GridBody = ({
2429
2430
  borderBottom: "var(--grid-border-width, 1px) solid var(--grid-border)",
2430
2431
  backgroundColor: isLoadingRow ? "var(--grid-bg-alt)" : isSelected ? "var(--grid-selected)" : isFocused ? "var(--grid-active)" : "var(--grid-bg)",
2431
2432
  cursor: isLoadingRow ? "wait" : isDragEnabled ? "grab" : "pointer",
2432
- transition: "background-color 0.15s ease"
2433
+ transition: "background-color 0.15s ease",
2434
+ ...isRowEditing ? { position: "relative", zIndex: 100 } : {}
2433
2435
  },
2434
2436
  onMouseEnter: (e) => !isSelected && !isLoadingRow && (e.currentTarget.style.backgroundColor = "var(--grid-hover)"),
2435
2437
  onMouseLeave: (e) => !isSelected && !isLoadingRow && (e.currentTarget.style.backgroundColor = "var(--grid-bg)"),
@@ -2515,7 +2517,8 @@ var GridBody = ({
2515
2517
  flexShrink: 0,
2516
2518
  outline: isCellFocused ? "2px solid var(--grid-primary)" : "none",
2517
2519
  outlineOffset: "-2px",
2518
- color: "var(--grid-text)"
2520
+ color: "var(--grid-text)",
2521
+ ...isEditing ? { position: "relative", zIndex: 1e3 } : {}
2519
2522
  },
2520
2523
  onDoubleClick: () => handleCellDoubleClick(row, field, cellValue),
2521
2524
  onContextMenu: (e) => onContextMenu == null ? void 0 : onContextMenu(e, row, column, rowIndex, columnIndex),
@@ -3854,6 +3857,7 @@ var ExportMenu = ({
3854
3857
 
3855
3858
  // src/components/DataGrid/ColumnFilters.tsx
3856
3859
  import React15, { useState as useState8, useEffect as useEffect4 } from "react";
3860
+ import ReactDOM from "react-dom";
3857
3861
 
3858
3862
  // src/components/DataGrid/AdvancedFilterBuilder.tsx
3859
3863
  import React14, { useState as useState7 } from "react";
@@ -4172,7 +4176,7 @@ var AdvancedFilterBuilder = ({
4172
4176
  borderRadius: "var(--grid-border-radius, 8px)",
4173
4177
  border: "1px solid var(--grid-border)",
4174
4178
  padding: "16px",
4175
- zIndex: 1001,
4179
+ zIndex: 10001,
4176
4180
  display: "flex",
4177
4181
  flexDirection: "column",
4178
4182
  overflowY: "auto"
@@ -4428,7 +4432,7 @@ var TextFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdvan
4428
4432
  borderRadius: "var(--grid-border-radius, 8px)",
4429
4433
  border: "var(--grid-border-width, 1px) solid var(--grid-border)",
4430
4434
  padding: "16px",
4431
- zIndex: 1e3
4435
+ zIndex: 1e4
4432
4436
  },
4433
4437
  onClick: (e) => e.stopPropagation()
4434
4438
  },
@@ -4550,7 +4554,7 @@ var NumberFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdv
4550
4554
  borderRadius: "var(--grid-border-radius, 8px)",
4551
4555
  border: "1px solid var(--grid-border)",
4552
4556
  padding: "16px",
4553
- zIndex: 1e3
4557
+ zIndex: 1e4
4554
4558
  },
4555
4559
  onClick: (e) => e.stopPropagation()
4556
4560
  },
@@ -4666,7 +4670,7 @@ var DateFilterMenu = ({ filterValue, onApplyFilter, onClose, anchorEl, showAdvan
4666
4670
  borderRadius: "var(--grid-border-radius, 8px)",
4667
4671
  border: "1px solid var(--grid-border)",
4668
4672
  padding: "16px",
4669
- zIndex: 1e3
4673
+ zIndex: 1e4
4670
4674
  },
4671
4675
  onClick: (e) => e.stopPropagation()
4672
4676
  },
@@ -4791,7 +4795,7 @@ var SetFilterMenu = ({ column, filterValue, onApplyFilter, onClose, rows, anchor
4791
4795
  borderRadius: "var(--grid-border-radius, 8px)",
4792
4796
  border: "1px solid var(--grid-border)",
4793
4797
  padding: "16px",
4794
- zIndex: 1e3,
4798
+ zIndex: 1e4,
4795
4799
  display: "flex",
4796
4800
  flexDirection: "column"
4797
4801
  },
@@ -5147,8 +5151,8 @@ var ColumnFilters = ({
5147
5151
  )
5148
5152
  )
5149
5153
  ),
5150
- openFilterMenu === field && renderFilterMenu(column),
5151
- advancedFilterField === field && renderAdvancedFilterMenu(column)
5154
+ openFilterMenu === field && ReactDOM.createPortal(renderFilterMenu(column), document.body),
5155
+ advancedFilterField === field && ReactDOM.createPortal(renderAdvancedFilterMenu(column), document.body)
5152
5156
  );
5153
5157
  })));
5154
5158
  };
@@ -12613,20 +12617,20 @@ function usePopupPosition(anchorRef, popupRef, isOpen, placement = "auto") {
12613
12617
  }
12614
12618
  switch (actualPlacement) {
12615
12619
  case "bottom":
12616
- top = anchorRect.bottom + window.scrollY;
12617
- left = anchorRect.left + window.scrollX;
12620
+ top = anchorRect.bottom;
12621
+ left = anchorRect.left;
12618
12622
  break;
12619
12623
  case "top":
12620
- top = anchorRect.top + window.scrollY - popupRect.height;
12621
- left = anchorRect.left + window.scrollX;
12624
+ top = anchorRect.top - popupRect.height;
12625
+ left = anchorRect.left;
12622
12626
  break;
12623
12627
  case "right":
12624
- top = anchorRect.top + window.scrollY;
12625
- left = anchorRect.right + window.scrollX;
12628
+ top = anchorRect.top;
12629
+ left = anchorRect.right;
12626
12630
  break;
12627
12631
  case "left":
12628
- top = anchorRect.top + window.scrollY;
12629
- left = anchorRect.left + window.scrollX - popupRect.width;
12632
+ top = anchorRect.top;
12633
+ left = anchorRect.left - popupRect.width;
12630
12634
  break;
12631
12635
  }
12632
12636
  const margin = 8;
@@ -12636,11 +12640,11 @@ function usePopupPosition(anchorRef, popupRef, isOpen, placement = "auto") {
12636
12640
  if (left < margin) {
12637
12641
  left = margin;
12638
12642
  }
12639
- if (top + popupRect.height > viewportHeight + window.scrollY) {
12640
- top = viewportHeight + window.scrollY - popupRect.height - margin;
12643
+ if (top + popupRect.height > viewportHeight) {
12644
+ top = viewportHeight - popupRect.height - margin;
12641
12645
  }
12642
- if (top < window.scrollY + margin) {
12643
- top = window.scrollY + margin;
12646
+ if (top < margin) {
12647
+ top = margin;
12644
12648
  }
12645
12649
  popup.style.top = `${top}px`;
12646
12650
  popup.style.left = `${left}px`;
@@ -12685,6 +12689,7 @@ function filterOptions(options, searchQuery) {
12685
12689
 
12686
12690
  // src/editors/RichSelectEditor.tsx
12687
12691
  import React32, { useState as useState21, useRef as useRef16, useEffect as useEffect15, useMemo as useMemo9 } from "react";
12692
+ import ReactDOM2 from "react-dom";
12688
12693
  function RichSelectEditor(props) {
12689
12694
  const {
12690
12695
  value,
@@ -12841,31 +12846,34 @@ function RichSelectEditor(props) {
12841
12846
  },
12842
12847
  "\xD7"
12843
12848
  ), /* @__PURE__ */ React32.createElement("span", { className: "editor-dropdown-icon", "aria-hidden": "true" }, "\u25BC"))),
12844
- isOpen && /* @__PURE__ */ React32.createElement(
12845
- "div",
12846
- {
12847
- ref: dropdownRef,
12848
- id: "richselect-dropdown",
12849
- className: "editor-dropdown",
12850
- role: "listbox",
12851
- style: { maxHeight: maxDropdownHeight }
12852
- },
12853
- filteredOptions.length === 0 ? /* @__PURE__ */ React32.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => /* @__PURE__ */ React32.createElement(
12849
+ isOpen && ReactDOM2.createPortal(
12850
+ /* @__PURE__ */ React32.createElement(
12854
12851
  "div",
12855
12852
  {
12856
- key: option.value,
12857
- ref: (el) => {
12858
- optionRefs.current[index] = el;
12859
- },
12860
- className: `editor-dropdown-option ${option.value === value ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
12861
- role: "option",
12862
- "aria-selected": option.value === value,
12863
- "aria-disabled": option.disabled,
12864
- onClick: () => handleSelectOption(option),
12865
- onMouseEnter: () => !option.disabled && setFocusedIndex(index)
12853
+ ref: dropdownRef,
12854
+ id: "richselect-dropdown",
12855
+ className: "editor-dropdown",
12856
+ role: "listbox",
12857
+ style: { maxHeight: maxDropdownHeight }
12866
12858
  },
12867
- renderLabel(option)
12868
- ))
12859
+ filteredOptions.length === 0 ? /* @__PURE__ */ React32.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => /* @__PURE__ */ React32.createElement(
12860
+ "div",
12861
+ {
12862
+ key: option.value,
12863
+ ref: (el) => {
12864
+ optionRefs.current[index] = el;
12865
+ },
12866
+ className: `editor-dropdown-option ${option.value === value ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
12867
+ role: "option",
12868
+ "aria-selected": option.value === value,
12869
+ "aria-disabled": option.disabled,
12870
+ onClick: () => handleSelectOption(option),
12871
+ onMouseEnter: () => !option.disabled && setFocusedIndex(index)
12872
+ },
12873
+ renderLabel(option)
12874
+ ))
12875
+ ),
12876
+ document.body
12869
12877
  )
12870
12878
  );
12871
12879
  }
@@ -12873,6 +12881,7 @@ RichSelectEditor.displayName = "RichSelectEditor";
12873
12881
 
12874
12882
  // src/editors/DateEditor.tsx
12875
12883
  import React33, { useState as useState22, useRef as useRef17, useMemo as useMemo10 } from "react";
12884
+ import ReactDOM3 from "react-dom";
12876
12885
  function DateEditor(props) {
12877
12886
  const {
12878
12887
  value,
@@ -12992,53 +13001,56 @@ function DateEditor(props) {
12992
13001
  autoComplete: "off"
12993
13002
  }
12994
13003
  ), /* @__PURE__ */ React33.createElement("span", { className: "editor-calendar-icon", "aria-hidden": "true" }, "\u{1F4C5}")),
12995
- isOpen && /* @__PURE__ */ React33.createElement("div", { ref: calendarRef, className: "editor-dropdown editor-calendar" }, /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-header" }, /* @__PURE__ */ React33.createElement(
12996
- "button",
12997
- {
12998
- type: "button",
12999
- className: "editor-calendar-nav",
13000
- onClick: handlePrevMonth,
13001
- "aria-label": "Previous month"
13002
- },
13003
- "\u2039"
13004
- ), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-title" }, viewDate.toLocaleDateString("en-US", {
13005
- month: "long",
13006
- year: "numeric"
13007
- })), /* @__PURE__ */ React33.createElement(
13008
- "button",
13009
- {
13010
- type: "button",
13011
- className: "editor-calendar-nav",
13012
- onClick: handleNextMonth,
13013
- "aria-label": "Next month"
13014
- },
13015
- "\u203A"
13016
- )), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-weekdays" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React33.createElement("div", { key: day, className: "editor-calendar-weekday" }, day))), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-days" }, calendarDays.map((day, index) => /* @__PURE__ */ React33.createElement(
13017
- "button",
13018
- {
13019
- key: index,
13020
- type: "button",
13021
- className: `editor-calendar-day ${day.className}`,
13022
- onClick: () => day.date && handleSelectDate(day.date),
13023
- disabled: day.disabled,
13024
- "aria-label": day.date ? day.date.toDateString() : ""
13025
- },
13026
- day.label
13027
- ))), showTime && /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-time" }, /* @__PURE__ */ React33.createElement(
13028
- "input",
13029
- {
13030
- type: "time",
13031
- className: "editor-time-input",
13032
- value: parsedValue ? `${String(parsedValue.getHours()).padStart(2, "0")}:${String(
13033
- parsedValue.getMinutes()
13034
- ).padStart(2, "0")}` : "00:00",
13035
- onChange: (e) => {
13036
- const [hours, minutes] = e.target.value.split(":").map(Number);
13037
- handleTimeChange(hours, minutes);
13004
+ isOpen && ReactDOM3.createPortal(
13005
+ /* @__PURE__ */ React33.createElement("div", { ref: calendarRef, className: "editor-dropdown editor-calendar" }, /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-header" }, /* @__PURE__ */ React33.createElement(
13006
+ "button",
13007
+ {
13008
+ type: "button",
13009
+ className: "editor-calendar-nav",
13010
+ onClick: handlePrevMonth,
13011
+ "aria-label": "Previous month"
13038
13012
  },
13039
- "aria-label": "Time input"
13040
- }
13041
- )))
13013
+ "\u2039"
13014
+ ), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-title" }, viewDate.toLocaleDateString("en-US", {
13015
+ month: "long",
13016
+ year: "numeric"
13017
+ })), /* @__PURE__ */ React33.createElement(
13018
+ "button",
13019
+ {
13020
+ type: "button",
13021
+ className: "editor-calendar-nav",
13022
+ onClick: handleNextMonth,
13023
+ "aria-label": "Next month"
13024
+ },
13025
+ "\u203A"
13026
+ )), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-weekdays" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React33.createElement("div", { key: day, className: "editor-calendar-weekday" }, day))), /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-days" }, calendarDays.map((day, index) => /* @__PURE__ */ React33.createElement(
13027
+ "button",
13028
+ {
13029
+ key: index,
13030
+ type: "button",
13031
+ className: `editor-calendar-day ${day.className}`,
13032
+ onClick: () => day.date && handleSelectDate(day.date),
13033
+ disabled: day.disabled,
13034
+ "aria-label": day.date ? day.date.toDateString() : ""
13035
+ },
13036
+ day.label
13037
+ ))), showTime && /* @__PURE__ */ React33.createElement("div", { className: "editor-calendar-time" }, /* @__PURE__ */ React33.createElement(
13038
+ "input",
13039
+ {
13040
+ type: "time",
13041
+ className: "editor-time-input",
13042
+ value: parsedValue ? `${String(parsedValue.getHours()).padStart(2, "0")}:${String(
13043
+ parsedValue.getMinutes()
13044
+ ).padStart(2, "0")}` : "00:00",
13045
+ onChange: (e) => {
13046
+ const [hours, minutes] = e.target.value.split(":").map(Number);
13047
+ handleTimeChange(hours, minutes);
13048
+ },
13049
+ "aria-label": "Time input"
13050
+ }
13051
+ ))),
13052
+ document.body
13053
+ )
13042
13054
  );
13043
13055
  }
13044
13056
  DateEditor.displayName = "DateEditor";
@@ -13295,6 +13307,7 @@ NumericEditor.displayName = "NumericEditor";
13295
13307
 
13296
13308
  // src/editors/MultiSelectEditor.tsx
13297
13309
  import React35, { useState as useState24, useRef as useRef18, useMemo as useMemo11 } from "react";
13310
+ import ReactDOM4 from "react-dom";
13298
13311
  function MultiSelectEditor(props) {
13299
13312
  const {
13300
13313
  value = [],
@@ -13462,45 +13475,48 @@ function MultiSelectEditor(props) {
13462
13475
  ),
13463
13476
  /* @__PURE__ */ React35.createElement("span", { className: "editor-dropdown-icon", "aria-hidden": "true" }, "\u25BC")
13464
13477
  ),
13465
- isOpen && /* @__PURE__ */ React35.createElement(
13466
- "div",
13467
- {
13468
- ref: dropdownRef,
13469
- id: "multiselect-dropdown",
13470
- className: "editor-dropdown",
13471
- role: "listbox",
13472
- "aria-multiselectable": "true",
13473
- style: { maxHeight: maxDropdownHeight }
13474
- },
13475
- filteredOptions.length === 0 ? /* @__PURE__ */ React35.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => {
13476
- const isSelected = selectedValues.includes(option.value);
13477
- return /* @__PURE__ */ React35.createElement(
13478
- "div",
13479
- {
13480
- key: option.value,
13481
- className: `editor-dropdown-option editor-multiselect-option ${isSelected ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13482
- role: "option",
13483
- "aria-selected": isSelected,
13484
- "aria-disabled": option.disabled,
13485
- onClick: () => handleToggleOption(option),
13486
- onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13487
- },
13488
- /* @__PURE__ */ React35.createElement(
13489
- "input",
13478
+ isOpen && ReactDOM4.createPortal(
13479
+ /* @__PURE__ */ React35.createElement(
13480
+ "div",
13481
+ {
13482
+ ref: dropdownRef,
13483
+ id: "multiselect-dropdown",
13484
+ className: "editor-dropdown",
13485
+ role: "listbox",
13486
+ "aria-multiselectable": "true",
13487
+ style: { maxHeight: maxDropdownHeight }
13488
+ },
13489
+ filteredOptions.length === 0 ? /* @__PURE__ */ React35.createElement("div", { className: "editor-dropdown-empty" }, "No options found") : filteredOptions.map((option, index) => {
13490
+ const isSelected = selectedValues.includes(option.value);
13491
+ return /* @__PURE__ */ React35.createElement(
13492
+ "div",
13490
13493
  {
13491
- type: "checkbox",
13492
- className: "editor-multiselect-checkbox",
13493
- checked: isSelected,
13494
- onChange: () => {
13495
- },
13496
- disabled: option.disabled,
13497
- tabIndex: -1,
13498
- "aria-hidden": "true"
13499
- }
13500
- ),
13501
- /* @__PURE__ */ React35.createElement("div", { className: "editor-option-content" }, option.icon && /* @__PURE__ */ React35.createElement("span", { className: "editor-option-icon" }, option.icon), /* @__PURE__ */ React35.createElement("span", { className: "editor-option-label" }, option.label))
13502
- );
13503
- })
13494
+ key: option.value,
13495
+ className: `editor-dropdown-option editor-multiselect-option ${isSelected ? "selected" : ""} ${option.disabled ? "disabled" : ""} ${index === focusedIndex ? "focused" : ""}`,
13496
+ role: "option",
13497
+ "aria-selected": isSelected,
13498
+ "aria-disabled": option.disabled,
13499
+ onClick: () => handleToggleOption(option),
13500
+ onMouseEnter: () => !option.disabled && setFocusedIndex(index)
13501
+ },
13502
+ /* @__PURE__ */ React35.createElement(
13503
+ "input",
13504
+ {
13505
+ type: "checkbox",
13506
+ className: "editor-multiselect-checkbox",
13507
+ checked: isSelected,
13508
+ onChange: () => {
13509
+ },
13510
+ disabled: option.disabled,
13511
+ tabIndex: -1,
13512
+ "aria-hidden": "true"
13513
+ }
13514
+ ),
13515
+ /* @__PURE__ */ React35.createElement("div", { className: "editor-option-content" }, option.icon && /* @__PURE__ */ React35.createElement("span", { className: "editor-option-icon" }, option.icon), /* @__PURE__ */ React35.createElement("span", { className: "editor-option-label" }, option.label))
13516
+ );
13517
+ })
13518
+ ),
13519
+ document.body
13504
13520
  )
13505
13521
  );
13506
13522
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-open-source-grid",
3
3
  "private": false,
4
- "version": "1.7.24",
4
+ "version": "1.7.25",
5
5
  "type": "module",
6
6
  "description": "A high-performance React DataGrid component with advanced features like virtual scrolling, infinite scrolling, tree data, market data mode, integrated charts with context menu, and more",
7
7
  "main": "./dist/lib/index.cjs",