@clickhouse/click-ui 0.0.171 → 0.0.172

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.
@@ -16914,9 +16914,46 @@ function throttle$1(func, wait, options) {
16914
16914
  }
16915
16915
  var throttle_1 = throttle$1;
16916
16916
  const throttle$2 = /* @__PURE__ */ getDefaultExportFromCjs(throttle_1);
16917
+ const initialPosition = {
16918
+ left: "calc(100% - 4px)",
16919
+ top: "0"
16920
+ };
16921
+ const useResizingState = () => {
16922
+ const [pressedColumnIndex, setPressedColumnIndex] = useState(-1);
16923
+ const [pointer, setPointer] = useState(null);
16924
+ const [position, setPosition] = useState(initialPosition);
16925
+ const [lastPressedTimestamp, setLastPressedTimestamp] = useState(0);
16926
+ const getIsPressed = useCallback((columnIndex) => {
16927
+ return pressedColumnIndex === columnIndex;
16928
+ }, [pressedColumnIndex]);
16929
+ const setIsPressed = useCallback((columnIndex, pressed) => {
16930
+ if (pressed) {
16931
+ setPressedColumnIndex(columnIndex);
16932
+ setLastPressedTimestamp(Date.now());
16933
+ } else {
16934
+ setPressedColumnIndex(-1);
16935
+ }
16936
+ }, []);
16937
+ const getPosition = useCallback((columnIndex) => {
16938
+ if (pressedColumnIndex !== columnIndex) {
16939
+ return initialPosition;
16940
+ }
16941
+ return position;
16942
+ }, [position, pressedColumnIndex]);
16943
+ return {
16944
+ pointer,
16945
+ setPointer,
16946
+ getIsPressed,
16947
+ setIsPressed,
16948
+ getPosition,
16949
+ setPosition,
16950
+ lastPressedTimestamp
16951
+ };
16952
+ };
16953
+ const DOUBLE_CLICK_THRESHOLD_MSEC = 300;
16917
16954
  const ResizeSpan = styled.div.withConfig({
16918
16955
  componentId: "sc-1r6e5v3-0"
16919
- })(["top:0;left:calc(100% - 4px);z-index:1;position:absolute;height:", "px;cursor:col-resize;width:4px;overflow:auto;&:hover,&:active,&:hover{background:", ";}", ""], ({
16956
+ })(["top:", ";left:", ";z-index:1;position:absolute;height:", "px;cursor:col-resize;width:4px;overflow:auto;&:hover,&:active,&:hover{background:", ";}", ""], initialPosition.top, initialPosition.left, ({
16920
16957
  $height
16921
16958
  }) => $height, ({
16922
16959
  theme: theme2
@@ -16930,67 +16967,87 @@ const ColumnResizer = ({
16930
16967
  height,
16931
16968
  onColumnResize: onColumnResizeProp,
16932
16969
  columnIndex,
16933
- setResizeCursorPosition
16970
+ getResizerPosition,
16971
+ columnWidth,
16972
+ resizingState
16934
16973
  }) => {
16935
16974
  const resizeRef = useRef(null);
16936
- const pointerRef = useRef(null);
16937
- const [isPressed, setIsPressed] = useState(false);
16975
+ const {
16976
+ pointer,
16977
+ setPointer,
16978
+ getIsPressed,
16979
+ setIsPressed,
16980
+ getPosition,
16981
+ setPosition,
16982
+ lastPressedTimestamp
16983
+ } = resizingState;
16984
+ const isPressed = getIsPressed(columnIndex);
16985
+ const position = getPosition(columnIndex);
16938
16986
  const onColumnResize = throttle$2(onColumnResizeProp, 1e3);
16939
- const onMouseDown = useCallback((e) => {
16940
- e.preventDefault();
16941
- e.stopPropagation();
16942
- setIsPressed(true);
16943
- if (e.detail > 1) {
16944
- onColumnResize(columnIndex, 0, "auto");
16987
+ useEffect(() => {
16988
+ const control = resizeRef.current;
16989
+ if (!isPressed || !control || !pointer) {
16990
+ return;
16945
16991
  }
16946
- }, [columnIndex, onColumnResize, setIsPressed]);
16947
- const onMouseUp = useCallback((e) => {
16948
- e.stopPropagation();
16949
- setIsPressed(false);
16950
- }, [setIsPressed]);
16992
+ const pointerId = pointer.pointerId;
16993
+ try {
16994
+ control.setPointerCapture(pointerId);
16995
+ return () => {
16996
+ if (control.hasPointerCapture(pointerId)) {
16997
+ control.releasePointerCapture(pointerId);
16998
+ }
16999
+ };
17000
+ } catch (e) {
17001
+ console.error(e);
17002
+ }
17003
+ }, [pointer, isPressed, columnIndex]);
16951
17004
  const onPointerDown = useCallback((e) => {
16952
17005
  e.stopPropagation();
17006
+ e.preventDefault();
16953
17007
  if (resizeRef.current) {
16954
- resizeRef.current.setPointerCapture(e.pointerId);
16955
- const header = resizeRef.current.closest(`[data-header="${columnIndex}"]`);
16956
- if (header) {
16957
- pointerRef.current = {
16958
- pointerId: e.pointerId,
16959
- initialClientX: e.clientX,
16960
- width: header.clientWidth
16961
- };
16962
- setResizeCursorPosition(resizeRef.current, e.clientX, header.clientWidth, columnIndex);
17008
+ if (lastPressedTimestamp > Date.now() - DOUBLE_CLICK_THRESHOLD_MSEC) {
17009
+ onColumnResize(columnIndex, 0, "auto");
16963
17010
  }
17011
+ setPointer({
17012
+ pointerId: e.pointerId,
17013
+ initialClientX: e.clientX,
17014
+ width: columnWidth
17015
+ });
17016
+ setIsPressed(columnIndex, true);
17017
+ const pos = getResizerPosition(e.clientX, columnWidth, columnIndex);
17018
+ setPosition(pos);
16964
17019
  }
16965
- }, [columnIndex, setResizeCursorPosition]);
16966
- const onMouseMove = useCallback((e) => {
17020
+ }, [lastPressedTimestamp, setPointer, columnWidth, setIsPressed, columnIndex, getResizerPosition, setPosition, onColumnResize]);
17021
+ const onPointerMove = useCallback((e) => {
16967
17022
  e.stopPropagation();
16968
- if (resizeRef.current && pointerRef.current) {
16969
- const header = resizeRef.current.closest(`[data-header="${columnIndex}"]`);
16970
- if (header) {
16971
- resizeRef.current.setPointerCapture(pointerRef.current.pointerId);
16972
- const width = header.clientWidth + (e.clientX - pointerRef.current.initialClientX);
16973
- setResizeCursorPosition(resizeRef.current, e.clientX, width, columnIndex);
16974
- pointerRef.current.width = Math.max(width, 50);
16975
- }
17023
+ e.preventDefault();
17024
+ if (isPressed && pointer) {
17025
+ const width = columnWidth + (e.clientX - pointer.initialClientX);
17026
+ const pos = getResizerPosition(e.clientX, width, columnIndex);
17027
+ setPosition(pos);
17028
+ pointer.width = Math.max(width, 50);
16976
17029
  }
16977
- }, [columnIndex, setResizeCursorPosition]);
17030
+ }, [pointer, isPressed, columnWidth, getResizerPosition, columnIndex, setPosition]);
16978
17031
  return /* @__PURE__ */ jsx(ResizeSpan, { ref: resizeRef, $height: height, $isPressed: isPressed, onPointerDown, onPointerUp: (e) => {
16979
- var _a, _b;
16980
17032
  e.preventDefault();
16981
17033
  e.stopPropagation();
16982
17034
  if (resizeRef.current && // 0 is a valid pointerId in Firefox
16983
- (((_a = pointerRef.current) == null ? void 0 : _a.pointerId) || ((_b = pointerRef.current) == null ? void 0 : _b.pointerId) === 0)) {
16984
- resizeRef.current.releasePointerCapture(pointerRef.current.pointerId);
16985
- const shouldCallResize = e.clientX !== pointerRef.current.initialClientX;
17035
+ ((pointer == null ? void 0 : pointer.pointerId) || (pointer == null ? void 0 : pointer.pointerId) === 0)) {
17036
+ const shouldCallResize = e.clientX !== pointer.initialClientX;
16986
17037
  if (shouldCallResize) {
16987
- onColumnResize(columnIndex, pointerRef.current.width, "manual");
17038
+ onColumnResize(columnIndex, pointer.width, "manual");
16988
17039
  }
16989
- resizeRef.current.style.top = "0";
16990
- resizeRef.current.style.left = "calc(100% - 4px)";
16991
- pointerRef.current = null;
17040
+ setPosition(initialPosition);
17041
+ setPointer(null);
17042
+ setIsPressed(columnIndex, false);
16992
17043
  }
16993
- }, onMouseMove, onMouseDown, onClick: (e) => e.stopPropagation(), onMouseUp, "data-resize": true });
17044
+ }, onPointerMove, onPointerCancel: (e) => {
17045
+ e.preventDefault();
17046
+ e.stopPropagation();
17047
+ setPosition(initialPosition);
17048
+ setPointer(null);
17049
+ setIsPressed(columnIndex, false);
17050
+ }, onClick: (e) => e.stopPropagation(), "data-resize": true, style: position });
16994
17051
  };
16995
17052
  const HeaderContainer = styled.div.withConfig({
16996
17053
  componentId: "sc-1oadqc8-0"
@@ -17030,15 +17087,16 @@ const RowColumn = styled(StyledCell).withConfig({
17030
17087
  const Column = ({
17031
17088
  columnIndex,
17032
17089
  cell,
17033
- columnWidth,
17090
+ getColumnWidth: getColumnWidth2,
17034
17091
  getColumnHorizontalPosition,
17035
17092
  getSelectionType,
17036
17093
  isFirstColumn,
17037
17094
  isLastColumn,
17038
17095
  onColumnResize,
17039
17096
  height,
17040
- setResizeCursorPosition,
17041
- showBorder
17097
+ getResizerPosition,
17098
+ showBorder,
17099
+ resizingState
17042
17100
  }) => {
17043
17101
  const selectionType = getSelectionType({
17044
17102
  column: columnIndex,
@@ -17051,9 +17109,10 @@ const Column = ({
17051
17109
  const columnPosition = getColumnHorizontalPosition(columnIndex);
17052
17110
  const isSelected = selectionType === "selectDirect";
17053
17111
  const isSelectedLeft = (leftSelectionType === "selectDirect" || isSelected) && leftSelectionType !== selectionType;
17054
- return /* @__PURE__ */ jsxs(HeaderCellContainer, { $width: columnWidth(columnIndex), $columnPosition: columnPosition, $height: height, "data-header": columnIndex, children: [
17055
- /* @__PURE__ */ jsx(StyledCell, { $type: "header", as: cell, columnIndex, type: "header-cell", $isFirstColumn: isFirstColumn, $selectionType: selectionType, $isLastColumn: isLastColumn, $isFocused: false, $isSelectedLeft: isSelectedLeft, $isSelectedTop: isSelected, $isLastRow: false, $isFirstRow: true, $height: height, "data-grid-row": -1, "data-grid-column": columnIndex, "data-selected": isSelected, $showBorder: showBorder, width: columnWidth(columnIndex) }),
17056
- /* @__PURE__ */ jsx(ColumnResizer, { height, onColumnResize, columnIndex, setResizeCursorPosition })
17112
+ const columnWidth = getColumnWidth2(columnIndex);
17113
+ return /* @__PURE__ */ jsxs(HeaderCellContainer, { $width: columnWidth, $columnPosition: columnPosition, $height: height, "data-header": columnIndex, children: [
17114
+ /* @__PURE__ */ jsx(StyledCell, { $type: "header", as: cell, columnIndex, type: "header-cell", $isFirstColumn: isFirstColumn, $selectionType: selectionType, $isLastColumn: isLastColumn, $isFocused: false, $isSelectedLeft: isSelectedLeft, $isSelectedTop: isSelected, $isLastRow: false, $isFirstRow: true, $height: height, "data-grid-row": -1, "data-grid-column": columnIndex, "data-selected": isSelected, $showBorder: showBorder, width: columnWidth }),
17115
+ /* @__PURE__ */ jsx(ColumnResizer, { height, onColumnResize, columnIndex, getResizerPosition, columnWidth, resizingState })
17057
17116
  ] });
17058
17117
  };
17059
17118
  const Header = ({
@@ -17064,14 +17123,15 @@ const Header = ({
17064
17123
  minColumn,
17065
17124
  maxColumn,
17066
17125
  height,
17067
- columnWidth,
17126
+ getColumnWidth: getColumnWidth2,
17068
17127
  cell,
17069
17128
  columnCount,
17070
17129
  getSelectionType,
17071
17130
  onColumnResize,
17072
17131
  getColumnHorizontalPosition,
17073
- setResizeCursorPosition,
17074
- showBorder
17132
+ getResizerPosition,
17133
+ showBorder,
17134
+ resizingState
17075
17135
  }) => {
17076
17136
  const selectedAllType = getSelectionType({
17077
17137
  type: "all"
@@ -17079,7 +17139,7 @@ const Header = ({
17079
17139
  return /* @__PURE__ */ jsxs(HeaderContainer, { $height: height, $scrolledVertical: scrolledVertical, children: [
17080
17140
  /* @__PURE__ */ jsx(ScrollableHeaderContainer, { $left: rowNumberWidth, children: Array.from({
17081
17141
  length: maxColumn - minColumn + 1
17082
- }, (_, index2) => minColumn + index2).map((columnIndex) => /* @__PURE__ */ jsx(Column, { getSelectionType, columnIndex, columnWidth, getColumnHorizontalPosition, cell, isFirstColumn: columnIndex === 0 && !showRowNumber, isLastColumn: columnIndex + 1 === columnCount, onColumnResize, height, setResizeCursorPosition, showBorder }, `header-${columnIndex}`)) }),
17142
+ }, (_, index2) => minColumn + index2).map((columnIndex) => /* @__PURE__ */ jsx(Column, { getSelectionType, columnIndex, getColumnWidth: getColumnWidth2, getColumnHorizontalPosition, cell, isFirstColumn: columnIndex === 0 && !showRowNumber, isLastColumn: columnIndex + 1 === columnCount, onColumnResize, height, getResizerPosition, showBorder, resizingState }, `header-${columnIndex}`)) }),
17083
17143
  showRowNumber && /* @__PURE__ */ jsx(RowColumnContainer, { $width: rowNumberWidth, $height: height, $columnPosition: 0, $scrolledHorizontal: scrolledHorizontal, children: /* @__PURE__ */ jsx(RowColumn, { "data-selected": selectedAllType === "selectDirect", $type: "header", $isFirstRow: true, $isFirstColumn: true, $selectionType: selectedAllType, $isLastRow: false, $isLastColumn: false, $height: height, $isFocused: false, $isSelectedLeft: false, $isSelectedTop: false, "data-grid-row": -1, "data-grid-column": -1, $showBorder: showBorder, children: "#" }) })
17084
17144
  ] });
17085
17145
  };
@@ -31758,6 +31818,7 @@ const Grid = forwardRef(({
31758
31818
  onSelectProp(action, selection2, focus2);
31759
31819
  }
31760
31820
  }, [onSelectProp]);
31821
+ const resizingState = useResizingState();
31761
31822
  const onFocusChange = useCallback((row, column) => {
31762
31823
  setFocus((focus2) => ({
31763
31824
  row: row ?? (focusProp == null ? void 0 : focusProp.row) ?? focus2.row,
@@ -31831,11 +31892,14 @@ const Grid = forwardRef(({
31831
31892
  }
31832
31893
  return columnLeft + rowNumberWidth - 4;
31833
31894
  }, [getColumnHorizontalPosition, rowNumberWidth]);
31834
- const setResizeCursorPosition = useCallback((element, clientX, width, columnIndex) => {
31835
- element.style.left = `${getFixedResizerLeftPosition(clientX, width, columnIndex)}px`;
31895
+ const getResizerPosition = useCallback((clientX, width, columnIndex) => {
31896
+ const result = {
31897
+ left: `${getFixedResizerLeftPosition(clientX, width, columnIndex)}px`
31898
+ };
31836
31899
  if (outerRef.current) {
31837
- element.style.top = `${outerRef.current.scrollTop}px`;
31900
+ result.top = `${outerRef.current.scrollTop}px`;
31838
31901
  }
31902
+ return result;
31839
31903
  }, [getFixedResizerLeftPosition]);
31840
31904
  const clearSelectionAndFocus = useCallback((force) => {
31841
31905
  setSelection((selection2) => {
@@ -31890,7 +31954,7 @@ const Grid = forwardRef(({
31890
31954
  return /* @__PURE__ */ jsxs(GridContainer, { ...containerProps, className: `sticky-grid__container grid-outer ${props.className ?? ""}`, children: [
31891
31955
  /* @__PURE__ */ jsx(GridDataContainer, { $top: showHeader ? headerHeight : 0, $left: showRowNumber ? rowNumberWidth : 0, ref, children }),
31892
31956
  showRowNumber && /* @__PURE__ */ jsx(RowNumberColumn, { scrolledHorizontal, minRow, maxRow, rowHeight, headerHeight, rowWidth: rowNumberWidth, rowCount, getSelectionType, showHeader, rowStart, showBorder }),
31893
- showHeader && /* @__PURE__ */ jsx(Header, { scrolledVertical, scrolledHorizontal, showRowNumber, minColumn, maxColumn, height: headerHeight, columnWidth, cell, rowNumberWidth, getSelectionType, columnCount, onColumnResize, getColumnHorizontalPosition, setResizeCursorPosition, showBorder })
31957
+ showHeader && /* @__PURE__ */ jsx(Header, { scrolledVertical, scrolledHorizontal, showRowNumber, minColumn, maxColumn, height: headerHeight, getColumnWidth: columnWidth, cell, rowNumberWidth, getSelectionType, columnCount, onColumnResize, getColumnHorizontalPosition, getResizerPosition, showBorder, resizingState })
31894
31958
  ] });
31895
31959
  });
31896
31960
  useEffect(() => {
@@ -16930,9 +16930,46 @@ var __publicField = (obj, key, value) => {
16930
16930
  }
16931
16931
  var throttle_1 = throttle$1;
16932
16932
  const throttle$2 = /* @__PURE__ */ getDefaultExportFromCjs(throttle_1);
16933
+ const initialPosition = {
16934
+ left: "calc(100% - 4px)",
16935
+ top: "0"
16936
+ };
16937
+ const useResizingState = () => {
16938
+ const [pressedColumnIndex, setPressedColumnIndex] = React.useState(-1);
16939
+ const [pointer, setPointer] = React.useState(null);
16940
+ const [position, setPosition] = React.useState(initialPosition);
16941
+ const [lastPressedTimestamp, setLastPressedTimestamp] = React.useState(0);
16942
+ const getIsPressed = React.useCallback((columnIndex) => {
16943
+ return pressedColumnIndex === columnIndex;
16944
+ }, [pressedColumnIndex]);
16945
+ const setIsPressed = React.useCallback((columnIndex, pressed) => {
16946
+ if (pressed) {
16947
+ setPressedColumnIndex(columnIndex);
16948
+ setLastPressedTimestamp(Date.now());
16949
+ } else {
16950
+ setPressedColumnIndex(-1);
16951
+ }
16952
+ }, []);
16953
+ const getPosition = React.useCallback((columnIndex) => {
16954
+ if (pressedColumnIndex !== columnIndex) {
16955
+ return initialPosition;
16956
+ }
16957
+ return position;
16958
+ }, [position, pressedColumnIndex]);
16959
+ return {
16960
+ pointer,
16961
+ setPointer,
16962
+ getIsPressed,
16963
+ setIsPressed,
16964
+ getPosition,
16965
+ setPosition,
16966
+ lastPressedTimestamp
16967
+ };
16968
+ };
16969
+ const DOUBLE_CLICK_THRESHOLD_MSEC = 300;
16933
16970
  const ResizeSpan = styled.styled.div.withConfig({
16934
16971
  componentId: "sc-1r6e5v3-0"
16935
- })(["top:0;left:calc(100% - 4px);z-index:1;position:absolute;height:", "px;cursor:col-resize;width:4px;overflow:auto;&:hover,&:active,&:hover{background:", ";}", ""], ({
16972
+ })(["top:", ";left:", ";z-index:1;position:absolute;height:", "px;cursor:col-resize;width:4px;overflow:auto;&:hover,&:active,&:hover{background:", ";}", ""], initialPosition.top, initialPosition.left, ({
16936
16973
  $height
16937
16974
  }) => $height, ({
16938
16975
  theme: theme2
@@ -16946,67 +16983,87 @@ var __publicField = (obj, key, value) => {
16946
16983
  height,
16947
16984
  onColumnResize: onColumnResizeProp,
16948
16985
  columnIndex,
16949
- setResizeCursorPosition
16986
+ getResizerPosition,
16987
+ columnWidth,
16988
+ resizingState
16950
16989
  }) => {
16951
16990
  const resizeRef = React.useRef(null);
16952
- const pointerRef = React.useRef(null);
16953
- const [isPressed, setIsPressed] = React.useState(false);
16991
+ const {
16992
+ pointer,
16993
+ setPointer,
16994
+ getIsPressed,
16995
+ setIsPressed,
16996
+ getPosition,
16997
+ setPosition,
16998
+ lastPressedTimestamp
16999
+ } = resizingState;
17000
+ const isPressed = getIsPressed(columnIndex);
17001
+ const position = getPosition(columnIndex);
16954
17002
  const onColumnResize = throttle$2(onColumnResizeProp, 1e3);
16955
- const onMouseDown = React.useCallback((e) => {
16956
- e.preventDefault();
16957
- e.stopPropagation();
16958
- setIsPressed(true);
16959
- if (e.detail > 1) {
16960
- onColumnResize(columnIndex, 0, "auto");
17003
+ React.useEffect(() => {
17004
+ const control = resizeRef.current;
17005
+ if (!isPressed || !control || !pointer) {
17006
+ return;
16961
17007
  }
16962
- }, [columnIndex, onColumnResize, setIsPressed]);
16963
- const onMouseUp = React.useCallback((e) => {
16964
- e.stopPropagation();
16965
- setIsPressed(false);
16966
- }, [setIsPressed]);
17008
+ const pointerId = pointer.pointerId;
17009
+ try {
17010
+ control.setPointerCapture(pointerId);
17011
+ return () => {
17012
+ if (control.hasPointerCapture(pointerId)) {
17013
+ control.releasePointerCapture(pointerId);
17014
+ }
17015
+ };
17016
+ } catch (e) {
17017
+ console.error(e);
17018
+ }
17019
+ }, [pointer, isPressed, columnIndex]);
16967
17020
  const onPointerDown = React.useCallback((e) => {
16968
17021
  e.stopPropagation();
17022
+ e.preventDefault();
16969
17023
  if (resizeRef.current) {
16970
- resizeRef.current.setPointerCapture(e.pointerId);
16971
- const header = resizeRef.current.closest(`[data-header="${columnIndex}"]`);
16972
- if (header) {
16973
- pointerRef.current = {
16974
- pointerId: e.pointerId,
16975
- initialClientX: e.clientX,
16976
- width: header.clientWidth
16977
- };
16978
- setResizeCursorPosition(resizeRef.current, e.clientX, header.clientWidth, columnIndex);
17024
+ if (lastPressedTimestamp > Date.now() - DOUBLE_CLICK_THRESHOLD_MSEC) {
17025
+ onColumnResize(columnIndex, 0, "auto");
16979
17026
  }
17027
+ setPointer({
17028
+ pointerId: e.pointerId,
17029
+ initialClientX: e.clientX,
17030
+ width: columnWidth
17031
+ });
17032
+ setIsPressed(columnIndex, true);
17033
+ const pos = getResizerPosition(e.clientX, columnWidth, columnIndex);
17034
+ setPosition(pos);
16980
17035
  }
16981
- }, [columnIndex, setResizeCursorPosition]);
16982
- const onMouseMove = React.useCallback((e) => {
17036
+ }, [lastPressedTimestamp, setPointer, columnWidth, setIsPressed, columnIndex, getResizerPosition, setPosition, onColumnResize]);
17037
+ const onPointerMove = React.useCallback((e) => {
16983
17038
  e.stopPropagation();
16984
- if (resizeRef.current && pointerRef.current) {
16985
- const header = resizeRef.current.closest(`[data-header="${columnIndex}"]`);
16986
- if (header) {
16987
- resizeRef.current.setPointerCapture(pointerRef.current.pointerId);
16988
- const width = header.clientWidth + (e.clientX - pointerRef.current.initialClientX);
16989
- setResizeCursorPosition(resizeRef.current, e.clientX, width, columnIndex);
16990
- pointerRef.current.width = Math.max(width, 50);
16991
- }
17039
+ e.preventDefault();
17040
+ if (isPressed && pointer) {
17041
+ const width = columnWidth + (e.clientX - pointer.initialClientX);
17042
+ const pos = getResizerPosition(e.clientX, width, columnIndex);
17043
+ setPosition(pos);
17044
+ pointer.width = Math.max(width, 50);
16992
17045
  }
16993
- }, [columnIndex, setResizeCursorPosition]);
17046
+ }, [pointer, isPressed, columnWidth, getResizerPosition, columnIndex, setPosition]);
16994
17047
  return /* @__PURE__ */ jsxRuntime.jsx(ResizeSpan, { ref: resizeRef, $height: height, $isPressed: isPressed, onPointerDown, onPointerUp: (e) => {
16995
- var _a, _b;
16996
17048
  e.preventDefault();
16997
17049
  e.stopPropagation();
16998
17050
  if (resizeRef.current && // 0 is a valid pointerId in Firefox
16999
- (((_a = pointerRef.current) == null ? void 0 : _a.pointerId) || ((_b = pointerRef.current) == null ? void 0 : _b.pointerId) === 0)) {
17000
- resizeRef.current.releasePointerCapture(pointerRef.current.pointerId);
17001
- const shouldCallResize = e.clientX !== pointerRef.current.initialClientX;
17051
+ ((pointer == null ? void 0 : pointer.pointerId) || (pointer == null ? void 0 : pointer.pointerId) === 0)) {
17052
+ const shouldCallResize = e.clientX !== pointer.initialClientX;
17002
17053
  if (shouldCallResize) {
17003
- onColumnResize(columnIndex, pointerRef.current.width, "manual");
17054
+ onColumnResize(columnIndex, pointer.width, "manual");
17004
17055
  }
17005
- resizeRef.current.style.top = "0";
17006
- resizeRef.current.style.left = "calc(100% - 4px)";
17007
- pointerRef.current = null;
17056
+ setPosition(initialPosition);
17057
+ setPointer(null);
17058
+ setIsPressed(columnIndex, false);
17008
17059
  }
17009
- }, onMouseMove, onMouseDown, onClick: (e) => e.stopPropagation(), onMouseUp, "data-resize": true });
17060
+ }, onPointerMove, onPointerCancel: (e) => {
17061
+ e.preventDefault();
17062
+ e.stopPropagation();
17063
+ setPosition(initialPosition);
17064
+ setPointer(null);
17065
+ setIsPressed(columnIndex, false);
17066
+ }, onClick: (e) => e.stopPropagation(), "data-resize": true, style: position });
17010
17067
  };
17011
17068
  const HeaderContainer = styled.styled.div.withConfig({
17012
17069
  componentId: "sc-1oadqc8-0"
@@ -17046,15 +17103,16 @@ var __publicField = (obj, key, value) => {
17046
17103
  const Column = ({
17047
17104
  columnIndex,
17048
17105
  cell,
17049
- columnWidth,
17106
+ getColumnWidth,
17050
17107
  getColumnHorizontalPosition,
17051
17108
  getSelectionType,
17052
17109
  isFirstColumn,
17053
17110
  isLastColumn,
17054
17111
  onColumnResize,
17055
17112
  height,
17056
- setResizeCursorPosition,
17057
- showBorder
17113
+ getResizerPosition,
17114
+ showBorder,
17115
+ resizingState
17058
17116
  }) => {
17059
17117
  const selectionType = getSelectionType({
17060
17118
  column: columnIndex,
@@ -17067,9 +17125,10 @@ var __publicField = (obj, key, value) => {
17067
17125
  const columnPosition = getColumnHorizontalPosition(columnIndex);
17068
17126
  const isSelected = selectionType === "selectDirect";
17069
17127
  const isSelectedLeft = (leftSelectionType === "selectDirect" || isSelected) && leftSelectionType !== selectionType;
17070
- return /* @__PURE__ */ jsxRuntime.jsxs(HeaderCellContainer, { $width: columnWidth(columnIndex), $columnPosition: columnPosition, $height: height, "data-header": columnIndex, children: [
17071
- /* @__PURE__ */ jsxRuntime.jsx(StyledCell, { $type: "header", as: cell, columnIndex, type: "header-cell", $isFirstColumn: isFirstColumn, $selectionType: selectionType, $isLastColumn: isLastColumn, $isFocused: false, $isSelectedLeft: isSelectedLeft, $isSelectedTop: isSelected, $isLastRow: false, $isFirstRow: true, $height: height, "data-grid-row": -1, "data-grid-column": columnIndex, "data-selected": isSelected, $showBorder: showBorder, width: columnWidth(columnIndex) }),
17072
- /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer, { height, onColumnResize, columnIndex, setResizeCursorPosition })
17128
+ const columnWidth = getColumnWidth(columnIndex);
17129
+ return /* @__PURE__ */ jsxRuntime.jsxs(HeaderCellContainer, { $width: columnWidth, $columnPosition: columnPosition, $height: height, "data-header": columnIndex, children: [
17130
+ /* @__PURE__ */ jsxRuntime.jsx(StyledCell, { $type: "header", as: cell, columnIndex, type: "header-cell", $isFirstColumn: isFirstColumn, $selectionType: selectionType, $isLastColumn: isLastColumn, $isFocused: false, $isSelectedLeft: isSelectedLeft, $isSelectedTop: isSelected, $isLastRow: false, $isFirstRow: true, $height: height, "data-grid-row": -1, "data-grid-column": columnIndex, "data-selected": isSelected, $showBorder: showBorder, width: columnWidth }),
17131
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer, { height, onColumnResize, columnIndex, getResizerPosition, columnWidth, resizingState })
17073
17132
  ] });
17074
17133
  };
17075
17134
  const Header = ({
@@ -17080,14 +17139,15 @@ var __publicField = (obj, key, value) => {
17080
17139
  minColumn,
17081
17140
  maxColumn,
17082
17141
  height,
17083
- columnWidth,
17142
+ getColumnWidth,
17084
17143
  cell,
17085
17144
  columnCount,
17086
17145
  getSelectionType,
17087
17146
  onColumnResize,
17088
17147
  getColumnHorizontalPosition,
17089
- setResizeCursorPosition,
17090
- showBorder
17148
+ getResizerPosition,
17149
+ showBorder,
17150
+ resizingState
17091
17151
  }) => {
17092
17152
  const selectedAllType = getSelectionType({
17093
17153
  type: "all"
@@ -17095,7 +17155,7 @@ var __publicField = (obj, key, value) => {
17095
17155
  return /* @__PURE__ */ jsxRuntime.jsxs(HeaderContainer, { $height: height, $scrolledVertical: scrolledVertical, children: [
17096
17156
  /* @__PURE__ */ jsxRuntime.jsx(ScrollableHeaderContainer, { $left: rowNumberWidth, children: Array.from({
17097
17157
  length: maxColumn - minColumn + 1
17098
- }, (_, index2) => minColumn + index2).map((columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(Column, { getSelectionType, columnIndex, columnWidth, getColumnHorizontalPosition, cell, isFirstColumn: columnIndex === 0 && !showRowNumber, isLastColumn: columnIndex + 1 === columnCount, onColumnResize, height, setResizeCursorPosition, showBorder }, `header-${columnIndex}`)) }),
17158
+ }, (_, index2) => minColumn + index2).map((columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(Column, { getSelectionType, columnIndex, getColumnWidth, getColumnHorizontalPosition, cell, isFirstColumn: columnIndex === 0 && !showRowNumber, isLastColumn: columnIndex + 1 === columnCount, onColumnResize, height, getResizerPosition, showBorder, resizingState }, `header-${columnIndex}`)) }),
17099
17159
  showRowNumber && /* @__PURE__ */ jsxRuntime.jsx(RowColumnContainer, { $width: rowNumberWidth, $height: height, $columnPosition: 0, $scrolledHorizontal: scrolledHorizontal, children: /* @__PURE__ */ jsxRuntime.jsx(RowColumn, { "data-selected": selectedAllType === "selectDirect", $type: "header", $isFirstRow: true, $isFirstColumn: true, $selectionType: selectedAllType, $isLastRow: false, $isLastColumn: false, $height: height, $isFocused: false, $isSelectedLeft: false, $isSelectedTop: false, "data-grid-row": -1, "data-grid-column": -1, $showBorder: showBorder, children: "#" }) })
17100
17160
  ] });
17101
17161
  };
@@ -31774,6 +31834,7 @@ var __publicField = (obj, key, value) => {
31774
31834
  onSelectProp(action, selection2, focus2);
31775
31835
  }
31776
31836
  }, [onSelectProp]);
31837
+ const resizingState = useResizingState();
31777
31838
  const onFocusChange = React.useCallback((row, column) => {
31778
31839
  setFocus((focus2) => ({
31779
31840
  row: row ?? (focusProp == null ? void 0 : focusProp.row) ?? focus2.row,
@@ -31847,11 +31908,14 @@ var __publicField = (obj, key, value) => {
31847
31908
  }
31848
31909
  return columnLeft + rowNumberWidth - 4;
31849
31910
  }, [getColumnHorizontalPosition, rowNumberWidth]);
31850
- const setResizeCursorPosition = React.useCallback((element, clientX, width, columnIndex) => {
31851
- element.style.left = `${getFixedResizerLeftPosition(clientX, width, columnIndex)}px`;
31911
+ const getResizerPosition = React.useCallback((clientX, width, columnIndex) => {
31912
+ const result = {
31913
+ left: `${getFixedResizerLeftPosition(clientX, width, columnIndex)}px`
31914
+ };
31852
31915
  if (outerRef.current) {
31853
- element.style.top = `${outerRef.current.scrollTop}px`;
31916
+ result.top = `${outerRef.current.scrollTop}px`;
31854
31917
  }
31918
+ return result;
31855
31919
  }, [getFixedResizerLeftPosition]);
31856
31920
  const clearSelectionAndFocus = React.useCallback((force) => {
31857
31921
  setSelection((selection2) => {
@@ -31906,7 +31970,7 @@ var __publicField = (obj, key, value) => {
31906
31970
  return /* @__PURE__ */ jsxRuntime.jsxs(GridContainer, { ...containerProps, className: `sticky-grid__container grid-outer ${props.className ?? ""}`, children: [
31907
31971
  /* @__PURE__ */ jsxRuntime.jsx(GridDataContainer, { $top: showHeader ? headerHeight : 0, $left: showRowNumber ? rowNumberWidth : 0, ref, children }),
31908
31972
  showRowNumber && /* @__PURE__ */ jsxRuntime.jsx(RowNumberColumn, { scrolledHorizontal, minRow, maxRow, rowHeight, headerHeight, rowWidth: rowNumberWidth, rowCount, getSelectionType, showHeader, rowStart, showBorder }),
31909
- showHeader && /* @__PURE__ */ jsxRuntime.jsx(Header, { scrolledVertical, scrolledHorizontal, showRowNumber, minColumn, maxColumn, height: headerHeight, columnWidth, cell, rowNumberWidth, getSelectionType, columnCount, onColumnResize, getColumnHorizontalPosition, setResizeCursorPosition, showBorder })
31973
+ showHeader && /* @__PURE__ */ jsxRuntime.jsx(Header, { scrolledVertical, scrolledHorizontal, showRowNumber, minColumn, maxColumn, height: headerHeight, getColumnWidth: columnWidth, cell, rowNumberWidth, getSelectionType, columnCount, onColumnResize, getColumnHorizontalPosition, getResizerPosition, showBorder, resizingState })
31910
31974
  ] });
31911
31975
  });
31912
31976
  React.useEffect(() => {
@@ -37,7 +37,7 @@ export declare const Flyout: {
37
37
  };
38
38
  CodeBlock: ({ statement, language, wrapLines, showLineNumbers, showWrapButton, onCopy, onCopyError, ...props }: FlyoutCodeBlockProps & ElementProps) => import("react/jsx-runtime").JSX.Element;
39
39
  };
40
- type FlyoutSizeType = "default" | "narrow" | "wide";
40
+ type FlyoutSizeType = "default" | "narrow" | "wide" | "widest";
41
41
  type Strategy = "relative" | "absolute" | "fixed";
42
42
  type FlyoutType = "default" | "inline";
43
43
  type DialogContentAlignmentType = "start" | "end";
@@ -1,10 +1,28 @@
1
- import { ColumnResizeFn, SetResizeCursorPositionFn } from './types';
1
+ import { ColumnResizeFn, GetResizerPositionFn } from './types';
2
+ import { ResizingState } from './useResizingState';
2
3
 
4
+ /**
5
+ * Properties for the ColumnResizer component.
6
+ * @typedef {Object} Props
7
+ * @property {number} height - Height of the resizer.
8
+ * @property {ColumnResizeFn} onColumnResize - Function to handle column resize.
9
+ * @property {number} columnIndex - Index of the column being resized.
10
+ * @property {GetResizerPositionFn} getResizerPosition - Function to get the position of the resizer.
11
+ * @property {number} columnWidth - Initial width of the column.
12
+ * @property {ResizingState} resizingState - State management object for resizing interactions.
13
+ */
3
14
  interface Props {
4
15
  height: number;
5
16
  onColumnResize: ColumnResizeFn;
6
17
  columnIndex: number;
7
- setResizeCursorPosition: SetResizeCursorPositionFn;
18
+ getResizerPosition: GetResizerPositionFn;
19
+ columnWidth: number;
20
+ resizingState: ResizingState;
8
21
  }
9
- declare const ColumnResizer: ({ height, onColumnResize: onColumnResizeProp, columnIndex, setResizeCursorPosition, }: Props) => import("react/jsx-runtime").JSX.Element;
22
+ /**
23
+ * Component for rendering a column resizer with pointer events and resizing state management.
24
+ * @param {Props} props - Properties passed to the component.
25
+ * @returns {JSX.Element} The ColumnResizer component.
26
+ */
27
+ declare const ColumnResizer: ({ height, onColumnResize: onColumnResizeProp, columnIndex, getResizerPosition, columnWidth, resizingState, }: Props) => import("react/jsx-runtime").JSX.Element;
10
28
  export default ColumnResizer;
@@ -1,4 +1,5 @@
1
- import { CellProps, ColumnResizeFn, SelectionTypeFn, SetResizeCursorPositionFn } from './types';
1
+ import { CellProps, ColumnResizeFn, GetResizerPositionFn, SelectionTypeFn } from './types';
2
+ import { ResizingState } from './useResizingState';
2
3
 
3
4
  interface HeaderProps {
4
5
  showRowNumber: boolean;
@@ -6,16 +7,17 @@ interface HeaderProps {
6
7
  minColumn: number;
7
8
  maxColumn: number;
8
9
  height: number;
9
- columnWidth: (index: number) => number;
10
+ getColumnWidth: (index: number) => number;
10
11
  cell: CellProps;
11
12
  getSelectionType: SelectionTypeFn;
12
13
  columnCount: number;
13
14
  onColumnResize: ColumnResizeFn;
14
15
  getColumnHorizontalPosition: (columnIndex: number) => number;
15
16
  scrolledVertical: boolean;
16
- setResizeCursorPosition: SetResizeCursorPositionFn;
17
+ getResizerPosition: GetResizerPositionFn;
17
18
  showBorder: boolean;
18
19
  scrolledHorizontal: boolean;
20
+ resizingState: ResizingState;
19
21
  }
20
- declare const Header: ({ scrolledVertical, scrolledHorizontal, showRowNumber, rowNumberWidth, minColumn, maxColumn, height, columnWidth, cell, columnCount, getSelectionType, onColumnResize, getColumnHorizontalPosition, setResizeCursorPosition, showBorder, }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
22
+ declare const Header: ({ scrolledVertical, scrolledHorizontal, showRowNumber, rowNumberWidth, minColumn, maxColumn, height, getColumnWidth, cell, columnCount, getSelectionType, onColumnResize, getColumnHorizontalPosition, getResizerPosition, showBorder, resizingState }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
21
23
  export default Header;
@@ -138,5 +138,9 @@ export interface GridProps extends Omit<VariableSizeGridProps, "height" | "width
138
138
  onContextMenu?: MouseEventHandler<HTMLDivElement>;
139
139
  forwardedGridRef?: MutableRefObject<VariableSizeGrid>;
140
140
  }
141
- export type SetResizeCursorPositionFn = (element: HTMLSpanElement, clientX: number, width: number, columnIndex: number) => void;
141
+ export type ResizerPosition = {
142
+ left: string;
143
+ top?: string;
144
+ };
145
+ export type GetResizerPositionFn = (clientX: number, width: number, columnIndex: number) => ResizerPosition;
142
146
  export {};
@@ -0,0 +1,48 @@
1
+ import { ResizerPosition } from './types';
2
+
3
+ /**
4
+ * Defines the type for pointer information used in resizing.
5
+ * @typedef {Object} PointerType
6
+ * @property {number} width - The width of the pointer component.
7
+ * @property {number} pointerId - Unique identifier for the pointer from a touch event.
8
+ * @property {number} initialClientX - The initial X coordinate of the pointer when resizing started.
9
+ */
10
+ export type PointerType = {
11
+ width: number;
12
+ pointerId: number;
13
+ initialClientX: number;
14
+ };
15
+ /**
16
+ * Defines the state and methods used for managing the column resizing.
17
+ * @typedef {Object} ResizingState
18
+ * @property {PointerType | null} pointer - The current pointer data, or null if no pointer is active.
19
+ * @property {(pointer: PointerType | null) => void} setPointer - Setter to update the pointer.
20
+ * @property {(columnIndex: number) => boolean} getIsPressed - Indicates if a resizer for the given column is currently pressed/dragged.
21
+ * @property {(columnIndex: number, pressed: boolean) => void} setIsPressed - Sets the pressed state for a given column.
22
+ * @property {(columnIndex: number) => ResizerPosition} getPosition - Gets the position of the resizer for the specified column.
23
+ * @property {(position: ResizerPosition) => void} setPosition - Updates the position of the resizer.
24
+ * @property {number} lastPressedTimestamp - Timestamp of the last time a column was pressed, used to detect double-clicks.
25
+ */
26
+ export interface ResizingState {
27
+ pointer: PointerType | null;
28
+ setPointer: (pointer: PointerType | null) => void;
29
+ getIsPressed: (columnIndex: number) => boolean;
30
+ setIsPressed: (columnIndex: number, pressed: boolean) => void;
31
+ getPosition: (columnIndex: number) => ResizerPosition;
32
+ setPosition: (position: ResizerPosition) => void;
33
+ lastPressedTimestamp: number;
34
+ }
35
+ /**
36
+ * The initial position of the resizer element.
37
+ * @type {ResizerPosition}
38
+ */
39
+ export declare const initialPosition: {
40
+ left: string;
41
+ top: string;
42
+ };
43
+ /**
44
+ * Custom hook that provides the state and methods needed to manage a resizing operation on columns.
45
+ * @returns {ResizingState} The resizing state and methods for controlling resizing behavior.
46
+ */
47
+ declare const useResizingState: () => ResizingState;
48
+ export default useResizingState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clickhouse/click-ui",
3
- "version": "0.0.171",
3
+ "version": "0.0.172",
4
4
  "description": "Official ClickHouse design system react library",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",