mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-25 05:02:57 +01:00
Ensure the Icon react component can support custom icon paths #11122
- When provided with children (e.g. custom paths), render these instead of the `use` symbol reference - Allow any valid SVG attribute to be passed to the component to render on the `svg` element - Clean up rendering of className to avoid extra whitespace - Clean up ordering of the props to be alphabetically sorted - Update unit tests to be focused more on testing and less on snapshots
This commit is contained in:
parent
d2f476c050
commit
c611dd4056
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
import Icon from './Icon';
|
||||
|
||||
describe('Icon', () => {
|
||||
@ -7,15 +7,53 @@ describe('Icon', () => {
|
||||
expect(Icon).toBeDefined();
|
||||
});
|
||||
|
||||
it('#name', () => {
|
||||
expect(shallow(<Icon name="test" />)).toMatchSnapshot();
|
||||
it('should support icons with a name', () => {
|
||||
const wrapper = mount(<Icon name="test" />);
|
||||
|
||||
expect(wrapper.find('.icon.icon-test')).toHaveLength(1);
|
||||
expect(wrapper.find('use[href="#icon-test"]')).toHaveLength(1);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('#className', () => {
|
||||
expect(shallow(<Icon name="test" className="u-test" />)).toMatchSnapshot();
|
||||
it('should support children in place of the icon use#name', () => {
|
||||
const wrapper = shallow(
|
||||
<icon name="example">
|
||||
<rect
|
||||
x="10"
|
||||
y="10"
|
||||
width="30"
|
||||
height="30"
|
||||
stroke="black"
|
||||
fill="transparent"
|
||||
strokeWidth="5"
|
||||
/>
|
||||
</icon>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('use')).toHaveLength(0);
|
||||
expect(wrapper.find('rect')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('#title', () => {
|
||||
expect(shallow(<Icon name="test" title="Test title" />)).toMatchSnapshot();
|
||||
it('should support a className prop', () => {
|
||||
const wrapper = mount(<Icon name="test" className="u-test" />);
|
||||
|
||||
expect(wrapper.find('.icon.u-test')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should support other svg attributes', () => {
|
||||
const wrapper = mount(<Icon name="test" viewBox="0 0 1024 1024" />);
|
||||
|
||||
expect(wrapper.find('svg').prop('viewBox')).toBe('0 0 1024 1024');
|
||||
});
|
||||
|
||||
it('should support a title that is output as a sibling of the title', () => {
|
||||
const wrapper = mount(<Icon name="test" title="Test title" />);
|
||||
|
||||
const title = wrapper.find('svg.icon ~ span');
|
||||
expect(title).toHaveLength(1);
|
||||
|
||||
expect(title.text()).toBe('Test title');
|
||||
expect(title.hasClass('w-sr-only')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IconProps {
|
||||
name: string;
|
||||
export interface IconProps extends React.SVGProps<SVGSVGElement> {
|
||||
/** Optional svg `path` instead of the `use` based on the icon name. */
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
name: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
@ -10,13 +12,21 @@ export interface IconProps {
|
||||
* Provide a `title` as an accessible label intended for screen readers.
|
||||
*/
|
||||
const Icon: React.FunctionComponent<IconProps> = ({
|
||||
name,
|
||||
children,
|
||||
className,
|
||||
name,
|
||||
title,
|
||||
...props
|
||||
}) => (
|
||||
<>
|
||||
<svg className={`icon icon-${name} ${className || ''}`} aria-hidden="true">
|
||||
<use href={`#icon-${name}`} />
|
||||
<svg
|
||||
{...props}
|
||||
className={['icon', `icon-${name}`, className || '']
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{children || <use href={`#icon-${name}`} />}
|
||||
</svg>
|
||||
{title && <span className="w-sr-only">{title}</span>}
|
||||
</>
|
||||
|
@ -1,20 +1,9 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Icon #className 1`] = `
|
||||
<Fragment>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="icon icon-test u-test"
|
||||
exports[`Icon should support icons with a name 1`] = `
|
||||
<Icon
|
||||
name="test"
|
||||
>
|
||||
<use
|
||||
href="#icon-test"
|
||||
/>
|
||||
</svg>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Icon #name 1`] = `
|
||||
<Fragment>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="icon icon-test"
|
||||
@ -23,23 +12,5 @@ exports[`Icon #name 1`] = `
|
||||
href="#icon-test"
|
||||
/>
|
||||
</svg>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Icon #title 1`] = `
|
||||
<Fragment>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="icon icon-test "
|
||||
>
|
||||
<use
|
||||
href="#icon-test"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
className="w-sr-only"
|
||||
>
|
||||
Test title
|
||||
</span>
|
||||
</Fragment>
|
||||
</Icon>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user