diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 6d30762..6268578 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -8,6 +8,7 @@ import IconGrid from "@/components/IconGrid"; import Footer from "@/components/Footer"; import ErrorBoundary from "@/components/ErrorBoundary"; import Notice from "@/components/Notice"; +import Recipes from "@/components/Recipes"; import { useIconParameters, usePersistSettings, @@ -21,7 +22,7 @@ const waitingFallback = ; const App: React.FC = () => { useIconParameters(); usePersistSettings(); - + const isDark = useRecoilValue(isDarkThemeSelector); const properties = useMemo( @@ -47,6 +48,7 @@ const App: React.FC = () => { + ); diff --git a/src/components/Recipes/Recipe.tsx b/src/components/Recipes/Recipe.tsx new file mode 100644 index 0000000..75cb198 --- /dev/null +++ b/src/components/Recipes/Recipe.tsx @@ -0,0 +1,22 @@ +import { ArrowCircleUpRight } from "@phosphor-icons/react"; + +export type RecipeProps = { + title: string; + url: string; + Example: () => JSX.Element; +}; + +const Recipe = ({ title, url, Example }: RecipeProps) => { + return ( + + {/* {title} */} + + Open on StackBlitz + + + + + ); +}; + +export default Recipe; diff --git a/src/components/Recipes/Recipes.css b/src/components/Recipes/Recipes.css new file mode 100644 index 0000000..719d4e5 --- /dev/null +++ b/src/components/Recipes/Recipes.css @@ -0,0 +1,39 @@ +.recipes { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(184px, 1fr)); + gap: 16px; + padding-block: 32px; +} + +a.recipe { + position: relative; + color: initial; + padding: 16px; + display: grid; + place-items: center; +} + +.recipe-linkout { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + background-color: var(--soft); + border-radius: 8px; + z-index: 1; + opacity: 0; + transition: opacity 200ms ease; +} + +.recipe-linkout:hover { + opacity: 1; +} + +.example { + display: grid; + grid-template-columns: 64px 64px; + gap: 12px; + place-items: center; +} diff --git a/src/components/Recipes/Recipes.tsx b/src/components/Recipes/Recipes.tsx new file mode 100644 index 0000000..8d25e3b --- /dev/null +++ b/src/components/Recipes/Recipes.tsx @@ -0,0 +1,29 @@ +import { IconContext } from "@phosphor-icons/react"; + +import Recipe from "./Recipe"; +import items from "./items"; +import "./Recipes.css"; + +const Recipes = () => { + return ( + <> + + + Recipes + Cool stuff to do with Phosphor + + + + + + {items.map((itemProps) => ( + + ))} + + + + > + ); +}; + +export default Recipes; diff --git a/src/components/Recipes/index.ts b/src/components/Recipes/index.ts new file mode 100644 index 0000000..83dc03a --- /dev/null +++ b/src/components/Recipes/index.ts @@ -0,0 +1 @@ +export { default } from "./Recipes"; diff --git a/src/components/Recipes/items/Animation.tsx b/src/components/Recipes/items/Animation.tsx new file mode 100644 index 0000000..8222a36 --- /dev/null +++ b/src/components/Recipes/items/Animation.tsx @@ -0,0 +1,83 @@ +import { Cube } from "@phosphor-icons/react"; + +import { RecipeProps } from "../Recipe"; + +const recipe: RecipeProps = { + title: "SVG Wizardry", + url: "https://stackblitz.com/edit/react-ts-f7q7gs?file=App.tsx,style.css", + Example() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ); + }, +}; + +export default recipe; diff --git a/src/components/Recipes/items/Duocolor.tsx b/src/components/Recipes/items/Duocolor.tsx new file mode 100644 index 0000000..4e9c186 --- /dev/null +++ b/src/components/Recipes/items/Duocolor.tsx @@ -0,0 +1,63 @@ +import { useMemo } from "react"; +import { + Icon, + IconProps, + Barricade, + GasCan, + IceCream, + FlyingSaucer, +} from "@phosphor-icons/react"; + +import { RecipeProps } from "../Recipe"; + +type DuocolorProps = Omit & { + Icon: Icon; + duocolor?: string; +}; + +function Duocolor({ Icon, duocolor, ...iconProps }: DuocolorProps) { + const [uuid, style] = useMemo(() => { + // UUID to make sure the inline stylesheet is "scoped" to this icon only. + // Could also easily be implemented with a regular CSS selector. + const uuid = "ph-" + Math.floor(Math.random() * 1_000_000).toString(16); + // const uuid = "ph-" + crypto.randomUUID(); + return [uuid, !duocolor ? null : createDuocolorStyle(uuid, duocolor)]; + }, [duocolor]); + + return ( + <> + {style} + + > + ); +} + +function createDuocolorStyle(id: string, color: string) { + return ( + + ); +} + +const recipe: RecipeProps = { + title: "Duocolor", + url: "https://stackblitz.com/edit/react-ts-kvdzu1?file=App.tsx", + Example() { + return ( + + + + + + + ); + }, +}; + +export default recipe; diff --git a/src/components/Recipes/items/index.ts b/src/components/Recipes/items/index.ts new file mode 100644 index 0000000..d4ecc34 --- /dev/null +++ b/src/components/Recipes/items/index.ts @@ -0,0 +1,6 @@ +import animation from "./Animation"; +import duocolor from "./Duocolor"; +import { RecipeProps } from "../Recipe"; + +const items: RecipeProps[] = [animation, duocolor, duocolor, animation]; +export default items; diff --git a/src/components/Toolbar/Toolbar.css b/src/components/Toolbar/Toolbar.css index c9f5576..17b73f6 100644 --- a/src/components/Toolbar/Toolbar.css +++ b/src/components/Toolbar/Toolbar.css @@ -1,9 +1,10 @@ -nav.toolbar { +.toolbar { position: -webkit-sticky; position: sticky; top: -1px; padding: 0; margin: 0; + color: white; background-color: var(--eggplant); z-index: 2; display: flex;
Cool stuff to do with Phosphor