diff --git a/.changeset/great-frogs-grin.md b/.changeset/great-frogs-grin.md new file mode 100644 index 0000000000..6ce0ff146a --- /dev/null +++ b/.changeset/great-frogs-grin.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/product-switcher": patch +"@twilio-paste/core": patch +--- + +[ProductSwitcherItem] made productIcon optional diff --git a/packages/paste-core/components/product-switcher/__tests__/ProductSwitcher.spec.tsx b/packages/paste-core/components/product-switcher/__tests__/ProductSwitcher.spec.tsx index fd9d2ed8b0..66c4e3818e 100644 --- a/packages/paste-core/components/product-switcher/__tests__/ProductSwitcher.spec.tsx +++ b/packages/paste-core/components/product-switcher/__tests__/ProductSwitcher.spec.tsx @@ -1,7 +1,11 @@ import { act, render, screen } from "@testing-library/react"; import * as React from "react"; -import { CustomElementName, DefaultElementName } from "../stories/ProductSwitcher.customization.stories"; +import { + CustomElementName, + DefaultElementName, + WithoutProductIcons, +} from "../stories/ProductSwitcher.customization.stories"; import { ProductSwitcherMenu } from "../stories/ProductSwitcher.stories"; describe("ProductSwitcher", () => { @@ -64,3 +68,21 @@ describe("ProductSwitcher", () => { }); }); }); +describe("customization of productIcon", () => { + it("should render product icon if set", async () => { + await act(async () => { + render(); + }); + const menuItem = screen.getByRole("menuitemradio", { name: "Twilio SMS, Voice & Video" }); + const imgChildren = Array.from(menuItem.querySelectorAll('[role="img"]')); + expect(imgChildren).toHaveLength(2); + }); + it("should not render product icon if none is set", async () => { + await act(async () => { + render(); + }); + const menuItem = screen.getByRole("menuitemradio", { name: "Twilio SMS, Voice & Video" }); + const imgChildren = Array.from(menuItem.querySelectorAll('[role="img"]')); + expect(imgChildren).toHaveLength(1); + }); +}); diff --git a/packages/paste-core/components/product-switcher/src/ProductSwitcherItem.tsx b/packages/paste-core/components/product-switcher/src/ProductSwitcherItem.tsx index 15db93150f..f31bfacf2e 100644 --- a/packages/paste-core/components/product-switcher/src/ProductSwitcherItem.tsx +++ b/packages/paste-core/components/product-switcher/src/ProductSwitcherItem.tsx @@ -24,10 +24,10 @@ export interface ProductSwitcherItemProps extends Omit} + * @type {React.ReactNode} * @memberof ProductSwitcherItemProps */ - productIcon: NonNullable; + productIcon?: React.ReactNode; /** * Overrides the default element name to apply unique styles with the Customization Provider. * @@ -43,7 +43,7 @@ const ProductSwitcherItem = React.forwardRef - {productIcon} + {productIcon && {productIcon}} {productName} diff --git a/packages/paste-core/components/product-switcher/stories/ProductSwitcher.customization.stories.tsx b/packages/paste-core/components/product-switcher/stories/ProductSwitcher.customization.stories.tsx index e9999d8327..cca401aae7 100644 --- a/packages/paste-core/components/product-switcher/stories/ProductSwitcher.customization.stories.tsx +++ b/packages/paste-core/components/product-switcher/stories/ProductSwitcher.customization.stories.tsx @@ -173,3 +173,75 @@ export const CustomElementName: StoryFn = () => { ); }; + +export const WithoutProductIcons: StoryFn = () => { + const productSwitcher = useProductSwitcherState({ visible: true }); + const [product, setProduct] = React.useState("twilio"); + return ( + <> + + + { + setProduct("twilio"); + }} + productName="Twilio" + productStrapline="SMS, Voice & Video" + /> + { + setProduct("segment"); + }} + productName="Segment" + productStrapline="Customer data platform" + /> + { + setProduct("flex"); + }} + productName="Flex" + productStrapline="Cloud-based contact center" + /> + { + setProduct("sendgrid"); + }} + productName="SendGrid" + productStrapline="Email delivery and API" + /> + { + setProduct("admin"); + }} + productName="Console Admin" + productStrapline="Admin center" + /> + + + ); +}; diff --git a/packages/paste-core/components/product-switcher/type-docs.json b/packages/paste-core/components/product-switcher/type-docs.json index 9f92d44f9a..73dc961837 100644 --- a/packages/paste-core/components/product-switcher/type-docs.json +++ b/packages/paste-core/components/product-switcher/type-docs.json @@ -2026,13 +2026,6 @@ "externalProp": true, "description": "Moves focus to the previous item." }, - "productIcon": { - "type": "NonNullable", - "defaultValue": "'PRODUCT_SWITCHER_ITEM'", - "required": true, - "externalProp": false, - "description": "Icon to use for the ProductSwitcherItem. Use a Paste Icon." - }, "productName": { "type": "string", "defaultValue": null, @@ -3883,6 +3876,13 @@ "required": false, "externalProp": true }, + "productIcon": { + "type": "string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>", + "defaultValue": "'PRODUCT_SWITCHER_ITEM'", + "required": false, + "externalProp": false, + "description": "Icon to use for the ProductSwitcherItem. Use a Paste Icon." + }, "property": { "type": "string", "defaultValue": null,