@atlaskit/editor-plugin-table 5.3.38 → 5.4.0
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 +18 -0
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +5 -2
- package/dist/cjs/plugins/table/nodeviews/TableRow.js +158 -45
- package/dist/cjs/plugins/table/ui/TableFloatingControls/CornerControls/DragCornerControls.js +0 -6
- package/dist/cjs/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +3 -0
- package/dist/cjs/plugins/table/ui/common-styles.js +18 -7
- package/dist/cjs/plugins/table/ui/ui-styles.js +26 -21
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +5 -2
- package/dist/es2019/plugins/table/nodeviews/TableRow.js +163 -50
- package/dist/es2019/plugins/table/ui/TableFloatingControls/CornerControls/DragCornerControls.js +1 -9
- package/dist/es2019/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +1 -0
- package/dist/es2019/plugins/table/ui/common-styles.js +17 -0
- package/dist/es2019/plugins/table/ui/ui-styles.js +36 -19
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +5 -2
- package/dist/esm/plugins/table/nodeviews/TableRow.js +158 -46
- package/dist/esm/plugins/table/ui/TableFloatingControls/CornerControls/DragCornerControls.js +1 -7
- package/dist/esm/plugins/table/ui/TableFloatingControls/RowDropTarget/index.js +3 -0
- package/dist/esm/plugins/table/ui/common-styles.js +18 -7
- package/dist/esm/plugins/table/ui/ui-styles.js +26 -21
- package/dist/types/plugins/table/nodeviews/TableRow.d.ts +3 -0
- package/dist/types-ts4.5/plugins/table/nodeviews/TableRow.d.ts +3 -0
- package/package.json +6 -3
- package/src/plugins/table/nodeviews/TableComponent.tsx +13 -12
- package/src/plugins/table/nodeviews/TableRow.ts +199 -52
- package/src/plugins/table/ui/TableFloatingControls/CornerControls/DragCornerControls.tsx +1 -7
- package/src/plugins/table/ui/TableFloatingControls/RowDropTarget/index.tsx +1 -0
- package/src/plugins/table/ui/common-styles.ts +23 -0
- package/src/plugins/table/ui/ui-styles.ts +40 -19
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
-
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20, _templateObject21, _templateObject22, _templateObject23, _templateObject24, _templateObject25, _templateObject26, _templateObject27, _templateObject28, _templateObject29, _templateObject30, _templateObject31, _templateObject32, _templateObject33, _templateObject34;
|
|
2
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20, _templateObject21, _templateObject22, _templateObject23, _templateObject24, _templateObject25, _templateObject26, _templateObject27, _templateObject28, _templateObject29, _templateObject30, _templateObject31, _templateObject32, _templateObject33, _templateObject34, _templateObject35;
|
|
3
3
|
import { css } from '@emotion/react';
|
|
4
4
|
import { tableCellBorderWidth, tableMarginTop, tableMarginTopWithControl } from '@atlaskit/editor-common/styles';
|
|
5
5
|
import { akEditorShadowZIndex, akEditorTableNumberColumnWidth, akEditorUnitZIndex } from '@atlaskit/editor-shared-styles';
|
|
@@ -39,7 +39,7 @@ export var dragInsertButtonWrapper = function dragInsertButtonWrapper(props) {
|
|
|
39
39
|
return css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n .", " {\n position: absolute;\n z-index: ", ";\n }\n\n .", " {\n bottom: -3px;\n left: 2px;\n }\n\n .", " {\n left: -3px;\n bottom: -2px;\n }\n\n .", " {\n ", "\n }\n\n .", ":hover {\n background: ", ";\n border: 1px solid ", ";\n color: ", ";\n cursor: pointer;\n }\n"])), ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER, akEditorUnitZIndex + 10, ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER_COLUMN, ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER_ROW, ClassName.DRAG_CONTROLS_INSERT_BUTTON, Button("\n background: ".concat("var(--ds-surface-overlay, white)", ";\n color: ", "var(--ds-icon, ".concat(N300, ")"), ";\n border: 1px solid ", "var(--ds-background-accent-gray-subtler, #C1C7D0)", ";\n border-radius: 50%;\n height: ", dragTableInsertColumnButtonSize, "px;\n width: ").concat(dragTableInsertColumnButtonSize, "px;\n ")), ClassName.DRAG_CONTROLS_INSERT_BUTTON, "var(--ds-background-brand-bold, ".concat(B300, ")"), "var(--ds-background-brand-bold, ".concat(B300, ")"), "var(--ds-icon-inverse, white)");
|
|
40
40
|
};
|
|
41
41
|
export var dragCornerControlButton = function dragCornerControlButton(props) {
|
|
42
|
-
return css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n .", " {\n width:
|
|
42
|
+
return css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n .", " {\n width: 24px;\n height: 24px;\n display: flex;\n justify-content: flex-end;\n align-items: flex-end;\n position: absolute;\n top: ", ";\n left: ", ";\n background-color: transparent;\n border: none;\n padding: 0;\n outline: none;\n z-index: ", ";\n\n &.active .", " {\n background-color: ", ";\n width: 10px;\n height: 10px;\n border-width: 2px;\n border-radius: 4px;\n top: ", ";\n left: ", ";\n }\n\n &:hover {\n cursor: pointer;\n\n .", " {\n width: 10px;\n height: 10px;\n border-width: 2px;\n border-radius: 4px;\n top: ", ";\n left: ", ";\n }\n }\n }\n\n .", " {\n border: 1px solid ", ";\n background-color: ", ";\n border-radius: 2px;\n width: 5px;\n height: 5px;\n position: relative;\n }\n"])), ClassName.DRAG_CORNER_BUTTON, "var(--ds-space-negative-250, -20px)", "var(--ds-space-negative-100, -8px)", akEditorUnitZIndex * 99, ClassName.DRAG_CORNER_BUTTON_INNER, "var(--ds-border-selected, #0C66E4)", "var(--ds-space-075, 6px)", "var(--ds-space-075, 6px)", ClassName.DRAG_CORNER_BUTTON_INNER, "var(--ds-space-075, 6px)", "var(--ds-space-075, 6px)", ClassName.DRAG_CORNER_BUTTON_INNER, "var(--ds-border-inverse, #FFF)", "var(--ds-background-accent-gray-subtler, #DCDFE4)");
|
|
43
43
|
};
|
|
44
44
|
export var insertColumnButtonWrapper = function insertColumnButtonWrapper(props) {
|
|
45
45
|
return css(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n ", "\n ", "\n ", "\n"])), InsertButton(), InsertButtonHover(), InsertLine(props, "\n width: 2px;\n left: 9px;\n "));
|
|
@@ -54,64 +54,69 @@ export var DeleteButton = function DeleteButton(props) {
|
|
|
54
54
|
return css(_templateObject15 || (_templateObject15 = _taggedTemplateLiteral(["\n .", ",\n .", " {\n height: ", "px;\n width: ", "px;\n }\n .", " {\n .", " {\n ", "\n }\n }\n\n .", ":hover {\n background: ", ";\n color: ", ";\n cursor: pointer;\n }\n"])), ClassName.CONTROLS_DELETE_BUTTON_WRAP, ClassName.CONTROLS_DELETE_BUTTON, tableDeleteButtonSize, tableDeleteButtonSize, ClassName.CONTROLS_DELETE_BUTTON_WRAP, ClassName.CONTROLS_DELETE_BUTTON, Button("\n background: ".concat(tableCellSelectedDeleteIconBackground(props), ";\n color: ").concat(tableCellSelectedDeleteIconColor(props), ";\n ")), ClassName.CONTROLS_DELETE_BUTTON, tableCellHoverDeleteIconBackground(props), tableCellHoverDeleteIconColor(props));
|
|
55
55
|
};
|
|
56
56
|
export var OverflowShadow = function OverflowShadow(props) {
|
|
57
|
-
return css(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["\n .", ", .", " {\n display: block;\n height: calc(100% - ", "px);\n position: absolute;\n pointer-events: none;\n top: ", "px;\n z-index: ", ";\n width: ", "px;\n }\n .", " {\n background: linear-gradient(\n to left,\n transparent 0,\n ", "\n ", "%\n ),\n linear-gradient(\n to right,\n ", " 0px,\n transparent 1px\n );\n left: 0px;\n }\n .", "[data-number-column='true'] > :not(.", ").", " {\n left: ", "px;\n }\n .", " {\n background: linear-gradient(\n to right,\n transparent 0,\n ", "\n ", "%\n ),\n linear-gradient(\n to left,\n ", " 0px,\n transparent 1px\n );\n left: ", ";\n }\n .", " {\n
|
|
57
|
+
return css(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["\n .", ", .", " {\n display: block;\n height: calc(100% - ", "px);\n position: absolute;\n pointer-events: none;\n top: ", "px;\n z-index: ", ";\n width: ", "px;\n }\n .", " {\n background: linear-gradient(\n to left,\n transparent 0,\n ", "\n ", "%\n ),\n linear-gradient(\n to right,\n ", " 0px,\n transparent 1px\n );\n left: 0px;\n }\n .", "[data-number-column='true'] > :not(.", ").", " {\n left: ", "px;\n }\n .", " {\n background: linear-gradient(\n to right,\n transparent 0,\n ", "\n ", "%\n ),\n linear-gradient(\n to left,\n ", " 0px,\n transparent 1px\n );\n left: ", ";\n }\n .", " {\n ", "\n .", " {\n border-left: 1px solid ", ";\n }\n }\n"])), ClassName.TABLE_RIGHT_SHADOW, ClassName.TABLE_LEFT_SHADOW, tableMarginTop, tableMarginTop, akEditorShadowZIndex, getBooleanFF('platform.editor.table.increase-shadow-visibility_lh89r') ? tableOverflowShadowWidthWide : tableOverflowShadowWidth, ClassName.TABLE_LEFT_SHADOW, "var(--ds-shadow-overflow-spread, ".concat(N40A, ")"), getBooleanFF('platform.editor.table.increase-shadow-visibility_lh89r') ? 140 : 100, "var(--ds-shadow-overflow-perimeter, transparent)", ClassName.TABLE_CONTAINER, ClassName.TABLE_STICKY_SHADOW, ClassName.TABLE_LEFT_SHADOW, akEditorTableNumberColumnWidth - 1, ClassName.TABLE_RIGHT_SHADOW, "var(--ds-shadow-overflow-spread, ".concat(N40A, ")"), getBooleanFF('platform.editor.table.increase-shadow-visibility_lh89r') ? 140 : 100, "var(--ds-shadow-overflow-perimeter, transparent)", getBooleanFF('platform.editor.custom-table-width') ? "calc(100% - ".concat(getBooleanFF('platform.editor.table.increase-shadow-visibility_lh89r') ? tableOverflowShadowWidthWide : tableOverflowShadowWidth, "px)") : "calc(100% - ".concat(getBooleanFF('platform.editor.table.increase-shadow-visibility_lh89r') ? tableOverflowShadowWidthWide - 10 : -2, "px)"), ClassName.WITH_CONTROLS, overflowShadowWidhoutDnD(), ClassName.TABLE_LEFT_SHADOW, tableBorderColor(props));
|
|
58
|
+
};
|
|
59
|
+
var overflowShadowWidhoutDnD = function overflowShadowWidhoutDnD() {
|
|
60
|
+
if (!getBooleanFF('platform.editor.table.drag-and-drop')) {
|
|
61
|
+
return css(_templateObject17 || (_templateObject17 = _taggedTemplateLiteral(["\n .", ", .", " {\n height: calc(100% - ", "px);\n top: ", "px;\n }\n "])), ClassName.TABLE_RIGHT_SHADOW, ClassName.TABLE_LEFT_SHADOW, tableMarginTopWithControl, tableMarginTopWithControl);
|
|
62
|
+
}
|
|
58
63
|
};
|
|
59
64
|
var columnHeaderButton = function columnHeaderButton(props, cssString) {
|
|
60
65
|
if (getBooleanFF('platform.editor.table.column-controls-styles-updated')) {
|
|
61
|
-
return css(
|
|
66
|
+
return css(_templateObject18 || (_templateObject18 = _taggedTemplateLiteral(["\n background: ", ";\n display: block;\n box-sizing: border-box;\n padding: 0;\n\n :focus {\n outline: none;\n }\n\n ", "\n "])), tableHeaderCellBackgroundColor(props), cssString);
|
|
62
67
|
} else {
|
|
63
|
-
return css(
|
|
68
|
+
return css(_templateObject19 || (_templateObject19 = _taggedTemplateLiteral(["\n background: ", ";\n border: 1px solid ", ";\n display: block;\n box-sizing: border-box;\n padding: 0;\n\n :focus {\n outline: none;\n }\n\n ", "\n "])), tableHeaderCellBackgroundColor(props), tableBorderColor(props), cssString);
|
|
64
69
|
}
|
|
65
70
|
};
|
|
66
71
|
var columnHeaderButtonSelected = function columnHeaderButtonSelected(props) {
|
|
67
|
-
return css(
|
|
72
|
+
return css(_templateObject20 || (_templateObject20 = _taggedTemplateLiteral(["\n color: ", ";\n background-color: ", ";\n border-color: ", ";\n z-index: ", ";\n"])), "var(--ds-text-inverse, ".concat(N0, ")"), tableToolbarSelectedColor(props), tableBorderSelectedColor(props), columnControlsSelectedZIndex);
|
|
68
73
|
};
|
|
69
74
|
var getFloatingDotOverrides = function getFloatingDotOverrides(props) {
|
|
70
|
-
return getBooleanFF('platform.editor.custom-table-width') ? css(
|
|
75
|
+
return getBooleanFF('platform.editor.custom-table-width') ? css(_templateObject21 || (_templateObject21 = _taggedTemplateLiteral(["\n tr\n th:last-child\n .", "::before,\n tr\n td:last-child\n .", "::before {\n content: '';\n background-color: ", ";\n position: absolute;\n height: ", "px;\n width: ", "px;\n border-radius: 50%;\n pointer-events: none;\n top: ", ";\n right: 0px;\n }\n "])), ClassName.COLUMN_CONTROLS_DECORATIONS, ClassName.COLUMN_CONTROLS_DECORATIONS, tableBorderColor(props), lineMarkerSize, lineMarkerSize, "var(--ds-space-025, 2px)") : '';
|
|
71
76
|
};
|
|
72
77
|
export var floatingColumnControls = function floatingColumnControls(props) {
|
|
73
|
-
return css(
|
|
78
|
+
return css(_templateObject22 || (_templateObject22 = _taggedTemplateLiteral(["\n .", " {\n box-sizing: border-box;\n position: absolute;\n top: 0;\n\n .", " {\n display: flex;\n flex-direction: row;\n }\n }\n\n .", " {\n box-sizing: border-box;\n\n .", " {\n display: grid;\n justify-items: center;\n }\n }\n "])), ClassName.DRAG_COLUMN_DROP_TARGET_CONTROLS, ClassName.DRAG_COLUMN_CONTROLS_INNER, ClassName.DRAG_COLUMN_CONTROLS, ClassName.DRAG_COLUMN_CONTROLS_INNER);
|
|
74
79
|
};
|
|
75
80
|
export var rowControlsWrapperDotStyle = function rowControlsWrapperDotStyle(props) {
|
|
76
81
|
if (getBooleanFF('platform.editor.table.drag-and-drop')) {
|
|
77
|
-
return css(
|
|
82
|
+
return css(_templateObject23 || (_templateObject23 = _taggedTemplateLiteral(["\n div.", ">.", "::after {\n display: none;\n }\n "])), ClassName.WITH_CONTROLS, ClassName.ROW_CONTROLS_WRAPPER);
|
|
78
83
|
} else {
|
|
79
|
-
return css(
|
|
84
|
+
return css(_templateObject24 || (_templateObject24 = _taggedTemplateLiteral(["\n div.", ">.", "::after {\n content: ' ';\n background-color: ", ";\n position: absolute;\n height: ", "px;\n width: ", "px;\n border-radius: 50%;\n pointer-events: none;\n top: -", "px;\n right: -1px;\n }\n "])), ClassName.WITH_CONTROLS, ClassName.ROW_CONTROLS_WRAPPER, tableBorderColor(props), lineMarkerSize, lineMarkerSize, tableToolbarSize + tableCellBorderWidth);
|
|
80
85
|
}
|
|
81
86
|
};
|
|
82
87
|
export var columnControlsDecoration = function columnControlsDecoration(props) {
|
|
83
88
|
if (getBooleanFF('platform.editor.table.column-controls-styles-updated')) {
|
|
84
|
-
return css(
|
|
89
|
+
return css(_templateObject25 || (_templateObject25 = _taggedTemplateLiteral(["\n .", " {\n display: none;\n cursor: pointer;\n position: absolute;\n width: 100%;\n left: 0;\n top: -", "px;\n height: ", "px;\n // floating dot for adding column button\n &::before {\n content: ' ';\n background-color: ", ";\n position: absolute;\n height: ", "px;\n width: ", "px;\n border-radius: 50%;\n pointer-events: none;\n top: 2px;\n right: -1px;\n }\n\n &::after {\n content: ' ';\n\n ", "\n }\n }\n\n // floating dot for adding column button - overriding style on last column to avoid scroll\n ", "\n\n .", " .", " {\n display: block;\n }\n\n table tr:first-of-type th.", " {\n &.", ", &.", " {\n .", "::after {\n ", ";\n }\n\n &.", "\n .", "::after {\n background-color: ", ";\n border-color: ", ";\n z-index: ", ";\n }\n }\n }\n\n table tr:first-of-type th.", " {\n &.", ", &.", " {\n .", "::after {\n ", ";\n border-left: ", "px solid\n ", ";\n left: -", "px;\n }\n }\n }\n\n table tr:first-of-type th.", " {\n &.", " {\n .", "::after {\n ", ";\n }\n\n &.", "\n .", "::after {\n background-color: ", ";\n border-color: ", ";\n border-left: ", "px solid\n ", ";\n left: -", "px;\n z-index: ", ";\n }\n }\n }\n\n .", "\n table\n tr:first-of-type\n td.", ",\n .", "\n table\n tr:first-of-type\n th.", " {\n .", "::after {\n ", ";\n }\n }\n "])), ClassName.COLUMN_CONTROLS_DECORATIONS, columnControlsDecorationHeight + tableCellBorderWidth, columnControlsDecorationHeight, tableBorderColor(props), lineMarkerSize, lineMarkerSize, columnHeaderButton(props, "\n border-right: ".concat(tableCellBorderWidth, "px solid ").concat(tableBorderColor(props), ";\n border-top: ").concat(tableCellBorderWidth, "px solid ").concat(tableBorderColor(props), ";\n border-bottom: ").concat(tableCellBorderWidth, "px solid ").concat(tableBorderColor(props), ";\n box-sizing: content-box;\n height: ").concat(tableToolbarSize - 1, "px;\n width: 100%;\n position: absolute;\n top: ").concat(columnControlsDecorationHeight - tableToolbarSize, "px;\n left: 0px;\n z-index: ").concat(columnControlsZIndex, ";\n ")), getFloatingDotOverrides(props), ClassName.WITH_CONTROLS, ClassName.COLUMN_CONTROLS_DECORATIONS, ClassName.TABLE_HEADER_CELL, ClassName.COLUMN_SELECTED, ClassName.HOVERED_TABLE, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props), ClassName.HOVERED_CELL_IN_DANGER, ClassName.COLUMN_CONTROLS_DECORATIONS, tableToolbarDeleteColor(props), tableBorderDeleteColor(props), akEditorUnitZIndex * 100, ClassName.TABLE_HEADER_CELL, ClassName.COLUMN_SELECTED, ClassName.HOVERED_COLUMN, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props), tableCellBorderWidth, tableBorderSelectedColor(props), tableCellBorderWidth, ClassName.TABLE_HEADER_CELL, ClassName.HOVERED_COLUMN, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props), ClassName.HOVERED_CELL_IN_DANGER, ClassName.COLUMN_CONTROLS_DECORATIONS, tableToolbarDeleteColor(props), tableBorderDeleteColor(props), tableCellBorderWidth, tableBorderDeleteColor(props), tableCellBorderWidth, akEditorUnitZIndex * 100, ClassName.TABLE_SELECTED, ClassName.TABLE_CELL, ClassName.TABLE_SELECTED, ClassName.TABLE_HEADER_CELL, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props));
|
|
85
90
|
} else {
|
|
86
|
-
return css(
|
|
91
|
+
return css(_templateObject26 || (_templateObject26 = _taggedTemplateLiteral(["\n .", " {\n display: none;\n cursor: pointer;\n position: absolute;\n width: calc(100% + ", "px);\n left: -1px;\n top: -", "px;\n height: ", "px;\n // floating dot for adding column button\n &::before {\n content: ' ';\n background-color: ", ";\n position: absolute;\n height: ", "px;\n width: ", "px;\n border-radius: 50%;\n pointer-events: none;\n top: 2px;\n right: -1px;\n }\n\n &::after {\n content: ' ';\n\n ", "\n }\n }\n\n // floating dot for adding column button - overriding style on last column to avoid scroll\n ", "\n\n .", " .", " {\n display: block;\n }\n\n table\n tr:first-of-type\n td.", ",\n table\n tr:first-of-type\n th.", " {\n &.", ",\n &.", ",\n &.", " {\n .", "::after {\n ", ";\n }\n\n &.", "\n .", "::after {\n background-color: ", ";\n border: 1px solid ", ";\n border-bottom: none;\n z-index: ", ";\n }\n }\n }\n\n .", "\n table\n tr:first-of-type\n td.", ",\n .", "\n table\n tr:first-of-type\n th.", " {\n .", "::after {\n ", ";\n }\n }\n "])), ClassName.COLUMN_CONTROLS_DECORATIONS, tableCellBorderWidth * 2, columnControlsDecorationHeight + tableCellBorderWidth, columnControlsDecorationHeight, tableBorderColor(props), lineMarkerSize, lineMarkerSize, columnHeaderButton(props, "\n border-right: ".concat(tableCellBorderWidth, "px solid ").concat(tableBorderColor(props), ";\n border-bottom: none;\n height: ").concat(tableToolbarSize, "px;\n width: 100%;\n position: absolute;\n top: ").concat(columnControlsDecorationHeight - tableToolbarSize, "px;\n left: 0px;\n z-index: ").concat(columnControlsZIndex, ";\n ")), getFloatingDotOverrides(props), ClassName.WITH_CONTROLS, ClassName.COLUMN_CONTROLS_DECORATIONS, ClassName.TABLE_CELL, ClassName.TABLE_HEADER_CELL, ClassName.COLUMN_SELECTED, ClassName.HOVERED_COLUMN, ClassName.HOVERED_TABLE, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props), ClassName.HOVERED_CELL_IN_DANGER, ClassName.COLUMN_CONTROLS_DECORATIONS, tableToolbarDeleteColor(props), tableBorderDeleteColor(props), akEditorUnitZIndex * 100, ClassName.TABLE_SELECTED, ClassName.TABLE_CELL, ClassName.TABLE_SELECTED, ClassName.TABLE_HEADER_CELL, ClassName.COLUMN_CONTROLS_DECORATIONS, columnHeaderButtonSelected(props));
|
|
87
92
|
}
|
|
88
93
|
};
|
|
89
94
|
export var hoveredDeleteButton = function hoveredDeleteButton(props) {
|
|
90
|
-
return css(
|
|
95
|
+
return css(_templateObject27 || (_templateObject27 = _taggedTemplateLiteral(["\n .", ".", " {\n .", ",\n .", ",\n .", " {\n border: 1px solid ", ";\n }\n .", "::after {\n background: ", ";\n }\n }\n"])), ClassName.TABLE_CONTAINER, ClassName.HOVERED_DELETE_BUTTON, ClassName.SELECTED_CELL, ClassName.COLUMN_SELECTED, ClassName.HOVERED_CELL, tableBorderDeleteColor(props), ClassName.SELECTED_CELL, tableCellDeleteColor(props));
|
|
91
96
|
};
|
|
92
97
|
export var disabledCell = function disabledCell(props) {
|
|
93
|
-
return css(
|
|
98
|
+
return css(_templateObject28 || (_templateObject28 = _taggedTemplateLiteral(["\n :not(.", ")\n .", ":not(.", ") {\n .", ".", " {\n position: relative;\n border: 1px solid ", ";\n }\n .", ".", "::after {\n border: 1px solid ", ";\n }\n }\n"])), ClassName.IS_RESIZING, ClassName.TABLE_CONTAINER, ClassName.HOVERED_DELETE_BUTTON, ClassName.HOVERED_CELL, ClassName.HOVERED_DISABLED_CELL, tableCellDisabledColor, ClassName.HOVERED_CELL, ClassName.HOVERED_DISABLED_CELL, tableCellDisabledColor);
|
|
94
99
|
};
|
|
95
100
|
export var hoveredCell = function hoveredCell(props) {
|
|
96
|
-
return css(
|
|
101
|
+
return css(_templateObject29 || (_templateObject29 = _taggedTemplateLiteral(["\n :not(.", ")\n .", ":not(.", ") {\n .", " {\n position: relative;\n border: 1px solid ", ";\n }\n }\n"])), ClassName.IS_RESIZING, ClassName.TABLE_CONTAINER, ClassName.HOVERED_DELETE_BUTTON, ClassName.HOVERED_CELL, tableBorderSelectedColor(props));
|
|
97
102
|
};
|
|
98
|
-
export var hoveredWarningCell = css(
|
|
103
|
+
export var hoveredWarningCell = css(_templateObject30 || (_templateObject30 = _taggedTemplateLiteral(["\n :not(.", ")\n .", ":not(.", ") {\n td.", " {\n background-color: ", " !important; // We need to override the background-color added to the cell\n border: 1px solid ", ";\n }\n }\n"])), ClassName.IS_RESIZING, ClassName.TABLE_CONTAINER, ClassName.HOVERED_DELETE_BUTTON, ClassName.HOVERED_CELL_WARNING, "var(--ds-background-warning, ".concat(Y50, ")"), "var(--ds-border-warning, ".concat(Y200, ")"));
|
|
99
104
|
|
|
100
105
|
// move the resize handle zone completely inside the table cell to avoid overflow
|
|
101
106
|
var getLastColumnResizerOverrides = function getLastColumnResizerOverrides() {
|
|
102
|
-
return getBooleanFF('platform.editor.custom-table-width') ? css(
|
|
107
|
+
return getBooleanFF('platform.editor.custom-table-width') ? css(_templateObject31 || (_templateObject31 = _taggedTemplateLiteral(["\n tr\n th:last-child\n .", ",\n tr\n td:last-child\n .", " {\n background-color: transparent;\n position: absolute;\n width: ", "px;\n height: 100%;\n top: 0;\n right: 0;\n cursor: col-resize;\n z-index: ", ";\n }\n "])), ClassName.RESIZE_HANDLE_DECORATION, ClassName.RESIZE_HANDLE_DECORATION, resizeHandlerAreaWidth / 2, resizeHandlerZIndex) : '';
|
|
103
108
|
};
|
|
104
109
|
var resizeHandleOverrides = function resizeHandleOverrides(props) {
|
|
105
110
|
if (getBooleanFF('platform.editor.table.drag-and-drop')) {
|
|
106
|
-
return css(
|
|
111
|
+
return css(_templateObject32 || (_templateObject32 = _taggedTemplateLiteral(["\n th.", "::before,\n td.", "::before {\n content: ' ';\n position: absolute;\n left: ", ";\n top: -1px;\n width: ", "px;\n height: calc(100% + 2px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before,\n td.", "::before {\n content: ' ';\n position: absolute;\n right: -1px;\n top: -1px;\n width: ", "px;\n height: calc(100% + 2px);\n background-color: ", ";\n z-index: ", ";\n }\n "])), ClassName.WITH_RESIZE_LINE, ClassName.WITH_RESIZE_LINE, "var(--ds-space-negative-025, -2px)", resizeLineWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_RESIZE_LINE_LAST_COLUMN, ClassName.WITH_RESIZE_LINE_LAST_COLUMN, resizeLineWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2);
|
|
107
112
|
}
|
|
108
|
-
return css(
|
|
113
|
+
return css(_templateObject33 || (_templateObject33 = _taggedTemplateLiteral(["\n td.", "::before {\n content: ' ';\n position: absolute;\n left: ", ";\n top: -1px;\n width: ", "px;\n height: calc(100% + 2px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n left: ", ";\n position: absolute;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -", "px;\n }\n\n td.", "::before {\n content: ' ';\n position: absolute;\n right: -1px;\n top: -1px;\n width: ", "px;\n height: calc(100% + 2px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n right: -1px;\n position: absolute;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -", "px;\n }\n "])), ClassName.WITH_RESIZE_LINE, "var(--ds-space-negative-025, -2px)", resizeLineWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_RESIZE_LINE, "var(--ds-space-negative-025, -2px)", resizeLineWidth, tableToolbarSize + tableCellBorderWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, tableToolbarSize + tableCellBorderWidth, ClassName.WITH_RESIZE_LINE_LAST_COLUMN, resizeLineWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_RESIZE_LINE_LAST_COLUMN, resizeLineWidth, tableToolbarSize + tableCellBorderWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, tableToolbarSize + tableCellBorderWidth);
|
|
109
114
|
};
|
|
110
115
|
export var resizeHandle = function resizeHandle(props) {
|
|
111
|
-
return css(
|
|
116
|
+
return css(_templateObject34 || (_templateObject34 = _taggedTemplateLiteral(["\n .", " {\n .", " {\n background-color: transparent;\n position: absolute;\n width: ", "px;\n height: 100%;\n top: 0;\n right: -", "px;\n cursor: col-resize;\n z-index: ", ";\n }\n\n ", "\n\n ", "\n\n table\n tr:first-of-type\n th.", "\n .", "::after,\n table\n tr:first-of-type\n td.", "\n .", "::after {\n top: -", "px;\n height: calc(100% + ", "px);\n }\n }\n"])), ClassName.TABLE_CONTAINER, ClassName.RESIZE_HANDLE_DECORATION, resizeHandlerAreaWidth, resizeHandlerAreaWidth / 2, resizeHandlerZIndex, getLastColumnResizerOverrides(), resizeHandleOverrides(props), ClassName.WITH_RESIZE_LINE, ClassName.RESIZE_HANDLE_DECORATION, ClassName.WITH_RESIZE_LINE, ClassName.RESIZE_HANDLE_DECORATION, tableToolbarSize + tableCellBorderWidth, tableToolbarSize + tableCellBorderWidth);
|
|
112
117
|
};
|
|
113
118
|
|
|
114
119
|
// Drag and Drop: drop target insert line
|
|
115
120
|
export var insertLine = function insertLine(props) {
|
|
116
|
-
return css(
|
|
121
|
+
return css(_templateObject35 || (_templateObject35 = _taggedTemplateLiteral(["\n .", " {\n td.", "::before {\n content: ' ';\n position: absolute;\n left: -1px;\n top: -1px;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n left: -1px;\n position: absolute;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -", "px;\n }\n\n td.", "::before {\n content: ' ';\n position: absolute;\n left: ", ";\n top: -1px;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n left: ", ";\n position: absolute;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -", "px;\n }\n\n td.", "::before {\n content: ' ';\n position: absolute;\n right: -1px;\n top: -1px;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n right: -1px;\n position: absolute;\n width: ", "px;\n height: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -", "px;\n }\n\n td.", "::before {\n content: ' ';\n position: absolute;\n left: ", ";\n top: -1px;\n height: ", "px;\n width: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n left: ", ";\n position: absolute;\n height: ", "px;\n width: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n top: -1px;\n }\n\n td.", "::before {\n content: ' ';\n position: absolute;\n left: ", ";\n bottom: 0;\n height: ", "px;\n width: calc(100% + 2px);\n background-color: ", ";\n z-index: ", ";\n }\n\n th.", "::before {\n content: ' ';\n left: ", ";\n bottom: 0;\n position: absolute;\n height: ", "px;\n width: calc(100% + ", "px);\n background-color: ", ";\n z-index: ", ";\n }\n }\n"])), ClassName.TABLE_CONTAINER, ClassName.WITH_FIRST_COLUMN_INSERT_LINE, insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_FIRST_COLUMN_INSERT_LINE, insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, tableCellBorderWidth, ClassName.WITH_COLUMN_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_COLUMN_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, tableCellBorderWidth, ClassName.WITH_LAST_COLUMN_INSERT_LINE, insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_LAST_COLUMN_INSERT_LINE, insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, tableCellBorderWidth, ClassName.WITH_ROW_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_ROW_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_LAST_ROW_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableBorderSelectedColor(props), columnControlsZIndex * 2, ClassName.WITH_LAST_ROW_INSERT_LINE, "var(--ds-space-negative-025, -2px)", insertLineWidth, tableCellBorderWidth * 2, tableBorderSelectedColor(props), columnControlsZIndex * 2);
|
|
117
122
|
};
|
|
@@ -18,6 +18,7 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
|
|
|
18
18
|
private intersectionObserver?;
|
|
19
19
|
private resizeObserver?;
|
|
20
20
|
private sentinels;
|
|
21
|
+
private sentinelData;
|
|
21
22
|
private stickyRowHeight?;
|
|
22
23
|
private listening;
|
|
23
24
|
private padding;
|
|
@@ -41,6 +42,8 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
|
|
|
41
42
|
private initObservers;
|
|
42
43
|
private createResizeObserver;
|
|
43
44
|
private createIntersectionObserver;
|
|
45
|
+
private refreshStickyState;
|
|
46
|
+
private isHeaderSticky;
|
|
44
47
|
private onTablePluginState;
|
|
45
48
|
private updateStickyHeaderWidth;
|
|
46
49
|
/**
|
|
@@ -18,6 +18,7 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
|
|
|
18
18
|
private intersectionObserver?;
|
|
19
19
|
private resizeObserver?;
|
|
20
20
|
private sentinels;
|
|
21
|
+
private sentinelData;
|
|
21
22
|
private stickyRowHeight?;
|
|
22
23
|
private listening;
|
|
23
24
|
private padding;
|
|
@@ -41,6 +42,8 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
|
|
|
41
42
|
private initObservers;
|
|
42
43
|
private createResizeObserver;
|
|
43
44
|
private createIntersectionObserver;
|
|
45
|
+
private refreshStickyState;
|
|
46
|
+
private isHeaderSticky;
|
|
44
47
|
private onTablePluginState;
|
|
45
48
|
private updateStickyHeaderWidth;
|
|
46
49
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-table",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"description": "Table plugin for the @atlaskit/editor",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@atlaskit/adf-schema": "^34.0.0",
|
|
31
31
|
"@atlaskit/custom-steps": "^0.0.4",
|
|
32
|
-
"@atlaskit/editor-common": "^76.
|
|
32
|
+
"@atlaskit/editor-common": "^76.23.0",
|
|
33
33
|
"@atlaskit/editor-palette": "1.5.2",
|
|
34
34
|
"@atlaskit/editor-plugin-analytics": "^0.3.0",
|
|
35
35
|
"@atlaskit/editor-plugin-content-insertion": "^0.1.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^0.12.0",
|
|
47
47
|
"@atlaskit/primitives": "^1.12.0",
|
|
48
48
|
"@atlaskit/theme": "^12.6.0",
|
|
49
|
-
"@atlaskit/tokens": "^1.
|
|
49
|
+
"@atlaskit/tokens": "^1.29.0",
|
|
50
50
|
"@atlaskit/tooltip": "^18.0.0",
|
|
51
51
|
"@babel/runtime": "^7.0.0",
|
|
52
52
|
"@emotion/react": "^11.7.1",
|
|
@@ -138,6 +138,9 @@
|
|
|
138
138
|
},
|
|
139
139
|
"platform.editor.table-update-colwidths-after-column-is-deleted": {
|
|
140
140
|
"type": "boolean"
|
|
141
|
+
},
|
|
142
|
+
"platform.editor.table.alternative-sticky-header-logic": {
|
|
143
|
+
"type": "boolean"
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
}
|
|
@@ -552,6 +552,15 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
552
552
|
|
|
553
553
|
const isNested = isTableNested(view.state, tablePos);
|
|
554
554
|
|
|
555
|
+
const topStickyShadowPosition = isDragAndDropEnabled
|
|
556
|
+
? this.state.stickyHeader &&
|
|
557
|
+
this.state.stickyHeader.top + this.state.stickyHeader.padding + 2
|
|
558
|
+
: this.state.stickyHeader &&
|
|
559
|
+
this.state.stickyHeader.top +
|
|
560
|
+
this.state.stickyHeader.padding +
|
|
561
|
+
shadowPadding +
|
|
562
|
+
2;
|
|
563
|
+
|
|
555
564
|
return (
|
|
556
565
|
<TableContainer
|
|
557
566
|
className={classnames(ClassName.TABLE_CONTAINER, {
|
|
@@ -605,12 +614,8 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
605
614
|
style={{
|
|
606
615
|
visibility:
|
|
607
616
|
showBeforeShadow && hasHeaderRow ? 'visible' : 'hidden',
|
|
608
|
-
top: `${
|
|
609
|
-
|
|
610
|
-
this.state.stickyHeader.padding +
|
|
611
|
-
shadowPadding +
|
|
612
|
-
2
|
|
613
|
-
}px`,
|
|
617
|
+
top: `${topStickyShadowPosition}px`,
|
|
618
|
+
paddingBottom: `${isDragAndDropEnabled ? '1px' : ''}`,
|
|
614
619
|
}}
|
|
615
620
|
/>
|
|
616
621
|
)}
|
|
@@ -670,12 +675,8 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
670
675
|
style={{
|
|
671
676
|
visibility:
|
|
672
677
|
showAfterShadow && hasHeaderRow ? 'visible' : 'hidden',
|
|
673
|
-
top: `${
|
|
674
|
-
|
|
675
|
-
this.state.stickyHeader.padding +
|
|
676
|
-
shadowPadding +
|
|
677
|
-
2
|
|
678
|
-
}px`,
|
|
678
|
+
top: `${topStickyShadowPosition}px`,
|
|
679
|
+
paddingBottom: `${isDragAndDropEnabled ? '1px' : ''}`,
|
|
679
680
|
}}
|
|
680
681
|
/>
|
|
681
682
|
</div>
|
|
@@ -6,6 +6,7 @@ import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
|
|
|
6
6
|
import { browser } from '@atlaskit/editor-common/utils';
|
|
7
7
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
8
8
|
import type { EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
|
|
9
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
9
10
|
|
|
10
11
|
import { getPluginState } from '../pm-plugins/plugin-factory';
|
|
11
12
|
import { pluginKey as tablePluginKey } from '../pm-plugins/plugin-key';
|
|
@@ -29,6 +30,12 @@ import { supportedHeaderRow } from '../utils/nodes';
|
|
|
29
30
|
|
|
30
31
|
import TableNodeView from './TableNodeViewBase';
|
|
31
32
|
|
|
33
|
+
interface SentinelData {
|
|
34
|
+
isIntersecting: boolean;
|
|
35
|
+
boundingClientRect: DOMRectReadOnly | null;
|
|
36
|
+
rootBounds: DOMRectReadOnly | null;
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
// limit scroll event calls
|
|
33
40
|
const HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200;
|
|
34
41
|
|
|
@@ -80,6 +87,21 @@ export default class TableRow
|
|
|
80
87
|
top?: HTMLElement | null;
|
|
81
88
|
bottom?: HTMLElement | null;
|
|
82
89
|
} = {};
|
|
90
|
+
private sentinelData: {
|
|
91
|
+
top: SentinelData;
|
|
92
|
+
bottom: SentinelData;
|
|
93
|
+
} = {
|
|
94
|
+
top: {
|
|
95
|
+
isIntersecting: false,
|
|
96
|
+
boundingClientRect: null,
|
|
97
|
+
rootBounds: null,
|
|
98
|
+
},
|
|
99
|
+
bottom: {
|
|
100
|
+
isIntersecting: false,
|
|
101
|
+
boundingClientRect: null,
|
|
102
|
+
rootBounds: null,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
83
105
|
private stickyRowHeight?: number;
|
|
84
106
|
private listening = false;
|
|
85
107
|
private padding: number = 0;
|
|
@@ -327,71 +349,196 @@ export default class TableRow
|
|
|
327
349
|
}
|
|
328
350
|
|
|
329
351
|
private createIntersectionObserver() {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
352
|
+
if (getBooleanFF('platform.editor.table.alternative-sticky-header-logic')) {
|
|
353
|
+
this.intersectionObserver = new IntersectionObserver(
|
|
354
|
+
(entries: IntersectionObserverEntry[], _: IntersectionObserver) => {
|
|
355
|
+
// IMPORTANT: please try and avoid using entry.rootBounds it's terribly inconsistent. For example; sometimes it may return
|
|
356
|
+
// 0 height. In safari it will multiply all values by the window scale factor, however chrome & firfox won't.
|
|
357
|
+
// This is why i just get the scroll view bounding rect here and use it, and fallback to the entry.rootBounds if needed.
|
|
358
|
+
const rootBounds = (
|
|
359
|
+
this.editorScrollableElement as Element
|
|
360
|
+
)?.getBoundingClientRect?.();
|
|
361
|
+
|
|
362
|
+
entries.forEach((entry) => {
|
|
363
|
+
const { target, isIntersecting, boundingClientRect } = entry;
|
|
364
|
+
// This observer only every looks at the top/bottom sentinels, we can assume if it's not one then it's the other.
|
|
365
|
+
const targetKey = target.classList.contains(
|
|
366
|
+
ClassName.TABLE_STICKY_SENTINEL_TOP,
|
|
367
|
+
)
|
|
368
|
+
? 'top'
|
|
369
|
+
: 'bottom';
|
|
370
|
+
// Cache the latest sentinel information
|
|
371
|
+
this.sentinelData[targetKey] = {
|
|
372
|
+
isIntersecting,
|
|
373
|
+
boundingClientRect,
|
|
374
|
+
rootBounds: rootBounds ?? entry.rootBounds,
|
|
375
|
+
};
|
|
376
|
+
// Keep the other sentinels rootBounds in sync with this latest one
|
|
377
|
+
this.sentinelData[
|
|
378
|
+
targetKey === 'top' ? 'bottom' : targetKey
|
|
379
|
+
].rootBounds = rootBounds ?? entry.rootBounds;
|
|
380
|
+
});
|
|
381
|
+
this.refreshStickyState();
|
|
382
|
+
},
|
|
383
|
+
{ threshold: 0, root: this.editorScrollableElement as Element },
|
|
384
|
+
);
|
|
385
|
+
} else {
|
|
386
|
+
this.intersectionObserver = new IntersectionObserver(
|
|
387
|
+
(entries: IntersectionObserverEntry[], _: IntersectionObserver) => {
|
|
388
|
+
const tree = getTree(this.dom);
|
|
389
|
+
if (!tree) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const { table } = tree;
|
|
346
393
|
|
|
347
|
-
|
|
348
|
-
|
|
394
|
+
if (table.rows.length < 2) {
|
|
395
|
+
// ED-19307 - When there's only one row in a table the top & bottom sentinels become inverted. This creates some nasty visiblity
|
|
396
|
+
// toggling side-effects because the intersection observers gets confused.
|
|
349
397
|
return;
|
|
350
398
|
}
|
|
351
399
|
|
|
352
|
-
|
|
353
|
-
const
|
|
354
|
-
(entry.rootBounds?.bottom || 0) < entry.boundingClientRect.bottom;
|
|
400
|
+
entries.forEach((entry) => {
|
|
401
|
+
const target = entry.target as HTMLElement;
|
|
355
402
|
|
|
356
|
-
if
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
} else {
|
|
360
|
-
table && this.makeRowHeaderNotSticky(table);
|
|
403
|
+
// if the rootBounds has 0 height, e.g. confluence preview mode, we do nothing.
|
|
404
|
+
if (entry.rootBounds?.height === 0) {
|
|
405
|
+
return;
|
|
361
406
|
}
|
|
362
|
-
}
|
|
363
407
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
408
|
+
if (
|
|
409
|
+
target.classList.contains(ClassName.TABLE_STICKY_SENTINEL_TOP)
|
|
410
|
+
) {
|
|
411
|
+
const sentinelIsBelowScrollArea =
|
|
412
|
+
(entry.rootBounds?.bottom || 0) <
|
|
413
|
+
entry.boundingClientRect.bottom;
|
|
414
|
+
|
|
415
|
+
if (!entry.isIntersecting && !sentinelIsBelowScrollArea) {
|
|
416
|
+
tree && this.makeHeaderRowSticky(tree, entry.rootBounds?.top);
|
|
417
|
+
this.lastStickyTimestamp = Date.now();
|
|
418
|
+
} else {
|
|
419
|
+
table && this.makeRowHeaderNotSticky(table);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (
|
|
424
|
+
target.classList.contains(ClassName.TABLE_STICKY_SENTINEL_BOTTOM)
|
|
425
|
+
) {
|
|
426
|
+
const sentinelIsAboveScrollArea =
|
|
427
|
+
entry.boundingClientRect.top - this.dom.offsetHeight <
|
|
428
|
+
(entry.rootBounds?.top || 0);
|
|
429
|
+
|
|
430
|
+
if (table && !entry.isIntersecting && sentinelIsAboveScrollArea) {
|
|
431
|
+
// Not a perfect solution, but need to this code specific for FireFox ED-19177
|
|
432
|
+
if (browser.gecko) {
|
|
433
|
+
if (
|
|
434
|
+
this.lastStickyTimestamp &&
|
|
435
|
+
Date.now() - this.lastStickyTimestamp >
|
|
436
|
+
STICKY_HEADER_TOGGLE_TOLERANCE_MS
|
|
437
|
+
) {
|
|
438
|
+
this.makeRowHeaderNotSticky(table);
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
379
441
|
this.makeRowHeaderNotSticky(table);
|
|
380
442
|
}
|
|
381
|
-
} else {
|
|
382
|
-
this.
|
|
443
|
+
} else if (entry.isIntersecting && sentinelIsAboveScrollArea) {
|
|
444
|
+
tree && this.makeHeaderRowSticky(tree, entry?.rootBounds?.top);
|
|
445
|
+
this.lastStickyTimestamp = Date.now();
|
|
383
446
|
}
|
|
384
|
-
} else if (entry.isIntersecting && sentinelIsAboveScrollArea) {
|
|
385
|
-
tree && this.makeHeaderRowSticky(tree, entry?.rootBounds?.top);
|
|
386
|
-
this.lastStickyTimestamp = Date.now();
|
|
387
447
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
448
|
+
return;
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
{ root: this.editorScrollableElement as Element },
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
private refreshStickyState() {
|
|
457
|
+
const tree = getTree(this.dom);
|
|
458
|
+
if (!tree) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const { table } = tree;
|
|
462
|
+
const shouldStick = this.isHeaderSticky();
|
|
463
|
+
if (this.isSticky !== shouldStick) {
|
|
464
|
+
if (shouldStick) {
|
|
465
|
+
// The rootRect is kept in sync across sentinels so it doesn't matter which one we use.
|
|
466
|
+
const rootRect =
|
|
467
|
+
this.sentinelData.top.rootBounds ??
|
|
468
|
+
this.sentinelData.bottom.rootBounds;
|
|
469
|
+
this.makeHeaderRowSticky(tree, rootRect?.top);
|
|
470
|
+
} else {
|
|
471
|
+
this.makeRowHeaderNotSticky(table);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private isHeaderSticky() {
|
|
477
|
+
/*
|
|
478
|
+
# Overview
|
|
479
|
+
I'm going to list all the view states associated with the sentinels and when they should trigger sticky headers.
|
|
480
|
+
The format of the states are; {top|bottom}:{in|above|below}
|
|
481
|
+
ie sentinel:view-position -- both "above" and "below" are equal to out of the viewport
|
|
482
|
+
|
|
483
|
+
For example; "top:in" means top sentinel is within the viewport. "bottom:above" means the bottom sentinel is
|
|
484
|
+
above and out of the viewport
|
|
485
|
+
|
|
486
|
+
This will hopefully simplify things and make it easier to determine when sticky should/shouldn't be triggered.
|
|
487
|
+
|
|
488
|
+
# States
|
|
489
|
+
top:in / bottom:in - NOT sticky
|
|
490
|
+
top:in / bottom:above - NOT sticky - NOTE: This is an inversion clause
|
|
491
|
+
top:in / bottom:below - NOT sticky
|
|
492
|
+
top:above / bottom:in - STICKY
|
|
493
|
+
top:above / bottom:above - NOT sticky
|
|
494
|
+
top:above / bottom:below - STICKY
|
|
495
|
+
top:below / bottom:in - NOT sticky - NOTE: This is an inversion clause
|
|
496
|
+
top:below / bottom:above - NOT sticky - NOTE: This is an inversion clause
|
|
497
|
+
top:below / bottom:below - NOT sticky
|
|
498
|
+
|
|
499
|
+
# Summary
|
|
500
|
+
The only time the header should be sticky is when the top sentinel is above the view and the bottom sentinel
|
|
501
|
+
is in or below it.
|
|
502
|
+
*/
|
|
503
|
+
|
|
504
|
+
const { top: sentinelTop, bottom: sentinelBottom } = this.sentinelData;
|
|
505
|
+
// The rootRect is kept in sync across sentinels so it doesn't matter which one we use.
|
|
506
|
+
const rootBounds = sentinelTop.rootBounds ?? sentinelBottom.rootBounds;
|
|
507
|
+
|
|
508
|
+
if (
|
|
509
|
+
!rootBounds ||
|
|
510
|
+
!sentinelTop.boundingClientRect ||
|
|
511
|
+
!sentinelBottom.boundingClientRect
|
|
512
|
+
) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Normalize the sentinels to y points
|
|
517
|
+
// Since the sentinels are actually rects 1px high we want make sure we normalise the inner most values closest to the table.
|
|
518
|
+
const sentinelTopY = sentinelTop.boundingClientRect.bottom;
|
|
519
|
+
const sentinelBottomY = sentinelBottom.boundingClientRect.top;
|
|
520
|
+
|
|
521
|
+
// If header row height is more than 50% of viewport height don't do this
|
|
522
|
+
const isRowHeaderTooLarge =
|
|
523
|
+
this.stickyRowHeight && this.stickyRowHeight > window.innerHeight * 0.5;
|
|
524
|
+
|
|
525
|
+
const isTopSentinelAboveScrollArea =
|
|
526
|
+
!sentinelTop.isIntersecting && sentinelTopY <= rootBounds.top;
|
|
527
|
+
|
|
528
|
+
const isBottomSentinelInOrBelowScrollArea =
|
|
529
|
+
sentinelBottom.isIntersecting || sentinelBottomY > rootBounds.bottom;
|
|
530
|
+
|
|
531
|
+
// This makes sure that the top sentinel is actually above the bottom sentinel, and that they havn't inverted.
|
|
532
|
+
const isTopSentinelAboveBottomSentinel = sentinelTopY < sentinelBottomY;
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
isTopSentinelAboveScrollArea &&
|
|
536
|
+
isBottomSentinelInOrBelowScrollArea &&
|
|
537
|
+
isTopSentinelAboveBottomSentinel &&
|
|
538
|
+
!isRowHeaderTooLarge
|
|
393
539
|
);
|
|
394
540
|
}
|
|
541
|
+
|
|
395
542
|
/* receive external events */
|
|
396
543
|
|
|
397
544
|
private onTablePluginState(state: TablePluginState) {
|