Created
August 15, 2019 20:41
-
-
Save johntran/afa98a4d2afe2a01dfbf627cab975cca to your computer and use it in GitHub Desktop.
This file contains hidden or 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
export default function useToggle(initial = false) { | |
const [open, setToggle] = useState(initial); | |
return { | |
open, | |
set: setToggle, | |
setOpen: () => setToggle(true), | |
setClose: () => setToggle(false), | |
reset: () => setToggle(initial), | |
toggle: () => setToggle(prev => !prev), | |
}; | |
} | |
const radix = 10; | |
function CartItem(props) { | |
const [editingQuantity, setEditingQuantity] = useState('-1'); | |
const { | |
open: editing, | |
setOpen: setIsEditing, | |
setClose: setIsNotEditing, | |
} = useToggle(); | |
const { | |
product, | |
quantity, | |
removeFromCart, | |
cartEntry, | |
disableTickers, | |
highlightText, | |
} = props; | |
let productImage = null; | |
if (product.images && product.images.productCatalog) { | |
productImage = <ShopImage url={`${product.images.productCatalog}`} />; | |
} | |
const decrementQuantity = useCallback(() => removeFromCart(cartEntry, 1), [ | |
cartEntry, | |
]); | |
const incrementQuantity = useCallback(() => removeFromCart(cartEntry, -1), [ | |
cartEntry, | |
]); | |
const removeEntryFromCart = useCallback(() => removeFromCart(cartEntry), [ | |
cartEntry, | |
]); | |
const onClick = useCallback(() => { | |
const newEditingQuantity = editing ? quantity : editingQuantity; | |
setEditingQuantity(newEditingQuantity); | |
setIsEditing(); | |
}, [quantity, editingQuantity]); | |
const onBlur = useCallback(() => { | |
const int = parseInt(editingQuantity, radix); | |
if (!isNaN(int)) { | |
removeFromCart(cartEntry, quantity - int); | |
} | |
setIsNotEditing(); | |
}, [editingQuantity, cartEntry, quantity]); | |
const onChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { | |
setEditingQuantity(e.target.value); | |
}, []); | |
return ( | |
<div css={itemRow} key={product.id}> | |
<div css={productContainer}> | |
<div css={itemImg}>{productImage}</div> | |
<div> | |
{!disableTickers && ( | |
<div css={itemPrice}> | |
<React.Fragment> | |
<div css={itemTickerContainer} onClick={decrementQuantity}> | |
<span css={itemTickerText}>-</span> | |
</div> | |
<div css={itemTickerContainer} onClick={incrementQuantity}> | |
<span css={itemTickerText}>+</span> | |
</div> | |
</React.Fragment> | |
<div | |
css={cartItemQuantityContainer} | |
onClick={onClick} | |
onBlur={onBlur} | |
> | |
{!editing ? ( | |
quantity | |
) : ( | |
<input | |
autoFocus | |
onChange={onChange} | |
type="text" | |
value={editingQuantity} | |
/> | |
)} | |
</div> | |
</div> | |
)} | |
<div css={tagInfo}> | |
<PriceTag product={product} /> | |
</div> | |
</div> | |
</div> | |
<div css={productNameContainer}> | |
{highlightText && ( | |
<div css={highlightContainer}> | |
<span>{highlightText}</span> | |
</div> | |
)} | |
<span>{product.name}</span> | |
</div> | |
<div> | |
<span css={removeFromCartStyle} onClick={removeEntryFromCart}> | |
Remove | |
</span> | |
</div> | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment