diff --git a/docs/public/car.webp b/docs/public/car.webp new file mode 100644 index 00000000..6473d936 Binary files /dev/null and b/docs/public/car.webp differ diff --git a/docs/public/horse.webp b/docs/public/horse.webp new file mode 100644 index 00000000..e761cb4e Binary files /dev/null and b/docs/public/horse.webp differ diff --git a/docs/src/components/ButtonList.tsx b/docs/src/components/ButtonList.tsx index 552e2952..6c43690f 100644 --- a/docs/src/components/ButtonList.tsx +++ b/docs/src/components/ButtonList.tsx @@ -12,7 +12,6 @@ export function ButtonList() { className={clsx([ "align-center", "flex", - "w-[187px]", "flex-row", "justify-between", "wide-phone:w-[220px]", @@ -65,10 +64,11 @@ export function ButtonList() { } const sharedClasses = clsx([ - "w-[44px]", + "w-[34px]", "h-[23px]", "rounded-[4px]", - "text-[14px]", + "text-[12px]", + "wide-phone:w-[44px]", "tablet:w-[73px]", "desktop:w-[110px]", "hover:text-white", diff --git a/docs/src/components/FooterCTA/Car.tsx b/docs/src/components/FooterCTA/Car.tsx new file mode 100644 index 00000000..2912777e --- /dev/null +++ b/docs/src/components/FooterCTA/Car.tsx @@ -0,0 +1,59 @@ +import clsx from "clsx"; +import { buttonClasses } from "./constants"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { getPathParts } from "@/lib/languageFromPath"; + +interface CarProps { + imageHeight: number; +} +export function Car({ imageHeight }: CarProps) { + const router = useRouter(); + const pathParts = getPathParts(router.pathname); + return ( +
+ + + let your codebase take its own selfies + + + get started + +
+ ); +} diff --git a/docs/src/components/FooterCTA/FooterCTA.tsx b/docs/src/components/FooterCTA/FooterCTA.tsx new file mode 100644 index 00000000..f95461c6 --- /dev/null +++ b/docs/src/components/FooterCTA/FooterCTA.tsx @@ -0,0 +1,87 @@ +import clsx from "clsx"; +import { useEffect, useRef, useState } from "react"; +import { Horse } from "./Horse"; +import { Car } from "./Car"; + +export function FooterCTA() { + const spacerRef = useRef(null); + const footerRef = useRef(null); + const imageRef = useRef(null); + const [imageHeight, setImageHeight] = useState(0); + + function handleResize() { + setImageHeight(imageRef.current!.height); + } + + function handleScroll() { + if (!footerRef.current || !spacerRef.current) return; + // 0 at the current scroll position, 1 at the bottom of the page + const topOfHorseFromBottomOfScreen = + window.innerHeight - spacerRef.current.getBoundingClientRect().top; + + let horseHeightScale: number; + if (topOfHorseFromBottomOfScreen < imageHeight) { + horseHeightScale = 0; + } else if (topOfHorseFromBottomOfScreen > imageHeight * 2) { + horseHeightScale = 1; + } else { + horseHeightScale = + (topOfHorseFromBottomOfScreen - imageHeight) / imageHeight; + } + footerRef.current!.style.setProperty( + "--horse-height-scale", + "" + horseHeightScale + ); + } + + useEffect(() => { + window.addEventListener("scroll", handleScroll, false); + window.addEventListener("resize", handleResize, false); + return () => { + window.removeEventListener("scroll", handleScroll); + window.removeEventListener("resize", handleResize); + }; + }, [imageHeight]); + + return ( +
+
+
+
+ +
+ +
+
+ ); +} diff --git a/docs/src/components/FooterCTA/Horse.tsx b/docs/src/components/FooterCTA/Horse.tsx new file mode 100644 index 00000000..51eb6238 --- /dev/null +++ b/docs/src/components/FooterCTA/Horse.tsx @@ -0,0 +1,62 @@ +import clsx from "clsx"; +import { buttonClasses } from "./constants"; +import Link from "next/link"; +import { MutableRefObject } from "react"; + +interface HorseProps { + imageRef: MutableRefObject; + setImageHeight: (height: number) => void; +} +export function Horse({ imageRef, setImageHeight }: HorseProps) { + return ( +
+ { + if (el) { + setImageHeight(el.height); + } + imageRef.current = el; + }} + className={clsx(["m-auto"])} + /> + + are you still writing assertions + + + by hand? + +
+ ); +} diff --git a/docs/src/components/FooterCTA/constants.ts b/docs/src/components/FooterCTA/constants.ts new file mode 100644 index 00000000..8140a34a --- /dev/null +++ b/docs/src/components/FooterCTA/constants.ts @@ -0,0 +1,24 @@ +import clsx from "clsx"; +export const buttonClasses = clsx([ + "flex", + "justify-center", + "items-center", + "border", + "border-black", + "cursor-pointer", + "border-2", + "wide-phone:border-[4px]", + "p-1", + "tablet:h-[53px]", + "rounded-[12px]", + "wide-phone:rounded-[16px]", + "text-sm", + "wide-phone:text-base", + "tablet:text-lg", + "hover:text-white", + "hover:bg-blue", + "text-black", + "bg-white", + "shadow-button", + "tablet:shadow-button-tablet", +]); diff --git a/docs/src/components/Hero.tsx b/docs/src/components/Hero.tsx index 7f6be21e..aa6db05a 100644 --- a/docs/src/components/Hero.tsx +++ b/docs/src/components/Hero.tsx @@ -42,7 +42,7 @@ export function Hero() {

{ } ``` -See the [advanced section](/jvm/advanced) for more details. \ No newline at end of file +See the [advanced section](/jvm/advanced) for more details. + + \ No newline at end of file diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js index 3b1ec40a..e16edbbe 100644 --- a/docs/tailwind.config.js +++ b/docs/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/**/*.{js,mjs,jsx,mdx,tsx}"], + content: ["./src/**/*.{js,mjs,jsx,mdx,ts,tsx}"], theme: { extend: { colors: { @@ -25,6 +25,8 @@ module.exports = { "slide-and-fade": "slide 1s linear calc(var(--page-scroll) * -0.9s) paused," + "customFade 1s linear calc(var(--literal-scroll) * -0.9s) paused", + "shrink-with-scroll": + "horseHeight 1s linear calc(var(--horse-height-scale) * -0.999s) paused", }, keyframes: { slide: { @@ -40,6 +42,14 @@ module.exports = { opacity: 0.2, }, }, + horseHeight: { + from: { + "max-height": "100%", + }, + to: { + "max-height": "0%", + }, + }, }, }, fontFamily: {