From 32509861415c3a73c2668a8c489e921ca4e3e0e9 Mon Sep 17 00:00:00 2001 From: Thomas Cristina de Carvalho Date: Mon, 5 Feb 2024 12:37:14 -0500 Subject: [PATCH] Add variant selector animation Update animation Update --- app/components/cart/CartLineItem.tsx | 3 + app/components/layout/Header.tsx | 3 + app/components/product/AddToCartForm.tsx | 87 +++++++++++--------- app/components/product/VariantSelector.tsx | 94 ++++++++++++++++------ app/components/ui/Button.tsx | 2 +- app/lib/framerMotionFeatures.ts | 4 +- 6 files changed, 131 insertions(+), 62 deletions(-) diff --git a/app/components/cart/CartLineItem.tsx b/app/components/cart/CartLineItem.tsx index 202aed1..5dceb1a 100644 --- a/app/components/cart/CartLineItem.tsx +++ b/app/components/cart/CartLineItem.tsx @@ -71,6 +71,9 @@ export function CartLineItem({ }, }; + // Animated list implmentation inspired by the fantastic Build UI recipes + // (Check out the original at: https://buildui.com/recipes/animated-list) + // Credit to the Build UI team for the awesome List animation. return ( - {(fetcher) => ( -
- + {showShopPay && ( +
+ +
)} - - {showShopPay && ( -
- -
- )} -
- )} + + ); + }} ) diff --git a/app/components/product/VariantSelector.tsx b/app/components/product/VariantSelector.tsx index 903badb..f98a65a 100644 --- a/app/components/product/VariantSelector.tsx +++ b/app/components/product/VariantSelector.tsx @@ -5,15 +5,14 @@ import type { import type {PartialDeep} from 'type-fest'; import type {PartialObjectDeep} from 'type-fest/source/partial-deep'; -import {Link} from '@remix-run/react'; +import {useNavigate} from '@remix-run/react'; import {parseGid} from '@shopify/hydrogen'; -import {useMemo} from 'react'; +import {m} from 'framer-motion'; +import {useCallback, useMemo, useState} from 'react'; import {useSelectedVariant} from '~/hooks/useSelectedVariant'; import {cn} from '~/lib/utils'; -import {badgeVariants} from '../ui/Badge'; - export type VariantOptionValue = { isActive: boolean; isAvailable: boolean; @@ -102,26 +101,75 @@ export function VariantSelector(props: { return options?.map((option) => (
{option.name}
-
- {option.values?.map(({isActive, isAvailable, search, value}) => ( - +
+ )); +} + +function Pills(props: { + option: { + name: string | undefined; + value: string | undefined; + values: VariantOptionValue[]; + }; +}) { + const navigate = useNavigate(); + const {values} = props.option; + const [activePill, setActivePill] = useState(values[0]); + + const handleOnClick = useCallback( + (value: string, search: string) => { + const newActivePill = values.find((option) => option.value === value); + + if (newActivePill) { + setActivePill(newActivePill); + navigate(search, { + preventScrollReset: true, + replace: true, + }); + } + }, + [setActivePill, values, navigate], + ); + + // Animated tabs implementation inspired by the fantastic Build UI recipes + // (Check out the original at: https://buildui.com/recipes/animated-tabs) + // Credit to the Build UI team for the awesome Pills animation. + return ( +
+ {props.option.values.map(({isAvailable, search, value}) => ( + handleOnClick(value, search)} + style={{ + WebkitTapHighlightColor: 'transparent', + }} + > + {activePill.value === value && ( + + )} + {value} - - ))} -
+ + + ))}
- )); + ); } diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx index 7b04ddc..892bbcc 100644 --- a/app/components/ui/Button.tsx +++ b/app/components/ui/Button.tsx @@ -7,7 +7,7 @@ import * as React from 'react'; import {cn} from '~/lib/utils'; const buttonVariants = cva( - 'inline-flex items-center justify-center whitespace-nowrap rounded-md font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', + 'inline-flex items-center justify-center whitespace-nowrap rounded-md font-medium ring-offset-background transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', { defaultVariants: { size: 'default', diff --git a/app/lib/framerMotionFeatures.ts b/app/lib/framerMotionFeatures.ts index aa1ab17..1f2bc7a 100644 --- a/app/lib/framerMotionFeatures.ts +++ b/app/lib/framerMotionFeatures.ts @@ -1,3 +1,3 @@ -import {domAnimation} from 'framer-motion'; +import {domMax} from 'framer-motion'; -export default domAnimation; +export default domMax;