From 52ae24d8f30138676fb7142b4ffc218d50b1f785 Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Tue, 19 May 2026 11:39:58 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9A=20docs(stories):=20extract=20depre?= =?UTF-8?q?cated=20containers=20into=20own=20story=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split Skus.stories.tsx → Sku.stories.tsx (standalone) + Skus.stories.tsx (iterator) - Add SkuList.stories.tsx and SkuListsContainer.stories.tsx (deprecated) - Add OrderContainer.stories.tsx (deprecated) extracted from Order.stories.tsx - Add PricesContainer.stories.tsx (deprecated) extracted from prices.stories.tsx - Add AvailabilityContainer.stories.tsx (deprecated) + AvailabilityTemplate.stories.tsx - Fix all meta.title values to sit under the correct Storybook menu - Remove deprecated-component sections from parent story doc pages - Replace PricesContainer/SkusContainer usage in non-deprecated stories with standalone components Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../AvailabilityContainer.stories.tsx | 106 +++++++ .../AvailabilityTemplate.stories.tsx | 278 ++++++++++++++++++ .../availability/availability.stories.tsx | 201 +++---------- .../src/stories/orders/Order.stories.tsx | 81 ++--- .../stories/orders/OrderContainer.stories.tsx | 124 ++++++++ .../prices/PricesContainer.stories.tsx | 150 ++++++++++ .../src/stories/prices/prices.stories.tsx | 197 ++++--------- .../document/src/stories/skus/Sku.stories.tsx | 107 +++++++ .../src/stories/skus/SkuList.stories.tsx | 92 ++++++ .../skus/SkuListsContainer.stories.tsx | 120 ++++++++ .../stories/skus/SkusContainer.stories.tsx | 77 ++--- .../src/stories/skus/skus.stories.tsx | 185 ++---------- 12 files changed, 1163 insertions(+), 555 deletions(-) create mode 100644 packages/document/src/stories/availability/AvailabilityContainer.stories.tsx create mode 100644 packages/document/src/stories/availability/AvailabilityTemplate.stories.tsx create mode 100644 packages/document/src/stories/orders/OrderContainer.stories.tsx create mode 100644 packages/document/src/stories/prices/PricesContainer.stories.tsx create mode 100644 packages/document/src/stories/skus/Sku.stories.tsx create mode 100644 packages/document/src/stories/skus/SkuList.stories.tsx create mode 100644 packages/document/src/stories/skus/SkuListsContainer.stories.tsx diff --git a/packages/document/src/stories/availability/AvailabilityContainer.stories.tsx b/packages/document/src/stories/availability/AvailabilityContainer.stories.tsx new file mode 100644 index 00000000..8e9421d1 --- /dev/null +++ b/packages/document/src/stories/availability/AvailabilityContainer.stories.tsx @@ -0,0 +1,106 @@ +import { + Availability, + AvailabilityContainer, + AvailabilityTemplate, +} from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function AvailabilityContainerDocsPage(): JSX.Element { + return ( + <> +

AvailabilityContainer

+ +

+ {""} is deprecated. Use the standalone{" "} + {""} component instead. See{" "} + Availability/Availability for the recommended pattern.{" "} + {""} will be removed in the next major version. +

+
+

+ {""} fetches inventory data for a given SKU code and + makes it available to its {""} children via context. +

+ +
+

Migration guide

+

+ Before (deprecated): +

+ + + + + +`} + /> +

+ After (recommended): +

+ + + + + +`} + /> +
+

Example

+ + + ) +} + +const meta = { + title: "Components/Availability/AvailabilityContainer", + component: AvailabilityContainer, + parameters: { + layout: "centered", + docs: { + page: AvailabilityContainerDocsPage, + }, + }, + argTypes: { + skuCode: { + control: "text", + description: "The SKU code to fetch availability for.", + }, + skuId: { + control: "text", + description: + "The SKU resource ID. Takes precedence over `skuCode` and improves performance by skipping the code-to-id lookup.", + }, + children: { + control: false, + description: "Accepts `` as a child.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const DeprecatedContainer: Story = { + name: "AvailabilityContainer — deprecated (legacy)", + render: () => ( + + + + + + ), +} diff --git a/packages/document/src/stories/availability/AvailabilityTemplate.stories.tsx b/packages/document/src/stories/availability/AvailabilityTemplate.stories.tsx new file mode 100644 index 00000000..f69ed080 --- /dev/null +++ b/packages/document/src/stories/availability/AvailabilityTemplate.stories.tsx @@ -0,0 +1,278 @@ +import { + Availability, + AvailabilityTemplate, +} from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function AvailabilityTemplateDocsPage(): JSX.Element { + return ( + <> +

AvailabilityTemplate

+

+ Reads from the parent {""} context and renders a{" "} + {""} with availability text. Customise the label shown for each state ( + available, outOfStock, negativeStock) and optionally + include delivery lead time and shipping method details. +

+
+

+ Must be a descendant of the {""} component. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDefaultDescription
+ labels.available + + string + + "Available" + Text shown when quantity > 0
+ labels.outOfStock + + string + + "Out of stock" + Text shown when quantity is 0
+ labels.negativeStock + + string + + "Not available" + Text shown when quantity is negative
+ timeFormat + + "days" | "hours" + When set, delivery lead time is appended to the label
+ showShippingMethodName + + boolean + + false + + Requires timeFormat. Appends the shipping method name +
+ showShippingMethodPrice + + boolean + + false + + Requires timeFormat. Appends the formatted shipping price +
+
+

Custom labels

+

+ Customise the displayed text for all stock states via the labels prop. +

+ +

Lead time

+

+ Set timeFormat to "days" or "hours" to show the + shipping lead time alongside the availability status. +

+ + +

Shipping method

+ + +
+

Children render prop

+

+ Pass a function as children to fully control the rendered output. The function + receives the full availability context including quantity, text,{" "} + min, max, and shipping_method. +

+ + + {({ quantity, text, min, max }) => ( +
+ {text} + {quantity > 0 && min != null && ( +

Ships in {min.days}–{max?.days ?? min.days} days

+ )} +
+ )} +
+ +`} + /> + + + ) +} + +const meta = { + title: "Components/Availability/AvailabilityTemplate", + component: AvailabilityTemplate, + parameters: { + layout: "centered", + docs: { + page: AvailabilityTemplateDocsPage, + }, + }, + argTypes: { + labels: { + control: "object", + description: + "Text labels for each stock state: `available`, `outOfStock`, `negativeStock`.", + }, + timeFormat: { + control: "select", + options: ["days", "hours"], + description: + "When set, delivery lead time is appended to the availability label.", + }, + showShippingMethodName: { + control: "boolean", + description: "Requires `timeFormat`. Appends the shipping method name to the label.", + }, + showShippingMethodPrice: { + control: "boolean", + description: "Requires `timeFormat`. Appends the formatted shipping price to the label.", + }, + children: { + control: false, + description: + "Render prop receiving `{ quantity, text, min, max, shipping_method }` for a fully custom availability UI.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const CustomLabels: Story = { + name: "AvailabilityTemplate — custom labels", + render: () => ( + + + + + + ), +} + +export const WithDeliveryLeadTimeDays: Story = { + name: "AvailabilityTemplate — lead time in days", + render: () => ( + + + + + + ), +} + +export const WithDeliveryLeadTimeHours: Story = { + name: "AvailabilityTemplate — lead time in hours", + render: () => ( + + + + + + ), +} + +export const WithShippingMethodName: Story = { + name: "AvailabilityTemplate — with shipping method name", + render: () => ( + + + + + + ), +} + +export const WithShippingMethodPrice: Story = { + name: "AvailabilityTemplate — with shipping method price", + render: () => ( + + + + + + ), +} + +export const WithChildrenRenderProp: Story = { + name: "AvailabilityTemplate — children render prop", + render: () => ( + + + + {({ quantity, text, min, max }) => ( +
+ {text} + {quantity > 0 && min != null && ( +

+ Ships in {min.days}–{max?.days ?? min.days} day(s) +

+ )} +
+ )} +
+
+
+ ), +} diff --git a/packages/document/src/stories/availability/availability.stories.tsx b/packages/document/src/stories/availability/availability.stories.tsx index 7c6d0bb8..f1a99236 100644 --- a/packages/document/src/stories/availability/availability.stories.tsx +++ b/packages/document/src/stories/availability/availability.stories.tsx @@ -1,6 +1,5 @@ import { Availability, - AvailabilityContainer, AvailabilityTemplate, Sku, SkuField, @@ -14,19 +13,20 @@ function AvailabilityDocsPage(): JSX.Element { <>

Availability

- The Availability components display real-time stock and shipping - information for a SKU. Use the standalone{" "} - {""} component (recommended) — it fetches - availability data automatically. The legacy{" "} - {""} is kept for backwards - compatibility. + The Availability components let you display real-time stock quantity and + delivery lead times for any SKU. They are powered by the Commerce Layer + inventory model and work by fetching availability data through the{" "} + useAvailability hook from @commercelayer/hooks + . All Availability components must be nested inside the{" "} + {""} context.


-

Availability

+

Availability (standalone)

- Standalone component that fetches availability without any container. - Picks up skuCode from a parent {""} or - line-item context when no prop is given. + The preferred way to display availability.{" "} + {""} fetches inventory data on its own — no + container wrapper needed. Picks up skuCode from a parent{" "} + {""} or line-item context when no prop is given.

@@ -42,60 +42,29 @@ function AvailabilityDocsPage(): JSX.Element { import { CommerceLayer, Availability, AvailabilityTemplate } from '@commercelayer/react-components' - - + + `} />


-

AvailabilityTemplate — custom labels

+

Usage inside Skus

- Customise the displayed text for all stock states via the{" "} - labels prop. -

- -
-

Lead time

-

- Set timeFormat to "days" or{" "} - "hours" to show the shipping lead time alongside the - availability status. -

- -
-

Children render prop

-

- Pass a function as children to{" "} - {""} to receive the raw data ( - quantity, text, min,{" "} - max) and build a custom UI. -

- -
-

Inside Sku (inherits skuCode)

-

- When {""} is nested inside{" "} - {""}, the skuCode prop can be omitted — - it is inherited from the context automatically. + When used inside a {""} or{" "} + {""}{""} tree,{" "} + {""} automatically inherits the{" "} + skuCode from the current SKU context — no need to pass{" "} + skuCode explicitly.

-
-

AvailabilityContainer (deprecated)

-

- {""} is the legacy wrapper. Prefer{" "} - the standalone {""} component for new code. -

- ) } const meta = { - title: "Availability/Availability", + title: "Components/Availability/Availability", component: Availability, parameters: { layout: "centered", @@ -103,6 +72,32 @@ const meta = { page: AvailabilityDocsPage, }, }, + argTypes: { + skuCode: { + control: "text", + description: + "The SKU code to fetch availability for. Automatically inherited from a parent `` or line-item context when omitted.", + }, + skuId: { + control: "text", + description: + "The SKU resource ID. Takes precedence over `skuCode` and improves performance by skipping the code-to-id lookup.", + }, + getQuantity: { + control: false, + description: + "Callback fired whenever the available quantity changes. Receives the quantity as a number.", + }, + loader: { + control: "text", + description: "Content displayed while availability data is loading.", + }, + children: { + control: false, + description: + "Accepts `` as a child to display stock status and lead time.", + }, + }, } satisfies Meta export default meta @@ -121,77 +116,6 @@ export const StandaloneAvailability: Story = { ), } -export const CustomLabels: Story = { - name: "AvailabilityTemplate — custom labels", - render: () => ( - - - - - - ), -} - -export const WithDeliveryLeadTimeDays: Story = { - name: "AvailabilityTemplate — lead time in days", - render: () => ( - - - - - - ), -} - -export const WithDeliveryLeadTimeHours: Story = { - name: "AvailabilityTemplate — lead time in hours", - render: () => ( - - - - - - ), -} - -export const WithShippingMethodName: Story = { - name: "AvailabilityTemplate — with shipping method name", - render: () => ( - - - - - - ), -} - -export const WithShippingMethodPrice: Story = { - name: "AvailabilityTemplate — with shipping method price", - render: () => ( - - - - - - ), -} - export const WithGetQuantityCallback: Story = { name: "Availability — getQuantity callback", render: () => ( @@ -208,28 +132,6 @@ export const WithGetQuantityCallback: Story = { ), } -export const WithChildrenRenderProp: Story = { - name: "AvailabilityTemplate — children render prop", - render: () => ( - - - - {({ quantity, text, min, max }) => ( -
- {text} - {quantity > 0 && min != null && ( -

- Ships in {min.days}–{max?.days ?? min.days} day(s) -

- )} -
- )} -
-
-
- ), -} - export const InsideSku: Story = { name: "Availability — inside Sku (inherits skuCode)", render: () => ( @@ -247,14 +149,3 @@ export const InsideSku: Story = { ), } - -export const DeprecatedContainer: Story = { - name: "AvailabilityContainer — deprecated (legacy)", - render: () => ( - - - - - - ), -} diff --git a/packages/document/src/stories/orders/Order.stories.tsx b/packages/document/src/stories/orders/Order.stories.tsx index ad01b754..eccf9d83 100644 --- a/packages/document/src/stories/orders/Order.stories.tsx +++ b/packages/document/src/stories/orders/Order.stories.tsx @@ -38,13 +38,13 @@ function OrderDocsPage(): JSX.Element { orderId from a parent {""}{" "} component.

-
+

- Must be a child of {""}. Can optionally - be a child of {""} to receive the{" "} + Must be a child of {""}. Can optionally be + a child of {""} to receive the{" "} orderId automatically.

-
+ -
-

OrderContainer (deprecated)

-
-

- ⚠️ Deprecated:{" "} - {""} is deprecated and will be removed - in the next major version. Use {""} instead — it - has the same API and is a drop-in replacement. -

-
-

- Before (deprecated): -

- - -
Order #
-
Total:
-
- -`} - /> -

- After (preferred): -

- - -
Order #
-
Total:
-
- -`} - /> ) } const meta = { - title: "Orders/Order", + title: "Components/Orders/Order", component: Order, parameters: { layout: "centered", @@ -150,6 +106,33 @@ const meta = { page: OrderDocsPage, }, }, + argTypes: { + orderId: { + control: "text", + description: + "ID of the order to fetch. Omit to create a new draft order on demand.", + }, + metadata: { + control: "object", + description: + "Metadata key-value pairs added when a new order is created.", + }, + attributes: { + control: "object", + description: + "Order attributes applied when the order is created or updated (e.g. `language_code`, `coupon_code`).", + }, + fetchOrder: { + control: false, + description: + "Callback fired every time the order is updated. Receives the updated `Order` SDK object — useful for syncing cart badge counts or analytics.", + }, + children: { + control: false, + description: + "Accepts order display components such as ``, ``, ``, etc.", + }, + }, } satisfies Meta export default meta diff --git a/packages/document/src/stories/orders/OrderContainer.stories.tsx b/packages/document/src/stories/orders/OrderContainer.stories.tsx new file mode 100644 index 00000000..381ad00b --- /dev/null +++ b/packages/document/src/stories/orders/OrderContainer.stories.tsx @@ -0,0 +1,124 @@ +import { + Order, + OrderContainer, + OrderNumber, + TotalAmount, +} from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function OrderContainerDocsPage(): JSX.Element { + return ( + <> +

OrderContainer

+ +

+ Use {""} instead — it has the same API and is a drop-in replacement. + See Orders/Order for the recommended pattern.{" "} + {""} will be removed in the next major version. +

+
+

+ {""} fetches an order by ID and stores it in context for its + children. It also fires the optional fetchOrder callback every time the order + is updated. +

+ +
+

Migration guide

+

+ Before (deprecated): +

+ + +
Order #
+
Total:
+
+ +`} + /> +

+ After (recommended): +

+ + +
Order #
+
Total:
+
+ +`} + /> +
+

Example

+ + + ) +} + +const meta = { + title: "Components/Orders/OrderContainer", + component: OrderContainer, + parameters: { + layout: "centered", + docs: { + page: OrderContainerDocsPage, + }, + }, + argTypes: { + orderId: { + control: "text", + description: "ID of the order to fetch.", + }, + metadata: { + control: "object", + description: "Metadata key-value pairs added when a new order is created.", + }, + attributes: { + control: "object", + description: + "Order attributes applied when the order is created or updated (e.g. `language_code`, `coupon_code`).", + }, + fetchOrder: { + control: false, + description: + "Callback fired every time the order is updated. Receives the updated `Order` SDK object.", + }, + children: { + control: false, + description: + "Accepts order display components such as ``, ``, ``, etc.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const OrderContainerStory: Story = { + name: "OrderContainer — display order details", + render: () => ( + + +
+ Order # +
+
+ Total: +
+
+
+ ), +} diff --git a/packages/document/src/stories/prices/PricesContainer.stories.tsx b/packages/document/src/stories/prices/PricesContainer.stories.tsx new file mode 100644 index 00000000..15406d06 --- /dev/null +++ b/packages/document/src/stories/prices/PricesContainer.stories.tsx @@ -0,0 +1,150 @@ +import { Price, PricesContainer } from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function PricesContainerDocsPage(): JSX.Element { + return ( + <> +

PricesContainer

+ +

+ {""} is deprecated and will be removed in a future major + release. Use {''} as a standalone component instead — + it handles batching automatically. See Prices/Price for the recommended + pattern. +

+
+

+ {""} fetches prices for one or more SKU codes and stores them + in a React context for its {""} children. Multiple{" "} + {""} children each register their own skuCode — the + container batches all registrations into a single API request using a 50 ms debounce. +

+ +
+

Migration guide

+

+ Before (deprecated): +

+ + + + + +`} + /> +

+ After (recommended): +

+ + + +`} + /> +
+

Examples

+ + + + + ) +} + +const meta = { + title: "Components/Prices/PricesContainer", + component: PricesContainer, + parameters: { + layout: "centered", + docs: { + page: PricesContainerDocsPage, + }, + }, + argTypes: { + skuCode: { + control: "text", + description: + "SKU code to fetch the prices for. If not provided, the `sku_code` will be retrieved from the nested `` components.", + }, + filters: { + control: "object", + description: "SDK query filter to fetch the prices when multiple prices are requested.", + }, + perPage: { + control: "number", + description: "Number of prices per page to fetch.", + }, + loader: { + control: "text", + description: "Content displayed while prices are loading.", + }, + children: { + control: false, + description: "Accepts `` components as children.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const SingleSkuStory: Story = { + name: "PricesContainer — single SKU", + render: () => ( + + + + + + ), +} + +export const BatchedPricesStory: Story = { + name: "PricesContainer — batched (single API request)", + render: () => ( + + +
+
+ + POST6191FFFFFF000000XXXX + + +
+
+ + POLOMXXX000000FFFFFFLXXX + + +
+
+
+
+ ), +} + +export const WithFiltersStory: Story = { + name: "PricesContainer — with filters", + render: () => ( + + + + + + ), +} diff --git a/packages/document/src/stories/prices/prices.stories.tsx b/packages/document/src/stories/prices/prices.stories.tsx index 6e5ecaaf..661d77a2 100644 --- a/packages/document/src/stories/prices/prices.stories.tsx +++ b/packages/document/src/stories/prices/prices.stories.tsx @@ -1,4 +1,4 @@ -import { Price, PricesContainer } from "@commercelayer/react-components" +import { Price } from "@commercelayer/react-components" import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" import type { Meta, StoryObj } from "@storybook/react-vite" import CommerceLayer from "../_internals/CommerceLayer" @@ -32,13 +32,13 @@ function PricesDocsPage(): JSX.Element { collects all sibling registrations into{" "} one SWR-deduplicated API request.

-
+

No provider or wrapper needed. Drop{" "} {''} anywhere inside{" "} {""} and batching happens automatically.

-
+ -
-

PricesContainer (deprecated)

-
-

- ⚠️ Deprecated:{" "} - {""} is deprecated and will be removed - in a future major release. Use {''}{" "} - as a standalone component instead — it handles batching automatically. -

-
-

- {""} fetches prices for one or more SKU - codes and stores them in a React context for its{" "} - {""} children. Multiple {""}{" "} - children each register their own skuCode — the container - batches all registrations into a single API request using a 50 ms - debounce. -

- instead -import { CommerceLayer, PricesContainer, Price } from '@commercelayer/react-components' - - - - - - -`} - /> - -
-

PricesContainer — batched (deprecated)

-

- Mount multiple {""} components inside{" "} - {""} — each registers its{" "} - skuCode and the container debounces all registrations into{" "} - one API call. -

-
-

- This pattern is still supported but deprecated. The same batching now - happens automatically when you use standalone{" "} - {""} components without any container. -

-
- components instead - - - - - -`} - /> - ) } const meta = { - title: "Prices/Price", + title: "Components/Prices/Price", component: Price, parameters: { layout: "centered", @@ -160,101 +99,67 @@ const meta = { page: PricesDocsPage, }, }, + argTypes: { + skuCode: { + control: "text", + description: + "The SKU code whose price to fetch. When used standalone (no `PricesContainer` parent), this triggers an automatic batched API request.", + }, + showCompare: { + control: "boolean", + description: + "When `false`, the `compare_at` (strike-through) price is not displayed.", + }, + compareClassName: { + control: "text", + description: "CSS class name applied to the compare-at price element.", + }, + loader: { + control: "text", + description: + "Content displayed while the price is loading in standalone mode.", + }, + children: { + control: false, + description: + "Render prop receiving `{ prices, loading, loader }` for a fully custom price UI.", + }, + }, } satisfies Meta export default meta type Story = StoryObj -export const SingleSkuStory: Story = { - name: "PricesContainer — single SKU", - render: () => ( - - - - - - ), -} - -export const BatchedPricesStory: Story = { - name: "PricesContainer — batched (single API request)", - render: () => ( - - -
-
- - POST6191FFFFFF000000XXXX - - -
-
- - POLOMXXX000000FFFFFFLXXX - - -
-
-
-
- ), -} - export const RenderPropStory: Story = { name: "Price — children render prop", render: () => ( - - - {({ prices, loading }) => { - if (loading) return Loading… - if (prices.length === 0) - return No price available - const [p] = prices - return ( -
- - {p.formatted_amount} - - {p.formatted_compare_at_amount != null && ( - - {p.formatted_compare_at_amount} - - )} -
- ) - }} -
-
-
- ), -} - -export const WithFiltersStory: Story = { - name: "PricesContainer — with filters", - render: () => ( - - - - + + {({ prices, loading }) => { + if (loading) return Loading… + if (prices.length === 0) + return No price available + const [p] = prices + return ( +
+ + {p.formatted_amount} + + {p.formatted_compare_at_amount != null && ( + + {p.formatted_compare_at_amount} + + )} +
+ ) + }} +
), } export const StandalonePrice: Story = { - name: "Price — standalone (no PricesContainer)", + name: "Price — standalone", render: () => (
diff --git a/packages/document/src/stories/skus/Sku.stories.tsx b/packages/document/src/stories/skus/Sku.stories.tsx new file mode 100644 index 00000000..a3a3b92f --- /dev/null +++ b/packages/document/src/stories/skus/Sku.stories.tsx @@ -0,0 +1,107 @@ +import { Sku, SkuField } from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function SkusDocsPage(): JSX.Element { + return ( + <> +

SKUs

+

+ The SKU components let you fetch and display product data from the Commerce Layer API. All + SKU components must be nested inside the {""} context that + handles API authentication. +

+

+ Refer to the{" "} + + SKUs API reference + {" "} + for the full list of available attributes. +

+
+

Sku (standalone — recommended)

+

+ {""} is a standalone component that fetches and displays SKU data without + requiring a {""} parent. Multiple sibling {""}{" "} + components are automatically batched into a single API request via a module-level debounce + store, so rendering many SKUs on one page is efficient. +

+ +

+ Must be a child of {""}. Accepts {""}{" "} + and {""} as children. +

+
+ + + + + + + + + + + +`} + /> + + + ) +} + +const meta = { + title: "Components/Skus/Sku", + component: Sku, + parameters: { + layout: "centered", + docs: { + page: SkusDocsPage, + }, + }, + argTypes: { + skuCode: { + control: "text", + description: + "The SKU code to fetch. Multiple sibling `` components with different codes are batched into a single API request.", + }, + loader: { + control: "text", + description: "Content displayed while the SKU data is loading.", + }, + children: { + control: false, + description: "Accepts `` and `` as children.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const StandaloneSkuStory: Story = { + name: "Sku — standalone (no container)", + render: () => ( + + +
+ + +
+
+ +
+ + +
+
+
+ ), +} diff --git a/packages/document/src/stories/skus/SkuList.stories.tsx b/packages/document/src/stories/skus/SkuList.stories.tsx new file mode 100644 index 00000000..fae9a904 --- /dev/null +++ b/packages/document/src/stories/skus/SkuList.stories.tsx @@ -0,0 +1,92 @@ +import { SkuField, SkuList, Skus } from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function SkuListDocsPage(): JSX.Element { + return ( + <> +

SkuList

+

+ {""} fetches and renders SKUs belonging to a Commerce Layer SKU list. + It can be used as a standalone component — pass the SKU list id directly and + nest {""} inside to iterate over the list items. +

+ +

+ Must be a child of {""}. Accepts {""} and{" "} + {""} as children. +

+
+ +
+

Example

+ + + + + + + + +`} + /> + + + ) +} + +const meta = { + title: "Components/Skus/SkuList", + component: SkuList, + parameters: { + layout: "centered", + docs: { + page: SkuListDocsPage, + }, + }, + argTypes: { + id: { + control: "text", + description: "The ID of the SKU list to fetch.", + }, + params: { + control: "object", + description: + "Optional query parameters forwarded to the SKU list retrieval call. `include: [\"skus\"]` is always enforced. Use `fields.skus` to request additional SKU attributes.", + }, + loader: { + control: "text", + description: "Content displayed while the SKU list data is loading.", + }, + children: { + control: false, + description: "Accepts `` and `` as children.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const StandaloneSkuList: Story = { + name: "SkuList — standalone (no container)", + render: () => ( + + + +
+ + +
+
+
+
+ ), +} diff --git a/packages/document/src/stories/skus/SkuListsContainer.stories.tsx b/packages/document/src/stories/skus/SkuListsContainer.stories.tsx new file mode 100644 index 00000000..0313dc4a --- /dev/null +++ b/packages/document/src/stories/skus/SkuListsContainer.stories.tsx @@ -0,0 +1,120 @@ +import { SkuField, SkuList, SkuListsContainer, Skus } from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" +import type { Meta, StoryObj } from "@storybook/react-vite" +import CommerceLayer from "../_internals/CommerceLayer" + +function SkuListsContainerDocsPage(): JSX.Element { + return ( + <> +

SkuListsContainer

+ +

+ Use the standalone {''} component instead — it fetches its + own data without requiring a container parent. See Skus/SkuList for the + recommended pattern. {""} will be removed in the next + major version. +

+
+

+ {""} fetches one or more SKU lists by ID and makes their SKU + data available to child {""} components. Each{" "} + {""} registers its own ID with this container on mount. +

+ +
+

Migration guide

+

+ Before (deprecated): +

+ + + + + + + + + + +`} + /> +

+ After (recommended): +

+ + + + + + + + +`} + /> +
+

Example

+ + + ) +} + +const meta = { + title: "Components/Skus/SkuListsContainer", + component: SkuListsContainer, + parameters: { + layout: "centered", + docs: { + page: SkuListsContainerDocsPage, + }, + }, + argTypes: { + params: { + control: "object", + description: + "Optional query parameters forwarded to each SKU list retrieval call. `include: [\"skus\"]` is always enforced. Use `fields.skus` to request additional SKU attributes.", + }, + children: { + control: false, + description: "Accepts `` as children.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const SkuListsContainerStory: Story = { + name: "SkuListsContainer — list items", + render: () => ( + + + + +
+ + +
+
+
+
+
+ ), +} diff --git a/packages/document/src/stories/skus/SkusContainer.stories.tsx b/packages/document/src/stories/skus/SkusContainer.stories.tsx index 43750550..37c9ce50 100644 --- a/packages/document/src/stories/skus/SkusContainer.stories.tsx +++ b/packages/document/src/stories/skus/SkusContainer.stories.tsx @@ -1,8 +1,4 @@ -import { - SkuField, - Skus, - SkusContainer, -} from "@commercelayer/react-components" +import { SkuField, Skus, SkusContainer } from "@commercelayer/react-components" import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" import type { Meta, StoryObj } from "@storybook/react-vite" import CommerceLayer from "../_internals/CommerceLayer" @@ -11,20 +7,18 @@ function SkusContainerDocsPage(): JSX.Element { return ( <>

SkusContainer

-
+

- ⚠️ Deprecated. Use the standalone{" "} - {''} component instead — it batches - requests automatically and requires no container. See{" "} - Skus/Sku for the recommended pattern. - {""} will be removed in the next major + Use the standalone {''} component instead — it batches + requests automatically and requires no container. See Skus/Sku for the + recommended pattern. {""} will be removed in the next major version.

-
+

- {""} fetches an array of SKUs by code and - stores them in a React context for its {""} children. - Internally it debounces registrations into a single API call. + {""} fetches an array of SKUs by code and stores them in a React + context for its {""} children. Internally it debounces registrations into + a single API call.


@@ -67,32 +61,6 @@ import { CommerceLayer, Sku, SkuField } from '@commercelayer/react-components'
-`} - /> -
-

Skus

-

- {""} is a child of {""}. - It iterates over every SKU fetched by the container and renders its - children once per record — no manual looping required. -

-
-

- Must be a direct child of {""}. Accepts{" "} - {""} and{" "} - {""} as children. -

-
- - - {/* rendered once per SKU */} - - - `} />
@@ -104,7 +72,7 @@ import { CommerceLayer, Sku, SkuField } from '@commercelayer/react-components' } const meta = { - title: "Skus/SkusContainer", + title: "Components/Skus/SkusContainer", component: SkusContainer, parameters: { layout: "centered", @@ -112,6 +80,21 @@ const meta = { page: SkusContainerDocsPage, }, }, + argTypes: { + skus: { + control: "object", + description: "Array of SKU codes to fetch. All codes are batched into a single API request.", + }, + queryParams: { + control: "object", + description: + "Optional query parameters forwarded to the SKUs API request (pagination, sorting, field selection, filters).", + }, + children: { + control: false, + description: "Accepts `` as a child to iterate over fetched SKUs.", + }, + }, } satisfies Meta export default meta @@ -123,10 +106,7 @@ export const Default: Story = { skus: ["POLOMXXX000000FFFFFFLXXX", "CROPTOPWFFFFFF000000XSXX"], }, render: (args) => ( - +
@@ -151,10 +131,7 @@ export const WithQueryParams: Story = { }, }, render: (args) => ( - +
diff --git a/packages/document/src/stories/skus/skus.stories.tsx b/packages/document/src/stories/skus/skus.stories.tsx index e756c9fa..56f13ec2 100644 --- a/packages/document/src/stories/skus/skus.stories.tsx +++ b/packages/document/src/stories/skus/skus.stories.tsx @@ -1,176 +1,69 @@ -import { - Sku, - SkuField, - SkuList, - SkuListsContainer, - Skus, -} from "@commercelayer/react-components" -import { ArgTypes, Source } from "@storybook/addon-docs/blocks" +import { SkuField, SkuList, Skus } from "@commercelayer/react-components" +import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks" import type { Meta, StoryObj } from "@storybook/react-vite" import CommerceLayer from "../_internals/CommerceLayer" function SkusDocsPage(): JSX.Element { return ( <> -

SKUs

+

Skus

- The SKU components let you fetch and display product data from the - Commerce Layer API. All SKU components must be nested inside the{" "} - {""} context that handles API - authentication. + {""} iterates over every SKU fetched by its parent container and renders + its children once per record — no manual looping required.

-

- Refer to the{" "} - - SKUs API reference - {" "} - for the full list of available attributes. -

-
-

Sku (standalone — recommended)

-

- {""} is a standalone component that fetches and - displays SKU data without requiring a {""}{" "} - parent. Multiple sibling {""} components are - automatically batched into a single API request via a module-level - debounce store, so rendering many SKUs on one page is efficient. -

-
+

- Must be a child of {""}. Accepts{" "} - {""} and{" "} - {""} as children. + Must be a direct child of {""}. Accepts{" "} + {""} as children.

-
+ - - - - - - - - - - -`} - /> -
-

SkuListsContainer

-

- {""} fetches one or more SKU lists by - ID and makes their SKU data available to child{" "} - {""} components. Each {""}{" "} - registers its own ID with this container on mount. -

-
-

- Must be a child of {""}. Accepts{" "} - {""} as children. -

-
- - - {/* components go here */} - - -`} - />
-

SkuList

-

- {""} registers its id with the - parent {""} and renders its children - using the SKUs that belong to that list. Nest {""}{" "} - and {""} inside to display list items. -

-
-

- Must be a child of {""}. Accepts{" "} - {""} and {""} as children. -

-
-

- Key props: id (string, required) — the SKU list ID from - Commerce Layer. Accepts {""} and{" "} - {""} as children. -

+

Example

- - - - - - - - + + + {/* rendered once per SKU */} + + + + `} /> + ) } const meta = { - title: "Skus/Sku", - component: Sku, + title: "Components/Skus/Skus", + component: Skus, parameters: { layout: "centered", docs: { page: SkusDocsPage, }, }, -} satisfies Meta + argTypes: { + children: { + control: false, + description: "Rendered once per SKU. Accepts `` as children.", + }, + }, +} satisfies Meta export default meta type Story = StoryObj -export const StandaloneSkuStory: Story = { - name: "Sku — standalone (no container)", - render: () => ( - - -
- - -
-
- -
- - -
-
-
- ), -} - -export const StandaloneSkuListStory: Story = { - name: "SkuList — standalone (no container)", +export const Default: Story = { + name: "Skus — inside SkuList", render: () => ( @@ -184,21 +77,3 @@ export const StandaloneSkuListStory: Story = { ), } - -export const SkuListsContainerStory: Story = { - name: "SkuListsContainer — list items", - render: () => ( - - - - -
- - -
-
-
-
-
- ), -}