Skip to content

Commit

Permalink
Merge pull request #3951 from Sage/FE-3550-styled-system-icon
Browse files Browse the repository at this point in the history
feat(icon): add support for styled-system margin interface FE-3550
  • Loading branch information
edleeks87 authored Apr 29, 2021
2 parents 53160e2 + 45ba4bd commit a7d76bd
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 83 deletions.
5 changes: 3 additions & 2 deletions src/components/accordion/accordion.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
import AccordionGroup from "./accordion-group.component";
import ValidationIcon from "../validations";
import StyledValidationIcon from "../validations/validation-icon.style";
import StyledIcon from "../icon/icon.style";

const contentHeight = 200;

Expand Down Expand Up @@ -462,7 +461,9 @@ describe("Accordion", () => {
{
marginLeft: "8px",
},
wrapper.find(StyledAccordionHeadingsContainer).find(StyledIcon)
wrapper
.find(StyledAccordionHeadingsContainer)
.find(StyledValidationIcon)
);
});
});
Expand Down
42 changes: 25 additions & 17 deletions src/components/help/help.component.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import React, { useState, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import styledSystemPropTypes from "@styled-system/prop-types";

import Icon from "../icon";
import tagComponent from "../../utils/helpers/tags";
import StyledHelp from "./help.style";
import Events from "../../utils/helpers/events/events";
import OptionsHelper from "../../utils/helpers/options-helper";
import { filterStyledSystemMarginProps } from "../../style/utils";

const marginPropTypes = filterStyledSystemMarginProps(
styledSystemPropTypes.space
);

const Help = (props) => {
const Help = ({
className,
href,
helpId,
children,
tabIndex,
as,
tooltipPosition,
isFocused,
type,
tooltipBgColor,
tooltipFontColor,
tooltipFlipOverrides,
...rest
}) => {
const helpElement = useRef(null);
const [isTooltipVisible, updateTooltipVisible] = useState(false);

const {
className,
href,
helpId,
children,
tabIndex,
as,
tooltipPosition,
isFocused,
type,
tooltipBgColor,
tooltipFontColor,
tooltipFlipOverrides,
} = props;

useEffect(() => {
document.addEventListener("keydown", handleKeyPress);

Expand Down Expand Up @@ -65,10 +71,11 @@ const Help = (props) => {
onBlur={handleFocusBlur(false)}
onMouseOver={handleFocusBlur(true)}
onMouseLeave={handleFocusBlur(false)}
{...tagComponent("help", props)}
{...tagComponent("help", rest)}
tabIndex={tabIndex}
value={children}
aria-label={children}
{...filterStyledSystemMarginProps(rest)}
>
<Icon
type={type}
Expand All @@ -84,6 +91,7 @@ const Help = (props) => {
};

Help.propTypes = {
...marginPropTypes,
/** [Legacy] A custom class name for the component. */
className: PropTypes.string,
/** Message to display in tooltip */
Expand Down
3 changes: 2 additions & 1 deletion src/components/help/help.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';
import { IconTypes, Positions } from "../../utils/helpers/options-helper/options-helper";
import { MarginSpacingProps } from "../../utils/helpers/options-helper";

export interface HelpProps {
export interface HelpProps extends MarginSpacingProps {
className?: string;
children?: string;
helpId?: string;
Expand Down
3 changes: 3 additions & 0 deletions src/components/help/help.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import Help from "./help.component";
import { rootTagTest } from "../../utils/helpers/tags/tags-specs";
import StyledHelp from "./help.style";
import Tooltip from "../tooltip";
import { testStyledSystemMargin } from "../../__spec_helper__/test-utils";

jest.mock("@tippyjs/react/headless");

describe("Help", () => {
let wrapper;

testStyledSystemMargin((props) => <Help {...props} />);

describe("when custom classes are passed", () => {
it("adds the custom classes", () => {
wrapper = renderHelp({ className: "fancy-pants" });
Expand Down
5 changes: 3 additions & 2 deletions src/components/help/help.stories.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import StyledSystemProps from '../../../.storybook/utils/styled-system-props';
import Help from '.';

<Meta title="Help" parameters={{ info: { disable: true }}} />
Expand Down Expand Up @@ -101,4 +102,4 @@ Using the `href` prop, a link can be specified.
## Props

### Help
<Props of={Help} />
<StyledSystemProps of={Help} noHeader margin/>
3 changes: 3 additions & 0 deletions src/components/help/help.style.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled, { css } from "styled-components";
import { margin } from "styled-system";
import baseTheme from "../../style/themes/base";
import StyledIcon from "../icon/icon.style";

Expand Down Expand Up @@ -31,6 +32,8 @@ const StyledHelp = styled.div`
&:focus ${StyledIcon} {
outline: ${({ theme }) => `2px solid ${theme.colors.focus}`};
}
${margin}
`;

StyledHelp.defaultProps = {
Expand Down
16 changes: 8 additions & 8 deletions src/components/icon/icon.component.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from "react";
import PropTypes from "prop-types";
import styledSystemPropTypes from "@styled-system/prop-types";
import tagComponent from "../../utils/helpers/tags";
import StyledIcon from "./icon.style";
import Tooltip from "../tooltip";
import { filterStyledSystemMarginProps } from "../../style/utils";

const marginPropTypes = filterStyledSystemMarginProps(
styledSystemPropTypes.space
);

const Icon = React.forwardRef(
(
Expand All @@ -17,8 +23,6 @@ const Icon = React.forwardRef(
fontSize,
iconColor,
type,
ml,
mr,
tooltipMessage,
tooltipPosition,
tooltipVisible,
Expand Down Expand Up @@ -61,10 +65,9 @@ const Icon = React.forwardRef(
disabled,
fontSize,
iconColor,
mr,
ml,
tabIndex,
type: iconType(),
...filterStyledSystemMarginProps(rest),
};

const icon = (
Expand Down Expand Up @@ -105,6 +108,7 @@ const Icon = React.forwardRef(
const placements = ["top", "bottom", "left", "right"];

Icon.propTypes = {
...marginPropTypes,
/**
* @private
* @ignore
Expand Down Expand Up @@ -141,10 +145,6 @@ Icon.propTypes = {
bg: PropTypes.string,
/** Sets the icon in the disabled state */
disabled: PropTypes.bool,
/** Margin right, given number will be multiplied by base spacing unit (8) */
mr: PropTypes.number,
/** Margin left, given number will be multiplied by base spacing unit (8) */
ml: PropTypes.number,
/** Aria label for accessibility purposes */
ariaLabel: PropTypes.string,
/** The message string to be displayed in the tooltip */
Expand Down
7 changes: 2 additions & 5 deletions src/components/icon/icon.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { Positions } from "../../utils/helpers/options-helper";
export interface IconProps {
import { MarginSpacingProps } from "../../utils/helpers/options-helper";
export interface IconProps extends MarginSpacingProps {
/** Icon type */
type: string;
/** Background size */
Expand All @@ -19,10 +20,6 @@ export interface IconProps {
bg?: string;
/** Sets the icon in the disabled state */
disabled?: boolean;
/** Margin right, given number will be multiplied by base spacing unit (8) */
mr?: number;
/** Margin left, given number will be multiplied by base spacing unit (8) */
ml?: number;
/** Aria label for accessibility purposes */
ariaLabel?: string;
/** The message string to be displayed in the tooltip */
Expand Down
33 changes: 6 additions & 27 deletions src/components/icon/icon.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { mount, shallow } from "enzyme";
import { shade } from "polished";

import { rootTagTest } from "../../utils/helpers/tags/tags-specs/tags-specs";
import { assertStyleMatch } from "../../__spec_helper__/test-utils";
import {
assertStyleMatch,
testStyledSystemMargin,
} from "../../__spec_helper__/test-utils";
import Icon from "./icon.component";
import StyledIcon from "./icon.style";
import OptionsHelper from "../../utils/helpers/options-helper";
Expand All @@ -28,6 +31,8 @@ function renderStyles(props) {
}

describe("Icon component", () => {
testStyledSystemMargin((props) => <Icon type="add" {...props} />);

const mismatchedPairs = [
{ prop: "help", rendersAs: "question" },
{ prop: "maintenance", rendersAs: "settings" },
Expand Down Expand Up @@ -333,32 +338,6 @@ describe("Icon component", () => {
});
});

describe("spacing props", () => {
describe("when mr prop is passed", () => {
it("renders with proper margin-right style", () => {
const wrapper = renderStyles({ mr: 2 });
assertStyleMatch(
{
marginRight: "16px",
},
wrapper.toJSON()
);
});
});

describe("when ml prop is passed", () => {
it("renders with proper margin-left style", () => {
const wrapper = renderStyles({ ml: 2 });
assertStyleMatch(
{
marginLeft: "16px",
},
wrapper.toJSON()
);
});
});
});

describe("background color", () => {
describe("when disabled", () => {
it("renders backgroundColor in a proper color", () => {
Expand Down
5 changes: 3 additions & 2 deletions src/components/icon/icon.stories.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks";
import { Meta, Story, Preview } from "@storybook/addon-docs/blocks";
import LinkTo from "@storybook/addon-links/react";
import StyledSystemProps from '../../../.storybook/utils/styled-system-props';

import Icon from "./";
import Box from "../box";
Expand Down Expand Up @@ -156,4 +157,4 @@ See <LinkTo kind='Documentation/Colors' name="page">Colors</LinkTo> for more inf
## Props

### Icon
<Props of={Icon} />
<StyledSystemProps of={Icon} noHeader margin />
12 changes: 2 additions & 10 deletions src/components/icon/icon.style.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import { shade } from "polished";
import { margin } from "styled-system";

import iconUnicodes from "./icon-unicodes";
import baseTheme from "../../style/themes/base";
Expand Down Expand Up @@ -100,8 +101,6 @@ const StyledIcon = styled.span`
type,
fontSize,
disabled,
mr,
ml,
}) => {
let finalColor;
let finalHoverColor;
Expand Down Expand Up @@ -185,14 +184,7 @@ const StyledIcon = styled.span`
display: block;
}
${ml &&
css`
margin-left: ${ml * theme.spacing}px;
`};
${mr &&
css`
margin-right: ${mr * theme.spacing}px;
`};
${margin}
`;
}}
`;
Expand Down
2 changes: 1 addition & 1 deletion src/components/portal/__snapshots__/portal.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ exports[`Portal when using default node to match snapshot 1`] = `
</span>
`;

exports[`Portal when using default node when an element with id 'root' does not exist will mount on body 1`] = `"<div id=\\"root\\"><div class=\\"carbon-portal\\" data-portal-exit=\\"guid-12345\\"><span class=\\"sc-bdVaJa hItwjy\\" data-element=\\"tick\\" data-component=\\"icon\\" font-size=\\"small\\" type=\\"tick\\"></span></div></div>"`;
exports[`Portal when using default node when an element with id 'root' does not exist will mount on body 1`] = `"<div id=\\"root\\"><div class=\\"carbon-portal\\" data-portal-exit=\\"guid-12345\\"><span class=\\"sc-bdVaJa jyaunv\\" data-element=\\"tick\\" data-component=\\"icon\\" font-size=\\"small\\" type=\\"tick\\"></span></div></div>"`;
17 changes: 9 additions & 8 deletions src/components/validations/validation-icon.component.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useContext } from "react";
import PropTypes from "prop-types";
import styledSystemPropTypes from "@styled-system/prop-types";

import Icon from "../icon";
import ValidationIconStyle from "./validation-icon.style";
Expand All @@ -8,6 +9,11 @@ import {
InputGroupContext,
} from "../../__internal__/input-behaviour";
import OptionsHelper from "../../utils/helpers/options-helper/options-helper";
import { filterStyledSystemMarginProps } from "../../style/utils";

const marginPropTypes = filterStyledSystemMarginProps(
styledSystemPropTypes.space
);

const getValidationType = ({ error, warning, info }) => {
if (error) return "error";
Expand All @@ -27,8 +33,7 @@ const ValidationIcon = ({
onClick,
tooltipPosition,
tooltipFlipOverrides,
ml,
mr,
...rest
}) => {
const { hasFocus, hasMouseOver } = useContext(InputContext);
const {
Expand Down Expand Up @@ -56,6 +61,7 @@ const ValidationIcon = ({
onMouseLeave={() => setTriggeredByIcon(false)}
onFocus={() => setTriggeredByIcon(true)}
onBlur={() => setTriggeredByIcon(false)}
{...filterStyledSystemMarginProps(rest)}
>
<Icon
key={`${validationType}-icon`}
Expand All @@ -77,14 +83,13 @@ const ValidationIcon = ({
}
isPartOfInput={isPartOfInput}
inputSize={size}
ml={ml}
mr={mr}
/>
</ValidationIconStyle>
);
};

ValidationIcon.propTypes = {
...marginPropTypes,
/** A small string to indicate the size of the icon */
size: PropTypes.oneOf(OptionsHelper.sizesRestricted),
/** The unique id of the component (used with aria-describedby for accessibility) */
Expand Down Expand Up @@ -119,10 +124,6 @@ ValidationIcon.propTypes = {
warning: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
/** Status of info */
info: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
/** Margin right, given number will be multiplied by base spacing unit (8) */
mr: PropTypes.number,
/** Margin left, given number will be multiplied by base spacing unit (8) */
ml: PropTypes.number,
};

ValidationIcon.defaultProps = {
Expand Down
Loading

0 comments on commit a7d76bd

Please sign in to comment.