diff options
Diffstat (limited to 'examples/with-nanostores/src/components')
5 files changed, 126 insertions, 0 deletions
diff --git a/examples/with-nanostores/src/components/AddToCartForm.tsx b/examples/with-nanostores/src/components/AddToCartForm.tsx new file mode 100644 index 000000000..7498443f6 --- /dev/null +++ b/examples/with-nanostores/src/components/AddToCartForm.tsx @@ -0,0 +1,18 @@ +import { isCartOpen, addCartItem } from '../cartStore'; +import type { CartItemDisplayInfo } from '../cartStore'; +import type { ComponentChildren } from 'preact'; + +type Props = { + item: CartItemDisplayInfo; + children: ComponentChildren; +}; + +export default function AddToCartForm({ item, children }: Props) { + function addToCart(e: SubmitEvent) { + e.preventDefault(); + isCartOpen.set(true); + addCartItem(item); + } + + return <form onSubmit={addToCart}>{children}</form>; +} diff --git a/examples/with-nanostores/src/components/CartFlyout.module.css b/examples/with-nanostores/src/components/CartFlyout.module.css new file mode 100644 index 000000000..cee43dd4c --- /dev/null +++ b/examples/with-nanostores/src/components/CartFlyout.module.css @@ -0,0 +1,29 @@ +.container { + position: fixed; + right: 0; + top: var(--nav-height); + height: 100vh; + background: var(--color-bg-2); + padding-inline: 2rem; + min-width: min(90vw, 300px); + border-left: 3px solid var(--color-bg-3); +} + +.list { + list-style: none; + padding: 0; +} + +.listItem { + display: flex; + gap: 1rem; + align-items: center; +} + +.listItem * { + margin-block: 0.3rem; +} + +.listItemImg { + width: 4rem; +} diff --git a/examples/with-nanostores/src/components/CartFlyout.tsx b/examples/with-nanostores/src/components/CartFlyout.tsx new file mode 100644 index 000000000..98fd8cbfb --- /dev/null +++ b/examples/with-nanostores/src/components/CartFlyout.tsx @@ -0,0 +1,28 @@ +import { useStore } from '@nanostores/preact'; +import { cartItems, isCartOpen } from '../cartStore'; +import styles from './CartFlyout.module.css'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + const $cartItems = useStore(cartItems); + + return ( + <aside hidden={!$isCartOpen} className={styles.container}> + {Object.values($cartItems).length ? ( + <ul className={styles.list} role="list"> + {Object.values($cartItems).map((cartItem) => ( + <li className={styles.listItem}> + <img className={styles.listItemImg} src={cartItem.imageSrc} alt={cartItem.name} /> + <div> + <h3>{cartItem.name}</h3> + <p>Quantity: {cartItem.quantity}</p> + </div> + </li> + ))} + </ul> + ) : ( + <p>Your cart is empty!</p> + )} + </aside> + ); +} diff --git a/examples/with-nanostores/src/components/CartFlyoutToggle.tsx b/examples/with-nanostores/src/components/CartFlyoutToggle.tsx new file mode 100644 index 000000000..14ce1c70d --- /dev/null +++ b/examples/with-nanostores/src/components/CartFlyoutToggle.tsx @@ -0,0 +1,7 @@ +import { useStore } from '@nanostores/preact'; +import { isCartOpen } from '../cartStore'; + +export default function CartFlyoutToggle() { + const $isCartOpen = useStore(isCartOpen); + return <button onClick={() => isCartOpen.set(!$isCartOpen)}>Cart</button>; +} diff --git a/examples/with-nanostores/src/components/FigurineDescription.astro b/examples/with-nanostores/src/components/FigurineDescription.astro new file mode 100644 index 000000000..1294b1510 --- /dev/null +++ b/examples/with-nanostores/src/components/FigurineDescription.astro @@ -0,0 +1,44 @@ +<h1>Astronaut Figurine</h1> +<p class="limited-edition-badge">Limited Edition</p> +<p> + The limited edition Astronaut Figurine is the perfect gift for any Astro contributor. This + fully-poseable action figurine comes equipped with: +</p> +<ul> + <li>A fabric space suit with adjustable straps</li> + <li>Boots lightly dusted by the lunar surface *</li> + <li>An adjustable space visor</li> +</ul> +<p> + <sub>* Dust not actually from the lunar surface</sub> +</p> + +<style> + h1 { + margin: 0; + margin-block-start: 2rem; + } + + .limited-edition-badge { + font-weight: 700; + text-transform: uppercase; + background-image: linear-gradient(0deg, var(--astro-blue), var(--astro-pink)); + background-size: 100% 200%; + background-position-y: 100%; + border-radius: 0.4rem; + animation: pulse 4s ease-in-out infinite; + display: inline-block; + color: white; + padding: 0.2rem 0.4rem; + } + + @keyframes pulse { + 0%, + 100% { + background-position-y: 0%; + } + 50% { + background-position-y: 80%; + } + } +</style> |