@atlaskit/renderer 137.1.9 → 137.1.11
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 +14 -0
- package/dist/cjs/actions/index.js +2 -2
- package/dist/cjs/react/index.js +2 -2
- package/dist/cjs/react/marks/breakout.js +3 -3
- package/dist/cjs/react/marks/code.js +1 -1
- package/dist/cjs/react/nodes/date.js +1 -1
- package/dist/cjs/react/nodes/embedCard.js +2 -2
- package/dist/cjs/react/nodes/heading-anchor.js +1 -1
- package/dist/cjs/react/nodes/layoutSection.js +2 -2
- package/dist/cjs/react/nodes/mediaInline.js +1 -1
- package/dist/cjs/react/nodes/mediaSingle/index.js +1 -1
- package/dist/cjs/react/nodes/table/colgroup.js +1 -2
- package/dist/cjs/react/nodes/table/sticky.js +2 -4
- package/dist/cjs/react/nodes/table/table.js +1 -12
- package/dist/cjs/react/nodes/table.js +474 -206
- package/dist/cjs/ui/Expand.js +1 -1
- package/dist/cjs/ui/Renderer/RendererStyleContainer.js +3 -3
- package/dist/cjs/ui/Renderer/breakout-ssr.js +1 -2
- package/dist/cjs/ui/Renderer/index.js +7 -7
- package/dist/cjs/utils.js +2 -2
- package/dist/es2019/actions/index.js +1 -1
- package/dist/es2019/react/index.js +1 -1
- package/dist/es2019/react/marks/breakout.js +1 -1
- package/dist/es2019/react/marks/code.js +1 -1
- package/dist/es2019/react/nodes/date.js +1 -1
- package/dist/es2019/react/nodes/embedCard.js +1 -1
- package/dist/es2019/react/nodes/heading-anchor.js +1 -1
- package/dist/es2019/react/nodes/layoutSection.js +1 -1
- package/dist/es2019/react/nodes/mediaInline.js +1 -1
- package/dist/es2019/react/nodes/mediaSingle/index.js +1 -1
- package/dist/es2019/react/nodes/table/colgroup.js +1 -2
- package/dist/es2019/react/nodes/table/sticky.js +2 -3
- package/dist/es2019/react/nodes/table/table.js +1 -12
- package/dist/es2019/react/nodes/table.js +458 -191
- package/dist/es2019/ui/Expand.js +1 -1
- package/dist/es2019/ui/Renderer/RendererStyleContainer.js +1 -1
- package/dist/es2019/ui/Renderer/breakout-ssr.js +1 -2
- package/dist/es2019/ui/Renderer/index.js +4 -4
- package/dist/es2019/utils.js +1 -1
- package/dist/esm/actions/index.js +1 -1
- package/dist/esm/react/index.js +1 -1
- package/dist/esm/react/marks/breakout.js +1 -1
- package/dist/esm/react/marks/code.js +1 -1
- package/dist/esm/react/nodes/date.js +1 -1
- package/dist/esm/react/nodes/embedCard.js +1 -1
- package/dist/esm/react/nodes/heading-anchor.js +1 -1
- package/dist/esm/react/nodes/layoutSection.js +1 -1
- package/dist/esm/react/nodes/mediaInline.js +1 -1
- package/dist/esm/react/nodes/mediaSingle/index.js +1 -1
- package/dist/esm/react/nodes/table/colgroup.js +1 -2
- package/dist/esm/react/nodes/table/sticky.js +2 -4
- package/dist/esm/react/nodes/table/table.js +1 -12
- package/dist/esm/react/nodes/table.js +472 -203
- package/dist/esm/ui/Expand.js +1 -1
- package/dist/esm/ui/Renderer/RendererStyleContainer.js +1 -1
- package/dist/esm/ui/Renderer/breakout-ssr.js +1 -2
- package/dist/esm/ui/Renderer/index.js +4 -4
- package/dist/esm/utils.js +1 -1
- package/dist/types/react/nodes/table/sticky.d.ts +1 -2
- package/dist/types/react/nodes/table.d.ts +78 -8
- package/package.json +5 -7
- package/dist/cjs/react/nodes/tableNew.js +0 -1020
- package/dist/es2019/react/nodes/tableNew.js +0 -956
- package/dist/esm/react/nodes/tableNew.js +0 -1014
- package/dist/types/react/nodes/tableNew.d.ts +0 -189
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
/* eslint-disable @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/enforce-style-prop, @repo/internal/react/no-class-components */
|
|
3
4
|
import React from 'react';
|
|
4
|
-
import { useIntl } from 'react-intl';
|
|
5
5
|
import { TableSharedCssClassName, tableMarginTop } from '@atlaskit/editor-common/styles';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { overflowShadow } from '@atlaskit/editor-common/ui';
|
|
7
|
+
import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
|
|
8
|
+
import { FullPagePadding } from '../../ui/Renderer/style';
|
|
8
9
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
10
|
+
import { RendererCssClassName } from '../../consts';
|
|
9
11
|
import { createCompareNodes, convertProsemirrorTableNodeToArrayOfRows, hasMergedCell, compose } from '@atlaskit/editor-common/utils';
|
|
10
12
|
import { SortOrder } from '@atlaskit/editor-common/types';
|
|
11
13
|
import { akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth, akEditorMaxWidthLayoutWidth } from '@atlaskit/editor-shared-styles';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { FullPagePadding } from '../../ui/Renderer/style';
|
|
15
|
-
import { TableHeader } from './tableCell';
|
|
14
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
15
|
+
import { TableCell, TableHeader } from './tableCell';
|
|
16
16
|
import { withSmartCardStorage } from '../../ui/SmartCardStorage';
|
|
17
17
|
import { StickyTable, tableStickyPadding, OverflowParent } from './table/sticky';
|
|
18
18
|
import { Table } from './table/table';
|
|
19
|
-
import { isCommentAppearance,
|
|
19
|
+
import { isCommentAppearance, isFullWidthOrFullPageAppearance, isFullWidthAppearance, isMaxWidthAppearance, isFullPageAppearance } from '../utils/appearance';
|
|
20
20
|
import { TableStickyScrollbar } from './TableStickyScrollbar';
|
|
21
21
|
import { useRendererContext } from '../../renderer-context';
|
|
22
|
-
import { TableProcessorWithContainerStyles, RefSyncBlockFakeBorders } from './tableNew';
|
|
23
22
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
24
23
|
import { isTableInContentMode } from '@atlaskit/editor-common/table';
|
|
25
24
|
import { isContentModeSupported } from './table/content-mode';
|
|
25
|
+
const stickyContainerBaseStyles = {
|
|
26
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
27
|
+
height: "var(--ds-space-250, 20px)",
|
|
28
|
+
// MAX_BROWSER_SCROLLBAR_HEIGHT
|
|
29
|
+
// Follow editor to hide by default so it does not show empty gap in SSR
|
|
30
|
+
// https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/editor/editor-plugin-table/src/nodeviews/TableComponent.tsx#957
|
|
31
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
32
|
+
display: 'block',
|
|
33
|
+
width: '100%'
|
|
34
|
+
};
|
|
35
|
+
const stickyContainerAdditionalStyles = {
|
|
36
|
+
visibility: 'hidden',
|
|
37
|
+
overflowX: 'auto',
|
|
38
|
+
position: 'sticky',
|
|
39
|
+
bottom: "var(--ds-space-0, 0px)",
|
|
40
|
+
zIndex: 1
|
|
41
|
+
};
|
|
26
42
|
export const isTableResizingEnabled = appearance => isFullWidthOrFullPageAppearance(appearance) || isCommentAppearance(appearance);
|
|
27
43
|
export const isStickyScrollbarEnabled = appearance => isFullWidthOrFullPageAppearance(appearance) && editorExperiment('platform_renderer_table_sticky_scrollbar', true, {
|
|
28
44
|
exposure: true
|
|
@@ -69,7 +85,7 @@ export const getRefTop = refElement => {
|
|
|
69
85
|
export const shouldHeaderStick = (scrollTop, tableTop, tableBottom, rowHeight) => tableTop <= scrollTop && !(tableBottom - rowHeight <= scrollTop);
|
|
70
86
|
export const shouldHeaderPinBottom = (scrollTop, tableBottom, rowHeight) => tableBottom - rowHeight <= scrollTop && !(tableBottom < scrollTop);
|
|
71
87
|
export const addSortableColumn = (rows, tableOrderStatus, onSorting
|
|
72
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
89
|
) => {
|
|
74
90
|
return React.Children.map(rows, (row, index) => {
|
|
75
91
|
if (index === 0) {
|
|
@@ -100,46 +116,54 @@ export const isHeaderRowEnabled = (rows
|
|
|
100
116
|
}
|
|
101
117
|
return children.every(node => node.type === TableHeader);
|
|
102
118
|
};
|
|
119
|
+
export const tableCanBeSticky = (node, children
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
|
+
) => {
|
|
122
|
+
return isHeaderRowEnabled(children) && node && node.firstChild && !hasRowspan(node.firstChild);
|
|
123
|
+
};
|
|
103
124
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
125
|
+
* Fake left/right borders rendered as direct children of TABLE_CONTAINER
|
|
126
|
+
* (the non-scrolling parent of the horizontally scrolling TABLE_NODE_WRAPPER).
|
|
106
127
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
128
|
+
* The visible styling for these divs lives in `tableFakeBorderStyles`
|
|
129
|
+
* (`renderer/src/ui/Renderer/RendererStyleContainer.tsx`), which is applied
|
|
130
|
+
* when `isInsideSyncBlock` is true.
|
|
131
|
+
*/
|
|
132
|
+
const TableFakeBorders = ({
|
|
133
|
+
isNumberColumnEnabled
|
|
134
|
+
}) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
135
|
+
className: TableSharedCssClassName.TABLE_LEFT_BORDER,
|
|
136
|
+
"data-with-numbered-table": isNumberColumnEnabled ? 'true' : undefined,
|
|
137
|
+
"data-testid": "table-left-border"
|
|
138
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
139
|
+
className: TableSharedCssClassName.TABLE_RIGHT_BORDER,
|
|
140
|
+
"data-with-numbered-table": isNumberColumnEnabled ? 'true' : undefined,
|
|
141
|
+
"data-testid": "table-right-border"
|
|
142
|
+
}));
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Reads `nestedRendererType` from RendererContext and renders the fake left/right
|
|
146
|
+
* borders only when the current renderer is the nested renderer for a reference
|
|
147
|
+
* synced block.
|
|
110
148
|
*/
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
wrapperRef,
|
|
114
|
-
onScroll,
|
|
115
|
-
stickyHeaders,
|
|
116
|
-
tabIndex
|
|
149
|
+
export const RefSyncBlockFakeBorders = ({
|
|
150
|
+
isNumberColumnEnabled
|
|
117
151
|
}) => {
|
|
118
152
|
const {
|
|
119
|
-
|
|
120
|
-
} =
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// eslint-disable-next-line @atlassian/a11y/no-noninteractive-tabindex
|
|
129
|
-
,
|
|
130
|
-
tabIndex: tabIndex,
|
|
131
|
-
role: isScrollableRegion ? 'region' : undefined,
|
|
132
|
-
"aria-label": isScrollableRegion ? formatMessage(tableMessages.tableScrollRegion) : undefined
|
|
133
|
-
}, children);
|
|
134
|
-
};
|
|
135
|
-
export const tableCanBeSticky = (node, children
|
|
136
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
137
|
-
) => {
|
|
138
|
-
return isHeaderRowEnabled(children) && node && node.firstChild && !hasRowspan(node.firstChild);
|
|
153
|
+
nestedRendererType
|
|
154
|
+
} = useRendererContext();
|
|
155
|
+
const isInsideOfRefSyncBlock = nestedRendererType === 'syncedBlock';
|
|
156
|
+
if (!isInsideOfRefSyncBlock) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
return /*#__PURE__*/React.createElement(TableFakeBorders, {
|
|
160
|
+
isNumberColumnEnabled: isNumberColumnEnabled
|
|
161
|
+
});
|
|
139
162
|
};
|
|
163
|
+
|
|
140
164
|
/**
|
|
141
|
-
*
|
|
142
|
-
*/
|
|
165
|
+
* TableContainer renders tables using only CSS-based rules
|
|
166
|
+
*/
|
|
143
167
|
// Ignored via go/ees005
|
|
144
168
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
145
169
|
export class TableContainer extends React.Component {
|
|
@@ -157,6 +181,12 @@ export class TableContainer extends React.Component {
|
|
|
157
181
|
_defineProperty(this, "stickyWrapperRef", /*#__PURE__*/React.createRef());
|
|
158
182
|
_defineProperty(this, "wrapperRef", /*#__PURE__*/React.createRef());
|
|
159
183
|
_defineProperty(this, "overflowParent", null);
|
|
184
|
+
_defineProperty(this, "containerRef", null);
|
|
185
|
+
_defineProperty(this, "_isInsideNestedRenderer", null);
|
|
186
|
+
_defineProperty(this, "_isInsideTableCell", null);
|
|
187
|
+
// Stores the last computed style values from render() for use by applyNestedRendererTableFix().
|
|
188
|
+
// This avoids reading from the DOM which can be stale when React removes properties between renders.
|
|
189
|
+
_defineProperty(this, "lastComputedStyle", {});
|
|
160
190
|
_defineProperty(this, "resizeObserver", null);
|
|
161
191
|
_defineProperty(this, "applyResizerChange", entries => {
|
|
162
192
|
let wrapperWidth = this.state.wrapperWidth;
|
|
@@ -175,6 +205,27 @@ export class TableContainer extends React.Component {
|
|
|
175
205
|
});
|
|
176
206
|
}
|
|
177
207
|
});
|
|
208
|
+
/**
|
|
209
|
+
* Callback ref that captures the container DOM element and also forwards
|
|
210
|
+
* to the handleRef prop from the overflow shadow HOC.
|
|
211
|
+
*/
|
|
212
|
+
_defineProperty(this, "setContainerRef", el => {
|
|
213
|
+
if (this.containerRef !== el) {
|
|
214
|
+
this._isInsideNestedRenderer = null;
|
|
215
|
+
this._isInsideTableCell = null;
|
|
216
|
+
}
|
|
217
|
+
this.containerRef = el;
|
|
218
|
+
const {
|
|
219
|
+
handleRef
|
|
220
|
+
} = this.props;
|
|
221
|
+
if (typeof handleRef === 'function') {
|
|
222
|
+
handleRef(el);
|
|
223
|
+
} else if (handleRef && typeof handleRef === 'object') {
|
|
224
|
+
// Ignored via go/ees005
|
|
225
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
226
|
+
handleRef.current = el;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
178
229
|
_defineProperty(this, "componentWillUnmount", () => {
|
|
179
230
|
if (this.overflowParent) {
|
|
180
231
|
// Ignored via go/ees005
|
|
@@ -250,6 +301,137 @@ export class TableContainer extends React.Component {
|
|
|
250
301
|
});
|
|
251
302
|
}
|
|
252
303
|
/**
|
|
304
|
+
* Checks if this table is inside a nested renderer (e.g. Include Page macro)
|
|
305
|
+
* by looking for multiple .ak-renderer-document ancestors in the DOM.
|
|
306
|
+
* The result is cached since a table's position in the DOM tree is stable after mount.
|
|
307
|
+
*/
|
|
308
|
+
isInsideNestedRenderer() {
|
|
309
|
+
if (this._isInsideNestedRenderer !== null) {
|
|
310
|
+
return this._isInsideNestedRenderer;
|
|
311
|
+
}
|
|
312
|
+
if (!this.containerRef) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
let docAncestorCount = 0;
|
|
316
|
+
let el = this.containerRef.parentElement;
|
|
317
|
+
while (el) {
|
|
318
|
+
if (el.classList.contains(RendererCssClassName.DOCUMENT)) {
|
|
319
|
+
docAncestorCount++;
|
|
320
|
+
if (docAncestorCount >= 2) {
|
|
321
|
+
this._isInsideNestedRenderer = true;
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
el = el.parentElement;
|
|
326
|
+
}
|
|
327
|
+
this._isInsideNestedRenderer = false;
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Checks if this table is inside a table cell in the DOM. The result is cached
|
|
333
|
+
* since a table's position in the DOM tree is stable after mount.
|
|
334
|
+
*/
|
|
335
|
+
isInsideTableCell() {
|
|
336
|
+
if (this._isInsideTableCell !== null) {
|
|
337
|
+
return this._isInsideTableCell;
|
|
338
|
+
}
|
|
339
|
+
if (!this.containerRef) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
this._isInsideTableCell = Boolean(this.containerRef.closest('td, th'));
|
|
343
|
+
return this._isInsideTableCell;
|
|
344
|
+
}
|
|
345
|
+
isInsideTableContext() {
|
|
346
|
+
return Boolean(this.props.isInsideOfTable || this.isInsideTableCell());
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* For tables inside nested renderers (e.g. Include Page macro), the parent
|
|
351
|
+
* renderer's CSS override forces width:100%!important and left:0!important
|
|
352
|
+
* which overrides the inline styles set by this component. Using
|
|
353
|
+
* style.setProperty with 'important' priority on inline styles beats
|
|
354
|
+
* stylesheet !important rules per the CSS cascade.
|
|
355
|
+
*
|
|
356
|
+
* Tables that are nested inside another table need to remain constrained by
|
|
357
|
+
* their table-cell context. Do not promote their width to inline !important,
|
|
358
|
+
* otherwise nested tables rendered through macros such as Excerpt Include can
|
|
359
|
+
* overflow and overlap adjacent cells.
|
|
360
|
+
*
|
|
361
|
+
* Top-level tables in nested renderers still preserve their saved width, but
|
|
362
|
+
* are capped to their containing block so wide tables do not escape constrained
|
|
363
|
+
* macro bodies such as Excerpt Include panels.
|
|
364
|
+
*
|
|
365
|
+
* Uses lastComputedStyle (populated during render) rather than reading from
|
|
366
|
+
* element.style, because React may remove properties from the DOM when their
|
|
367
|
+
* values transition to undefined between renders.
|
|
368
|
+
*
|
|
369
|
+
* `platform_nested_table_style_override_2` fixes a follow-up regression where a
|
|
370
|
+
* NON-resized table inside an Excerpt macro (not Excerpt Include) on a
|
|
371
|
+
* wide/full-width page shrinks to only show its first columns in the renderer.
|
|
372
|
+
* Inside a nested renderer (a macro body) a non-resized table's computed width
|
|
373
|
+
* is a default layout cap (760px/1800px, or a `cqw` length for full-page
|
|
374
|
+
* appearances) taken from the outer renderer's width context. That value does
|
|
375
|
+
* not match the macro's own box, so promoting it to inline `!important` makes
|
|
376
|
+
* the table collapse. Such tables have no author-chosen size to preserve, so
|
|
377
|
+
* under this gate we re-assert the parent stylesheet's intent (fill the box:
|
|
378
|
+
* `width: 100%; left: 0`) with inline `!important`.
|
|
379
|
+
*
|
|
380
|
+
* Explicitly resized tables (`tableNode.attrs.width` set) are excluded and keep
|
|
381
|
+
* the original PGXT-10226 behavior: their author-chosen width/left is promoted
|
|
382
|
+
* verbatim so the Include Page macro does not stretch or indent them. The
|
|
383
|
+
* table-cell short-circuit (PGXT-10294) above also still applies.
|
|
384
|
+
*/
|
|
385
|
+
applyNestedRendererTableFix() {
|
|
386
|
+
var _this$props$tableNode;
|
|
387
|
+
if (!this.containerRef || !fg('platform_nested_table_style_override')) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (!this.isInsideNestedRenderer() || this.isInsideTableContext()) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const {
|
|
394
|
+
width,
|
|
395
|
+
left,
|
|
396
|
+
marginLeft
|
|
397
|
+
} = this.lastComputedStyle;
|
|
398
|
+
const style = this.containerRef.style;
|
|
399
|
+
|
|
400
|
+
// A table is "explicitly resized" when the author set a width on the node.
|
|
401
|
+
// Non-resized tables instead take a default layout cap (e.g. 760px/1800px)
|
|
402
|
+
// derived from the outer renderer's appearance.
|
|
403
|
+
const isExplicitlyResized = Boolean((_this$props$tableNode = this.props.tableNode) === null || _this$props$tableNode === void 0 ? void 0 : _this$props$tableNode.attrs.width);
|
|
404
|
+
if (!isExplicitlyResized && fg('platform_nested_table_style_override_2')) {
|
|
405
|
+
// PGXT-10421: For a NON-resized table inside a nested renderer (e.g. an
|
|
406
|
+
// Excerpt macro body), the computed width is a default layout cap
|
|
407
|
+
// (760px/1800px, or a `cqw` length for full-page appearances) taken from
|
|
408
|
+
// the *outer* renderer's width context. That value does not match the
|
|
409
|
+
// macro's own box, so promoting it to inline `!important` makes the table
|
|
410
|
+
// ignore the available space and collapse to its first columns.
|
|
411
|
+
//
|
|
412
|
+
// These tables have no author-chosen size to preserve, so re-assert the
|
|
413
|
+
// parent stylesheet's intent — fill the available box (`width: 100%`) —
|
|
414
|
+
// with inline `!important` priority so it survives React re-renders and
|
|
415
|
+
// wins over the stylesheet rule that leaks into nested renderers.
|
|
416
|
+
style.setProperty('width', '100%', 'important');
|
|
417
|
+
style.setProperty('max-width', '100%', 'important');
|
|
418
|
+
style.setProperty('left', '0', 'important');
|
|
419
|
+
style.setProperty('margin-left', '0', 'important');
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// PGXT-10226: An explicitly resized table inside a nested renderer (e.g.
|
|
424
|
+
// Include Page macro) must keep its author-chosen width and position. The
|
|
425
|
+
// parent stylesheet forces `width: 100% !important; left: 0 !important`,
|
|
426
|
+
// which would stretch and indent it, so we promote the component's own
|
|
427
|
+
// computed width/left with inline `!important` to win the cascade.
|
|
428
|
+
style.setProperty('width', width || 'auto', 'important');
|
|
429
|
+
style.setProperty('max-width', '100%', 'important');
|
|
430
|
+
style.setProperty('left', left || 'auto', 'important');
|
|
431
|
+
style.setProperty('margin-left', marginLeft || '0', 'important');
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Starts observing table dimensions and wires sticky header/scrollbar behavior after mount.
|
|
253
435
|
*
|
|
254
436
|
* @example
|
|
255
437
|
*/
|
|
@@ -271,9 +453,11 @@ export class TableContainer extends React.Component {
|
|
|
271
453
|
if (this.wrapperRef.current && isStickyScrollbarEnabled(this.props.rendererAppearance)) {
|
|
272
454
|
this.stickyScrollbar = new TableStickyScrollbar(this.wrapperRef.current);
|
|
273
455
|
}
|
|
456
|
+
this.applyNestedRendererTableFix();
|
|
274
457
|
}
|
|
275
458
|
|
|
276
459
|
/**
|
|
460
|
+
* Updates sticky header wiring and scroll synchronization after prop or state changes.
|
|
277
461
|
*
|
|
278
462
|
* @param prevProps
|
|
279
463
|
* @param prevState
|
|
@@ -300,9 +484,13 @@ export class TableContainer extends React.Component {
|
|
|
300
484
|
if (prevState.stickyMode !== this.state.stickyMode) {
|
|
301
485
|
this.onWrapperScrolled();
|
|
302
486
|
}
|
|
487
|
+
|
|
488
|
+
// React re-applies the style prop on every render, which overwrites the
|
|
489
|
+
// !important priorities set at mount time. Re-apply after each update.
|
|
490
|
+
this.applyNestedRendererTableFix();
|
|
303
491
|
}
|
|
304
492
|
/**
|
|
305
|
-
*
|
|
493
|
+
* Calculates the top offset used when the sticky header is pinned to the table bottom.
|
|
306
494
|
*/
|
|
307
495
|
get pinTop() {
|
|
308
496
|
if (!this.tableRef.current || !this.stickyHeaderRef.current) {
|
|
@@ -312,7 +500,7 @@ export class TableContainer extends React.Component {
|
|
|
312
500
|
}
|
|
313
501
|
|
|
314
502
|
/**
|
|
315
|
-
*
|
|
503
|
+
* Determines whether sticky header positioning should include the default scroll root offset.
|
|
316
504
|
*/
|
|
317
505
|
get shouldAddOverflowParentOffsetTop_DO_NOT_USE() {
|
|
318
506
|
// IF the StickyHeaderConfig specifies that the default scroll root offsetTop should be added
|
|
@@ -323,7 +511,7 @@ export class TableContainer extends React.Component {
|
|
|
323
511
|
}
|
|
324
512
|
|
|
325
513
|
/**
|
|
326
|
-
*
|
|
514
|
+
* Resolves the top position for the sticky header based on the current sticky mode.
|
|
327
515
|
*/
|
|
328
516
|
get stickyTop() {
|
|
329
517
|
switch (this.state.stickyMode) {
|
|
@@ -343,6 +531,7 @@ export class TableContainer extends React.Component {
|
|
|
343
531
|
}
|
|
344
532
|
|
|
345
533
|
/**
|
|
534
|
+
* Renders the table container, sticky header, table content, sticky scrollbar, and synced block borders.
|
|
346
535
|
*
|
|
347
536
|
* @example
|
|
348
537
|
*/
|
|
@@ -351,7 +540,6 @@ export class TableContainer extends React.Component {
|
|
|
351
540
|
const {
|
|
352
541
|
isNumberColumnEnabled,
|
|
353
542
|
layout,
|
|
354
|
-
renderWidth,
|
|
355
543
|
columnWidths,
|
|
356
544
|
stickyHeaders,
|
|
357
545
|
tableNode,
|
|
@@ -369,64 +557,43 @@ export class TableContainer extends React.Component {
|
|
|
369
557
|
stickyMode
|
|
370
558
|
} = this.state;
|
|
371
559
|
const lineLengthFixedWidth = akEditorDefaultLayoutWidth;
|
|
372
|
-
let left;
|
|
373
560
|
let updatedLayout;
|
|
374
|
-
|
|
375
|
-
// The tableWidth and left offset logic below must stay aligned with the `breakout-ssr.tsx` logic
|
|
376
|
-
// Please consider changes below carefully to not negatively impact SSR
|
|
377
|
-
// `renderWidth` cannot be depended on during SSR
|
|
378
|
-
const isRenderWidthValid = !!renderWidth && renderWidth > 0;
|
|
379
561
|
const fullPageRendererWidthCSS = editorExperiment('platform_editor_preview_panel_responsiveness', true, {
|
|
380
562
|
exposure: true
|
|
381
563
|
}) ? 'calc(100cqw - var(--ak-renderer--full-page-gutter) * 2)' : `100cqw - ${FullPagePadding}px * 2`;
|
|
382
564
|
const renderWidthCSS = rendererAppearance === 'full-page' ? fullPageRendererWidthCSS : `100cqw`;
|
|
383
565
|
const calcDefaultLayoutWidthByAppearance = (rendererAppearance, tableNode) => {
|
|
384
|
-
if (rendererAppearance === '
|
|
385
|
-
return
|
|
386
|
-
} else if (rendererAppearance === '
|
|
387
|
-
return
|
|
566
|
+
if (rendererAppearance === 'max' && !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width) && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) {
|
|
567
|
+
return `min(${akEditorMaxWidthLayoutWidth}px, ${renderWidthCSS})`;
|
|
568
|
+
} else if (rendererAppearance === 'full-width' && !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width)) {
|
|
569
|
+
return `min(${akEditorFullWidthLayoutWidth}px, ${renderWidthCSS})`;
|
|
388
570
|
} else if (rendererAppearance === 'comment' && allowTableResizing && !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width)) {
|
|
389
|
-
|
|
390
|
-
return [isRenderWidthValid ? renderWidth : tableContainerWidth, renderWidthCSS];
|
|
571
|
+
return renderWidthCSS;
|
|
391
572
|
} else {
|
|
392
573
|
// custom width, or width mapped to breakpoint
|
|
393
574
|
const tableContainerWidth = getTableContainerWidth(tableNode);
|
|
394
|
-
return
|
|
575
|
+
return `min(${tableContainerWidth}px, ${renderWidthCSS})`;
|
|
395
576
|
}
|
|
396
577
|
};
|
|
397
|
-
const
|
|
578
|
+
const tableWidthCSS = calcDefaultLayoutWidthByAppearance(rendererAppearance, tableNode);
|
|
398
579
|
|
|
399
580
|
// Logic for table alignment in renderer
|
|
400
581
|
const isTableAlignStart = tableNode && tableNode.attrs && tableNode.attrs.layout === 'align-start' && allowTableAlignment;
|
|
401
|
-
const fullWidthLineLength = isRenderWidthValid ? Math.min(akEditorFullWidthLayoutWidth, renderWidth) : akEditorFullWidthLayoutWidth;
|
|
402
582
|
const fullWidthLineLengthCSS = `min(${akEditorFullWidthLayoutWidth}px, ${renderWidthCSS})`;
|
|
403
|
-
const maxWidthLineLength = isRenderWidthValid ? Math.min(akEditorMaxWidthLayoutWidth, renderWidth) : akEditorMaxWidthLayoutWidth;
|
|
404
583
|
const maxWidthLineLengthCSS = `min(${akEditorMaxWidthLayoutWidth}px, ${renderWidthCSS})`;
|
|
405
|
-
const commentLineLength = isRenderWidthValid ? renderWidth : lineLengthFixedWidth;
|
|
406
584
|
const isCommentAppearanceAndTableAlignmentEnabled = isCommentAppearance(rendererAppearance) && allowTableAlignment;
|
|
407
|
-
const lineLength = isFullWidthAppearance(rendererAppearance) ? fullWidthLineLength : isMaxWidthAppearance(rendererAppearance) && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) ? maxWidthLineLength : isCommentAppearanceAndTableAlignmentEnabled ? commentLineLength : lineLengthFixedWidth;
|
|
408
585
|
const lineLengthCSS = isFullWidthAppearance(rendererAppearance) ? fullWidthLineLengthCSS : isMaxWidthAppearance(rendererAppearance) && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) ? maxWidthLineLengthCSS : isCommentAppearanceAndTableAlignmentEnabled ? renderWidthCSS : `${lineLengthFixedWidth}px`;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const fixTableSSRResizing = false;
|
|
412
|
-
const tableWidthNew = fixTableSSRResizing ? getTableContainerWidth(tableNode) : tableWidth;
|
|
413
|
-
const shouldCalculateLeftForAlignment = !isInsideOfBlockNode && !isInsideOfTable && isTableAlignStart && (isFullPageAppearance(rendererAppearance) && tableWidthNew <= lineLengthFixedWidth || isFullWidthAppearance(rendererAppearance) || (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) && isMaxWidthAppearance(rendererAppearance) || isCommentAppearanceAndTableAlignmentEnabled);
|
|
586
|
+
const tableWidthNew = getTableContainerWidth(tableNode);
|
|
587
|
+
const shouldCalculateLeftForAlignment = !isInsideOfBlockNode && !isInsideOfTable && isTableAlignStart && (isFullPageAppearance(rendererAppearance) && tableWidthNew <= lineLengthFixedWidth || isFullWidthAppearance(rendererAppearance) || isMaxWidthAppearance(rendererAppearance) && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) || isCommentAppearanceAndTableAlignmentEnabled);
|
|
414
588
|
let leftCSS;
|
|
415
589
|
if (shouldCalculateLeftForAlignment) {
|
|
416
|
-
left = (tableWidth - lineLength) / 2;
|
|
417
590
|
leftCSS = `(${tableWidthCSS} - ${lineLengthCSS}) / 2`;
|
|
418
591
|
}
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
leftCSS = `min(0px, ${lineLengthCSS} - ${tableWidthCSS}) / 2`;
|
|
425
|
-
}
|
|
426
|
-
} else {
|
|
427
|
-
if (!shouldCalculateLeftForAlignment && isFullPageAppearance(rendererAppearance) && tableWidthNew > lineLengthFixedWidth) {
|
|
428
|
-
left = lineLengthFixedWidth / 2 - tableWidth / 2;
|
|
429
|
-
}
|
|
592
|
+
if (!shouldCalculateLeftForAlignment && isFullPageAppearance(rendererAppearance)) {
|
|
593
|
+
// Note tableWidthCSS here is the renderer width
|
|
594
|
+
// When the screen is super wide we want table to break out.
|
|
595
|
+
// However if screen is smaller than 760px. We want table align to left.
|
|
596
|
+
leftCSS = `min(0px, ${lineLengthCSS} - ${tableWidthCSS}) / 2`;
|
|
430
597
|
}
|
|
431
598
|
const children = React.Children.toArray(this.props.children);
|
|
432
599
|
|
|
@@ -446,7 +613,7 @@ export class TableContainer extends React.Component {
|
|
|
446
613
|
// We can only use CSS to determine the width when we have a known width in container.
|
|
447
614
|
// When appearance is full-page, full-width or comment we use CSS based width calculation.
|
|
448
615
|
// Otherwise it's fixed table width (customized width) or inherit.
|
|
449
|
-
if (
|
|
616
|
+
if (rendererAppearance === 'full-page' || rendererAppearance === 'full-width' || rendererAppearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) {
|
|
450
617
|
finalTableContainerWidth = allowTableResizing ? `calc(${tableWidthCSS})` : 'inherit';
|
|
451
618
|
}
|
|
452
619
|
if (rendererAppearance === 'comment' && allowTableResizing && !allowTableAlignment) {
|
|
@@ -457,13 +624,13 @@ export class TableContainer extends React.Component {
|
|
|
457
624
|
|
|
458
625
|
// !NOTE: it a table resized to 760 is copied from 'full-page' editor and pasted in comment editor
|
|
459
626
|
// where (allowTableResizing && !allowTableAlignment), the table will loose 760px width.
|
|
460
|
-
finalTableContainerWidth = tableNode !== null && tableNode !== void 0 && tableNode.attrs.width && (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.width) !== akEditorDefaultLayoutWidth ?
|
|
627
|
+
finalTableContainerWidth = tableNode !== null && tableNode !== void 0 && tableNode.attrs.width && (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.width) !== akEditorDefaultLayoutWidth ? `calc(${tableWidthCSS})` : 'inherit';
|
|
461
628
|
}
|
|
462
629
|
if (rendererAppearance === 'comment' && allowTableResizing && allowTableAlignment) {
|
|
463
630
|
// If table alignment is enabled and layout is not 'align-start' or 'center', we are loading a table that was
|
|
464
631
|
// created before "Support Table in Comments" FF was enabled. So the table should have the same width as renderer container
|
|
465
632
|
// instead of 760 that was set on tableNode when the table had been published.
|
|
466
|
-
finalTableContainerWidth = ((tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout) === 'align-start' || (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout) === 'center') && tableNode !== null && tableNode !== void 0 && tableNode.attrs.width ?
|
|
633
|
+
finalTableContainerWidth = ((tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout) === 'align-start' || (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout) === 'center') && tableNode !== null && tableNode !== void 0 && tableNode.attrs.width ? `calc(${tableWidthCSS})` : 'inherit';
|
|
467
634
|
}
|
|
468
635
|
const isContentModeTable = isTableInContentMode({
|
|
469
636
|
tableNode,
|
|
@@ -473,43 +640,40 @@ export class TableContainer extends React.Component {
|
|
|
473
640
|
}),
|
|
474
641
|
isTableNested: isInsideOfBlockNode || isInsideOfNestedRenderer || isInsideOfTable
|
|
475
642
|
}) && expValEquals('platform_editor_table_fit_to_content_auto_convert', 'isEnabled', true);
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
marginLeft: shouldCalculateLeftForAlignment && left !== undefined ? -left : undefined
|
|
494
|
-
};
|
|
495
|
-
}
|
|
643
|
+
const style = {
|
|
644
|
+
...(isContentModeTable && {
|
|
645
|
+
'--renderer-table-max-width': renderWidthCSS
|
|
646
|
+
}),
|
|
647
|
+
width: finalTableContainerWidth,
|
|
648
|
+
left: leftCSS ? `calc(${leftCSS})` : undefined,
|
|
649
|
+
marginLeft: shouldCalculateLeftForAlignment && leftCSS !== undefined ? `calc(-1 * (${leftCSS}))` : undefined
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
// Store computed style values for applyNestedRendererTableFix() to use.
|
|
653
|
+
// Reading from props rather than the DOM ensures correctness when React
|
|
654
|
+
// removes properties (transitions from set to undefined) between renders.
|
|
655
|
+
this.lastComputedStyle = {
|
|
656
|
+
width: typeof style.width === 'number' ? `${style.width}px` : style.width,
|
|
657
|
+
left: style.left,
|
|
658
|
+
marginLeft: style.marginLeft
|
|
659
|
+
};
|
|
496
660
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
497
661
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
498
662
|
className: `${TableSharedCssClassName.TABLE_CONTAINER} ${this.props.shadowClassNames || ''}`,
|
|
499
663
|
"data-layout": updatedLayout,
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
,
|
|
664
|
+
"data-testid": "table-container",
|
|
665
|
+
ref: this.setContainerRef,
|
|
503
666
|
style: style
|
|
667
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
504
668
|
}, isStickyScrollbarEnabled(this.props.rendererAppearance) && /*#__PURE__*/React.createElement("div", {
|
|
505
669
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
506
670
|
className: TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP,
|
|
507
671
|
"data-testid": "sticky-scrollbar-sentinel-top"
|
|
508
|
-
}), stickyHeaders && tableCanBeSticky(tableNode, children) && /*#__PURE__*/React.createElement(StickyTable, {
|
|
672
|
+
}), stickyHeaders && tableNode && !isContentModeTable && tableCanBeSticky(tableNode, children) && /*#__PURE__*/React.createElement(StickyTable, {
|
|
509
673
|
isNumberColumnEnabled: isNumberColumnEnabled,
|
|
510
|
-
tableWidth:
|
|
674
|
+
tableWidth: "inherit",
|
|
675
|
+
renderWidth: 0,
|
|
511
676
|
layout: layout,
|
|
512
|
-
renderWidth: renderWidth,
|
|
513
677
|
handleRef: this.props.handleRef,
|
|
514
678
|
shadowClassNames: this.props.shadowClassNames,
|
|
515
679
|
top: this.stickyTop,
|
|
@@ -522,17 +686,23 @@ export class TableContainer extends React.Component {
|
|
|
522
686
|
rendererAppearance: rendererAppearance,
|
|
523
687
|
allowTableResizing: allowTableResizing,
|
|
524
688
|
allowFixedColumnWidthOption: allowFixedColumnWidthOption
|
|
525
|
-
}, [children && children[0]]), /*#__PURE__*/React.createElement(
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
689
|
+
}, [children && children[0]]), /*#__PURE__*/React.createElement("div", {
|
|
690
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
691
|
+
className: TableSharedCssClassName.TABLE_NODE_WRAPPER,
|
|
692
|
+
ref: this.wrapperRef,
|
|
693
|
+
"data-number-column": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.isNumberColumnEnabled,
|
|
694
|
+
"data-layout": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout,
|
|
695
|
+
"data-autosize": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.__autoSize,
|
|
696
|
+
"data-table-local-id": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.localId,
|
|
697
|
+
"data-table-width": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.width,
|
|
698
|
+
"data-vc": "table-node-wrapper",
|
|
699
|
+
onScroll: this.props.stickyHeaders && this.onWrapperScrolled
|
|
530
700
|
}, /*#__PURE__*/React.createElement(Table, {
|
|
531
701
|
innerRef: this.tableRef,
|
|
532
702
|
columnWidths: columnWidths,
|
|
533
703
|
layout: layout,
|
|
704
|
+
renderWidth: 0,
|
|
534
705
|
isNumberColumnEnabled: isNumberColumnEnabled,
|
|
535
|
-
renderWidth: renderWidth,
|
|
536
706
|
tableNode: tableNode,
|
|
537
707
|
rendererAppearance: rendererAppearance,
|
|
538
708
|
isInsideOfBlockNode: isInsideOfBlockNode,
|
|
@@ -544,22 +714,16 @@ export class TableContainer extends React.Component {
|
|
|
544
714
|
allowFixedColumnWidthOption: allowFixedColumnWidthOption
|
|
545
715
|
}, this.grabFirstRowRef(children))), isStickyScrollbarEnabled(this.props.rendererAppearance) && /*#__PURE__*/React.createElement("div", {
|
|
546
716
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
547
|
-
className: TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_CONTAINER
|
|
717
|
+
className: `${TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_CONTAINER}${fg('confluence_frontend_table_scrollbar_ttvc_fix') ? '-view-page' : ''}`,
|
|
548
718
|
ref: this.stickyScrollbarRef,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
// https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/editor/editor-plugin-table/src/nodeviews/TableComponent.tsx#957
|
|
555
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
556
|
-
display: fixTableSSRResizing ? 'none' : 'block',
|
|
557
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
558
|
-
width: '100%'
|
|
559
|
-
}
|
|
719
|
+
"data-vc": "table-sticky-scrollbar-container",
|
|
720
|
+
style: fg('confluence_frontend_table_scrollbar_ttvc_fix') ? {
|
|
721
|
+
...stickyContainerBaseStyles,
|
|
722
|
+
...stickyContainerAdditionalStyles
|
|
723
|
+
} : stickyContainerBaseStyles
|
|
560
724
|
}, /*#__PURE__*/React.createElement("div", {
|
|
561
725
|
style: {
|
|
562
|
-
width: (_this$tableRef$curren = this.tableRef.current) === null || _this$tableRef$curren === void 0 ? void 0 : _this$tableRef$curren.clientWidth,
|
|
726
|
+
width: fg('confluence_frontend_table_scrollbar_ttvc_fix') ? '100%' : (_this$tableRef$curren = this.tableRef.current) === null || _this$tableRef$curren === void 0 ? void 0 : _this$tableRef$curren.clientWidth,
|
|
563
727
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
564
728
|
height: '100%'
|
|
565
729
|
}
|
|
@@ -572,12 +736,110 @@ export class TableContainer extends React.Component {
|
|
|
572
736
|
})));
|
|
573
737
|
}
|
|
574
738
|
}
|
|
739
|
+
const getCellEdgePropsByCellOffset = (tableNode, isNumberColumnEnabled) => {
|
|
740
|
+
const cellEdgePropsByCellOffset = new Map();
|
|
741
|
+
const cellRightByCellOffset = new Map();
|
|
742
|
+
const occupiedGrid = [];
|
|
743
|
+
let tableWidth = 0;
|
|
744
|
+
let cellOffset = 0;
|
|
745
|
+
tableNode.forEach((rowNode, _rowOffset, rowIndex) => {
|
|
746
|
+
var _occupiedGrid$rowInde;
|
|
747
|
+
occupiedGrid[rowIndex] = (_occupiedGrid$rowInde = occupiedGrid[rowIndex]) !== null && _occupiedGrid$rowInde !== void 0 ? _occupiedGrid$rowInde : [];
|
|
748
|
+
let columnIndex = 0;
|
|
749
|
+
cellOffset += 1;
|
|
750
|
+
rowNode.forEach(cellNode => {
|
|
751
|
+
while (occupiedGrid[rowIndex][columnIndex]) {
|
|
752
|
+
columnIndex += 1;
|
|
753
|
+
}
|
|
754
|
+
const colspan = cellNode.attrs.colspan || 1;
|
|
755
|
+
const rowspan = cellNode.attrs.rowspan || 1;
|
|
756
|
+
const cellLeft = columnIndex;
|
|
757
|
+
const cellRight = cellLeft + colspan;
|
|
758
|
+
const cellTop = rowIndex;
|
|
759
|
+
const cellBottom = cellTop + rowspan;
|
|
760
|
+
for (let row = cellTop; row < cellBottom; row += 1) {
|
|
761
|
+
var _occupiedGrid$row;
|
|
762
|
+
occupiedGrid[row] = (_occupiedGrid$row = occupiedGrid[row]) !== null && _occupiedGrid$row !== void 0 ? _occupiedGrid$row : [];
|
|
763
|
+
for (let column = cellLeft; column < cellRight; column += 1) {
|
|
764
|
+
occupiedGrid[row][column] = true;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
tableWidth = Math.max(tableWidth, cellRight);
|
|
768
|
+
cellRightByCellOffset.set(cellOffset, cellRight);
|
|
769
|
+
cellEdgePropsByCellOffset.set(cellOffset, {
|
|
770
|
+
reachesBottom: cellBottom >= tableNode.childCount,
|
|
771
|
+
// With number column enabled, PM column 0 is not visually leftmost and must not get `data-reaches-left`.
|
|
772
|
+
reachesLeft: cellLeft === 0 && !isNumberColumnEnabled,
|
|
773
|
+
reachesRight: false,
|
|
774
|
+
reachesTop: cellTop === 0
|
|
775
|
+
});
|
|
776
|
+
columnIndex = cellRight;
|
|
777
|
+
cellOffset += cellNode.nodeSize;
|
|
778
|
+
});
|
|
779
|
+
cellOffset += 1;
|
|
780
|
+
});
|
|
781
|
+
cellRightByCellOffset.forEach((cellRight, currentCellOffset) => {
|
|
782
|
+
const edgeProps = cellEdgePropsByCellOffset.get(currentCellOffset);
|
|
783
|
+
if (edgeProps) {
|
|
784
|
+
edgeProps.reachesRight = cellRight >= tableWidth;
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
return cellEdgePropsByCellOffset;
|
|
788
|
+
};
|
|
789
|
+
const isRenderedTableCell = element => {
|
|
790
|
+
const {
|
|
791
|
+
nodeType
|
|
792
|
+
} = element.props;
|
|
793
|
+
return nodeType === 'tableCell' || nodeType === 'tableHeader' || element.type === TableCell || element.type === TableHeader;
|
|
794
|
+
};
|
|
795
|
+
const addTableCellEdgePropsThroughWrappers = (rows, tableNode, isNumberColumnEnabled) => {
|
|
796
|
+
try {
|
|
797
|
+
if (!tableNode) {
|
|
798
|
+
return rows;
|
|
799
|
+
}
|
|
800
|
+
const cellEdgePropsByCellOffset = getCellEdgePropsByCellOffset(tableNode, isNumberColumnEnabled);
|
|
801
|
+
let cellOffset = 0;
|
|
802
|
+
return React.Children.map(rows, (row, rowIndex) => {
|
|
803
|
+
const rowNode = tableNode.child(rowIndex);
|
|
804
|
+
cellOffset += 1;
|
|
805
|
+
let cellIndex = 0;
|
|
806
|
+
const addEdgePropsToRenderedCells = element => {
|
|
807
|
+
if (isRenderedTableCell(element)) {
|
|
808
|
+
const cellNode = rowNode.child(cellIndex);
|
|
809
|
+
const edgeProps = cellEdgePropsByCellOffset.get(cellOffset);
|
|
810
|
+
cellIndex += 1;
|
|
811
|
+
cellOffset += cellNode.nodeSize;
|
|
812
|
+
return edgeProps ? /*#__PURE__*/React.cloneElement(element, edgeProps) : element;
|
|
813
|
+
}
|
|
814
|
+
const {
|
|
815
|
+
children
|
|
816
|
+
} = element.props;
|
|
817
|
+
if (children === undefined) {
|
|
818
|
+
return element;
|
|
819
|
+
}
|
|
820
|
+
const childrenWithEdgeProps = React.Children.map(children, child => /*#__PURE__*/React.isValidElement(child) ? addEdgePropsToRenderedCells(child) : child);
|
|
821
|
+
return /*#__PURE__*/React.cloneElement(element, undefined, childrenWithEdgeProps);
|
|
822
|
+
};
|
|
823
|
+
const rowWithEdgeProps = addEdgePropsToRenderedCells(row);
|
|
824
|
+
if (cellIndex !== rowNode.childCount) {
|
|
825
|
+
throw new Error('Rendered table row does not match its document node');
|
|
826
|
+
}
|
|
827
|
+
cellOffset += 1;
|
|
828
|
+
return rowWithEdgeProps;
|
|
829
|
+
});
|
|
830
|
+
} catch {
|
|
831
|
+
// Renderer can receive malformed historical ADF. If the table shape cannot
|
|
832
|
+
// be described safely, keep rendering without rounded edge metadata.
|
|
833
|
+
return rows;
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
|
|
575
837
|
/**
|
|
576
|
-
*
|
|
838
|
+
* Processes table children before passing them to the styled table container.
|
|
577
839
|
*/
|
|
578
840
|
// Ignored via go/ees005
|
|
579
841
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
580
|
-
export class
|
|
842
|
+
export class TableProcessorWithContainerStyles extends React.Component {
|
|
581
843
|
constructor(...args) {
|
|
582
844
|
super(...args);
|
|
583
845
|
_defineProperty(this, "state", {
|
|
@@ -613,33 +875,78 @@ export class TableProcessor extends React.Component {
|
|
|
613
875
|
isNumberColumnEnabled
|
|
614
876
|
} = this.props;
|
|
615
877
|
const headerRowEnabled = isHeaderRowEnabled(rows);
|
|
878
|
+
const lastRowIndex = React.Children.count(rows) - 1;
|
|
616
879
|
return React.Children.map(rows, (row, index) => {
|
|
617
880
|
return /*#__PURE__*/React.cloneElement(React.Children.only(row), {
|
|
618
881
|
isNumberColumnEnabled,
|
|
619
|
-
index: headerRowEnabled ? index === 0 ? '' : index : index + 1
|
|
882
|
+
index: headerRowEnabled ? index === 0 ? '' : index : index + 1,
|
|
883
|
+
isFirstRow: index === 0,
|
|
884
|
+
isLastRow: index === lastRowIndex
|
|
620
885
|
});
|
|
621
886
|
});
|
|
622
887
|
});
|
|
623
888
|
}
|
|
624
889
|
/**
|
|
890
|
+
* Renders processed table children inside the table container.
|
|
625
891
|
*
|
|
626
892
|
* @example
|
|
627
893
|
*/
|
|
628
894
|
render() {
|
|
629
895
|
const {
|
|
630
|
-
|
|
896
|
+
allowColumnSorting,
|
|
897
|
+
allowFixedColumnWidthOption,
|
|
898
|
+
allowTableAlignment,
|
|
899
|
+
allowTableResizing,
|
|
900
|
+
children,
|
|
901
|
+
columnWidths,
|
|
902
|
+
disableTableOverflowShadow,
|
|
903
|
+
handleRef,
|
|
904
|
+
isinsideMultiBodiedExtension,
|
|
905
|
+
isInsideOfBlockNode,
|
|
906
|
+
isInsideOfNestedRenderer,
|
|
907
|
+
isInsideOfTable,
|
|
908
|
+
isNumberColumnEnabled,
|
|
909
|
+
isPresentational,
|
|
910
|
+
layout,
|
|
911
|
+
rendererAppearance,
|
|
912
|
+
renderWidth,
|
|
913
|
+
shadowClassNames,
|
|
914
|
+
smartCardStorage,
|
|
915
|
+
stickyHeaders,
|
|
916
|
+
tabIndex,
|
|
917
|
+
tableNode
|
|
631
918
|
} = this.props;
|
|
632
919
|
if (!children) {
|
|
633
920
|
return null;
|
|
634
921
|
}
|
|
635
922
|
const childrenArray = React.Children.toArray(children);
|
|
923
|
+
const childrenWithTableEdgeProps = expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? addTableCellEdgePropsThroughWrappers(childrenArray, tableNode, isNumberColumnEnabled) : childrenArray;
|
|
636
924
|
const orderedChildren = compose(this.addNumberColumnIndexes, this.addSortableColumn
|
|
637
925
|
// @ts-expect-error TS2345: Argument of type '(ReactChild | ReactFragment | ReactPortal)[]' is not assignable to parameter of type 'ReactElement<any, string | JSXElementConstructor<any>>[]'
|
|
638
|
-
)(
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
926
|
+
)(childrenWithTableEdgeProps);
|
|
927
|
+
return /*#__PURE__*/React.createElement(TableContainer, {
|
|
928
|
+
allowColumnSorting: allowColumnSorting,
|
|
929
|
+
allowFixedColumnWidthOption: allowFixedColumnWidthOption,
|
|
930
|
+
allowTableAlignment: allowTableAlignment,
|
|
931
|
+
allowTableResizing: allowTableResizing,
|
|
932
|
+
columnWidths: columnWidths,
|
|
933
|
+
disableTableOverflowShadow: disableTableOverflowShadow,
|
|
934
|
+
handleRef: handleRef,
|
|
935
|
+
isinsideMultiBodiedExtension: isinsideMultiBodiedExtension,
|
|
936
|
+
isInsideOfBlockNode: isInsideOfBlockNode,
|
|
937
|
+
isInsideOfNestedRenderer: isInsideOfNestedRenderer,
|
|
938
|
+
isInsideOfTable: isInsideOfTable,
|
|
939
|
+
isNumberColumnEnabled: isNumberColumnEnabled,
|
|
940
|
+
isPresentational: isPresentational,
|
|
941
|
+
layout: layout,
|
|
942
|
+
rendererAppearance: rendererAppearance,
|
|
943
|
+
renderWidth: renderWidth,
|
|
944
|
+
shadowClassNames: shadowClassNames,
|
|
945
|
+
smartCardStorage: smartCardStorage,
|
|
946
|
+
stickyHeaders: stickyHeaders,
|
|
947
|
+
tabIndex: tabIndex,
|
|
948
|
+
tableNode: tableNode
|
|
949
|
+
}, orderedChildren);
|
|
643
950
|
}
|
|
644
951
|
}
|
|
645
952
|
|
|
@@ -653,69 +960,29 @@ const TableWithShadowsAndContainerStyles = overflowShadow(TableProcessorWithCont
|
|
|
653
960
|
overflowSelector: `:scope > .${TableSharedCssClassName.TABLE_NODE_WRAPPER}`,
|
|
654
961
|
useShadowObserver: true
|
|
655
962
|
});
|
|
656
|
-
|
|
657
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
658
|
-
const TableWithShadows = overflowShadow(TableProcessor, {
|
|
659
|
-
/**
|
|
660
|
-
* The :scope is in reference to table container and we are selecting only
|
|
661
|
-
* direct children that match the table node wrapper selector, not their
|
|
662
|
-
* descendants.
|
|
663
|
-
*/
|
|
664
|
-
overflowSelector: `:scope > .${TableSharedCssClassName.TABLE_NODE_WRAPPER}`,
|
|
665
|
-
useShadowObserver: true
|
|
666
|
-
});
|
|
667
963
|
const TableWithWidth = props => {
|
|
964
|
+
var _props$columnWidths;
|
|
668
965
|
const {
|
|
669
966
|
isTopLevelRenderer
|
|
670
967
|
} = useRendererContext();
|
|
671
968
|
const isInsideOfNestedRenderer = isTopLevelRenderer === false && expValEquals('platform_editor_table_nested_content_mode_fix', 'isEnabled', true);
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
if (colWidthsSum || props.allowTableResizing) {
|
|
678
|
-
return /*#__PURE__*/React.createElement(TableWithShadowsAndContainerStyles
|
|
679
|
-
// Ignored via go/ees005
|
|
680
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
681
|
-
, _extends({}, props, {
|
|
682
|
-
isInsideOfNestedRenderer: isInsideOfNestedRenderer
|
|
683
|
-
}));
|
|
684
|
-
}
|
|
685
|
-
return /*#__PURE__*/React.createElement(TableProcessorWithContainerStyles
|
|
969
|
+
const colWidthsSum =
|
|
970
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed)
|
|
971
|
+
((_props$columnWidths = props.columnWidths) === null || _props$columnWidths === void 0 ? void 0 : _props$columnWidths.reduce((total, val) => total + val, 0)) || 0;
|
|
972
|
+
if (colWidthsSum || props.allowTableResizing) {
|
|
973
|
+
return /*#__PURE__*/React.createElement(TableWithShadowsAndContainerStyles
|
|
686
974
|
// Ignored via go/ees005
|
|
687
975
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
688
976
|
, _extends({}, props, {
|
|
689
977
|
isInsideOfNestedRenderer: isInsideOfNestedRenderer
|
|
690
978
|
}));
|
|
691
|
-
} else {
|
|
692
|
-
return /*#__PURE__*/React.createElement(WidthConsumer, null, ({
|
|
693
|
-
width
|
|
694
|
-
}) => {
|
|
695
|
-
var _props$columnWidths2;
|
|
696
|
-
const renderWidth = props.rendererAppearance === 'full-page' ? width - FullPagePadding * 2 : width;
|
|
697
|
-
const colWidthsSum =
|
|
698
|
-
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed)
|
|
699
|
-
((_props$columnWidths2 = props.columnWidths) === null || _props$columnWidths2 === void 0 ? void 0 : _props$columnWidths2.reduce((total, val) => total + val, 0)) || 0;
|
|
700
|
-
if (colWidthsSum || props.allowTableResizing) {
|
|
701
|
-
return /*#__PURE__*/React.createElement(TableWithShadows, _extends({
|
|
702
|
-
renderWidth: renderWidth
|
|
703
|
-
// Ignored via go/ees005
|
|
704
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
705
|
-
}, props, {
|
|
706
|
-
isInsideOfNestedRenderer: isInsideOfNestedRenderer
|
|
707
|
-
}));
|
|
708
|
-
}
|
|
709
|
-
// there should not be a case when colWidthsSum is 0 and table is in overflow state - so no need to render shadows in this case
|
|
710
|
-
return /*#__PURE__*/React.createElement(TableProcessor, _extends({
|
|
711
|
-
renderWidth: renderWidth
|
|
712
|
-
// Ignored via go/ees005
|
|
713
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
714
|
-
}, props, {
|
|
715
|
-
isInsideOfNestedRenderer: isInsideOfNestedRenderer
|
|
716
|
-
}));
|
|
717
|
-
});
|
|
718
979
|
}
|
|
980
|
+
return /*#__PURE__*/React.createElement(TableProcessorWithContainerStyles
|
|
981
|
+
// Ignored via go/ees005
|
|
982
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
983
|
+
, _extends({}, props, {
|
|
984
|
+
isInsideOfNestedRenderer: isInsideOfNestedRenderer
|
|
985
|
+
}));
|
|
719
986
|
};
|
|
720
987
|
const _default_1 = withSmartCardStorage(TableWithWidth);
|
|
721
988
|
export default _default_1;
|