From 36b9a677f379357c4c41f057ce0319427f6903a2 Mon Sep 17 00:00:00 2001 From: Arno V Date: Wed, 8 Nov 2023 08:46:40 -0500 Subject: [PATCH 1/3] feat: adding spacing prop to Icons --- packages/documentation/src/modules/App/App.tsx | 2 +- .../ui-components/src/components/Icons/IconClose.tsx | 9 ++++++++- .../ui-components/src/components/Icons/IconCopied.tsx | 9 ++++++++- .../ui-components/src/components/Icons/IconCopy.tsx | 9 ++++++++- .../ui-components/src/components/Icons/IconDelete.tsx | 9 ++++++++- .../ui-components/src/components/Icons/IconDog.tsx | 9 ++++++++- .../src/components/Icons/IconDogInShield.tsx | 9 ++++++++- .../ui-components/src/components/Icons/IconEdit.tsx | 9 ++++++++- .../src/components/Icons/IconRestore.tsx | 9 ++++++++- .../src/components/Icons/IconSettings.tsx | 8 +++++++- .../ui-components/src/components/Icons/IconUser.tsx | 9 ++++++++- .../src/components/Icons/IconsTypes.d.ts | 3 +++ .../src/components/private/SvgIcon/SvgIcon.tsx | 11 ++++++++++- .../src/components/private/SvgIcon/SvgIconTypes.d.ts | 3 +++ 14 files changed, 96 insertions(+), 12 deletions(-) diff --git a/packages/documentation/src/modules/App/App.tsx b/packages/documentation/src/modules/App/App.tsx index 1db9d695..596b2a67 100644 --- a/packages/documentation/src/modules/App/App.tsx +++ b/packages/documentation/src/modules/App/App.tsx @@ -130,7 +130,7 @@ function App() {
- + diff --git a/packages/ui-components/src/components/Icons/IconClose.tsx b/packages/ui-components/src/components/Icons/IconClose.tsx index 42460cbe..8de0d6f4 100644 --- a/packages/ui-components/src/components/Icons/IconClose.tsx +++ b/packages/ui-components/src/components/Icons/IconClose.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconClose = ({ className, viewBox }: IconsProps) => { +export const IconClose = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconCopied.tsx b/packages/ui-components/src/components/Icons/IconCopied.tsx index 81d49c16..6b8ee8e3 100644 --- a/packages/ui-components/src/components/Icons/IconCopied.tsx +++ b/packages/ui-components/src/components/Icons/IconCopied.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconCopied = ({ className, viewBox }: IconsProps) => { +export const IconCopied = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconCopy.tsx b/packages/ui-components/src/components/Icons/IconCopy.tsx index 001479a8..975000e0 100644 --- a/packages/ui-components/src/components/Icons/IconCopy.tsx +++ b/packages/ui-components/src/components/Icons/IconCopy.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconCopy = ({ className, viewBox }: IconsProps) => { +export const IconCopy = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconDelete.tsx b/packages/ui-components/src/components/Icons/IconDelete.tsx index 96b34442..57724419 100644 --- a/packages/ui-components/src/components/Icons/IconDelete.tsx +++ b/packages/ui-components/src/components/Icons/IconDelete.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconDelete = ({ className, viewBox }: IconsProps) => { +export const IconDelete = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconDog.tsx b/packages/ui-components/src/components/Icons/IconDog.tsx index 692f465c..e1263116 100644 --- a/packages/ui-components/src/components/Icons/IconDog.tsx +++ b/packages/ui-components/src/components/Icons/IconDog.tsx @@ -1,13 +1,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import type { IconsProps } from "./IconsTypes"; -export const IconDog = ({ className, viewBox }: IconsProps) => { +export const IconDog = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( { +export const IconDogInShield = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconEdit.tsx b/packages/ui-components/src/components/Icons/IconEdit.tsx index 956106d3..90f8e59d 100644 --- a/packages/ui-components/src/components/Icons/IconEdit.tsx +++ b/packages/ui-components/src/components/Icons/IconEdit.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconEdit = ({ className, viewBox }: IconsProps) => { +export const IconEdit = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconRestore.tsx b/packages/ui-components/src/components/Icons/IconRestore.tsx index 151e24a5..33492e7d 100644 --- a/packages/ui-components/src/components/Icons/IconRestore.tsx +++ b/packages/ui-components/src/components/Icons/IconRestore.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconRestore = ({ className, viewBox }: IconsProps) => { +export const IconRestore = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconSettings.tsx b/packages/ui-components/src/components/Icons/IconSettings.tsx index 8cdf3fda..8c645c11 100644 --- a/packages/ui-components/src/components/Icons/IconSettings.tsx +++ b/packages/ui-components/src/components/Icons/IconSettings.tsx @@ -2,13 +2,19 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconSettings = ({ className, viewBox, ...rest }: IconsProps) => { +export const IconSettings = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconUser.tsx b/packages/ui-components/src/components/Icons/IconUser.tsx index 5ae6f374..6ce806cb 100644 --- a/packages/ui-components/src/components/Icons/IconUser.tsx +++ b/packages/ui-components/src/components/Icons/IconUser.tsx @@ -2,13 +2,20 @@ import { SvgIcon } from "../private/SvgIcon/SvgIcon"; import { defaultIconSize } from "./constants"; import type { IconsProps } from "./IconsTypes"; -export const IconUser = ({ className, viewBox }: IconsProps) => { +export const IconUser = ({ + className, + viewBox, + spacing, + ...rest +}: IconsProps) => { return ( {/* Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. */} diff --git a/packages/ui-components/src/components/Icons/IconsTypes.d.ts b/packages/ui-components/src/components/Icons/IconsTypes.d.ts index 50104bd2..285fce78 100644 --- a/packages/ui-components/src/components/Icons/IconsTypes.d.ts +++ b/packages/ui-components/src/components/Icons/IconsTypes.d.ts @@ -1,4 +1,7 @@ +import { SpacingType } from "../../common/commonTypes"; + export type IconsProps = { className?: string; viewBox?: string; + spacing?: SpacingType; } & React.SVGAttributes; diff --git a/packages/ui-components/src/components/private/SvgIcon/SvgIcon.tsx b/packages/ui-components/src/components/private/SvgIcon/SvgIcon.tsx index d07a57ad..c4317916 100644 --- a/packages/ui-components/src/components/private/SvgIcon/SvgIcon.tsx +++ b/packages/ui-components/src/components/private/SvgIcon/SvgIcon.tsx @@ -1,3 +1,6 @@ +import clsx from "clsx"; + +import { getSpacing } from "../../../common/utilities"; import type { SvgIconProps } from "./SvgIconTypes"; export const SvgIcon = ({ @@ -7,12 +10,18 @@ export const SvgIcon = ({ className, defaultViewBox, defaultClassName, + spacing, ...rest }: SvgIconProps) => { + const generatedSpacing = getSpacing(spacing); + const generatedClassName = clsx( + generatedSpacing, + className ? className : defaultClassName, + ); return ( ; From 7e908544a7305f47a394651504be38fc2caeb7cc Mon Sep 17 00:00:00 2001 From: Arno V Date: Wed, 8 Nov 2023 10:19:20 -0500 Subject: [PATCH 2/3] chore: adding tests for all Icons --- .../components/Icons/__tests__/Icons.test.tsx | 185 ++++++++++++++++++ packages/ui-components/vitest.config.ts | 7 +- 2 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 packages/ui-components/src/components/Icons/__tests__/Icons.test.tsx diff --git a/packages/ui-components/src/components/Icons/__tests__/Icons.test.tsx b/packages/ui-components/src/components/Icons/__tests__/Icons.test.tsx new file mode 100644 index 00000000..828459e4 --- /dev/null +++ b/packages/ui-components/src/components/Icons/__tests__/Icons.test.tsx @@ -0,0 +1,185 @@ +import { render, screen } from "@testing-library/react"; + +import { defaultIconSize } from "../constants"; +import { IconClose } from "../IconClose"; +import { IconCopied } from "../IconCopied"; +import { IconCopy } from "../IconCopy"; +import { IconDelete } from "../IconDelete"; +import { IconDog } from "../IconDog"; +import { IconDogInShield } from "../IconDogInShield"; +import { IconEdit } from "../IconEdit"; +import { IconRestore } from "../IconRestore"; +import { IconSettings } from "../IconSettings"; +import { IconUser } from "../IconUser"; + +const renderExpected = async ({ + dataTestId, + fill, + viewBox, + className, + spacing, +}: { + dataTestId: string; + fill?: string; + viewBox?: string; + className?: string; + spacing?: string | number | { t: string | number }; +}) => { + const svg = await screen.findByTestId(dataTestId); + expect(svg.getAttribute("fill")).toBe(fill ? fill : "currentColor"); + expect(svg.getAttribute("viewBox")).toContain(viewBox ? viewBox : "0 0 "); + expect(svg.getAttribute("class")).toContain( + className ? className : defaultIconSize, + ); + if (typeof spacing === "string") { + expect(svg.getAttribute("class")).toContain(`m-${spacing}`); + } + if (typeof spacing === "number") { + expect(svg.getAttribute("class")).toContain(`m-${spacing}`); + } + if (typeof spacing === "object") { + expect(svg.getAttribute("class")).toContain(`mt-${spacing.t}`); + } +}; + +describe("Generic Icons prop tests", () => { + it.each` + fill | viewBox | className | spacing | description + ${"red"} | ${"0 0 666 666"} | ${"toto"} | ${undefined} | ${"with fill, viewBox and className"} + ${undefined} | ${undefined} | ${undefined} | ${undefined} | ${"with default fill, default viewBox and default className"} + ${undefined} | ${undefined} | ${undefined} | ${"666"} | ${"with string spacing"} + ${undefined} | ${undefined} | ${undefined} | ${666} | ${"with number spacing"} + ${undefined} | ${undefined} | ${undefined} | ${{ t: 666 }} | ${"with object spacing"} + `( + "should render Icons $description", + async ({ fill, viewBox, className, spacing }) => { + render( + <> + + + + + + + + + + , + ); + + [ + "icon-close", + "icon-copied", + "icon-copy", + "icon-delete", + "icon-dog-in-shield", + "icon-edit", + "icon-restore", + "icon-settings", + "icon-user", + ].forEach(async (dataTestId) => { + await renderExpected({ + dataTestId, + fill, + viewBox, + className, + spacing, + }); + }); + }, + ); +}); + +describe("Custom IconDog prop tests", () => { + it.each` + fill | viewBox | className | spacing | description + ${"red"} | ${"0 0 666 666"} | ${"toto"} | ${undefined} | ${"with fill, viewBox and className"} + ${undefined} | ${undefined} | ${undefined} | ${undefined} | ${"with default fill, default viewBox and default className"} + ${undefined} | ${undefined} | ${undefined} | ${"666"} | ${"with string spacing"} + ${undefined} | ${undefined} | ${undefined} | ${666} | ${"with number spacing"} + ${undefined} | ${undefined} | ${undefined} | ${{ t: 666 }} | ${"with object spacing"} + `( + "should render IconDog $description", + async ({ fill, viewBox, className, spacing }) => { + render( + , + ); + + const svg = await screen.findByTestId("icon-dog"); + expect(svg.getAttribute("fill")).toBe(fill ? fill : "currentColor"); + expect(svg.getAttribute("viewBox")).toContain(viewBox ? viewBox : "0 0 "); + expect(svg.getAttribute("class")).toContain( + className ? className : "w-full", + ); + if (typeof spacing === "string") { + expect(svg.getAttribute("class")).toContain(`m-${spacing}`); + } + if (typeof spacing === "number") { + expect(svg.getAttribute("class")).toContain(`m-${spacing}`); + } + if (typeof spacing === "object") { + expect(svg.getAttribute("class")).toContain(`mt-${spacing.t}`); + } + }, + ); +}); diff --git a/packages/ui-components/vitest.config.ts b/packages/ui-components/vitest.config.ts index e8a25305..318de68e 100644 --- a/packages/ui-components/vitest.config.ts +++ b/packages/ui-components/vitest.config.ts @@ -10,12 +10,11 @@ export default mergeConfig( setupFiles: ["./vitest.setup.ts"], environment: "jsdom", coverage: { - exclude: ["**/Icons/**"], provider: "v8", - lines: 55, - functions: 30, + lines: 100, + functions: 100, branches: 100, - statements: 55, + statements: 100, }, }, }), From 56e8a5ccd12c41d469359929fcf75895aa6111c5 Mon Sep 17 00:00:00 2001 From: Arno V Date: Wed, 8 Nov 2023 10:20:08 -0500 Subject: [PATCH 3/3] Update App.tsx --- packages/documentation/src/modules/App/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/src/modules/App/App.tsx b/packages/documentation/src/modules/App/App.tsx index 596b2a67..1db9d695 100644 --- a/packages/documentation/src/modules/App/App.tsx +++ b/packages/documentation/src/modules/App/App.tsx @@ -130,7 +130,7 @@ function App() {
- +