Table improvements (#6958)
* Header toggling, resizable columns * Allow all blocks in table cells, disable column resizing in read-only * Fixed dynamic scroll shadows * Refactor, scroll styling * fix scrolling, tweaks * fix: Table layout lost on sort * fix: Caching of grip decorators * refactor * stash * fix first render shadows * stash * First add column grip, styles * Just add column/row click handlers left * fix: isTableSelected for single cell table * Refactor mousedown handlers * fix: 'Add row before' command missing on first row * fix overflow on rhs * fix: Error clicking column grip when menu is open * Hide table controls when printing * Restore table header background * fix: Header behavior when adding columns and rows at the edges * Tweak header styling * fix: Serialize and parsing of column attributes when copy/pasting fix: Column width is lost when changing column alignment
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-irregular-whitespace */
|
||||
import { lighten, transparentize } from "polished";
|
||||
import styled, { DefaultTheme, css, keyframes } from "styled-components";
|
||||
import { EditorStyleHelper } from "../styles/EditorStyleHelper";
|
||||
import { videoStyle } from "./Video";
|
||||
|
||||
export type Props = {
|
||||
@@ -13,6 +14,11 @@ export type Props = {
|
||||
theme: DefaultTheme;
|
||||
};
|
||||
|
||||
export const fadeIn = keyframes`
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
`;
|
||||
|
||||
export const pulse = keyframes`
|
||||
0% { box-shadow: 0 0 0 1px rgba(255, 213, 0, 0.75) }
|
||||
50% { box-shadow: 0 0 0 4px rgba(255, 213, 0, 0.75) }
|
||||
@@ -267,7 +273,7 @@ const emailStyle = (props: Props) => css`
|
||||
}
|
||||
`;
|
||||
|
||||
const style = (props: Props) => `
|
||||
const style = (props: Props) => css`
|
||||
flex-grow: ${props.grow ? 1 : 0};
|
||||
justify-content: start;
|
||||
color: ${props.theme.text};
|
||||
@@ -563,6 +569,40 @@ iframe.embed {
|
||||
}
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableFullWidth} {
|
||||
transform: translateX(calc(50% + ${
|
||||
EditorStyleHelper.padding
|
||||
}px + var(--container-width) * -0.5));
|
||||
|
||||
.${EditorStyleHelper.tableScrollable},
|
||||
table {
|
||||
width: calc(var(--container-width) - ${EditorStyleHelper.padding * 2}px);
|
||||
}
|
||||
|
||||
&.${EditorStyleHelper.tableShadowRight}::after {
|
||||
left: calc(var(--container-width) - ${EditorStyleHelper.padding * 3}px);
|
||||
}
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
animation: ${fadeIn} 150ms ease-in-out;
|
||||
${props.readOnly ? "display: none;" : ""}
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: 0;
|
||||
bottom: -1px;
|
||||
width: 2px;
|
||||
z-index: 20;
|
||||
background-color: ${props.theme.text};
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.resize-cursor {
|
||||
${props.readOnly ? "pointer-events: none;" : ""}
|
||||
cursor: ew-resize;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.ProseMirror-hideselection *::selection {
|
||||
background: transparent;
|
||||
}
|
||||
@@ -1284,26 +1324,25 @@ table {
|
||||
|
||||
tr {
|
||||
position: relative;
|
||||
border-bottom: 1px solid ${props.theme.tableDivider};
|
||||
}
|
||||
|
||||
tr:first-of-type {
|
||||
background: ${props.theme.secondaryBackground};
|
||||
}
|
||||
|
||||
th {
|
||||
background: transparent;
|
||||
border-bottom: 1px solid ${props.theme.divider};
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
border: 1px solid ${props.theme.tableDivider};
|
||||
border: 1px solid ${props.theme.divider};
|
||||
position: relative;
|
||||
padding: 4px 8px;
|
||||
text-align: ${props.rtl ? "right" : "left"};
|
||||
min-width: 100px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
th {
|
||||
background: ${transparentize(0.75, props.theme.divider)};
|
||||
color: ${props.theme.textSecondary};
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
td .component-embed {
|
||||
@@ -1320,7 +1359,135 @@ table {
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.grip-column {
|
||||
.${EditorStyleHelper.tableAddRow},
|
||||
.${EditorStyleHelper.tableAddColumn},
|
||||
.${EditorStyleHelper.tableGrip},
|
||||
.${EditorStyleHelper.tableGripColumn},
|
||||
.${EditorStyleHelper.tableGripRow} {
|
||||
@media print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableAddRow},
|
||||
.${EditorStyleHelper.tableAddColumn} {
|
||||
display: block;
|
||||
position: absolute;
|
||||
background: ${props.theme.accent};
|
||||
cursor: var(--pointer);
|
||||
|
||||
&:hover::after {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
z-index: 20;
|
||||
background-color: ${props.theme.accent};
|
||||
background-size: 16px 16px;
|
||||
background-position: 50% 50%;
|
||||
background-image: url("data:image/svg+xml;base64,${btoa(
|
||||
'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 5C11.4477 5 11 5.44772 11 6V11H6C5.44772 11 5 11.4477 5 12C5 12.5523 5.44772 13 6 13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V13H18C18.5523 13 19 12.5523 19 12C19 11.4477 18.5523 11 18 11H13V6C13 5.44772 12.5523 5 12 5Z" fill="white"/></svg>'
|
||||
)}")
|
||||
}
|
||||
|
||||
// extra clickable area
|
||||
&::before {
|
||||
content: "";
|
||||
display: block;
|
||||
cursor: var(--pointer);
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableAddRow} {
|
||||
bottom: -1px;
|
||||
left: -16px;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: -10px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
display: ${props.readOnly ? "none" : "block"};
|
||||
border-radius: 100%;
|
||||
background-color: ${props.theme.divider};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
width: calc(var(--table-width) - ${EditorStyleHelper.padding * 1.5}px);
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
bottom: -7.5px;
|
||||
left: -16px;
|
||||
}
|
||||
|
||||
// extra clickable area
|
||||
&::before {
|
||||
bottom: -12px;
|
||||
left: -18px;
|
||||
}
|
||||
|
||||
&.first {
|
||||
bottom: auto;
|
||||
top: -1px;
|
||||
|
||||
&::before {
|
||||
bottom: auto;
|
||||
top: -12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableAddColumn} {
|
||||
top: -16px;
|
||||
right: -1px;
|
||||
width: 2px;
|
||||
height: 0;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: -1px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
display: ${props.readOnly ? "none" : "block"};
|
||||
border-radius: 100%;
|
||||
background-color: ${props.theme.divider};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
height: calc(var(--table-height) - ${EditorStyleHelper.padding}px + 6px);
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
top: -16px;
|
||||
right: -7px;
|
||||
}
|
||||
|
||||
// extra clickable area
|
||||
&::before {
|
||||
top: -16px;
|
||||
right: -12px;
|
||||
}
|
||||
|
||||
&.first {
|
||||
right: auto;
|
||||
left: -1px;
|
||||
|
||||
&::before {
|
||||
right: auto;
|
||||
left: -12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableGripColumn} {
|
||||
/* usage of ::after for all of the table grips works around a bug in
|
||||
* prosemirror-tables that causes Safari to hang when selecting a cell
|
||||
* in an empty table:
|
||||
@@ -1333,8 +1500,7 @@ table {
|
||||
${props.rtl ? "right" : "left"}: 0;
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background: ${props.theme.tableDivider};
|
||||
border-bottom: 3px solid ${props.theme.background};
|
||||
background: ${props.theme.divider};
|
||||
display: ${props.readOnly ? "none" : "block"};
|
||||
}
|
||||
|
||||
@@ -1343,16 +1509,18 @@ table {
|
||||
}
|
||||
&.first::after {
|
||||
border-top-${props.rtl ? "right" : "left"}-radius: 3px;
|
||||
border-bottom-${props.rtl ? "right" : "left"}-radius: 3px;
|
||||
}
|
||||
&.last::after {
|
||||
border-top-${props.rtl ? "left" : "right"}-radius: 3px;
|
||||
border-bottom-${props.rtl ? "left" : "right"}-radius: 3px;
|
||||
}
|
||||
&.selected::after {
|
||||
background: ${props.theme.tableSelected};
|
||||
}
|
||||
}
|
||||
|
||||
.grip-row {
|
||||
.${EditorStyleHelper.tableGripRow} {
|
||||
&::after {
|
||||
content: "";
|
||||
cursor: var(--pointer);
|
||||
@@ -1361,8 +1529,7 @@ table {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 12px;
|
||||
background: ${props.theme.tableDivider};
|
||||
border-${props.rtl ? "left" : "right"}: 3px solid;
|
||||
background: ${props.theme.divider};
|
||||
border-color: ${props.theme.background};
|
||||
display: ${props.readOnly ? "none" : "block"};
|
||||
}
|
||||
@@ -1371,21 +1538,23 @@ table {
|
||||
background: ${props.theme.text};
|
||||
}
|
||||
&.first::after {
|
||||
border-top-${props.rtl ? "right" : "left"}-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
&.last::after {
|
||||
border-bottom-${props.rtl ? "right" : "left"}-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
&.selected::after {
|
||||
background: ${props.theme.tableSelected};
|
||||
}
|
||||
}
|
||||
|
||||
.grip-table {
|
||||
.${EditorStyleHelper.tableGrip} {
|
||||
&::after {
|
||||
content: "";
|
||||
cursor: var(--pointer);
|
||||
background: ${props.theme.tableDivider};
|
||||
background: ${props.theme.divider};
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 13px;
|
||||
@@ -1394,6 +1563,7 @@ table {
|
||||
top: -18px;
|
||||
${props.rtl ? "right" : "left"}: -18px;
|
||||
display: ${props.readOnly ? "none" : "block"};
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
@@ -1405,11 +1575,22 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
.scrollable-wrapper {
|
||||
.${EditorStyleHelper.table} {
|
||||
position: relative;
|
||||
margin: 0.5em 0px;
|
||||
}
|
||||
|
||||
.${EditorStyleHelper.tableScrollable} {
|
||||
position: relative;
|
||||
margin: -1em ${-EditorStyleHelper.padding}px -0.5em;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: transparent transparent;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
padding-top: 1em;
|
||||
padding-bottom: .5em;
|
||||
padding-left: ${EditorStyleHelper.padding}px;
|
||||
padding-right: ${EditorStyleHelper.padding}px;
|
||||
transition: border 250ms ease-in-out 0s;
|
||||
|
||||
&:hover {
|
||||
scrollbar-color: ${props.theme.scrollbarThumb} ${
|
||||
@@ -1438,39 +1619,36 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
padding-${props.rtl ? "right" : "left"}: 1em;
|
||||
margin-${props.rtl ? "right" : "left"}: -1em;
|
||||
transition: border 250ms ease-in-out 0s;
|
||||
}
|
||||
|
||||
.scrollable-shadow {
|
||||
.${EditorStyleHelper.tableShadowLeft}::before,
|
||||
.${EditorStyleHelper.tableShadowRight}::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
top: 1px;
|
||||
bottom: 0;
|
||||
${props.rtl ? "right" : "left"}: -1em;
|
||||
width: 32px;
|
||||
z-index: 1;
|
||||
z-index: 20;
|
||||
transition: box-shadow 250ms ease-in-out;
|
||||
border: 0px solid transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.left {
|
||||
box-shadow: 16px 0 16px -16px inset rgba(0, 0, 0, ${
|
||||
props.theme.isDark ? 1 : 0.25
|
||||
});
|
||||
border-left: 1em solid ${props.theme.background};
|
||||
}
|
||||
.${EditorStyleHelper.tableShadowLeft}::before {
|
||||
left: -${EditorStyleHelper.padding}px;
|
||||
right: auto;
|
||||
box-shadow: 16px 0 16px -16px inset rgba(0, 0, 0, ${
|
||||
props.theme.isDark ? 1 : 0.25
|
||||
});
|
||||
border-left: ${EditorStyleHelper.padding}px solid ${props.theme.background};
|
||||
}
|
||||
|
||||
&.right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
box-shadow: -16px 0 16px -16px inset rgba(0, 0, 0, ${
|
||||
props.theme.isDark ? 1 : 0.25
|
||||
});
|
||||
}
|
||||
.${EditorStyleHelper.tableShadowRight}::after {
|
||||
right: -${EditorStyleHelper.padding}px;
|
||||
left: auto;
|
||||
box-shadow: -16px 0 16px -16px inset rgba(0, 0, 0, ${
|
||||
props.theme.isDark ? 1 : 0.25
|
||||
});
|
||||
border-right: ${EditorStyleHelper.padding}px solid ${props.theme.background};
|
||||
}
|
||||
|
||||
.block-menu-trigger {
|
||||
|
||||
Reference in New Issue
Block a user