@shopify/cli-hydrogen 3.26.0 → 4.0.0-alpha.1
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.
- package/dist/commands/hydrogen/build.js +89 -0
- package/dist/commands/hydrogen/dev.js +116 -0
- package/dist/commands/hydrogen/init.js +42 -0
- package/dist/commands/hydrogen/preview.js +34 -0
- package/dist/hooks/init.js +21 -0
- package/dist/templates/demo-store/.editorconfig +8 -0
- package/dist/templates/demo-store/.eslintignore +4 -0
- package/dist/templates/demo-store/.eslintrc.js +16 -0
- package/dist/templates/demo-store/.graphqlrc.yml +1 -0
- package/dist/templates/demo-store/.prettierignore +2 -0
- package/dist/templates/demo-store/.turbo/turbo-build.log +13 -0
- package/dist/templates/demo-store/app/components/AccountAddressBook.tsx +97 -0
- package/dist/templates/demo-store/app/components/AccountDetails.tsx +41 -0
- package/dist/templates/demo-store/app/components/AddToCartButton.tsx +42 -0
- package/dist/templates/demo-store/app/components/Breadcrumbs.tsx +36 -0
- package/dist/templates/demo-store/app/components/Button.tsx +56 -0
- package/dist/templates/demo-store/app/components/Cart.tsx +431 -0
- package/dist/templates/demo-store/app/components/CartLoading.tsx +50 -0
- package/dist/templates/demo-store/app/components/CountrySelector.tsx +180 -0
- package/dist/templates/demo-store/app/components/Drawer.tsx +115 -0
- package/dist/templates/demo-store/app/components/FeaturedCollections.tsx +54 -0
- package/dist/templates/demo-store/app/components/FeaturedProducts.tsx +116 -0
- package/dist/templates/demo-store/app/components/FeaturedSection.tsx +39 -0
- package/dist/templates/demo-store/app/components/GenericError.tsx +58 -0
- package/dist/templates/demo-store/app/components/Grid.tsx +44 -0
- package/dist/templates/demo-store/app/components/Hero.tsx +136 -0
- package/dist/templates/demo-store/app/components/Icon.tsx +253 -0
- package/dist/templates/demo-store/app/components/Input.tsx +24 -0
- package/dist/templates/demo-store/app/components/Layout.tsx +492 -0
- package/dist/templates/demo-store/app/components/Link.tsx +46 -0
- package/dist/templates/demo-store/app/components/Modal.tsx +46 -0
- package/dist/templates/demo-store/app/components/NotFound.tsx +22 -0
- package/dist/templates/demo-store/app/components/OrderCard.tsx +85 -0
- package/dist/templates/demo-store/app/components/Pagination.tsx +277 -0
- package/dist/templates/demo-store/app/components/ProductCard.tsx +146 -0
- package/dist/templates/demo-store/app/components/ProductGallery.tsx +114 -0
- package/dist/templates/demo-store/app/components/ProductGrid.tsx +93 -0
- package/dist/templates/demo-store/app/components/ProductSwimlane.tsx +30 -0
- package/dist/templates/demo-store/app/components/Skeleton.tsx +24 -0
- package/dist/templates/demo-store/app/components/SortFilter.tsx +411 -0
- package/dist/templates/demo-store/app/components/Text.tsx +192 -0
- package/dist/templates/demo-store/app/components/index.ts +28 -0
- package/dist/templates/demo-store/app/data/countries.ts +194 -0
- package/dist/templates/demo-store/app/data/index.ts +1037 -0
- package/dist/templates/demo-store/app/entry.client.tsx +4 -0
- package/dist/templates/demo-store/app/entry.server.tsx +26 -0
- package/dist/templates/demo-store/app/hooks/useCartFetchers.tsx +14 -0
- package/dist/templates/demo-store/app/hooks/useIsHydrated.tsx +12 -0
- package/dist/templates/demo-store/app/lib/const.ts +10 -0
- package/dist/templates/demo-store/app/lib/placeholders.ts +242 -0
- package/dist/templates/demo-store/app/lib/seo/common.tsx +324 -0
- package/dist/templates/demo-store/app/lib/seo/debugger.tsx +175 -0
- package/dist/templates/demo-store/app/lib/seo/image.tsx +32 -0
- package/dist/templates/demo-store/app/lib/seo/index.ts +4 -0
- package/dist/templates/demo-store/app/lib/seo/seo.tsx +24 -0
- package/dist/templates/demo-store/app/lib/seo/types.ts +70 -0
- package/dist/templates/demo-store/app/lib/session.server.ts +57 -0
- package/dist/templates/demo-store/app/lib/type.ts +21 -0
- package/dist/templates/demo-store/app/lib/utils.ts +310 -0
- package/dist/templates/demo-store/app/root.tsx +282 -0
- package/dist/templates/demo-store/app/routes/$.tsx +7 -0
- package/dist/templates/demo-store/app/routes/$lang/$.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/[robots.txt].tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/[sitemap.xml].tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__private/address/$id.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__private/edit.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__private/logout.ts +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__private/orders.$id.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__public/activate.$id.$activationToken.tsx +6 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__public/login.tsx +7 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__public/recover.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__public/register.tsx +6 -0
- package/dist/templates/demo-store/app/routes/$lang/account/__public/reset.$id.$resetToken.tsx +5 -0
- package/dist/templates/demo-store/app/routes/$lang/account.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/api/countries.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/api/products.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/cart.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/collections/$collectionHandle.tsx +6 -0
- package/dist/templates/demo-store/app/routes/$lang/collections/all.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/collections/index.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/featured-products.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/index.tsx +7 -0
- package/dist/templates/demo-store/app/routes/$lang/journal/$journalHandle.tsx +7 -0
- package/dist/templates/demo-store/app/routes/$lang/journal/index.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/og-image.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/pages/$pageHandle.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/policies/$policyHandle.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/policies/index.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/products/$productHandle.tsx +6 -0
- package/dist/templates/demo-store/app/routes/$lang/products/index.tsx +1 -0
- package/dist/templates/demo-store/app/routes/$lang/search.tsx +6 -0
- package/dist/templates/demo-store/app/routes/[robots.txt].tsx +40 -0
- package/dist/templates/demo-store/app/routes/[sitemap.xml].tsx +198 -0
- package/dist/templates/demo-store/app/routes/account/__private/address/$id.tsx +320 -0
- package/dist/templates/demo-store/app/routes/account/__private/edit.tsx +273 -0
- package/dist/templates/demo-store/app/routes/account/__private/logout.ts +29 -0
- package/dist/templates/demo-store/app/routes/account/__private/orders.$id.tsx +324 -0
- package/dist/templates/demo-store/app/routes/account/__public/activate.$id.$activationToken.tsx +218 -0
- package/dist/templates/demo-store/app/routes/account/__public/login.tsx +197 -0
- package/dist/templates/demo-store/app/routes/account/__public/recover.tsx +144 -0
- package/dist/templates/demo-store/app/routes/account/__public/register.tsx +184 -0
- package/dist/templates/demo-store/app/routes/account/__public/reset.$id.$resetToken.tsx +214 -0
- package/dist/templates/demo-store/app/routes/account.tsx +191 -0
- package/dist/templates/demo-store/app/routes/api/countries.tsx +22 -0
- package/dist/templates/demo-store/app/routes/api/products.tsx +116 -0
- package/dist/templates/demo-store/app/routes/cart.tsx +498 -0
- package/dist/templates/demo-store/app/routes/collections/$collectionHandle.tsx +308 -0
- package/dist/templates/demo-store/app/routes/collections/all.tsx +5 -0
- package/dist/templates/demo-store/app/routes/collections/index.tsx +195 -0
- package/dist/templates/demo-store/app/routes/discounts.$code.tsx +60 -0
- package/dist/templates/demo-store/app/routes/featured-products.tsx +58 -0
- package/dist/templates/demo-store/app/routes/index.tsx +254 -0
- package/dist/templates/demo-store/app/routes/journal/$journalHandle.tsx +147 -0
- package/dist/templates/demo-store/app/routes/journal/index.tsx +150 -0
- package/dist/templates/demo-store/app/routes/og-image.tsx +19 -0
- package/dist/templates/demo-store/app/routes/pages/$pageHandle.tsx +82 -0
- package/dist/templates/demo-store/app/routes/policies/$policyHandle.tsx +117 -0
- package/dist/templates/demo-store/app/routes/policies/index.tsx +104 -0
- package/dist/templates/demo-store/app/routes/products/$productHandle.tsx +561 -0
- package/dist/templates/demo-store/app/routes/products/index.tsx +155 -0
- package/dist/templates/demo-store/app/routes/search.tsx +205 -0
- package/dist/templates/demo-store/app/styles/custom-font.css +13 -0
- package/dist/templates/demo-store/package-lock.json +25515 -0
- package/dist/templates/demo-store/package.json +67 -0
- package/dist/templates/demo-store/playwright.config.ts +109 -0
- package/dist/templates/demo-store/postcss.config.js +10 -0
- package/dist/templates/demo-store/public/favicon.svg +28 -0
- package/dist/templates/demo-store/public/fonts/IBMPlexSerif-Text.woff2 +0 -0
- package/dist/templates/demo-store/public/fonts/IBMPlexSerif-TextItalic.woff2 +0 -0
- package/dist/templates/demo-store/remix.config.js +12 -0
- package/dist/templates/demo-store/remix.env.d.ts +34 -0
- package/dist/templates/demo-store/remix.init/index.ts +15 -0
- package/dist/templates/demo-store/remix.init/package.json +7 -0
- package/dist/templates/demo-store/server.ts +87 -0
- package/dist/templates/demo-store/styles/app.css +182 -0
- package/dist/templates/demo-store/tailwind.config.js +70 -0
- package/dist/templates/demo-store/tests/cart.test.ts +70 -0
- package/dist/templates/demo-store/tests/seo.test.ts +36 -0
- package/dist/templates/demo-store/tests/utils.ts +100 -0
- package/dist/templates/demo-store/tsconfig.json +26 -0
- package/dist/templates/hello-world/.eslintignore +4 -0
- package/dist/templates/hello-world/.eslintrc.js +6 -0
- package/dist/templates/hello-world/.graphqlrc.yml +1 -0
- package/dist/templates/hello-world/.turbo/turbo-build.log +9 -0
- package/dist/templates/hello-world/README.md +20 -0
- package/dist/templates/hello-world/app/components/Layout.tsx +15 -0
- package/dist/templates/hello-world/app/components/index.ts +1 -0
- package/dist/templates/hello-world/app/entry.client.tsx +4 -0
- package/dist/templates/hello-world/app/entry.server.tsx +21 -0
- package/dist/templates/hello-world/app/root.tsx +212 -0
- package/dist/templates/hello-world/app/routes/index.tsx +7 -0
- package/dist/templates/hello-world/app/styles/app.css +38 -0
- package/dist/templates/hello-world/package-lock.json +27641 -0
- package/dist/templates/hello-world/package.json +41 -0
- package/dist/templates/hello-world/public/favicon.svg +28 -0
- package/dist/templates/hello-world/remix.env.d.ts +29 -0
- package/dist/templates/hello-world/server.ts +127 -0
- package/dist/templates/hello-world/tsconfig.json +25 -0
- package/dist/utils/config.js +81 -0
- package/dist/utils/flags.js +15 -0
- package/dist/utils/log.js +20 -0
- package/dist/utils/mini-oxygen.js +70 -0
- package/package.json +27 -64
- package/tmp-create-app.mjs +29 -0
- package/LICENSE +0 -8
- package/README.md +0 -61
- package/dist/cli/commands/hydrogen/add/eslint.d.ts +0 -11
- package/dist/cli/commands/hydrogen/add/eslint.js +0 -26
- package/dist/cli/commands/hydrogen/add/eslint.js.map +0 -1
- package/dist/cli/commands/hydrogen/add/tailwind.d.ts +0 -11
- package/dist/cli/commands/hydrogen/add/tailwind.js +0 -26
- package/dist/cli/commands/hydrogen/add/tailwind.js.map +0 -1
- package/dist/cli/commands/hydrogen/build.d.ts +0 -14
- package/dist/cli/commands/hydrogen/build.js +0 -49
- package/dist/cli/commands/hydrogen/build.js.map +0 -1
- package/dist/cli/commands/hydrogen/deploy.d.ts +0 -19
- package/dist/cli/commands/hydrogen/deploy.js +0 -58
- package/dist/cli/commands/hydrogen/deploy.js.map +0 -1
- package/dist/cli/commands/hydrogen/dev.d.ts +0 -13
- package/dist/cli/commands/hydrogen/dev.js +0 -31
- package/dist/cli/commands/hydrogen/dev.js.map +0 -1
- package/dist/cli/commands/hydrogen/info.d.ts +0 -12
- package/dist/cli/commands/hydrogen/info.js +0 -28
- package/dist/cli/commands/hydrogen/info.js.map +0 -1
- package/dist/cli/commands/hydrogen/preview.d.ts +0 -13
- package/dist/cli/commands/hydrogen/preview.js +0 -46
- package/dist/cli/commands/hydrogen/preview.js.map +0 -1
- package/dist/cli/constants.d.ts +0 -15
- package/dist/cli/constants.js +0 -16
- package/dist/cli/constants.js.map +0 -1
- package/dist/cli/flags.d.ts +0 -4
- package/dist/cli/flags.js +0 -16
- package/dist/cli/flags.js.map +0 -1
- package/dist/cli/models/hydrogen.d.ts +0 -22
- package/dist/cli/models/hydrogen.js +0 -82
- package/dist/cli/models/hydrogen.js.map +0 -1
- package/dist/cli/prompts/git-init.d.ts +0 -1
- package/dist/cli/prompts/git-init.js +0 -16
- package/dist/cli/prompts/git-init.js.map +0 -1
- package/dist/cli/services/build/check-lockfile.d.ts +0 -3
- package/dist/cli/services/build/check-lockfile.js +0 -80
- package/dist/cli/services/build/check-lockfile.js.map +0 -1
- package/dist/cli/services/build.d.ts +0 -14
- package/dist/cli/services/build.js +0 -44
- package/dist/cli/services/build.js.map +0 -1
- package/dist/cli/services/deploy/config.d.ts +0 -4
- package/dist/cli/services/deploy/config.js +0 -49
- package/dist/cli/services/deploy/config.js.map +0 -1
- package/dist/cli/services/deploy/error.d.ts +0 -4
- package/dist/cli/services/deploy/error.js +0 -11
- package/dist/cli/services/deploy/error.js.map +0 -1
- package/dist/cli/services/deploy/graphql/create_deployment.d.ts +0 -10
- package/dist/cli/services/deploy/graphql/create_deployment.js +0 -15
- package/dist/cli/services/deploy/graphql/create_deployment.js.map +0 -1
- package/dist/cli/services/deploy/graphql/upload_deployment.d.ts +0 -1
- package/dist/cli/services/deploy/graphql/upload_deployment.js +0 -16
- package/dist/cli/services/deploy/graphql/upload_deployment.js.map +0 -1
- package/dist/cli/services/deploy/types.d.ts +0 -37
- package/dist/cli/services/deploy/types.js +0 -2
- package/dist/cli/services/deploy/types.js.map +0 -1
- package/dist/cli/services/deploy/upload.d.ts +0 -5
- package/dist/cli/services/deploy/upload.js +0 -81
- package/dist/cli/services/deploy/upload.js.map +0 -1
- package/dist/cli/services/deploy.d.ts +0 -2
- package/dist/cli/services/deploy.js +0 -103
- package/dist/cli/services/deploy.js.map +0 -1
- package/dist/cli/services/dev/check-version.d.ts +0 -1
- package/dist/cli/services/dev/check-version.js +0 -30
- package/dist/cli/services/dev/check-version.js.map +0 -1
- package/dist/cli/services/dev.d.ts +0 -10
- package/dist/cli/services/dev.js +0 -36
- package/dist/cli/services/dev.js.map +0 -1
- package/dist/cli/services/eslint.d.ts +0 -8
- package/dist/cli/services/eslint.js +0 -74
- package/dist/cli/services/eslint.js.map +0 -1
- package/dist/cli/services/info.d.ts +0 -7
- package/dist/cli/services/info.js +0 -131
- package/dist/cli/services/info.js.map +0 -1
- package/dist/cli/services/preview.d.ts +0 -12
- package/dist/cli/services/preview.js +0 -63
- package/dist/cli/services/preview.js.map +0 -1
- package/dist/cli/services/tailwind.d.ts +0 -9
- package/dist/cli/services/tailwind.js +0 -103
- package/dist/cli/services/tailwind.js.map +0 -1
- package/dist/cli/utilities/load-config.d.ts +0 -5
- package/dist/cli/utilities/load-config.js +0 -6
- package/dist/cli/utilities/load-config.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/oclif.manifest.json +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import * as remix from '@remix-run/dev/dist/compiler.js';
|
|
3
|
+
import fsExtra from 'fs-extra';
|
|
4
|
+
import { output } from '@shopify/cli-kit';
|
|
5
|
+
import colors from '@shopify/cli-kit/node/colors';
|
|
6
|
+
import { getProjectPaths, getRemixConfig } from '../../utils/config.js';
|
|
7
|
+
import { flags } from '../../utils/flags.js';
|
|
8
|
+
import Command from '@shopify/cli-kit/node/base-command';
|
|
9
|
+
import { Flags } from '@oclif/core';
|
|
10
|
+
|
|
11
|
+
const LOG_WORKER_BUILT = "\u{1F4E6} Worker built";
|
|
12
|
+
class Build extends Command {
|
|
13
|
+
static description = "Builds a Hydrogen storefront for production";
|
|
14
|
+
static flags = {
|
|
15
|
+
...flags,
|
|
16
|
+
sourcemap: Flags.boolean({
|
|
17
|
+
env: "SHOPIFY_HYDROGEN_FLAG_SOURCEMAP"
|
|
18
|
+
}),
|
|
19
|
+
entry: Flags.string({
|
|
20
|
+
env: "SHOPIFY_HYDROGEN_FLAG_SOURCEMAP",
|
|
21
|
+
required: true
|
|
22
|
+
}),
|
|
23
|
+
minify: Flags.boolean({
|
|
24
|
+
description: "Minify the build output",
|
|
25
|
+
env: "SHOPIFY_HYDROGEN_FLAG_MINIFY"
|
|
26
|
+
})
|
|
27
|
+
};
|
|
28
|
+
async run() {
|
|
29
|
+
const { flags: flags2 } = await this.parse(Build);
|
|
30
|
+
const directory = flags2.path ? path.resolve(flags2.path) : process.cwd();
|
|
31
|
+
await runBuild({ ...flags2, path: directory });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function runBuild({
|
|
35
|
+
entry,
|
|
36
|
+
sourcemap = true,
|
|
37
|
+
path: appPath
|
|
38
|
+
}) {
|
|
39
|
+
if (!process.env.NODE_ENV) {
|
|
40
|
+
process.env.NODE_ENV = "production";
|
|
41
|
+
}
|
|
42
|
+
const {
|
|
43
|
+
root,
|
|
44
|
+
entryFile,
|
|
45
|
+
buildPath,
|
|
46
|
+
buildPathClient,
|
|
47
|
+
buildPathWorkerFile,
|
|
48
|
+
publicPath
|
|
49
|
+
} = getProjectPaths(appPath, entry);
|
|
50
|
+
console.time(LOG_WORKER_BUILT);
|
|
51
|
+
const remixConfig = await getRemixConfig(root, entryFile, publicPath);
|
|
52
|
+
await fsExtra.rm(buildPath, { force: true, recursive: true });
|
|
53
|
+
output.info(`
|
|
54
|
+
\u{1F3D7}\uFE0F Building in ${process.env.NODE_ENV} mode...`);
|
|
55
|
+
await Promise.all([
|
|
56
|
+
copyPublicFiles(publicPath, buildPathClient),
|
|
57
|
+
remix.build(remixConfig, {
|
|
58
|
+
mode: process.env.NODE_ENV,
|
|
59
|
+
sourcemap,
|
|
60
|
+
onBuildFailure: (failure) => {
|
|
61
|
+
remix.formatBuildFailure(failure);
|
|
62
|
+
throw Error();
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
]);
|
|
66
|
+
if (process.env.NODE_ENV !== "development") {
|
|
67
|
+
console.timeEnd(LOG_WORKER_BUILT);
|
|
68
|
+
const { size } = await fsExtra.stat(buildPathWorkerFile);
|
|
69
|
+
const sizeMB = size / (1024 * 1024);
|
|
70
|
+
output.info(
|
|
71
|
+
output.content` ${colors.dim(
|
|
72
|
+
path.relative(root, buildPathWorkerFile)
|
|
73
|
+
)} ${output.token.yellow(sizeMB.toFixed(2))} MB\n`
|
|
74
|
+
);
|
|
75
|
+
if (sizeMB >= 1) {
|
|
76
|
+
output.warn(
|
|
77
|
+
"\u{1F6A8} Worker bundle exceeds 1 MB! This can delay your worker response.\n"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function copyPublicFiles(publicPath, buildPathClient) {
|
|
83
|
+
return fsExtra.copy(publicPath, buildPathClient, {
|
|
84
|
+
recursive: true,
|
|
85
|
+
overwrite: true
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { copyPublicFiles, Build as default, runBuild };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import * as remix from '@remix-run/dev/dist/compiler.js';
|
|
4
|
+
import { output } from '@shopify/cli-kit';
|
|
5
|
+
import { copyPublicFiles } from './build.js';
|
|
6
|
+
import { getProjectPaths, getRemixConfig } from '../../utils/config.js';
|
|
7
|
+
import { muteDevLogs } from '../../utils/log.js';
|
|
8
|
+
import { flags } from '../../utils/flags.js';
|
|
9
|
+
import Command from '@shopify/cli-kit/node/base-command';
|
|
10
|
+
import { Flags } from '@oclif/core';
|
|
11
|
+
import { startMiniOxygen } from '../../utils/mini-oxygen.js';
|
|
12
|
+
|
|
13
|
+
const LOG_INITIAL_BUILD = "\n\u{1F3C1} Initial build";
|
|
14
|
+
const LOG_REBUILDING = "\u{1F9F1} Rebuilding...";
|
|
15
|
+
const LOG_REBUILT = "\u{1F680} Rebuilt";
|
|
16
|
+
class Dev extends Command {
|
|
17
|
+
static description = "Runs Hydrogen storefront in a MiniOxygen worker in development";
|
|
18
|
+
static flags = {
|
|
19
|
+
...flags,
|
|
20
|
+
port: Flags.integer({
|
|
21
|
+
description: "Port to run the preview server on",
|
|
22
|
+
env: "SHOPIFY_HYDROGEN_FLAG_PORT",
|
|
23
|
+
default: 3e3
|
|
24
|
+
}),
|
|
25
|
+
entry: Flags.string({
|
|
26
|
+
env: "SHOPIFY_HYDROGEN_FLAG_ENTRY",
|
|
27
|
+
required: true
|
|
28
|
+
})
|
|
29
|
+
};
|
|
30
|
+
async run() {
|
|
31
|
+
const { flags: flags2 } = await this.parse(Dev);
|
|
32
|
+
const directory = flags2.path ? path.resolve(flags2.path) : process.cwd();
|
|
33
|
+
await runDev({ ...flags2, path: directory });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function runDev({
|
|
37
|
+
entry,
|
|
38
|
+
port,
|
|
39
|
+
path: appPath
|
|
40
|
+
}) {
|
|
41
|
+
if (!process.env.NODE_ENV)
|
|
42
|
+
process.env.NODE_ENV = "development";
|
|
43
|
+
muteDevLogs();
|
|
44
|
+
await compileAndWatch(getProjectPaths(appPath, entry), { port });
|
|
45
|
+
}
|
|
46
|
+
async function compileAndWatch(projectPaths, options = {}, isInit = true) {
|
|
47
|
+
isInit && console.time(LOG_INITIAL_BUILD);
|
|
48
|
+
const { root, entryFile, publicPath, buildPathClient, buildPathWorkerFile } = projectPaths;
|
|
49
|
+
const shouldReloadRemixApp = (file) => file.startsWith(path.resolve(root, "remix.config.")) || process.env.LOCAL_DEV && (file.includes(path.resolve("/hydrogen/src/templates/")) || file.includes(path.resolve("/hydrogen/dist/build/index.js")));
|
|
50
|
+
const remixConfig = await getRemixConfig(
|
|
51
|
+
root,
|
|
52
|
+
entryFile,
|
|
53
|
+
publicPath,
|
|
54
|
+
options.cacheBust
|
|
55
|
+
);
|
|
56
|
+
const copyingFiles = copyPublicFiles(publicPath, buildPathClient);
|
|
57
|
+
const stopCompileWatcher = await remix.watch(remixConfig, {
|
|
58
|
+
mode: process.env.NODE_ENV,
|
|
59
|
+
async onInitialBuild() {
|
|
60
|
+
await copyingFiles;
|
|
61
|
+
if (isInit) {
|
|
62
|
+
console.timeEnd(LOG_INITIAL_BUILD);
|
|
63
|
+
await startMiniOxygen({
|
|
64
|
+
root,
|
|
65
|
+
port: options.port,
|
|
66
|
+
watch: true,
|
|
67
|
+
buildPathWorkerFile,
|
|
68
|
+
buildPathClient
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
async onFileCreated(file) {
|
|
73
|
+
output.info(`
|
|
74
|
+
\u{1F4C4} File created: ${path.relative(root, file)}`);
|
|
75
|
+
if (file.startsWith(publicPath)) {
|
|
76
|
+
await copyPublicFiles(file, file.replace(publicPath, buildPathClient));
|
|
77
|
+
}
|
|
78
|
+
if (shouldReloadRemixApp(file)) {
|
|
79
|
+
await reloadRemixApp(file);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
async onFileChanged(file) {
|
|
83
|
+
output.info(`
|
|
84
|
+
\u{1F4C4} File changed: ${path.relative(root, file)}`);
|
|
85
|
+
if (file.startsWith(publicPath)) {
|
|
86
|
+
await copyPublicFiles(file, file.replace(publicPath, buildPathClient));
|
|
87
|
+
}
|
|
88
|
+
if (shouldReloadRemixApp(file)) {
|
|
89
|
+
await reloadRemixApp(file);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
async onFileDeleted(file) {
|
|
93
|
+
output.info(`
|
|
94
|
+
\u{1F4C4} File deleted: ${path.relative(root, file)}`);
|
|
95
|
+
if (file.startsWith(publicPath)) {
|
|
96
|
+
await fs.unlink(file.replace(publicPath, buildPathClient));
|
|
97
|
+
}
|
|
98
|
+
if (shouldReloadRemixApp(file)) {
|
|
99
|
+
await reloadRemixApp(file);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
onRebuildStart() {
|
|
103
|
+
output.info(LOG_REBUILDING);
|
|
104
|
+
console.time(LOG_REBUILT);
|
|
105
|
+
},
|
|
106
|
+
async onRebuildFinish() {
|
|
107
|
+
console.timeEnd(LOG_REBUILT);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
async function reloadRemixApp(cacheBust) {
|
|
111
|
+
await stopCompileWatcher();
|
|
112
|
+
compileAndWatch(projectPaths, { ...options, cacheBust }, false);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { Dev as default, runDev };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { cli } from '@remix-run/dev';
|
|
2
|
+
import Command from '@shopify/cli-kit/node/base-command';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
|
|
5
|
+
class Init extends Command {
|
|
6
|
+
static description = "Creates a new Hydrogen storefront project";
|
|
7
|
+
static flags = {
|
|
8
|
+
typescript: Flags.boolean({
|
|
9
|
+
description: "Use TypeScript",
|
|
10
|
+
env: "SHOPIFY_HYDROGEN_FLAG_TYPESCRIPT"
|
|
11
|
+
}),
|
|
12
|
+
template: Flags.string({
|
|
13
|
+
description: "The template to use",
|
|
14
|
+
env: "SHOPIFY_HYDROGEN_FLAG_TEMPLATE",
|
|
15
|
+
default: "../../templates/demo-store",
|
|
16
|
+
required: true
|
|
17
|
+
}),
|
|
18
|
+
token: Flags.string({
|
|
19
|
+
description: "A GitHub token used to access access private repository templates"
|
|
20
|
+
})
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { flags } = await this.parse(Init);
|
|
24
|
+
await runInit({ ...flags });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function runInit({
|
|
28
|
+
template,
|
|
29
|
+
typescript,
|
|
30
|
+
token
|
|
31
|
+
}) {
|
|
32
|
+
const defaults = [
|
|
33
|
+
"--template",
|
|
34
|
+
template,
|
|
35
|
+
"--install",
|
|
36
|
+
typescript ? "--typescript" : "",
|
|
37
|
+
token ? `--token ${token}` : ""
|
|
38
|
+
];
|
|
39
|
+
cli.run(["create", ...defaults]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { Init as default, runInit };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Command from '@shopify/cli-kit/node/base-command';
|
|
2
|
+
import { muteDevLogs } from '../../utils/log.js';
|
|
3
|
+
import { getProjectPaths } from '../../utils/config.js';
|
|
4
|
+
import { flags } from '../../utils/flags.js';
|
|
5
|
+
import { startMiniOxygen } from '../../utils/mini-oxygen.js';
|
|
6
|
+
|
|
7
|
+
class Preview extends Command {
|
|
8
|
+
static description = "Runs an existing Hydrogen storefront build in a MiniOxygen worker";
|
|
9
|
+
static flags = {
|
|
10
|
+
paths: flags.path,
|
|
11
|
+
port: flags.port
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags: flags2 } = await this.parse(Preview);
|
|
15
|
+
await runPreview({ ...flags2 });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function runPreview({
|
|
19
|
+
port,
|
|
20
|
+
path: appPath
|
|
21
|
+
}) {
|
|
22
|
+
if (!process.env.NODE_ENV)
|
|
23
|
+
process.env.NODE_ENV = "production";
|
|
24
|
+
const { root, buildPathWorkerFile, buildPathClient } = getProjectPaths(appPath);
|
|
25
|
+
muteDevLogs({ workerReload: false });
|
|
26
|
+
await startMiniOxygen({
|
|
27
|
+
root,
|
|
28
|
+
port,
|
|
29
|
+
buildPathClient,
|
|
30
|
+
buildPathWorkerFile
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { Preview as default, runPreview };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { output } from '@shopify/cli-kit';
|
|
3
|
+
|
|
4
|
+
const EXPERIMENTAL_VM_MODULES_FLAG = "--experimental-vm-modules";
|
|
5
|
+
const hook = async function(options) {
|
|
6
|
+
if (!options.id || !["hydrogen:dev", "hydrogen:preview"].includes(options.id)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (!process.execArgv.includes(EXPERIMENTAL_VM_MODULES_FLAG) && !(process.env.NODE_OPTIONS ?? "").includes(EXPERIMENTAL_VM_MODULES_FLAG)) {
|
|
10
|
+
output.debug(
|
|
11
|
+
`Restarting CLI process with ${EXPERIMENTAL_VM_MODULES_FLAG} flag.`
|
|
12
|
+
);
|
|
13
|
+
const [command, ...args] = process.argv;
|
|
14
|
+
args.unshift(EXPERIMENTAL_VM_MODULES_FLAG);
|
|
15
|
+
spawnSync(command, args, { stdio: "inherit" });
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var init_default = hook;
|
|
20
|
+
|
|
21
|
+
export { init_default as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {import("@types/eslint").Linter.BaseConfig}
|
|
3
|
+
*/
|
|
4
|
+
module.exports = {
|
|
5
|
+
extends: ['plugin:hydrogen/recommended', 'plugin:hydrogen/typescript'],
|
|
6
|
+
rules: {
|
|
7
|
+
'@typescript-eslint/ban-ts-comment': 'off',
|
|
8
|
+
'@typescript-eslint/naming-convention': 'off',
|
|
9
|
+
'hydrogen/prefer-image-component': 'off',
|
|
10
|
+
'no-useless-escape': 'off',
|
|
11
|
+
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
|
|
12
|
+
'no-case-declarations': 'off',
|
|
13
|
+
// TODO: Remove jest plugin from hydrogen/eslint-plugin
|
|
14
|
+
'jest/no-deprecated-functions': 'off',
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
schema: node_modules/@shopify/hydrogen-react/storefront.schema.json
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
> demo-store@0.0.0 build
|
|
3
|
+
> npm run build:css && shopify hydrogen build --entry ./server
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> demo-store@0.0.0 build:css
|
|
7
|
+
> postcss styles --base styles --dir app/styles --env production
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
🏗️ Building in production mode...
|
|
11
|
+
📦 Worker built: 1.466s
|
|
12
|
+
dist/worker/index.js 0.57 MB
|
|
13
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {Form} from '@remix-run/react';
|
|
2
|
+
import type {
|
|
3
|
+
Customer,
|
|
4
|
+
MailingAddress,
|
|
5
|
+
} from '@shopify/hydrogen-react/storefront-api-types';
|
|
6
|
+
import {Button, Link, Text} from '~/components';
|
|
7
|
+
|
|
8
|
+
export function AccountAddressBook({
|
|
9
|
+
customer,
|
|
10
|
+
addresses,
|
|
11
|
+
}: {
|
|
12
|
+
customer: Customer;
|
|
13
|
+
addresses: MailingAddress[];
|
|
14
|
+
}) {
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<div className="grid w-full gap-4 p-4 py-6 md:gap-8 md:p-8 lg:p-12">
|
|
18
|
+
<h3 className="font-bold text-lead">Address Book</h3>
|
|
19
|
+
<div>
|
|
20
|
+
{!addresses?.length && (
|
|
21
|
+
<Text className="mb-1" width="narrow" as="p" size="copy">
|
|
22
|
+
You haven't saved any addresses yet.
|
|
23
|
+
</Text>
|
|
24
|
+
)}
|
|
25
|
+
<div className="w-48">
|
|
26
|
+
<Button
|
|
27
|
+
to="address/add"
|
|
28
|
+
className="mt-2 text-sm w-full mb-6"
|
|
29
|
+
variant="secondary"
|
|
30
|
+
>
|
|
31
|
+
Add an Address
|
|
32
|
+
</Button>
|
|
33
|
+
</div>
|
|
34
|
+
{Boolean(addresses?.length) && (
|
|
35
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
|
36
|
+
{customer.defaultAddress && (
|
|
37
|
+
<Address address={customer.defaultAddress} defaultAddress />
|
|
38
|
+
)}
|
|
39
|
+
{addresses
|
|
40
|
+
.filter((address) => address.id !== customer.defaultAddress?.id)
|
|
41
|
+
.map((address) => (
|
|
42
|
+
<Address key={address.id} address={address} />
|
|
43
|
+
))}
|
|
44
|
+
</div>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function Address({
|
|
53
|
+
address,
|
|
54
|
+
defaultAddress,
|
|
55
|
+
}: {
|
|
56
|
+
address: MailingAddress;
|
|
57
|
+
defaultAddress?: boolean;
|
|
58
|
+
}) {
|
|
59
|
+
return (
|
|
60
|
+
<div className="lg:p-8 p-6 border border-gray-200 rounded flex flex-col">
|
|
61
|
+
{defaultAddress && (
|
|
62
|
+
<div className="mb-3 flex flex-row">
|
|
63
|
+
<span className="px-3 py-1 text-xs font-medium rounded-full bg-primary/20 text-primary/50">
|
|
64
|
+
Default
|
|
65
|
+
</span>
|
|
66
|
+
</div>
|
|
67
|
+
)}
|
|
68
|
+
<ul className="flex-1 flex-row">
|
|
69
|
+
{(address.firstName || address.lastName) && (
|
|
70
|
+
<li>
|
|
71
|
+
{'' +
|
|
72
|
+
(address.firstName && address.firstName + ' ') +
|
|
73
|
+
address?.lastName}
|
|
74
|
+
</li>
|
|
75
|
+
)}
|
|
76
|
+
{address.formatted &&
|
|
77
|
+
address.formatted.map((line: string) => <li key={line}>{line}</li>)}
|
|
78
|
+
</ul>
|
|
79
|
+
|
|
80
|
+
<div className="flex flex-row font-medium mt-6">
|
|
81
|
+
<Link
|
|
82
|
+
to={`/account/address/${encodeURIComponent(address.id)}`}
|
|
83
|
+
className="text-left underline text-sm"
|
|
84
|
+
prefetch="intent"
|
|
85
|
+
>
|
|
86
|
+
Edit
|
|
87
|
+
</Link>
|
|
88
|
+
<Form action="address/delete" method="delete">
|
|
89
|
+
<input type="hidden" name="addressId" value={address.id} />
|
|
90
|
+
<button className="text-left text-primary/50 ml-6 text-sm">
|
|
91
|
+
Remove
|
|
92
|
+
</button>
|
|
93
|
+
</Form>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type {Customer} from '@shopify/hydrogen-react/storefront-api-types';
|
|
2
|
+
import {Link} from '~/components';
|
|
3
|
+
|
|
4
|
+
export function AccountDetails({customer}: {customer: Customer}) {
|
|
5
|
+
const {firstName, lastName, email, phone} = customer;
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<div className="grid w-full gap-4 p-4 py-6 md:gap-8 md:p-8 lg:p-12">
|
|
10
|
+
<h3 className="font-bold text-lead">Account Details</h3>
|
|
11
|
+
<div className="lg:p-8 p-6 border border-gray-200 rounded">
|
|
12
|
+
<div className="flex">
|
|
13
|
+
<h3 className="font-bold text-base flex-1">Profile & Security</h3>
|
|
14
|
+
<Link
|
|
15
|
+
prefetch="intent"
|
|
16
|
+
className="underline text-sm font-normal"
|
|
17
|
+
to="/account/edit"
|
|
18
|
+
>
|
|
19
|
+
Edit
|
|
20
|
+
</Link>
|
|
21
|
+
</div>
|
|
22
|
+
<div className="mt-4 text-sm text-primary/50">Name</div>
|
|
23
|
+
<p className="mt-1">
|
|
24
|
+
{firstName || lastName
|
|
25
|
+
? (firstName ? firstName + ' ' : '') + lastName
|
|
26
|
+
: 'Add name'}{' '}
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
<div className="mt-4 text-sm text-primary/50">Contact</div>
|
|
30
|
+
<p className="mt-1">{phone ?? 'Add mobile'}</p>
|
|
31
|
+
|
|
32
|
+
<div className="mt-4 text-sm text-primary/50">Email address</div>
|
|
33
|
+
<p className="mt-1">{email}</p>
|
|
34
|
+
|
|
35
|
+
<div className="mt-4 text-sm text-primary/50">Password</div>
|
|
36
|
+
<p className="mt-1">**************</p>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {CartLineInput} from '@shopify/hydrogen-react/storefront-api-types';
|
|
2
|
+
import {useFetcher, useMatches} from '@remix-run/react';
|
|
3
|
+
import {Button} from '~/components';
|
|
4
|
+
import {CartAction} from '~/lib/type';
|
|
5
|
+
|
|
6
|
+
export function AddToCartButton({
|
|
7
|
+
children,
|
|
8
|
+
lines,
|
|
9
|
+
className = '',
|
|
10
|
+
variant = 'primary',
|
|
11
|
+
width = 'full',
|
|
12
|
+
...props
|
|
13
|
+
}: {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
lines: CartLineInput[];
|
|
16
|
+
className?: string;
|
|
17
|
+
variant?: 'primary' | 'secondary' | 'inline';
|
|
18
|
+
width?: 'auto' | 'full';
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
}) {
|
|
21
|
+
const [root] = useMatches();
|
|
22
|
+
const selectedLocale = root?.data?.selectedLocale;
|
|
23
|
+
const fetcher = useFetcher();
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<fetcher.Form action="/cart" method="post">
|
|
27
|
+
<input type="hidden" name="cartAction" value={CartAction.ADD_TO_CART} />
|
|
28
|
+
<input type="hidden" name="countryCode" value={selectedLocale.country} />
|
|
29
|
+
<input type="hidden" name="lines" value={JSON.stringify(lines)} />
|
|
30
|
+
<Button
|
|
31
|
+
as="button"
|
|
32
|
+
type="submit"
|
|
33
|
+
width={width}
|
|
34
|
+
variant={variant}
|
|
35
|
+
className={className}
|
|
36
|
+
{...props}
|
|
37
|
+
>
|
|
38
|
+
{children}
|
|
39
|
+
</Button>
|
|
40
|
+
</fetcher.Form>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Text} from './Text';
|
|
2
|
+
import {Link} from './Link';
|
|
3
|
+
|
|
4
|
+
interface Breadcrumb {
|
|
5
|
+
handle: string;
|
|
6
|
+
title: string;
|
|
7
|
+
id: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Renders a breadcrumb trail from a references metafield list
|
|
11
|
+
export function Breadcrumbs({
|
|
12
|
+
breadcrumbs,
|
|
13
|
+
}: {
|
|
14
|
+
breadcrumbs?: Breadcrumb[] | null;
|
|
15
|
+
}) {
|
|
16
|
+
if (!breadcrumbs || breadcrumbs.length === 0) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const breadcrumbsMarkup = breadcrumbs.map((breadcrumb, index) => {
|
|
21
|
+
const isLastBreadcrumb = index === breadcrumbs.length - 1;
|
|
22
|
+
|
|
23
|
+
return isLastBreadcrumb ? (
|
|
24
|
+
<Text key={breadcrumb.id} as="span">
|
|
25
|
+
{breadcrumb.title}
|
|
26
|
+
</Text>
|
|
27
|
+
) : (
|
|
28
|
+
<span key={breadcrumb.id}>
|
|
29
|
+
<Link to={`/collections/${breadcrumb.handle}`}>{breadcrumb.title}</Link>
|
|
30
|
+
<span className="px-2">/</span>
|
|
31
|
+
</span>
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return <nav className="flex items-center">{breadcrumbsMarkup}</nav>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {forwardRef} from 'react';
|
|
2
|
+
import {Link} from '@remix-run/react';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
|
|
5
|
+
import {missingClass} from '~/lib/utils';
|
|
6
|
+
|
|
7
|
+
export const Button = forwardRef(
|
|
8
|
+
(
|
|
9
|
+
{
|
|
10
|
+
as = 'button',
|
|
11
|
+
className = '',
|
|
12
|
+
variant = 'primary',
|
|
13
|
+
width = 'auto',
|
|
14
|
+
...props
|
|
15
|
+
}: {
|
|
16
|
+
as?: React.ElementType;
|
|
17
|
+
className?: string;
|
|
18
|
+
variant?: 'primary' | 'secondary' | 'inline';
|
|
19
|
+
width?: 'auto' | 'full';
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
},
|
|
22
|
+
ref,
|
|
23
|
+
) => {
|
|
24
|
+
const Component = props?.to ? Link : as;
|
|
25
|
+
|
|
26
|
+
const baseButtonClasses =
|
|
27
|
+
'inline-block rounded font-medium text-center py-3 px-6';
|
|
28
|
+
|
|
29
|
+
const variants = {
|
|
30
|
+
primary: `${baseButtonClasses} bg-primary text-contrast`,
|
|
31
|
+
secondary: `${baseButtonClasses} border border-primary/10 bg-contrast text-primary`,
|
|
32
|
+
inline: 'border-b border-primary/10 leading-none pb-1',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const widths = {
|
|
36
|
+
auto: 'w-auto',
|
|
37
|
+
full: 'w-full',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const styles = clsx(
|
|
41
|
+
missingClass(className, 'bg-') && variants[variant],
|
|
42
|
+
missingClass(className, 'w-') && widths[width],
|
|
43
|
+
className,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Component
|
|
48
|
+
// @todo: not supported until react-router makes it into Remix.
|
|
49
|
+
// preventScrollReset={true}
|
|
50
|
+
className={styles}
|
|
51
|
+
{...props}
|
|
52
|
+
ref={ref}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
);
|