From 00408dd32c3eb0c70ed944b00837cc3de0cb09b1 Mon Sep 17 00:00:00 2001 From: Jared White Date: Wed, 24 Apr 2024 13:58:49 -0700 Subject: [PATCH] feat: adopt Hero Icons as replacement for FontAwesome (#74) * feat: first pass at switching to Hero Icons * feat: update icon stories, use scale factor to equalize new icons * test: fix unit tests * fix: text button stories * fix: adjust lg icon alignment * Rejigger all icon sizes to conform to Hero Icons specs * docs: add comment for Icon `outlined` * feat: update icon sizes to use size tokens --- package.json | 3 +- src/actions/Button.scss | 8 ++- src/actions/Button.tsx | 7 +- src/actions/Link.scss | 4 +- src/actions/Link.tsx | 5 +- src/actions/__stories__/Button.docs.mdx | 34 +++++----- src/actions/__stories__/Button.stories.tsx | 40 +++++++++-- src/actions/__stories__/Link.docs.mdx | 8 +-- src/actions/__stories__/Link.stories.tsx | 6 +- src/actions/__tests__/Button.test.tsx | 8 +-- src/actions/__tests__/Link.test.tsx | 8 +-- src/blocks/Alert.scss | 4 +- src/blocks/Message.scss | 4 +- src/blocks/Toast.scss | 4 +- src/blocks/__stories__/Alert.docs.mdx | 24 +++---- src/blocks/__stories__/Alert.stories.tsx | 11 ++- src/blocks/__stories__/Message.docs.mdx | 24 +++---- src/blocks/__stories__/Message.stories.tsx | 12 +--- src/blocks/__stories__/Toast.docs.mdx | 24 +++---- src/blocks/__tests__/CommonMessage.test.tsx | 2 +- src/blocks/shared/CommonMessage.scss | 8 +-- src/blocks/shared/CommonMessage.tsx | 48 +++++++------ src/icons/Icon.scss | 31 ++++++--- src/icons/Icon.tsx | 7 +- src/icons/__stories__/Icon.stories.tsx | 75 ++++++++++++++++----- src/icons/__tests__/Icon.test.tsx | 8 +-- src/overlays/Overlay.tsx | 4 +- src/text/Tag.scss | 1 + src/text/__stories__/Tag.stories.tsx | 6 +- yarn.lock | 19 ++---- 30 files changed, 263 insertions(+), 184 deletions(-) diff --git a/package.json b/package.json index a129fba..e9c0b6a 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,8 @@ ], "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.3.0", - "@fortawesome/free-regular-svg-icons": "^6.3.0", - "@fortawesome/free-solid-svg-icons": "^6.3.0", "@fortawesome/react-fontawesome": "^0.2.0", + "@heroicons/react": "^2.0.18", "@types/markdown-to-jsx": "^6.11.2", "@types/mdx": "^2.0.3", "@types/node": "^16.7.13", diff --git a/src/actions/Button.scss b/src/actions/Button.scss index 485cf89..9f009cb 100644 --- a/src/actions/Button.scss +++ b/src/actions/Button.scss @@ -3,7 +3,7 @@ --button-font-family: var(--seeds-font-alt-sans); --button-font-weight: bold; --button-interior-gap: var(--seeds-s3); - --button-icon-size-percentage: 75%; + --button-icon-scale-factor: 0.85; --button-icon-side-padding: var(--seeds-s4); --button-padding-sm: calc(var(--seeds-s3_5) - var(--button-border-width)) @@ -212,7 +212,11 @@ } & > .seeds-icon { - font-size: var(--button-icon-size-percentage); + --icon-scale-factor: var(--button-icon-scale-factor); + } + + &[data-size="sm"] > .seeds-icon { + --icon-scale-factor: calc(var(--button-icon-scale-factor) * 1.15); } &:focus-visible { diff --git a/src/actions/Button.tsx b/src/actions/Button.tsx index 220372b..d2f0e2b 100644 --- a/src/actions/Button.tsx +++ b/src/actions/Button.tsx @@ -6,8 +6,7 @@ import { shouldShowExternalLinkIcon, } from "../global/NavigationContext" import Icon from "../icons/Icon" - -import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons" +import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/solid" import "./Button.scss" @@ -70,7 +69,9 @@ const setupButtonProps = (props: ButtonProps) => { const classNames = ["seeds-button"] const tailIcon = shouldShowExternalLinkIcon(props) ? ( - + + + ) : ( props.tailIcon ) diff --git a/src/actions/Link.scss b/src/actions/Link.scss index 7f8737c..aca790f 100644 --- a/src/actions/Link.scss +++ b/src/actions/Link.scss @@ -4,7 +4,7 @@ .seeds-link { --link-interior-gap: var(--seeds-s1); - --link-icon-size-percentage: 75%; + --link-icon-scale-factor: 0.85; display: inline-flex; gap: var(--link-interior-gap); @@ -14,6 +14,6 @@ } & > .seeds-icon { - font-size: var(--link-icon-size-percentage); + --icon-scale-factor: var(--link-icon-scale-factor); } } diff --git a/src/actions/Link.tsx b/src/actions/Link.tsx index f4c4c45..4da35ed 100644 --- a/src/actions/Link.tsx +++ b/src/actions/Link.tsx @@ -5,9 +5,8 @@ import { isExternalLink, shouldShowExternalLinkIcon, } from "../global/NavigationContext" - import Icon from "../icons/Icon" -import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons" +import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/solid" import "./Link.scss" @@ -38,7 +37,7 @@ const Link = (props: LinkProps) => { const classNames = ["seeds-link"] const tailIcon = shouldShowExternalLinkIcon(props) ? ( - + ) : ( props.tailIcon ) diff --git a/src/actions/__stories__/Button.docs.mdx b/src/actions/__stories__/Button.docs.mdx index 8e51cd0..3222f26 100644 --- a/src/actions/__stories__/Button.docs.mdx +++ b/src/actions/__stories__/Button.docs.mdx @@ -9,20 +9,20 @@ import Button from "../Button" ## Theme Variables -| Name | Description | Default | -| ------------------------------- | ----------------------------------------- | ----------------------- | -| `--button-border-width` | Border width | `--seeds-border-2` | -| `--button-font-family` | Font family | `--seeds-font-alt-sans` | -| `--button-font-weight` | Font weight | `none` | -| `--button-interior-gap` | Space between icons/text | `--seeds-s3` | -| `--button-icon-size-percentage` | Relative size to base font | `75%` | -| `--button-icon-side-padding` | Space between an icon and the button edge | `--seeds-s4` | -| `--button-padding-sm` | Small button padding | | -| `--button-font-size-sm` | Small button font size | `--seeds-font-size-sm` | -| `--button-border-radius-sm` | Small button border radius | `--seeds-rounded` | -| `--button-padding-md` | Medium button padding | | -| `--button-font-size-md` | Medium button font size | `--seeds-font-size-md` | -| `--button-border-radius-md` | Medium button border radius | `--seeds-rounded` | -| `--button-padding-lg` | Large button padding | | -| `--button-font-size-lg` | Large button font size | `--seeds-font-size-lg` | -| `--button-border-radius-lg` | Large button border radius | `--seeds-rounded` | +| Name | Description | Default | +| ---------------------------- | ----------------------------------------- | ----------------------- | +| `--button-border-width` | Border width | `--seeds-border-2` | +| `--button-font-family` | Font family | `--seeds-font-alt-sans` | +| `--button-font-weight` | Font weight | `none` | +| `--button-interior-gap` | Space between icons/text | `--seeds-s3` | +| `--button-icon-scale-factor` | Integer | `0.85` | +| `--button-icon-side-padding` | Space between an icon and the button edge | `--seeds-s4` | +| `--button-padding-sm` | Small button padding | | +| `--button-font-size-sm` | Small button font size | `--seeds-font-size-sm` | +| `--button-border-radius-sm` | Small button border radius | `--seeds-rounded` | +| `--button-padding-md` | Medium button padding | | +| `--button-font-size-md` | Medium button font size | `--seeds-font-size-md` | +| `--button-border-radius-md` | Medium button border radius | `--seeds-rounded` | +| `--button-padding-lg` | Large button padding | | +| `--button-font-size-lg` | Large button font size | `--seeds-font-size-lg` | +| `--button-border-radius-lg` | Large button border radius | `--seeds-rounded` | diff --git a/src/actions/__stories__/Button.stories.tsx b/src/actions/__stories__/Button.stories.tsx index 991fac6..f6fcc95 100644 --- a/src/actions/__stories__/Button.stories.tsx +++ b/src/actions/__stories__/Button.stories.tsx @@ -3,7 +3,7 @@ import React from "react" import Button from "../Button" import Icon from "../../icons/Icon" -import { faHeart } from "@fortawesome/free-solid-svg-icons" +import { HeartIcon } from "@heroicons/react/24/solid" import MDXDocs from "./Button.docs.mdx" import HeadingGroup from "../../text/HeadingGroup" @@ -163,8 +163,24 @@ export const linkButtons = () => ( export const buttonsWithIcons = () => (
- - + +
) @@ -177,10 +193,24 @@ export const textButtons = () => (
- -
diff --git a/src/actions/__stories__/Link.docs.mdx b/src/actions/__stories__/Link.docs.mdx index 50f3329..28af48f 100644 --- a/src/actions/__stories__/Link.docs.mdx +++ b/src/actions/__stories__/Link.docs.mdx @@ -9,7 +9,7 @@ import Link from "../Link" ## Theme Variables -| Name | Description | Default | -| ----------------------------- | -------------------------- | ------------ | -| `--link-interior-gap` | Space between icons/text | `--seeds-s1` | -| `--link-icon-size-percentage` | Relative size to base font | `75%` | +| Name | Description | Default | +| -------------------------- | ------------------------ | ------------ | +| `--link-interior-gap` | Space between icons/text | `--seeds-s1` | +| `--link-icon-scale-factor` | Integer | `0.85` | diff --git a/src/actions/__stories__/Link.stories.tsx b/src/actions/__stories__/Link.stories.tsx index 8623508..cb27a41 100644 --- a/src/actions/__stories__/Link.stories.tsx +++ b/src/actions/__stories__/Link.stories.tsx @@ -3,7 +3,7 @@ import React from "react" import Link from "../Link" import Icon from "../../icons/Icon" -import { faHeart } from "@fortawesome/free-solid-svg-icons" +import { HeartIcon } from "@heroicons/react/24/solid" import MDXDocs from "./Link.docs.mdx" @@ -37,10 +37,10 @@ export const externalLink = () => ( export const linksWithIcons = () => (
- }> + }> Lead Icon - }> + }> Tail Icon
diff --git a/src/actions/__tests__/Button.test.tsx b/src/actions/__tests__/Button.test.tsx index 38202c0..77d9ad0 100644 --- a/src/actions/__tests__/Button.test.tsx +++ b/src/actions/__tests__/Button.test.tsx @@ -2,7 +2,7 @@ import { render, cleanup, fireEvent } from "@testing-library/react" import Button from "../Button" import Icon from "../../icons/Icon" -import { faHeart } from "@fortawesome/free-solid-svg-icons" +import { HeartIcon } from "@heroicons/react/24/solid" afterEach(cleanup) @@ -45,19 +45,19 @@ describe(" ) expect(getByRole("link", { name: content })).toHaveAttribute("href", "https://example.com") - expect(container.querySelector("svg[data-icon='heart']")).toBeVisible() + expect(container.querySelector("svg")).toBeVisible() }) it("displays external links with no icon", () => { diff --git a/src/actions/__tests__/Link.test.tsx b/src/actions/__tests__/Link.test.tsx index e593e91..78fba4f 100644 --- a/src/actions/__tests__/Link.test.tsx +++ b/src/actions/__tests__/Link.test.tsx @@ -2,7 +2,7 @@ import { render, cleanup } from "@testing-library/react" import Link from "../Link" import Icon from "../../icons/Icon" -import { faHeart } from "@fortawesome/free-solid-svg-icons" +import { HeartIcon } from "@heroicons/react/24/solid" afterEach(cleanup) @@ -32,19 +32,19 @@ describe("", () => { "href", "https://example.com" ) - expect(container.querySelector("svg[data-icon='arrow-up-right-from-square']")).toBeVisible() + expect(container.querySelector("svg")).toBeVisible() }) it("displays external links with a custom icon", () => { const content = "Button Label" const { getByRole, container } = render( - }> +
}> {content} ) expect(getByRole("link", { name: content })).toHaveAttribute("href", "https://example.com") - expect(container.querySelector("svg[data-icon='heart']")).toBeVisible() + expect(container.querySelector("svg[class='hero-icon']")).toBeVisible() }) it("displays external links with no icon", () => { diff --git a/src/blocks/Alert.scss b/src/blocks/Alert.scss index e3664f8..04dd50a 100644 --- a/src/blocks/Alert.scss +++ b/src/blocks/Alert.scss @@ -3,7 +3,7 @@ --alert-border-radius: 0; --alert-border: none; --alert-flex-gap: var(--seeds-s3); - --alert-icon-size: 1em; + --alert-icon-scale-factor: 1; --alert-max-width: var(--seeds-width-sm); --alert-font: var(--seeds-font-sans); --alert-font-size: var(--seeds-type-caption-size); @@ -14,7 +14,7 @@ --common-message-border-radius: var(--alert-border-radius); --common-message-border: var(--alert-border); --common-message-flex-gap: var(--alert-flex-gap); - --common-message-icon-size: var(--alert-icon-size); + --common-message-icon-scale-factor: var(--alert-icon-scale-factor); --common-message-max-width: var(--alert-max-width); --common-message-font: var(--alert-font); --common-message-font-size: var(--alert-font-size); diff --git a/src/blocks/Message.scss b/src/blocks/Message.scss index 1a81896..9791ba5 100644 --- a/src/blocks/Message.scss +++ b/src/blocks/Message.scss @@ -3,7 +3,7 @@ --message-border-radius: 0; --message-border: none; --message-flex-gap: var(--seeds-s3); - --message-icon-size: 1em; + --message-icon-scale-factor: 1; --message-max-width: var(--seeds-width-sm); --message-font: var(--seeds-font-sans); --message-font-size: var(--seeds-type-caption-size); @@ -14,7 +14,7 @@ --common-message-border-radius: var(--message-border-radius); --common-message-border: var(--message-border); --common-message-flex-gap: var(--message-flex-gap); - --common-message-icon-size: var(--message-icon-size); + --common-message-icon-scale-factor: var(--message-icon-scale-factor); --common-message-max-width: var(--message-max-width); --common-message-font: var(--message-font); --common-message-font-size: var(--message-font-size); diff --git a/src/blocks/Toast.scss b/src/blocks/Toast.scss index 7600a24..f326d6b 100644 --- a/src/blocks/Toast.scss +++ b/src/blocks/Toast.scss @@ -20,7 +20,7 @@ --toast-border-radius: 0; --toast-border: none; --toast-flex-gap: var(--seeds-s3); - --toast-icon-size: 1em; + --toast-icon-scale-factor: 1; --toast-max-width: var(--seeds-width-sm); --toast-font: var(--seeds-font-sans); --toast-font-size: var(--seeds-type-caption-size); @@ -31,7 +31,7 @@ --common-message-border-radius: var(--toast-border-radius); --common-message-border: var(--toast-border); --common-message-flex-gap: var(--toast-flex-gap); - --common-message-icon-size: var(--toast-icon-size); + --common-message-icon-scale-factor: var(--toast-icon-scale-factor); --common-message-max-width: var(--toast-max-width); --common-message-font: var(--toast-font); --common-message-font-size: var(--toast-font-size); diff --git a/src/blocks/__stories__/Alert.docs.mdx b/src/blocks/__stories__/Alert.docs.mdx index 1067bc4..e2c3c01 100644 --- a/src/blocks/__stories__/Alert.docs.mdx +++ b/src/blocks/__stories__/Alert.docs.mdx @@ -9,15 +9,15 @@ import Alert from "../Alert" ## Theme Variables -| Name | Description | Default | -| -------------------------- | ----------------------------- | ------------------------------ | -| `--alert-padding` | Interior spacing | `--seeds-s4` | -| `--alert-border-radius` | Radius | `0` | -| `--alert-border` | Border shorthand | `none` | -| `--alert-flex-gap` | Space between icons/text | `--seeds-s3` | -| `--alert-icon-size` | Size | `1em` | -| `--alert-max-width` | Size | `--seeds-width-sm` | -| `--alert-font` | Font | `--seeds-font-sans` | -| `--alert-font-size` | Component font size | `--seeds-type-caption-size` | -| `--alert-link-gap` | Space between text and a link | `--seeds-s1` | -| `--alert-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | +| Name | Description | Default | +| --------------------------- | ----------------------------- | ------------------------------ | +| `--alert-padding` | Interior spacing | `--seeds-s4` | +| `--alert-border-radius` | Radius | `0` | +| `--alert-border` | Border shorthand | `none` | +| `--alert-flex-gap` | Space between icons/text | `--seeds-s3` | +| `--alert-icon-scale-factor` | Integer | `1` | +| `--alert-max-width` | Size | `--seeds-width-sm` | +| `--alert-font` | Font | `--seeds-font-sans` | +| `--alert-font-size` | Component font size | `--seeds-type-caption-size` | +| `--alert-link-gap` | Space between text and a link | `--seeds-s1` | +| `--alert-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | diff --git a/src/blocks/__stories__/Alert.stories.tsx b/src/blocks/__stories__/Alert.stories.tsx index 4b7c52e..042a000 100644 --- a/src/blocks/__stories__/Alert.stories.tsx +++ b/src/blocks/__stories__/Alert.stories.tsx @@ -3,7 +3,7 @@ import { Story } from "@storybook/react" import Alert from "../Alert" import Icon from "../../icons/Icon" -import { faHouseChimney } from "@fortawesome/free-solid-svg-icons" +import { HomeModernIcon } from "@heroicons/react/24/solid" import MDXDocs from "./Alert.docs.mdx" @@ -40,7 +40,14 @@ export const inverseVariants = () => ( ) export const withCustomIcon = () => ( - }> + + +
+ } + > A custom icon (house-chimney) ) diff --git a/src/blocks/__stories__/Message.docs.mdx b/src/blocks/__stories__/Message.docs.mdx index 5b5bfb0..d1dd3c5 100644 --- a/src/blocks/__stories__/Message.docs.mdx +++ b/src/blocks/__stories__/Message.docs.mdx @@ -9,15 +9,15 @@ import Message from "../Message" ## Theme Variables -| Name | Description | Default | -| ---------------------------- | ----------------------------- | ------------------------------ | -| `--message-padding` | Interior spacing | `--seeds-s4` | -| `--message-border-radius` | Radius | `0` | -| `--message-border` | Border shorthand | `none` | -| `--message-flex-gap` | Space between icons/text | `--seeds-s3` | -| `--message-icon-size` | Size | `1em` | -| `--message-max-width` | Size | `--seeds-width-sm` | -| `--message-font` | Font | `--seeds-font-sans` | -| `--message-font-size` | Component font size | `--seeds-type-caption-size` | -| `--message-link-gap` | Space between text and a link | `--seeds-s1` | -| `--message-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | +| Name | Description | Default | +| ----------------------------- | ----------------------------- | ------------------------------ | +| `--message-padding` | Interior spacing | `--seeds-s4` | +| `--message-border-radius` | Radius | `0` | +| `--message-border` | Border shorthand | `none` | +| `--message-flex-gap` | Space between icons/text | `--seeds-s3` | +| `--message-icon-scale-factor` | Integer | `1` | +| `--message-max-width` | Size | `--seeds-width-sm` | +| `--message-font` | Font | `--seeds-font-sans` | +| `--message-font-size` | Component font size | `--seeds-type-caption-size` | +| `--message-link-gap` | Space between text and a link | `--seeds-s1` | +| `--message-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | diff --git a/src/blocks/__stories__/Message.stories.tsx b/src/blocks/__stories__/Message.stories.tsx index bd15ef7..4364403 100644 --- a/src/blocks/__stories__/Message.stories.tsx +++ b/src/blocks/__stories__/Message.stories.tsx @@ -3,7 +3,7 @@ import { Story } from "@storybook/react" import Message from "../Message" import Icon from "../../icons/Icon" -import { faClock } from "@fortawesome/free-regular-svg-icons" +import { ClockIcon } from "@heroicons/react/24/outline" import MDXDocs from "./Message.docs.mdx" @@ -19,17 +19,9 @@ export default { export const status = () => ( <> - }> + }> Application Due Date - - ) diff --git a/src/blocks/__stories__/Toast.docs.mdx b/src/blocks/__stories__/Toast.docs.mdx index eb3e8e1..88ff31f 100644 --- a/src/blocks/__stories__/Toast.docs.mdx +++ b/src/blocks/__stories__/Toast.docs.mdx @@ -9,18 +9,18 @@ import Toast from "../Toast" ## Theme Variables -| Name | Description | Default | -| -------------------------- | ----------------------------- | ------------------------------ | -| `--toast-padding` | Interior spacing | `--seeds-s4` | -| `--toast-border-radius` | Radius | `0` | -| `--toast-border` | Border shorthand | `none` | -| `--toast-flex-gap` | Space between icons/text | `--seeds-s3` | -| `--toast-icon-size` | Size | `1em` | -| `--toast-max-width` | Size | `--seeds-width-sm` | -| `--toast-font` | Font | `--seeds-font-sans` | -| `--toast-font-size` | Component font size | `--seeds-type-caption-size` | -| `--toast-link-gap` | Space between text and a link | `--seeds-s1` | -| `--toast-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | +| Name | Description | Default | +| --------------------------- | ----------------------------- | ------------------------------ | +| `--toast-padding` | Interior spacing | `--seeds-s4` | +| `--toast-border-radius` | Radius | `0` | +| `--toast-border` | Border shorthand | `none` | +| `--toast-flex-gap` | Space between icons/text | `--seeds-s3` | +| `--toast-icon-scale-factor` | Integer | `1` | +| `--toast-max-width` | Size | `--seeds-width-sm` | +| `--toast-font` | Font | `--seeds-font-sans` | +| `--toast-font-size` | Component font size | `--seeds-type-caption-size` | +| `--toast-link-gap` | Space between text and a link | `--seeds-s1` | +| `--toast-link-font-weight` | Font weight | `--seeds-font-weight-semibold` | In addition, there are a set of variables you can customize via `#toast-stack` which affects the fixed container within which toasts are rendered: diff --git a/src/blocks/__tests__/CommonMessage.test.tsx b/src/blocks/__tests__/CommonMessage.test.tsx index b4486c7..f3fc6cc 100644 --- a/src/blocks/__tests__/CommonMessage.test.tsx +++ b/src/blocks/__tests__/CommonMessage.test.tsx @@ -28,7 +28,7 @@ describe("", () => { expect(container.querySelector("#test-id.test-class")).not.toBeNull() expect(container.querySelector("#test-id[data-variant=warn]")).not.toBeNull() expect(container.querySelector("button[aria-label=Close]")).not.toBeNull() - expect(container.querySelector("svg.fa-clock")).not.toBeNull() + expect(container.querySelector("svg")).not.toBeNull() }) it("supports a custom onClose callback", () => { diff --git a/src/blocks/shared/CommonMessage.scss b/src/blocks/shared/CommonMessage.scss index 2149094..006cff1 100644 --- a/src/blocks/shared/CommonMessage.scss +++ b/src/blocks/shared/CommonMessage.scss @@ -5,7 +5,7 @@ --common-message-border-radius: 0; --common-message-border: none; --common-message-flex-gap: var(--seeds-s3); - --common-message-icon-size: 1em; + --common-message-icon-scale-factor: 1; --common-message-max-width: var(--seeds-width-sm); --common-message-font: var(--seeds-font-sans); --common-message-font-size: var(--seeds-type-caption-size); @@ -15,6 +15,7 @@ padding: var(--common-message-padding); display: flex; align-items: center; + line-height: var(--seeds-line-height-4); gap: var(--common-message-flex-gap); max-width: var(--common-message-max-width); font-family: var(--common-message-font); @@ -94,9 +95,8 @@ border: none; } - .icon { - font-size: var(--common-message-icon-size); - margin-block-start: -0.15em; /* Slightly adjust flex alignment */ + .seeds-icon { + --icon-scale-factor: var(--common-message-icon-scale-factor); } a { diff --git a/src/blocks/shared/CommonMessage.tsx b/src/blocks/shared/CommonMessage.tsx index 4aa1993..af21610 100644 --- a/src/blocks/shared/CommonMessage.tsx +++ b/src/blocks/shared/CommonMessage.tsx @@ -1,29 +1,28 @@ import React, { forwardRef } from "react" import { - faCheck, - faClock, - faClose, - faInfoCircle, - faLock, - faTriangleExclamation, - IconDefinition, -} from "@fortawesome/free-solid-svg-icons" + CheckIcon, + ClockIcon, + XMarkIcon, + InformationCircleIcon, + LockClosedIcon, + ExclamationTriangleIcon, +} from "@heroicons/react/20/solid" import Icon from "../../icons/Icon" import useToggle from "../../hooks/useToggle" import "./CommonMessage.scss" -const CommonMessageIconMap: Record = { - primary: faInfoCircle, - "primary-inverse": faInfoCircle, - success: faCheck, - "success-inverse": faCheck, - alert: faTriangleExclamation, - "alert-inverse": faTriangleExclamation, - warn: faClock, - "warn-inverse": faClock, - secondary: faLock, - "secondary-inverse": faLock, +const CommonMessageIconMap: Record = { + primary: InformationCircleIcon, + "primary-inverse": InformationCircleIcon, + success: CheckIcon, + "success-inverse": CheckIcon, + alert: ExclamationTriangleIcon, + "alert-inverse": ExclamationTriangleIcon, + warn: ClockIcon, + "warn-inverse": ClockIcon, + secondary: LockClosedIcon, + "secondary-inverse": LockClosedIcon, } export interface CommonMessageProps { @@ -69,6 +68,7 @@ const CommonMessage = forwardRef( if (props.className) classNames.push(props.className) const variant = props.variant || "primary" + const VariantIcon = CommonMessageIconMap[variant] return props.children ? (
{props.customIcon ? props.customIcon - : CommonMessageIconMap[variant] && ( - + : VariantIcon && ( + + + )} {props.children} {props.closeable && ( @@ -97,7 +99,9 @@ const CommonMessage = forwardRef( } }} > - + + + )}
diff --git a/src/icons/Icon.scss b/src/icons/Icon.scss index b6d54ab..0f623b7 100644 --- a/src/icons/Icon.scss +++ b/src/icons/Icon.scss @@ -1,20 +1,22 @@ .seeds-icon { - --icon-sm: 0.75rem; + --icon-scale-factor: 1.0; + + --icon-sm: var(--seeds-s3_5); --icon-sm-alignment: -0.05rem; - --icon-md: 1rem; + --icon-md: var(--seeds-s5); --icon-md-alignment: -0.125rem; - --icon-lg: 1.5rem; - --icon-lg-alignment: -0.5rem; - --icon-xl: 2.5rem; - --icon-xl-alignment: -0.75rem; - --icon-2xl: 3rem; - --icon-2xl-alignment: -1rem; - --icon-height: 1em; - --icon-alignment: -0.125em; + --icon-lg: var(--seeds-s7); + --icon-lg-alignment: -0.35rem; + --icon-xl: var(--seeds-s11); + --icon-xl-alignment: -0.95rem; + --icon-2xl: var(--seeds-s14); + --icon-2xl-alignment: -1.25rem; + --icon-height: 1.15em; + --icon-alignment: -0.25em; display: inline-block; vertical-align: var(--icon-alignment); - height: var(--icon-height); + height: calc(var(--icon-height) * var(--icon-scale-factor)); &[data-size="sm"] { --icon-height: var(--icon-sm); @@ -46,5 +48,12 @@ display: block; height: 100%; aspect-ratio: 1 / 1; +} + +.seeds-icon:not([data-outlined]) svg { fill: currentColor; } + +.seeds-icon[data-outlined] svg { + stroke: currentColor; +} diff --git a/src/icons/Icon.tsx b/src/icons/Icon.tsx index b82b5c6..eeb3218 100644 --- a/src/icons/Icon.tsx +++ b/src/icons/Icon.tsx @@ -11,13 +11,15 @@ export interface IconProps { className?: string /** Specify a specific preset size */ size?: "sm" | "md" | "lg" | "xl" | "2xl" + /** Set this to true for icons which only use outlined paths */ + outlined?: boolean "aria-hidden"?: boolean "aria-label"?: string "aria-labelledby"?: string tabIndex?: number - /** Icon SVG metadata imported from Font Awesome */ + /** DEPRECATED: Icon SVG metadata imported from Font Awesome */ icon?: IconDefinition - /** Custom SVG in JSX if not using Font Awesome */ + /** Custom SVG in JSX */ children?: React.ReactNode } @@ -31,6 +33,7 @@ const Icon = (props: IconProps) => { id={props.id} className={classNames.join(" ")} data-size={props.size} + data-outlined={props.outlined} aria-hidden={isHidden} aria-label={props["aria-label"]} aria-labelledby={props["aria-labelledby"]} diff --git a/src/icons/__stories__/Icon.stories.tsx b/src/icons/__stories__/Icon.stories.tsx index fe446fb..7f31ce5 100644 --- a/src/icons/__stories__/Icon.stories.tsx +++ b/src/icons/__stories__/Icon.stories.tsx @@ -1,11 +1,11 @@ import React from "react" import { Story } from "@storybook/react" -import { faHouseChimney } from "@fortawesome/free-solid-svg-icons" -import { faEnvelope } from "@fortawesome/free-regular-svg-icons" -import { faDoorOpen } from "@fortawesome/free-solid-svg-icons" -import { faPhone } from "@fortawesome/free-solid-svg-icons" -import { faCircleUser } from "@fortawesome/free-regular-svg-icons" +import { HomeModernIcon } from "@heroicons/react/24/solid" +import { EnvelopeIcon } from "@heroicons/react/24/outline" +import { BookOpenIcon } from "@heroicons/react/24/solid" +import { PhoneIcon } from "@heroicons/react/24/solid" +import { UserCircleIcon } from "@heroicons/react/24/outline" import Icon, { IconProps } from "../Icon" @@ -34,19 +34,34 @@ export default { const Template: Story = ({ size }) => ( <>
- house-chimney + + + {" "} + home-modern
- envelope + + + {" "} + envelope
- door-open + + + {" "} + book-open
- phone + + + {" "} + phone
- circle-user + + + {" "} + user-circle
) @@ -60,13 +75,22 @@ icons.args = { export const containerBasedSizes = () => ( <>
- door-open + + + {" "} + book-open
- door-open + + + {" "} + book-open
- door-open + + + {" "} + book-open
) @@ -74,19 +98,34 @@ export const containerBasedSizes = () => ( export const presetSizes = () => ( <>
- house-chimney (sm) + + + {" "} + home-modern (sm)
- house-chimney (md) + + + {" "} + home-modern (md)
- house-chimney (lg) + + + {" "} + home-modern (lg)
- house-chimney (xl) + + + {" "} + home-modern (xl)
- house-chimney (2xl) + + + {" "} + home-modern (2xl)
) diff --git a/src/icons/__tests__/Icon.test.tsx b/src/icons/__tests__/Icon.test.tsx index f4827b4..6a45fac 100644 --- a/src/icons/__tests__/Icon.test.tsx +++ b/src/icons/__tests__/Icon.test.tsx @@ -1,26 +1,26 @@ import { render, cleanup } from "@testing-library/react" import Icon from "../Icon" -import { faCoffee } from "@fortawesome/free-solid-svg-icons" +import { BookOpenIcon } from "@heroicons/react/24/solid" afterEach(cleanup) describe("", () => { it("displays the icon", () => { - const { getByText, container } = render() + const { container } = render() expect(container.querySelector("#icn")).not.toBeNull() expect(container.querySelector("#icn.test-class")).not.toBeNull() expect(container.querySelector("#icn svg")).not.toBeNull() }) it("supports different sizes", () => { - const { getByText, container } = render() + const { container } = render() expect(container.querySelector("#icn")).not.toBeNull() expect(container.querySelector("#icn[data-size='md']")).not.toBeNull() expect(container.querySelector("#icn svg")).not.toBeNull() }) it("displays SVG child content", () => { - const { getByText, container } = render() + const { container } = render() expect(container.querySelector("#icn")).not.toBeNull() expect(container.querySelector("#icn.test-class")).not.toBeNull() expect(container.querySelector("#icn svg")).not.toBeNull() diff --git a/src/overlays/Overlay.tsx b/src/overlays/Overlay.tsx index 35b220e..6b19c09 100644 --- a/src/overlays/Overlay.tsx +++ b/src/overlays/Overlay.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef, useId } from "react" import { createPortal } from "react-dom" import FocusTrap from "focus-trap-react" -import { faXmark } from "@fortawesome/free-solid-svg-icons" +import { XMarkIcon } from "@heroicons/react/20/solid" import Icon from "../icons/Icon" import Heading from "../text/Heading" import usePortal from "../hooks/usePortal" @@ -30,7 +30,7 @@ const OverlayHeader = (props: OverlayHeaderProps) => { const closeButton = ( ) diff --git a/src/text/Tag.scss b/src/text/Tag.scss index 1ad7a84..498deae 100644 --- a/src/text/Tag.scss +++ b/src/text/Tag.scss @@ -9,6 +9,7 @@ --tag-font-weight-lg: var(--seeds-font-weight-semibold); display: inline-flex; + align-items: center; border-radius: var(--tag-border-radius); padding-inline: var(--tag-padding-inline); padding-block: var(--tag-padding-block); diff --git a/src/text/__stories__/Tag.stories.tsx b/src/text/__stories__/Tag.stories.tsx index 147d08a..534f4fa 100644 --- a/src/text/__stories__/Tag.stories.tsx +++ b/src/text/__stories__/Tag.stories.tsx @@ -3,7 +3,7 @@ import React from "react" import Tag from "../Tag" import Icon from "../../icons/Icon" -import { faFaceSmile } from "@fortawesome/free-solid-svg-icons" +import { FaceSmileIcon } from "@heroicons/react/20/solid" import MDXDocs from "./Tag.docs.mdx" import HeadingGroup from "../HeadingGroup" @@ -88,10 +88,10 @@ export const withIcons = () => ( <>
- Icon Left + Icon Left - Icon Right + Icon Right
diff --git a/yarn.lock b/yarn.lock index 66349c3..8d72d0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1417,20 +1417,6 @@ dependencies: "@fortawesome/fontawesome-common-types" "6.3.0" -"@fortawesome/free-regular-svg-icons@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz#286f87f777e6c96af59151e86647c81083029ee2" - integrity sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg== - dependencies: - "@fortawesome/fontawesome-common-types" "6.3.0" - -"@fortawesome/free-solid-svg-icons@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz#d3bd33ae18bb15fdfc3ca136e2fea05f32768a65" - integrity sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA== - dependencies: - "@fortawesome/fontawesome-common-types" "6.3.0" - "@fortawesome/react-fontawesome@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" @@ -1443,6 +1429,11 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@heroicons/react@^2.0.18": + version "2.0.18" + resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.0.18.tgz#f80301907c243df03c7e9fd76c0286e95361f7c1" + integrity sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw== + "@humanwhocodes/config-array@^0.11.6": version "0.11.7" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f"