@shopify/create-hydrogen 1.0.0-alpha.23 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +256 -0
  2. package/bin/run.cmd +3 -0
  3. package/bin/run.js +7 -0
  4. package/dist/commands/init.js +157943 -0
  5. package/dist/commands/init.js.map +1 -0
  6. package/dist/index.js +151598 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +64 -16
  9. package/templates/template-hydrogen-default/.devcontainer/devcontainer.json +18 -0
  10. package/templates/template-hydrogen-default/.eslintrc.js +3 -0
  11. package/templates/template-hydrogen-default/.gitignore +7 -0
  12. package/{template-hydrogen → templates/template-hydrogen-default}/.stylelintrc.js +1 -1
  13. package/templates/template-hydrogen-default/.vscode/extensions.json +8 -0
  14. package/{template-hydrogen → templates/template-hydrogen-default}/README.md +11 -2
  15. package/{template-hydrogen → templates/template-hydrogen-default}/_gitignore +0 -0
  16. package/templates/template-hydrogen-default/index.html +20 -0
  17. package/templates/template-hydrogen-default/package.json.liquid +48 -0
  18. package/{template-hydrogen → templates/template-hydrogen-default}/postcss.config.js +0 -0
  19. package/templates/template-hydrogen-default/public/favicon.ico +0 -0
  20. package/{template-hydrogen → templates/template-hydrogen-default}/shopify.config.js +1 -2
  21. package/templates/template-hydrogen-default/src/App.server.jsx +27 -0
  22. package/templates/template-hydrogen-default/src/components/Button.client.jsx +65 -0
  23. package/templates/template-hydrogen-default/src/components/Cart.client.jsx +265 -0
  24. package/templates/template-hydrogen-default/src/components/CartIcon.jsx +33 -0
  25. package/templates/template-hydrogen-default/src/components/CartIconWithItems.client.jsx +28 -0
  26. package/templates/template-hydrogen-default/src/components/CartProvider.client.jsx +35 -0
  27. package/templates/template-hydrogen-default/src/components/CartToggle.client.jsx +30 -0
  28. package/templates/template-hydrogen-default/src/components/CartUIProvider.client.jsx +45 -0
  29. package/templates/template-hydrogen-default/src/components/CountrySelector.client.jsx +116 -0
  30. package/templates/template-hydrogen-default/src/components/DefaultSeo.server.jsx +36 -0
  31. package/templates/template-hydrogen-default/src/components/FeaturedCollection.jsx +26 -0
  32. package/templates/template-hydrogen-default/src/components/Footer.server.jsx +103 -0
  33. package/templates/template-hydrogen-default/src/components/Gallery.client.jsx +66 -0
  34. package/templates/template-hydrogen-default/src/components/Header.client.jsx +62 -0
  35. package/templates/template-hydrogen-default/src/components/Layout.server.jsx +86 -0
  36. package/templates/template-hydrogen-default/src/components/LoadMoreProducts.client.jsx +56 -0
  37. package/templates/template-hydrogen-default/src/components/LoadingFallback.jsx +26 -0
  38. package/templates/template-hydrogen-default/src/components/MobileCountrySelector.client.jsx +64 -0
  39. package/templates/template-hydrogen-default/src/components/MobileNavigation.client.jsx +98 -0
  40. package/templates/template-hydrogen-default/src/components/MoneyCompareAtPrice.client.jsx +14 -0
  41. package/templates/template-hydrogen-default/src/components/MoneyPrice.client.jsx +15 -0
  42. package/templates/template-hydrogen-default/src/components/Navigation.client.jsx +23 -0
  43. package/templates/template-hydrogen-default/src/components/NotFound.server.jsx +93 -0
  44. package/templates/template-hydrogen-default/src/components/OpenIcon.jsx +33 -0
  45. package/templates/template-hydrogen-default/src/components/ProductCard.jsx +50 -0
  46. package/templates/template-hydrogen-default/src/components/ProductDetails.client.jsx +233 -0
  47. package/{template-hydrogen → templates/template-hydrogen-default}/src/components/ProductOptions.client.jsx +7 -4
  48. package/templates/template-hydrogen-default/src/components/Welcome.server.jsx +188 -0
  49. package/{template-hydrogen → templates/template-hydrogen-default}/src/index.css +31 -0
  50. package/templates/template-hydrogen-default/src/pages/collections/[handle].server.jsx +105 -0
  51. package/templates/template-hydrogen-default/src/pages/index.server.jsx +241 -0
  52. package/{template-hydrogen → templates/template-hydrogen-default}/src/pages/pages/[handle].server.jsx +14 -5
  53. package/templates/template-hydrogen-default/src/pages/products/[handle].server.jsx +66 -0
  54. package/templates/template-hydrogen-default/src/pages/redirect.server.jsx +4 -0
  55. package/templates/template-hydrogen-default/src/pages/robots.txt.server.js +40 -0
  56. package/templates/template-hydrogen-default/src/pages/sitemap.xml.server.jsx +151 -0
  57. package/templates/template-hydrogen-default/src/routes/collections/[handle].server.jsx +105 -0
  58. package/templates/template-hydrogen-default/src/routes/index.server.jsx +241 -0
  59. package/templates/template-hydrogen-default/src/routes/pages/[handle].server.jsx +37 -0
  60. package/templates/template-hydrogen-default/src/routes/products/[handle].server.jsx +66 -0
  61. package/templates/template-hydrogen-default/src/routes/redirect.server.jsx +4 -0
  62. package/templates/template-hydrogen-default/src/routes/robots.txt.server.js +40 -0
  63. package/templates/template-hydrogen-default/src/routes/sitemap.xml.server.jsx +151 -0
  64. package/templates/template-hydrogen-default/tailwind.config.js +26 -0
  65. package/{template-hydrogen → templates/template-hydrogen-default}/vite.config.js +1 -0
  66. package/templates/template-hydrogen-minimal/README.md +8 -0
  67. package/templates/template-hydrogen-minimal/package.json +14 -0
  68. package/index.js +0 -201
  69. package/scripts/tmp-copy-template-from-dev.js +0 -21
  70. package/scripts/utils.js +0 -29
  71. package/template-hydrogen/.eslintrc.js +0 -41
  72. package/template-hydrogen/.vscode/extensions.json +0 -3
  73. package/template-hydrogen/Dockerfile +0 -15
  74. package/template-hydrogen/index.html +0 -14
  75. package/template-hydrogen/package.json +0 -43
  76. package/template-hydrogen/server.js +0 -40
  77. package/template-hydrogen/src/App.server.jsx +0 -42
  78. package/template-hydrogen/src/components/Cart.client.jsx +0 -287
  79. package/template-hydrogen/src/components/CartProvider.client.jsx +0 -15
  80. package/template-hydrogen/src/components/DefaultSeo.server.jsx +0 -22
  81. package/template-hydrogen/src/components/Footer.jsx +0 -12
  82. package/template-hydrogen/src/components/Gallery.client.jsx +0 -36
  83. package/template-hydrogen/src/components/Header.client.jsx +0 -46
  84. package/template-hydrogen/src/components/HightlightedProduct.client.jsx +0 -54
  85. package/template-hydrogen/src/components/Layout.client.jsx +0 -61
  86. package/template-hydrogen/src/components/MediaPlaceholder.jsx +0 -21
  87. package/template-hydrogen/src/components/NotFound.server.jsx +0 -104
  88. package/template-hydrogen/src/components/ProductCard.client.jsx +0 -39
  89. package/template-hydrogen/src/components/ProductDetails.client.jsx +0 -184
  90. package/template-hydrogen/src/components/Seo.client.jsx +0 -75
  91. package/template-hydrogen/src/entry-client.jsx +0 -12
  92. package/template-hydrogen/src/entry-server.jsx +0 -7
  93. package/template-hydrogen/src/favicon.svg +0 -15
  94. package/template-hydrogen/src/pages/Index.server.jsx +0 -186
  95. package/template-hydrogen/src/pages/blogs/[handle]/[articleHandle].server.jsx +0 -49
  96. package/template-hydrogen/src/pages/blogs/[handle].server.jsx +0 -76
  97. package/template-hydrogen/src/pages/collections/[handle].server.jsx +0 -69
  98. package/template-hydrogen/src/pages/products/[handle].server.jsx +0 -56
  99. package/template-hydrogen/src/pages/search.server.jsx +0 -107
  100. package/template-hydrogen/src/pages/sitemap.xml.server.jsx +0 -64
  101. package/template-hydrogen/tailwind.config.js +0 -9
  102. package/template-hydrogen/worker.js +0 -22
package/package.json CHANGED
@@ -1,28 +1,76 @@
1
1
  {
2
2
  "name": "@shopify/create-hydrogen",
3
- "publishConfig": {
4
- "access": "public",
5
- "@shopify:registry": "https://registry.npmjs.org"
6
- },
7
- "version": "1.0.0-alpha.23",
8
- "main": "index.js",
3
+ "version": "1.0.4",
4
+ "private": false,
5
+ "description": "A CLI tool to create a new Shopify hydrogen app.",
6
+ "type": "module",
7
+ "keywords": [
8
+ "shopify",
9
+ "shopify-cli",
10
+ "shopify-partners",
11
+ "shopify-hydrogen"
12
+ ],
9
13
  "license": "MIT",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
10
20
  "bin": {
11
- "create-app": "index.js",
12
- "create-hydrogen": "index.js"
21
+ "create-hydrogen": "./bin/run.js"
13
22
  },
14
23
  "files": [
15
- "index.js",
16
- "scripts",
17
- "template-*"
24
+ "/bin/run.js",
25
+ "/bin/run.cmd",
26
+ "/dist",
27
+ "templates",
28
+ "/oclif.manifest.json"
18
29
  ],
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "@shopify:registry": "https://registry.npmjs.org"
33
+ },
19
34
  "scripts": {
20
- "prepack": "node ./scripts/tmp-copy-template-from-dev.js"
35
+ "clean": "shx rm -rf dist",
36
+ "build": "rimraf dist/ && rollup -c",
37
+ "prepack": "cross-env NODE_ENV=production yarn run build",
38
+ "lint": "prettier -c src/** && eslint 'src/**/*.ts'",
39
+ "lint:fix": "prettier -w src/** && eslint 'src/**/*.ts' --fix",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest watch",
42
+ "tsc": "tsc --noEmit",
43
+ "refresh-templates": "node ./scripts/refresh-templates.mjs"
44
+ },
45
+ "eslintConfig": {
46
+ "extends": [
47
+ "../../.eslintrc.cjs"
48
+ ],
49
+ "rules": {
50
+ "no-warning-comments": "off"
51
+ }
21
52
  },
22
53
  "dependencies": {
23
- "enquirer": "^2.3.6",
24
- "kolorist": "^1.4.0",
25
- "minimist": "^1.2.5"
54
+ "@bugsnag/js": "^7.16.2",
55
+ "@shopify/cli-hydrogen": "1.0.4",
56
+ "@shopify/cli-kit": "1.0.4",
57
+ "@oclif/core": "1.6.4",
58
+ "open": "^8.4.0"
26
59
  },
27
- "gitHead": "8933b705cf46a3be7bae83e125a3152a9ddf4f5d"
60
+ "devDependencies": {
61
+ "vitest": "0.8.1"
62
+ },
63
+ "engine-strict": true,
64
+ "engines": {
65
+ "node": "^14.13.1 || ^16.0.0 || ^17.0.0"
66
+ },
67
+ "os": [
68
+ "darwin",
69
+ "linux",
70
+ "win32"
71
+ ],
72
+ "oclif": {
73
+ "bin": "create-hydrogen",
74
+ "commands": "./dist/commands"
75
+ }
28
76
  }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "Shopify Hydrogen",
3
+ "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16",
4
+ "settings": {},
5
+ "extensions": [
6
+ "graphql.vscode-graphql",
7
+ "dbaeumer.vscode-eslint",
8
+ "bradlc.vscode-tailwindcss",
9
+ "esbenp.prettier-vscode"
10
+ ],
11
+ "forwardPorts": [3000],
12
+ "postCreateCommand": "yarn install",
13
+ "postStartCommand": "yarn dev",
14
+ "remoteUser": "node",
15
+ "features": {
16
+ "git": "latest"
17
+ }
18
+ }
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ extends: ['plugin:hydrogen/recommended'],
3
+ };
@@ -0,0 +1,7 @@
1
+
2
+ node_modules
3
+ .DS_Store
4
+ dist
5
+ dist-ssr
6
+ *.local
7
+
@@ -4,7 +4,7 @@ module.exports = {
4
4
  'at-rule-no-unknown': [
5
5
  true,
6
6
  {
7
- ignoreAtRules: ['tailwind'],
7
+ ignoreAtRules: ['tailwind', 'layer'],
8
8
  },
9
9
  ],
10
10
  'selector-type-no-unknown': [
@@ -0,0 +1,8 @@
1
+ {
2
+ "recommendations": [
3
+ "graphql.vscode-graphql",
4
+ "dbaeumer.vscode-eslint",
5
+ "esbenp.prettier-vscode",
6
+ "bradlc.vscode-tailwindcss"
7
+ ]
8
+ }
@@ -2,13 +2,13 @@
2
2
 
3
3
  Hydrogen is a React framework and SDK that you can use to build fast and dynamic Shopify custom storefronts.
4
4
 
5
- [Check out the docs](https://shopify.dev/beta/hydrogen)
5
+ [Check out the docs](https://shopify.dev/custom-storefronts/hydrogen)
6
6
 
7
7
  ## Getting started
8
8
 
9
9
  **Requirements:**
10
10
 
11
- - Node v14+
11
+ - Node.js version 16.5.0 or higher
12
12
  - Yarn
13
13
 
14
14
  ```bash
@@ -18,6 +18,15 @@ yarn dev
18
18
 
19
19
  Remember to update `shopify.config.js` with your shop's domain and Storefront API token!
20
20
 
21
+ ## Previewing a production build
22
+
23
+ To run a local preview of your Hydrogen app in an environment similar to Oxygen, build your Hydrogen app and then run `yarn preview`:
24
+
25
+ ```bash
26
+ yarn build
27
+ yarn preview
28
+ ```
29
+
21
30
  ## Building for production
22
31
 
23
32
  ```bash
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Hydrogen App</title>
8
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
+ <link
11
+ href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@500&family=Roboto:wght@400;500;900&display=swap"
12
+ rel="stylesheet"
13
+ />
14
+ <link rel="stylesheet" href="/src/index.css" />
15
+ </head>
16
+ <body>
17
+ <div id="root"></div>
18
+ <script type="module" src="/@shopify/hydrogen/entry-client"></script>
19
+ </body>
20
+ </html>
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "description": "This the default template for Hydrogen",
4
+ "version": "0.11.0",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "scripts": {
8
+ "dev": "vite",
9
+ "lint": "npm-run-all lint:*",
10
+ "lint:js": "eslint --no-error-on-unmatched-pattern --ext .js,.ts,.jsx,.tsx src",
11
+ "lint:css": "stylelint ./src/**/*.{css,sass,scss}",
12
+ "build": "yarn build:client && yarn build:server && yarn build:worker",
13
+ "build:client": "vite build --outDir dist/client --manifest",
14
+ "build:server": "vite build --outDir dist/server --ssr @shopify/hydrogen/platforms/node",
15
+ "build:worker": "cross-env WORKER=true vite build --outDir dist/worker --ssr @shopify/hydrogen/platforms/worker-event",
16
+ "serve": "node --enable-source-maps dist/server",
17
+ "preview": "npx @shopify/hydrogen-cli@latest preview"
18
+ },
19
+ "prettier": "@shopify/prettier-config",
20
+ "devDependencies": {
21
+ "@shopify/prettier-config": "^1.1.2",
22
+ "@shopify/stylelint-plugin": "^10.0.1",
23
+ "@tailwindcss/typography": "^0.5.0",
24
+ "autoprefixer": "^10.4.1",
25
+ "cross-env": "^7.0.3",
26
+ "eslint": "^7.31.0",
27
+ "eslint-plugin-hydrogen": "^0.6.2",
28
+ "npm-run-all": "^4.1.5",
29
+ "postcss": "^8.4.5",
30
+ "prettier": "^2.3.2",
31
+ "stylelint": "^13.13.0",
32
+ "tailwindcss": "^3.0.0",
33
+ "vite": "^2.8.0"
34
+ },
35
+ "dependencies": {
36
+ "@headlessui/react": "^1.4.1",
37
+ "@shopify/hydrogen": "{{hydrogen_version}}",
38
+ "body-parser": "^1.19.1",
39
+ "compression": "^1.7.4",
40
+ "graphql-tag": "^2.12.4",
41
+ "path-to-regexp": "^6.2.0",
42
+ "react": "0.0.0-experimental-529dc3ce8-20220124",
43
+ "react-dom": "0.0.0-experimental-529dc3ce8-20220124",
44
+ "serve-static": "^1.14.1",
45
+ "@shopify/cli": "{{shopify_cli_version}}"
46
+ },
47
+ "author": "{{author}}"
48
+ }
@@ -1,6 +1,5 @@
1
1
  export default {
2
- locale: 'en-us',
3
2
  storeDomain: 'hydrogen-preview.myshopify.com',
4
3
  storefrontToken: '3b580e70970c4528da70c98e097c2fa0',
5
- graphqlApiVersion: '2021-10',
4
+ storefrontApiVersion: '2022-01',
6
5
  };
@@ -0,0 +1,27 @@
1
+ import renderHydrogen from '@shopify/hydrogen/entry-server';
2
+ import {Router, FileRoutes, ShopifyProvider} from '@shopify/hydrogen';
3
+ import {Suspense} from 'react';
4
+ import shopifyConfig from '../shopify.config';
5
+ import DefaultSeo from './components/DefaultSeo.server';
6
+ import NotFound from './components/NotFound.server';
7
+ import LoadingFallback from './components/LoadingFallback';
8
+ import CartProvider from './components/CartProvider.client';
9
+
10
+ function App({routes, ...serverProps}) {
11
+ return (
12
+ <Suspense fallback={<LoadingFallback />}>
13
+ <ShopifyProvider shopifyConfig={shopifyConfig}>
14
+ <CartProvider>
15
+ <DefaultSeo />
16
+ <Router fallback={<NotFound />} serverProps={serverProps}>
17
+ <FileRoutes routes={routes} />
18
+ </Router>
19
+ </CartProvider>
20
+ </ShopifyProvider>
21
+ </Suspense>
22
+ );
23
+ }
24
+
25
+ const routes = import.meta.globEager('./routes/**/*.server.[jt](s|sx)');
26
+
27
+ export default renderHydrogen(App, {shopifyConfig, routes});
@@ -0,0 +1,65 @@
1
+ import {Link} from '@shopify/hydrogen/client';
2
+
3
+ const DEFAULT_CLASSES =
4
+ 'block m-0 w-full items-center justify-center uppercase font-medium text-center px-6 py-4 rounded disabled:border-gray-300 disabled:bg-gray-300 disabled:cursor-not-allowed';
5
+
6
+ const VARIANT_CLASSES = {
7
+ primary: 'text-white bg-gray-900 hover:bg-gray-800 active:bg-gray-700',
8
+ secondary: 'bg-white hover:bg-gray-50 active:bg-gray-100 border border-black',
9
+ };
10
+
11
+ export const BUTTON_PRIMARY_CLASSES = `${DEFAULT_CLASSES} ${VARIANT_CLASSES.primary}`;
12
+ export const BUTTON_SECONDARY_CLASSES = `${DEFAULT_CLASSES} ${VARIANT_CLASSES.secondary}`;
13
+
14
+ const ExternalIcon = () => (
15
+ <svg
16
+ className="fill-current text-white ml-3"
17
+ width="15"
18
+ height="14"
19
+ viewBox="0 0 15 14"
20
+ xmlns="http://www.w3.org/2000/svg"
21
+ >
22
+ <path d="M8.11963 0.000976562C7.56734 0.000976562 7.11963 0.448692 7.11963 1.00098C7.11963 1.55326 7.56734 2.00098 8.11963 2.00098H10.7054L4.41252 8.29387C4.022 8.68439 4.022 9.31756 4.41252 9.70808C4.80305 10.0986 5.43621 10.0986 5.82674 9.70808L12.1196 3.41519V6.00098C12.1196 6.55326 12.5673 7.00098 13.1196 7.00098C13.6719 7.00098 14.1196 6.55326 14.1196 6.00098V1.00098C14.1196 0.448692 13.6719 0.000976562 13.1196 0.000976562H8.11963Z" />
23
+ <path d="M2.11963 2.00098C1.01506 2.00098 0.119629 2.89641 0.119629 4.00098V12.001C0.119629 13.1055 1.01506 14.001 2.11963 14.001H10.1196C11.2242 14.001 12.1196 13.1055 12.1196 12.001V9.00098C12.1196 8.44869 11.6719 8.00098 11.1196 8.00098C10.5673 8.00098 10.1196 8.44869 10.1196 9.00098V12.001H2.11963V4.00098L5.11963 4.00098C5.67191 4.00098 6.11963 3.55326 6.11963 3.00098C6.11963 2.44869 5.67191 2.00098 5.11963 2.00098H2.11963Z" />
24
+ </svg>
25
+ );
26
+
27
+ /**
28
+ * A client component that sets the primary and secondary classes for button components
29
+ */
30
+ export default function Button({
31
+ className,
32
+ label,
33
+ handleClick,
34
+ url,
35
+ variant = 'primary',
36
+ passthroughProps,
37
+ }) {
38
+ const classes = `${DEFAULT_CLASSES} ${VARIANT_CLASSES[variant]} ${className}`;
39
+ const isExternal = url
40
+ ? url.indexOf('://') > 0 || url.indexOf('//') === 0
41
+ : false;
42
+
43
+ if (isExternal) {
44
+ return (
45
+ <a href={url} className={classes} {...passthroughProps}>
46
+ {label}
47
+ <ExternalIcon />
48
+ </a>
49
+ );
50
+ }
51
+
52
+ if (handleClick) {
53
+ return (
54
+ <button className={classes} onClick={handleClick} type="button">
55
+ {label}
56
+ </button>
57
+ );
58
+ }
59
+
60
+ return (
61
+ <Link to={url} className={classes} {...passthroughProps}>
62
+ {label}
63
+ </Link>
64
+ );
65
+ }
@@ -0,0 +1,265 @@
1
+ import {
2
+ useCart,
3
+ CartCheckoutButton,
4
+ Link,
5
+ CartLines,
6
+ CartLineImage,
7
+ CartLineProductTitle,
8
+ CartLineQuantityAdjustButton,
9
+ CartLinePrice,
10
+ CartLineQuantity,
11
+ CartShopPayButton,
12
+ CartEstimatedCost,
13
+ useCartLine,
14
+ } from '@shopify/hydrogen/client';
15
+ import {Dialog} from '@headlessui/react';
16
+
17
+ import {useCartUI} from './CartUIProvider.client';
18
+ import CartIconWithItems from './CartIconWithItems.client';
19
+ import {BUTTON_PRIMARY_CLASSES} from './Button.client';
20
+
21
+ /**
22
+ * A client component that contains the merchandise that a customer intends to purchase, and the estimated cost associated with the cart
23
+ */
24
+ export default function Cart() {
25
+ const {isCartOpen, closeCart} = useCartUI();
26
+ const {totalQuantity} = useCart();
27
+
28
+ return (
29
+ <div>
30
+ {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
31
+ <div
32
+ className={`z-20 fixed top-0 bottom-0 left-0 right-0 bg-black transition-opacity duration-400 ${
33
+ isCartOpen ? 'opacity-20' : 'opacity-0 pointer-events-none'
34
+ }`}
35
+ onClick={isCartOpen ? closeCart : null}
36
+ />
37
+ <Dialog open={isCartOpen} onClose={closeCart}>
38
+ <Dialog.Overlay className="fixed z-20 inset-0 bg-gray-50 opacity-75" />
39
+ <div
40
+ className={`absolute flex flex-col md:block z-20 top-0 left-0 right-0 bottom-0 md:top-7 h-full md:left-auto md:right-7 md:bottom-auto md:h-auto md:max-h-[calc(100vh-56px)] bg-gray-50 w-full md:w-[470px] rounded-b-lg shadow-2xl ${
41
+ totalQuantity === 0 ? 'overflow-hidden' : 'overflow-y-scroll'
42
+ }`}
43
+ >
44
+ <CartHeader />
45
+ {totalQuantity === 0 ? (
46
+ <CartEmpty />
47
+ ) : (
48
+ <>
49
+ <CartItems />
50
+ <CartFooter />
51
+ </>
52
+ )}
53
+ </div>
54
+ </Dialog>
55
+ </div>
56
+ );
57
+ }
58
+
59
+ function CartHeader() {
60
+ const {closeCart} = useCartUI();
61
+ return (
62
+ <header className="border-b border-gray-300 bg-white py-3 px-6 flex justify-between items-center sticky top-0">
63
+ <button type="button" onClick={closeCart}>
64
+ <ArrowIcon />
65
+ <span className="sr-only">Close cart</span>
66
+ </button>
67
+ <span className="text-xs text-gray-500">
68
+ Free shipping on orders over $50
69
+ </span>
70
+ <CartIconWithItems />
71
+ </header>
72
+ );
73
+ }
74
+
75
+ function CartItems() {
76
+ return (
77
+ <div className="px-7 flex-grow" role="table" aria-label="Shopping cart">
78
+ <div role="row" className="sr-only">
79
+ <div role="columnheader">Product image</div>
80
+ <div role="columnheader">Product details</div>
81
+ <div role="columnheader">Price</div>
82
+ </div>
83
+ <CartLines>
84
+ <LineInCart />
85
+ </CartLines>
86
+ </div>
87
+ );
88
+ }
89
+
90
+ function LineInCart() {
91
+ const {merchandise} = useCartLine();
92
+ return (
93
+ <div
94
+ role="row"
95
+ className="flex py-7 border-b last:border-b-0 border-gray-300 text-gray-900"
96
+ >
97
+ <div role="cell" className="flex-shrink-0 mr-7">
98
+ <Link to={`/products/${merchandise.product.handle}`}>
99
+ <CartLineImage
100
+ className="bg-white border border-black border-opacity-5 rounded-xl "
101
+ options={{width: 98, height: 98, crop: 'center'}}
102
+ />
103
+ </Link>
104
+ </div>
105
+ <div
106
+ role="cell"
107
+ className="flex flex-col w-full justify-between items-start flex-grow-1 mr-4"
108
+ >
109
+ <Link
110
+ to={`/products/${merchandise.product.handle}`}
111
+ className="hover:underline"
112
+ >
113
+ <CartLineProductTitle className="text-lg font-medium" />
114
+ </Link>
115
+ <ul className="text-xs space-y-1">
116
+ {merchandise.selectedOptions.map(({name, value}) => (
117
+ <li key={name}>
118
+ {name}: {value}
119
+ </li>
120
+ ))}
121
+ </ul>
122
+ <CartItemQuantity />
123
+ </div>
124
+ <div role="cell" className="flex flex-col justify-between items-end">
125
+ <CartLineQuantityAdjustButton
126
+ adjust="remove"
127
+ aria-label="Remove from cart"
128
+ className="disabled:pointer-events-all disabled:cursor-wait"
129
+ >
130
+ <svg
131
+ xmlns="http://www.w3.org/2000/svg"
132
+ className="h-5 w-5"
133
+ viewBox="0 0 20 20"
134
+ fill="currentColor"
135
+ >
136
+ <path
137
+ fillRule="evenodd"
138
+ d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
139
+ clipRule="evenodd"
140
+ />
141
+ </svg>
142
+ </CartLineQuantityAdjustButton>
143
+ <CartLinePrice className="text-lg" />
144
+ </div>
145
+ </div>
146
+ );
147
+ }
148
+
149
+ function CartItemQuantity() {
150
+ return (
151
+ <div className="flex border rounded border-gray-300 items-center overflow-auto mt-2">
152
+ <CartLineQuantityAdjustButton
153
+ adjust="decrease"
154
+ aria-label="Decrease quantity"
155
+ className="p-2 disabled:pointer-events-all disabled:cursor-wait"
156
+ >
157
+ <svg
158
+ xmlns="http://www.w3.org/2000/svg"
159
+ className="h-5 w-5 text-gray-400"
160
+ viewBox="0 0 20 20"
161
+ fill="currentColor"
162
+ >
163
+ <path
164
+ fillRule="evenodd"
165
+ d="M5 10a1 1 0 011-1h8a1 1 0 110 2H6a1 1 0 01-1-1z"
166
+ clipRule="evenodd"
167
+ />
168
+ </svg>
169
+ </CartLineQuantityAdjustButton>
170
+ <CartLineQuantity
171
+ as="div"
172
+ className="p-2 text-gray-900 text-xs text-center"
173
+ />
174
+ <CartLineQuantityAdjustButton
175
+ adjust="increase"
176
+ aria-label="Increase quantity"
177
+ className="p-2 text-gray-400 disabled:pointer-events-all disabled:cursor-wait"
178
+ >
179
+ <svg
180
+ xmlns="http://www.w3.org/2000/svg"
181
+ className="h-5 w-5"
182
+ viewBox="0 0 20 20"
183
+ fill="currentColor"
184
+ >
185
+ <path
186
+ fillRule="evenodd"
187
+ d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z"
188
+ clipRule="evenodd"
189
+ />
190
+ </svg>
191
+ </CartLineQuantityAdjustButton>
192
+ </div>
193
+ );
194
+ }
195
+
196
+ function CartFooter() {
197
+ return (
198
+ <footer className="bottom-0 sticky pb-8 border-t border-black border-opacity-5">
199
+ <div className="relative h-60 bg-white text-gray-900 p-7">
200
+ <div role="table" aria-label="Cost summary">
201
+ <div role="row" className="flex justify-between">
202
+ <span className="font-semibold" role="rowheader">
203
+ Subtotal
204
+ </span>
205
+ <CartEstimatedCost
206
+ amountType="subtotal"
207
+ role="cell"
208
+ className="text-right "
209
+ />
210
+ </div>
211
+ <div role="row" className="flex justify-between mt-2">
212
+ <span className="font-semibold" role="rowheader">
213
+ Shipping
214
+ </span>
215
+ <span role="cell" className="uppercase">
216
+ Free
217
+ </span>
218
+ </div>
219
+ </div>
220
+ <CartShopPayButton className="flex my-4 justify-center w-full bg-[#5a31f4] py-2 rounded-md" />
221
+ <CartCheckoutButton className={BUTTON_PRIMARY_CLASSES}>
222
+ Checkout
223
+ </CartCheckoutButton>
224
+ </div>
225
+ </footer>
226
+ );
227
+ }
228
+
229
+ function CartEmpty() {
230
+ const {closeCart} = useCartUI();
231
+ return (
232
+ <div className="p-7 flex flex-col">
233
+ <p className="mb-4 text-lg text-gray-500 text-center">
234
+ Your cart is empty
235
+ </p>
236
+ <button
237
+ type="button"
238
+ onClick={closeCart}
239
+ className={BUTTON_PRIMARY_CLASSES}
240
+ >
241
+ Continue Shopping
242
+ </button>
243
+ </div>
244
+ );
245
+ }
246
+
247
+ function ArrowIcon() {
248
+ return (
249
+ <svg
250
+ width="20"
251
+ height="17"
252
+ viewBox="0 0 20 17"
253
+ fill="none"
254
+ xmlns="http://www.w3.org/2000/svg"
255
+ >
256
+ <path
257
+ d="M12 1.5L19 8.5M19 8.5L12 15.5M19 8.5L1 8.5"
258
+ stroke="black"
259
+ strokeWidth="2"
260
+ strokeLinecap="round"
261
+ strokeLinejoin="round"
262
+ />
263
+ </svg>
264
+ );
265
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A shared component that specifies the icon to represent a cart
3
+ */
4
+ export default function CartIcon() {
5
+ return (
6
+ <svg
7
+ aria-hidden="true"
8
+ width="40"
9
+ height="40"
10
+ viewBox="0 0 40 40"
11
+ fill="none"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ >
14
+ <path
15
+ d="M26.5894 12H14.4106C13.8945 12 13.4632 12.3928 13.415 12.9067L12.205 25.8133C12.095 26.9865 13.018 28 14.1963 28H26.8037C27.982 28 28.905 26.9865 28.795 25.8133L27.585 12.9067C27.5368 12.3928 27.1055 12 26.5894 12Z"
16
+ stroke="#1F2937"
17
+ strokeWidth="2"
18
+ strokeMiterlimit="10"
19
+ strokeLinecap="round"
20
+ />
21
+ <path
22
+ d="M17 12V14.9895C17 17.0075 18.6359 18.6434 20.6539 18.6434V18.6434C22.6718 18.6434 24.3077 17.0075 24.3077 14.9895V12"
23
+ stroke="#1F2937"
24
+ strokeWidth="2"
25
+ />
26
+ <path
27
+ d="M24 11L24 9.5C24 7.567 22.433 6 20.5 6V6C18.567 6 17 7.567 17 9.5L17 11"
28
+ stroke="#1F2937"
29
+ strokeWidth="2"
30
+ />
31
+ </svg>
32
+ );
33
+ }