@atlaskit/editor-plugin-table 7.16.2 → 7.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 7.16.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#102667](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/102667)
8
+ [`ab69107b7352`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ab69107b7352) -
9
+ Force placeholder drag handle to be positioned in first column to avoid overflow
10
+
11
+ ## 7.16.3
12
+
13
+ ### Patch Changes
14
+
15
+ - [#102385](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/102385)
16
+ [`501e08d95a31`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/501e08d95a31) -
17
+ [ux] Resize ratio depends on table alignment option. Fixed resize ratio for the cases when table
18
+ alignment is not 'center'.
19
+
3
20
  ## 7.16.2
4
21
 
5
22
  ### Patch Changes
@@ -163,6 +163,7 @@ var ResizableTableContainer = exports.ResizableTableContainer = /*#__PURE__*/_re
163
163
  displayGuideline: displayGuideline,
164
164
  attachAnalyticsEvent: attachAnalyticsEvent,
165
165
  displayGapCursor: displayGapCursor,
166
+ isTableAlignmentEnabled: isTableAlignmentEnabled,
166
167
  isTableScalingEnabled: isTableScalingEnabled,
167
168
  isWholeTableInDanger: isWholeTableInDanger,
168
169
  pluginInjectionApi: pluginInjectionApi,
@@ -25,6 +25,7 @@ var _tableAnalytics = require("../pm-plugins/table-analytics");
25
25
  var _utils3 = require("../pm-plugins/table-resizing/utils");
26
26
  var _tableWidth = require("../pm-plugins/table-width");
27
27
  var _consts = require("../ui/consts");
28
+ var _alignment = require("../utils/alignment");
28
29
  var _analytics2 = require("../utils/analytics");
29
30
  var _guidelines = require("../utils/guidelines");
30
31
  var _snapping = require("../utils/snapping");
@@ -98,6 +99,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
98
99
  attachAnalyticsEvent = _ref.attachAnalyticsEvent,
99
100
  displayGapCursor = _ref.displayGapCursor,
100
101
  isTableScalingEnabled = _ref.isTableScalingEnabled,
102
+ isTableAlignmentEnabled = _ref.isTableAlignmentEnabled,
101
103
  isWholeTableInDanger = _ref.isWholeTableInDanger,
102
104
  pluginInjectionApi = _ref.pluginInjectionApi;
103
105
  var currentGap = (0, _react.useRef)(0);
@@ -365,6 +367,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
365
367
  (_updateTooltip$curren = updateTooltip.current) === null || _updateTooltip$curren === void 0 || _updateTooltip$curren.call(updateTooltip);
366
368
  }
367
369
  }, [width]);
370
+ var resizeRatio = !isTableAlignmentEnabled || isTableAlignmentEnabled && (0, _alignment.normaliseAlignment)(node.attrs.layout) === 'center' ? 2 : 1;
368
371
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_resizer.ResizerNext, {
369
372
  ref: resizerRef,
370
373
  enable: handles,
@@ -375,7 +378,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
375
378
  handleResizeStart: handleResizeStart,
376
379
  handleResize: scheduleResize,
377
380
  handleResizeStop: handleResizeStop,
378
- resizeRatio: 2,
381
+ resizeRatio: resizeRatio,
379
382
  minWidth: resizerMinWidth,
380
383
  maxWidth: maxWidth,
381
384
  snapGap: _consts.TABLE_SNAP_GAP,
@@ -126,6 +126,7 @@ var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) {
126
126
  var generateHandleByType = function generateHandleByType(type, appearance, gridColumn, indexes) {
127
127
  var _rowHeights$reduce, _colWidths$reduce;
128
128
  var isHover = type === 'hover';
129
+ var isPlaceholder = appearance === 'placeholder';
129
130
  var previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce(function (sum, cur) {
130
131
  return sum + cur;
131
132
  }, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0;
@@ -147,7 +148,7 @@ var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) {
147
148
  width: '100%',
148
149
  position: 'relative'
149
150
  },
150
- "data-testid": "table-floating-column-".concat(isHover ? colIndex : selectedColIndexes[0], "-drag-handle")
151
+ "data-testid": "table-floating-column-".concat(isHover ? colIndex : isPlaceholder ? appearance : selectedColIndexes[0], "-drag-handle")
151
152
  }, /*#__PURE__*/_react.default.createElement(_DragHandle.DragHandle, {
152
153
  isDragMenuTarget: !isHover,
153
154
  direction: "column",
@@ -172,10 +173,13 @@ var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) {
172
173
  if (!tableActive) {
173
174
  return null;
174
175
  }
176
+ var selectedAppearance = isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder';
175
177
 
176
178
  // placeholder / selected need to always render at least one handle
177
179
  // so it can be focused via keyboard shortcuts
178
- handles.push(generateHandleByType('selected', isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', "".concat(selectedColIndexes[0] + 1, " / span ").concat(selectedColIndexes.length), selectedColIndexes));
180
+ handles.push(generateHandleByType('selected', selectedAppearance,
181
+ // always position placeholder in first column to avoid overflow issues
182
+ selectedAppearance === 'placeholder' ? '1 / span 1' : "".concat(selectedColIndexes[0] + 1, " / span ").concat(selectedColIndexes.length), selectedColIndexes));
179
183
  if (hoveredCell && isTableHovered && colIndex !== undefined && !selectedColIndexes.includes(colIndex)) {
180
184
  handles.push(generateHandleByType('hover', 'default', "".concat(colIndex + 1, " / span 1"), colIndexes));
181
185
  }
@@ -154,6 +154,7 @@ export const ResizableTableContainer = /*#__PURE__*/React.memo(({
154
154
  displayGuideline,
155
155
  attachAnalyticsEvent,
156
156
  displayGapCursor,
157
+ isTableAlignmentEnabled,
157
158
  isTableScalingEnabled,
158
159
  isWholeTableInDanger,
159
160
  pluginInjectionApi,
@@ -15,6 +15,7 @@ import { META_KEYS } from '../pm-plugins/table-analytics';
15
15
  import { COLUMN_MIN_WIDTH, getColgroupChildrenLength, previewScaleTable, scaleTable, TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils';
16
16
  import { pluginKey as tableWidthPluginKey } from '../pm-plugins/table-width';
17
17
  import { TABLE_GUIDELINE_VISIBLE_ADJUSTMENT, TABLE_HIGHLIGHT_GAP, TABLE_HIGHLIGHT_TOLERANCE, TABLE_SNAP_GAP } from '../ui/consts';
18
+ import { normaliseAlignment } from '../utils/alignment';
18
19
  import { generateResizedPayload, generateResizeFrameRatePayloads, useMeasureFramerate } from '../utils/analytics';
19
20
  import { defaultGuidelines, defaultGuidelinesForPreserveTable } from '../utils/guidelines';
20
21
  import { defaultSnappingWidths, defaultTablePreserveSnappingWidths, findClosestSnap } from '../utils/snapping';
@@ -83,6 +84,7 @@ export const TableResizer = ({
83
84
  attachAnalyticsEvent,
84
85
  displayGapCursor,
85
86
  isTableScalingEnabled,
87
+ isTableAlignmentEnabled,
86
88
  isWholeTableInDanger,
87
89
  pluginInjectionApi
88
90
  }) => {
@@ -363,6 +365,7 @@ export const TableResizer = ({
363
365
  (_updateTooltip$curren = updateTooltip.current) === null || _updateTooltip$curren === void 0 ? void 0 : _updateTooltip$curren.call(updateTooltip);
364
366
  }
365
367
  }, [width]);
368
+ const resizeRatio = !isTableAlignmentEnabled || isTableAlignmentEnabled && normaliseAlignment(node.attrs.layout) === 'center' ? 2 : 1;
366
369
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ResizerNext, {
367
370
  ref: resizerRef,
368
371
  enable: handles,
@@ -373,7 +376,7 @@ export const TableResizer = ({
373
376
  handleResizeStart: handleResizeStart,
374
377
  handleResize: scheduleResize,
375
378
  handleResizeStop: handleResizeStop,
376
- resizeRatio: 2,
379
+ resizeRatio: resizeRatio,
377
380
  minWidth: resizerMinWidth,
378
381
  maxWidth: maxWidth,
379
382
  snapGap: TABLE_SNAP_GAP,
@@ -126,6 +126,7 @@ export const ColumnControls = ({
126
126
  const generateHandleByType = (type, appearance, gridColumn, indexes) => {
127
127
  var _rowHeights$reduce, _colWidths$reduce;
128
128
  const isHover = type === 'hover';
129
+ const isPlaceholder = appearance === 'placeholder';
129
130
  const previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce((sum, cur) => sum + cur, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0;
130
131
  const previewWidth = (_colWidths$reduce = colWidths === null || colWidths === void 0 ? void 0 : colWidths.reduce((sum, v, i) => sum + (v !== null && v !== void 0 ? v : tableCellMinWidth) * (indexes.includes(i) ? 1 : 0), 0)) !== null && _colWidths$reduce !== void 0 ? _colWidths$reduce : tableCellMinWidth;
131
132
  return /*#__PURE__*/React.createElement("div", {
@@ -143,7 +144,7 @@ export const ColumnControls = ({
143
144
  width: '100%',
144
145
  position: 'relative'
145
146
  },
146
- "data-testid": `table-floating-column-${isHover ? colIndex : selectedColIndexes[0]}-drag-handle`
147
+ "data-testid": `table-floating-column-${isHover ? colIndex : isPlaceholder ? appearance : selectedColIndexes[0]}-drag-handle`
147
148
  }, /*#__PURE__*/React.createElement(DragHandle, {
148
149
  isDragMenuTarget: !isHover,
149
150
  direction: "column",
@@ -168,10 +169,13 @@ export const ColumnControls = ({
168
169
  if (!tableActive) {
169
170
  return null;
170
171
  }
172
+ const selectedAppearance = isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder';
171
173
 
172
174
  // placeholder / selected need to always render at least one handle
173
175
  // so it can be focused via keyboard shortcuts
174
- handles.push(generateHandleByType('selected', isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`, selectedColIndexes));
176
+ handles.push(generateHandleByType('selected', selectedAppearance,
177
+ // always position placeholder in first column to avoid overflow issues
178
+ selectedAppearance === 'placeholder' ? '1 / span 1' : `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`, selectedColIndexes));
175
179
  if (hoveredCell && isTableHovered && colIndex !== undefined && !selectedColIndexes.includes(colIndex)) {
176
180
  handles.push(generateHandleByType('hover', 'default', `${colIndex + 1} / span 1`, colIndexes));
177
181
  }
@@ -153,6 +153,7 @@ export var ResizableTableContainer = /*#__PURE__*/React.memo(function (_ref4) {
153
153
  displayGuideline: displayGuideline,
154
154
  attachAnalyticsEvent: attachAnalyticsEvent,
155
155
  displayGapCursor: displayGapCursor,
156
+ isTableAlignmentEnabled: isTableAlignmentEnabled,
156
157
  isTableScalingEnabled: isTableScalingEnabled,
157
158
  isWholeTableInDanger: isWholeTableInDanger,
158
159
  pluginInjectionApi: pluginInjectionApi,
@@ -19,6 +19,7 @@ import { META_KEYS } from '../pm-plugins/table-analytics';
19
19
  import { COLUMN_MIN_WIDTH, getColgroupChildrenLength, previewScaleTable, scaleTable, TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils';
20
20
  import { pluginKey as tableWidthPluginKey } from '../pm-plugins/table-width';
21
21
  import { TABLE_GUIDELINE_VISIBLE_ADJUSTMENT, TABLE_HIGHLIGHT_GAP, TABLE_HIGHLIGHT_TOLERANCE, TABLE_SNAP_GAP } from '../ui/consts';
22
+ import { normaliseAlignment } from '../utils/alignment';
22
23
  import { generateResizedPayload, generateResizeFrameRatePayloads, useMeasureFramerate } from '../utils/analytics';
23
24
  import { defaultGuidelines, defaultGuidelinesForPreserveTable } from '../utils/guidelines';
24
25
  import { defaultSnappingWidths, defaultTablePreserveSnappingWidths, findClosestSnap } from '../utils/snapping';
@@ -88,6 +89,7 @@ export var TableResizer = function TableResizer(_ref) {
88
89
  attachAnalyticsEvent = _ref.attachAnalyticsEvent,
89
90
  displayGapCursor = _ref.displayGapCursor,
90
91
  isTableScalingEnabled = _ref.isTableScalingEnabled,
92
+ isTableAlignmentEnabled = _ref.isTableAlignmentEnabled,
91
93
  isWholeTableInDanger = _ref.isWholeTableInDanger,
92
94
  pluginInjectionApi = _ref.pluginInjectionApi;
93
95
  var currentGap = useRef(0);
@@ -355,6 +357,7 @@ export var TableResizer = function TableResizer(_ref) {
355
357
  (_updateTooltip$curren = updateTooltip.current) === null || _updateTooltip$curren === void 0 || _updateTooltip$curren.call(updateTooltip);
356
358
  }
357
359
  }, [width]);
360
+ var resizeRatio = !isTableAlignmentEnabled || isTableAlignmentEnabled && normaliseAlignment(node.attrs.layout) === 'center' ? 2 : 1;
358
361
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ResizerNext, {
359
362
  ref: resizerRef,
360
363
  enable: handles,
@@ -365,7 +368,7 @@ export var TableResizer = function TableResizer(_ref) {
365
368
  handleResizeStart: handleResizeStart,
366
369
  handleResize: scheduleResize,
367
370
  handleResizeStop: handleResizeStop,
368
- resizeRatio: 2,
371
+ resizeRatio: resizeRatio,
369
372
  minWidth: resizerMinWidth,
370
373
  maxWidth: maxWidth,
371
374
  snapGap: TABLE_SNAP_GAP,
@@ -117,6 +117,7 @@ export var ColumnControls = function ColumnControls(_ref) {
117
117
  var generateHandleByType = function generateHandleByType(type, appearance, gridColumn, indexes) {
118
118
  var _rowHeights$reduce, _colWidths$reduce;
119
119
  var isHover = type === 'hover';
120
+ var isPlaceholder = appearance === 'placeholder';
120
121
  var previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce(function (sum, cur) {
121
122
  return sum + cur;
122
123
  }, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0;
@@ -138,7 +139,7 @@ export var ColumnControls = function ColumnControls(_ref) {
138
139
  width: '100%',
139
140
  position: 'relative'
140
141
  },
141
- "data-testid": "table-floating-column-".concat(isHover ? colIndex : selectedColIndexes[0], "-drag-handle")
142
+ "data-testid": "table-floating-column-".concat(isHover ? colIndex : isPlaceholder ? appearance : selectedColIndexes[0], "-drag-handle")
142
143
  }, /*#__PURE__*/React.createElement(DragHandle, {
143
144
  isDragMenuTarget: !isHover,
144
145
  direction: "column",
@@ -163,10 +164,13 @@ export var ColumnControls = function ColumnControls(_ref) {
163
164
  if (!tableActive) {
164
165
  return null;
165
166
  }
167
+ var selectedAppearance = isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder';
166
168
 
167
169
  // placeholder / selected need to always render at least one handle
168
170
  // so it can be focused via keyboard shortcuts
169
- handles.push(generateHandleByType('selected', isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', "".concat(selectedColIndexes[0] + 1, " / span ").concat(selectedColIndexes.length), selectedColIndexes));
171
+ handles.push(generateHandleByType('selected', selectedAppearance,
172
+ // always position placeholder in first column to avoid overflow issues
173
+ selectedAppearance === 'placeholder' ? '1 / span 1' : "".concat(selectedColIndexes[0] + 1, " / span ").concat(selectedColIndexes.length), selectedColIndexes));
170
174
  if (hoveredCell && isTableHovered && colIndex !== undefined && !selectedColIndexes.includes(colIndex)) {
171
175
  handles.push(generateHandleByType('hover', 'default', "".concat(colIndex + 1, " / span 1"), colIndexes));
172
176
  }
@@ -19,11 +19,12 @@ interface TableResizerProps {
19
19
  displayGapCursor: (toggle: boolean) => boolean;
20
20
  pluginInjectionApi?: PluginInjectionAPI;
21
21
  isTableScalingEnabled?: boolean;
22
+ isTableAlignmentEnabled?: boolean;
22
23
  isWholeTableInDanger?: boolean;
23
24
  }
24
25
  export interface TableResizerImprovementProps extends TableResizerProps {
25
26
  onResizeStop?: () => void;
26
27
  onResizeStart?: () => void;
27
28
  }
28
- export declare const TableResizer: ({ children, width, maxWidth, containerWidth, updateWidth, onResizeStop, onResizeStart, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, displayGapCursor, isTableScalingEnabled, isWholeTableInDanger, pluginInjectionApi, }: PropsWithChildren<TableResizerImprovementProps>) => JSX.Element;
29
+ export declare const TableResizer: ({ children, width, maxWidth, containerWidth, updateWidth, onResizeStop, onResizeStart, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, displayGapCursor, isTableScalingEnabled, isTableAlignmentEnabled, isWholeTableInDanger, pluginInjectionApi, }: PropsWithChildren<TableResizerImprovementProps>) => JSX.Element;
29
30
  export {};
@@ -19,11 +19,12 @@ interface TableResizerProps {
19
19
  displayGapCursor: (toggle: boolean) => boolean;
20
20
  pluginInjectionApi?: PluginInjectionAPI;
21
21
  isTableScalingEnabled?: boolean;
22
+ isTableAlignmentEnabled?: boolean;
22
23
  isWholeTableInDanger?: boolean;
23
24
  }
24
25
  export interface TableResizerImprovementProps extends TableResizerProps {
25
26
  onResizeStop?: () => void;
26
27
  onResizeStart?: () => void;
27
28
  }
28
- export declare const TableResizer: ({ children, width, maxWidth, containerWidth, updateWidth, onResizeStop, onResizeStart, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, displayGapCursor, isTableScalingEnabled, isWholeTableInDanger, pluginInjectionApi, }: PropsWithChildren<TableResizerImprovementProps>) => JSX.Element;
29
+ export declare const TableResizer: ({ children, width, maxWidth, containerWidth, updateWidth, onResizeStop, onResizeStart, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, displayGapCursor, isTableScalingEnabled, isTableAlignmentEnabled, isWholeTableInDanger, pluginInjectionApi, }: PropsWithChildren<TableResizerImprovementProps>) => JSX.Element;
29
30
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "7.16.2",
3
+ "version": "7.16.4",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -254,6 +254,7 @@ export const ResizableTableContainer = React.memo(
254
254
  displayGuideline,
255
255
  attachAnalyticsEvent,
256
256
  displayGapCursor,
257
+ isTableAlignmentEnabled,
257
258
  isTableScalingEnabled,
258
259
  isWholeTableInDanger,
259
260
  pluginInjectionApi,
@@ -48,6 +48,7 @@ import {
48
48
  TABLE_HIGHLIGHT_TOLERANCE,
49
49
  TABLE_SNAP_GAP,
50
50
  } from '../ui/consts';
51
+ import { normaliseAlignment } from '../utils/alignment';
51
52
  import {
52
53
  generateResizedPayload,
53
54
  generateResizeFrameRatePayloads,
@@ -79,6 +80,7 @@ interface TableResizerProps {
79
80
  displayGapCursor: (toggle: boolean) => boolean;
80
81
  pluginInjectionApi?: PluginInjectionAPI;
81
82
  isTableScalingEnabled?: boolean;
83
+ isTableAlignmentEnabled?: boolean;
82
84
  isWholeTableInDanger?: boolean;
83
85
  }
84
86
 
@@ -169,6 +171,7 @@ export const TableResizer = ({
169
171
  attachAnalyticsEvent,
170
172
  displayGapCursor,
171
173
  isTableScalingEnabled,
174
+ isTableAlignmentEnabled,
172
175
  isWholeTableInDanger,
173
176
  pluginInjectionApi,
174
177
  }: PropsWithChildren<TableResizerImprovementProps>) => {
@@ -594,6 +597,13 @@ export const TableResizer = ({
594
597
  }
595
598
  }, [width]);
596
599
 
600
+ const resizeRatio =
601
+ !isTableAlignmentEnabled ||
602
+ (isTableAlignmentEnabled &&
603
+ normaliseAlignment(node.attrs.layout) === 'center')
604
+ ? 2
605
+ : 1;
606
+
597
607
  return (
598
608
  <>
599
609
  <ResizerNext
@@ -606,7 +616,7 @@ export const TableResizer = ({
606
616
  handleResizeStart={handleResizeStart}
607
617
  handleResize={scheduleResize}
608
618
  handleResizeStop={handleResizeStop}
609
- resizeRatio={2}
619
+ resizeRatio={resizeRatio}
610
620
  minWidth={resizerMinWidth}
611
621
  maxWidth={maxWidth}
612
622
  snapGap={TABLE_SNAP_GAP}
@@ -195,6 +195,7 @@ export const ColumnControls = ({
195
195
  indexes: number[],
196
196
  ) => {
197
197
  const isHover = type === 'hover';
198
+ const isPlaceholder = appearance === 'placeholder';
198
199
  const previewHeight = rowHeights?.reduce((sum, cur) => sum + cur, 0) ?? 0;
199
200
 
200
201
  const previewWidth =
@@ -221,7 +222,11 @@ export const ColumnControls = ({
221
222
  position: 'relative',
222
223
  }}
223
224
  data-testid={`table-floating-column-${
224
- isHover ? colIndex : selectedColIndexes[0]
225
+ isHover
226
+ ? colIndex
227
+ : isPlaceholder
228
+ ? appearance
229
+ : selectedColIndexes[0]
225
230
  }-drag-handle`}
226
231
  >
227
232
  <DragHandle
@@ -254,17 +259,23 @@ export const ColumnControls = ({
254
259
  return null;
255
260
  }
256
261
 
262
+ const selectedAppearance =
263
+ isColumnSelected && isEntireTableSelected
264
+ ? isInDanger
265
+ ? 'danger'
266
+ : 'selected'
267
+ : 'placeholder';
268
+
257
269
  // placeholder / selected need to always render at least one handle
258
270
  // so it can be focused via keyboard shortcuts
259
271
  handles.push(
260
272
  generateHandleByType(
261
273
  'selected',
262
- isColumnSelected && isEntireTableSelected
263
- ? isInDanger
264
- ? 'danger'
265
- : 'selected'
266
- : 'placeholder',
267
- `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`,
274
+ selectedAppearance,
275
+ // always position placeholder in first column to avoid overflow issues
276
+ selectedAppearance === 'placeholder'
277
+ ? '1 / span 1'
278
+ : `${selectedColIndexes[0] + 1} / span ${selectedColIndexes.length}`,
268
279
  selectedColIndexes,
269
280
  ),
270
281
  );