diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index 4423bfc38..7fac56d8d 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -72,6 +72,10 @@ opacity: 0; display: flex; + &[draggable=true] { + cursor: grab; + } + svg { height: 25px; } @@ -90,6 +94,10 @@ cursor: pointer; } + &__body { + float: left; + } + &__row { display: flex; border-bottom: 1px solid var(--b3-theme-surface-lighter); @@ -113,6 +121,10 @@ .av__gutters { opacity: 1; } + + .av__firstcol svg { + opacity: 1; + } } &--select { @@ -136,11 +148,23 @@ } } + &--add { + .av__firstcol svg { + opacity: 1; + } + + &:hover { + background-color: var(--b3-list-icon-hover); + } + } + &--header, &--footer { background-color: var(--b3-theme-background); + position: relative; } + &--add, &--footer { display: flex; border-top: 1px solid var(--b3-theme-surface-lighter); @@ -184,27 +208,6 @@ } } } - - &--add { - color: var(--b3-theme-on-surface); - padding: 5px 5px 5px 7px; - display: flex; - align-items: center; - transition: background 20ms ease-in 0s; - font-size: 87.5%; - - svg { - height: 12px; - width: 12px; - color: var(--b3-theme-on-surface); - margin-right: 5px; - flex-shrink: 0; - } - - &:hover { - background-color: var(--b3-list-icon-hover); - } - } } &__cell { @@ -234,6 +237,13 @@ border-radius: var(--b3-border-radius); } + &--add { + position: sticky; + left: 25px; + font-size: 87.5%; + padding: 0 0.5em; + } + .block__icon { position: absolute; right: 5px; @@ -265,6 +275,7 @@ &__celltext { overflow: hidden; + line-height: normal; .b3-chip { margin: 1px 2px; @@ -283,6 +294,14 @@ } &__firstcol { + background-color: var(--b3-theme-background); + border-right: 1px solid var(--b3-theme-surface-lighter); + + position: sticky; + left: 0; + width: 24px; + z-index: 1; + svg { color: var(--b3-theme-on-surface); height: 33px; @@ -292,10 +311,6 @@ box-sizing: border-box; float: left; } - - &:hover svg { - opacity: 1; - } } &__widthdrag { @@ -380,6 +395,7 @@ .protyle-wysiwyg--select, .protyle-wysiwyg--hl { .av__row--header, + .av__firstcol, .av__row--footer { background-color: transparent; } diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index a8daeba91..7538fc8dd 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -32,7 +32,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle if (event.shiftKey) { const rowElement = hasClosestByClassName(event.target, "av__row"); if (rowElement && !rowElement.classList.contains("av__row--header")) { - selectRow(rowElement.querySelector(".av__firstcol"), "toggle"); + selectRow(rowElement.querySelector(".av__check"), "toggle"); return true; } } @@ -63,8 +63,8 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle return true; } - const gutterElement = hasClosestByClassName(event.target, "ariaLabel"); - if (gutterElement && gutterElement.parentElement.classList.contains("av__gutters")) { + const gutterElement = hasClosestByClassName(event.target, "av__gutter"); + if (gutterElement) { const rowElement = gutterElement.parentElement.parentElement; if (gutterElement.dataset.action === "add") { const avID = blockElement.getAttribute("data-av-id"); @@ -97,7 +97,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle return true; } - const checkElement = hasClosestByClassName(event.target, "av__firstcol"); + const checkElement = hasClosestByClassName(event.target, "av__check"); if (checkElement) { window.siyuan.menus.menu.remove(); selectRow(checkElement, "toggle"); @@ -199,10 +199,10 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) { const type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol; if (type === "updated" || type === "created" || (type === "block" && !cellElement.getAttribute("data-detached"))) { - selectRow(cellElement.parentElement.querySelector(".av__firstcol"), "toggle"); + selectRow(cellElement.parentElement.querySelector(".av__check"), "toggle"); } else { cellElement.parentElement.parentElement.querySelectorAll(".av__row--select").forEach(item => { - item.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck"); + item.querySelector(".av__check use").setAttribute("xlink:href", "#iconUncheck"); item.classList.remove("av__row--select"); }); updateHeader(cellElement.parentElement); @@ -259,7 +259,7 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi blockElement.querySelectorAll(".av__row--select").forEach(item => { item.classList.remove("av__row--select"); }); - blockElement.querySelectorAll(".av__firstcol use").forEach(item => { + blockElement.querySelectorAll(".av__check use").forEach(item => { item.setAttribute("xlink:href", "#iconUncheck"); }); } @@ -269,7 +269,7 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi return true; } rowElement.classList.add("av__row--select"); - rowElement.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconCheck"); + rowElement.querySelector(".av__check use").setAttribute("xlink:href", "#iconCheck"); const rowIds: string[] = []; const blockIds: string[] = []; const rowElements = blockElement.querySelectorAll(".av__row--select:not(.av__row--header)"); diff --git a/app/src/protyle/render/av/keydown.ts b/app/src/protyle/render/av/keydown.ts index 2557737ff..9a87a06e1 100644 --- a/app/src/protyle/render/av/keydown.ts +++ b/app/src/protyle/render/av/keydown.ts @@ -19,7 +19,7 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl if (selectCellElement) { if (event.key === "Escape") { selectCellElement.classList.remove("av__cell--select"); - selectRow(selectCellElement.parentElement.querySelector(".av__firstcol"), "select"); + selectRow(selectCellElement.parentElement.querySelector(".av__check"), "select"); event.preventDefault(); return true; } @@ -100,11 +100,11 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl } if (event.key === "Escape") { event.preventDefault(); - selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll"); + selectRow(selectRowElements[0].querySelector(".av__check"), "unselectAll"); return true; } if (event.key === "Enter") { - selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll"); + selectRow(selectRowElements[0].querySelector(".av__check"), "unselectAll"); popTextCell(protyle, [selectRowElements[0].querySelector(".av__cell")]); event.preventDefault(); return true; @@ -112,9 +112,9 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl // TODO event.shiftKey if (event.key === "ArrowUp") { const previousRowElement = selectRowElements[0].previousElementSibling; - selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll"); + selectRow(selectRowElements[0].querySelector(".av__check"), "unselectAll"); if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) { - selectRow(previousRowElement.querySelector(".av__firstcol"), "select"); + selectRow(previousRowElement.querySelector(".av__check"), "select"); cellScrollIntoView(nodeElement, previousRowElement.getBoundingClientRect(), true); } else { nodeElement.classList.add("protyle-wysiwyg--select"); @@ -124,9 +124,9 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl } if (event.key === "ArrowDown") { const nextRowElement = selectRowElements[selectRowElements.length - 1].nextElementSibling; - selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll"); + selectRow(selectRowElements[0].querySelector(".av__check"), "unselectAll"); if (nextRowElement && !nextRowElement.classList.contains("av__row--add")) { - selectRow(nextRowElement.querySelector(".av__firstcol"), "select"); + selectRow(nextRowElement.querySelector(".av__check"), "select"); cellScrollIntoView(nodeElement, nextRowElement.getBoundingClientRect(), true); } else { nodeElement.classList.add("protyle-wysiwyg--select"); @@ -137,4 +137,3 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl } return false; }; - diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index 4e3732464..903baac11 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -6,6 +6,7 @@ import * as dayjs from "dayjs"; import {unicode2Emoji} from "../../../emoji"; import {focusBlock} from "../../util/selection"; import {isMac} from "../../util/compatibility"; +import {stickyScrollY} from "../../scroll/stickyScroll"; export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => { let avElements: Element[] = []; @@ -40,8 +41,6 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) = e.firstElementChild.innerHTML = html; } const left = e.querySelector(".av__scroll")?.scrollLeft || 0; - const headerTransform = (e.querySelector(".av__row--header") as HTMLElement)?.style.transform; - const footerTransform = (e.querySelector(".av__row--footer") as HTMLElement)?.style.transform; let selectCellId = ""; const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement; if (selectCellElement) { @@ -52,7 +51,7 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) = }, (response) => { const data = response.data.view as IAVTable; // header - let tableHTML = '