Improved markdawn by adding more functionalities
This commit is contained in:
parent
c48ff5249b
commit
de6b0fe017
@ -5,18 +5,22 @@ import LightBox from "components/LightBox";
|
|||||||
import ToolTip from "components/ToolTip";
|
import ToolTip from "components/ToolTip";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import Markdown from "markdown-to-jsx";
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import { NextRouter } from "next/router";
|
||||||
import { slugify } from "queries/helpers";
|
import { slugify } from "queries/helpers";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
type ScenBreakProps = {
|
type MarkdawnProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
router: NextRouter;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
export default function Markdawn(props: MarkdawnProps): JSX.Element {
|
||||||
const appLayout = useAppLayout();
|
const appLayout = useAppLayout();
|
||||||
const text = preprocessMarkDawn(props.text);
|
const text = preprocessMarkDawn(props.text);
|
||||||
|
|
||||||
|
const { router } = props;
|
||||||
|
|
||||||
const [lightboxOpen, setLightboxOpen] = useState(false);
|
const [lightboxOpen, setLightboxOpen] = useState(false);
|
||||||
const [lightboxImages, setLightboxImages] = useState([""]);
|
const [lightboxImages, setLightboxImages] = useState([""]);
|
||||||
const [lightboxIndex, setLightboxIndex] = useState(0);
|
const [lightboxIndex, setLightboxIndex] = useState(0);
|
||||||
@ -43,12 +47,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h1 id={props.id} style={props.style}>
|
||||||
<h1 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h1>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h1>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -59,12 +61,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h2 id={props.id} style={props.style}>
|
||||||
<h2 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h2>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h2>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -75,12 +75,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h3 id={props.id} style={props.style}>
|
||||||
<h3 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h3>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h3>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -91,12 +89,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h4 id={props.id} style={props.style}>
|
||||||
<h4 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h4>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h4>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -107,12 +103,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h5 id={props.id} style={props.style}>
|
||||||
<h5 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h5>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h5>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -123,12 +117,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row place-items-center place-content-center gap-3">
|
<h6 id={props.id} style={props.style}>
|
||||||
<h6 id={props.id} style={props.style}>
|
{props.children}
|
||||||
{props.children}
|
|
||||||
</h6>
|
|
||||||
<HeaderToolTip id={props.id} />
|
<HeaderToolTip id={props.id} />
|
||||||
</div>
|
</h6>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -151,6 +143,28 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
IntraLink: {
|
||||||
|
component: (props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
target?: string;
|
||||||
|
page?: string;
|
||||||
|
}) => {
|
||||||
|
const slug = props.target
|
||||||
|
? slugify(props.target)
|
||||||
|
: slugify(props.children?.toString());
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
onClick={() =>
|
||||||
|
router.replace(
|
||||||
|
`${props.page ? props.page : ""}#${slug}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
player: {
|
player: {
|
||||||
component: () => {
|
component: () => {
|
||||||
return (
|
return (
|
||||||
@ -219,6 +233,25 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
blockquote: {
|
||||||
|
component: (props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
cite?: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<blockquote>
|
||||||
|
{props.cite ? (
|
||||||
|
<>
|
||||||
|
“{props.children}”
|
||||||
|
<cite>— {props.cite}</cite>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
props.children
|
||||||
|
)}
|
||||||
|
</blockquote>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
img: {
|
img: {
|
||||||
component: (props: {
|
component: (props: {
|
||||||
alt: string;
|
alt: string;
|
||||||
@ -230,7 +263,7 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="my-8 cursor-pointer"
|
className="my-8 cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setLightboxOpen(true);
|
setLightboxOpen(true);
|
||||||
setLightboxImages([
|
setLightboxImages([
|
||||||
@ -280,8 +313,12 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
|||||||
|
|
||||||
function HeaderToolTip(props: { id: string }) {
|
function HeaderToolTip(props: { id: string }) {
|
||||||
return (
|
return (
|
||||||
<ToolTip content={"Copy anchor link"} trigger="mouseenter">
|
<ToolTip
|
||||||
<ToolTip content={"Copied! 👍"} trigger="click">
|
content={"Copy anchor link"}
|
||||||
|
trigger="mouseenter"
|
||||||
|
className="text-sm"
|
||||||
|
>
|
||||||
|
<ToolTip content={"Copied! 👍"} trigger="click" className="text-sm">
|
||||||
<span
|
<span
|
||||||
className="material-icons transition-color hover:text-dark cursor-pointer"
|
className="material-icons transition-color hover:text-dark cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -49,7 +49,7 @@ function TOCLevel(props: TOCLevelProps): JSX.Element {
|
|||||||
>
|
>
|
||||||
<span className="text-dark">{`${parentNumbering}${
|
<span className="text-dark">{`${parentNumbering}${
|
||||||
childIndex + 1
|
childIndex + 1
|
||||||
}.`}</span>
|
}.`}</span>{" "}
|
||||||
<a onClick={() => router.replace(`#${child.slug}`)}>
|
<a onClick={() => router.replace(`#${child.slug}`)}>
|
||||||
{<abbr title={child.title}>{child.title}</abbr>}
|
{<abbr title={child.title}>{child.title}</abbr>}
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import type { AppProps } from "next/app";
|
import type { AppProps } from "next/app";
|
||||||
import "tailwind.css";
|
import "tailwind.css";
|
||||||
import "@fontsource/zen-maru-gothic/500.css";
|
import "@fontsource/zen-maru-gothic/500.css";
|
||||||
|
import "@fontsource/zen-maru-gothic/900.css";
|
||||||
import "@fontsource/vollkorn/700.css";
|
import "@fontsource/vollkorn/700.css";
|
||||||
import "@fontsource/opendyslexic/400.css";
|
import "@fontsource/opendyslexic/400.css";
|
||||||
|
import "@fontsource/opendyslexic/700.css";
|
||||||
import "@fontsource/material-icons";
|
import "@fontsource/material-icons";
|
||||||
|
|
||||||
import { AppContextProvider } from "contexts/AppLayoutContext";
|
import { AppContextProvider } from "contexts/AppLayoutContext";
|
||||||
|
@ -187,7 +187,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
|||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
{content.text_set.length > 0 && content.text_set[0].text && (
|
{content.text_set.length > 0 && content.text_set[0].text && (
|
||||||
<Markdawn text={content.text_set[0].text} />
|
<Markdawn router={router} text={content.text_set[0].text} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
|
@ -7,11 +7,13 @@ import { useCallback, useState } from "react";
|
|||||||
import Markdawn from "components/Markdown/Markdawn";
|
import Markdawn from "components/Markdown/Markdawn";
|
||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
interface EditorProps extends AppStaticProps {}
|
interface EditorProps extends AppStaticProps {}
|
||||||
|
|
||||||
export default function Editor(props: EditorProps): JSX.Element {
|
export default function Editor(props: EditorProps): JSX.Element {
|
||||||
const { langui } = props;
|
const { langui } = props;
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const handleInput = useCallback((e) => {
|
const handleInput = useCallback((e) => {
|
||||||
setMarkdown(e.target.value);
|
setMarkdown(e.target.value);
|
||||||
@ -76,7 +78,7 @@ export default function Editor(props: EditorProps): JSX.Element {
|
|||||||
<div>
|
<div>
|
||||||
<h2>Preview</h2>
|
<h2>Preview</h2>
|
||||||
<div className="bg-mid rounded-xl p-8">
|
<div className="bg-mid rounded-xl p-8">
|
||||||
<Markdawn className="max-w-full" text={markdown} />
|
<Markdawn router={router} className="max-w-full" text={markdown} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,7 @@ import ContentPanel from "components/Panels/ContentPanel";
|
|||||||
import { getPost } from "graphql/operations";
|
import { getPost } from "graphql/operations";
|
||||||
import { GetPostQuery } from "graphql/operations-types";
|
import { GetPostQuery } from "graphql/operations-types";
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||||
import { prettySlug } from "queries/helpers";
|
import { prettySlug } from "queries/helpers";
|
||||||
|
|
||||||
@ -13,6 +14,8 @@ interface HomeProps extends AppStaticProps {
|
|||||||
|
|
||||||
export default function Home(props: HomeProps): JSX.Element {
|
export default function Home(props: HomeProps): JSX.Element {
|
||||||
const { post } = props;
|
const { post } = props;
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
|
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
|
||||||
@ -23,7 +26,7 @@ export default function Home(props: HomeProps): JSX.Element {
|
|||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
{post.translations.length > 0 && (
|
{post.translations.length > 0 && (
|
||||||
<Markdawn text={post.translations[0].body} />
|
<Markdawn router={router} text={post.translations[0].body} />
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
);
|
);
|
||||||
|
@ -108,7 +108,7 @@ export default function LibrarySlug(props: PostProps): JSX.Element {
|
|||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
{post.translations.length > 0 && post.translations[0].body && (
|
{post.translations.length > 0 && post.translations[0].body && (
|
||||||
<Markdawn text={post.translations[0].body} />
|
<Markdawn router={router} text={post.translations[0].body} />
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
);
|
);
|
||||||
|
@ -274,8 +274,9 @@ export function getStatusDescription(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function slugify(str: string): string {
|
export function slugify(string: string | undefined): string {
|
||||||
return str
|
if (!string) return "";
|
||||||
|
return string
|
||||||
.replace(/[ÀÁÂÃÄÅàáâãä忯]/g, "a")
|
.replace(/[ÀÁÂÃÄÅàáâãä忯]/g, "a")
|
||||||
.replace(/[çÇ]/g, "c")
|
.replace(/[çÇ]/g, "c")
|
||||||
.replace(/[ðÐ]/g, "d")
|
.replace(/[ðÐ]/g, "d")
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
.formatted h4,
|
.formatted h4,
|
||||||
.formatted h5,
|
.formatted h5,
|
||||||
.formatted h6 {
|
.formatted h6 {
|
||||||
@apply text-center;
|
@apply text-center flex gap-3 justify-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formatted h1 {
|
.formatted h1 {
|
||||||
@ -94,6 +94,10 @@
|
|||||||
@apply my-2 text-justify;
|
@apply my-2 text-justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.formatted strong {
|
||||||
|
@apply font-black;
|
||||||
|
}
|
||||||
|
|
||||||
.formatted footer {
|
.formatted footer {
|
||||||
@apply border-t-[3px] border-dotted pt-6;
|
@apply border-t-[3px] border-dotted pt-6;
|
||||||
}
|
}
|
||||||
@ -122,6 +126,14 @@
|
|||||||
@apply list-decimal pl-4;
|
@apply list-decimal pl-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.formatted blockquote {
|
||||||
|
@apply border-2 border-mid rounded-lg p-5 text-center my-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formatted blockquote cite {
|
||||||
|
@apply text-dark block;
|
||||||
|
}
|
||||||
|
|
||||||
/* INPUT */
|
/* INPUT */
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user