diff --git a/app/src/assets/scss/component/_typography.scss b/app/src/assets/scss/component/_typography.scss index 7e4ac9190..d44b0153f 100644 --- a/app/src/assets/scss/component/_typography.scss +++ b/app/src/assets/scss/component/_typography.scss @@ -161,20 +161,20 @@ display: flex; flex-direction: column; - &[data-subtype="NOTE"] { - &::before { - background-color: var(--b3-theme-primary); - } + // NOTE + &::before { + background-color: var(--b3-theme-primary); + } - .callout-info { - color: var(--b3-theme-primary); - } + .callout-info { + color: var(--b3-theme-primary); } &[data-subtype="WARNING"] { &::before { background-color: var(--b3-callout-warning); } + .callout-info { color: var(--b3-callout-warning); } @@ -184,6 +184,7 @@ &::before { background-color: var(--b3-theme-success); } + .callout-info { color: var(--b3-theme-success); } @@ -193,6 +194,7 @@ &::before { background-color: var(--b3-callout-important); } + .callout-info { color: var(--b3-callout-important); } @@ -202,6 +204,7 @@ &::before { background-color: var(--b3-theme-error); } + .callout-info { color: var(--b3-theme-error); } @@ -229,6 +232,8 @@ margin-left: 8px; font-weight: 500; font-size: 114%; + opacity: .86; + transition: var(--b3-color-transition); } } diff --git a/app/src/assets/scss/protyle/_wysiwyg.scss b/app/src/assets/scss/protyle/_wysiwyg.scss index 1ead82a3a..1f60de26b 100644 --- a/app/src/assets/scss/protyle/_wysiwyg.scss +++ b/app/src/assets/scss/protyle/_wysiwyg.scss @@ -793,6 +793,14 @@ background-color: var(--b3-list-hover); } } + + .callout-title { + cursor: pointer; + + &:hover { + opacity: 1; + } + } } .protyle-wysiwyg:not([contenteditable]), diff --git a/app/src/protyle/wysiwyg/callout.ts b/app/src/protyle/wysiwyg/callout.ts new file mode 100644 index 000000000..ea85a10b9 --- /dev/null +++ b/app/src/protyle/wysiwyg/callout.ts @@ -0,0 +1,80 @@ +import {hasClosestBlock} from "../util/hasClosest"; +import {updateTransaction} from "./transaction"; +import {focusBlock} from "../util/selection"; +import {Dialog} from "../../dialog"; +import {escapeHtml} from "../../util/escape"; +import {Menu} from "../../plugin/Menu"; + +export const updateCalloutType = (titleElement: HTMLElement, protyle: IProtyle) => { + const blockElement = hasClosestBlock(titleElement); + if (!blockElement) { + return; + } + const dialog = new Dialog({ + title: window.siyuan.languages.callout, + content: `
+ +
+ +
`, + width: "520px", + destroyCallback() { + const oldHTML = blockElement.outerHTML; + blockElement.setAttribute("data-subtype", textElements[0].value.trim()); + titleElement.textContent = escapeHtml(textElements[1].value); + if (updateIcon) { + blockElement.querySelector(".callout-icon").textContent = updateIcon; + } + updateTransaction(protyle, blockElement.getAttribute("data-node-id"), blockElement.outerHTML, oldHTML); + focusBlock(blockElement); + } + }); + const textElements: NodeListOf = dialog.element.querySelectorAll(".b3-text-field"); + let updateIcon = ""; + dialog.element.querySelector(".b3-form__icona-icon").addEventListener("click", (event) => { + const menu = new Menu(); + [{ + icon: "✏️", type: "NOTE" + }, { + icon: "💡", type: "TIP" + }, { + icon: "❗", type: "IMPORTANT" + }, { + icon: "⚠️", type: "WARNING" + }, { + icon: "🚨", type: "CAUTION" + }].forEach(item => { + menu.addItem({ + iconHTML: `${item.icon}`, + label: item.type, + click() { + textElements[0].value = item.type; + textElements[1].value = item.type; + updateIcon = item.icon; + } + }); + }); + const inputRect = textElements[0].getBoundingClientRect(); + menu.open({ + x: inputRect.left, + y: inputRect.bottom + }); + event.stopPropagation(); + event.preventDefault(); + }); +}; diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 51b1072a9..df497693c 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -101,6 +101,7 @@ import {hideTooltip} from "../../dialog/tooltip"; import {openGalleryItemMenu} from "../render/av/gallery/util"; import {clearSelect} from "../util/clear"; import {chartRender} from "../render/chartRender"; +import {updateCalloutType} from "./callout"; export class WYSIWYG { public lastHTMLs: { [key: string]: string } = {}; @@ -3036,6 +3037,13 @@ export class WYSIWYG { return; } + const calloutTitleElement = hasTopClosestByClassName(event.target, "callout-title"); + if (!protyle.disabled && !event.shiftKey && !ctrlIsPressed && calloutTitleElement) { + updateCalloutType(calloutTitleElement, protyle); + event.preventDefault(); + event.stopPropagation(); + return; + } const calloutIconElement = hasTopClosestByClassName(event.target, "callout-icon"); if (!protyle.disabled && !event.shiftKey && !ctrlIsPressed && calloutIconElement) { const nodeElement = hasClosestBlock(calloutIconElement); @@ -3059,7 +3067,7 @@ export class WYSIWYG { calloutIconElement.innerHTML = emojiHTML; hideElements(["dialog"]); updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); - focusByWbr(nodeElement, range); + focusBlock(nodeElement); }, calloutIconElement.querySelector("img")); } event.preventDefault();