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,