Skip to content

Commit

Permalink
Icon & eds-icons refactor to typescript (#616)
Browse files Browse the repository at this point in the history
* Added types to eds-icons

* Rewrote Icon typescript

* Fixed data prop checking

* Added description to .add

* IconName can also be random string
  • Loading branch information
Michael Marszalek authored and vnys committed Nov 13, 2020
1 parent 7677cd4 commit a80d085
Show file tree
Hide file tree
Showing 13 changed files with 5,786 additions and 5,728 deletions.
8 changes: 5 additions & 3 deletions apps/figma-broker/actions/createAssets.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ const writeSVGSprite = (assets) => {

const writeJsFile = (assets) => {
const prefix = 'eds'
const jsFile = R.pipe(
const svgObjects = R.pipe(
R.map((iconGroups) =>
R.pipe(
R.reduce((acc, icon) => {
const { name, height, width, pathData } = icon

const svgObj = `
export const ${name} = {
export const ${name}: IconData = {
name: '${name}',
prefix: '${prefix}',
height: '${height}',
Expand All @@ -76,7 +76,9 @@ export const ${name} = {
R.head,
)(assets)

writeFile(PATHS.ICON_FILES, 'index', 'ts', jsFile)
const jsFile = `import type { IconData } from './types'\n${svgObjects}`

writeFile(PATHS.ICON_FILES, 'data', 'ts', jsFile)
}

const writeJsonAssets = (assets) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/figma-broker/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export const PATHS = {
CSS: `${COMMON_DIR}/public/css`,
IMAGES: `${STOREFRONT_DIR}/src/assets/figma`,
ICONS: `${STOREFRONT_DIR}/src/assets/icons`,
ICON_FILES: `${ICONS_DIR}`,
ICON_FILES: `${ICONS_DIR}/src`,
}
107 changes: 0 additions & 107 deletions libraries/core-react/src/Icon/Icon.jsx

This file was deleted.

File renamed without changes.
129 changes: 129 additions & 0 deletions libraries/core-react/src/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React, { forwardRef } from 'react'
import styled from 'styled-components'
import { get } from './library'
import type { IconData } from '@equinor/eds-icons'
import type { IconBasket, Name } from './Icon.types'

type StyledProps = {
height: number
width: number
fill: string
size?: number
rotation?: number
}

type SvgProps = {
name: string
viewBox: string
className: string
rotation?: number
title?: string
role?: string
'aria-hidden'?: boolean
'aria-labelledby'?: string
}

const customIcon = (icon: IconData): IconBasket => ({
icon,
count: Math.floor(Math.random() * 1000),
})

const transform = ({ rotation }: SvgProps): string =>
rotation ? `transform: rotate(${rotation}deg)` : ''

const StyledSvg = styled.svg.attrs<StyledProps>(({ height, width, fill }) => ({
name: null,
xmlns: 'http://www.w3.org/2000/svg',
height,
width,
fill,
}))`
${transform}
`

const StyledPath = styled.path.attrs<StyledProps>(({ height, size }) => ({
size: null,
fillRule: 'evenodd',
clipRule: 'evenodd',
transform: size / height !== 1 ? `scale(${size / height})` : null,
}))``

type Props = {
/** @ignore */
className?: string
/** Title for icon when used semantically */
title?: string
/** Color */
color?: string
/** Size */
size?: 16 | 24 | 32 | 40 | 48
/** Rotation */
rotation?: 0 | 90 | 180 | 270
/** Name */
name?: Name
/** Manually specify which icon data to use */
data?: IconData
}

export const Icon = forwardRef<SVGSVGElement, Props>(function EdsIcon(
{
size = 24,
color = 'currentColor',
name,
className,
rotation,
title,
data,
...rest
},
ref,
) {
const { icon, count }: IconBasket = data ? customIcon(data) : get(name)

if (typeof icon === 'undefined') {
throw Error(
`Icon "${name}" not found. Have you added it using Icon.add() or using data props?`,
)
}

let svgProps: SvgProps & StyledProps = {
height: size,
width: size,
fill: color,
viewBox: `0 0 ${size} ${size}`,
className,
rotation,
name,
'aria-hidden': true,
title: null,
}

const pathProps = {
d: icon.svgPathData,
height: icon.height ? icon.height : size,
size,
}

// Accessibility
let titleId = ''

if (title) {
titleId = `${icon.prefix}-${icon.name}-${count}`
svgProps = {
...svgProps,
title,
role: 'img',
'aria-hidden': null,
'aria-labelledby': titleId,
}
}

return (
<StyledSvg {...svgProps} {...rest} ref={ref}>
{title && <title id={titleId}>{title}</title>}
<StyledPath data-testid="eds-icon-path" {...pathProps} />
</StyledSvg>
)
})

Icon.displayName = 'eds-icon'
11 changes: 11 additions & 0 deletions libraries/core-react/src/Icon/Icon.types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { IconData, IconName } from '@equinor/eds-icons'
import { Icon } from './Icon'
import { add } from './library'

export type IconBasket = { icon?: IconData; count: number }

export type Name = IconName | string

export type IconType = typeof Icon & {
add: typeof add
}
7 changes: 0 additions & 7 deletions libraries/core-react/src/Icon/index.js

This file was deleted.

9 changes: 9 additions & 0 deletions libraries/core-react/src/Icon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Icon as IconComponent } from './Icon'
import { add } from './library'
import type { IconType } from './Icon.types'

const Icon = IconComponent as IconType

Icon.add = add

export { Icon }
14 changes: 0 additions & 14 deletions libraries/core-react/src/Icon/library.js

This file was deleted.

20 changes: 20 additions & 0 deletions libraries/core-react/src/Icon/library.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { IconData } from '@equinor/eds-icons'
import type { IconBasket, Name } from './Icon.types'

type IconRecord = Record<Name, IconData>

let _icons: IconRecord = {}
let count = 0
/** Add icons to library to be used for rendering using name.
This needs to be done lonly once */
export const add = (icons: IconRecord): void => {
_icons = {
..._icons,
...icons,
}
}

export const get = (name: Name): IconBasket => {
count += 1
return { icon: _icons[name], count }
}
Loading

0 comments on commit a80d085

Please sign in to comment.