diff --git a/app/editor/menus/block.tsx b/app/editor/menus/block.tsx
index 3d954b274..d9404e6ba 100644
--- a/app/editor/menus/block.tsx
+++ b/app/editor/menus/block.tsx
@@ -19,6 +19,7 @@ import {
ClockIcon,
CalendarIcon,
MathIcon,
+ DoneIcon,
} from "outline-icons";
import * as React from "react";
import styled from "styled-components";
@@ -116,6 +117,7 @@ export default function blockMenuItems(dictionary: Dictionary): MenuItem[] {
name: "blockquote",
title: dictionary.quote,
icon: ,
+ keywords: "blockquote pullquote",
shortcut: `${metaDisplay} ]`,
},
{
@@ -173,6 +175,13 @@ export default function blockMenuItems(dictionary: Dictionary): MenuItem[] {
keywords: "notice card information",
attrs: { style: "info" },
},
+ {
+ name: "container_notice",
+ title: dictionary.successNotice,
+ icon: ,
+ keywords: "notice card success",
+ attrs: { style: "success" },
+ },
{
name: "container_notice",
title: dictionary.warningNotice,
diff --git a/app/hooks/useDictionary.ts b/app/hooks/useDictionary.ts
index 15dff16fd..5d359bc0b 100644
--- a/app/hooks/useDictionary.ts
+++ b/app/hooks/useDictionary.ts
@@ -76,6 +76,8 @@ export default function useDictionary() {
showSource: t("Show source"),
warning: t("Warning"),
warningNotice: t("Warning notice"),
+ success: t("Success"),
+ successNotice: t("Success notice"),
insertDate: t("Current date"),
insertTime: t("Current time"),
insertDateTime: t("Current date and time"),
diff --git a/app/typings/styled-components.d.ts b/app/typings/styled-components.d.ts
index 45a8b7500..e30b32de3 100644
--- a/app/typings/styled-components.d.ts
+++ b/app/typings/styled-components.d.ts
@@ -53,6 +53,8 @@ declare module "styled-components" {
noticeTipText: string;
noticeWarningBackground: string;
noticeWarningText: string;
+ noticeSuccessBackground: string;
+ noticeSuccessText: string;
}
interface Colors {
diff --git a/shared/editor/components/Styles.ts b/shared/editor/components/Styles.ts
index 0d11d4f17..f62d5990d 100644
--- a/shared/editor/components/Styles.ts
+++ b/shared/editor/components/Styles.ts
@@ -651,9 +651,23 @@ h6 {
}
}
+.notice-block.success {
+ background: ${transparentize(0.9, props.theme.noticeSuccessBackground)};
+ border-left: 4px solid ${props.theme.noticeSuccessBackground};
+ color: ${props.theme.noticeSuccessText};
+
+ .icon {
+ color: ${props.theme.noticeSuccessBackground};
+ }
+
+ a {
+ color: ${props.theme.noticeSuccessText};
+ }
+}
+
blockquote {
margin: 0;
- padding-left: 1.5em;
+ padding: 8px 10px 8px 1.5em;
font-style: italic;
overflow: hidden;
position: relative;
diff --git a/shared/editor/nodes/Notice.tsx b/shared/editor/nodes/Notice.tsx
index 5c315c8d4..788ab5882 100644
--- a/shared/editor/nodes/Notice.tsx
+++ b/shared/editor/nodes/Notice.tsx
@@ -1,5 +1,5 @@
import Token from "markdown-it/lib/token";
-import { WarningIcon, InfoIcon, StarredIcon } from "outline-icons";
+import { WarningIcon, InfoIcon, StarredIcon, DoneIcon } from "outline-icons";
import { wrappingInputRule } from "prosemirror-inputrules";
import { NodeSpec, Node as ProsemirrorNode, NodeType } from "prosemirror-model";
import * as React from "react";
@@ -14,6 +14,7 @@ export default class Notice extends Node {
return Object.entries({
info: this.options.dictionary.info,
warning: this.options.dictionary.warning,
+ success: this.options.dictionary.success,
tip: this.options.dictionary.tip,
});
}
@@ -47,6 +48,28 @@ export default class Notice extends Node {
? "tip"
: dom.className.includes("warning")
? "warning"
+ : dom.className.includes("success")
+ ? "success"
+ : undefined,
+ }),
+ },
+ // Quill editor parsing
+ {
+ tag: "div.ql-hint",
+ preserveWhitespace: "full",
+ getAttrs: (dom: HTMLDivElement) => ({
+ style: dom.dataset.hint,
+ }),
+ },
+ // GitBook parsing
+ {
+ tag: "div.alert.theme-admonition",
+ preserveWhitespace: "full",
+ getAttrs: (dom: HTMLDivElement) => ({
+ style: dom.className.includes("warning")
+ ? "warning"
+ : dom.className.includes("success")
+ ? "success"
: undefined,
}),
},
@@ -75,6 +98,8 @@ export default class Notice extends Node {
component = ;
} else if (node.attrs.style === "warning") {
component = ;
+ } else if (node.attrs.style === "success") {
+ component = ;
} else {
component = ;
}
diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json
index 2f9e88e9c..80e7166d3 100644
--- a/shared/i18n/locales/en_US/translation.json
+++ b/shared/i18n/locales/en_US/translation.json
@@ -299,6 +299,8 @@
"Show source": "Show source",
"Warning": "Warning",
"Warning notice": "Warning notice",
+ "Success": "Success",
+ "Success notice": "Success notice",
"Current date": "Current date",
"Current time": "Current time",
"Current date and time": "Current date and time",
diff --git a/shared/styles/theme.ts b/shared/styles/theme.ts
index a9b958043..f3d83141e 100644
--- a/shared/styles/theme.ts
+++ b/shared/styles/theme.ts
@@ -38,7 +38,7 @@ const defaultColors: Colors = {
purple: "#9E5CF7",
blue: "#3633FF",
marine: "#2BC2FF",
- green: "#42DED1",
+ green: "#3ad984",
yellow: "#F5BE31",
},
};
@@ -90,6 +90,8 @@ const buildBaseTheme = (input: Partial) => {
noticeTipText: colors.almostBlack,
noticeWarningBackground: "#d73a49",
noticeWarningText: colors.almostBlack,
+ noticeSuccessBackground: colors.brand.green,
+ noticeSuccessText: colors.almostBlack,
tableSelectedBackground: transparentize(0.8, colors.accent),
breakpoints,
...colors,
@@ -230,6 +232,7 @@ export const buildDarkTheme = (input: Partial): DefaultTheme => {
noticeInfoText: colors.white,
noticeTipText: colors.white,
noticeWarningText: colors.white,
+ noticeSuccessText: colors.white,
progressBarBackground: colors.slate,
scrollbarBackground: colors.black,
scrollbarThumb: colors.lightBlack,