UNPKG

@shopgate/engage

Version:
146 lines (142 loc) 4.5 kB
import "core-js/modules/es.regexp.flags.js"; import React, { useMemo, useCallback, useState, useRef } from 'react'; import { getAbsoluteHeight } from '@shopgate/pwa-common/helpers/dom'; import { themeConfig } from '@shopgate/pwa-common/helpers/config'; import { CART_ITEM_TYPE_PRODUCT } from '@shopgate/pwa-common-commerce/cart/constants'; import PropTypes from 'prop-types'; import { CART_INPUT_AUTO_SCROLL_DELAY } from "../../cart.constants"; import Context from "./CartItemProductProvider.context"; import connect from "./CartItemProductProvider.connector"; import CartItemProductProviderLegacy from "./CartItemProductProviderLegacy"; import { jsx as _jsx } from "react/jsx-runtime"; const { variables } = themeConfig; /** * @typedef {import('./CartItemProductProvider.types').OwnProps} OwnProps * @typedef {import('./CartItemProductProvider.types').StateProps} StateProps * @typedef {import('./CartItemProductProvider.types').DispatchProps} DispatchProps */ /** * @typedef {OwnProps & StateProps & DispatchProps} Props */ /** * The CartItemProduct Provider * @param {Props} props The component props. * @returns {JSX.Element} */ const CartItemProductProvider = ({ currency, deleteProduct, updateProduct, onFocus, cartItem, isEditable, children, isAndroid, currencyOverride }) => { const { id, product, quantity, fulfillment = null, messages = [], status, subStatus, orderedQuantity, unitPromoAmount, unitDiscountAmount, price, promoAmount, discountAmount, extendedPrice, appliedPromotions, flags = {} } = cartItem; const [editMode, setEditMode] = useState(false); const cartItemRef = useRef(); const handleRemove = useCallback(() => { deleteProduct(id); }, [deleteProduct, id]); const handleUpdate = useCallback(updatedQuantity => { updateProduct(id, updatedQuantity); }, [id, updateProduct]); const toggleEditMode = useCallback(isEnabled => { if (isAndroid && isEnabled) { /** * When the user focuses the quantity input, the keyboard will pop up an overlap the input. * Therefor the input has to be scrolled into the viewport again. Since between the focus and * the keyboard appearance some time ticks away, the execution of the scroll code is delayed. * * This should not happen on iOS devices, since their web views behave different. */ setTimeout(() => { const yOffset = -(window.innerHeight / 2) + getAbsoluteHeight(cartItemRef.current) + variables.paymentBar.height; if (cartItemRef.current) { cartItemRef.current.scrollIntoView({ behavior: 'smooth', yOffset }); } }, CART_INPUT_AUTO_SCROLL_DELAY); } // Give the keyboard some time to slide out after blur, before further actions are taken. setTimeout(() => { if (onFocus) { onFocus(isEnabled); } }, isEnabled ? 300 : 0); setEditMode(isEnabled); }, [isAndroid, onFocus]); const value = useMemo(() => { const isLinkable = flags?.disableLink !== true; const allowQuantityChange = flags?.disableQuantityField !== true; return { type: CART_ITEM_TYPE_PRODUCT, currency: currencyOverride || currency, product, messages, handleRemove, handleUpdate, cartItemRef, toggleEditMode, editMode, isEditable, isLinkable, allowQuantityChange, cartItemId: id, cartItem: { id, product, status, subStatus, quantity, orderedQuantity, fulfillment, unitPromoAmount, unitDiscountAmount, price, promoAmount, discountAmount, extendedPrice, appliedPromotions } }; }, [currency, currencyOverride, editMode, fulfillment, handleRemove, handleUpdate, id, isEditable, flags, messages, product, status, subStatus, quantity, orderedQuantity, toggleEditMode, unitPromoAmount, unitDiscountAmount, price, promoAmount, discountAmount, extendedPrice, appliedPromotions]); return /*#__PURE__*/_jsx(Context.Provider, { value: value, children: /*#__PURE__*/_jsx(CartItemProductProviderLegacy, { children: children }) }); }; CartItemProductProvider.defaultProps = { children: null, isEditable: true, onFocus: () => {}, currencyOverride: null, currency: null, isAndroid: false }; export default connect(CartItemProductProvider);