Yuki Takei 1 год назад
Родитель
Сommit
d0f1f73c89

+ 9 - 6
apps/app/src/features/callout/components/CalloutViewer.tsx

@@ -13,7 +13,7 @@ type CALLOUT_TO = {
   [key in Callout]: string;
   [key in Callout]: string;
 }
 }
 
 
-const CALLOUT_TO_TITLE: CALLOUT_TO = {
+const CALLOUT_TO_TYPE: CALLOUT_TO = {
   note: 'Note',
   note: 'Note',
   tip: 'Tip',
   tip: 'Tip',
   important: 'Important',
   important: 'Important',
@@ -36,12 +36,15 @@ const CALLOUT_TO_ICON: CALLOUT_TO = {
 type CalloutViewerProps = {
 type CalloutViewerProps = {
   children: ReactNode,
   children: ReactNode,
   node: Element,
   node: Element,
-  name: string
+  type: string,
+  label?: string,
 }
 }
 
 
 export const CalloutViewer = React.memo((props: CalloutViewerProps): JSX.Element => {
 export const CalloutViewer = React.memo((props: CalloutViewerProps): JSX.Element => {
 
 
-  const { node, name, children } = props;
+  const {
+    node, type, label, children,
+  } = props;
 
 
   if (node == null) {
   if (node == null) {
     return <></>;
     return <></>;
@@ -49,13 +52,13 @@ export const CalloutViewer = React.memo((props: CalloutViewerProps): JSX.Element
 
 
   return (
   return (
     <div className={`${moduleClass} callout-viewer`}>
     <div className={`${moduleClass} callout-viewer`}>
-      <div className={`callout callout-${CALLOUT_TO_TITLE[name].toLowerCase()}`}>
+      <div className={`callout callout-${CALLOUT_TO_TYPE[type].toLowerCase()}`}>
         <div className="callout-indicator">
         <div className="callout-indicator">
           <div className="callout-hint">
           <div className="callout-hint">
-            <span className="material-symbols-outlined">{CALLOUT_TO_ICON[name]}</span>
+            <span className="material-symbols-outlined">{CALLOUT_TO_ICON[type]}</span>
           </div>
           </div>
           <div className="callout-title">
           <div className="callout-title">
-            {CALLOUT_TO_TITLE[name]}
+            {label ?? CALLOUT_TO_TYPE[type]}
           </div>
           </div>
         </div>
         </div>
         <div className="callout-content">
         <div className="callout-content">

+ 20 - 1
apps/app/src/features/callout/services/callout.ts

@@ -1,3 +1,4 @@
+import type { Text } from 'mdast';
 import type { ContainerDirective } from 'mdast-util-directive';
 import type { ContainerDirective } from 'mdast-util-directive';
 import type { Plugin } from 'unified';
 import type { Plugin } from 'unified';
 import { visit } from 'unist-util-visit';
 import { visit } from 'unist-util-visit';
@@ -8,11 +9,26 @@ export const remarkPlugin: Plugin = () => {
   return (tree) => {
   return (tree) => {
     visit(tree, 'containerDirective', (node: ContainerDirective) => {
     visit(tree, 'containerDirective', (node: ContainerDirective) => {
       if (AllCallout.some(name => name === node.name.toLowerCase())) {
       if (AllCallout.some(name => name === node.name.toLowerCase())) {
+        const type = node.name.toLowerCase();
         const data = node.data ?? (node.data = {});
         const data = node.data ?? (node.data = {});
+
+        // extract directive label
+        const paragraphs = (node.children ?? []).filter(child => child.type === 'paragraph') ?? [];
+        const paragraphForDirectiveLabel = paragraphs.find(p => p.data?.directiveLabel);
+        const label = paragraphForDirectiveLabel != null
+          ? (paragraphForDirectiveLabel.children[0] as Text).value
+          : undefined;
+        // remove directive label from children
+        if (paragraphForDirectiveLabel != null) {
+          node.children.splice(node.children.indexOf(paragraphForDirectiveLabel), 1);
+        }
+
         data.hName = 'callout';
         data.hName = 'callout';
         data.hProperties = {
         data.hProperties = {
-          name: node.name.toLocaleLowerCase(),
+          type,
+          label: label ?? type,
         };
         };
+
       }
       }
     });
     });
   };
   };
@@ -20,4 +36,7 @@ export const remarkPlugin: Plugin = () => {
 
 
 export const sanitizeOption = {
 export const sanitizeOption = {
   tagNames: ['callout'],
   tagNames: ['callout'],
+  attributes: {
+    callout: ['type', 'label'],
+  },
 };
 };