From bf0e88df20f7ebd1034ee3d87b65a1eb751db304 Mon Sep 17 00:00:00 2001 From: Stefan Imhoff Date: Mon, 17 Apr 2023 20:27:44 +0200 Subject: [PATCH] feat: add ColorSwatch component --- src/components/ColorSwatch.tsx | 85 ++++++++++++++++++++++++++++++++++ src/components/index.ts | 1 + src/mdx-components.ts | 2 + 3 files changed, 88 insertions(+) create mode 100644 src/components/ColorSwatch.tsx diff --git a/src/components/ColorSwatch.tsx b/src/components/ColorSwatch.tsx new file mode 100644 index 0000000..f9b538f --- /dev/null +++ b/src/components/ColorSwatch.tsx @@ -0,0 +1,85 @@ +import cx from 'classnames'; + +import type { FunctionalComponent, JSX } from 'preact'; +import { useState } from 'preact/hooks'; + +import { Subheadline, Text } from '.'; + +interface ColorCardProps extends JSX.HTMLAttributes { + class?: string; +} + +interface Props extends JSX.HTMLAttributes { + class?: string; + color: string; + title?: string; + description?: string; +} + +const ColorCard: FunctionalComponent = ({ + class: className, + children, + ...props +}) => { + const classes = cx( + 'absolute box-border h-[100vw] max-h-[200px] w-full max-w-[300px] rounded-25 bg-white shadow-book inline-start-0 block-start-0 [perspective:500px] [backface-visibility:hidden] dark:bg-black dark:rounded-25 dark:border-[1px] dark:border-white/20', + className + ); + + return ( +
+ {children} +
+ ); +}; + +export const ColorSwatch: FunctionalComponent = ({ + class: className, + color, + title, + description, + ...props +}) => { + const [active, setActive] = useState(false); + const classes = cx( + 'h-[100vw] max-h-[200px] w-full max-w-[300px] [perspective:500px]', + { 'cursor-pointer': description }, + className + ); + const flipperClasses = cx( + 'relative transition-transform duration-500 ease-in-out [transform-style:preserve-3d]', + { '[transform:rotateY(180deg)]': active } + ); + + const handleClick = () => { + description && setActive(!active); + }; + + return ( +
+
+ +
+
+ {title && ( + + {title} + + )} + + {color} + +
+
+ {description && ( + + {description} + + )} +
+
+ ); +}; diff --git a/src/components/index.ts b/src/components/index.ts index 5ea2acd..c5799e8 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,6 @@ export * from './AmazonBook'; export * from './Book'; +export * from './ColorSwatch'; export * from './Divider'; export * from './Headline'; export * from './Image'; diff --git a/src/mdx-components.ts b/src/mdx-components.ts index da41f64..856e431 100644 --- a/src/mdx-components.ts +++ b/src/mdx-components.ts @@ -1,6 +1,7 @@ import { AmazonBook, Book, + ColorSwatch, Divider, Headline, Image, @@ -19,6 +20,7 @@ export const mapping = { a: TextLink, AmazonBook, Book, + ColorSwatch, h1: Title, h2: Headline, h3: Subheadline,