Skip to content

Commit

Permalink
feat(core/presentation): add Icon component w/ inline SVG (#8056)
Browse files Browse the repository at this point in the history
* feat(core/presentation): add Icon component w/ inline SVG

* refactor(core/managed): add explicit size strings to IIconProps

Co-Authored-By: Chris Thielen <christopherthielen@users.noreply.github.com>

Co-authored-by: Chris Thielen <christopherthielen@users.noreply.github.com>
  • Loading branch information
Erik Munson and christopherthielen committed Mar 19, 2020
1 parent 15e47a6 commit 113c4cd
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .gitignore
Expand Up @@ -2,7 +2,10 @@
*.swp
.DS_Store
ehthumbs.db
Icon?
# This "Icon" entry needs its invisible carriage return character preserved
# to avoid ignoring *any* directory that starts with the name 'icon':
# https://stackoverflow.com/questions/17556250/how-to-ignore-icon-in-git
Icon
Thumbs.db

# IDE Files
Expand Down
47 changes: 47 additions & 0 deletions app/scripts/modules/core/src/presentation/icons/Icon.tsx
@@ -0,0 +1,47 @@
import React, { memo } from 'react';

import { iconsByName } from './iconsByName';

export type IconNames = keyof typeof iconsByName;

export type IIconProps = {
name: IconNames;
appearance?: 'light' | 'neutral' | 'dark';
size?: 'extraSmall' | 'small' | 'medium' | 'large' | 'extraLarge' | string;
color?: string;
className?: string;
};

const DEFAULT_SIZE = 'small';
const DEFAULT_APPEARANCE = 'neutral';

const pxDimensionsBySize: { [size: string]: string } = {
extraSmall: '16px',
small: '20px',
medium: '24px',
large: '32px',
extraLarge: '40px',
};

const colorsByAppearance = {
light: 'var(--color-white)',
neutral: 'rgba(0, 0, 0, 0.5)',
dark: 'var(--color-black)',
};

const throwInvalidIconError = (name: string) => {
throw new Error(`No icon with the name ${name} exists`);
};

export const Icon = memo(({ name, appearance, size, color, className }: IIconProps) => {
const Component = iconsByName[name];

if (!Component) {
throwInvalidIconError(name);
}

const width = pxDimensionsBySize[size] || size || pxDimensionsBySize[DEFAULT_SIZE];
const fill = color ? `var(--color-${color})` : colorsByAppearance[appearance || DEFAULT_APPEARANCE];

return <Component className={className} style={{ width, fill }} />;
});
@@ -0,0 +1,9 @@
import { ReactComponent as artifact } from './vectors/artifact.svg';
import { ReactComponent as close } from './vectors/close.svg';
import { ReactComponent as environment } from './vectors/environment.svg';

export const iconsByName = {
artifact,
close,
environment,
} as const;
1 change: 1 addition & 0 deletions app/scripts/modules/core/src/presentation/icons/index.ts
@@ -0,0 +1 @@
export * from './Icon';
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions app/scripts/modules/core/src/presentation/icons/vectors/close.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/scripts/modules/core/src/presentation/index.ts
Expand Up @@ -5,6 +5,7 @@ export * from './FormElements';
export * from './forms';
export * from './hooks';
export * from './HoverablePopover';
export * from './icons';
export * from './LabelComponent';
export * from './labeledValues';
export * from './LinkWithClipboard';
Expand Down

0 comments on commit 113c4cd

Please sign in to comment.