From 113c4cdf4e27e2bf711b92cebaeaff778c94e52e Mon Sep 17 00:00:00 2001 From: Erik Munson Date: Wed, 18 Mar 2020 21:39:59 -0700 Subject: [PATCH] feat(core/presentation): add Icon component w/ inline SVG (#8056) * feat(core/presentation): add Icon component w/ inline SVG * refactor(core/managed): add explicit size strings to IIconProps Co-Authored-By: Chris Thielen Co-authored-by: Chris Thielen --- .gitignore | 5 +- .../core/src/presentation/icons/Icon.tsx | 47 +++++++++++++++++++ .../src/presentation/icons/iconsByName.ts | 9 ++++ .../core/src/presentation/icons/index.ts | 1 + .../presentation/icons/vectors/artifact.svg | 14 ++++++ .../src/presentation/icons/vectors/close.svg | 12 +++++ .../icons/vectors/environment.svg | 38 +++++++++++++++ .../modules/core/src/presentation/index.ts | 1 + 8 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 app/scripts/modules/core/src/presentation/icons/Icon.tsx create mode 100644 app/scripts/modules/core/src/presentation/icons/iconsByName.ts create mode 100644 app/scripts/modules/core/src/presentation/icons/index.ts create mode 100644 app/scripts/modules/core/src/presentation/icons/vectors/artifact.svg create mode 100644 app/scripts/modules/core/src/presentation/icons/vectors/close.svg create mode 100644 app/scripts/modules/core/src/presentation/icons/vectors/environment.svg diff --git a/.gitignore b/.gitignore index 7e43df977da..f190e141894 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/app/scripts/modules/core/src/presentation/icons/Icon.tsx b/app/scripts/modules/core/src/presentation/icons/Icon.tsx new file mode 100644 index 00000000000..1ceaad9667b --- /dev/null +++ b/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 ; +}); diff --git a/app/scripts/modules/core/src/presentation/icons/iconsByName.ts b/app/scripts/modules/core/src/presentation/icons/iconsByName.ts new file mode 100644 index 00000000000..0e3c82782f0 --- /dev/null +++ b/app/scripts/modules/core/src/presentation/icons/iconsByName.ts @@ -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; diff --git a/app/scripts/modules/core/src/presentation/icons/index.ts b/app/scripts/modules/core/src/presentation/icons/index.ts new file mode 100644 index 00000000000..e263cc0e6db --- /dev/null +++ b/app/scripts/modules/core/src/presentation/icons/index.ts @@ -0,0 +1 @@ +export * from './Icon'; diff --git a/app/scripts/modules/core/src/presentation/icons/vectors/artifact.svg b/app/scripts/modules/core/src/presentation/icons/vectors/artifact.svg new file mode 100644 index 00000000000..8b370789ade --- /dev/null +++ b/app/scripts/modules/core/src/presentation/icons/vectors/artifact.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/app/scripts/modules/core/src/presentation/icons/vectors/close.svg b/app/scripts/modules/core/src/presentation/icons/vectors/close.svg new file mode 100644 index 00000000000..8e377914745 --- /dev/null +++ b/app/scripts/modules/core/src/presentation/icons/vectors/close.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/app/scripts/modules/core/src/presentation/icons/vectors/environment.svg b/app/scripts/modules/core/src/presentation/icons/vectors/environment.svg new file mode 100644 index 00000000000..2b69e3ea875 --- /dev/null +++ b/app/scripts/modules/core/src/presentation/icons/vectors/environment.svg @@ -0,0 +1,38 @@ + + + + + network + + + diff --git a/app/scripts/modules/core/src/presentation/index.ts b/app/scripts/modules/core/src/presentation/index.ts index 9e0a1a62dd2..2f89f9aaa05 100644 --- a/app/scripts/modules/core/src/presentation/index.ts +++ b/app/scripts/modules/core/src/presentation/index.ts @@ -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';