From b609a2ffa9b8d906c8d217937c21893257fa11bd Mon Sep 17 00:00:00 2001 From: toddriley Date: Mon, 2 Oct 2023 16:45:34 -0400 Subject: [PATCH 1/5] Replace the CodeGroup component with our own - much simpler - components. --- docs/src/components/Code.jsx | 298 ----------------------------------- docs/src/components/Tag.jsx | 58 ------- docs/src/components/mdx.tsx | 21 ++- 3 files changed, 19 insertions(+), 358 deletions(-) delete mode 100644 docs/src/components/Code.jsx delete mode 100644 docs/src/components/Tag.jsx diff --git a/docs/src/components/Code.jsx b/docs/src/components/Code.jsx deleted file mode 100644 index 4bfc80ab..00000000 --- a/docs/src/components/Code.jsx +++ /dev/null @@ -1,298 +0,0 @@ -import { - Children, - createContext, - useContext, - useEffect, - useRef, - useState, -} from "react"; -import { Tab } from "@headlessui/react"; -import clsx from "clsx"; -import { create } from "zustand"; - -import { Tag } from "@/components/Tag"; - -const languageNames = { - js: "JavaScript", - ts: "TypeScript", - javascript: "JavaScript", - typescript: "TypeScript", - php: "PHP", - python: "Python", - ruby: "Ruby", - go: "Go", -}; - -function getPanelTitle({ title, language }) { - return title ?? languageNames[language] ?? "Code"; -} - -function ClipboardIcon(props) { - return ( - - ); -} - -function CopyButton({ code }) { - let [copyCount, setCopyCount] = useState(0); - let copied = copyCount > 0; - - useEffect(() => { - if (copyCount > 0) { - let timeout = setTimeout(() => setCopyCount(0), 1000); - return () => { - clearTimeout(timeout); - }; - } - }, [copyCount]); - - return ( - - ); -} - -function CodePanelHeader({ tag, label }) { - if (!tag && !label) { - return null; - } - - return ( -
- {tag && ( -
- {tag} -
- )} - {tag && label && ( - - )} - {label && ( - {label} - )} -
- ); -} - -function CodePanel({ tag, label, code, children }) { - let child = Children.only(children); - - return ( -
- -
-
{children}
- -
-
- ); -} - -function CodeGroupHeader({ title, children, selectedIndex }) { - let hasTabs = Children.count(children) > 1; - - if (!title && !hasTabs) { - return null; - } - - return ( -
- {title && ( -

- {title} -

- )} - {hasTabs && ( - - {Children.map(children, (child, childIndex) => ( - - {getPanelTitle(child.props)} - - ))} - - )} -
- ); -} - -function CodeGroupPanels({ children, ...props }) { - let hasTabs = Children.count(children) > 1; - - if (hasTabs) { - return ( - - {Children.map(children, (child) => ( - - {child} - - ))} - - ); - } - - return {children}; -} - -function usePreventLayoutShift() { - let positionRef = useRef(); - let rafRef = useRef(); - - useEffect(() => { - return () => { - window.cancelAnimationFrame(rafRef.current); - }; - }, []); - - return { - positionRef, - preventLayoutShift(callback) { - let initialTop = positionRef.current.getBoundingClientRect().top; - - callback(); - - rafRef.current = window.requestAnimationFrame(() => { - let newTop = positionRef.current.getBoundingClientRect().top; - window.scrollBy(0, newTop - initialTop); - }); - }, - }; -} - -const usePreferredLanguageStore = create((set) => ({ - preferredLanguages: [], - addPreferredLanguage: (language) => - set((state) => ({ - preferredLanguages: [ - ...state.preferredLanguages.filter( - (preferredLanguage) => preferredLanguage !== language - ), - language, - ], - })), -})); - -function useTabGroupProps(availableLanguages) { - let { preferredLanguages, addPreferredLanguage } = - usePreferredLanguageStore(); - let [selectedIndex, setSelectedIndex] = useState(0); - let activeLanguage = [...availableLanguages].sort( - (a, z) => preferredLanguages.indexOf(z) - preferredLanguages.indexOf(a) - )[0]; - let languageIndex = availableLanguages.indexOf(activeLanguage); - let newSelectedIndex = languageIndex === -1 ? selectedIndex : languageIndex; - if (newSelectedIndex !== selectedIndex) { - setSelectedIndex(newSelectedIndex); - } - - let { positionRef, preventLayoutShift } = usePreventLayoutShift(); - - return { - as: "div", - ref: positionRef, - selectedIndex, - onChange: (newSelectedIndex) => { - preventLayoutShift(() => - addPreferredLanguage(availableLanguages[newSelectedIndex]) - ); - }, - }; -} - -const CodeGroupContext = createContext(false); - -export function CodeGroup({ children, title, ...props }) { - let languages = Children.map(children, (child) => getPanelTitle(child.props)); - let tabGroupProps = useTabGroupProps(languages); - let hasTabs = Children.count(children) > 1; - let Container = hasTabs ? Tab.Group : "div"; - let containerProps = hasTabs ? tabGroupProps : {}; - let headerProps = hasTabs - ? { selectedIndex: tabGroupProps.selectedIndex } - : {}; - - return ( - - - - {children} - - {children} - - - ); -} - -export function Code({ children, ...props }) { - let isGrouped = useContext(CodeGroupContext); - - if (isGrouped) { - return ; - } - - return {children}; -} - -export function Pre({ children, ...props }) { - let isGrouped = useContext(CodeGroupContext); - - if (isGrouped) { - return children; - } - - return {children}; -} diff --git a/docs/src/components/Tag.jsx b/docs/src/components/Tag.jsx deleted file mode 100644 index fb411b75..00000000 --- a/docs/src/components/Tag.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import clsx from "clsx"; - -const variantStyles = { - medium: "rounded-lg px-1.5 ring-1 ring-inset", -}; - -const colorStyles = { - emerald: { - small: "text-emerald-500 dark:text-emerald-400", - medium: - "ring-emerald-300 dark:ring-emerald-400/30 bg-emerald-400/10 text-emerald-500 dark:text-emerald-400", - }, - sky: { - small: "text-sky-500", - medium: - "ring-sky-300 bg-sky-400/10 text-sky-500 dark:ring-sky-400/30 dark:bg-sky-400/10 dark:text-sky-400", - }, - amber: { - small: "text-amber-500", - medium: - "ring-amber-300 bg-amber-400/10 text-amber-500 dark:ring-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400", - }, - rose: { - small: "text-red-500 dark:text-rose-500", - medium: - "ring-rose-200 bg-rose-50 text-red-500 dark:ring-rose-500/20 dark:bg-rose-400/10 dark:text-rose-400", - }, - zinc: { - small: "text-zinc-400 dark:text-zinc-500", - medium: - "ring-zinc-200 bg-zinc-50 text-zinc-500 dark:ring-zinc-500/20 dark:bg-zinc-400/10 dark:text-zinc-400", - }, -}; - -const valueColorMap = { - get: "emerald", - post: "sky", - put: "amber", - delete: "rose", -}; - -export function Tag({ - children, - variant = "medium", - color = valueColorMap[children.toLowerCase()] ?? "emerald", -}) { - return ( - - {children} - - ); -} diff --git a/docs/src/components/mdx.tsx b/docs/src/components/mdx.tsx index c90c0035..16285828 100644 --- a/docs/src/components/mdx.tsx +++ b/docs/src/components/mdx.tsx @@ -1,8 +1,7 @@ import clsx from "clsx"; -export { CodeGroup, Code as code, Pre as pre } from "@/components/Code"; type ParentComponentProps = { - children: React.ReactNode; + children?: React.ReactNode; }; export function Row({ children }: ParentComponentProps) { @@ -29,3 +28,21 @@ export function Col({ children, sticky = false }: ColProps) { ); } + +export function code({ children, ...props }: ParentComponentProps) { + return children ? ( + + ) : ( + + ); +} + +export function pre({ children, ...props }: ParentComponentProps) { + return ( +
+
+        {children}
+      
+
+ ); +} From 46c4ffb5f2d21abaf6b52af10e9fd400d86815c2 Mon Sep 17 00:00:00 2001 From: toddriley Date: Mon, 2 Oct 2023 16:46:04 -0400 Subject: [PATCH 2/5] Use github light theme for code blocks. --- docs/src/mdx/rehype.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/mdx/rehype.mjs b/docs/src/mdx/rehype.mjs index a57309aa..5936bf4c 100644 --- a/docs/src/mdx/rehype.mjs +++ b/docs/src/mdx/rehype.mjs @@ -20,11 +20,11 @@ function rehypeParseCodeBlocks() { } let highlighter - +const theme = await shiki.loadTheme("themes/github-light.json"); function rehypeShiki() { return async (tree) => { highlighter = - highlighter ?? (await shiki.getHighlighter({ theme: 'css-variables' })) + highlighter ?? (await shiki.getHighlighter({ theme })) visit(tree, 'element', (node) => { if (node.tagName === 'pre' && node.children[0]?.tagName === 'code') { From a031a8e01f888b585ec35ec19678be843ec3f1d2 Mon Sep 17 00:00:00 2001 From: toddriley Date: Mon, 2 Oct 2023 16:47:51 -0400 Subject: [PATCH 3/5] Add framework for custom code block colors if desired. --- docs/src/styles/tailwind.css | 14 ++++++++++++++ docs/tailwind.config.js | 1 + 2 files changed, 15 insertions(+) diff --git a/docs/src/styles/tailwind.css b/docs/src/styles/tailwind.css index ab2e10c2..0c04e047 100644 --- a/docs/src/styles/tailwind.css +++ b/docs/src/styles/tailwind.css @@ -12,4 +12,18 @@ @apply text-lg; @apply desktop:text-2xl; } + + :root { + --shiki-color-text: #BBB; + --shiki-color-background: #EEE; + --shiki-token-constant: #ff8866; + --shiki-token-string: #8855ff; + --shiki-token-comment: #BBB; + --shiki-token-keyword: #0099ff; + --shiki-token-parameter: #33cccc; + --shiki-token-function: #FFAA00; + --shiki-token-string-expression: #8855ff; + --shiki-token-punctuation: #BBB; + --shiki-token-link: #0099ff; + } } diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js index 521bf63a..d4bec14c 100644 --- a/docs/tailwind.config.js +++ b/docs/tailwind.config.js @@ -8,6 +8,7 @@ module.exports = { blue: "#63B9E3", green: "#78ACAE", red: "#E35C61", + grey: "#EEE", }, boxShadow: { button: "2px 2px 1px #4D4D4D", From 358435bdf469cb134936237b2c0e99a5a9edcd9c Mon Sep 17 00:00:00 2001 From: toddriley Date: Mon, 2 Oct 2023 16:52:41 -0400 Subject: [PATCH 4/5] Decrease code font size. --- docs/src/components/mdx.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/components/mdx.tsx b/docs/src/components/mdx.tsx index 16285828..b963d577 100644 --- a/docs/src/components/mdx.tsx +++ b/docs/src/components/mdx.tsx @@ -39,7 +39,7 @@ export function code({ children, ...props }: ParentComponentProps) { export function pre({ children, ...props }: ParentComponentProps) { return ( -
+
         {children}
       
From e8114e7c2486c2060126067c1bff5d71b20e18b6 Mon Sep 17 00:00:00 2001 From: toddriley Date: Mon, 2 Oct 2023 16:53:00 -0400 Subject: [PATCH 5/5] Add language annotations back. --- docs/src/pages/index.mdx | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/docs/src/pages/index.mdx b/docs/src/pages/index.mdx index 68534ab3..f840e357 100644 --- a/docs/src/pages/index.mdx +++ b/docs/src/pages/index.mdx @@ -7,7 +7,7 @@ import { Selfie } from "@/components/Selfie"; Sure, you could write your assertions like this. -``` +```java @Test public void login() { given().redirects().follow(false) @@ -19,7 +19,7 @@ public void login() { But isn't this easier to read? And also more complete? -``` +```java @Test public void login() { expectSelfie( @@ -37,7 +37,7 @@ public void login() { The only reason we don't test that way already is that it's too tedious to write out that big string literal. Buf if you write this... -``` +```java @Test public void login() { expectSelfie( @@ -50,7 +50,7 @@ public void login() { It's like a printf directly into your code. And it's not just for strings, it's for any literal. -``` +```java @Test public void preventCssBloat() { int size = expectSelfie(get("/index.css").length).toBe(5_236); @@ -64,7 +64,7 @@ public void preventCssBloat() { Some snapshots are so big that it would be cumbersome to put them inline into your test code. So selfie helps you put them on disk. -``` +```java @Test public void gzipFavicon() { expectSelfie(get("/favicon.ico", ContentEncoding.GZIP)).toMatchDisk(); } @@ -77,21 +77,24 @@ Some snapshots are so big that it would be cumbersome to put them inline into yo This will generate a snapshot file like so: -``` +```html ╔═ gzipFavicon ═╗ base64 length 823 bytes -H4sIAAAAAAAA/8pIzcnJVyjPL8pJUQQAlQYXAAAA -╔═ orderFlow/initial ═╗ - - - +H4sIAAAAAAAA/8pIzcnJVyjPL8pJUQQAlQYXAAAA ╔═ orderFlow/initial ═╗ + + + + + ╔═ orderFlow/ordered ═╗ - -

Thanks for your business!

-
- Order information -

Tracking #ABC123

-
- + + +

Thanks for your business!

+
+ Order information +

Tracking #ABC123

+
+ + ``` TODO.