Skip to content

Commit

Permalink
Add TypeScript usage example (#245)
Browse files Browse the repository at this point in the history
* Add TypeScript usage example.

* remove unused import
  • Loading branch information
andria-dev authored Sep 27, 2021
1 parent eeae8a9 commit 6fd480c
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 1,856 deletions.
10 changes: 10 additions & 0 deletions examples/typescript-usage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Usage of `use-shopping-cart` with TypeScript and React

In order to run this demo, please run the following commands:

```bash
yarn
yarn workspace typescript-usage start
```

You may use the code in this demo to help you understand how to use the `use-shopping-cart` package with TypeScript types.
47 changes: 47 additions & 0 deletions examples/typescript-usage/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "typescript-usage",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/plugin-syntax-jsx": "^7.14.5",
"@babel/preset-react": "^7.14.5"
}
}
137 changes: 137 additions & 0 deletions examples/typescript-usage/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import {
useShoppingCart,
DebugCart,
formatCurrencyString
} from 'use-shopping-cart/dist/react'
import {
Product,
CartActions,
CartEntry as ICartEntry
} from 'use-shopping-cart/dist/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
24 changes: 24 additions & 0 deletions examples/typescript-usage/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import reportWebVitals from './reportWebVitals'
import { CartProvider } from 'use-shopping-cart/dist/react'

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')
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()
1 change: 1 addition & 0 deletions examples/typescript-usage/src/react-app-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="react-scripts" />
15 changes: 15 additions & 0 deletions examples/typescript-usage/src/reportWebVitals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals'

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry)
getFID(onPerfEntry)
getFCP(onPerfEntry)
getLCP(onPerfEntry)
getTTFB(onPerfEntry)
})
}
}

export default reportWebVitals
26 changes: 26 additions & 0 deletions examples/typescript-usage/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ES2019",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
Loading

0 comments on commit 6fd480c

Please sign in to comment.