diff --git a/.changeset/clever-feet-clean.md b/.changeset/clever-feet-clean.md new file mode 100644 index 000000000..fcbe3e9d8 --- /dev/null +++ b/.changeset/clever-feet-clean.md @@ -0,0 +1,5 @@ +--- +"@easypost/easy-ui": minor +--- + +feat(Icon): add support for images diff --git a/documentation/specs/Icon.md b/documentation/specs/Icon.md index ff0bfdb80..e34c7a671 100644 --- a/documentation/specs/Icon.md +++ b/documentation/specs/Icon.md @@ -14,7 +14,7 @@ type ResponsiveIconSize = { type IconColor = TokenNamespace<"color">; interface Icon { - symbol: ReactElement; + symbol: ReactElement | ReactElement>; size?: IconSize | ResponsiveIconSize; color?: IconColor; accessibilityLabel?: string; diff --git a/easy-ui-react/src/Icon/Icon.module.scss b/easy-ui-react/src/Icon/Icon.module.scss index 611f3a79f..c68ef7a0b 100644 --- a/easy-ui-react/src/Icon/Icon.module.scss +++ b/easy-ui-react/src/Icon/Icon.module.scss @@ -21,7 +21,7 @@ } } -.Svg { +.symbol { position: relative; display: block; width: 100%; diff --git a/easy-ui-react/src/Icon/Icon.stories.tsx b/easy-ui-react/src/Icon/Icon.stories.tsx index c23d35abf..8b18e4bee 100644 --- a/easy-ui-react/src/Icon/Icon.stories.tsx +++ b/easy-ui-react/src/Icon/Icon.stories.tsx @@ -3,7 +3,7 @@ import ErrorIcon from "@easypost/easy-ui-icons/Error"; import InfoIcon from "@easypost/easy-ui-icons/Info"; import WarningIcon from "@easypost/easy-ui-icons/Warning"; import { Meta, StoryObj } from "@storybook/react"; -import React from "react"; +import React, { ComponentProps } from "react"; import { createColorTokensControl, createLabelledOptionsControl, @@ -23,6 +23,7 @@ const meta: Meta = { Info: InfoIcon, Warning: WarningIcon, Error: ErrorIcon, + FedExLogoImg: FedExLogoImg, }), size: createLabelledOptionsControl({ md: "md", @@ -54,3 +55,12 @@ export const Controls: Story = { symbol: CheckCircleIcon, }, }; + +function FedExLogoImg(props: ComponentProps<"img">) { + return ( + + ); +} diff --git a/easy-ui-react/src/Icon/Icon.test.tsx b/easy-ui-react/src/Icon/Icon.test.tsx index eda1e8325..4d95585c4 100644 --- a/easy-ui-react/src/Icon/Icon.test.tsx +++ b/easy-ui-react/src/Icon/Icon.test.tsx @@ -1,6 +1,6 @@ import CheckCircleIcon from "@easypost/easy-ui-icons/CheckCircle"; import { render, screen } from "@testing-library/react"; -import React from "react"; +import React, { ComponentProps } from "react"; import { getResponsiveDesignToken, getComponentThemeToken, @@ -39,4 +39,13 @@ describe("", () => { getResponsiveDesignToken("icon", "size", "size.icon", "sm"), ); }); + + it("should render an image", () => { + const CarrierLogo = (props: ComponentProps<"img">) => ( + + ); + render(); + expect(screen.getByRole("img", { hidden: false })).toBeInTheDocument(); + expect(screen.getByTitle("Carrier name")).toBeInTheDocument(); + }); }); diff --git a/easy-ui-react/src/Icon/Icon.tsx b/easy-ui-react/src/Icon/Icon.tsx index f417bfeb3..ce8a47718 100644 --- a/easy-ui-react/src/Icon/Icon.tsx +++ b/easy-ui-react/src/Icon/Icon.tsx @@ -22,7 +22,12 @@ export type IconColor = | "primary-inverse"; export type IconProps = { - /** Icon symbol SVG source from @easypost/easy-ui-icons */ + /** + * Icon symbol. + * + * This can be an SVG source from @easypost/easy-ui-icons or a React + * element that renders to an img. + */ symbol: IconSymbol; /** Size of the icon */ size?: ResponsiveProp; @@ -82,6 +87,16 @@ export type IconProps = { * return ; * } * ``` + * @example + * _With image symbol:_ + * ```tsx + * import { Icon } from "@easypost/easy-ui/Icon"; + * + * export function Component() { + * const CarrierLogo = (props) => ; + * return ; + * } + * ``` */ export function Icon({ symbol: Symbol, @@ -101,7 +116,7 @@ export function Icon({ return ( = Namespace< export type ThemeColorAliases = ThemeTokenNamespace<"color">; -type IconSymbolProps = React.SVGProps & { +type IconSvgSymbolProps = React.SVGProps & { title?: string; titleId?: string; }; -export type IconSymbol = React.FunctionComponent; +export type IconSymbol = + | React.FunctionComponent + | React.FunctionComponent>; export type SpaceScale = DesignTokenNamespace<"space">; export type ResponsiveSpaceScale = ResponsiveProp;