From 33e35dc1971a9710cfe8979eda868835cab5deaf Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 10:07:23 -0400 Subject: [PATCH 01/11] Delete unused box shadow config. --- docs/tailwind.config.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js index d4bec14c..244a2043 100644 --- a/docs/tailwind.config.js +++ b/docs/tailwind.config.js @@ -10,10 +10,6 @@ module.exports = { red: "#E35C61", grey: "#EEE", }, - boxShadow: { - button: "2px 2px 1px #4D4D4D", - "button-tablet": "4px 4px 2px #4D4D4D", - }, dropShadow: { logo: "3px 3px 2px #4D4D4D", "logo-wide-phone": "3px 3px 2px #4D4D4D", From 86c6aaa6c6b95d13212de5143196aae5d6758a27 Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 10:21:25 -0400 Subject: [PATCH 02/11] Connect links to their respective pages. --- docs/src/components/Button.tsx | 9 ++++++--- docs/src/components/ButtonList.tsx | 8 ++++---- docs/src/components/IntroText.tsx | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/src/components/Button.tsx b/docs/src/components/Button.tsx index beea5989..dcb5f5c7 100644 --- a/docs/src/components/Button.tsx +++ b/docs/src/components/Button.tsx @@ -1,19 +1,22 @@ import clsx from "clsx"; -import { CSSProperties } from "react"; +import Link from "next/link"; type ButtonProps = { + href: string; text: string; isDepressed?: boolean; isWide?: boolean; }; export function Button({ + href, text, isDepressed = false, isWide = false, }: ButtonProps) { return ( -
{text} -
+ ); } diff --git a/docs/src/components/ButtonList.tsx b/docs/src/components/ButtonList.tsx index ef87d281..5b02fc34 100644 --- a/docs/src/components/ButtonList.tsx +++ b/docs/src/components/ButtonList.tsx @@ -15,10 +15,10 @@ export function ButtonList() { "desktop:w-[490px]", ])} > - + + + + + + + + + + ); } diff --git a/docs/src/components/IntroText.tsx b/docs/src/components/IntroText.tsx index 73cb267c..83c187b2 100644 --- a/docs/src/components/IntroText.tsx +++ b/docs/src/components/IntroText.tsx @@ -1,5 +1,6 @@ import clsx from "clsx"; import { Button } from "./Button"; +import Link from "next/link"; export function IntroText() { return ( @@ -28,11 +29,21 @@ export function IntroText() { ])} > Which is
{" "} - literal,{" "} - lensable -
and like a filesystem + + literal + + ,{" "} + + lensable + +
and{" "} + + like a filesystem +

- +
); } - -type LinkProps = { - href: string; - children: React.ReactNode; -}; -function Link({ href, children }: LinkProps) { - return ( - - {children} - - ); -} From 8ac09d1b0705137b61f5b2635f42e8badf0bbba0 Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 17:10:49 -0400 Subject: [PATCH 05/11] Revert "Delete unused box shadow config." This reverts commit 519d0983525900ec8784e92368638c1522607479. --- docs/tailwind.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js index 244a2043..d4bec14c 100644 --- a/docs/tailwind.config.js +++ b/docs/tailwind.config.js @@ -10,6 +10,10 @@ module.exports = { red: "#E35C61", grey: "#EEE", }, + boxShadow: { + button: "2px 2px 1px #4D4D4D", + "button-tablet": "4px 4px 2px #4D4D4D", + }, dropShadow: { logo: "3px 3px 2px #4D4D4D", "logo-wide-phone": "3px 3px 2px #4D4D4D", From b06c383e1bb76035b691c0373e01ab1cec068831 Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 17:26:37 -0400 Subject: [PATCH 06/11] Remove all the variant logic from the Button component. --- docs/src/components/Button.tsx | 23 ++---------- docs/src/components/ButtonList.tsx | 60 ++++++++++++++++++++++++++++-- docs/src/components/IntroText.tsx | 17 ++++++++- 3 files changed, 75 insertions(+), 25 deletions(-) diff --git a/docs/src/components/Button.tsx b/docs/src/components/Button.tsx index 873232c1..885d7524 100644 --- a/docs/src/components/Button.tsx +++ b/docs/src/components/Button.tsx @@ -3,48 +3,31 @@ import { ReactNode } from "react"; type ButtonProps = { children: ReactNode; - isDepressed?: boolean; - isWide?: boolean; + className?: string; }; -export function Button({ - children, - isDepressed = false, - isWide = false, -}: ButtonProps) { +export function Button({ children, className }: ButtonProps) { return ( {children} diff --git a/docs/src/components/ButtonList.tsx b/docs/src/components/ButtonList.tsx index 0cec1339..f330ce16 100644 --- a/docs/src/components/ButtonList.tsx +++ b/docs/src/components/ButtonList.tsx @@ -21,21 +21,73 @@ export function ButtonList() { ])} > - - + - + -
); } + +const sharedClasses = clsx([ + "w-[44px]", + "h-[23px]", + "rounded-[4px]", + "text-[14px]", + "tablet:w-[73px]", + "desktop:w-[110px]", +]); + +const pressedClasses = clsx([ + "mt-[1px]", + "text-white", + "bg-blue", + "shadow-none", + "tablet:mt-[2px]", + "shadow-none", + "tablet:mt-[3px]", + sharedClasses, +]); + +const unPressedClasses = clsx([ + "text-black", + "bg-white", + "shadow-button", + "tablet:shadow-button-tablet", + sharedClasses, +]); diff --git a/docs/src/components/IntroText.tsx b/docs/src/components/IntroText.tsx index 83c187b2..16620f96 100644 --- a/docs/src/components/IntroText.tsx +++ b/docs/src/components/IntroText.tsx @@ -42,7 +42,22 @@ export function IntroText() {

- +
Date: Tue, 3 Oct 2023 18:12:13 -0400 Subject: [PATCH 07/11] Add Navigation components. --- docs/src/components/Button.tsx | 2 - docs/src/components/ButtonList.tsx | 8 +- docs/src/components/Icons/CaretBottom.tsx | 9 ++ docs/src/components/IntroText.tsx | 2 + .../components/Navigation/LanguageSelect.tsx | 35 ++++++ docs/src/components/Navigation/Navigation.tsx | 103 ++++++++++++++++++ docs/src/lib/languageFromPath.ts | 23 ++++ docs/src/pages/_app.tsx | 10 +- docs/src/pages/index.mdx | 3 +- docs/src/pages/js/index.mdx | 54 +++++---- 10 files changed, 216 insertions(+), 33 deletions(-) create mode 100644 docs/src/components/Icons/CaretBottom.tsx create mode 100644 docs/src/components/Navigation/LanguageSelect.tsx create mode 100644 docs/src/components/Navigation/Navigation.tsx create mode 100644 docs/src/lib/languageFromPath.ts diff --git a/docs/src/components/Button.tsx b/docs/src/components/Button.tsx index 885d7524..20a334b4 100644 --- a/docs/src/components/Button.tsx +++ b/docs/src/components/Button.tsx @@ -16,8 +16,6 @@ export function Button({ children, className }: ButtonProps) { "border", "border-2", "border-black", - "hover:text-white", - "hover:bg-blue", "cursor-pointer", "tablet:h-[35px]", "tablet:text-[22px]", diff --git a/docs/src/components/ButtonList.tsx b/docs/src/components/ButtonList.tsx index f330ce16..4f05fec3 100644 --- a/docs/src/components/ButtonList.tsx +++ b/docs/src/components/ButtonList.tsx @@ -2,11 +2,11 @@ import clsx from "clsx"; import Link from "next/link"; import { Button } from "./Button"; import { useRouter } from "next/dist/client/router"; -import { languageFromPath } from "@/lib/languageFromPath"; +import { getPathParts } from "@/lib/languageFromPath"; export function ButtonList() { const router = useRouter(); - const selectedLanguage = languageFromPath(router.pathname); + const selectedLanguage = getPathParts(router.pathname).language; return (
) { + return ( + + + + ); +} diff --git a/docs/src/components/IntroText.tsx b/docs/src/components/IntroText.tsx index 16620f96..9f67002d 100644 --- a/docs/src/components/IntroText.tsx +++ b/docs/src/components/IntroText.tsx @@ -54,6 +54,8 @@ export function IntroText() { "bg-white", "shadow-button", "tablet:shadow-button-tablet", + "hover:text-white", + "hover:bg-blue", ])} > get started diff --git a/docs/src/components/Navigation/LanguageSelect.tsx b/docs/src/components/Navigation/LanguageSelect.tsx new file mode 100644 index 00000000..4436dd86 --- /dev/null +++ b/docs/src/components/Navigation/LanguageSelect.tsx @@ -0,0 +1,35 @@ +import { LanguageSlug, languageSlugsToLabels } from "@/lib/languageFromPath"; +import { Listbox } from "@headlessui/react"; +import clsx from "clsx"; +import { Dispatch, SetStateAction } from "react"; +import { Button } from "../Button"; +import { CaretBottom } from "../Icons/CaretBottom"; + +type LanguageSelectProps = { + selectedLanguage: LanguageSlug; + handleChange(value: LanguageSlug): void; +}; + +export function LanguageSelect({ + selectedLanguage, + handleChange, +}: LanguageSelectProps) { + return ( +
+ + + + + + jvm + js + go + ... + + +
+ ); +} diff --git a/docs/src/components/Navigation/Navigation.tsx b/docs/src/components/Navigation/Navigation.tsx new file mode 100644 index 00000000..f5e1105d --- /dev/null +++ b/docs/src/components/Navigation/Navigation.tsx @@ -0,0 +1,103 @@ +import { LanguageSlug, getPathParts } from "@/lib/languageFromPath"; +import clsx from "clsx"; +import { useRouter } from "next/dist/client/router"; +import Link from "next/link"; +import { Button } from "../Button"; +import { Logo } from "../Logo"; +import { LanguageSelect } from "./LanguageSelect"; + +export function Navigation() { + const router = useRouter(); + const pathParts = getPathParts(router.pathname); + + function handleChange(value: LanguageSlug) { + let nextRoute = "/" + value; + if (pathParts.subpath) { + nextRoute += "/" + pathParts.subpath; + } + router.push(nextRoute); + } + + return ( +
+
+ + + + +
+ +
+ ); +} + +const sharedClasses = clsx([ + "h-[23px]", + "rounded-[4px]", + "text-[14px]", + "px-2", +]); + +const pressedClasses = clsx([ + "mt-[1px]", + "text-white", + "bg-blue", + "shadow-none", + "tablet:mt-[3px]", + sharedClasses, +]); + +const unPressedClasses = clsx([ + "text-black", + "bg-white", + "shadow-button", + "tablet:shadow-button-tablet", + sharedClasses, +]); diff --git a/docs/src/lib/languageFromPath.ts b/docs/src/lib/languageFromPath.ts new file mode 100644 index 00000000..36d2dd86 --- /dev/null +++ b/docs/src/lib/languageFromPath.ts @@ -0,0 +1,23 @@ +export const languageSlugsToLabels = { + jvm: "jvm", + js: "js", + go: "go", + "other-platforms": "...", +}; + +export type LanguageSlug = keyof typeof languageSlugsToLabels; + +export type PathParts = { + language: LanguageSlug; + subpath: "" | "get-started" | "advanced"; +}; + +// TODO handle 404s +export function getPathParts(path: string): PathParts { + const splitPath = path.split("/"); + console.log(splitPath); + return { + language: splitPath[1], + subpath: splitPath.length === 3 ? splitPath[2] : "", + } as PathParts; +} diff --git a/docs/src/pages/_app.tsx b/docs/src/pages/_app.tsx index 9a160d31..5b86c48a 100644 --- a/docs/src/pages/_app.tsx +++ b/docs/src/pages/_app.tsx @@ -1,9 +1,10 @@ -import { AppProps } from "next/app"; -import Head from "next/head"; +import { Hero } from "@/components/Hero"; +import { Navigation } from "@/components/Navigation/Navigation"; +import * as mdxComponents from "@/components/mdx"; import { MDXProvider } from "@mdx-js/react"; import clsx from "clsx"; - -import * as mdxComponents from "@/components/mdx"; +import { AppProps } from "next/app"; +import Head from "next/head"; import "@/styles/tailwind.css"; @@ -25,6 +26,7 @@ export default function App({ Component, pageProps }: AppProps) { "wide-phone:py-2", ])} > + {pageProps.showHero ? : }
diff --git a/docs/src/pages/index.mdx b/docs/src/pages/index.mdx index f840e357..c3157a0a 100644 --- a/docs/src/pages/index.mdx +++ b/docs/src/pages/index.mdx @@ -1,7 +1,8 @@ import { Hero } from "@/components/Hero"; import { Selfie } from "@/components/Selfie"; - +{/* show the homepage hero component and hide the navigation used everywhere else in the app */} +export const showHero = true ## is literal diff --git a/docs/src/pages/js/index.mdx b/docs/src/pages/js/index.mdx index 4f7b08d1..d5b5e9b0 100644 --- a/docs/src/pages/js/index.mdx +++ b/docs/src/pages/js/index.mdx @@ -1,14 +1,21 @@ -## selfie is literal +import { Selfie } from "@/components/Selfie"; + +## is literal Sure, you could write your assertions like this. ```javascript -describe('login', () => { - it('should set the login cookie', () => { - const response = request.post('/confirm/login/erjchFbCXxMlUfFXx3oYiO-Rj6zM7tRGdRV8ziqRn5Jh', { - followRedirect: false - }); - expect(response.cookies.login).toBe("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiaXNzIjoiZGlmZnBsdWcuY29tIiwiYXVkIjoiZGlmZnBsdWcuY29tIiwiaWF0IjoxNTc3NjY0MDAsImVtYWlsIjoibHVrZS5za3l3YWxrZXJAZGlmZnBsdWcuY29tIiwic2FsZXMiOiJ0cnVlIn0.v7nes7_rTa0NiwTz6OLIAmRZJ-XzzGULRiAPWBiV5iI"); +describe("login", () => { + it("should set the login cookie", () => { + const response = request.post( + "/confirm/login/erjchFbCXxMlUfFXx3oYiO-Rj6zM7tRGdRV8ziqRn5Jh", + { + followRedirect: false, + } + ); + expect(response.cookies.login).toBe( + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiaXNzIjoiZGlmZnBsdWcuY29tIiwiYXVkIjoiZGlmZnBsdWcuY29tIiwiaWF0IjoxNTc3NjY0MDAsImVtYWlsIjoibHVrZS5za3l3YWxrZXJAZGlmZnBsdWcuY29tIiwic2FsZXMiOiJ0cnVlIn0.v7nes7_rTa0NiwTz6OLIAmRZJ-XzzGULRiAPWBiV5iI" + ); }); }); ``` @@ -16,11 +23,14 @@ describe('login', () => { But isn't this easier to read? And also more complete? ```javascript -describe('login', () => { - it('should match expected headers', () => { - const response = request.post('/confirm/login/erjchFbCXxMlUfFXx3oYiO-Rj6zM7tRGdRV8ziqRn5Jh', { - followRedirect: false - }); +describe("login", () => { + it("should match expected headers", () => { + const response = request.post( + "/confirm/login/erjchFbCXxMlUfFXx3oYiO-Rj6zM7tRGdRV8ziqRn5Jh", + { + followRedirect: false, + } + ); expectSelfie(response.headers).toBe(` content-type=text/plain ... @@ -32,25 +42,25 @@ describe('login', () => { ... And so on ... -## selfie is lensable +## is lensable 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. ```javascript -describe('gzipFavicon', () => { - it('should match the disk content', () => { - const response = request.get('/favicon.ico', { encoding: 'gzip' }); +describe("gzipFavicon", () => { + it("should match the disk content", () => { + const response = request.get("/favicon.ico", { encoding: "gzip" }); expectSelfie(response).toMatchDisk(); }); }); -describe('orderFlow', () => { - it('should match the disk content', () => { - let response = request.get('/orders'); - expectSelfie(response).toMatchDisk('initial'); +describe("orderFlow", () => { + it("should match the disk content", () => { + let response = request.get("/orders"); + expectSelfie(response).toMatchDisk("initial"); postOrder(); - response = request.get('/orders'); - expectSelfie(response).toMatchDisk('ordered'); + response = request.get("/orders"); + expectSelfie(response).toMatchDisk("ordered"); }); }); ``` From 6453b107b9bc07fece231ab042def7faf593acfe Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 19:23:58 -0400 Subject: [PATCH 08/11] Use selfie logo in headings. --- docs/src/pages/jvm/index.mdx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/src/pages/jvm/index.mdx b/docs/src/pages/jvm/index.mdx index d9a2a613..b95e48fc 100644 --- a/docs/src/pages/jvm/index.mdx +++ b/docs/src/pages/jvm/index.mdx @@ -1,4 +1,6 @@ -## selfie is literal +import { Selfie } from "@/components/Selfie"; + +## is literal Sure, you could write your assertions like this. @@ -55,7 +57,7 @@ public void preventCssBloat() { } ``` -## selfie is lensable +## is lensable 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. @@ -91,8 +93,8 @@ H4sIAAAAAAAA/8pIzcnJVyjPL8pJUQQAlQYXAAAA TODO. -## selfie is like a filesystem +## is like a filesystem Selfie's snapshot files `.ss` are incredibly simple to parse, and you can use `selfie-lib` to parse them for you if you want. You can treat them as an output deliverable of your code, and use them as an input to other tooling. - -TODO. \ No newline at end of file + +TODO. From cec03f6a0ebdb77c37a433469875df889962808c Mon Sep 17 00:00:00 2001 From: toddriley Date: Tue, 3 Oct 2023 19:32:25 -0400 Subject: [PATCH 09/11] Style the language selector. --- .../components/Navigation/LanguageSelect.tsx | 57 +++++++++++++++---- docs/src/components/Navigation/Navigation.tsx | 6 +- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/docs/src/components/Navigation/LanguageSelect.tsx b/docs/src/components/Navigation/LanguageSelect.tsx index 4436dd86..699c48d6 100644 --- a/docs/src/components/Navigation/LanguageSelect.tsx +++ b/docs/src/components/Navigation/LanguageSelect.tsx @@ -1,7 +1,6 @@ import { LanguageSlug, languageSlugsToLabels } from "@/lib/languageFromPath"; import { Listbox } from "@headlessui/react"; import clsx from "clsx"; -import { Dispatch, SetStateAction } from "react"; import { Button } from "../Button"; import { CaretBottom } from "../Icons/CaretBottom"; @@ -18,16 +17,54 @@ export function LanguageSelect({
- + {({ open }) => { + return ( + + ); + }} - - jvm - js - go - ... + + {Object.keys(languageSlugsToLabels) + .filter((slug) => slug !== selectedLanguage) + .map((slug) => ( + + + + ))}
diff --git a/docs/src/components/Navigation/Navigation.tsx b/docs/src/components/Navigation/Navigation.tsx index f5e1105d..3bb2793c 100644 --- a/docs/src/components/Navigation/Navigation.tsx +++ b/docs/src/components/Navigation/Navigation.tsx @@ -37,7 +37,7 @@ export function Navigation() { handleChange={handleChange} />
-