Skip to content

Latest commit

 

History

History
169 lines (154 loc) · 4.01 KB

typescript.mdx

File metadata and controls

169 lines (154 loc) · 4.01 KB
title id
Getting started with TypeScript
getting-started-with-typescript

This library now works with TypeScript! You can use use-shopping-cart just the same as before but now with types. Take for example these two files from our very own typescript-usage example workspace.

import * as React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { CartProvider } from 'use-shopping-cart'

ReactDOM.render(
  <React.StrictMode>
    <CartProvider
      cartMode="checkout-session"
      stripe=""
      currency="USD"
      loading={<p aria-live="polite">Loading redux-persist...</p>}
    >
      <App />
    </CartProvider>
  </React.StrictMode>,
  document.getElementById('root')
)

The above file didn't really use types yet but it is type-safe. Let's get into some more TypeScript specific use cases.

import {
  useShoppingCart,
  DebugCart,
  formatCurrencyString
} from 'use-shopping-cart'
import {
  Product,
  CartActions,
  CartEntry as ICartEntry
} from 'use-shopping-cart/core'

function CartEntry({
  entry,
  removeItem
}: {
  entry: ICartEntry
  removeItem: CartActions['removeItem']
}) {
  return (
    <div>
      <h3>{entry.name}</h3>
      {entry.image ? (
        <img width={100} src={entry.image} alt={entry.description} />
      ) : null}
      <p>
        {entry.quantity} x{' '}
        {formatCurrencyString({ value: entry.price, currency: 'USD' })} ={' '}
        {entry.formattedValue}
      </p>
      <button onClick={() => removeItem(entry.id)}>Remove</button>
    </div>
  )
}

function Cart() {
  const cart = useShoppingCart()
  const { removeItem, cartDetails, clearCart, formattedTotalPrice } = cart

  const cartEntries = Object.values(cartDetails ?? {}).map((entry) => (
    <CartEntry key={entry.id} entry={entry} removeItem={removeItem} />
  ))

  return (
    <div>
      <h2>Cart</h2>
      <p>Total: {formattedTotalPrice}</p>
      {cartEntries.length === 0 ? <p>Cart is empty.</p> : null}
      {cartEntries.length > 0 ? (
        <>
          <button onClick={() => clearCart()}>Clear cart</button>
          {cartEntries}
        </>
      ) : null}
    </div>
  )
}

const products: Product[] = [
  {
    name: 'Sunglasses',
    id: 'price_1GwzfVCNNrtKkPVCh2MVxRkO',
    price: 15_00,
    image: 'https://files.stripe.com/links/fl_test_FR8EZTS7UDXE0uljMfT7hwmH',
    currency: 'USD',
    description: 'A pair of average black sunglasses.'
  },
  {
    name: '3 Stripe Streak Scoop Neck Flowy T-Shirt',
    id: 'price_OkRxVM2hCVPkKtrNNCVfzwG1',
    price: 30_00,
    image:
      'https://static.musictoday.com/store/bands/4806/product_600/5QCTBL052.jpg',
    description:
      'A black scoop neck flowy t-shirt with 3 bright yellow strips behind the words Black Lives Matter.',
    currency: 'USD'
  }
]

function ProductListing({
  product,
  addItem
}: {
  product: Product
  addItem: CartActions['addItem']
}) {
  return (
    <div key={product.id}>
      <h3>{product.name}</h3>
      {product.image ? (
        <img width={300} src={product.image} alt={product.description} />
      ) : null}
      <p>{formatCurrencyString({ value: product.price, currency: 'USD' })}</p>
      <button
        onClick={() => addItem(product)}
        aria-label={`Add one ${product.name} to your cart.`}
      >
        Add 1 to Cart
      </button>
    </div>
  )
}

function ProductList() {
  const cart = useShoppingCart()
  const { addItem } = cart

  return (
    <div>
      <h2>Products</h2>
      {products.map((product) => (
        <ProductListing key={product.id} product={product} addItem={addItem} />
      ))}
    </div>
  )
}

function App() {
  return (
    <div style={{ display: 'grid', placeItems: 'center' }}>
      <h1>Grocery+ Store</h1>
      <ProductList />
      <br />
      <hr
        style={{
          background: 'grey',
          height: 1,
          width: '100%',
          maxWidth: '20rem'
        }}
      />
      <Cart />
      <DebugCart />
    </div>
  )
}

export default App