diff --git a/app/src/assets/scss/component/_menu.scss b/app/src/assets/scss/component/_menu.scss index 10380fcaf..35fc29e38 100644 --- a/app/src/assets/scss/component/_menu.scss +++ b/app/src/assets/scss/component/_menu.scss @@ -284,6 +284,18 @@ } } + &__checked { + width: 22px; + height: 22px; + align-self: center; + margin-left: 8px; + color: var(--b3-theme-on-surface-light); + border-radius: var(--b3-border-radius); + padding: 4px; + box-sizing: border-box; + translate: var(--b3-transition); + } + &__separator { background-color: var(--b3-theme-surface-lighter); height: 1px; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index b11fc064f..988217250 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -32,6 +32,7 @@ import {updateCellsValue} from "./cell"; import {openCalcMenu} from "./calc"; import * as dayjs from "dayjs"; import {confirmDialog} from "../../../dialog/confirmDialog"; +import {escapeAttr} from "../../../util/escape"; export const openMenuPanel = (options: { protyle: IProtyle, @@ -1074,7 +1075,11 @@ export const openMenuPanel = (options: { event.stopPropagation(); break; } else if (type === "addColOptionOrCell") { - addColOptionOrCell(options.protyle, data, options.cellElements, target, menuElement, options.blockElement); + if (target.querySelector(".b3-menu__checked")) { + removeCellOption(options.protyle, data, options.cellElements, menuElement.querySelector(`.b3-chips .b3-chip[data-content="${escapeAttr(target.dataset.name)}"]`), options.blockElement); + } else { + addColOptionOrCell(options.protyle, data, options.cellElements, target, menuElement, options.blockElement); + } window.siyuan.menus.menu.remove(); event.preventDefault(); event.stopPropagation(); diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index d4fe699f8..d8c92133e 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -9,15 +9,21 @@ import {genAVValueHTML} from "./blockAttr"; import {escapeAttr} from "../../../util/escape"; import {genCellValueByElement, getTypeByCellElement} from "./cell"; -const filterSelectHTML = (key: string, options: { name: string, color: string }[]) => { +const filterSelectHTML = (key: string, options: { name: string, color: string }[], selected: string[] = []) => { let html = ""; let hasMatch = false; + if (selected.length === 0) { + document.querySelectorAll(".av__panel .b3-chips .b3-chip").forEach((item: HTMLElement) => { + selected.push(item.dataset.content); + }); + } + const checkedName = document.querySelector('.av__panel .b3-menu__item--current[data-type="addColOptionOrCell"]')?.getAttribute("data-name") || "" if (options) { options.forEach(item => { if (!key || (key.toLowerCase().indexOf(item.name.toLowerCase()) > -1 || item.name.toLowerCase().indexOf(key.toLowerCase()) > -1)) { - html += ``; } if (key === item.name) { @@ -33,6 +40,7 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[ }); } if (!hasMatch && key) { + html = html.replace('class="b3-menu__item b3-menu__item--current"', 'class="b3-menu__item"'); const colorIndex = (options?.length || 0) % 13 + 1; html = `${html}`; - } else { + } else if (html.indexOf("b3-menu__item--current") === -1) { if (key) { - html = html.replace(`class="b3-menu__item" data-name="${key}"` , `class="b3-menu__item b3-menu__item--current" data-name="${key}"`); + html = html.replace(`class="b3-menu__item" data-name="${key}"`, `class="b3-menu__item b3-menu__item--current" data-name="${key}"`); } else { - html = html.replace('class="b3-menu__item"' , 'class="b3-menu__item b3-menu__item--current"'); + html = html.replace('class="b3-menu__item"', 'class="b3-menu__item b3-menu__item--current"'); } } return html; @@ -113,6 +121,12 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM } }); transaction(protyle, doOperations, undoOperations); + Array.from(document.querySelectorAll(".av__panel .b3-menu__item")).find((item: HTMLElement) => { + if (item.dataset.name === target.dataset.content) { + item.querySelector(".b3-menu__checked")?.remove(); + return true; + } + }) target.remove(); }; @@ -413,7 +427,11 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE if (!currentElement) { currentElement = menuElement.querySelector(".b3-menu__item--current"); } - addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement, blockElement); + if (currentElement.querySelector(".b3-menu__checked")) { + removeCellOption(protyle, data, cellElements, menuElement.querySelector(`.b3-chips .b3-chip[data-content="${escapeAttr(currentElement.dataset.name)}"]`), blockElement); + } else { + addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement, blockElement); + } } else if (event.key === "Backspace" && inputElement.value === "") { removeCellOption(protyle, data, cellElements, inputElement.previousElementSibling as HTMLElement, blockElement); } @@ -562,7 +580,9 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => { }); let selectedHTML = ""; + const selected: string[] = [] genCellValueByElement(colData.type, cellElements[0]).mSelect?.forEach((item) => { + selected.push(item.content) selectedHTML += `
${item.content}
`; }); @@ -571,6 +591,6 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => { ${selectedHTML} -
${filterSelectHTML("", colData.options)}
+
${filterSelectHTML("", colData.options, selected)}
`; };