diff --git a/app/components/hydrogen/new/Accordion.jsx b/app/components/hydrogen/new/Accordion.jsx
new file mode 100644
index 0000000..bc2c19f
--- /dev/null
+++ b/app/components/hydrogen/new/Accordion.jsx
@@ -0,0 +1,45 @@
+import {useState} from 'react';
+import {Disclosure, DisclosureButton, DisclosurePanel} from '@headlessui/react';
+import {Text} from '@h2/Text';
+
+const Accordion = ({data}) => {
+ const [openPanel, setOpenPanel] = useState(null);
+
+ const handleToggle = (index) => {
+ if (openPanel === index) {
+ setOpenPanel(null);
+ } else {
+ setOpenPanel(index);
+ }
+ };
+
+ return (
+
+ {data.map((item, index) => (
+ handleToggle(index)}
+ >
+ {({open}) => (
+ <>
+
+ {item.title}
+
+ ×
+
+
+ {item.content}
+ >
+ )}
+
+ ))}
+
+ );
+};
+
+export default Accordion;
diff --git a/app/components/hydrogen/new/Layout.tsx b/app/components/hydrogen/new/Layout.tsx
new file mode 100644
index 0000000..98473d8
--- /dev/null
+++ b/app/components/hydrogen/new/Layout.tsx
@@ -0,0 +1,188 @@
+import React from 'react';
+
+// Import configured class names generator functions with predetermined styles.
+import {cx, cva} from './cva.config';
+
+/**
+ * Type definitions for the Flex component props enriched with Tailwind CSS class and CSS mapping details.
+ */
+interface FlexProps {
+ as?: React.ElementType;
+ asChild?: boolean;
+ children?: React.ReactNode;
+ className?: string;
+ /**
+ * Controls the flex-direction CSS property.
+ * - `'row'`: `flex-row` (CSS: `flex-direction: row`)
+ * - `'column'`: `flex-col` (CSS: `flex-direction: column`)
+ */
+ direction?: 'row' | 'column';
+ /**
+ * Controls the align-items CSS property.
+ * - `'start'`: `items-start` (CSS: `align-items: flex-start`)
+ * - `'center'`: `items-center` (CSS: `align-items: center`)
+ * - `'end'`: `items-end` (CSS: `align-items: flex-end`)
+ * - `'baseline'`: `items-baseline` (CSS: `align-items: baseline`)
+ * - `'stretch'`: `items-stretch` (CSS: `align-items: stretch`)
+ */
+ align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
+ /**
+ * Controls the justify-content CSS property.
+ * - `'center'`: `justify-center` (CSS: `justify-content: center`)
+ * - `'start'`: `justify-start` (CSS: `justify-content: flex-start`)
+ * - `'end'`: `justify-end` (CSS: `justify-content: flex-end`)
+ * - `'between'`: `justify-between` (CSS: `justify-content: space-between`)
+ */
+ justify?: 'center' | 'start' | 'end' | 'between';
+ /**
+ * Controls the gap CSS property.
+ * - `1`: `gap-1` (CSS: `gap: 0.25rem`)
+ * - `2`: `gap-2` (CSS: `gap: 0.5rem`)
+ * - `3`: `gap-3` (CSS: `gap: 0.75rem`)
+ * - `4`: `gap-4` (CSS: `gap: 1rem`)
+ * - `5`: `gap-5` (CSS: `gap: 1.25rem`)
+ */
+ gap?: 1 | 2 | 3 | 4 | 5;
+}
+
+/**
+ * Configuration for "cva" to generate a dynamic class string based on the provided flex configuration.
+ */
+const flex = cva({
+ base: 'flex',
+ variants: {
+ direction: {
+ row: 'flex-row',
+ column: 'flex-col',
+ },
+ align: {
+ start: 'items-start',
+ center: 'items-center',
+ end: 'items-end',
+ baseline: 'items-baseline',
+ stretch: 'items-stretch',
+ },
+ justify: {
+ center: 'justify-center',
+ start: 'justify-start',
+ end: 'justify-end',
+ between: 'justify-between',
+ },
+ gap: {
+ 1: 'gap-1',
+ 2: 'gap-2',
+ 3: 'gap-3',
+ 4: 'gap-4',
+ 5: 'gap-5',
+ },
+ },
+});
+
+/**
+ * A highly customizable Flex component designed to facilitate the easier use of CSS flexbox layout
+ * with additional options to control alignment, distribution, and direction of child components.
+ *
+ * @component
+ * @param {React.ElementType} [as='div'] - The element type to be rendered as the Flex container.
+ * @param {React.ReactNode} children - Elements to be included inside the Flex container.
+ * @param {string} className - Additional custom classes to enhance or modify the default styling.
+ * @param {'row' | 'column'} direction - Direction which children are laid out in the Flex container.
+ * @param {'start' | 'center' | 'end' | 'baseline' | 'stretch'} align - Align children vertically or horizontally (dependent on `direction`).
+ * @param {'center' | 'start' | 'end' | 'between'} justify - Control the distribution of children along main axis.
+ * @returns {React.ReactNode} The React component rendering the Flex container with applied styles.
+ */
+export const Flex = React.forwardRef(
+ ({as: Component = 'div', children, className = '', ...props}, ref) => {
+ const classes = cx(flex(props), className);
+
+ return (
+
+ {children}
+
+ );
+ },
+);
+
+interface BackgroundProps {
+ as?: React.ElementType;
+ asChild?: boolean;
+ children?: React.ReactNode;
+ className?: string;
+ columns?: 1 | 2 | 3 | 4 | 5;
+ rows?: 1 | 2 | 3 | 4 | 5;
+}
+
+const background = cva({
+ base: ['grid', 'absolute', 'z-0', 'inset-0', 'pointer-events-none'],
+ variants: {
+ columns: {
+ 1: 'grid-cols-1',
+ 2: 'grid-cols-2',
+ 3: 'grid-cols-3',
+ 4: 'grid-cols-4',
+ 5: 'grid-cols-5',
+ },
+ rows: {
+ 1: 'grid-rows-1',
+ 2: 'grid-rows-2',
+ 3: 'grid-rows-3',
+ 4: 'grid-rows-4',
+ 5: 'grid-rows-5',
+ },
+ },
+ defaultVariants: {
+ columns: 2,
+ },
+});
+
+export const Background = React.forwardRef(
+ ({children, className, ...props}, ref) => {
+ const classes = cx(background(props), className);
+
+ return (
+
+ {children}
+
+ );
+ },
+);
+
+// /**
+// * Grid
+// */
+// const grid = cva({
+// base: 'grid',
+// variants: {
+// gridTemplateColumns: {
+// three: 'grid-cols-3',
+// },
+// },
+// defaultVariants: {
+// gridTemplateColumns: 'three',
+// },
+// });
+
+// export const Grid = React.forwardRef((props, ref) => (
+//
+// ));
+
+// // export const Section = React.forwardRef((props, ref) => (
+// //
+// // ));
+
+// const container = cva({
+// base: 'container mx-auto px-4',
+// variants: {
+// size: {
+// small: 'max-w-sm',
+// large: 'max-w-7xl',
+// },
+// },
+// defaultVariants: {
+// size: 'large',
+// },
+// });
+
+// export const Container = React.forwardRef((props, ref) => (
+//
+// ));
diff --git a/app/components/hydrogen/new/cva.config.js b/app/components/hydrogen/new/cva.config.js
new file mode 100644
index 0000000..7b6a37f
--- /dev/null
+++ b/app/components/hydrogen/new/cva.config.js
@@ -0,0 +1,8 @@
+import {defineConfig} from 'cva';
+import {twMerge} from 'tailwind-merge';
+
+export const {cva, cx, compose} = defineConfig({
+ hooks: {
+ onComplete: (className) => twMerge(className),
+ },
+});
diff --git a/app/components/hydrogen/new/scratch-pad.jsx b/app/components/hydrogen/new/scratch-pad.jsx
new file mode 100644
index 0000000..0095145
--- /dev/null
+++ b/app/components/hydrogen/new/scratch-pad.jsx
@@ -0,0 +1,175 @@
+import React from 'react';
+import {cva} from 'cva';
+
+/**
+ * Trying a new thing — starting from what I actually need
+ */
+
+function Dx({props}) {
+ return {props.children};
+}
+
+/**
+ * Components:
+ * - Box
+ * - Flex
+ * - Grid
+ * - Section
+ * - Container
+ *
+ * Common layout props:
+ * - Padding:
+ * - p, px, py, pt, pr, pb, pl
+ * - Responsive 0 to 9, or any CSS value
+ * - Margin
+ * - m, mx, my, mt, mr, mb, ml
+ * - Responsive -9 to 9, or any CSS value
+ * - Width: width, minWidth, maxWidth
+ * - https://tailwindcss.com/docs/width
+ * - Height:
+ * - height: https://tailwindcss.com/docs/height
+ * - minHeight: https://tailwindcss.com/docs/min-height
+ * - maxHeight: https://tailwindcss.com/docs/max-height
+ * - Position:
+ * - position: static | relative | absolute | fixed | sticky
+ * - inset: Responsive: -9 - 9, or any CSS value
+ * - top: Responsive: -9 - 9, or any CSS value
+ * - right: Responsive: -9 - 9, or any CSS value
+ * - bottom: Responsive: -9 - 9, or any CSS value
+ * - left: Responsive: -9 - 9, or any CSS value
+ * - Flex children
+ * - flexBasis: Responsive (e.g. 100%)
+ * - flexShrink: Responsive>
+ * - flexGrow: Responsive>
+ * - Grid children
+ * - gridColumn: Responsive
+ * - gridColumnStart: Responsive
+ * - gridColumnEnd: Responsive
+ * - gridRow: Responsive
+ * - gridRowStart: Responsive
+ * - gridRowEnd: Responsive
+ */
+
+const flex = cva({
+ base: 'flex',
+ variants: {},
+});
+
+const Flex = React.forwardRef(
+ ({as: Component = 'div', asChild, children, ...props}, ref) => {
+ const className = flex(props); // Apply CVA-generated class
+
+ if (asChild) {
+ // If asChild is true, clone the only child and pass all props
+ return React.cloneElement(React.Children.only(children), {
+ ...props,
+ ref,
+ className: `${children.props.className || ''} ${className}`,
+ });
+ }
+
+ return (
+
+ {children}
+
+ );
+ },
+);
+
+function DemoDX(props) {
+ /**
+ * Use Tailwind values for all prop values —
+ * ideally dynamically via [`resolveConfig`](https://tailwindcss.com/docs/configuration#referencing-in-java-script);
+ * if we need to [hard code it at the start](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/config.full.js)
+ * that's OK too. */
+ return (
+ <>
+ {/* Strict Utopia… not thinking about naming, just using what's there */}
+
+ {props.children}
+
+ {/* Basic*/}
+
+ {props.children}
+
+ {/* Other ideas… */}
+ {/* Responsive styles: `default, tablet, laptop, desktop` */}
+
+ {props.children}
+
+ {/* With min-max, array of objects for responsive */}
+
+ {props.children}
+
+ {/* Prop shorthands */}
+
+ {props.children}
+
+ >
+ );
+}
+
+// Define possible style variants and default props if needed
+const box = cva({
+ base: 'box-border p-0 m-0', // base classes including resetting padding and margin
+ variants: {
+ display: {
+ none: 'hidden',
+ block: 'block',
+ inline: 'inline',
+ inlineBlock: 'inline-block',
+ flex: 'flex',
+ inlineFlex: 'inline-flex',
+ },
+ position: {
+ static: 'static',
+ fixed: 'fixed',
+ absolute: 'absolute',
+ relative: 'relative',
+ sticky: 'sticky',
+ },
+ // Add more Tailwind variants for other CSS properties as needed
+ },
+ compoundVariants: [
+ // Compound variants can be used for responsive or state-based styling
+ ],
+ defaultVariants: {
+ display: 'block',
+ },
+});
+
+const Box = React.forwardRef(
+ ({as: Component = 'div', asChild, children, ...props}, ref) => {
+ const className = box(props); // Apply CVA-generated class
+
+ if (asChild) {
+ // If asChild is true, clone the only child and pass all props
+ return React.cloneElement(React.Children.only(children), {
+ ...props,
+ ref,
+ className: `${children.props.className || ''} ${className}`,
+ });
+ }
+
+ return (
+
+ {children}
+
+ );
+ },
+);
diff --git a/app/components/hydrogen/new/tokens.js b/app/components/hydrogen/new/tokens.js
new file mode 100644
index 0000000..b6628fd
--- /dev/null
+++ b/app/components/hydrogen/new/tokens.js
@@ -0,0 +1,30 @@
+/**
+ * Palette + Dark Mode:
+ * - text
+ * - background
+ * - primary
+ * - secondary
+ * - accent
+ * - highlight
+ * - muted
+ *
+ * Colours: RGB + Alpha
+ */
+
+/**
+ * Typography
+ *
+ * fonts: (for each: typeface, weight, line height, emphasis + bold alts)
+ * - display
+ * - heading
+ * - body
+ * - code
+ *
+ * fontSizes:
+ * - 1: 12
+ * - 2: 14
+ * - 3: 16
+ * - 4: 20
+ * - 5: 24
+ * - 6: 32
+ */
diff --git a/app/routes/products.$handle/route.jsx b/app/routes/products.$handle/route.jsx
index 50afa31..b285088 100644
--- a/app/routes/products.$handle/route.jsx
+++ b/app/routes/products.$handle/route.jsx
@@ -8,6 +8,7 @@ import Reviews from './sections/reviews';
import Spotlight from './sections/spotlight';
import Recommended from './sections/recommended';
import Marquee from './sections/marquee';
+import {Flex} from '@h2/new/Layout';
export const meta = ({data}) => {
return [{title: `Hydrogen | ${data?.product.title ?? ''}`}];
diff --git a/app/routes/products.$handle/sections/hero.jsx b/app/routes/products.$handle/sections/hero.jsx
index 25da5cc..39ba590 100644
--- a/app/routes/products.$handle/sections/hero.jsx
+++ b/app/routes/products.$handle/sections/hero.jsx
@@ -5,6 +5,9 @@ import {AddToCartButton} from '@h2/Button';
import {Heading, Text} from '@h2/Text';
import {Price, PriceCompareAt} from '@h2/Price';
import {ShopPayButton} from '@h2/ShopPayButton';
+import {Background, Flex} from '@h2/new/Layout';
+import Link from '@h2/Link';
+import Accordion from '@h2/new/Accordion';
export default function Hero() {
const {product} = useLoaderData();
@@ -23,18 +26,20 @@ export default function Hero() {
sizes="(min-width: 45em) 50vw, 100vw"
/>
-
+
);
@@ -44,6 +49,27 @@ function ProductSummary() {
const {product, variants} = useLoaderData();
const {selectedVariant, title, description} = product;
+ const accordionData = [
+ {
+ id: '1',
+ title: 'Materials',
+ content:
+ 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Alias debitis illo unde itaque eius eos necessitatibus assumenda, quos nisi cum reprehenderit aut placeat modi corrupti repudiandae mollitia corporis et labore?',
+ },
+ {
+ id: '2',
+ title: 'Care Instructions',
+ content:
+ 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Alias debitis illo unde itaque eius eos necessitatibus assumenda, quos nisi cum reprehenderit aut placeat modi corrupti repudiandae mollitia corporis et labore?',
+ },
+ {
+ id: '3',
+ title: 'Fit',
+ content:
+ 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Alias debitis illo unde itaque eius eos necessitatibus assumenda, quos nisi cum reprehenderit aut placeat modi corrupti repudiandae mollitia corporis et labore?',
+ },
+ ];
+
return (
- */}
+
-
+
{/* */}
Receive it by{' '}
{businessDaysFromNow(7)}
-
-
+
+
{/* */}
Free shipping over $50
-
-
+
+
{/* */}
Free 30-day returns
-
+
-
-
- Materials
- +
-
-
- Care Instructions
- +
-
-
- Fit
- +
-
-
-
+
+
+ {/* */}
);
}
@@ -216,7 +236,7 @@ function ProductForm({product, selectedVariant, variants}) {
)}
-
+
{selectedVariant?.availableForSale ? 'Add to cart' : 'Sold out'}
-
+
);
}
diff --git a/jsconfig.json b/jsconfig.json
deleted file mode 100644
index 414b665..0000000
--- a/jsconfig.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "compilerOptions": {
- "checkJs": false,
- "target": "ES2022",
- "module": "ES2022",
- "moduleResolution": "Bundler",
- "baseUrl": ".",
- "paths": {
- "@h2/*": ["app/components/hydrogen/*"],
- "~/*": ["app/*"]
- }
- },
- "include": ["./**/*.d.ts", "./**/*.js", "./**/*.jsx"]
-}
diff --git a/package-lock.json b/package-lock.json
index 77f935b..29dd77c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,6 +26,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-use": "^17.5.0",
+ "tailwind-merge": "^2.3.0",
"typographic-base": "^1.0.4"
},
"devDependencies": {
@@ -46,6 +47,7 @@
"eslint-plugin-hydrogen": "0.12.2",
"prettier": "^2.8.4",
"tailwindcss": "^3.4.3",
+ "ts-node": "^10.9.2",
"typescript": "^5.2.2",
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.3.1"
@@ -7366,6 +7368,30 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true
+ },
"node_modules/@types/acorn": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
@@ -9904,6 +9930,12 @@
"node": ">= 10"
}
},
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
"node_modules/cross-fetch": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
@@ -15293,6 +15325,12 @@
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.5.3.tgz",
"integrity": "sha512-vGBKTA+jwM4KgjGZ+S/8/Mkj9rWzePyGY6jManXPGhiWu63RYwW8dKPyk5koP+8qNVhPhHgFa1y/MJ4wrjsNrg=="
},
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
"node_modules/map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@@ -20772,6 +20810,18 @@
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
+ "node_modules/tailwind-merge": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz",
+ "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==",
+ "dependencies": {
+ "@babel/runtime": "^7.24.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
"node_modules/tailwindcss": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
@@ -21253,6 +21303,64 @@
"code-block-writer": "^12.0.0"
}
},
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/tsconfck": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz",
@@ -21969,6 +22077,12 @@
"node": ">=8"
}
},
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true
+ },
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -22869,6 +22983,15 @@
"node": ">=12"
}
},
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 5771045..be6128c 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-use": "^17.5.0",
+ "tailwind-merge": "^2.3.0",
"typographic-base": "^1.0.4"
},
"devDependencies": {
@@ -51,6 +52,7 @@
"eslint-plugin-hydrogen": "0.12.2",
"prettier": "^2.8.4",
"tailwindcss": "^3.4.3",
+ "ts-node": "^10.9.2",
"typescript": "^5.2.2",
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.3.1"
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..e48b63b
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,35 @@
+{
+ // "compilerOptions": {
+ // "checkJs": false,
+ // "target": "ES2022",
+ // "module": "ES2022",
+ // "moduleResolution": "Bundler",
+ // "baseUrl": ".",
+ // "paths": {
+ // "@h2/*": ["app/components/hydrogen/*"],
+ // "~/*": ["app/*"]
+ // }
+ // },
+ "compilerOptions": {
+ "lib": ["DOM", "DOM.Iterable", "ES2022"],
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "Bundler",
+ "resolveJsonModule": true,
+ "module": "ES2022",
+ "target": "ES2022",
+ "strict": true,
+ "allowJs": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true,
+ "baseUrl": ".",
+ "types": ["@shopify/oxygen-workers-types"],
+ "paths": {
+ "@h2/*": ["app/components/hydrogen/*"],
+ "~/*": ["app/*"]
+ },
+ "noEmit": true
+ },
+ "include": ["./**/*.d.ts", "./**/*.js", "./**/*.jsx"]
+}