Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src-docs/src/views/icon/icon_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ import IconTypes from './icon_types';
const iconTypesSource = require('!!raw-loader!./icon_types');
const iconTypesSnippet = [`<EuiIcon type="logoElastic" size="xl" />`,
`<EuiIcon type={reactSVGElement} size="xl" />`,
`<EuiIcon type="https://upload.wikimedia.org/wikipedia/commons/9/9f/Vimlogo.svg" size="xl" />`,
`<EuiIcon type="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg" size="xl" />`,
`<EuiButton iconType={reactSVGElement}>Works in other components too</EuiButton>`];

export const IconExample = {
Expand Down Expand Up @@ -278,7 +278,8 @@ export const IconExample = {
text: (
<p>
The <EuiCode>type</EuiCode> prop can accept a valid enum, string or React SVG Element. When using a custom SVG, please make sure
it sits on a square canvas and preferably utilizes one of EUI&apos;s sizes (16x16, 32x32...etc).
it sits on a square canvas and preferably utilizes one of EUI&apos;s sizes (16x16, 32x32...etc). For IE11 compatibility, the SVG
file <em>must</em> contain a <EuiCode>viewBox</EuiCode>.
</p>
),
source: [{
Expand Down
4 changes: 2 additions & 2 deletions src-docs/src/views/icon/icon_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default () => (
>
<EuiPanel>
<EuiIcon
type="https://upload.wikimedia.org/wikipedia/commons/9/9f/Vimlogo.svg"
type="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"
size="xl"
/>
<EuiText size="s">
Expand Down Expand Up @@ -72,7 +72,7 @@ export default () => (

<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiButton iconType="https://upload.wikimedia.org/wikipedia/commons/9/9f/Vimlogo.svg">http://some.svg</EuiButton>
<EuiButton iconType="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg">http://some.svg</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton iconType={reactSvg}>{`{reactSvg}`}</EuiButton>
Expand Down
4 changes: 2 additions & 2 deletions src/components/badge/badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isColorDark, hexToRgb } from '../../services/color';
import { EuiKeyboardAccessible } from '../accessibility';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../icon';

Expand Down Expand Up @@ -150,7 +150,7 @@ EuiBadge.propTypes = {
/**
* Accepts any string from our icon library
*/
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,

/**
* The side of the badge the icon should sit
Expand Down
4 changes: 2 additions & 2 deletions src/components/badge/beta_badge/beta_badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import classNames from 'classnames';
import { EuiToolTip } from '../../tool_tip';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../../icon';

Expand Down Expand Up @@ -78,7 +78,7 @@ EuiBetaBadge.propTypes = {
/**
* Supply an icon type if the badge should just be an icon
*/
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,

/**
* Content for the tooltip
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { getSecureRelForTarget } from '../../services';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../icon';

Expand Down Expand Up @@ -152,7 +152,7 @@ EuiButton.propTypes = {
/**
* See EuiIcon
*/
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
iconSide: PropTypes.oneOf(ICON_SIDES),

/**
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/button_empty/button_empty.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { getSecureRelForTarget } from '../../../services';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../../icon';

Expand Down Expand Up @@ -150,7 +150,7 @@ export const EuiButtonEmpty = ({
EuiButtonEmpty.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
iconSide: PropTypes.oneOf(ICON_SIDES),
color: PropTypes.oneOf(COLORS),
size: PropTypes.oneOf(SIZES),
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/button_icon/button_icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getSecureRelForTarget } from '../../../services';

import {
ICON_SIZES,
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../../icon';

Expand Down Expand Up @@ -107,7 +107,7 @@ export const EuiButtonIcon = ({
EuiButtonIcon.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
iconSize: PropTypes.oneOf(ICON_SIZES),
color: PropTypes.oneOf(COLORS),
isDisabled: PropTypes.bool,
Expand Down
4 changes: 2 additions & 2 deletions src/components/call_out/call_out.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../icon';

Expand Down Expand Up @@ -94,7 +94,7 @@ EuiCallOut.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
title: PropTypes.node,
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
color: PropTypes.oneOf(COLORS),
size: PropTypes.oneOf(SIZES),
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/date_picker/date_picker_range.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import classNames from 'classnames';

import { EuiText } from '../text';
import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../icon';

Expand Down Expand Up @@ -91,7 +91,7 @@ EuiDatePickerRange.propTypes = {
*/
iconType: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(ICON_TYPES),
IconPropType,
]),
fullWidth: PropTypes.bool,
/**
Expand Down
4 changes: 2 additions & 2 deletions src/components/empty_prompt/empty_prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import classNames from 'classnames';
import { TITLE_SIZES } from '../title/title';
import { EuiFlexGroup, EuiFlexItem } from '../flex';
import { EuiSpacer } from '../spacer';
import { EuiIcon, COLORS, TYPES } from '../icon/icon';
import { EuiIcon, COLORS, IconPropType } from '../icon/icon';
import { EuiText, EuiTextColor } from '../text';
import { EuiTitle } from '../title';

Expand Down Expand Up @@ -116,7 +116,7 @@ export const EuiEmptyPrompt = ({
};

EuiEmptyPrompt.propTypes = {
iconType: PropTypes.oneOf(TYPES),
iconType: IconPropType,

/**
* Pass `null` to use original icon color
Expand Down
4 changes: 2 additions & 2 deletions src/components/filter_group/filter_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '../button/button_empty';

import {
ICON_TYPES,
IconPropType,
} from '../icon';

export const EuiFilterButton = ({
Expand Down Expand Up @@ -95,7 +95,7 @@ EuiFilterButton.propTypes = {
/**
* Use any one of our icons
*/
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
iconSide: PropTypes.oneOf(ICON_SIDES),
color: PropTypes.oneOf(COLORS),
/**
Expand Down
3 changes: 2 additions & 1 deletion src/components/header/header_logo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import classNames from 'classnames';

import {
EuiIcon,
IconPropType,
} from '../icon';

export const EuiHeaderLogo = ({ iconType, iconTitle, href, children, className, ...rest }) => {
Expand All @@ -28,7 +29,7 @@ export const EuiHeaderLogo = ({ iconType, iconTitle, href, children, className,
EuiHeaderLogo.propTypes = {
href: PropTypes.string,
children: PropTypes.node,
iconType: PropTypes.string,
iconType: IconPropType,
iconTitle: PropTypes.string,
};

Expand Down
25 changes: 17 additions & 8 deletions src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
ReactElement,
SVGAttributes,
} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { CommonProps, Omit, keysOf } from '../common';
Expand Down Expand Up @@ -316,9 +317,16 @@ const typeToPathMap = {
tokenNamespace: 'tokens/tokenNamespace',
};

export const TYPES: IconType[] = keysOf(typeToPathMap);
export const TYPES = keysOf(typeToPathMap);

export type IconType = keyof typeof typeToPathMap;
export type EuiIconType = keyof typeof typeToPathMap;

export type IconType = EuiIconType | string | ReactElement;

export const IconPropType = PropTypes.oneOfType([
PropTypes.string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this bust IDE auto suggest because it no longer knows that the strings that are accepted also include the enums?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebStorm still autosuggests/completes the available string constants, both when used internally by another EUI component and when used by a consuming application.

PropTypes.node,
]);

const colorToClassMap = {
default: null,
Expand Down Expand Up @@ -361,7 +369,7 @@ export interface EuiIconProps {
/**
* `Enum` is any of the named icons listed in the docs, `Element` is any React SVG element, and `string` is usually a URL to an SVG file
*/
type: IconType | ReactElement<SVGElement> | string;
type: IconType;
/**
* One of EUI's color palette or a valid CSS color value https://developer.mozilla.org/en-US/docs/Web/CSS/color_value.
* Note that coloring only works if your SVG is removed of fill attributes.
Expand All @@ -374,23 +382,23 @@ export interface EuiIconProps {
}

type Props = CommonProps &
Omit<SVGAttributes<SVGElement>, 'color'> &
Omit<SVGAttributes<SVGElement>, keyof EuiIconProps> &
EuiIconProps;

interface State {
icon: undefined | ReactElement<any> | string;
icon: undefined | ReactElement | string;
isLoading: boolean;
}

function isIconType(x: EuiIconProps['type']): x is IconType {
function isEuiIconType(x: EuiIconProps['type']): x is EuiIconType {
return typeof x === 'string' && typeToPathMap.hasOwnProperty(x);
}

function getInitialIcon(icon: EuiIconProps['type']) {
if (icon == null) {
return undefined;
}
if (isIconType(icon)) {
if (isEuiIconType(icon)) {
return undefined;
}
return icon;
Expand All @@ -403,7 +411,7 @@ export class EuiIcon extends Component<Props, State> {
const initialIcon = getInitialIcon(this.props.type);
let isLoading = false;

if (isIconType(this.props.type)) {
if (isEuiIconType(this.props.type)) {
isLoading = true;
import('./assets/' + typeToPathMap[this.props.type] + '.js').then(
({ icon }) => {
Expand Down Expand Up @@ -447,6 +455,7 @@ export class EuiIcon extends Component<Props, State> {
// These icons are a little special and get some extra CSS flexibility
const isAppIcon =
type &&
typeof type === 'string' &&
(/.+App$/.test(type) || /.+Job$/.test(type) || type === 'dataVisualizer');

const classes = classNames(
Expand Down
1 change: 1 addition & 0 deletions src/components/icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export {
IconColor,
IconSize,
IconType,
IconPropType,
TYPES as ICON_TYPES,
SIZES as ICON_SIZES,
COLORS as ICON_COLORS,
Expand Down
4 changes: 2 additions & 2 deletions src/components/key_pad_menu/key_pad_menu_item.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import classNames from 'classnames';
import { EuiBetaBadge } from '../../components/badge/beta_badge';

import {
ICON_TYPES,
IconPropType,
} from '../icon';

const renderContent = (children, label, betaBadgeLabel, betaBadgeTooltipContent, betaBadgeIconType) => (
Expand Down Expand Up @@ -43,7 +43,7 @@ const commonPropTypes = {
/**
* Supply an icon type if the badge should just be an icon
*/
betaBadgeIconType: PropTypes.oneOf(ICON_TYPES),
betaBadgeIconType: IconPropType,

/**
* Add a description to the beta badge (will appear in a tooltip)
Expand Down
6 changes: 3 additions & 3 deletions src/components/list_group/list_group_item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import { EuiButtonIcon } from '../button';
import { ICON_TYPES, EuiIcon } from '../icon';
import { IconPropType, EuiIcon } from '../icon';
import { EuiToolTip } from '../tool_tip';

const sizeToClassNameMap = {
Expand Down Expand Up @@ -182,7 +182,7 @@ EuiListGroupItem.propTypes = {
/**
* Adds `EuiIcon` of `EuiIcon.type`
*/
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,

/**
* Custom node to pass as the icon. Cannot be used in conjunction
Expand All @@ -200,7 +200,7 @@ EuiListGroupItem.propTypes = {
* pass `alwaysShow` if you don't want the default behavior of only showing on hover
*/
extraAction: PropTypes.shape({
iconType: PropTypes.oneOf(ICON_TYPES).isRequired,
iconType: IconPropType.isRequired,
alwaysShow: PropTypes.bool,
}),

Expand Down
4 changes: 2 additions & 2 deletions src/components/table/table_header_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import {
ICON_TYPES,
IconPropType,
EuiIcon,
} from '../icon';

Expand Down Expand Up @@ -44,5 +44,5 @@ export const EuiTableHeaderButton = ({
EuiTableHeaderButton.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
};
4 changes: 2 additions & 2 deletions src/components/toast/global_toast_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import { Timer } from '../../services/time';
import { ICON_TYPES } from '../icon';
import { IconPropType } from '../icon';
import { EuiGlobalToastListItem } from './global_toast_list_item';
import { EuiToast } from './toast';

Expand Down Expand Up @@ -38,7 +38,7 @@ export class EuiGlobalToastList extends Component {
title: PropTypes.string,
text: PropTypes.node,
color: PropTypes.string,
iconType: PropTypes.oneOf(ICON_TYPES),
iconType: IconPropType,
toastLifeTimeMs: PropTypes.number,
}).isRequired),
dismissToast: PropTypes.func.isRequired,
Expand Down
Loading