npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mrvautin/react-shoppingcart

v1.0.4

Published

A React Context provider to quickly and easily build a shopping cart using Next.js or any other React framework.

Downloads

22

Readme

  • Persistent local storage using React Context
  • Works with Next, Gatsby, React
  • Supports hooks to listen for events
  • Written in Typescript
  • Supports discount codes
  • Supports shipping costs
  • Supports product variants - Size, colour etc
  • Supports cart metadata

View Demo.

Install

npm:

npm install @mrvautin/react-shoppingcart --save

yarn:

yarn add @mrvautin/react-shoppingcart 

Getting started

Add the Context

Wrap your app in the <CartProvider> (eg: Add to your _app.tsx):

import type { AppProps } from 'next/app';
import { CartProvider } from '@mrvautin/react-shoppingcart';

export default function App({ Component, pageProps }: AppProps) {
    return (
        <CartProvider>
            <Component {...pageProps} />
        </CartProvider>
    );
}

| Prop | Required | Description | | ------------------- | -------- | --------------------------------------------------------------------------------------------- | | cartId | No | cartId for your cart storage. If nothing is supplied, react-shoppingcart is used. | | onItemAdd | No | Triggered an item is added to your cart using addItem. | | onItemUpdate | No | Triggered when items are updated in your cart using updateItemQuantity(). | | onItemRemove | No | Triggered on items are removed from your cart using removeItem(). | | onDiscountAdd | No | Triggered when a discount is added using addDiscount(). | | onDiscountRemove | No | Triggered when a discount is removed using removeDiscount(). | | onShippingAdd | No | Triggered when a shipping is added using addShipping(). | | onShippingRemove | No | Triggered when a shipping is removed using removeShipping(). | | onEmptyCart | No | Triggered on emptyCart() is called. | | onMetadataUpdate | No | Triggered when metadata is changed in your cart using setMetadata() or clearMetadata(). | | currency | No | Used to set the currency formatting of the discount. Defaults to USD. | | locale | No | Used to set the locale formatting of the discount. Defaults to en-US. |

Listening to a hook

You may want to use hooks to check your backend server for things like:

  • A discount code is valid and not expired
  • The price of an item is correct
  • The cartTotal matches your expected value in database

Available Hooks are: onItemAdd, onItemUpdate, onItemRemove, onDiscountAdd, onDiscountRemove, onShippingAdd, onShippingRemove, onEmptyCart and onMetadataUpdate.

On the <CartProvider> you can add any hooks you need to listen on:

import type { AppProps } from 'next/app';
import { CartProvider } from '@mrvautin/react-shoppingcart';

export default function App({ Component, pageProps }: AppProps) {
    return (
        <CartProvider onItemAdd={cart => alert(cart)}>
            {children}
        </CartProvider>
    );
}

Keeping in mind that any cart values can be altered by the user by changing their localstorage.

Add to your Component

import { useCart } from '@mrvautin/react-shoppingcart';
...
const {
    items,
    addItem,
    removeItem,
    getItem,
    updateItemQuantity,
    addDiscount,
    removeDiscount,
    setMetadata,
    clearMetadata,
    metadata,
    totalShippingAmount,
    totalDiscountAmount,
    totalItemsAmount,
    discount,
    cartDiscountText,
    totalNumberItems
    totalUniqueItems,
    cartTotal,
    cartNetTotal,
    emptyCart,
} = useCart();

Usage

addItem

The first argument is a product object to add to the cart. Minimum values required are:

| Prop | Required | Description | | ------------------- | --------- | --------------------------------------------------------------------------------------------- | | id | Yes | id for the item being added to the cart | | name | Yes | name for the items. | | price | Yes | price formatted in whole number. Eg: $10.00 would be 1000. |

The second arguement is an option quantity. If not supplied, 1 is added by default.

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
}
<button
    onClick={() => addItem(product)}
/>

// Adding 5 items
<button
    onClick={() => addItem(product, 5)}
/>

Note: If the exact same item (eg: Same id and itemVariants - if supplied) is added twice, the quantity for the item is increased by 1.

removeItem

Used to remove an item from the cart.

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
}
<button
    onClick={() => addItem(product)}
/>

// Adding 5 items
<button
    onClick={() => addItem(product, 5)}
/>

Note: If using itemVariants, you will need to supply the same id amd itemVariants.

getItem

Used to get an item which has been already added to the cart.

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
}
<button
    onClick={() => getItem(product)}
/>

Note: If using itemVariants, you will need to supply the same id amd itemVariants.

items

items is an array property which stores a list of items in the cart.

// You can loop the items
<div>
    <h1>Cart</h1>
    {items.map((item) => (
        <div key={item.id}>
            <div>Name: {item.name} - Quantity: {item.quantity}</div>
        </div>
    ))}
</div>

itemVariants

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
    itemVariants: [
        {
            size: 'US11'
        },
        {
            color: 'white'
        }
    ],
}
<button
    onClick={() => addItem(product)}
>

Note this function allows for a single product ID to be used per product but multiple variations to it. For instance, you may have a single product with an ID of shoes1 but it may have an itemVariants of size of US11 in the example above. This allows the same product to be added to the cart multiple times despite having a different variant set.

updateItemQuantity

Used to update the quantity of an item already in the cart.

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
    itemVariants: [
        {
            size: 'US11'
        },
        {
            color: 'white'
        }
    ],
}
<button
    onClick={() => updateItemQuantity(product, 'increase', 2)}
>

removeItem

Used to remove an item already in the cart.

const product = {
    id: 'shoes1',
    name: 'Running shoes',
    price: 1000,
    itemVariants: [
        {
            size: 'US11'
        },
        {
            color: 'white'
        }
    ],
}
<button
    onClick={() => removeItem(product)}
>

Note: If using itemVariants ensure the same id and itemVariants are supplied in the removeItem() call.

discount

discount returns an object if a discount is applied else it returns an empty object {}.

addDiscount

Used to add a discount to the cart. You will want to ensure this discount is allowed and valid on your backend. You can do this by listening on the onDiscountAdd event to validate and remove if required.

| Prop | Required | Description | | ------------------- | --------- | ---------------------------------------------------------------------------------------------- | | id | Yes | id for the discount | | code | Yes | code for the discount being added. This would be what is advised to the customer and entered at checkout. | | type | Yes | type of discount. Allowed values are: amount and percent. | | value | Yes | value to be discounted in whole number. Eg: 1000 is $10.00 discount or 10% depending on type. |

const discount = {
    id: 'discount1',
    code: 'AMOUNT_DISCOUNT',
    type: 'amount',
    value: 2000,
}
<button
    onClick={() => addDiscount(discount)}
>

removeDiscount

Used to remove a discount from the cart.

const discount = {
    id: 'discount1',
    code: 'AMOUNT_DISCOUNT',
    type: 'amount',
    value: 2000,
}
<button
    onClick={() => removeDiscount()}
>

shipping

shipping returns an object if shipping is applied else it returns an empty object {}.

addShipping

Used to add shipping to the cart. You will want to ensure this shipping is allowed and valid on your backend. You can do this by listening on the onShippingAdd or onShippingRemove event to validate and remove if required.

| Prop | Required | Description | | ------------------- | --------- | ---------------------------------------------------------------------------------------------- | | description | Yes | description for the discount being added. This would be what is advised to the customer and entered at checkout. | | costs | Yes | Shipping costs to be adding as a whole number. Eg: 1000 is $10.00 |

const shipping = {
    description: 'Flat rate shipping',
    costs: 1000,
}
<button
    onClick={() => addShipping(shipping)}
>

removeShipping

Used to remove shipping from the cart.

const shipping = {
    description: 'Flat rate shipping',
    costs: 1000,
}
<button
    onClick={() => removeShipping()}
>

emptyCart

Used to completely empty the cart including items, discounts and metadata.

<button
    onClick={() => emptyCart()}
>

setMetadata

Used to add metadata to the cart. This could be used to store an order ID, customer ID or notes about shipping etc.

const metadata = {
    customerId: '1234',
    notes: 'Leave on door step',
};
<button
    onClick={() => setMetadata(metadata)}
>

clearMetadata

Used to clear whetever metadata is currently set on the cart.

<button
    onClick={() => clearMetadata()}
>

metadata

Returns whatever metadata is currently set on the cart.

totalNumberItems

Returns the total number of items in the cart. This adds the quantity of all items in the cart to give a total number of items being purchased.

totalUniqueItems

Returns the total unique items in the cart. This ignores the quantity and simply counts all unique products in the cart.

totalShippingAmount

This value is 0 by default. If shipping is added, the total shipping is caluculated and stored in this value.

totalDiscountAmount

This value is 0 by default. If a discount is added, the total discount is caluculated and stored in this value. Eg: If the discount is a percent, this value will store the total discounted $ based on the set %.

cartDiscountText

This value stores a nice discount value which can be displayed on the cart. Eg: If the discount is set to $20.00 then the text will be: $20.00 off. Depending on the currency and locale set, this same text in Euro will be: 20,00 € off.

totalItemsAmount

This value stores the total amount of just the items. This is a total of the item price * the item quantity.

cartNetTotal

This value stores the net total taking into account any discounts. Eg: This value is: cartTotal - totalDiscountAmount = cartNetTotal.

cartTotal

Returns the total value in the cart including totalDiscountAmount and totalShippingAmount. Essentially it's totalItemsAmount - totalDiscountAmount + totalShippingAmount = cartTotal. The value is in whole number. Eg: 1000 is $10.00.

Example

An example Next.js project is stored in /example. You can see the basics of using the component in this example project.

  1. Enter directory: cd example
  2. Install: yarn install
  3. Start up Next.js: yarn run dev
  4. Visit the example: http://localhost:3000

Tests

Running tests with:

yarn run test