Skip to content

Commit

Permalink
feat(Icon): migrate to Tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
DSil committed Feb 5, 2024
1 parent 59d30e7 commit 778bee5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 86 deletions.
20 changes: 10 additions & 10 deletions packages/orbit-components/src/Icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ After adding import into your project you can use it simply like:

Table below contains all types of the props available for icons in general.

| Name | Type | Default | Description |
| :----------- | :-------------- | :------------- | :--------------------------------------------------------------------- |
| className | `string` | | The optional className of Icon. |
| color | [`enum`](#enum) | `currentColor` | The color of the Icon. |
| customColor | `string` | | The customColor of the Icon. [See Functional specs](#functional-specs) |
| dataTest | `string` | | Optional prop for testing purposes. |
| **size** | [`enum`](#enum) | `"medium"` | The size of the Icon. |
| reverseOnRtl | `boolean` | `false` | If `true`, the icon will be reversed if `theme.rtl` is set to `true`. |
| ariaHidden | `boolean` | | Adds prop `aria-hidden` to an element, useful for screenreaders. |
| ariaLabel | `string` | | Adds prop `aria-label` to an element, useful for screenreaders. |
| Name | Type | Default | Description |
| :----------- | :-------------- | :------------- | :----------------------------------------------------------------------------------------- |
| className | `string` | | The optional className of Icon. |
| color | [`enum`](#enum) | `currentColor` | The color of the Icon. |
| customColor | `string` | | The customColor of the Icon, as valid CSS value. [See Functional specs](#functional-specs) |
| dataTest | `string` | | Optional prop for testing purposes. |
| **size** | [`enum`](#enum) | `"medium"` | The size of the Icon. |
| reverseOnRtl | `boolean` | `false` | If `true`, the icon will be reversed if `theme.rtl` is set to `true`. |
| ariaHidden | `boolean` | | Adds prop `aria-hidden` to an element, useful for screenreaders. |
| ariaLabel | `string` | | Adds prop `aria-label` to an element, useful for screenreaders. |

### enum

Expand Down
14 changes: 2 additions & 12 deletions packages/orbit-components/src/Icon/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,15 @@ import * as React from "react";

import { render, screen } from "../../test-utils";
import Accommodation from "../../icons/Accommodation";
import { ICON_SIZES, ICON_COLORS } from "../consts";
import defaultTheme from "../../defaultTheme";

describe("Icon", () => {
it("should have expected DOM output", () => {
render(
<Accommodation
size={ICON_SIZES.LARGE}
color={ICON_COLORS.PRIMARY}
dataTest="test"
ariaHidden
ariaLabel="Accommodation"
/>,
);
render(<Accommodation dataTest="test" ariaHidden ariaLabel="Accommodation" />);

expect(screen.getByTestId("test")).toBeInTheDocument();
const icon = screen.getByLabelText("Accommodation");
expect(icon.tagName.toLowerCase()).toBe("svg");
expect(icon).toHaveAttribute("aria-hidden", "true");
expect(icon).toHaveStyle({ color: defaultTheme.orbit.colorIconPrimary });
});

it("should support passing custom color", () => {
Expand Down
94 changes: 30 additions & 64 deletions packages/orbit-components/src/Icon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,25 @@
"use client";

import * as React from "react";
import styled, { css } from "styled-components";
import cx from "clsx";

import { ICON_SIZES, ICON_COLORS } from "./consts";
import defaultTheme from "../defaultTheme";
import type { GetSize, FactoryProps } from "./types";

export const getSize: GetSize =
size =>
({ theme }) => {
const tokens = {
[ICON_SIZES.SMALL]: theme.orbit.widthIconSmall,
[ICON_SIZES.MEDIUM]: theme.orbit.widthIconMedium,
[ICON_SIZES.LARGE]: theme.orbit.widthIconLarge,
[ICON_SIZES.SMALL]: theme.orbit.iconSmallSize,
[ICON_SIZES.MEDIUM]: theme.orbit.iconMediumSize,
[ICON_SIZES.LARGE]: theme.orbit.iconLargeSize,
};
return tokens[size] || tokens[ICON_SIZES.MEDIUM];
};

const getColor =
() =>
({ theme, color }) => {
const tokens = {
[ICON_COLORS.PRIMARY]: theme.orbit.colorIconPrimary,
[ICON_COLORS.SECONDARY]: theme.orbit.colorIconSecondary,
[ICON_COLORS.TERTIARY]: theme.orbit.colorIconTertiary,
[ICON_COLORS.INFO]: theme.orbit.colorIconInfo,
[ICON_COLORS.SUCCESS]: theme.orbit.colorIconSuccess,
[ICON_COLORS.WARNING]: theme.orbit.colorIconWarning,
[ICON_COLORS.CRITICAL]: theme.orbit.colorIconCritical,
};
return tokens[color];
};

const reverse = ({ reverseOnRtl, theme }) =>
reverseOnRtl &&
theme.rtl &&
css`
transform: scale(-1, 1);
`;

const StyledIcon = styled(({ className, viewBox, dataTest, children, ariaHidden, ariaLabel }) => (
<svg
className={className}
viewBox={viewBox}
data-test={dataTest}
preserveAspectRatio="xMidYMid meet"
aria-hidden={ariaHidden ? "true" : undefined}
aria-label={ariaLabel}
>
{children}
</svg>
))`
display: inline-block;
width: ${({ size }) => getSize(size)};
height: ${({ size }) => getSize(size)};
flex-shrink: 0;
vertical-align: middle;
fill: currentColor;
color: ${({ color, customColor }) => customColor || (color && getColor())};
${reverse};
`;

StyledIcon.defaultProps = {
theme: defaultTheme,
};

const OrbitIcon = (props: FactoryProps) => {
const {
size,
size = ICON_SIZES.MEDIUM,
color,
customColor,
className,
Expand All @@ -80,19 +31,34 @@ const OrbitIcon = (props: FactoryProps) => {
ariaLabel,
} = props;
return (
<StyledIcon
<svg
className={cx(
className,
"orbit-icon",
"inline-block shrink-0 fill-current align-middle",
reverseOnRtl && "rtl:-scale-x-100",
size === ICON_SIZES.SMALL && "size-icon-small",
size === ICON_SIZES.MEDIUM && "size-icon-medium",
size === ICON_SIZES.LARGE && "size-icon-large",
!customColor && [
color === ICON_COLORS.PRIMARY && "text-icon-primary-foreground",
color === ICON_COLORS.SECONDARY && "text-icon-secondary-foreground",
color === ICON_COLORS.TERTIARY && "text-icon-tertiary-foreground",
color === ICON_COLORS.INFO && "text-icon-info-foreground",
color === ICON_COLORS.SUCCESS && "text-icon-success-foreground",
color === ICON_COLORS.WARNING && "text-icon-warning-foreground",
color === ICON_COLORS.CRITICAL && "text-icon-critical-foreground",
],
)}
viewBox={viewBox}
size={size}
className={className}
dataTest={dataTest}
customColor={customColor}
color={color}
ariaHidden={ariaHidden}
reverseOnRtl={reverseOnRtl}
ariaLabel={ariaLabel}
preserveAspectRatio="xMidYMid meet"
data-test={dataTest}
aria-hidden={ariaHidden ? "true" : undefined}
aria-label={ariaLabel}
style={customColor ? { color: customColor } : {}}
>
{children}
</StyledIcon>
</svg>
);
};

Expand Down

0 comments on commit 778bee5

Please sign in to comment.