-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Icon & eds-icons refactor to typescript (#616)
* 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
Showing
13 changed files
with
5,786 additions
and
5,728 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } | ||
} |
Oops, something went wrong.