diff --git a/packages/docs/.npmrc b/packages/docs/.npmrc new file mode 100644 index 00000000..a6a66558 --- /dev/null +++ b/packages/docs/.npmrc @@ -0,0 +1 @@ +use-node-version=20.19.0 \ No newline at end of file diff --git a/packages/docs/.storybook/addon-container/Tool.tsx b/packages/docs/.storybook/addon-container/Tool.tsx new file mode 100644 index 00000000..0464a75f --- /dev/null +++ b/packages/docs/.storybook/addon-container/Tool.tsx @@ -0,0 +1,41 @@ +import { BoxIcon } from "@storybook/icons" +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React, { useCallback, useEffect } from "react" +import { IconButton } from "storybook/internal/components" +import { useGlobals, useStorybookApi } from "storybook/manager-api" +import { ADDON_ID, ADDON_NAME, PARAM_KEY, TOOL_ID } from "./constants" + +export const Tool = () => { + const [globals, updateGlobals] = useGlobals() + const active = globals[PARAM_KEY] === true || globals[PARAM_KEY] === "true" + const api = useStorybookApi() + + const toggleContainer = useCallback( + () => + updateGlobals({ + [PARAM_KEY]: !active, + }), + [updateGlobals, active], + ) + + useEffect(() => { + api.setAddonShortcut(ADDON_ID, { + label: "Toggle Container [C]", + defaultShortcut: ["C"], + actionName: "container", + showInMenu: false, + action: toggleContainer, + }) + }, [toggleContainer, api]) + + return ( + + + + ) +} diff --git a/packages/docs/.storybook/addon-container/constants.ts b/packages/docs/.storybook/addon-container/constants.ts new file mode 100644 index 00000000..45fbc03d --- /dev/null +++ b/packages/docs/.storybook/addon-container/constants.ts @@ -0,0 +1,4 @@ +export const ADDON_ID = "addon-container" +export const ADDON_NAME = "Enable " +export const TOOL_ID = `${ADDON_ID}/tool` +export const PARAM_KEY = "containerEnabled" diff --git a/packages/docs/.storybook/addon-container/manager.tsx b/packages/docs/.storybook/addon-container/manager.tsx new file mode 100644 index 00000000..f7f30702 --- /dev/null +++ b/packages/docs/.storybook/addon-container/manager.tsx @@ -0,0 +1,14 @@ +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React from "react" +import { addons, types } from "storybook/manager-api" +import { ADDON_ID, ADDON_NAME } from "./constants" +import { Tool } from "./Tool" + +addons.register(ADDON_ID, () => { + addons.add(ADDON_ID, { + title: ADDON_NAME, + type: types.TOOL, + match: ({ viewMode }) => !!viewMode?.match(/^(story|docs)$/), + render: () => , + }) +}) diff --git a/packages/docs/.storybook/addon-gh-repository/Tool.tsx b/packages/docs/.storybook/addon-gh-repository/Tool.tsx index 25f4aa10..267e34fd 100644 --- a/packages/docs/.storybook/addon-gh-repository/Tool.tsx +++ b/packages/docs/.storybook/addon-gh-repository/Tool.tsx @@ -1,14 +1,16 @@ -import { A, IconButton, Icons, Separator } from '@storybook/components' -import React from 'react' -import { ADDON_NAME, REPOSITORY_URL, TOOL_ID } from './constants' +import { GithubIcon } from "@storybook/icons" +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React from "react" +import { A, IconButton, Separator } from "storybook/internal/components" +import { ADDON_NAME, REPOSITORY_URL, TOOL_ID } from "./constants" export const Tool = () => { return ( <> - - + +   repository diff --git a/packages/docs/.storybook/addon-gh-repository/manager.tsx b/packages/docs/.storybook/addon-gh-repository/manager.tsx index a354e49b..f7f30702 100644 --- a/packages/docs/.storybook/addon-gh-repository/manager.tsx +++ b/packages/docs/.storybook/addon-gh-repository/manager.tsx @@ -1,13 +1,14 @@ -import { addons, types } from '@storybook/addons' -import React from 'react' -import { Tool } from './Tool' -import { ADDON_ID, ADDON_NAME } from './constants' +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React from "react" +import { addons, types } from "storybook/manager-api" +import { ADDON_ID, ADDON_NAME } from "./constants" +import { Tool } from "./Tool" addons.register(ADDON_ID, () => { addons.add(ADDON_ID, { title: ADDON_NAME, type: types.TOOL, - match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), + match: ({ viewMode }) => !!viewMode?.match(/^(story|docs)$/), render: () => , }) }) diff --git a/packages/docs/.storybook/addon-version/Tool.tsx b/packages/docs/.storybook/addon-version/Tool.tsx new file mode 100644 index 00000000..8b061087 --- /dev/null +++ b/packages/docs/.storybook/addon-version/Tool.tsx @@ -0,0 +1,22 @@ +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React from "react" +import { IconButton, Separator } from "storybook/internal/components" +import { ADDON_NAME, LINK_URL, TOOL_ID, VERSION } from "./constants" + +export const Tool = () => { + return ( + <> + + { + window.open(LINK_URL, "_blank") + }} + > + v{VERSION} + + + ) +} diff --git a/packages/docs/.storybook/addon-version/constants.ts b/packages/docs/.storybook/addon-version/constants.ts new file mode 100644 index 00000000..4981d650 --- /dev/null +++ b/packages/docs/.storybook/addon-version/constants.ts @@ -0,0 +1,8 @@ +export const ADDON_ID = "addon-version" +export const ADDON_NAME = "Latest version" +export const TOOL_ID = `${ADDON_ID}/tool` +export const LINK_URL = "https://github.com/commercelayer/app-elements/releases" + +import lernaJson from "../../../../lerna.json" with { type: "json" } + +export const VERSION = lernaJson.version diff --git a/packages/docs/.storybook/addon-version/manager.tsx b/packages/docs/.storybook/addon-version/manager.tsx new file mode 100644 index 00000000..f7f30702 --- /dev/null +++ b/packages/docs/.storybook/addon-version/manager.tsx @@ -0,0 +1,14 @@ +// biome-ignore lint/correctness/noUnusedImports: React is used in the render method +import React from "react" +import { addons, types } from "storybook/manager-api" +import { ADDON_ID, ADDON_NAME } from "./constants" +import { Tool } from "./Tool" + +addons.register(ADDON_ID, () => { + addons.add(ADDON_ID, { + title: ADDON_NAME, + type: types.TOOL, + match: ({ viewMode }) => !!viewMode?.match(/^(story|docs)$/), + render: () => , + }) +}) diff --git a/packages/docs/.storybook/commercelayer.theme.ts b/packages/docs/.storybook/commercelayer.theme.ts index 1b06740a..f7ceed75 100644 --- a/packages/docs/.storybook/commercelayer.theme.ts +++ b/packages/docs/.storybook/commercelayer.theme.ts @@ -1,4 +1,4 @@ -import { create } from '@storybook/theming' +import { create } from 'storybook/theming' export default create({ base: 'light', diff --git a/packages/docs/.storybook/main.ts b/packages/docs/.storybook/main.ts index 9c1cdee5..0fc2b89f 100644 --- a/packages/docs/.storybook/main.ts +++ b/packages/docs/.storybook/main.ts @@ -1,5 +1,6 @@ -import { type StorybookConfig } from '@storybook/react-vite' -import { resolve } from 'path' +import { dirname, join, resolve } from "node:path" +import type { StorybookConfig } from '@storybook/react-vite' +import remarkGfm from "remark-gfm" import { mergeConfig, type UserConfig } from 'vite' import tsconfigPaths from 'vite-tsconfig-paths' @@ -19,27 +20,39 @@ const storybookConfig: StorybookConfig = { async viteFinal(config) { return mergeConfig(config, viteOverrides) }, - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'], + staticDirs: ["../public"], + stories: [ + '../stories/**/*.mdx', + '../stories/**/*.stories.@(js|jsx|ts|tsx)' + ], addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-interactions', - '@storybook/addon-mdx-gfm' + getAbsolutePath("@storybook/addon-links"), + { + name: getAbsolutePath("@storybook/addon-docs"), + options: { + mdxPluginOptions: { + mdxCompileOptions: { + remarkPlugins: [remarkGfm], + }, + }, + }, + }, + getAbsolutePath("@storybook/addon-styling-webpack"), ], // @ts-expect-error This 'managerEntries' exists. - managerEntries: [require.resolve('./addon-gh-repository/manager.tsx')], + managerEntries: [ + require.resolve("./addon-container/manager.tsx"), + require.resolve("./addon-version/manager.tsx"), + require.resolve("./addon-gh-repository/manager.tsx"), + ], framework: { - name: '@storybook/react-vite', + name: getAbsolutePath("@storybook/react-vite"), options: {} }, core: { disableTelemetry: true }, - features: { - storyStoreV7: true - }, docs: { - autodocs: true, docsMode: true }, typescript: { @@ -63,4 +76,8 @@ const storybookConfig: StorybookConfig = { } } -module.exports = storybookConfig +export default storybookConfig + +function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, "package.json"))) +} \ No newline at end of file diff --git a/packages/docs/.storybook/manager-head.html b/packages/docs/.storybook/manager-head.html index ece446c3..3c5af570 100644 --- a/packages/docs/.storybook/manager-head.html +++ b/packages/docs/.storybook/manager-head.html @@ -1,3 +1,3 @@ - + diff --git a/packages/docs/.storybook/manager.ts b/packages/docs/.storybook/manager.ts index 0cf7ecaa..e1c8afc5 100644 --- a/packages/docs/.storybook/manager.ts +++ b/packages/docs/.storybook/manager.ts @@ -1,4 +1,4 @@ -import { addons } from '@storybook/manager-api' +import { addons } from 'storybook/manager-api' import commercelayerTheme from './commercelayer.theme' addons.setConfig({ diff --git a/packages/docs/.storybook/preview-head.html b/packages/docs/.storybook/preview-head.html index 02113d82..58bc401b 100644 --- a/packages/docs/.storybook/preview-head.html +++ b/packages/docs/.storybook/preview-head.html @@ -3,8 +3,11 @@ href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" /> + - diff --git a/packages/docs/.storybook/preview.tsx b/packages/docs/.storybook/preview.tsx index a1fc5851..797d8c7b 100644 --- a/packages/docs/.storybook/preview.tsx +++ b/packages/docs/.storybook/preview.tsx @@ -1,59 +1,67 @@ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// -import type { Parameters, Preview } from '@storybook/react' -import { worker } from '../mocks/browser' +import { PARAM_KEY } from ".storybook/addon-container/constants" import { Controls, Description, Primary, Stories, Subtitle, - Title -} from '@storybook/addon-docs' + Title, +} from "@storybook/addon-docs/blocks" +import type { Parameters } from "@storybook/react-vite" +import { worker } from "../mocks/browser" -const parameters: Parameters = { - actions: { argTypesRegex: '^on[A-Z].*' }, - layout: 'padded', +export const parameters: Parameters = { + layout: "centered", controls: { matchers: { color: /(background|color)$/i, - date: /Date$/ - } + date: /Date$/, + }, + }, + backgrounds: { + values: [ + { + name: "overlay", + value: "#F8F8F8", + }, + ], }, options: { storySort: { order: [ - 'Getting Started', - 'Components', + "Getting Started", + "Components", [ - 'Skus', - ['SkusContainer', 'Skus'], - 'Prices', - ['PricesContainer'], - 'Availability', - ['AvailabilityContainer'], - 'Orders', - ['OrderStorage', 'OrderContainer'], - 'Cart', - ['AddToCartButton', 'HostedCart', 'CartLink', 'MiniCart'], - 'Customers', + "Skus", + ["SkusContainer", "Skus"], + "Prices", + ["PricesContainer"], + "Availability", + ["AvailabilityContainer"], + "Orders", + ["OrderStorage", "OrderContainer"], + "Cart", + ["AddToCartButton", "HostedCart", "CartLink", "MiniCart"], + "Customers", [ - 'CustomerContainer', - 'CustomerField', - 'AddressesContainer', - 'AddressesEmpty', - 'Address', - 'AddressField', - 'BillingAddressForm', - 'MyAccountLink' - ] + "CustomerContainer", + "CustomerField", + "AddressesContainer", + "AddressesEmpty", + "Address", + "AddressField", + "BillingAddressForm", + "MyAccountLink", + ], ], - 'Examples', - ['Listing Page', 'Shopping Cart', 'Checkout Page', 'My Account'], - 'Hooks' - ] - } + "Examples", + ["Listing Page", "Shopping Cart", "Checkout Page", "My Account"], + "Hooks", + ], + }, }, docs: { page: () => ( @@ -65,49 +73,34 @@ const parameters: Parameters = { - ) - } + ), + }, } // Storybook executes this module in both bootstrap phase (Node) // and a story's runtime (browser). However, we cannot call `setupWorker` // in Node environment, so need to check if we're in a browser. -if (typeof global.process === 'undefined') { +if (typeof global.process === "undefined") { // Start the mocking when each story is loaded. // Repetitive calls to the `.start()` method do not register a new worker, // but check whether there's an existing once, reusing it, if so. worker.start({ serviceWorker: { - url: `${import.meta.env.BASE_URL}mockServiceWorker.js` + url: `${import.meta.env.BASE_URL}mockServiceWorker.js`, }, quiet: import.meta.env.PROD, onUnhandledRequest: !import.meta.env.PROD ? (req, reqPrint) => { - if (req.url.hostname === 'mock.localhost') { - reqPrint.warning() - } + const url = new URL(req.url) + if (url.hostname === "mock.localhost") { + reqPrint.warning() } - : () => {} + } + : () => { }, }) } -const argTypesEnhancers: Preview['argTypesEnhancers'] = [ - (context) => { - // when the className prop comes from `JSX.IntrinsicElements['div' | 'span']` - // and is not documented, we add a default description - if ( - 'className' in context.argTypes && - context.argTypes.className.description === '' - ) { - context.argTypes.className.description = - 'CSS class name for the base component' - } - - return context.argTypes - } -] - -export default { - parameters, - argTypesEnhancers +export const initialGlobals = { + [PARAM_KEY]: true, } +export const tags = ["autodocs"] diff --git a/packages/docs/package.json b/packages/docs/package.json index f73e780e..22c255fc 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -8,26 +8,12 @@ "@commercelayer/js-auth": "^6.7.1", "@commercelayer/sdk": "^6.32.0", "@mdx-js/react": "^3.1.0", - "@storybook/addon-actions": "^7.6.17", - "@storybook/addon-backgrounds": "^7.6.17", - "@storybook/addon-docs": "^7.6.17", - "@storybook/addon-essentials": "^7.6.17", - "@storybook/addon-interactions": "^7.6.17", - "@storybook/addon-links": "^7.6.17", - "@storybook/addon-mdx-gfm": "^7.6.17", - "@storybook/addon-measure": "^7.6.17", - "@storybook/addon-outline": "^7.6.17", - "@storybook/addons": "^7.6.17", - "@storybook/api": "^7.6.17", - "@storybook/blocks": "^7.6.17", - "@storybook/client-api": "^7.6.17", - "@storybook/client-logger": "^7.6.17", - "@storybook/manager-api": "^7.6.17", - "@storybook/node-logger": "^8.4.2", - "@storybook/react": "^7.6.17", - "@storybook/react-vite": "^7.6.17", - "@storybook/testing-library": "^0.2.2", - "@storybook/theming": "^7.6.17", + "@storybook/addon-docs": "^9.1.6", + "@storybook/addon-links": "^9.1.6", + "@storybook/addon-styling-webpack": "^2.0.0", + "@storybook/cli": "^9.1.6", + "@storybook/icons": "^1.6.0", + "@storybook/react-vite": "^9.1.6", "@types/js-cookie": "^3.0.6", "@types/react": "^18.3.3", "@vitejs/plugin-react": "^4.3.4", @@ -38,7 +24,8 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "storybook": "^8.0.0", + "remark-gfm": "^4.0.1", + "storybook": "^9.1.6", "type-fest": "^4.35.0", "typescript": "^5.7.3", "vite": "^6.1.0", @@ -47,8 +34,8 @@ "scripts": { "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", - "storybook": "storybook dev -s ./public -p 6006", - "build-storybook": "storybook build -s public -o dist" + "storybook": "NODE_OPTIONS='--openssl-legacy-provider' storybook dev -p 6006", + "build-storybook": "NODE_OPTIONS='--openssl-legacy-provider' storybook build -o dist" }, "repository": { "type": "git", diff --git a/packages/docs/public/storybook-preview.css b/packages/docs/public/storybook-preview.css index 3d591793..35f47534 100644 --- a/packages/docs/public/storybook-preview.css +++ b/packages/docs/public/storybook-preview.css @@ -20,19 +20,44 @@ span[type]::before { span[type] > p { margin: 0; } -span[type='info'] { +span[type="info"] { border-color: #3b82f6; background-color: #dbebfe; } -span[type='warning'] { +span[type="warning"] { border-color: #f97317; background-color: #ffedd5; } -span[type='success'] { +span[type="success"] { border-color: #22c55f; background-color: #ddfce7; } -span[type='danger'] { +span[type="danger"] { border-color: #ef4544; background-color: #fee2e3; } + +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; + max-width: 600px; +} +.embed-responsive::before { + padding-top: 56.25%; +} +.embed-responsive::before { + display: block; + content: ""; +} +.embed-responsive iframe { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} diff --git a/packages/docs/stories/_internals/useGetToken.ts b/packages/docs/stories/_internals/useGetToken.ts index 966dd14f..9dd8472e 100644 --- a/packages/docs/stories/_internals/useGetToken.ts +++ b/packages/docs/stories/_internals/useGetToken.ts @@ -1,20 +1,20 @@ -import { authenticate } from '@commercelayer/js-auth' -import { useEffect, useMemo, useState } from 'react' -import Cookie from 'js-cookie' -import { jwtDecode } from 'jwt-decode' +import { authenticate } from "@commercelayer/js-auth" +import Cookie from "js-cookie" +import { jwtDecode } from "jwt-decode" +import { useEffect, useMemo, useState } from "react" const salesChannel = { - clientId: 'Z5ypiDlsqgV8twWRz0GabrJvTKXad4U-PMoVAU-XvV0', - slug: 'react-components-store', - scope: 'market:15283', - domain: 'commercelayer.io' + clientId: "Z5ypiDlsqgV8twWRz0GabrJvTKXad4U-PMoVAU-XvV0", + slug: "react-components-store", + scope: "market:id:DomJOhYmGj", + domain: "commercelayer.io", } const savedCustomerWithOrders = { - username: 'bruce@wayne.com', - password: '123456' + username: "bruce@wayne.com", + password: "123456", } -type UserMode = 'customer' | 'customer-orders' | 'guest' +type UserMode = "customer" | "customer-orders" | "guest" interface UseGetTokenOptions { mode?: UserMode } @@ -26,14 +26,14 @@ const getCustomerLoginCookieName = (mode: UserMode): string => `clToken.customerLogin.${mode}` export function useGetToken( - options?: T + options?: T, ): { accessToken: string endpoint: string } { - const mode = options?.mode ?? 'guest' + const mode = options?.mode ?? "guest" const [accessToken, setAccessToken] = useState( - Cookie.get(getAccessTokenCookieName(mode)) ?? '' + Cookie.get(getAccessTokenCookieName(mode)) ?? "", ) const clientId = salesChannel.clientId const slug = salesChannel.slug @@ -43,15 +43,15 @@ export function useGetToken( const initToken = useMemo(() => { return async () => { const user = - mode === 'customer' + mode === "customer" ? await retrieveCustomerData({ clientId, slug, scope, domain, - mode + mode, }) - : mode === 'customer-orders' + : mode === "customer-orders" ? savedCustomerWithOrders : undefined @@ -61,27 +61,27 @@ export function useGetToken( scope, domain, user, - mode + mode, }).then(({ accessToken, expires }) => { setAccessToken(accessToken) Cookie.set(getAccessTokenCookieName(mode), accessToken, { expires }) }) } - }, []) + }, [clientId, domain, mode, scope, slug]) useEffect(() => { if ( accessToken == null || - accessToken === '' || + accessToken === "" || isTokenExpired({ accessToken, compareTo: new Date() }) ) { initToken() } - }, [accessToken]) + }, [accessToken, initToken]) return { accessToken, - endpoint: `https://${slug}.${domain}` + endpoint: `https://${slug}.${domain}`, } } @@ -90,7 +90,7 @@ async function retrieveCustomerData({ slug, scope, domain, - mode + mode, }: { clientId: string slug: string @@ -102,18 +102,19 @@ async function retrieveCustomerData({ password: string }> { const existingUser = Cookie.get(getCustomerLoginCookieName(mode)) - const savedEmail = parseEmailAddress(existingUser?.split(':')[0]) - const savedPassword = parsePassword(existingUser?.split(':')[1]) + const savedEmail = parseEmailAddress(existingUser?.split(":")[0]) + const savedPassword = parsePassword(existingUser?.split(":")[1]) if (savedEmail != null && savedPassword != null) { return { - username: savedEmail, - password: savedPassword + // Here we force the username to lowercase to avoid issues with email case sensitivity during authentication + username: savedEmail.toLowerCase(), + password: savedPassword, } } const newEmail = `user-${generateRandomString(5)}-${generateRandomString( - 5 + 5, )}@domain.com` const newPassword = generateRandomString(10) @@ -122,7 +123,7 @@ async function retrieveCustomerData({ slug, scope, domain, - mode + mode, }) await createNewCustomer({ @@ -130,14 +131,14 @@ async function retrieveCustomerData({ password: newPassword, salesChannelToken: guestToken.accessToken, slug, - domain + domain, }) Cookie.set(getCustomerLoginCookieName(mode), `${newEmail}:${newPassword}`) return { username: newEmail, - password: newPassword + password: newPassword, } } @@ -148,7 +149,7 @@ async function generateNewToken({ scope, domain, user, - mode + mode, }: { clientId: string slug: string @@ -158,20 +159,20 @@ async function generateNewToken({ mode: UserMode }) { return user == null - ? await authenticate('client_credentials', { + ? await authenticate("client_credentials", { clientId, scope, - domain + domain, }) - : await authenticate('password', { + : await authenticate("password", { clientId, scope, domain, - ...user + ...user, }).then((res) => { - if (res != null && 'error' in res) { - Cookie.remove(getCustomerLoginCookieName('customer')) - Cookie.remove(getCustomerLoginCookieName('customer-orders')) + if (res != null && "error" in res) { + Cookie.remove(getCustomerLoginCookieName("customer")) + Cookie.remove(getCustomerLoginCookieName("customer-orders")) Cookie.remove(getAccessTokenCookieName(mode)) } return res @@ -180,12 +181,12 @@ async function generateNewToken({ function isTokenExpired({ accessToken, - compareTo + compareTo, }: { accessToken?: string compareTo: Date }): boolean { - if (accessToken == null || accessToken === '') { + if (accessToken == null || accessToken === "") { return true } @@ -204,8 +205,8 @@ function isTokenExpired({ } function generateRandomString(length = 10): string { - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' - let result = '' + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + let result = "" for (let i = 0; i < length; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)) } @@ -229,7 +230,7 @@ async function createNewCustomer({ password, salesChannelToken, slug, - domain + domain, }: { email: string password: string @@ -238,24 +239,24 @@ async function createNewCustomer({ domain: string }): Promise { const newCustomer = await fetch(`https://${slug}.${domain}/api/customers`, { - method: 'POST', + method: "POST", headers: { - Accept: 'application/vnd.api+json', - 'Content-Type': 'application/vnd.api+json', - Authorization: `Bearer ${salesChannelToken}` + Accept: "application/vnd.api+json", + "Content-Type": "application/vnd.api+json", + Authorization: `Bearer ${salesChannelToken}`, }, body: JSON.stringify({ data: { - type: 'customers', + type: "customers", attributes: { email, - password - } - } - }) + password, + }, + }, + }), }) if (newCustomer.status !== 201) { - throw new Error('Error creating customer') + throw new Error("Error creating customer") } } diff --git a/packages/docs/stories/availability/AvailabilityContainer.stories.tsx b/packages/docs/stories/availability/AvailabilityContainer.stories.tsx index 8b1897eb..50125790 100644 --- a/packages/docs/stories/availability/AvailabilityContainer.stories.tsx +++ b/packages/docs/stories/availability/AvailabilityContainer.stories.tsx @@ -1,10 +1,10 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import { AvailabilityContainer } from '#components/skus/AvailabilityContainer' +import type { Meta, StoryFn } from "@storybook/react-vite" +import { AvailabilityContainer } from "#components/skus/AvailabilityContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Availability/AvailabilityContainer', - component: AvailabilityContainer + title: "Components/Availability/AvailabilityContainer", + component: AvailabilityContainer, } export default setup @@ -12,8 +12,8 @@ export default setup const Template: StoryFn = (args) => { return ( ... @@ -22,15 +22,15 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - skuCode: 'POLOMXXX000000FFFFFFLXXX', + skuCode: "POLOMXXX000000FFFFFFLXXX", getQuantity: (quantity) => { - console.log('quantity', quantity) - } + console.log("quantity", quantity) + }, } Default.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } diff --git a/packages/docs/stories/availability/AvailabilityTemplate.stories.tsx b/packages/docs/stories/availability/AvailabilityTemplate.stories.tsx index bd5a9791..e6bb08dd 100644 --- a/packages/docs/stories/availability/AvailabilityTemplate.stories.tsx +++ b/packages/docs/stories/availability/AvailabilityTemplate.stories.tsx @@ -1,32 +1,32 @@ -import type { Meta, StoryFn, StoryObj } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import { AvailabilityTemplate } from '#components/skus/AvailabilityTemplate' -import { AvailabilityContainer } from '#components/skus/AvailabilityContainer' -import PricesContainer from '#components/prices/PricesContainer' +import type { Meta, StoryFn, StoryObj } from "@storybook/react-vite" +import PricesContainer from "#components/prices/PricesContainer" +import { AvailabilityContainer } from "#components/skus/AvailabilityContainer" +import { AvailabilityTemplate } from "#components/skus/AvailabilityTemplate" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Availability/AvailabilityTemplate', + title: "Components/Availability/AvailabilityTemplate", component: AvailabilityTemplate, argTypes: { showShippingMethodName: { - control: 'boolean' + control: "boolean", }, showShippingMethodPrice: { - control: 'boolean' + control: "boolean", }, timeFormat: { - control: 'radio', - options: ['days', 'hours', undefined] - } - } + control: "radio", + options: ["days", "hours", undefined], + }, + }, } export default setup const Template: StoryFn = (args) => { return ( - - + + @@ -35,9 +35,9 @@ const Template: StoryFn = (args) => { export const AvailableWithDeliveryTime = Template.bind({}) AvailableWithDeliveryTime.args = { - timeFormat: 'days', + timeFormat: "days", showShippingMethodName: true, - showShippingMethodPrice: true + showShippingMethodPrice: true, } /** @@ -46,8 +46,8 @@ AvailableWithDeliveryTime.args = { export const WithCustomLabel = Template.bind({}) WithCustomLabel.args = { labels: { - available: 'Item is available' - } + available: "Item is available", + }, } /** @@ -56,12 +56,12 @@ WithCustomLabel.args = { export const NotAvailable: StoryFn = (args) => { return ( - + @@ -80,20 +80,20 @@ export const NotAvailable: StoryFn = (args) => { export const ChildrenProps: StoryObj = () => { return ( - + {(childrenProps) => { return (
-

Custom logic:

-

- {childrenProps.quantity} items available delivered in{' '} +

Custom logic:

+

+ {childrenProps.quantity} items available delivered in{" "} {childrenProps.min?.hours} hours

-

The delivery_lead_times object

+

The delivery_lead_times object

{JSON.stringify(childrenProps, null, 2)}
) @@ -107,20 +107,20 @@ ChildrenProps.decorators = [ (Story) => { return ( ) - } + }, ] ChildrenProps.parameters = { docs: { source: { - type: 'code' - } - } + type: "code", + }, + }, } diff --git a/packages/docs/stories/cart/AddToCartButton.stories.tsx b/packages/docs/stories/cart/AddToCartButton.stories.tsx index 876bfae7..01505179 100644 --- a/packages/docs/stories/cart/AddToCartButton.stories.tsx +++ b/packages/docs/stories/cart/AddToCartButton.stories.tsx @@ -1,93 +1,94 @@ -import type { Meta, StoryFn, StoryObj } from "@storybook/react"; -import CommerceLayer from "../_internals/CommerceLayer"; -import OrderContainerComponent from "#components/orders/OrderContainer"; -import { AddToCartButton } from "#components/orders/AddToCartButton"; -import OrderStorage from "#components/orders/OrderStorage"; -import LineItemsContainer from "#components/line_items/LineItemsContainer"; -import Errors from "#components/errors/Errors"; -import LineItemName from "#components/line_items/LineItemName"; -import LineItem from "#components/line_items/LineItem"; -import LineItemQuantity from "#components/line_items/LineItemQuantity"; -import LineItemRemoveLink from "#components/line_items/LineItemRemoveLink"; -import LineItemsEmpty from "#components/line_items/LineItemsEmpty"; -import AvailabilityContainer from "#components/skus/AvailabilityContainer"; -import AvailabilityTemplate from "#components/skus/AvailabilityTemplate"; -import { SkusContainer } from "#components/skus/SkusContainer"; -import Skus from "#components/skus/Skus"; +import type { Meta, StoryFn, StoryObj } from "@storybook/react-vite" +import { useId } from "react" +import Errors from "#components/errors/Errors" +import LineItem from "#components/line_items/LineItem" +import LineItemName from "#components/line_items/LineItemName" +import LineItemQuantity from "#components/line_items/LineItemQuantity" +import LineItemRemoveLink from "#components/line_items/LineItemRemoveLink" +import LineItemsContainer from "#components/line_items/LineItemsContainer" +import LineItemsEmpty from "#components/line_items/LineItemsEmpty" +import { AddToCartButton } from "#components/orders/AddToCartButton" +import OrderContainerComponent from "#components/orders/OrderContainer" +import OrderStorage from "#components/orders/OrderStorage" +import AvailabilityContainer from "#components/skus/AvailabilityContainer" +import AvailabilityTemplate from "#components/skus/AvailabilityTemplate" +import Skus from "#components/skus/Skus" +import { SkusContainer } from "#components/skus/SkusContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: "Components/Cart/AddToCartButton", - component: AddToCartButton, -}; + title: "Components/Cart/AddToCartButton", + component: AddToCartButton, +} -export default setup; +export default setup const Template: StoryFn = (args) => { - return ( - - - - - - - - ); -}; + return ( + + + + + + + + ) +} -export const AddSku = Template.bind({}); +export const AddSku = Template.bind({}) AddSku.args = { - skuCode: "SWEATWCX000000FFFFFFXSXX", - label: "Add SKU to cart", - quantity: "2", - className: "px-3 py-2 bg-black text-white rounded disabled:opacity-50", -}; + skuCode: "SWEATWCX000000FFFFFFXSXX", + label: "Add SKU to cart", + quantity: "2", + className: "px-3 py-2 bg-black text-white rounded disabled:opacity-50", +} -export const AddBundle = Template.bind({}); +export const AddBundle = Template.bind({}) AddBundle.args = { - bundleCode: "BUNDLE001", - label: "Add bundle to cart", - quantity: "2", - className: "px-3 py-2 bg-black text-white rounded disabled:opacity-50", -}; + bundleCode: "BUNDLE001", + label: "Add bundle to cart", + quantity: "2", + className: "px-3 py-2 bg-black text-white rounded disabled:opacity-50", +} /** * You can combine components and contexts to render an `` within a `` context * and get available quantity from the `` to control the button disable state. */ export const DisabledWhenOutOfStock: StoryObj = () => { - return ( - - - - - - - - {(childrenProps) => { - return ( -
- Quantity available: {childrenProps.quantity} - -
- ); - }} -
-
-
-
-
-
-
- ); -}; + return ( + + + + + + + + {(childrenProps) => { + return ( +
+ Quantity available: {childrenProps.quantity} + +
+ ) + }} +
+
+
+
+
+
+
+ ) +} -DisabledWhenOutOfStock.args = {}; +DisabledWhenOutOfStock.args = {} /** * The add to cart button will automatically create a new `line_item` (or update an existing one), but it is also possible to @@ -100,25 +101,25 @@ DisabledWhenOutOfStock.args = {}; * */ export const UseCustomAttributesOrExternalPrice: StoryObj = () => { - return ( - - - - - - - - ); -}; -UseCustomAttributesOrExternalPrice.args = {}; + return ( + + + + + + + + ) +} +UseCustomAttributesOrExternalPrice.args = {} /** * You can access the component children props to customize the button or use a different tag. @@ -127,68 +128,70 @@ UseCustomAttributesOrExternalPrice.args = {}; * and show an alert with the `orderId` when the operation is successful. */ export const ChildrenProps: StoryObj = () => { - return ( - - {(childrenProps) => { - return ( -
{ - childrenProps.handleClick().then(({ orderId, success }) => { - if (success) { - alert(`item added to cart with orderId ${orderId}`); - } - }); - }} - > - Add to cart -
- ); - }} -
- ); -}; + return ( + + {(childrenProps) => { + return ( + + ) + }} + + ) +} ChildrenProps.decorators = [ - (Story) => { - return ( - - - - - - - - ); - }, -]; + (Story) => { + return ( + + + + + + + + ) + }, +] // Fake OrderContainer to show a cart recap block but keep it hidden in the documentation source code const OrderContainer: React.FC<{ children: React.ReactNode }> = ({ - children, + children, }) => { - return ( - - <>{children} + const cartRecapId = useId() -
- - -
- {(["skus", "bundles"] as const).map((type) => ( - -
-
- - - -
- - ))} -
- - -
- - ); -}; + return ( + + <>{children} + +
+ + +
+ {(["skus", "bundles"] as const).map((type) => ( + +
+
+ + + +
+ + ))} +
+ + +
+ + ) +} diff --git a/packages/docs/stories/cart/CartLink.stories.tsx b/packages/docs/stories/cart/CartLink.stories.tsx index ab2a9e0e..7dfa307c 100644 --- a/packages/docs/stories/cart/CartLink.stories.tsx +++ b/packages/docs/stories/cart/CartLink.stories.tsx @@ -1,19 +1,19 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import CartLink from '#components/orders/CartLink' +import type { Meta, StoryFn } from "@storybook/react-vite" +import CartLink from "#components/orders/CartLink" +import OrderContainer from "#components/orders/OrderContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Cart/CartLink', - component: CartLink + title: "Components/Cart/CartLink", + component: CartLink, } export default setup const Template: StoryFn = (args) => { return ( - - + + @@ -22,8 +22,8 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - label: 'Go to cart', - target: '_blank', - onClick: () => {}, - className: 'text-blue-500 hover:underline' + label: "Go to cart", + target: "_blank", + onClick: () => { }, + className: "text-blue-500 hover:underline", } diff --git a/packages/docs/stories/cart/HostedCart.stories.tsx b/packages/docs/stories/cart/HostedCart.stories.tsx index c946fb71..070d0a75 100644 --- a/packages/docs/stories/cart/HostedCart.stories.tsx +++ b/packages/docs/stories/cart/HostedCart.stories.tsx @@ -1,14 +1,14 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import { HostedCart } from '#components/orders/HostedCart' -import { OrderStorage, AddSampleItems } from '../_internals/OrderStorage' -import LineItemsEmpty from '#components/line_items/LineItemsEmpty' -import LineItemsContainer from '#components/line_items/LineItemsContainer' +import type { Meta, StoryFn } from "@storybook/react-vite" +import LineItemsContainer from "#components/line_items/LineItemsContainer" +import LineItemsEmpty from "#components/line_items/LineItemsEmpty" +import { HostedCart } from "#components/orders/HostedCart" +import OrderContainer from "#components/orders/OrderContainer" +import CommerceLayer from "../_internals/CommerceLayer" +import { AddSampleItems, OrderStorage } from "../_internals/OrderStorage" const setup: Meta = { - title: 'Components/Cart/HostedCart', - component: HostedCart + title: "Components/Cart/HostedCart", + component: HostedCart, } export default setup @@ -23,17 +23,17 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - type: undefined + type: undefined, } Default.decorators = [ (Story) => { return ( - + @@ -49,5 +49,5 @@ Default.decorators = [ ) - } + }, ] diff --git a/packages/docs/stories/cart/MiniCart.mdx b/packages/docs/stories/cart/MiniCart.mdx index 96d5d1ba..7ac3d44a 100644 --- a/packages/docs/stories/cart/MiniCart.mdx +++ b/packages/docs/stories/cart/MiniCart.mdx @@ -1,4 +1,4 @@ -import { Meta, Source, Canvas } from '@storybook/addon-docs'; +import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks'; import * as Stories from './MiniCart.stories.tsx' diff --git a/packages/docs/stories/cart/MiniCart.stories.tsx b/packages/docs/stories/cart/MiniCart.stories.tsx index e446023e..0ba2d36a 100644 --- a/packages/docs/stories/cart/MiniCart.stories.tsx +++ b/packages/docs/stories/cart/MiniCart.stories.tsx @@ -1,14 +1,14 @@ -import type { Meta, StoryFn, Decorator } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import CartLink from '#components/orders/CartLink' -import { HostedCart } from '#components/orders/HostedCart' -import { OrderStorage } from '../_internals/OrderStorage' -import LineItemsContainer from '#components/line_items/LineItemsContainer' -import LineItemsCount from '#components/line_items/LineItemsCount' +import type { Decorator, Meta, StoryFn } from "@storybook/react-vite" +import LineItemsContainer from "#components/line_items/LineItemsContainer" +import LineItemsCount from "#components/line_items/LineItemsCount" +import CartLink from "#components/orders/CartLink" +import { HostedCart } from "#components/orders/HostedCart" +import OrderContainer from "#components/orders/OrderContainer" +import CommerceLayer from "../_internals/CommerceLayer" +import { OrderStorage } from "../_internals/OrderStorage" const setup: Meta = { - title: 'Components/Cart/Mini Cart' + title: "Components/Cart/Mini Cart", } export default setup @@ -16,13 +16,13 @@ export default setup const CartDecorator: Decorator = (Story) => { return ( - +
{/* we need more space on the canvas to open the mini cart */} @@ -37,18 +37,18 @@ export const Basic: StoryFn = (arg) => { return ( ) @@ -58,18 +58,18 @@ Basic.decorators = [CartDecorator] export const CartIcon: StoryFn = (args) => { return ( -
+
- + - +
) @@ -78,44 +78,44 @@ CartIcon.parameters = {} CartIcon.decorators = [ (Story) => ( - + - ) + ), ] const MyCartIcon = (): JSX.Element => ( -
+
- + - +
) -MyCartIcon.DisplayName = 'MyCartIcon' +MyCartIcon.DisplayName = "MyCartIcon" -const cartOverlayStyle = { container: { backgroundColor: 'white' } } +const cartOverlayStyle = { container: { backgroundColor: "white" } } export const WithCartIcon: StoryFn = () => ( - + } - type='mini' - className='underline hover:text-blue-500' + type="mini" + className="underline hover:text-blue-500" /> ) @@ -124,7 +124,7 @@ WithCartIcon.decorators = [CartDecorator] WithCartIcon.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } diff --git a/packages/docs/stories/customers/Address.stories.tsx b/packages/docs/stories/customers/Address.stories.tsx index 3065b090..004a93a0 100644 --- a/packages/docs/stories/customers/Address.stories.tsx +++ b/packages/docs/stories/customers/Address.stories.tsx @@ -1,44 +1,44 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import CustomerContainer from '#components/customers/CustomerContainer' -import AddressesContainer from '#components/addresses/AddressesContainer' -import { AddressesEmpty } from '#components/addresses/AddressesEmpty' -import { Address } from '#components/addresses/Address' -import { AddressField } from '#components/addresses/AddressField' +import type { Meta, StoryFn } from "@storybook/react-vite" +import { Address } from "#components/addresses/Address" +import AddressesContainer from "#components/addresses/AddressesContainer" +import { AddressesEmpty } from "#components/addresses/AddressesEmpty" +import { AddressField } from "#components/addresses/AddressField" +import CustomerContainer from "#components/customers/CustomerContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/Address', - component: Address + title: "Components/Customers/Address", + component: Address, } export default setup const Template: StoryFn = () => { return ( - + -

Customer Addresses

- +

Customer Addresses

+
{ - alert('select') + alert("select") }} > -
+
First Name - +
Last Name - +
Address - +
@@ -53,10 +53,10 @@ Default.args = {} Default.parameters = { docs: { canvas: { - sourceState: 'shown' + sourceState: "shown", }, source: { - type: 'code' - } - } + type: "code", + }, + }, } diff --git a/packages/docs/stories/customers/AddressField.stories.tsx b/packages/docs/stories/customers/AddressField.stories.tsx index 115f0cd3..918f8fe7 100644 --- a/packages/docs/stories/customers/AddressField.stories.tsx +++ b/packages/docs/stories/customers/AddressField.stories.tsx @@ -1,40 +1,40 @@ -import { type Meta, type StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import { AddressesContainer } from '#components/addresses/AddressesContainer' -import { Address } from '#components/addresses/Address' -import { AddressField } from '#components/addresses/AddressField' -import CustomerContainer from '#components/customers/CustomerContainer' -import AddressesEmpty from '#components/addresses/AddressesEmpty' +import type { Meta, StoryFn } from "@storybook/react-vite" +import { Address } from "#components/addresses/Address" +import { AddressesContainer } from "#components/addresses/AddressesContainer" +import AddressesEmpty from "#components/addresses/AddressesEmpty" +import { AddressField } from "#components/addresses/AddressField" +import CustomerContainer from "#components/customers/CustomerContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/AddressField', + title: "Components/Customers/AddressField", component: AddressField, argTypes: { name: { - control: 'select', + control: "select", options: [ - 'first_name', - 'last_name', - 'full_name', - 'full_address', - 'email', - 'phone', - 'line_1' + "first_name", + "last_name", + "full_name", + "full_address", + "email", + "phone", + "line_1", ], - description: 'Resource attribute to be displayed.' + description: "Resource attribute to be displayed.", }, type: { - control: 'select', - options: ['field', 'edit', 'delete'], + control: "select", + options: ["field", "edit", "delete"], description: - 'Behavior requested for current `AddressField`. It could be `field` to show an attribute of an `address` or either `Edit` or `Delete` to generate an action button to interact with current `address`.' + "Behavior requested for current `AddressField`. It could be `field` to show an attribute of an `address` or either `Edit` or `Delete` to generate an action button to interact with current `address`.", }, label: { - control: 'text', + control: "text", description: - 'Label to be displayed in case of `field` is set to either `edit` or `delete`.' - } - } + "Label to be displayed in case of `field` is set to either `edit` or `delete`.", + }, + }, } export default setup @@ -45,18 +45,18 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - name: 'first_name', - type: 'field' + name: "first_name", + type: "field", } Default.decorators = [ (Story) => ( - +
@@ -64,5 +64,5 @@ Default.decorators = [ - ) + ), ] diff --git a/packages/docs/stories/customers/AddressesContainer.stories.tsx b/packages/docs/stories/customers/AddressesContainer.stories.tsx index 5c57e1b8..78b554a5 100644 --- a/packages/docs/stories/customers/AddressesContainer.stories.tsx +++ b/packages/docs/stories/customers/AddressesContainer.stories.tsx @@ -1,24 +1,24 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import CustomerContainer from '#components/customers/CustomerContainer' -import AddressesContainer from '#components/addresses/AddressesContainer' -import { AddressesEmpty } from '#components/addresses/AddressesEmpty' -import { Address as AddressComponent } from '#components/addresses/Address' -import { AddressField } from '#components/addresses/AddressField' +import type { Meta, StoryFn } from "@storybook/react-vite" +import { Address as AddressComponent } from "#components/addresses/Address" +import AddressesContainer from "#components/addresses/AddressesContainer" +import { AddressesEmpty } from "#components/addresses/AddressesEmpty" +import { AddressField } from "#components/addresses/AddressField" +import CustomerContainer from "#components/customers/CustomerContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/AddressesContainer', - component: AddressesContainer + title: "Components/Customers/AddressesContainer", + component: AddressesContainer, } export default setup const Template: StoryFn = (args) => { return ( - + - +
@@ -31,17 +31,17 @@ Default.args = {} Default.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } const Address: React.FC = () => { return ( -
- - +
+ +
) diff --git a/packages/docs/stories/customers/AddressesEmpty.stories.tsx b/packages/docs/stories/customers/AddressesEmpty.stories.tsx index 04ed138e..e5a921df 100644 --- a/packages/docs/stories/customers/AddressesEmpty.stories.tsx +++ b/packages/docs/stories/customers/AddressesEmpty.stories.tsx @@ -1,22 +1,22 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import CustomerContainer from '#components/customers/CustomerContainer' -import AddressesContainer from '#components/addresses/AddressesContainer' -import { AddressesEmpty } from '#components/addresses/AddressesEmpty' +import type { Meta, StoryFn } from "@storybook/react-vite" +import AddressesContainer from "#components/addresses/AddressesContainer" +import { AddressesEmpty } from "#components/addresses/AddressesEmpty" +import CustomerContainer from "#components/customers/CustomerContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/AddressesEmpty', - component: AddressesEmpty + title: "Components/Customers/AddressesEmpty", + component: AddressesEmpty, } export default setup const Template: StoryFn = (args) => { return ( - + - + @@ -28,7 +28,7 @@ Default.args = {} Default.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } diff --git a/packages/docs/stories/customers/BillingAddressForm.stories.tsx b/packages/docs/stories/customers/BillingAddressForm.stories.tsx index 69eb66e0..858f217f 100644 --- a/packages/docs/stories/customers/BillingAddressForm.stories.tsx +++ b/packages/docs/stories/customers/BillingAddressForm.stories.tsx @@ -1,25 +1,25 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import CustomerContainer from '#components/customers/CustomerContainer' -import AddressesContainer from '#components/addresses/AddressesContainer' -import { BillingAddressForm } from '#components/addresses/BillingAddressForm' +import type { Meta, StoryFn } from "@storybook/react-vite" +import AddressesContainer from "#components/addresses/AddressesContainer" +import { BillingAddressForm } from "#components/addresses/BillingAddressForm" +import CustomerContainer from "#components/customers/CustomerContainer" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/BillingAddressForm', - component: BillingAddressForm + title: "Components/Customers/BillingAddressForm", + component: BillingAddressForm, } export default setup const Template: StoryFn = () => { return ( - +
{/* Fields here... */} @@ -37,7 +37,7 @@ Default.args = {} Default.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } diff --git a/packages/docs/stories/customers/CustomerContainer.stories.tsx b/packages/docs/stories/customers/CustomerContainer.stories.tsx index b67f32bd..c5db3651 100644 --- a/packages/docs/stories/customers/CustomerContainer.stories.tsx +++ b/packages/docs/stories/customers/CustomerContainer.stories.tsx @@ -1,20 +1,20 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import CustomerContainer from '#components/customers/CustomerContainer' -import { CustomerField } from '#components/customers/CustomerField' +import type { Meta, StoryFn } from "@storybook/react-vite" +import CustomerContainer from "#components/customers/CustomerContainer" +import { CustomerField } from "#components/customers/CustomerField" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/CustomerContainer', - component: CustomerContainer + title: "Components/Customers/CustomerContainer", + component: CustomerContainer, } export default setup const Template: StoryFn = (args) => { return ( - + - + ) @@ -25,7 +25,7 @@ Default.args = {} Default.parameters = { docs: { canvas: { - sourceState: 'shown' - } - } + sourceState: "shown", + }, + }, } diff --git a/packages/docs/stories/customers/CustomerField.stories.tsx b/packages/docs/stories/customers/CustomerField.stories.tsx index e80d1d9a..da5ee505 100644 --- a/packages/docs/stories/customers/CustomerField.stories.tsx +++ b/packages/docs/stories/customers/CustomerField.stories.tsx @@ -1,24 +1,24 @@ -import { type Meta, type StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import { CustomerContainer } from '#components/customers/CustomerContainer' -import { CustomerField } from '#components/customers/CustomerField' +import type { Meta, StoryFn } from "@storybook/react-vite" +import { CustomerContainer } from "#components/customers/CustomerContainer" +import { CustomerField } from "#components/customers/CustomerField" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/CustomerField', + title: "Components/Customers/CustomerField", component: CustomerField, argTypes: { attribute: { - control: 'select', - options: ['email', 'status', 'total_orders_count'], - description: 'Resource attribute to display' + control: "select", + options: ["email", "status", "total_orders_count"], + description: "Resource attribute to display", }, tagElement: { - control: 'select', - options: ['div', 'p', 'span', 'section'], + control: "select", + options: ["div", "p", "span", "section"], description: - 'Resource attribute to displayHtml tag to render. When tag is `img` the value will be used to fill the `src` attribute.' - } - } + "Resource attribute to displayHtml tag to render. When tag is `img` the value will be used to fill the `src` attribute.", + }, + }, } export default setup @@ -29,16 +29,16 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - attribute: 'email', - tagElement: 'p' + attribute: "email", + tagElement: "p", } Default.decorators = [ (Story) => ( - + - ) + ), ] diff --git a/packages/docs/stories/customers/MyAccountLink.stories.tsx b/packages/docs/stories/customers/MyAccountLink.stories.tsx index cede187b..f2673acb 100644 --- a/packages/docs/stories/customers/MyAccountLink.stories.tsx +++ b/packages/docs/stories/customers/MyAccountLink.stories.tsx @@ -1,18 +1,18 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import MyAccountLink from '#components/customers/MyAccountLink' -import CustomerContainer from '#components/customers/CustomerContainer' +import type { Meta, StoryFn } from "@storybook/react-vite" +import CustomerContainer from "#components/customers/CustomerContainer" +import MyAccountLink from "#components/customers/MyAccountLink" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/MyAccountLink', - component: MyAccountLink + title: "Components/Customers/MyAccountLink", + component: MyAccountLink, } export default setup const Template: StoryFn = (args) => { return ( - + @@ -22,8 +22,8 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - label: 'Go to my-account', - target: '_blank', - onClick: () => {}, - className: 'text-blue-500 hover:underline' + label: "Go to my-account", + target: "_blank", + onClick: () => { }, + className: "text-blue-500 hover:underline", } diff --git a/packages/docs/stories/customers/MyIdentityLink.stories.tsx b/packages/docs/stories/customers/MyIdentityLink.stories.tsx index c5250860..bedc195d 100644 --- a/packages/docs/stories/customers/MyIdentityLink.stories.tsx +++ b/packages/docs/stories/customers/MyIdentityLink.stories.tsx @@ -1,17 +1,17 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../_internals/CommerceLayer' -import MyIdentityLink from '#components/customers/MyIdentityLink' -import { Code } from 'stories/_internals/Code' import { + Controls, Description, + Primary, Subtitle, Title, - Controls, - Primary -} from '@storybook/addon-docs' +} from "@storybook/addon-docs" +import type { Meta, StoryFn } from "@storybook/react-vite" +import { Code } from "stories/_internals/Code" +import MyIdentityLink from "#components/customers/MyIdentityLink" +import CommerceLayer from "../_internals/CommerceLayer" const setup: Meta = { - title: 'Components/Customers/MyIdentityLink', + title: "Components/Customers/MyIdentityLink", component: MyIdentityLink, parameters: { @@ -25,16 +25,16 @@ const setup: Meta = { - ) - } - } + ), + }, + }, } export default setup const Template: StoryFn = (args) => { return ( - + ) @@ -42,14 +42,14 @@ const Template: StoryFn = (args) => { export const Default = Template.bind({}) Default.args = { - label: 'Open my-identity app', - target: '_blank', - onClick: () => {}, - className: 'text-blue-500 hover:underline', - returnUrl: '', - clientId: '', - type: 'signup', - scope: '' + label: "Open my-identity app", + target: "_blank", + onClick: () => { }, + className: "text-blue-500 hover:underline", + returnUrl: "", + clientId: "", + type: "signup", + scope: "", } Default.decorators = [ @@ -59,14 +59,14 @@ Default.decorators = [
) - } + }, ] const Instructions = (): JSX.Element => ( -
+
{/* @ts-expect-error add a note of type `info` just for documenting the use case */} - - Fill the table of values below with a valid clientId,{' '} + + Fill the table of values below with a valid clientId,{" "} scope and returnUrl from your organization to see the link in action.

diff --git a/packages/docs/stories/examples/cart/000.intro.mdx b/packages/docs/stories/examples/cart/000.intro.mdx index 09e91c70..39ce88b1 100644 --- a/packages/docs/stories/examples/cart/000.intro.mdx +++ b/packages/docs/stories/examples/cart/000.intro.mdx @@ -1,4 +1,4 @@ -import { Meta, Source } from '@storybook/addon-docs'; +import { Meta, Source } from '@storybook/addon-docs/blocks'; diff --git a/packages/docs/stories/examples/cart/001.cart.mdx b/packages/docs/stories/examples/cart/001.cart.mdx index edb1e9db..938c1613 100644 --- a/packages/docs/stories/examples/cart/001.cart.mdx +++ b/packages/docs/stories/examples/cart/001.cart.mdx @@ -1,5 +1,5 @@ -import { Meta, Canvas } from '@storybook/addon-docs'; +import { Meta, Canvas } from '@storybook/addon-docs/blocks'; import * as Stories from './001.cart.stories.tsx' diff --git a/packages/docs/stories/examples/cart/001.cart.stories.tsx b/packages/docs/stories/examples/cart/001.cart.stories.tsx index 628bf3bd..5d93a05d 100644 --- a/packages/docs/stories/examples/cart/001.cart.stories.tsx +++ b/packages/docs/stories/examples/cart/001.cart.stories.tsx @@ -1,29 +1,29 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import LineItemsContainer from '#components/line_items/LineItemsContainer' -import LineItemsCount from '#components/line_items/LineItemsCount' -import LineItem from '#components/line_items/LineItem' -import LineItemName from '#components/line_items/LineItemName' -import LineItemRemoveLink from '#components/line_items/LineItemRemoveLink' -import LineItemImage from '#components/line_items/LineItemImage' -import LineItemQuantity from '#components/line_items/LineItemQuantity' -import Errors from '#components/errors/Errors' -import LineItemAmount from '#components/line_items/LineItemAmount' -import LineItemsEmpty from '#components/line_items/LineItemsEmpty' -import SubTotalAmount from '#components/orders/SubTotalAmount' -import DiscountAmount from '#components/orders/DiscountAmount' -import GiftCardAmount from '#components/orders/GiftCardAmount' -import TotalAmount from '#components/orders/TotalAmount' -import GiftCardOrCouponForm from '#components/gift_cards/GiftCardOrCouponForm' -import GiftCardOrCouponSubmit from '#components/gift_cards/GiftCardOrCouponSubmit' -import GiftCardOrCouponInput from '#components/gift_cards/GiftCardOrCouponInput' -import GiftCardOrCouponCode from '#components/gift_cards/GiftCardOrCouponCode' -import GiftCardOrCouponRemoveButton from '#components/gift_cards/GiftCardOrCouponRemoveButton' -import { OrderStorage, AddSampleItems } from '../../_internals/OrderStorage' +import type { Meta, StoryFn } from "@storybook/react-vite" +import Errors from "#components/errors/Errors" +import GiftCardOrCouponCode from "#components/gift_cards/GiftCardOrCouponCode" +import GiftCardOrCouponForm from "#components/gift_cards/GiftCardOrCouponForm" +import GiftCardOrCouponInput from "#components/gift_cards/GiftCardOrCouponInput" +import GiftCardOrCouponRemoveButton from "#components/gift_cards/GiftCardOrCouponRemoveButton" +import GiftCardOrCouponSubmit from "#components/gift_cards/GiftCardOrCouponSubmit" +import LineItem from "#components/line_items/LineItem" +import LineItemAmount from "#components/line_items/LineItemAmount" +import LineItemImage from "#components/line_items/LineItemImage" +import LineItemName from "#components/line_items/LineItemName" +import LineItemQuantity from "#components/line_items/LineItemQuantity" +import LineItemRemoveLink from "#components/line_items/LineItemRemoveLink" +import LineItemsContainer from "#components/line_items/LineItemsContainer" +import LineItemsCount from "#components/line_items/LineItemsCount" +import LineItemsEmpty from "#components/line_items/LineItemsEmpty" +import DiscountAmount from "#components/orders/DiscountAmount" +import GiftCardAmount from "#components/orders/GiftCardAmount" +import OrderContainer from "#components/orders/OrderContainer" +import SubTotalAmount from "#components/orders/SubTotalAmount" +import TotalAmount from "#components/orders/TotalAmount" +import CommerceLayer from "../../_internals/CommerceLayer" +import { AddSampleItems, OrderStorage } from "../../_internals/OrderStorage" const setup: Meta = { - title: 'Examples/Shopping Cart/Cart page' + title: "Examples/Shopping Cart/Cart page", } export default setup @@ -31,29 +31,29 @@ export default setup export const Default: StoryFn = (args) => { return ( - + -
- Line items +
+ Line items -

+

Items count:

- -
+ +
- +
- +
@@ -63,38 +63,38 @@ export const Default: StoryFn = (args) => {
-
- Coupon - - - +
+ Coupon + + + -
- +
+
-
- Gift Card - - - +
+ Gift Card + + + -
- +
+
-
- Totals -
+
+ Totals +
Subtotal Discount Gift Card @@ -102,7 +102,7 @@ export const Default: StoryFn = (args) => {
- + diff --git a/packages/docs/stories/examples/checkout/000.intro.mdx b/packages/docs/stories/examples/checkout/000.intro.mdx index 88bfe10e..ce5642cc 100644 --- a/packages/docs/stories/examples/checkout/000.intro.mdx +++ b/packages/docs/stories/examples/checkout/000.intro.mdx @@ -1,4 +1,4 @@ -import { Meta, Source, Canvas } from '@storybook/addon-docs'; +import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks'; diff --git a/packages/docs/stories/examples/checkout/001.items.mdx b/packages/docs/stories/examples/checkout/001.items.mdx index cb42fccb..93f7ed76 100644 --- a/packages/docs/stories/examples/checkout/001.items.mdx +++ b/packages/docs/stories/examples/checkout/001.items.mdx @@ -1,4 +1,4 @@ -import { Meta, Source, Canvas } from '@storybook/addon-docs'; +import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks'; import * as Stories from './001.items.stories.tsx' diff --git a/packages/docs/stories/examples/checkout/001.items.stories.tsx b/packages/docs/stories/examples/checkout/001.items.stories.tsx index 6ffed270..87ebc79f 100644 --- a/packages/docs/stories/examples/checkout/001.items.stories.tsx +++ b/packages/docs/stories/examples/checkout/001.items.stories.tsx @@ -1,52 +1,52 @@ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import LineItemsContainer from '#components/line_items/LineItemsContainer' -import LineItem from '#components/line_items/LineItem' -import LineItemName from '#components/line_items/LineItemName' -import LineItemImage from '#components/line_items/LineItemImage' -import LineItemAmount from '#components/line_items/LineItemAmount' -import LineItemsEmpty from '#components/line_items/LineItemsEmpty' -import { OrderStorage, AddSampleItems } from '../../_internals/OrderStorage' -import LineItemQuantity from '#components/line_items/LineItemQuantity' -import { persistKey } from './utils' -import GiftCardOrCouponForm from '#components/gift_cards/GiftCardOrCouponForm' -import GiftCardOrCouponSubmit from '#components/gift_cards/GiftCardOrCouponSubmit' -import GiftCardOrCouponInput from '#components/gift_cards/GiftCardOrCouponInput' -import Errors from '#components/errors/Errors' -import GiftCardOrCouponCode from '#components/gift_cards/GiftCardOrCouponCode' -import GiftCardOrCouponRemoveButton from '#components/gift_cards/GiftCardOrCouponRemoveButton' -import SubTotalAmount from '#components/orders/SubTotalAmount' -import DiscountAmount from '#components/orders/DiscountAmount' -import GiftCardAmount from '#components/orders/GiftCardAmount' -import TotalAmount from '#components/orders/TotalAmount' +import type { Meta, StoryFn } from "@storybook/react-vite" +import Errors from "#components/errors/Errors" +import GiftCardOrCouponCode from "#components/gift_cards/GiftCardOrCouponCode" +import GiftCardOrCouponForm from "#components/gift_cards/GiftCardOrCouponForm" +import GiftCardOrCouponInput from "#components/gift_cards/GiftCardOrCouponInput" +import GiftCardOrCouponRemoveButton from "#components/gift_cards/GiftCardOrCouponRemoveButton" +import GiftCardOrCouponSubmit from "#components/gift_cards/GiftCardOrCouponSubmit" +import LineItem from "#components/line_items/LineItem" +import LineItemAmount from "#components/line_items/LineItemAmount" +import LineItemImage from "#components/line_items/LineItemImage" +import LineItemName from "#components/line_items/LineItemName" +import LineItemQuantity from "#components/line_items/LineItemQuantity" +import LineItemsContainer from "#components/line_items/LineItemsContainer" +import LineItemsEmpty from "#components/line_items/LineItemsEmpty" +import DiscountAmount from "#components/orders/DiscountAmount" +import GiftCardAmount from "#components/orders/GiftCardAmount" +import OrderContainer from "#components/orders/OrderContainer" +import SubTotalAmount from "#components/orders/SubTotalAmount" +import TotalAmount from "#components/orders/TotalAmount" +import CommerceLayer from "../../_internals/CommerceLayer" +import { AddSampleItems, OrderStorage } from "../../_internals/OrderStorage" +import { persistKey } from "./utils" const setup: Meta = { - title: 'Examples/Checkout Page/Item list' + title: "Examples/Checkout Page/Item list", } export default setup export const ListOfItems: StoryFn = (args) => { return ( - + -
+
- -
+ +
-
- Unit price: +
+ Unit price:
×
- +
@@ -62,44 +62,44 @@ export const ListOfItems: StoryFn = (args) => { export const Coupons: StoryFn = (args) => { return ( - + -
+
-
+
-
+
Subtotal Discount Gift Card diff --git a/packages/docs/stories/examples/checkout/002.addresses.mdx b/packages/docs/stories/examples/checkout/002.addresses.mdx index c9ffeb5a..0b0e6254 100644 --- a/packages/docs/stories/examples/checkout/002.addresses.mdx +++ b/packages/docs/stories/examples/checkout/002.addresses.mdx @@ -1,4 +1,4 @@ -import { Meta, Source, Canvas } from '@storybook/addon-docs'; +import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks'; import * as Stories from './002.addresses.stories.tsx' diff --git a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx index e8d9b8f5..102091bc 100644 --- a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx +++ b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx @@ -1,37 +1,38 @@ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-base-to-string */ -import type { Meta, StoryFn } from '@storybook/react' -import CommerceLayer from '../../_internals/CommerceLayer' -import OrderContainer from '#components/orders/OrderContainer' -import { OrderStorage } from '../../_internals/OrderStorage' -import { CustomerContainer } from '#components/customers/CustomerContainer' -import { CustomerInput } from '#components/customers/CustomerInput' -import Errors from '#components/errors/Errors' -import { BillingAddressForm } from '#components/addresses/BillingAddressForm' -import { ShippingAddressForm } from '#components/addresses/ShippingAddressForm' -import { AddressesContainer } from '#components/addresses/AddressesContainer' -import { AddressInput } from '#components/addresses/AddressInput' -import { AddressCountrySelector } from '#components/addresses/AddressCountrySelector' -import { AddressStateSelector } from '#components/addresses/AddressStateSelector' -import { SaveAddressesButton } from '#components/addresses/SaveAddressesButton' -import { makeAddressWithRequired, persistKey } from './utils' -import { useMemo, useState } from 'react' -import { type Order } from '@commercelayer/sdk' + +import type { Order } from "@commercelayer/sdk" +import type { Meta, StoryFn } from "@storybook/react-vite" +import { useMemo, useState } from "react" +import { AddressCountrySelector } from "#components/addresses/AddressCountrySelector" +import { AddressesContainer } from "#components/addresses/AddressesContainer" +import { AddressInput } from "#components/addresses/AddressInput" +import { AddressStateSelector } from "#components/addresses/AddressStateSelector" +import { BillingAddressForm } from "#components/addresses/BillingAddressForm" +import { SaveAddressesButton } from "#components/addresses/SaveAddressesButton" +import { ShippingAddressForm } from "#components/addresses/ShippingAddressForm" +import { CustomerContainer } from "#components/customers/CustomerContainer" +import { CustomerInput } from "#components/customers/CustomerInput" +import Errors from "#components/errors/Errors" +import OrderContainer from "#components/orders/OrderContainer" +import CommerceLayer from "../../_internals/CommerceLayer" +import { OrderStorage } from "../../_internals/OrderStorage" +import { makeAddressWithRequired, persistKey } from "./utils" const setup: Meta = { - title: 'Examples/Checkout Page/Addresses' + title: "Examples/Checkout Page/Addresses", } export default setup -const inputCss = 'border border-gray-300 p-2 rounded-md w-full' +const inputCss = "border border-gray-300 p-2 rounded-md w-full" export const CustomerAddresses: StoryFn = (args) => { const [order, setOrder] = useState(null) const billingAddress = useMemo( () => makeAddressWithRequired(order?.billing_address), - [order?.billing_address] + [order?.billing_address], ) // const shippingAddress = useMemo( @@ -40,192 +41,192 @@ export const CustomerAddresses: StoryFn = (args) => { // ) return ( - + -
+
-
- +
+ - +
{/* Use `key` to re-render the BillingAddressForm once we have the order from `fetchOrder`. */} {/* When you are in your own project, you can retrieve the order before rendering the form. */} -
-
-