From 13a3e3bc1f7d8cc674042c8a3d01f1159d2d1758 Mon Sep 17 00:00:00 2001 From: luzmediach Date: Thu, 14 Dec 2023 15:53:58 +0100 Subject: [PATCH 1/9] Support for Obsidian-style foldable callout syntax (e.g. "![Info]- Title") --- .../remark-callouts/src/lib/remark-callouts.ts | 16 +++++++++++----- packages/remark-callouts/styles.css | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/remark-callouts/src/lib/remark-callouts.ts b/packages/remark-callouts/src/lib/remark-callouts.ts index 4924638f3..7955f4fd3 100644 --- a/packages/remark-callouts/src/lib/remark-callouts.ts +++ b/packages/remark-callouts/src/lib/remark-callouts.ts @@ -113,7 +113,7 @@ export const callouts: Plugin = function (providedConfig?: Partial) { const [t, ...rest] = paragraph.children; const regex = new RegExp( - `^\\[!(?(.*?))\\][\t\f ]?(?.*?)$`, + `^\\[!(?<keyword>(.*?))\\](?<foldChar>[+-]?)[\t\f ]?(?<title>.*?)$`, "gi" ); const m = regex.exec(t.value); @@ -121,7 +121,7 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { // if no callout syntax, forget about it. if (!m) return; - const [key, title] = [m.groups?.keyword, m.groups?.title]; + const [key, foldChar, title] = [m.groups?.keyword, m.groups?.foldChar, m.groups?.title]; // if there's nothing inside the brackets, is it really a callout ? if (!key) return; @@ -228,6 +228,7 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { border-bottom:1px solid ${entry?.color}33;` : "", }, + foldChar: foldChar, }, }; @@ -236,12 +237,17 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { blockquote.children.unshift(titleNode as BlockContent); // Add classes for the callout block + let classList = [formatClassNameMap(config.classNameMaps.block)(keyword.toLowerCase())] + if (foldChar) { + classList.push('callout-foldable') + if (foldChar === '-') { + classList.push('callout-folded') + } + } blockquote.data = config.dataMaps.block({ ...blockquote.data, hProperties: { - className: formatClassNameMap(config.classNameMaps.block)( - keyword.toLowerCase() - ), + className: formatClassNameMap(classList), style: `border-left-color:${entry?.color};`, }, }); diff --git a/packages/remark-callouts/styles.css b/packages/remark-callouts/styles.css index d96092264..2030f3fe7 100644 --- a/packages/remark-callouts/styles.css +++ b/packages/remark-callouts/styles.css @@ -62,3 +62,19 @@ p:after { p:after { display: none; } + +blockquote.callout-foldable { + cursor: pointer; + display: grid; + grid-template-rows: min-content 1fr; + transition: all 0.3s ease-in-out; +} + +blockquote.callout-foldable.callout-folded { + grid-template-rows: min-content 0fr; +} + +blockquote.callout-foldable .callout-content { + overflow: hidden; + padding: 0px 10px; +} \ No newline at end of file From 51569299037071b53217cf5a5a80b2a8550048f4 Mon Sep 17 00:00:00 2001 From: marcchehab <105868642+marcchehab@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:10:37 +0100 Subject: [PATCH 2/9] Update remark-callouts.ts Agh, small error I fixed only locally --- packages/remark-callouts/src/lib/remark-callouts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remark-callouts/src/lib/remark-callouts.ts b/packages/remark-callouts/src/lib/remark-callouts.ts index 7955f4fd3..7e799939b 100644 --- a/packages/remark-callouts/src/lib/remark-callouts.ts +++ b/packages/remark-callouts/src/lib/remark-callouts.ts @@ -247,7 +247,7 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { blockquote.data = config.dataMaps.block({ ...blockquote.data, hProperties: { - className: formatClassNameMap(classList), + className: classList.join(" "), style: `border-left-color:${entry?.color};`, }, }); From d0250aca7f9c1c03765935b650b71ad2cee41504 Mon Sep 17 00:00:00 2001 From: marcchehab <105868642+marcchehab@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:40:11 +0100 Subject: [PATCH 3/9] Small arrows to indicate fold-state --- packages/remark-callouts/styles.css | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/remark-callouts/styles.css b/packages/remark-callouts/styles.css index 2030f3fe7..53ec363a8 100644 --- a/packages/remark-callouts/styles.css +++ b/packages/remark-callouts/styles.css @@ -77,4 +77,22 @@ blockquote.callout-foldable.callout-folded { blockquote.callout-foldable .callout-content { overflow: hidden; padding: 0px 10px; -} \ No newline at end of file +} + +blockquote.callout-foldable .callout-title strong::after { + content: ""; + display: inline-block; + height: 10px; + width: 10px; + border-style: solid; + border-width: 0 3px 3px 0; + position: absolute; + top: 0.8em; + right: 1em; + transform: rotate(45deg); + transition: all 0.3s ease-in-out; +} + +blockquote.callout-foldable.callout-folded .callout-title strong::after { + transform: rotate(-45deg); +} From a5ddfd482ea93cc26e3e7e6f5fdd88a6c3cc8702 Mon Sep 17 00:00:00 2001 From: luzmediach <marc@luzmedia.ch> Date: Fri, 15 Dec 2023 11:18:22 +0100 Subject: [PATCH 4/9] Solution for adding event listener --- .../src/lib/remark-callouts.ts | 3 +-- site/components/Callout.tsx | 22 +++++++++++++++++++ site/components/MDXPage.tsx | 4 +++- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 site/components/Callout.tsx diff --git a/packages/remark-callouts/src/lib/remark-callouts.ts b/packages/remark-callouts/src/lib/remark-callouts.ts index 7e799939b..6a5429e17 100644 --- a/packages/remark-callouts/src/lib/remark-callouts.ts +++ b/packages/remark-callouts/src/lib/remark-callouts.ts @@ -228,7 +228,6 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { border-bottom:1px solid ${entry?.color}33;` : "", }, - foldChar: foldChar, }, }; @@ -237,7 +236,7 @@ export const callouts: Plugin = function (providedConfig?: Partial<Config>) { blockquote.children.unshift(titleNode as BlockContent); // Add classes for the callout block - let classList = [formatClassNameMap(config.classNameMaps.block)(keyword.toLowerCase())] + const classList = [formatClassNameMap(config.classNameMaps.block)(keyword.toLowerCase())] if (foldChar) { classList.push('callout-foldable') if (foldChar === '-') { diff --git a/site/components/Callout.tsx b/site/components/Callout.tsx new file mode 100644 index 000000000..1f751199d --- /dev/null +++ b/site/components/Callout.tsx @@ -0,0 +1,22 @@ +import { useRef } from "react"; + +const Callout = ({ className, children }) => { + // If it's not a foldable callout, just render it as a blockquote + if (!className.includes("callout-foldable")) { + return <blockquote className={className}>{children}</blockquote>; + } + + // If we're here, it's a foldable callout + + const elem = useRef(null); + + const handleClick = () => { + elem.current.classList.toggle("callout-folded"); + }; + + return ( + <blockquote className={className} ref={elem} onClick={handleClick}>{children}</blockquote> + ); +}; + +export default Callout; \ No newline at end of file diff --git a/site/components/MDXPage.tsx b/site/components/MDXPage.tsx index 31e060e15..ffd247602 100644 --- a/site/components/MDXPage.tsx +++ b/site/components/MDXPage.tsx @@ -1,8 +1,10 @@ +import { useRef } from "react"; import { MDXRemote } from 'next-mdx-remote'; import { NextSeo } from 'next-seo'; import layouts from 'layouts'; import DocsPagination from './DocsPagination'; import { Hero } from "@portaljs/core"; +import Callout from "./Callout"; export default function MDXPage({ source, frontMatter }) { const Layout = ({ children }) => { @@ -14,7 +16,7 @@ export default function MDXPage({ source, frontMatter }) { return ( <Layout> - <MDXRemote {...source} components={{ DocsPagination, NextSeo, Hero }} /> + <MDXRemote {...source} components={{ DocsPagination, NextSeo, Hero, blockquote: Callout }} /> </Layout> ); } From 87f48ada83c95fd9d4b8cd15a138052385ecdd89 Mon Sep 17 00:00:00 2001 From: luzmediach <marc@luzmedia.ch> Date: Fri, 22 Dec 2023 17:46:22 +0100 Subject: [PATCH 5/9] implementing @mohamedsalem401 suggestions --- packages/remark-callouts/src/index.ts | 1 + .../remark-callouts/src/lib}/Callout.tsx | 0 site/components/MDXPage.tsx | 4 +--- 3 files changed, 2 insertions(+), 3 deletions(-) rename {site/components => packages/remark-callouts/src/lib}/Callout.tsx (100%) diff --git a/packages/remark-callouts/src/index.ts b/packages/remark-callouts/src/index.ts index 28c2aea52..178d1c7d0 100644 --- a/packages/remark-callouts/src/index.ts +++ b/packages/remark-callouts/src/index.ts @@ -1,2 +1,3 @@ export * from "./lib/remark-callouts"; export { default } from "./lib/remark-callouts"; +export Callout from "./lib/Callout"; \ No newline at end of file diff --git a/site/components/Callout.tsx b/packages/remark-callouts/src/lib/Callout.tsx similarity index 100% rename from site/components/Callout.tsx rename to packages/remark-callouts/src/lib/Callout.tsx diff --git a/site/components/MDXPage.tsx b/site/components/MDXPage.tsx index ffd247602..31e060e15 100644 --- a/site/components/MDXPage.tsx +++ b/site/components/MDXPage.tsx @@ -1,10 +1,8 @@ -import { useRef } from "react"; import { MDXRemote } from 'next-mdx-remote'; import { NextSeo } from 'next-seo'; import layouts from 'layouts'; import DocsPagination from './DocsPagination'; import { Hero } from "@portaljs/core"; -import Callout from "./Callout"; export default function MDXPage({ source, frontMatter }) { const Layout = ({ children }) => { @@ -16,7 +14,7 @@ export default function MDXPage({ source, frontMatter }) { return ( <Layout> - <MDXRemote {...source} components={{ DocsPagination, NextSeo, Hero, blockquote: Callout }} /> + <MDXRemote {...source} components={{ DocsPagination, NextSeo, Hero }} /> </Layout> ); } From 74845858d2cf7bdb7a330dcc1a1f9f66f8118097 Mon Sep 17 00:00:00 2001 From: luzmediach <marc@luzmedia.ch> Date: Fri, 22 Dec 2023 18:23:12 +0100 Subject: [PATCH 6/9] update adding react-jsx to compileoptions in packages/remark-callouts --- packages/remark-callouts/src/index.ts | 2 +- packages/remark-callouts/src/lib/Callout.tsx | 2 +- packages/remark-callouts/tsconfig.lib.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/remark-callouts/src/index.ts b/packages/remark-callouts/src/index.ts index 178d1c7d0..c66d78faf 100644 --- a/packages/remark-callouts/src/index.ts +++ b/packages/remark-callouts/src/index.ts @@ -1,3 +1,3 @@ export * from "./lib/remark-callouts"; export { default } from "./lib/remark-callouts"; -export Callout from "./lib/Callout"; \ No newline at end of file +export { Callout } from "./lib/Callout"; \ No newline at end of file diff --git a/packages/remark-callouts/src/lib/Callout.tsx b/packages/remark-callouts/src/lib/Callout.tsx index 1f751199d..aca73c5ac 100644 --- a/packages/remark-callouts/src/lib/Callout.tsx +++ b/packages/remark-callouts/src/lib/Callout.tsx @@ -19,4 +19,4 @@ const Callout = ({ className, children }) => { ); }; -export default Callout; \ No newline at end of file +export { Callout }; \ No newline at end of file diff --git a/packages/remark-callouts/tsconfig.lib.json b/packages/remark-callouts/tsconfig.lib.json index 18857e49b..677a24aed 100644 --- a/packages/remark-callouts/tsconfig.lib.json +++ b/packages/remark-callouts/tsconfig.lib.json @@ -7,7 +7,8 @@ "types": ["node"], "moduleResolution": "node", "esModuleInterop": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx" }, "exclude": ["**/*.spec.ts", "**/*.test.ts"], "include": ["src/**/*.ts"] From cf2699de659c26335f7992178e8530e15d9649a6 Mon Sep 17 00:00:00 2001 From: luzmediach <marc@luzmedia.ch> Date: Fri, 19 Jan 2024 16:08:36 +0100 Subject: [PATCH 7/9] adding color to fold indicator --- packages/remark-callouts/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/remark-callouts/styles.css b/packages/remark-callouts/styles.css index 53ec363a8..02214e0b0 100644 --- a/packages/remark-callouts/styles.css +++ b/packages/remark-callouts/styles.css @@ -86,6 +86,7 @@ blockquote.callout-foldable .callout-title strong::after { width: 10px; border-style: solid; border-width: 0 3px 3px 0; + border-color: var(--tw-prose-body); position: absolute; top: 0.8em; right: 1em; From 1056fff3a0b2fd32728fd4608d75ae957d789c4c Mon Sep 17 00:00:00 2001 From: marcchehab <105868642+marcchehab@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:56:17 +0100 Subject: [PATCH 8/9] Applying @olayway's suggestions from code review Applying @olayway's suggestions from code review Co-authored-by: Ola Rubaj <52197250+olayway@users.noreply.github.com> --- packages/remark-callouts/src/lib/Callout.tsx | 2 -- packages/remark-callouts/styles.css | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/remark-callouts/src/lib/Callout.tsx b/packages/remark-callouts/src/lib/Callout.tsx index aca73c5ac..215e7f780 100644 --- a/packages/remark-callouts/src/lib/Callout.tsx +++ b/packages/remark-callouts/src/lib/Callout.tsx @@ -5,8 +5,6 @@ const Callout = ({ className, children }) => { if (!className.includes("callout-foldable")) { return <blockquote className={className}>{children}</blockquote>; } - - // If we're here, it's a foldable callout const elem = useRef(null); diff --git a/packages/remark-callouts/styles.css b/packages/remark-callouts/styles.css index 02214e0b0..ccb437558 100644 --- a/packages/remark-callouts/styles.css +++ b/packages/remark-callouts/styles.css @@ -88,12 +88,14 @@ blockquote.callout-foldable .callout-title strong::after { border-width: 0 3px 3px 0; border-color: var(--tw-prose-body); position: absolute; - top: 0.8em; + top: 50%; right: 1em; - transform: rotate(45deg); + transform: translateY(-50%) rotate(45deg); + transform-origin: center; transition: all 0.3s ease-in-out; } blockquote.callout-foldable.callout-folded .callout-title strong::after { - transform: rotate(-45deg); + transform: translateY(-50%) rotate(-45deg); + transform-origin: center; } From 43f8561547b22f512467aaa37f9dc48db2451453 Mon Sep 17 00:00:00 2001 From: marcchehab <105868642+marcchehab@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:59:24 +0100 Subject: [PATCH 9/9] @olayway's suggestion positioning the arrow --- packages/remark-callouts/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/remark-callouts/styles.css b/packages/remark-callouts/styles.css index ccb437558..7b54cab2e 100644 --- a/packages/remark-callouts/styles.css +++ b/packages/remark-callouts/styles.css @@ -23,6 +23,7 @@ align-items: center; padding: 10px; gap: 10px; + position: relative; } .callout-title > strong {