This commit is contained in:
Benjamin Toby 2025-07-25 19:21:17 +01:00
parent aceddf5146
commit 6d833c7d3b
11 changed files with 88 additions and 40 deletions

View File

@ -22,7 +22,7 @@ export default function ModalComponent({ open, setOpen, ...props }: Props) {
<div <div
className={twMerge( className={twMerge(
"fixed z-[200] top-0 left-0 w-screen h-screen", "fixed z-[200] top-0 left-0 w-screen h-screen",
"flex flex-col items-center justify-center", "flex flex-col items-center justify-center p-4",
"twui-modal-root" "twui-modal-root"
)} )}
> >

View File

@ -1,4 +1,4 @@
import { DetailedHTMLProps, HTMLAttributes } from "react"; import { DetailedHTMLProps, HTMLAttributes, RefObject } from "react";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
export type TWUI_BORDER_PROPS = DetailedHTMLProps< export type TWUI_BORDER_PROPS = DetailedHTMLProps<
@ -6,13 +6,18 @@ export type TWUI_BORDER_PROPS = DetailedHTMLProps<
HTMLDivElement HTMLDivElement
> & { > & {
spacing?: "normal" | "loose" | "tight" | "wide" | "tightest"; spacing?: "normal" | "loose" | "tight" | "wide" | "tightest";
componentRef?: RefObject<HTMLDivElement>;
}; };
/** /**
* # Toggle Component * # Toggle Component
* @className_wrapper twui-border * @className_wrapper twui-border
*/ */
export default function Border({ spacing, ...props }: TWUI_BORDER_PROPS) { export default function Border({
spacing,
componentRef,
...props
}: TWUI_BORDER_PROPS) {
return ( return (
<div <div
{...props} {...props}
@ -29,6 +34,7 @@ export default function Border({ spacing, ...props }: TWUI_BORDER_PROPS) {
"twui-border", "twui-border",
props.className props.className
)} )}
ref={componentRef}
> >
{props.children} {props.children}
</div> </div>

View File

@ -104,7 +104,7 @@ export default function HeaderNavLinkComponent({
<Dropdown <Dropdown
target={mainLinkComponent} target={mainLinkComponent}
position="bottom-right" position="bottom-right"
hoverOpen // hoverOpen
className="hidden xl:flex" className="hidden xl:flex"
> >
{dropdown ? ( {dropdown ? (

View File

@ -0,0 +1,48 @@
import React from "react";
import { serialize } from "next-mdx-remote/serialize";
import remarkGfm from "remark-gfm";
import rehypePrismPlus from "rehype-prism-plus";
import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote";
import { useMDXComponents } from "../mdx/mdx-components";
export const TWUIPrismLanguages = ["shell", "javascript"] as const;
type Props = {
content: string;
};
/**
* # CodeBlock
*
* @className `twui-remote-code-block-wrapper`
*/
export default function RemoteCodeBlock({ content }: Props) {
const [mdxSource, setMdxSource] =
React.useState<MDXRemoteSerializeResult<any>>();
const { components } = useMDXComponents();
React.useEffect(() => {
serialize(content, {
mdxOptions: {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypePrismPlus],
},
}).then((mdxSrc) => {
setMdxSource(mdxSrc);
});
}, []);
if (!mdxSource) {
return null;
}
return (
<MDXRemote
{...mdxSource}
components={{
...components,
}}
/>
);
}

View File

@ -70,7 +70,7 @@ export default function Toast({
<Card <Card
{...props} {...props}
className={twMerge( className={twMerge(
"absolute bottom-4 right-4 z-[250] border-none", "fixed bottom-4 right-4 z-[250] border-none",
"pl-6 pr-8 py-4 bg-primary dark:bg-primary-dark", "pl-6 pr-8 py-4 bg-primary dark:bg-primary-dark",
color == "success" color == "success"
? "bg-success dark:bg-success-dark twui-toast-success" ? "bg-success dark:bg-success-dark twui-toast-success"

View File

@ -451,32 +451,6 @@ export default function Input<KeyType extends string>(
buttonDownRef={buttonDownRef} buttonDownRef={buttonDownRef}
/> />
) : null} ) : null}
{/* {info && (
<Dropdown
target={
<Button
variant="ghost"
color="gray"
title="Input Info Button"
>
<Info
size={15}
className="opacity-50 hover:opacity-100"
/>
</Button>
}
hoverOpen
>
<Card className="min-w-[250px] text-sm p-6">
{typeof info == "string" ? (
<Span className="text-sm">{info}</Span>
) : (
info
)}
</Card>
</Dropdown>
)} */}
</div> </div>
{info && ( {info && (
<Dropdown <Dropdown

View File

@ -14,6 +14,7 @@ type Props = {
changeHandler?: (content: string) => void; changeHandler?: (content: string) => void;
editorProps?: ComponentProps<typeof AceEditor>; editorProps?: ComponentProps<typeof AceEditor>;
maxHeight?: string; maxHeight?: string;
noToggleButtons?: boolean;
}; };
export default function MarkdownEditor({ export default function MarkdownEditor({
@ -23,6 +24,7 @@ export default function MarkdownEditor({
changeHandler, changeHandler,
editorProps, editorProps,
maxHeight: existingMaxHeight, maxHeight: existingMaxHeight,
noToggleButtons,
}: Props) { }: Props) {
const [value, setValue] = React.useState<any>(existingValue || ``); const [value, setValue] = React.useState<any>(existingValue || ``);
@ -40,9 +42,11 @@ export default function MarkdownEditor({
return ( return (
<Stack className="w-full items-stretch"> <Stack className="w-full items-stretch">
{!noToggleButtons && (
<MarkdownEditorSelectorButtons <MarkdownEditorSelectorButtons
{...{ preview, setPreview, setSideBySide, sideBySide }} {...{ preview, setPreview, setSideBySide, sideBySide }}
/> />
)}
{sideBySide ? ( {sideBySide ? (
<Row <Row
@ -58,7 +62,6 @@ export default function MarkdownEditor({
{...editorProps} {...editorProps}
/> />
<MarkdownEditorPreviewComponent <MarkdownEditorPreviewComponent
setValue={setValue}
value={value} value={value}
maxHeight={maxHeight} maxHeight={maxHeight}
/> />
@ -69,7 +72,6 @@ export default function MarkdownEditor({
> >
{preview ? ( {preview ? (
<MarkdownEditorPreviewComponent <MarkdownEditorPreviewComponent
setValue={setValue}
value={value} value={value}
maxHeight={maxHeight} maxHeight={maxHeight}
/> />

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { ComponentProps, RefObject } from "react";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { serialize } from "next-mdx-remote/serialize"; import { serialize } from "next-mdx-remote/serialize";
import remarkGfm from "remark-gfm"; import remarkGfm from "remark-gfm";
@ -10,14 +10,14 @@ import EmptyContent from "../../elements/EmptyContent";
type Props = { type Props = {
value: string; value: string;
setValue: React.Dispatch<any>;
maxHeight: string; maxHeight: string;
wrapperProps?: ComponentProps<typeof Border>;
}; };
export default function MarkdownEditorPreviewComponent({ export default function MarkdownEditorPreviewComponent({
value, value,
setValue,
maxHeight, maxHeight,
wrapperProps,
}: Props) { }: Props) {
try { try {
const [mdxSource, setMdxSource] = const [mdxSource, setMdxSource] =
@ -56,9 +56,11 @@ export default function MarkdownEditorPreviewComponent({
return ( return (
<Border <Border
{...wrapperProps}
className={twMerge( className={twMerge(
`w-full max-h-[${maxHeight}] h-[${maxHeight}] block px-6 pb-10`, `w-full max-h-[${maxHeight}] h-[${maxHeight}] block px-6 pb-10`,
"overflow-auto" "overflow-auto",
wrapperProps?.className
)} )}
> >
{mdxSource ? ( {mdxSource ? (

View File

@ -27,6 +27,9 @@ export const getStaticProps: GetStaticProps<PagePropsType> = async (ctx) => {
slug: { slug: {
value: ctx.params?.slug, value: ctx.params?.slug,
}, },
published: {
value: "1",
},
}, },
}, },
}); });
@ -68,6 +71,13 @@ export const getStaticPaths: GetStaticPaths = async (ctx) => {
await datasquirel.crud<DSQL_TBENME_BLOG_POSTS>({ await datasquirel.crud<DSQL_TBENME_BLOG_POSTS>({
action: "get", action: "get",
table: "blog_posts", table: "blog_posts",
query: {
query: {
published: {
value: "1",
},
},
},
}); });
const blogPosts = blogPostRes.payload; const blogPosts = blogPostRes.payload;

View File

@ -23,6 +23,11 @@ export const getStaticProps: GetStaticProps<PagePropsType> = async (ctx) => {
field: "id", field: "id",
strategy: "DESC", strategy: "DESC",
}, },
query: {
published: {
value: "1",
},
},
}, },
}); });

View File

@ -13,6 +13,7 @@ export type DSQL_TBENME_BLOG_POSTS = {
excerpt?: string; excerpt?: string;
body?: string; body?: string;
metadata?: string; metadata?: string;
published?: 0 | 1;
date_created?: string; date_created?: string;
date_created_code?: number; date_created_code?: number;
date_created_timestamp?: string; date_created_timestamp?: string;