-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
robust cart component, mobile + free shipping progress example
- Loading branch information
1 parent
c887965
commit 3aec24d
Showing
6 changed files
with
174 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,89 @@ | ||
import React from 'react' | ||
import { Link } from 'gatsby' | ||
import cx from 'classnames' | ||
|
||
import { Cart } from 'src/components/cart' | ||
import { useStore, useToggleCart} from 'src/context/siteContext' | ||
import { useStore, useToggleCart, useCartTotals, useCartItems, useCheckout } from 'src/context/siteContext' | ||
|
||
import { | ||
Close | ||
} from 'src/components/svgs' | ||
|
||
/* | ||
/ Cart Drawer: This module is a bit more robust then other parts of the theme, | ||
/ this is because carts are relatively difficult to execute, scale to mobile etc, | ||
/ feel free to keep more of this styling if you use this component, the structure | ||
/ a bit confusing to make sure all elements are visible/scrollable on mobile | ||
*/ | ||
|
||
export const CartDrawer = () => { | ||
const lineItems = useCartItems() | ||
const { cartIsOpen } = useStore() | ||
const { total } = useCartTotals() | ||
const toggleCart = useToggleCart() | ||
const openCheckout = useCheckout() | ||
const trap = cartIsOpen ? ( | ||
<div className='cart__drawer-inner'> | ||
<div className='ac rel cart__drawer-header'> | ||
<h4>Your Cart</h4> | ||
<button type='reset' className='p05 abs no-style cart__drawer-close close right top cb' onClick={() => toggleCart()}> | ||
<Close className='block' /> | ||
</button> | ||
<React.Fragment> | ||
<div className='cart__drawer-inner'> | ||
<div className='ac rel cart__drawer-header df aic jcc'> | ||
<button type='reset' className='pa button--none bg--transparent cart__drawer-close close left cb' onClick={() => toggleCart()}> | ||
<Close className='db m1' /> | ||
</button> | ||
<h4 className='s26 medium'>Cart</h4> | ||
</div> | ||
<div className='bg--off-white cart__drawer-shipping df jcc aic tc'> | ||
<div className='x ac'> | ||
<div className='cart__drawer-progress x pr'> | ||
<span className='block pa bg--black left y' style={{ 'width': `${((parseFloat(total)).toFixed(2) / 40) * 100}%` }} /> | ||
</div> | ||
{lineItems.length > 0 && ( | ||
<> | ||
{parseInt(total, 0) <= 40 ? ( | ||
<div className='s12 p1'>You're <span className=''>${(40 - (parseFloat(total))).toFixed(2)}</span> away from free shipping!</div> | ||
) : ( | ||
<div className='s12 p1'>Your order qualifies for <span className='bold'>Free Shipping!</span></div> | ||
)} | ||
</> | ||
)} | ||
</div> | ||
</div> | ||
<Cart /> | ||
</div> | ||
<div className={cx('bg--white cart__drawer-buttons', parseInt(total, 0) >= 40 && 'free', lineItems.length >= 1 && 'visible')}> | ||
<div className='f fw bcw left ac cart__drawer-bottom pa bottom x jcc aic rel x'> | ||
<div className='x p2 jcb'> | ||
{lineItems.length > 0 && ( | ||
<div className='py1 cart__drawer-sub medium'> | ||
<div className='x df jcb aic py18 px1 bcw'> | ||
<span className='s18'>Subtotal</span> | ||
<span className='s18 mono'>${total}</span> | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
{lineItems.length < 1 ? ( | ||
<Link className='button button--lg p3 bold s16 dib tc color--white bg--black medium x' onClick={() => toggleCart()} to='/'>Continue Shopping</Link> | ||
): ( | ||
<button onClick={openCheckout} type='submit' className='button bn bt p2 medium bg--black color--black s16 x'> | ||
<span className='color--white'>Checkout</span> | ||
</button> | ||
)} | ||
</div> | ||
</div> | ||
<Cart /> | ||
</div> | ||
</React.Fragment> | ||
) : ( | ||
false | ||
) | ||
return ( | ||
<div | ||
className={cx('cart__drawer bcw z10 right top x abs', cartIsOpen && 'is-open')} | ||
id='container' | ||
> | ||
<> | ||
<div | ||
className={cx('cart__drawer bg--white aist z10 right top x pf', cartIsOpen && 'is-open')} | ||
id='container' | ||
> | ||
{trap} | ||
</div> | ||
</div> | ||
{/* Handles the overlay to click-close the cart */} | ||
<div onClick={() => toggleCart()} className={cx('cart__drawer-bg bg--white z9 left top x y pf', cartIsOpen && 'is-open')} /> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
.cart { | ||
&__drawer { | ||
height: 100vh; | ||
max-height: -webkit-fill-available; | ||
max-height: stretch; | ||
border-left: 1px solid currentColor; | ||
transition: all 0.3s ease-in-out; | ||
transform: translateX(100%); | ||
display: flex; | ||
justify-content: space; | ||
flex-direction: column; | ||
justify-content: space-between; | ||
width: 100%; | ||
align-items: stretch; | ||
&-buttons { | ||
&.visible { | ||
border-top: 2px solid rgba(28, 31, 42, 0.1); | ||
} | ||
} | ||
&-inner { | ||
flex: 1; | ||
overflow-y: scroll; | ||
} | ||
@include breakpoint(800) { | ||
left: auto; | ||
transform: translateX(375px); | ||
max-width: 375px; | ||
right: 0; | ||
} | ||
&-progress { | ||
min-height: 6px; | ||
> span { | ||
max-width: 100%; | ||
} | ||
} | ||
&-bg { | ||
opacity: 0; | ||
user-select: none; | ||
visibility: hidden; | ||
&.is-open { | ||
user-select: visible; | ||
visibility: visible; | ||
opacity: 0.4; | ||
} | ||
} | ||
&.is-open { | ||
transform: translateX(0px); | ||
} | ||
&-header { | ||
min-height: 60px; | ||
} | ||
&-close { | ||
margin-left: 10px; | ||
svg { | ||
width: 10px; | ||
height: auto; | ||
} | ||
} | ||
&-buttons { | ||
max-height: 120px; | ||
flex: 1; | ||
&.visible { | ||
max-height: 164px; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters