This commit is contained in:
Benjamin Toby 2025-07-20 10:56:17 +01:00
parent b6a5982f02
commit 668b596402
13 changed files with 59 additions and 100 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -69,6 +69,7 @@ export default function LinkList({
{...props} {...props}
className={twMerge( className={twMerge(
"flex flex-row items-center gap-1", "flex flex-row items-center gap-1",
"twui-link-list",
props.className props.className
)} )}
> >

View File

@ -1,28 +0,0 @@
import MDEditor from "@uiw/react-md-editor";
import rehypeSanitize from "rehype-sanitize";
import React from "react";
import remarkGfm from "remark-gfm";
import rehypePrismPlus from "rehype-prism-plus";
import ReactDOM from "react-dom";
export default function MarkdownEditor() {
const [value, setValue] = React.useState<any>(
`**Hello world!!!** <IFRAME SRC=\"javascript:javascript:alert(window.origin);\"></IFRAME>`
);
React.useEffect(() => {
console.log("value", value);
}, [value]);
return ReactDOM.createPortal(
<MDEditor
value={value}
onChange={setValue}
previewOptions={{
rehypePlugins: [rehypeSanitize, rehypePrismPlus],
remarkPlugins: [remarkGfm],
}}
/>,
document.getElementById("markdown-modal-root") as HTMLElement
);
}

View File

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import Button from "../../layout/Button"; import Button from "../../layout/Button";
import Border from "../../elements/Border"; import Border from "../../elements/Border";
import { LocalStorageDict } from "@/package-shared/dict/local-storage-dict";
type Props = { type Props = {
preview: boolean; preview: boolean;
@ -18,45 +17,30 @@ export default function MarkdownEditorSelectorButtons({
}: Props) { }: Props) {
const [ready, setReady] = React.useState(false); const [ready, setReady] = React.useState(false);
const defSbsName = "TWUIMarkdownEditorDefaultSideBySide";
const defPrevName = "TWUIMarkdownEditorDefaultPreview";
React.useEffect(() => { React.useEffect(() => {
if (!ready) return; if (!ready) return;
if (sideBySide) { if (sideBySide) {
localStorage.setItem( localStorage.setItem(defSbsName, "true");
LocalStorageDict["MarkdownEditorDefaultSideBySide"],
"true"
);
} else { } else {
localStorage.removeItem( localStorage.removeItem(defSbsName);
LocalStorageDict["MarkdownEditorDefaultSideBySide"]
);
} }
if (preview) { if (preview) {
localStorage.setItem( localStorage.setItem(defPrevName, "true");
LocalStorageDict["MarkdownEditorDefaultPreview"],
"true"
);
} else { } else {
localStorage.removeItem( localStorage.removeItem(defPrevName);
LocalStorageDict["MarkdownEditorDefaultPreview"]
);
} }
}, [sideBySide, preview, ready]); }, [sideBySide, preview, ready]);
React.useEffect(() => { React.useEffect(() => {
if ( if (localStorage.getItem(defPrevName)) {
localStorage.getItem(
LocalStorageDict["MarkdownEditorDefaultPreview"]
)
) {
setPreview(true); setPreview(true);
} }
if ( if (!localStorage.getItem(defSbsName)) {
!localStorage.getItem(
LocalStorageDict["MarkdownEditorDefaultSideBySide"]
)
) {
setSideBySide(false); setSideBySide(false);
} }

View File

@ -17,6 +17,7 @@ export default function Main() {
</H1> </H1>
<Row className="items-stretch flex-col md:flex-row w-full md:w-auto"> <Row className="items-stretch flex-col md:flex-row w-full md:w-auto">
<Button <Button
title="Contact Me"
beforeIcon={ beforeIcon={
<Contact size={17} className="font-normal" /> <Contact size={17} className="font-normal" />
} }

View File

@ -1,37 +1,32 @@
import { TWUI_LINK_LIST_LINK_OBJECT } from "@/components/lib/elements/LinkList";
import { GitBranch, Github, Linkedin, Mail, Users } from "lucide-react"; import { GitBranch, Github, Linkedin, Mail, Users } from "lucide-react";
import { ReactNode } from "react"; import { ReactNode } from "react";
export type HeaderLinkType = { export const HeaderLinks: TWUI_LINK_LIST_LINK_OBJECT[] = [
name: string;
href: string;
current?: boolean;
};
export const HeaderLinks: HeaderLinkType[] = [
{ {
name: "Home", title: "Home",
href: "/", url: "/",
current: true, strict: true,
}, },
{ {
name: "About", title: "About",
href: "/about", url: "/about",
}, },
{ {
name: "Skills", title: "Skills",
href: "/skills", url: "/skills",
}, },
{ {
name: "Work", title: "Work",
href: "/work", url: "/work",
}, },
{ {
name: "Blog", title: "Blog",
href: "/blog", url: "/blog",
}, },
{ {
name: "Contact", title: "Contact",
href: "/contact", url: "/contact",
}, },
]; ];

View File

@ -1,13 +1,13 @@
import { HeaderLinkType } from "../(data)/links"; import { TWUI_LINK_LIST_LINK_OBJECT } from "@/components/lib/elements/LinkList";
type Props = { type Props = {
link: HeaderLinkType; link: TWUI_LINK_LIST_LINK_OBJECT;
}; };
export default function HeaderLink({ link }: Props) { export default function HeaderLink({ link }: Props) {
return ( return (
<a href={link.href} className="text-white hover:text-gray-300"> <a href={link.url} className="text-white hover:text-gray-300">
{link.name} {link.title}
</a> </a>
); );
} }

View File

@ -2,13 +2,13 @@ import Logo from "@/components/general/Logo";
import Stack from "@/components/lib/layout/Stack"; import Stack from "@/components/lib/layout/Stack";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { HeaderLinks, SocialLinks } from "../(data)/links"; import { HeaderLinks, SocialLinks } from "../(data)/links";
import HeaderLink from "../(partials)/HeaderLink";
import React from "react"; import React from "react";
import Divider from "@/components/lib/layout/Divider"; import Divider from "@/components/lib/layout/Divider";
import Button from "@/components/lib/layout/Button"; import Button from "@/components/lib/layout/Button";
import { X } from "lucide-react"; import { X } from "lucide-react";
import SocialLink from "../(partials)/SocialLink"; import SocialLink from "../(partials)/SocialLink";
import Row from "@/components/lib/layout/Row"; import Row from "@/components/lib/layout/Row";
import LinkList from "@/components/lib/elements/LinkList";
type Props = { type Props = {
menuOpen: boolean; menuOpen: boolean;
@ -19,12 +19,13 @@ export default function MobileMenu({ menuOpen, setMenuOpen }: Props) {
return ( return (
<div <div
className={twMerge( className={twMerge(
"fixed top-0 bg-[var(--bg-color)] w-full h-full overflow-y-auto", "fixed top-0 w-full h-full overflow-y-auto",
"z-[100] p-10", "z-[100] p-10 bg-background dark:bg-background-dark",
menuOpen ? "right-0" : "right-[100vw]" menuOpen ? "right-0" : "right-[100vw]"
)} )}
> >
<Button <Button
title="Close Mobile Menu"
variant="ghost" variant="ghost"
className="absolute top-10 right-10" className="absolute top-10 right-10"
onClick={() => setMenuOpen(false)} onClick={() => setMenuOpen(false)}
@ -33,19 +34,15 @@ export default function MobileMenu({ menuOpen, setMenuOpen }: Props) {
</Button> </Button>
<Stack className="w-full h-full"> <Stack className="w-full h-full">
<Logo size={40} /> <Logo size={40} />
<Divider /> <Divider dashed className="border-[2px] mt-4 mb-2" />
<Stack className="w-full items-stretch"> <Stack className="w-full items-stretch">
{HeaderLinks.map((link, index) => { <LinkList
return ( links={HeaderLinks}
<React.Fragment key={index}> className="flex-col items-stretch"
<HeaderLink key={index} link={link} /> />
{index < HeaderLinks.length - 1 && <Divider />}
</React.Fragment>
);
})}
</Stack> </Stack>
<Divider /> <Divider dashed className="border-[2px] my-4" />
<Row className="items-center w-full py-6 mt-auto gap-10 mt-auto"> <Row className="items-center w-full py-6 gap-10 mt-auto">
{SocialLinks.map((link, index) => { {SocialLinks.map((link, index) => {
return <SocialLink key={index} link={link} />; return <SocialLink key={index} link={link} />;
})} })}

View File

@ -1,11 +1,11 @@
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { HeaderLinks } from "./(data)/links"; import { HeaderLinks } from "./(data)/links";
import HeaderLink from "./(partials)/HeaderLink";
import Row from "@/components/lib/layout/Row"; import Row from "@/components/lib/layout/Row";
import Logo from "@/components/general/Logo"; import Logo from "@/components/general/Logo";
import { Menu } from "lucide-react"; import { Menu } from "lucide-react";
import Button from "@/components/lib/layout/Button"; import Button from "@/components/lib/layout/Button";
import React from "react"; import React from "react";
import LinkList from "@/components/lib/elements/LinkList";
type Props = { type Props = {
menuOpen: boolean; menuOpen: boolean;
@ -22,13 +22,15 @@ export default function Header({ menuOpen, setMenuOpen }: Props) {
)} )}
> >
<Row className="gap-6 ml-auto hidden md:flex"> <Row className="gap-6 ml-auto hidden md:flex">
{HeaderLinks.map((link, index) => { <LinkList links={HeaderLinks} />
return <HeaderLink key={index} link={link} />;
})}
</Row> </Row>
<Row className="flex md:hidden w-full justify-between"> <Row className="flex md:hidden w-full justify-between">
<Logo size={25} /> <Logo size={25} />
<Button variant="ghost" onClick={() => setMenuOpen(!menuOpen)}> <Button
title="Mobile Menu"
variant="ghost"
onClick={() => setMenuOpen(!menuOpen)}
>
<Menu /> <Menu />
</Button> </Button>
</Row> </Row>

View File

@ -1,12 +1,8 @@
import Main from "@/components/lib/layout/Main";
import React, { PropsWithChildren } from "react"; import React, { PropsWithChildren } from "react";
import Aside from "./Aside"; import Aside from "./Aside";
import Header from "./Header"; import Header from "./Header";
import Footer from "./Footer"; import Footer from "./Footer";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import Stack from "@/components/lib/layout/Stack";
import { HeaderLinks } from "./(data)/links";
import HeaderLink from "./(partials)/HeaderLink";
import MobileMenu from "./(sections)/MobileMenu"; import MobileMenu from "./(sections)/MobileMenu";
type Props = PropsWithChildren & {}; type Props = PropsWithChildren & {};

View File

@ -13,6 +13,7 @@
"@moduletrace/datasquirel": "^5.1.0", "@moduletrace/datasquirel": "^5.1.0",
"@moduletrace/twui": "file:./components/lib", "@moduletrace/twui": "file:./components/lib",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"html-to-react": "^1.7.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lucide-react": "^0.462.0", "lucide-react": "^0.462.0",
"next": "15.0.3", "next": "15.0.3",

View File

@ -26,12 +26,14 @@ export default function Home() {
<Span>Page Not Found!</Span> <Span>Page Not Found!</Span>
<Row className="gap-4 max-w-[400px] w-[400px]"> <Row className="gap-4 max-w-[400px] w-[400px]">
<Button <Button
title="Go Back"
onClick={() => window.history.back()} onClick={() => window.history.back()}
className="grow" className="grow"
> >
Go Back Go Back
</Button> </Button>
<Button <Button
title="Home Page"
href="/" href="/"
variant="outlined" variant="outlined"
linkProps={{ linkProps={{

View File

@ -58,3 +58,11 @@
.twui-card-link { .twui-card-link {
@apply p-0 w-full border-none; @apply p-0 w-full border-none;
} }
.twui-a {
@apply !text-foreground-light/70 dark:!text-foreground-dark/70 border-none;
}
.twui-a.active {
@apply !text-foreground-light dark:!text-foreground-dark font-bold;
}