@atlaskit/renderer 137.1.8 → 137.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cjs/react/index.js +1 -1
  3. package/dist/cjs/react/nodes/table/colgroup.js +1 -2
  4. package/dist/cjs/react/nodes/table/sticky.js +2 -4
  5. package/dist/cjs/react/nodes/table/table.js +1 -12
  6. package/dist/cjs/react/nodes/table.js +471 -203
  7. package/dist/cjs/ui/Expand.js +33 -7
  8. package/dist/cjs/ui/Renderer/breakout-ssr.js +1 -2
  9. package/dist/cjs/ui/Renderer/index.js +3 -3
  10. package/dist/cjs/ui/utils/expand-body.js +218 -0
  11. package/dist/cjs/ui/utils/expand-search-text.js +39 -1
  12. package/dist/es2019/react/index.js +1 -1
  13. package/dist/es2019/react/nodes/table/colgroup.js +1 -2
  14. package/dist/es2019/react/nodes/table/sticky.js +2 -3
  15. package/dist/es2019/react/nodes/table/table.js +1 -12
  16. package/dist/es2019/react/nodes/table.js +457 -190
  17. package/dist/es2019/ui/Expand.js +33 -7
  18. package/dist/es2019/ui/Renderer/breakout-ssr.js +1 -2
  19. package/dist/es2019/ui/Renderer/index.js +3 -3
  20. package/dist/es2019/ui/utils/expand-body.js +198 -0
  21. package/dist/es2019/ui/utils/expand-search-text.js +38 -0
  22. package/dist/esm/react/index.js +1 -1
  23. package/dist/esm/react/nodes/table/colgroup.js +1 -2
  24. package/dist/esm/react/nodes/table/sticky.js +2 -4
  25. package/dist/esm/react/nodes/table/table.js +1 -12
  26. package/dist/esm/react/nodes/table.js +471 -202
  27. package/dist/esm/ui/Expand.js +33 -7
  28. package/dist/esm/ui/Renderer/breakout-ssr.js +1 -2
  29. package/dist/esm/ui/Renderer/index.js +3 -3
  30. package/dist/esm/ui/utils/expand-body.js +210 -0
  31. package/dist/esm/ui/utils/expand-search-text.js +38 -0
  32. package/dist/types/react/nodes/table/sticky.d.ts +1 -2
  33. package/dist/types/react/nodes/table.d.ts +78 -8
  34. package/dist/types/ui/{expand-body.d.ts → utils/expand-body.d.ts} +26 -5
  35. package/dist/types/ui/utils/expand-search-text.d.ts +14 -0
  36. package/package.json +6 -9
  37. package/dist/cjs/react/nodes/tableNew.js +0 -1050
  38. package/dist/cjs/ui/expand-body.js +0 -122
  39. package/dist/es2019/react/nodes/tableNew.js +0 -986
  40. package/dist/es2019/ui/expand-body.js +0 -107
  41. package/dist/esm/react/nodes/tableNew.js +0 -1044
  42. package/dist/esm/ui/expand-body.js +0 -114
  43. package/dist/types/react/nodes/tableNew.d.ts +0 -189
@@ -1,986 +0,0 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- /* eslint-disable @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/enforce-style-prop, @repo/internal/react/no-class-components */
3
- import React from 'react';
4
- import { TableSharedCssClassName, tableMarginTop } from '@atlaskit/editor-common/styles';
5
- import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
6
- import { FullPagePadding } from '../../ui/Renderer/style';
7
- import { fg } from '@atlaskit/platform-feature-flags/fg';
8
- import { RendererCssClassName } from '../../consts';
9
- import { createCompareNodes, convertProsemirrorTableNodeToArrayOfRows, hasMergedCell, compose } from '@atlaskit/editor-common/utils';
10
- import { SortOrder } from '@atlaskit/editor-common/types';
11
- import { akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth, akEditorMaxWidthLayoutWidth } from '@atlaskit/editor-shared-styles';
12
- import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
13
- import { TableCell, TableHeader } from './tableCell';
14
- import { StickyTable, tableStickyPadding, OverflowParent } from './table/sticky';
15
- import { Table } from './table/table';
16
- import { isCommentAppearance, isFullWidthOrFullPageAppearance, isFullWidthAppearance, isMaxWidthAppearance, isFullPageAppearance } from '../utils/appearance';
17
- import { TableStickyScrollbar } from './TableStickyScrollbar';
18
- import { useRendererContext } from '../../renderer-context';
19
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
- import { isTableInContentMode } from '@atlaskit/editor-common/table';
21
- import { isContentModeSupported } from './table/content-mode';
22
- const stickyContainerBaseStyles = {
23
- // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
24
- height: "var(--ds-space-250, 20px)",
25
- // MAX_BROWSER_SCROLLBAR_HEIGHT
26
- // Follow editor to hide by default so it does not show empty gap in SSR
27
- // https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/editor/editor-plugin-table/src/nodeviews/TableComponent.tsx#957
28
- // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
29
- display: 'block',
30
- width: '100%'
31
- };
32
- const stickyContainerAdditionalStyles = {
33
- visibility: 'hidden',
34
- overflowX: 'auto',
35
- position: 'sticky',
36
- bottom: "var(--ds-space-0, 0px)",
37
- zIndex: 1
38
- };
39
- export const isTableResizingEnabled = appearance => isFullWidthOrFullPageAppearance(appearance) || isCommentAppearance(appearance);
40
- export const isStickyScrollbarEnabled = appearance => isFullWidthOrFullPageAppearance(appearance) && editorExperiment('platform_renderer_table_sticky_scrollbar', true, {
41
- exposure: true
42
- });
43
- export const orderChildren = (children, tableNode, smartCardStorage, tableOrderStatus) => {
44
- if (!tableOrderStatus || tableOrderStatus.order === SortOrder.NO_ORDER) {
45
- return children;
46
- }
47
- const {
48
- order,
49
- columnIndex
50
- } = tableOrderStatus;
51
- const compareNodesInOrder = createCompareNodes({
52
- getInlineCardTextFromStore(attrs) {
53
- const {
54
- url
55
- } = attrs;
56
- if (!url) {
57
- return null;
58
- }
59
- return smartCardStorage.get(url) || null;
60
- }
61
- }, order);
62
- const tableArray = convertProsemirrorTableNodeToArrayOfRows(tableNode);
63
- const tableArrayWithChildren = tableArray.map((rowNodes, index) => ({
64
- rowNodes,
65
- rowReact: children[index]
66
- }));
67
- const headerRow = tableArrayWithChildren.shift();
68
- const sortedTable = tableArrayWithChildren.sort((rowA, rowB) => compareNodesInOrder(rowA.rowNodes[columnIndex], rowB.rowNodes[columnIndex]));
69
- if (headerRow) {
70
- sortedTable.unshift(headerRow);
71
- }
72
- return sortedTable.map(elem => elem.rowReact);
73
- };
74
- export const hasRowspan = row => {
75
- let hasRowspan = false;
76
- row.forEach(cell => hasRowspan = hasRowspan || cell.attrs.rowspan > 1);
77
- return hasRowspan;
78
- };
79
- export const getRefTop = refElement => {
80
- return Math.round(refElement.getBoundingClientRect().top);
81
- };
82
- export const shouldHeaderStick = (scrollTop, tableTop, tableBottom, rowHeight) => tableTop <= scrollTop && !(tableBottom - rowHeight <= scrollTop);
83
- export const shouldHeaderPinBottom = (scrollTop, tableBottom, rowHeight) => tableBottom - rowHeight <= scrollTop && !(tableBottom < scrollTop);
84
- export const addSortableColumn = (rows, tableOrderStatus, onSorting
85
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
- ) => {
87
- return React.Children.map(rows, (row, index) => {
88
- if (index === 0) {
89
- return /*#__PURE__*/React.cloneElement(React.Children.only(row), {
90
- tableOrderStatus,
91
- onSorting
92
- });
93
- }
94
- return row;
95
- });
96
- };
97
- export const isHeaderRowEnabled = (rows
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- ) => {
100
- if (!rows.length) {
101
- return false;
102
- }
103
- // Ignored via go/ees005
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- const {
106
- children
107
- } = rows[0].props;
108
- if (!children.length) {
109
- return false;
110
- }
111
- if (children.length === 1) {
112
- return children[0].type === TableHeader;
113
- }
114
- return children.every(node => node.type === TableHeader);
115
- };
116
- export const tableCanBeSticky = (node, children
117
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
- ) => {
119
- return isHeaderRowEnabled(children) && node && node.firstChild && !hasRowspan(node.firstChild);
120
- };
121
- /**
122
- * Fake left/right borders rendered as direct children of TABLE_CONTAINER
123
- * (the non-scrolling parent of the horizontally scrolling TABLE_NODE_WRAPPER).
124
- *
125
- * The visible styling for these divs lives in `tableFakeBorderStyles`
126
- * (`renderer/src/ui/Renderer/RendererStyleContainer.tsx`), which is applied
127
- * when `isInsideSyncBlock` is true.
128
- *
129
- * Shared between `renderer/src/react/nodes/table.tsx` and
130
- * `renderer/src/react/nodes/tableNew.tsx` so the two stay in sync.
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.
148
- */
149
- export const RefSyncBlockFakeBorders = ({
150
- isNumberColumnEnabled
151
- }) => {
152
- const {
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
- });
162
- };
163
-
164
- /**
165
- * TableContainer renders tables using only CSS-based rules
166
- */
167
- // Ignored via go/ees005
168
- // eslint-disable-next-line @repo/internal/react/no-class-components
169
- /**
170
- *
171
- */
172
- export class TableContainer extends React.Component {
173
- constructor(...args) {
174
- super(...args);
175
- _defineProperty(this, "state", {
176
- stickyMode: 'none',
177
- wrapperWidth: 0,
178
- headerRowHeight: 0
179
- });
180
- _defineProperty(this, "tableRef", /*#__PURE__*/React.createRef());
181
- _defineProperty(this, "stickyHeaderRef", /*#__PURE__*/React.createRef());
182
- _defineProperty(this, "stickyScrollbarRef", /*#__PURE__*/React.createRef());
183
- // used for sync scroll + copying wrapper width to sticky header
184
- _defineProperty(this, "stickyWrapperRef", /*#__PURE__*/React.createRef());
185
- _defineProperty(this, "wrapperRef", /*#__PURE__*/React.createRef());
186
- _defineProperty(this, "overflowParent", null);
187
- _defineProperty(this, "updatedLayout", 'custom');
188
- _defineProperty(this, "containerRef", null);
189
- _defineProperty(this, "_isInsideNestedRenderer", null);
190
- _defineProperty(this, "_isInsideTableCell", null);
191
- // Stores the last computed style values from render() for use by applyNestedRendererTableFix().
192
- // This avoids reading from the DOM which can be stale when React removes properties between renders.
193
- _defineProperty(this, "lastComputedStyle", {});
194
- _defineProperty(this, "resizeObserver", null);
195
- _defineProperty(this, "applyResizerChange", entries => {
196
- let wrapperWidth = this.state.wrapperWidth;
197
- let headerRowHeight = this.state.headerRowHeight;
198
- for (const entry of entries) {
199
- if (entry.target === this.wrapperRef.current) {
200
- wrapperWidth = entry.contentRect.width;
201
- } else if (entry.target === this.stickyHeaderRef.current) {
202
- headerRowHeight = Math.round(entry.contentRect.height);
203
- }
204
- }
205
- if (headerRowHeight !== this.state.headerRowHeight || wrapperWidth !== this.state.wrapperWidth) {
206
- this.setState({
207
- wrapperWidth,
208
- headerRowHeight
209
- });
210
- }
211
- });
212
- /**
213
- * Callback ref that captures the container DOM element and also forwards
214
- * to the handleRef prop from the overflow shadow HOC.
215
- */
216
- _defineProperty(this, "setContainerRef", el => {
217
- if (this.containerRef !== el) {
218
- this._isInsideNestedRenderer = null;
219
- this._isInsideTableCell = null;
220
- }
221
- this.containerRef = el;
222
- const {
223
- handleRef
224
- } = this.props;
225
- if (typeof handleRef === 'function') {
226
- handleRef(el);
227
- } else if (handleRef && typeof handleRef === 'object') {
228
- // Ignored via go/ees005
229
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
230
- handleRef.current = el;
231
- }
232
- });
233
- _defineProperty(this, "componentWillUnmount", () => {
234
- if (this.overflowParent) {
235
- // Ignored via go/ees005
236
- // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
237
- this.overflowParent.removeEventListener('scroll', this.onScroll);
238
- }
239
- if (this.nextFrame) {
240
- cancelAnimationFrame(this.nextFrame);
241
- }
242
- if (this.resizeObserver) {
243
- this.resizeObserver.disconnect();
244
- }
245
- if (this.stickyScrollbar) {
246
- this.stickyScrollbar.dispose();
247
- }
248
- });
249
- _defineProperty(this, "getScrollTop", () => {
250
- const {
251
- stickyHeaders
252
- } = this.props;
253
- const offsetTop = stickyHeaders && stickyHeaders.offsetTop || 0;
254
- return (this.overflowParent ? this.overflowParent.top : 0) + offsetTop;
255
- });
256
- _defineProperty(this, "updateSticky", () => {
257
- const tableElem = this.tableRef.current;
258
- const refElem = this.stickyHeaderRef.current;
259
- if (!tableElem || !refElem) {
260
- return;
261
- }
262
- const scrollTop = this.getScrollTop() + tableStickyPadding;
263
- const tableTop = getRefTop(tableElem);
264
- const tableBottom = tableTop + tableElem.clientHeight;
265
- const shouldSticky = shouldHeaderStick(scrollTop, tableTop, tableBottom, refElem.clientHeight);
266
- const shouldPin = shouldHeaderPinBottom(scrollTop, tableBottom, refElem.clientHeight);
267
- let stickyMode = 'none';
268
- if (shouldPin) {
269
- stickyMode = 'pin-bottom';
270
- } else if (shouldSticky) {
271
- stickyMode = 'stick';
272
- }
273
- if (this.state.stickyMode !== stickyMode) {
274
- this.setState({
275
- stickyMode
276
- });
277
- }
278
- this.nextFrame = undefined;
279
- });
280
- _defineProperty(this, "onScroll", () => {
281
- if (!this.nextFrame) {
282
- this.nextFrame = requestAnimationFrame(this.updateSticky);
283
- }
284
- });
285
- _defineProperty(this, "onWrapperScrolled", () => {
286
- if (!this.wrapperRef.current || !this.stickyWrapperRef.current) {
287
- return;
288
- }
289
- this.stickyWrapperRef.current.scrollLeft = this.wrapperRef.current.scrollLeft;
290
- if (this.stickyScrollbarRef.current) {
291
- this.stickyScrollbarRef.current.scrollLeft = this.wrapperRef.current.scrollLeft;
292
- }
293
- });
294
- _defineProperty(this, "grabFirstRowRef", children => {
295
- // Ignored via go/ees005
296
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
297
- return React.Children.map(children || false, (child, idx) => {
298
- if (idx === 0 && /*#__PURE__*/React.isValidElement(child)) {
299
- return /*#__PURE__*/React.cloneElement(child, {
300
- innerRef: this.stickyHeaderRef
301
- });
302
- }
303
- return child;
304
- });
305
- });
306
- }
307
- /**
308
- * Checks if this table is inside a nested renderer (e.g. Include Page macro)
309
- * by looking for multiple .ak-renderer-document ancestors in the DOM.
310
- * The result is cached since a table's position in the DOM tree is stable after mount.
311
- */
312
- isInsideNestedRenderer() {
313
- if (this._isInsideNestedRenderer !== null) {
314
- return this._isInsideNestedRenderer;
315
- }
316
- if (!this.containerRef) {
317
- return false;
318
- }
319
- let docAncestorCount = 0;
320
- let el = this.containerRef.parentElement;
321
- while (el) {
322
- if (el.classList.contains(RendererCssClassName.DOCUMENT)) {
323
- docAncestorCount++;
324
- if (docAncestorCount >= 2) {
325
- this._isInsideNestedRenderer = true;
326
- return true;
327
- }
328
- }
329
- el = el.parentElement;
330
- }
331
- this._isInsideNestedRenderer = false;
332
- return false;
333
- }
334
-
335
- /**
336
- * Checks if this table is inside a table cell in the DOM. The result is cached
337
- * since a table's position in the DOM tree is stable after mount.
338
- */
339
- isInsideTableCell() {
340
- if (this._isInsideTableCell !== null) {
341
- return this._isInsideTableCell;
342
- }
343
- if (!this.containerRef) {
344
- return false;
345
- }
346
- this._isInsideTableCell = Boolean(this.containerRef.closest('td, th'));
347
- return this._isInsideTableCell;
348
- }
349
- isInsideTableContext() {
350
- return Boolean(this.props.isInsideOfTable || this.isInsideTableCell());
351
- }
352
-
353
- /**
354
- * For tables inside nested renderers (e.g. Include Page macro), the parent
355
- * renderer's CSS override forces width:100%!important and left:0!important
356
- * which overrides the inline styles set by this component. Using
357
- * style.setProperty with 'important' priority on inline styles beats
358
- * stylesheet !important rules per the CSS cascade.
359
- *
360
- * Tables that are nested inside another table need to remain constrained by
361
- * their table-cell context. Do not promote their width to inline !important,
362
- * otherwise nested tables rendered through macros such as Excerpt Include can
363
- * overflow and overlap adjacent cells.
364
- *
365
- * Top-level tables in nested renderers still preserve their saved width, but
366
- * are capped to their containing block so wide tables do not escape constrained
367
- * macro bodies such as Excerpt Include panels.
368
- *
369
- * Uses lastComputedStyle (populated during render) rather than reading from
370
- * element.style, because React may remove properties from the DOM when their
371
- * values transition to undefined between renders.
372
- *
373
- * `platform_nested_table_style_override_2` fixes a follow-up regression where a
374
- * NON-resized table inside an Excerpt macro (not Excerpt Include) on a
375
- * wide/full-width page shrinks to only show its first columns in the renderer.
376
- * Inside a nested renderer (a macro body) a non-resized table's computed width
377
- * is a default layout cap (760px/1800px, or a `cqw` length for full-page
378
- * appearances) taken from the outer renderer's width context. That value does
379
- * not match the macro's own box, so promoting it to inline `!important` makes
380
- * the table collapse. Such tables have no author-chosen size to preserve, so
381
- * under this gate we re-assert the parent stylesheet's intent (fill the box:
382
- * `width: 100%; left: 0`) with inline `!important`.
383
- *
384
- * Explicitly resized tables (`tableNode.attrs.width` set) are excluded and keep
385
- * the original PGXT-10226 behavior: their author-chosen width/left is promoted
386
- * verbatim so the Include Page macro does not stretch or indent them. The
387
- * table-cell short-circuit (PGXT-10294) above also still applies.
388
- */
389
- applyNestedRendererTableFix() {
390
- var _this$props$tableNode;
391
- if (!this.containerRef || !fg('platform_nested_table_style_override')) {
392
- return;
393
- }
394
- if (!this.isInsideNestedRenderer() || this.isInsideTableContext()) {
395
- return;
396
- }
397
- const {
398
- width,
399
- left,
400
- marginLeft
401
- } = this.lastComputedStyle;
402
- const style = this.containerRef.style;
403
-
404
- // A table is "explicitly resized" when the author set a width on the node.
405
- // Non-resized tables instead take a default layout cap (e.g. 760px/1800px)
406
- // derived from the outer renderer's appearance.
407
- const isExplicitlyResized = Boolean((_this$props$tableNode = this.props.tableNode) === null || _this$props$tableNode === void 0 ? void 0 : _this$props$tableNode.attrs.width);
408
- if (!isExplicitlyResized && fg('platform_nested_table_style_override_2')) {
409
- // PGXT-10421: For a NON-resized table inside a nested renderer (e.g. an
410
- // Excerpt macro body), the computed width is a default layout cap
411
- // (760px/1800px, or a `cqw` length for full-page appearances) taken from
412
- // the *outer* renderer's width context. That value does not match the
413
- // macro's own box, so promoting it to inline `!important` makes the table
414
- // ignore the available space and collapse to its first columns.
415
- //
416
- // These tables have no author-chosen size to preserve, so re-assert the
417
- // parent stylesheet's intent — fill the available box (`width: 100%`) —
418
- // with inline `!important` priority so it survives React re-renders and
419
- // wins over the stylesheet rule that leaks into nested renderers.
420
- style.setProperty('width', '100%', 'important');
421
- style.setProperty('max-width', '100%', 'important');
422
- style.setProperty('left', '0', 'important');
423
- style.setProperty('margin-left', '0', 'important');
424
- return;
425
- }
426
-
427
- // PGXT-10226: An explicitly resized table inside a nested renderer (e.g.
428
- // Include Page macro) must keep its author-chosen width and position. The
429
- // parent stylesheet forces `width: 100% !important; left: 0 !important`,
430
- // which would stretch and indent it, so we promote the component's own
431
- // computed width/left with inline `!important` to win the cascade.
432
- style.setProperty('width', width || 'auto', 'important');
433
- style.setProperty('max-width', '100%', 'important');
434
- style.setProperty('left', left || 'auto', 'important');
435
- style.setProperty('margin-left', marginLeft || '0', 'important');
436
- }
437
- /**
438
- * Starts observing table dimensions and wires sticky header/scrollbar behavior after mount.
439
- *
440
- * @example
441
- */
442
- componentDidMount() {
443
- this.resizeObserver = new ResizeObserver(this.applyResizerChange);
444
- if (this.wrapperRef.current) {
445
- this.resizeObserver.observe(this.wrapperRef.current);
446
- }
447
- if (this.stickyHeaderRef.current) {
448
- this.resizeObserver.observe(this.stickyHeaderRef.current);
449
- }
450
- if (this.props.stickyHeaders) {
451
- var _this$props$stickyHea;
452
- this.overflowParent = OverflowParent.fromElement(this.tableRef.current, (_this$props$stickyHea = this.props.stickyHeaders) === null || _this$props$stickyHea === void 0 ? void 0 : _this$props$stickyHea.defaultScrollRootId_DO_NOT_USE);
453
- // Ignored via go/ees005
454
- // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
455
- this.overflowParent.addEventListener('scroll', this.onScroll);
456
- }
457
- if (this.wrapperRef.current && isStickyScrollbarEnabled(this.props.rendererAppearance)) {
458
- this.stickyScrollbar = new TableStickyScrollbar(this.wrapperRef.current);
459
- }
460
- this.applyNestedRendererTableFix();
461
- }
462
-
463
- /**
464
- * Updates sticky header wiring and scroll synchronization after prop or state changes.
465
- *
466
- * @param prevProps
467
- * @param prevState
468
- * @example
469
- */
470
- componentDidUpdate(prevProps, prevState) {
471
- // toggling sticky headers visiblity
472
- if (this.props.stickyHeaders && !this.overflowParent) {
473
- var _this$props$stickyHea2;
474
- this.overflowParent = OverflowParent.fromElement(this.tableRef.current, (_this$props$stickyHea2 = this.props.stickyHeaders) === null || _this$props$stickyHea2 === void 0 ? void 0 : _this$props$stickyHea2.defaultScrollRootId_DO_NOT_USE);
475
- } else if (!this.props.stickyHeaders && this.overflowParent) {
476
- // Ignored via go/ees005
477
- // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
478
- this.overflowParent.removeEventListener('scroll', this.onScroll);
479
- this.overflowParent = null;
480
- }
481
-
482
- // offsetTop might have changed, re-position sticky header
483
- if (this.props.stickyHeaders !== prevProps.stickyHeaders) {
484
- this.updateSticky();
485
- }
486
-
487
- // sync horizontal scroll in floating div when toggling modes
488
- if (prevState.stickyMode !== this.state.stickyMode) {
489
- this.onWrapperScrolled();
490
- }
491
-
492
- // React re-applies the style prop on every render, which overwrites the
493
- // !important priorities set at mount time. Re-apply after each update.
494
- this.applyNestedRendererTableFix();
495
- }
496
- /**
497
- * Calculates the top offset used when the sticky header is pinned to the table bottom.
498
- */
499
- get pinTop() {
500
- if (!this.tableRef.current || !this.stickyHeaderRef.current) {
501
- return;
502
- }
503
- return this.tableRef.current.offsetHeight - this.stickyHeaderRef.current.offsetHeight + tableMarginTop - tableStickyPadding;
504
- }
505
-
506
- /**
507
- * Determines whether sticky header positioning should include the default scroll root offset.
508
- */
509
- get shouldAddOverflowParentOffsetTop_DO_NOT_USE() {
510
- // IF the StickyHeaderConfig specifies that the default scroll root offsetTop should be added
511
- // AND the StickyHeaderConfig specifies a default scroll root id
512
- // AND the OverflowParent is the corresponding element
513
- // THEN we should add the OverflowParent offset top (RETURN TRUE)
514
- return this.props.stickyHeaders && !!this.props.stickyHeaders.shouldAddDefaultScrollRootOffsetTop_DO_NOT_USE && !!this.props.stickyHeaders.defaultScrollRootId_DO_NOT_USE && this.overflowParent && this.overflowParent.id === this.props.stickyHeaders.defaultScrollRootId_DO_NOT_USE;
515
- }
516
-
517
- /**
518
- * Resolves the top position for the sticky header based on the current sticky mode.
519
- */
520
- get stickyTop() {
521
- switch (this.state.stickyMode) {
522
- case 'pin-bottom':
523
- return this.pinTop;
524
- case 'stick':
525
- const offsetTop = this.props.stickyHeaders && this.props.stickyHeaders.offsetTop;
526
- if (typeof offsetTop === 'number' && this.shouldAddOverflowParentOffsetTop_DO_NOT_USE) {
527
- const overflowParentOffsetTop = this.overflowParent ? this.overflowParent.top : 0;
528
- return offsetTop + overflowParentOffsetTop;
529
- } else {
530
- return offsetTop;
531
- }
532
- default:
533
- return undefined;
534
- }
535
- }
536
-
537
- /**
538
- * Renders the table container, sticky header, table content, sticky scrollbar, and synced block borders.
539
- *
540
- * @example
541
- */
542
- render() {
543
- var _this$tableRef$curren;
544
- const {
545
- isNumberColumnEnabled,
546
- layout,
547
- columnWidths,
548
- stickyHeaders,
549
- tableNode,
550
- rendererAppearance,
551
- isInsideOfBlockNode,
552
- isInsideOfNestedRenderer,
553
- isInsideOfTable,
554
- isinsideMultiBodiedExtension,
555
- allowTableAlignment,
556
- allowTableResizing,
557
- isPresentational,
558
- allowFixedColumnWidthOption
559
- } = this.props;
560
- const {
561
- stickyMode
562
- } = this.state;
563
- const lineLengthFixedWidth = akEditorDefaultLayoutWidth;
564
- let updatedLayout;
565
- const fullPageRendererWidthCSS = editorExperiment('platform_editor_preview_panel_responsiveness', true, {
566
- exposure: true
567
- }) ? 'calc(100cqw - var(--ak-renderer--full-page-gutter) * 2)' : `100cqw - ${FullPagePadding}px * 2`;
568
- const renderWidthCSS = rendererAppearance === 'full-page' ? fullPageRendererWidthCSS : `100cqw`;
569
- const calcDefaultLayoutWidthByAppearance = (rendererAppearance, tableNode) => {
570
- 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))) {
571
- return `min(${akEditorMaxWidthLayoutWidth}px, ${renderWidthCSS})`;
572
- } else if (rendererAppearance === 'full-width' && !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width)) {
573
- return `min(${akEditorFullWidthLayoutWidth}px, ${renderWidthCSS})`;
574
- } else if (rendererAppearance === 'comment' && allowTableResizing && !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width)) {
575
- return renderWidthCSS;
576
- } else {
577
- // custom width, or width mapped to breakpoint
578
- const tableContainerWidth = getTableContainerWidth(tableNode);
579
- return `min(${tableContainerWidth}px, ${renderWidthCSS})`;
580
- }
581
- };
582
- const tableWidthCSS = calcDefaultLayoutWidthByAppearance(rendererAppearance, tableNode);
583
-
584
- // Logic for table alignment in renderer
585
- const isTableAlignStart = tableNode && tableNode.attrs && tableNode.attrs.layout === 'align-start' && allowTableAlignment;
586
- const fullWidthLineLengthCSS = `min(${akEditorFullWidthLayoutWidth}px, ${renderWidthCSS})`;
587
- const maxWidthLineLengthCSS = `min(${akEditorMaxWidthLayoutWidth}px, ${renderWidthCSS})`;
588
- const isCommentAppearanceAndTableAlignmentEnabled = isCommentAppearance(rendererAppearance) && allowTableAlignment;
589
- 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`;
590
- const tableWidthNew = getTableContainerWidth(tableNode);
591
- 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);
592
- let leftCSS;
593
- if (shouldCalculateLeftForAlignment) {
594
- leftCSS = `(${tableWidthCSS} - ${lineLengthCSS}) / 2`;
595
- }
596
- if (!shouldCalculateLeftForAlignment && isFullPageAppearance(rendererAppearance)) {
597
- // Note tableWidthCSS here is the renderer width
598
- // When the screen is super wide we want table to break out.
599
- // However if screen is smaller than 760px. We want table align to left.
600
- leftCSS = `min(0px, ${lineLengthCSS} - ${tableWidthCSS}) / 2`;
601
- }
602
- const children = React.Children.toArray(this.props.children);
603
-
604
- // Historically, tables in the full-width renderer had their layout set to 'default' which is deceiving.
605
- // This check caters for those tables and helps with SSR logic
606
- const isFullWidth = !(tableNode !== null && tableNode !== void 0 && tableNode.attrs.width) && rendererAppearance === 'full-width' && layout !== 'full-width';
607
- if (isFullWidth) {
608
- updatedLayout = 'full-width';
609
- // if table has width explicity set, ensure SSR is handled
610
- } else if (tableNode !== null && tableNode !== void 0 && tableNode.attrs.width) {
611
- updatedLayout = 'custom';
612
- } else {
613
- updatedLayout = layout;
614
- }
615
- let finalTableContainerWidth = allowTableResizing ? tableWidthNew : 'inherit';
616
-
617
- // We can only use CSS to determine the width when we have a known width in container.
618
- // When appearance is full-page, full-width or comment we use CSS based width calculation.
619
- // Otherwise it's fixed table width (customized width) or inherit.
620
- 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))) {
621
- finalTableContainerWidth = allowTableResizing ? `calc(${tableWidthCSS})` : 'inherit';
622
- }
623
- if (rendererAppearance === 'comment' && allowTableResizing && !allowTableAlignment) {
624
- // If table alignment is disabled and table width is akEditorDefaultLayoutWidth = 760,
625
- // it is most likely a table created before "Support Table in Comments" FF was enabled
626
- // and we would see a bug ED-24795. A table created before "Support Table in Comments",
627
- // should inhirit the width of the renderer container.
628
-
629
- // !NOTE: it a table resized to 760 is copied from 'full-page' editor and pasted in comment editor
630
- // where (allowTableResizing && !allowTableAlignment), the table will loose 760px width.
631
- finalTableContainerWidth = tableNode !== null && tableNode !== void 0 && tableNode.attrs.width && (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.width) !== akEditorDefaultLayoutWidth ? `calc(${tableWidthCSS})` : 'inherit';
632
- }
633
- if (rendererAppearance === 'comment' && allowTableResizing && allowTableAlignment) {
634
- // If table alignment is enabled and layout is not 'align-start' or 'center', we are loading a table that was
635
- // created before "Support Table in Comments" FF was enabled. So the table should have the same width as renderer container
636
- // instead of 760 that was set on tableNode when the table had been published.
637
- 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';
638
- }
639
- const isContentModeTable = isTableInContentMode({
640
- tableNode,
641
- isSupported: isContentModeSupported({
642
- allowTableResizing,
643
- rendererAppearance
644
- }),
645
- isTableNested: isInsideOfBlockNode || isInsideOfNestedRenderer || isInsideOfTable
646
- }) && expValEquals('platform_editor_table_fit_to_content_auto_convert', 'isEnabled', true);
647
- const style = {
648
- ...(isContentModeTable && {
649
- '--renderer-table-max-width': renderWidthCSS
650
- }),
651
- width: finalTableContainerWidth,
652
- left: leftCSS ? `calc(${leftCSS})` : undefined,
653
- marginLeft: shouldCalculateLeftForAlignment && leftCSS !== undefined ? `calc(-1 * (${leftCSS}))` : undefined
654
- };
655
-
656
- // Store computed style values for applyNestedRendererTableFix() to use.
657
- // Reading from props rather than the DOM ensures correctness when React
658
- // removes properties (transitions from set to undefined) between renders.
659
- this.lastComputedStyle = {
660
- width: typeof style.width === 'number' ? `${style.width}px` : style.width,
661
- left: style.left,
662
- marginLeft: style.marginLeft
663
- };
664
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
665
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
666
- className: `${TableSharedCssClassName.TABLE_CONTAINER} ${this.props.shadowClassNames || ''}`,
667
- "data-layout": updatedLayout,
668
- "data-testid": "table-container",
669
- ref: this.setContainerRef,
670
- style: style
671
- // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
672
- }, isStickyScrollbarEnabled(this.props.rendererAppearance) && /*#__PURE__*/React.createElement("div", {
673
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
674
- className: TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP,
675
- "data-testid": "sticky-scrollbar-sentinel-top"
676
- }), stickyHeaders && tableNode && !isContentModeTable && tableCanBeSticky(tableNode, children) && /*#__PURE__*/React.createElement(StickyTable, {
677
- isNumberColumnEnabled: isNumberColumnEnabled,
678
- tableWidth: "inherit",
679
- renderWidth: 0,
680
- layout: layout,
681
- handleRef: this.props.handleRef,
682
- shadowClassNames: this.props.shadowClassNames,
683
- top: this.stickyTop,
684
- mode: stickyMode,
685
- innerRef: this.stickyWrapperRef,
686
- wrapperWidth: this.state.wrapperWidth,
687
- columnWidths: columnWidths,
688
- rowHeight: this.state.headerRowHeight,
689
- tableNode: tableNode,
690
- rendererAppearance: rendererAppearance,
691
- allowTableResizing: allowTableResizing,
692
- fixTableSSRResizing: true,
693
- allowFixedColumnWidthOption: allowFixedColumnWidthOption
694
- }, [children && children[0]]), /*#__PURE__*/React.createElement("div", {
695
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
696
- className: TableSharedCssClassName.TABLE_NODE_WRAPPER,
697
- ref: this.wrapperRef,
698
- "data-number-column": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.isNumberColumnEnabled,
699
- "data-layout": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.layout,
700
- "data-autosize": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.__autoSize,
701
- "data-table-local-id": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.localId,
702
- "data-table-width": tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.width,
703
- "data-vc": "table-node-wrapper",
704
- onScroll: this.props.stickyHeaders && this.onWrapperScrolled
705
- }, /*#__PURE__*/React.createElement(Table, {
706
- innerRef: this.tableRef,
707
- columnWidths: columnWidths,
708
- layout: layout,
709
- renderWidth: 0,
710
- isNumberColumnEnabled: isNumberColumnEnabled,
711
- tableNode: tableNode,
712
- rendererAppearance: rendererAppearance,
713
- isInsideOfBlockNode: isInsideOfBlockNode,
714
- isInsideOfNestedRenderer: isInsideOfNestedRenderer,
715
- isInsideOfTable: isInsideOfTable,
716
- isinsideMultiBodiedExtension: isinsideMultiBodiedExtension,
717
- allowTableResizing: allowTableResizing,
718
- isPresentational: isPresentational,
719
- allowFixedColumnWidthOption: allowFixedColumnWidthOption
720
- }, this.grabFirstRowRef(children))), isStickyScrollbarEnabled(this.props.rendererAppearance) && /*#__PURE__*/React.createElement("div", {
721
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
722
- className: `${TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_CONTAINER}${fg('confluence_frontend_table_scrollbar_ttvc_fix') ? '-view-page' : ''}`,
723
- ref: this.stickyScrollbarRef,
724
- "data-vc": "table-sticky-scrollbar-container",
725
- style: fg('confluence_frontend_table_scrollbar_ttvc_fix') ? {
726
- ...stickyContainerBaseStyles,
727
- ...stickyContainerAdditionalStyles
728
- } : stickyContainerBaseStyles
729
- }, /*#__PURE__*/React.createElement("div", {
730
- style: {
731
- 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,
732
- // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
733
- height: '100%'
734
- }
735
- })), isStickyScrollbarEnabled(this.props.rendererAppearance) && /*#__PURE__*/React.createElement("div", {
736
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
737
- className: TableSharedCssClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_BOTTOM,
738
- "data-testid": "sticky-scrollbar-sentinel-bottom"
739
- }), /*#__PURE__*/React.createElement(RefSyncBlockFakeBorders, {
740
- isNumberColumnEnabled: isNumberColumnEnabled
741
- })));
742
- }
743
- }
744
- const getCellEdgePropsByCellOffset = (tableNode, isNumberColumnEnabled) => {
745
- const cellEdgePropsByCellOffset = new Map();
746
- const cellRightByCellOffset = new Map();
747
- const occupiedGrid = [];
748
- let tableWidth = 0;
749
- let cellOffset = 0;
750
- tableNode.forEach((rowNode, _rowOffset, rowIndex) => {
751
- var _occupiedGrid$rowInde;
752
- occupiedGrid[rowIndex] = (_occupiedGrid$rowInde = occupiedGrid[rowIndex]) !== null && _occupiedGrid$rowInde !== void 0 ? _occupiedGrid$rowInde : [];
753
- let columnIndex = 0;
754
- cellOffset += 1;
755
- rowNode.forEach(cellNode => {
756
- while (occupiedGrid[rowIndex][columnIndex]) {
757
- columnIndex += 1;
758
- }
759
- const colspan = cellNode.attrs.colspan || 1;
760
- const rowspan = cellNode.attrs.rowspan || 1;
761
- const cellLeft = columnIndex;
762
- const cellRight = cellLeft + colspan;
763
- const cellTop = rowIndex;
764
- const cellBottom = cellTop + rowspan;
765
- for (let row = cellTop; row < cellBottom; row += 1) {
766
- var _occupiedGrid$row;
767
- occupiedGrid[row] = (_occupiedGrid$row = occupiedGrid[row]) !== null && _occupiedGrid$row !== void 0 ? _occupiedGrid$row : [];
768
- for (let column = cellLeft; column < cellRight; column += 1) {
769
- occupiedGrid[row][column] = true;
770
- }
771
- }
772
- tableWidth = Math.max(tableWidth, cellRight);
773
- cellRightByCellOffset.set(cellOffset, cellRight);
774
- cellEdgePropsByCellOffset.set(cellOffset, {
775
- reachesBottom: cellBottom >= tableNode.childCount,
776
- // With number column enabled, PM column 0 is not visually leftmost and must not get `data-reaches-left`.
777
- reachesLeft: cellLeft === 0 && !isNumberColumnEnabled,
778
- reachesRight: false,
779
- reachesTop: cellTop === 0
780
- });
781
- columnIndex = cellRight;
782
- cellOffset += cellNode.nodeSize;
783
- });
784
- cellOffset += 1;
785
- });
786
- cellRightByCellOffset.forEach((cellRight, currentCellOffset) => {
787
- const edgeProps = cellEdgePropsByCellOffset.get(currentCellOffset);
788
- if (edgeProps) {
789
- edgeProps.reachesRight = cellRight >= tableWidth;
790
- }
791
- });
792
- return cellEdgePropsByCellOffset;
793
- };
794
- const isRenderedTableCell = element => {
795
- const {
796
- nodeType
797
- } = element.props;
798
- return nodeType === 'tableCell' || nodeType === 'tableHeader' || element.type === TableCell || element.type === TableHeader;
799
- };
800
- const addTableCellEdgePropsThroughWrappers = (rows, tableNode, isNumberColumnEnabled) => {
801
- try {
802
- if (!tableNode) {
803
- return rows;
804
- }
805
- const cellEdgePropsByCellOffset = getCellEdgePropsByCellOffset(tableNode, isNumberColumnEnabled);
806
- let cellOffset = 0;
807
- return React.Children.map(rows, (row, rowIndex) => {
808
- const rowNode = tableNode.child(rowIndex);
809
- cellOffset += 1;
810
- let cellIndex = 0;
811
- const addEdgePropsToRenderedCells = element => {
812
- if (isRenderedTableCell(element)) {
813
- const cellNode = rowNode.child(cellIndex);
814
- const edgeProps = cellEdgePropsByCellOffset.get(cellOffset);
815
- cellIndex += 1;
816
- cellOffset += cellNode.nodeSize;
817
- return edgeProps ? /*#__PURE__*/React.cloneElement(element, edgeProps) : element;
818
- }
819
- const {
820
- children
821
- } = element.props;
822
- if (children === undefined) {
823
- return element;
824
- }
825
- const childrenWithEdgeProps = React.Children.map(children, child => /*#__PURE__*/React.isValidElement(child) ? addEdgePropsToRenderedCells(child) : child);
826
- return /*#__PURE__*/React.cloneElement(element, undefined, childrenWithEdgeProps);
827
- };
828
- const rowWithEdgeProps = addEdgePropsToRenderedCells(row);
829
- if (cellIndex !== rowNode.childCount) {
830
- throw new Error('Rendered table row does not match its document node');
831
- }
832
- cellOffset += 1;
833
- return rowWithEdgeProps;
834
- });
835
- } catch {
836
- // Renderer can receive malformed historical ADF. If the table shape cannot
837
- // be described safely, keep rendering without rounded edge metadata.
838
- return rows;
839
- }
840
- };
841
- const addTableCellEdgeProps = (rows, tableNode, isNumberColumnEnabled) => {
842
- try {
843
- if (!tableNode) {
844
- return rows;
845
- }
846
- const cellEdgePropsByCellOffset = getCellEdgePropsByCellOffset(tableNode, isNumberColumnEnabled);
847
- let cellOffset = 0;
848
- return React.Children.map(rows, (row, rowIndex) => {
849
- const rowNode = tableNode.child(rowIndex);
850
- cellOffset += 1;
851
- let cellIndex = 0;
852
- const rowChildren = React.Children.map(row.props.children, child => {
853
- if (! /*#__PURE__*/React.isValidElement(child)) {
854
- return child;
855
- }
856
- const cellNode = rowNode.child(cellIndex);
857
- const edgeProps = cellEdgePropsByCellOffset.get(cellOffset);
858
- cellIndex += 1;
859
- cellOffset += cellNode.nodeSize;
860
- return edgeProps ? /*#__PURE__*/React.cloneElement(child, edgeProps) : child;
861
- });
862
- cellOffset += 1;
863
- return /*#__PURE__*/React.cloneElement(row, undefined, rowChildren);
864
- });
865
- } catch {
866
- // Renderer can receive malformed historical ADF. If the table shape cannot
867
- // be described safely, keep rendering without rounded edge metadata.
868
- return rows;
869
- }
870
- };
871
-
872
- /**
873
- * Processes table children before passing them to the styled table container.
874
- */
875
- // Ignored via go/ees005
876
- // eslint-disable-next-line @repo/internal/react/no-class-components
877
- export class TableProcessorWithContainerStyles extends React.Component {
878
- constructor(...args) {
879
- super(...args);
880
- _defineProperty(this, "state", {
881
- tableOrderStatus: undefined
882
- });
883
- // adds sortable + re-orders children
884
- _defineProperty(this, "addSortableColumn", childrenArray => {
885
- const {
886
- tableNode,
887
- allowColumnSorting,
888
- smartCardStorage
889
- } = this.props;
890
- const {
891
- tableOrderStatus
892
- } = this.state;
893
- if (allowColumnSorting && isHeaderRowEnabled(childrenArray) && tableNode && !hasMergedCell(tableNode)) {
894
- return addSortableColumn(orderChildren(childrenArray, tableNode, smartCardStorage, tableOrderStatus), tableOrderStatus, this.changeSortOrder);
895
- }
896
- return childrenArray;
897
- });
898
- _defineProperty(this, "changeSortOrder", (columnIndex, sortOrder) => {
899
- this.setState({
900
- tableOrderStatus: {
901
- columnIndex,
902
- order: sortOrder
903
- }
904
- });
905
- });
906
- // Ignored via go/ees005
907
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
908
- _defineProperty(this, "addNumberColumnIndexes", rows => {
909
- const {
910
- isNumberColumnEnabled
911
- } = this.props;
912
- const headerRowEnabled = isHeaderRowEnabled(rows);
913
- const lastRowIndex = React.Children.count(rows) - 1;
914
- return React.Children.map(rows, (row, index) => {
915
- return /*#__PURE__*/React.cloneElement(React.Children.only(row), {
916
- isNumberColumnEnabled,
917
- index: headerRowEnabled ? index === 0 ? '' : index : index + 1,
918
- isFirstRow: index === 0,
919
- isLastRow: index === lastRowIndex
920
- });
921
- });
922
- });
923
- }
924
- /**
925
- * Renders processed table children inside the table container.
926
- *
927
- * @example
928
- */
929
- render() {
930
- const {
931
- allowColumnSorting,
932
- allowFixedColumnWidthOption,
933
- allowTableAlignment,
934
- allowTableResizing,
935
- children,
936
- columnWidths,
937
- disableTableOverflowShadow,
938
- handleRef,
939
- isinsideMultiBodiedExtension,
940
- isInsideOfBlockNode,
941
- isInsideOfNestedRenderer,
942
- isInsideOfTable,
943
- isNumberColumnEnabled,
944
- isPresentational,
945
- layout,
946
- rendererAppearance,
947
- renderWidth,
948
- shadowClassNames,
949
- smartCardStorage,
950
- stickyHeaders,
951
- tabIndex,
952
- tableNode
953
- } = this.props;
954
- if (!children) {
955
- return null;
956
- }
957
- const childrenArray = React.Children.toArray(children);
958
- const childrenWithTableEdgeProps = expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? expValEquals('platform_editor_table_q4_patch_5', 'isEnabled', true) ? addTableCellEdgePropsThroughWrappers(childrenArray, tableNode, isNumberColumnEnabled) : addTableCellEdgeProps(childrenArray, tableNode, isNumberColumnEnabled) : childrenArray;
959
- const orderedChildren = compose(this.addNumberColumnIndexes, this.addSortableColumn
960
- // @ts-expect-error TS2345: Argument of type '(ReactChild | ReactFragment | ReactPortal)[]' is not assignable to parameter of type 'ReactElement<any, string | JSXElementConstructor<any>>[]'
961
- )(childrenWithTableEdgeProps);
962
- return /*#__PURE__*/React.createElement(TableContainer, {
963
- allowColumnSorting: allowColumnSorting,
964
- allowFixedColumnWidthOption: allowFixedColumnWidthOption,
965
- allowTableAlignment: allowTableAlignment,
966
- allowTableResizing: allowTableResizing,
967
- columnWidths: columnWidths,
968
- disableTableOverflowShadow: disableTableOverflowShadow,
969
- handleRef: handleRef,
970
- isinsideMultiBodiedExtension: isinsideMultiBodiedExtension,
971
- isInsideOfBlockNode: isInsideOfBlockNode,
972
- isInsideOfNestedRenderer: isInsideOfNestedRenderer,
973
- isInsideOfTable: isInsideOfTable,
974
- isNumberColumnEnabled: isNumberColumnEnabled,
975
- isPresentational: isPresentational,
976
- layout: layout,
977
- rendererAppearance: rendererAppearance,
978
- renderWidth: renderWidth,
979
- shadowClassNames: shadowClassNames,
980
- smartCardStorage: smartCardStorage,
981
- stickyHeaders: stickyHeaders,
982
- tabIndex: tabIndex,
983
- tableNode: tableNode
984
- }, orderedChildren);
985
- }
986
- }