From df20a472533bd9bd518f232315f6125472217d68 Mon Sep 17 00:00:00 2001 From: Emma Date: Sat, 16 Mar 2024 09:18:16 -0600 Subject: [PATCH] toolbox: adds devtoolbox to easily manage debug components --- app/client.tsx | 2 + app/globals.css | 4 +- app/help/[article]/client.tsx | 2 + app/layout.tsx | 13 +++++-- components/devtools/Toolbox.tsx | 52 ++++++++++++++++++++++++++ components/devtools/context.tsx | 66 +++++++++++++++++++++++++++++++++ components/loader.tsx | 2 +- components/ttcmd/index.tsx | 34 +++++++++++------ hooks/useRefCallback.ts | 16 ++++---- lib/tcmd/TokenIdentifiers.tsx | 4 +- md/home.md | 18 ++++++--- 11 files changed, 181 insertions(+), 32 deletions(-) create mode 100644 components/devtools/Toolbox.tsx create mode 100644 components/devtools/context.tsx diff --git a/app/client.tsx b/app/client.tsx index d25feb3..bd52c7c 100644 --- a/app/client.tsx +++ b/app/client.tsx @@ -9,6 +9,8 @@ export const HomeClient: FC<{ body: Promise }> = ({ body }) => { return ( ); }; diff --git a/app/globals.css b/app/globals.css index e05a5ad..ed3088f 100644 --- a/app/globals.css +++ b/app/globals.css @@ -31,7 +31,7 @@ } .heading { - @apply pb-6 border-b border-b-primary-500 dark:border-b-dark-500 min-w-full; + @apply pb-6 mb-6 border-b border-b-primary-500 dark:border-b-dark-500 min-w-full; } .heading h1 { @apply text-5xl font-bold; @@ -50,7 +50,7 @@ @apply dark:text-primary-500 text-primary-100 py-4 px-6 font-bold text-lg; } .p { - @apply py-1; + @apply pb-1; } .poppable { diff --git a/app/help/[article]/client.tsx b/app/help/[article]/client.tsx index 20ed9ba..e2bd247 100644 --- a/app/help/[article]/client.tsx +++ b/app/help/[article]/client.tsx @@ -52,6 +52,8 @@ export const HelpClient: FC<{ body: Promise; title: string }> = ({ {toc && ( diff --git a/app/layout.tsx b/app/layout.tsx index c16fbc5..3c359e6 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -9,6 +9,7 @@ import { QuestionMarkCircleIcon, } from "@heroicons/react/24/solid"; import Link from "next/link"; +import { DevToolboxContextProvider } from "@/components/devtools/context"; const inter = Inter({ subsets: ["latin"] }); @@ -50,6 +51,8 @@ export default function RootLayout({ }, ]; + console.log(process.env.NODE_ENV); + return ( @@ -71,9 +74,13 @@ export default function RootLayout({ ))} -
- {children} -
+ +
+ {children} +
+
diff --git a/components/devtools/Toolbox.tsx b/components/devtools/Toolbox.tsx new file mode 100644 index 0000000..a45f130 --- /dev/null +++ b/components/devtools/Toolbox.tsx @@ -0,0 +1,52 @@ +import { Portal } from "@/lib/portal/components"; +import { FC, PropsWithChildren, use, useEffect, useState } from "react"; +import { DevToolboxContext } from "./context"; +import { WrenchScrewdriverIcon } from "@heroicons/react/24/solid"; +import { XMarkIcon } from "@heroicons/react/16/solid"; + +export const DevToolbox: FC = () => { + const { tools, shouldShowDevTools } = use(DevToolboxContext); + const [open, setOpen] = useState(false); + return shouldShowDevTools + ? ( + +
+ {open + ? ( +
+ +

Dev Toolbox

+ {Object.values(tools)} +
+ ) + : ( +
+ +
+ )} +
+
+ ) + : <>; +}; + +export const DevTool: FC> = ( + { children, id }, +) => { + const { addTool, removeTool } = use(DevToolboxContext); + useEffect(() => { + addTool(id, children); + (() => removeTool(id)); + }, [addTool, children, id, removeTool]); + + return <>; +}; diff --git a/components/devtools/context.tsx b/components/devtools/context.tsx new file mode 100644 index 0000000..e3dfbeb --- /dev/null +++ b/components/devtools/context.tsx @@ -0,0 +1,66 @@ +"use client"; + +import { + createContext, + Dispatch, + FC, + PropsWithChildren, + ReactNode, + SetStateAction, + useCallback, + useEffect, + useState, +} from "react"; +import { DevToolbox } from "./Toolbox"; + +interface ContextProps { + tools: Record; + addTool: (key: string, r: ReactNode) => void; + removeTool: (key: string) => void; + shouldShowDevTools: boolean; + setShouldShowDevTools: Dispatch>; +} + +export const DevToolboxContext = createContext({ + tools: {}, + addTool: () => {}, + removeTool: () => {}, + shouldShowDevTools: false, + setShouldShowDevTools: () => {}, +}); + +export const DevToolboxContextProvider: FC< + PropsWithChildren<{ isDev: boolean }> +> = ( + { children, isDev }, +) => { + console.log(isDev); + const [tools, setTools] = useState>({}); + const [shouldShowDevTools, setShouldShowDevTools] = useState(isDev); + + const addTool = useCallback((key: string, r: ReactNode) => { + setTools((t) => ({ ...t, [key]: r })); + }, []); + const removeTool = useCallback((key: string) => { + setTools((t) => ({ ...t, [key]: undefined })); + }, []); + + useEffect(() => { + if (localStorage.getItem("dev")) setShouldShowDevTools(true); + }, []); + + return ( + + {children} + + + ); +}; diff --git a/components/loader.tsx b/components/loader.tsx index da1c214..15ab000 100644 --- a/components/loader.tsx +++ b/components/loader.tsx @@ -72,7 +72,7 @@ export const MDSkeletonLoader: FC = () => { i, ) => (
  • boolean } -> = ({ body, escapeTOC = () => false }) => { +interface Props { + body: string; + escapeTOC?: (tokens: Token[]) => boolean; + parserId: string; + title: string; +} + +export const TTCMD: FC = ( + { body, parserId, escapeTOC = () => false, title }, +) => { const elements = useMemo(() => createElements(body), [body]); const [toc, start, end] = useMemo(() => { @@ -31,15 +37,19 @@ export const TTCMD: FC< setHasEscapedTOC(escapeTOC(toc)); }, [escapeTOC, toc]); + console.log("mdId", parserId); + return ( }> - + + + {hasEscapedTOC !== undefined && ( () : [T | null, (arg: T) => void] => { +export const useRefCallback = (): [ + T | null, + (arg: T) => void, +] => { const ref = useRef(null); const setRef = useCallback((val: T) => { - console.log(val); if (ref.current) { // does something? } @@ -12,8 +14,8 @@ export const useRefCallback = () : [T | null, (arg: T) => void] = // also does something? } - ref.current = val - }, []) + ref.current = val; + }, []); - return [ref.current, setRef] -} \ No newline at end of file + return [ref.current, setRef]; +}; diff --git a/lib/tcmd/TokenIdentifiers.tsx b/lib/tcmd/TokenIdentifiers.tsx index 479f6c1..c4372f9 100644 --- a/lib/tcmd/TokenIdentifiers.tsx +++ b/lib/tcmd/TokenIdentifiers.tsx @@ -108,11 +108,11 @@ export const buildOnlyDefaultElements = () => { style={{ "--grid-cols": metadata.columns, } as React.CSSProperties} - className="grid grid-cols-dynamic gap-x-8 gap-y-6 mb-6" + className="grid grid-cols-dynamic gap-x-8 mb-6" > {children?.map((c) => { const Comp = c.metadata.span ? Fragment : "div"; - return {c.render(c)}; + return {c.render(c)}; })} ); diff --git a/md/home.md b/md/home.md index 4d6611d..5dd16bc 100644 --- a/md/home.md +++ b/md/home.md @@ -2,7 +2,7 @@ Tabletop Commander (TTC) is a rules-and-tools app for tabletop games - board, card, war, role-playing, you name it! It is the spiritual successor of Chapter Master by Emmaline Autumn, a Warhammer 40,000 9th Edition rules reference and game helper. -Emma decided to move on from Chapter Master as her interest in 40k was supplanted by the greater wargaming hobby after the release of 10th edition made clear that Chapter Master was too inflexible and tedious to work on. +Emma decided to move on from Chapter Master as her interest in Warhammer 40k waned, replaced by a broader enthusiasm for the wargaming hobby. The release of the 10th edition highlighted Chapter Master's inflexibility and tediousness, prompting her to seek new avenues. See, Emma had a vision that anyone could contribute to making rules corrections so that anyone could have all of the rules as they currently exist. This ballooned into the idea that you could have all the rules as they existed at *any point in time.* As soon as she realized that every code change either needed to keep that backward compatibility in mind or would cause the data to no longer be usable, she decided to drop Chapter Master entirely. @@ -16,7 +16,7 @@ It didn't sit right with her. A big project no longer being worked on and a dead ### Game Systems -The basis of TTC is called a Game System Package. This package +The basis of TTC is called a Game System. This package includes everything needed for a game system, including schemas, publications, and tools. Players can follow a Game System to get consistently updated content publications, or fork it to @@ -81,12 +81,20 @@ Publications use an enhanced markdown syntax (ttcMD) that implements ttcQuery, and adds a bit of custom syntax for things like pop-overs and styling hints for rendering. -The styling aspect is similar to a very trimmed down CSS, but -can accomplish quite a lot. For example, this page is actually -built using ttcMD! +Though it uses markdown as its base syntax, ttcMD could more accurately be called a templating language as it contains a lot of custom elements to handle different layouts [~~cta Learn More](/help/Publications.md) ]] +[[2 + +Want to keep up with TTC? Join us over at the CyborgGrizzly Games Discord server! Come discuss tabletop gaming, stay updated on the latest developments with Tabletop Commander, and collaborate with fellow gamers to create and update game systems. It's the perfect spot to connect with like-minded enthusiasts and be part of shaping the future of tabletop gaming. Don't miss out – hop on the Discord server today! + +Disclaimer: *I'm so sorry, I had ChatGPT write that last paragraph. I tried to save it, but it's just so... corporate* + +[~~cta Join the Discord](https://discord.gg/bePt7MQHQA) + +]] /[] +