@atlaskit/renderer
Version:
Renderer component
279 lines (269 loc) • 9.26 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React from 'react';
/* eslint-disable @typescript-eslint/consistent-type-imports, @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic */
import { jsx, css } from '@emotion/react';
import { TableSharedCssClassName } from '@atlaskit/editor-common/styles';
import { akEditorStickyHeaderZIndex } from '@atlaskit/editor-shared-styles';
import { Table } from './table';
import { recursivelyInjectProps } from '../../utils/inject-props';
export const tableStickyPadding = 8;
const modeSpecficStyles = {
none: css({
display: 'none'
}),
stick: css({
position: 'fixed'
}),
'pin-bottom': css({
position: 'absolute'
})
};
// refactored based on fixedTableDivStaticStyles
// TODO: DSP-4123 - Quality ticket
const fixedTableDivStaticStyles = css({
zIndex: 'var(--ak-renderer-sticky-header-zindex)',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
[`& .${TableSharedCssClassName.TABLE_CONTAINER}, & .${TableSharedCssClassName.TABLE_STICKY_WRAPPER} > table`]: {
marginTop: 0,
marginBottom: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
tr: {
background: "var(--ds-surface, #FFFFFF)"
}
},
borderTop: `${tableStickyPadding}px solid ${"var(--ds-surface, #FFFFFF)"}`,
background: "var(--ds-surface-overlay, #FFFFFF)",
boxShadow: `0 6px 4px -4px ${"var(--ds-shadow-overflow-perimeter, #1E1F211f)"}`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
"div[data-expanded='false'] &": {
display: 'none'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
[`& .${TableSharedCssClassName.TABLE_CONTAINER}.is-sticky.right-shadow::after, & .${TableSharedCssClassName.TABLE_CONTAINER}.is-sticky.left-shadow::before`]: {
top: '0px',
height: '100%'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
"&.fixed-table-div-custom-table-resizing[mode='stick']": {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
zIndex: 'var(--ak-renderer-sticky-header-zindex)'
}
});
const FixedTableDiv = props => {
const {
top,
wrapperWidth,
mode,
allowTableResizing
} = props;
let stickyHeaderZIndex;
if (allowTableResizing) {
stickyHeaderZIndex = 13;
} else {
stickyHeaderZIndex = akEditorStickyHeaderZIndex;
}
const attrs = {
mode
};
return jsx("div", _extends({}, attrs, {
"data-testid": "sticky-table-fixed"
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
,
className: allowTableResizing ? 'fixed-table-div-custom-table-resizing' : '',
css: [fixedTableDivStaticStyles, modeSpecficStyles === null || modeSpecficStyles === void 0 ? void 0 : modeSpecficStyles[mode]],
style: {
'--ak-renderer-sticky-header-zindex': stickyHeaderZIndex,
width: `${wrapperWidth}px`,
top: typeof top === 'number' ? `${top}px` : undefined
}
}), props.children);
};
export const StickyTable = ({
top,
left,
mode,
shadowClassNames,
innerRef,
wrapperWidth,
tableWidth,
isNumberColumnEnabled,
layout,
children,
columnWidths,
renderWidth,
rowHeight,
tableNode,
rendererAppearance,
allowTableResizing,
fixTableSSRResizing = false,
allowFixedColumnWidthOption
}) => {
let styles;
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
if (allowTableResizing) {
styles = css({
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
top: mode === 'pin-bottom' ? top : undefined,
position: 'absolute'
});
} else {
styles = css({
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
left: left && left < 0 ? left : undefined,
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
top: mode === 'pin-bottom' ? top : undefined,
position: 'relative'
});
}
/* eslint-enable @atlaskit/design-system/ensure-design-token-usage */
return (
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
jsx("div", {
css: styles
}, jsx(FixedTableDiv, {
top: mode === 'stick' ? top : undefined,
mode: rowHeight > 300 ? 'none' : mode,
wrapperWidth: wrapperWidth,
allowTableResizing: allowTableResizing
}, jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: `${TableSharedCssClassName.TABLE_CONTAINER} is-sticky ${shadowClassNames || ''}`,
"data-layout": layout,
style: {
width: tableWidth,
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
marginBottom: fixTableSSRResizing ? 0 : ''
}
}, jsx("div", {
ref: innerRef
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
,
className: `${TableSharedCssClassName.TABLE_STICKY_WRAPPER}`,
style: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
overflow: 'hidden'
}
}, jsx(Table, {
columnWidths: columnWidths,
layout: layout,
isNumberColumnEnabled: isNumberColumnEnabled,
renderWidth: renderWidth,
tableNode: tableNode,
rendererAppearance: rendererAppearance,
fixTableSSRResizing: fixTableSSRResizing,
allowFixedColumnWidthOption: allowFixedColumnWidthOption
},
/**
* @see https://product-fabric.atlassian.net/browse/ED-10235
* We pass prop 'invisible' to our table's children nodes meaning
* they exist inside of the 'invisible' duplicated table component that
* enables sticky headers.
*/
recursivelyInjectProps(children, {
invisible: true
}))))))
);
};
/**
* Traverse DOM Tree upwards looking for table parents with "overflow: scroll".
* @param table
* @param defaultScrollRootId
* @example
*/
function findHorizontalOverflowScrollParent(table, defaultScrollRootId) {
let parent = table;
if (!parent) {
return null;
}
// Ignored via go/ees005
// eslint-disable-next-line no-cond-assign
while (parent = parent.parentElement) {
// IE11 on Window 8 doesn't show styles from CSS when accessing through element.style property.
const style = window.getComputedStyle(parent);
if (style.overflow === 'scroll' || style.overflowY === 'scroll') {
return parent;
}
if (!!defaultScrollRootId && parent.id === defaultScrollRootId) {
// If a defaultScrollRootId was specified and we reached the element with this id without finding a closer
// scroll parent, use this element as the scroll parent
return parent;
}
}
return null;
}
/**
*
*/
export class OverflowParent {
constructor(ref) {
this.ref = ref;
this.ref = ref;
}
/**
*
* @param el
* @param defaultScrollRootId
* @example
*/
static fromElement(el, defaultScrollRootId) {
return new OverflowParent(findHorizontalOverflowScrollParent(el, defaultScrollRootId) || window);
}
/**
*
*/
get isElement() {
return this.ref instanceof HTMLElement;
}
/**
*
*/
get id() {
if (this.ref instanceof HTMLElement) {
return this.ref.id;
}
return '';
}
/**
*
*/
get top() {
if (this.ref instanceof HTMLElement) {
return this.ref.getBoundingClientRect().top;
}
return 0;
}
/**
*
* @param type
* @param cb
* @param {...any} args
* @example
*/
// Ignored via go/ees005
addEventListener(type, cb,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...args) {
// Ignored via go/ees005
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
this.ref.addEventListener(type, cb, ...args);
}
/**
*
* @param type
* @param cb
* @param {...any} args
* @example
*/
// Ignored via go/ees005
removeEventListener(type, cb,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...args) {
// Ignored via go/ees005
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
this.ref.removeEventListener(type, cb, ...args);
}
}