Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit bcff4a5

Browse files
author
Alexandru Buliga
authored
feat(icon): color prop (#651)
* feat(icon): color prop * changelog * addressed PR comments * addressed PR comments
1 parent 39381d2 commit bcff4a5

File tree

5 files changed

+71
-51
lines changed

5 files changed

+71
-51
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
4141
- Export `table-add` and `table-delete` SVG icon in Teams theme @VyshnaviDasari ([#643](https://github.com/stardust-ui/react/pull/643))
4242
- Add handling of `Enter` and `Spacebar` in List component @ jurokapsiar ([#279](https://github.com/stardust-ui/react/pull/279))
4343
- Enable RTL for keyboard handlers @sophieH29 ([#656](https://github.com/stardust-ui/react/pull/656))
44+
- Add `color` prop to `Icon` component @Bugaa92 ([#651](https://github.com/stardust-ui/react/pull/651))
4445

4546
### Documentation
4647
- Add more accessibility descriptions to components and behaviors @jurokapsiar ([#648](https://github.com/stardust-ui/react/pull/648))

docs/src/examples/components/Icon/Variations/IconExampleColor.shorthand.tsx

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react'
2-
import { Icon, Grid, Text } from '@stardust-ui/react'
2+
import * as _ from 'lodash'
3+
import { Icon, Grid, Text, ProviderConsumer } from '@stardust-ui/react'
34

45
const IconExampleColor = () => (
56
<Grid columns="repeat(4, auto)" styles={{ alignItems: 'center' }} variables={{ gridGap: '10px' }}>
@@ -15,27 +16,17 @@ const IconExampleColor = () => (
1516
<Icon name="call" bordered variables={{ outline: true }} />
1617
<Icon name="call-video" bordered variables={{ outline: true }} />
1718
</div>
18-
<Text
19-
content={
20-
<span>
21-
USING THE <code>color</code> VARIABLE:
22-
</span>
23-
}
24-
weight="bold"
25-
/>
19+
<Text weight="bold">
20+
USING THE <code>color</code> VARIABLE:
21+
</Text>
2622
<div>
2723
<Icon name="calendar" bordered variables={{ color: 'violet' }} />
2824
<Icon name="call" bordered variables={{ color: 'yellowgreen' }} />
2925
<Icon name="call-video" bordered variables={{ color: 'cornflowerblue' }} />
3026
</div>
31-
<Text
32-
content={
33-
<span>
34-
USING THE <code>borderColor</code> VARIABLE:
35-
</span>
36-
}
37-
weight="bold"
38-
/>
27+
<Text weight="bold">
28+
USING THE <code>borderColor</code> VARIABLE:
29+
</Text>
3930
<div>
4031
<Icon
4132
name="calendar"
@@ -53,6 +44,18 @@ const IconExampleColor = () => (
5344
variables={{ color: 'cornflowerblue', borderColor: 'orangered' }}
5445
/>
5546
</div>
47+
<Text weight="bold">
48+
USING THE <code>color</code> PROP:
49+
</Text>
50+
<div>
51+
<ProviderConsumer
52+
render={({ siteVariables: { emphasisColors, naturalColors } }) =>
53+
_.take(_.keys({ ...emphasisColors, ...naturalColors }), 3).map(color => (
54+
<Icon key={color} name="call" bordered color={color} />
55+
))
56+
}
57+
/>
58+
</div>
5659
</Grid>
5760
)
5861

src/components/Icon/Icon.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
createShorthandFactory,
77
UIComponentProps,
88
commonPropTypes,
9+
ColorComponentProps,
910
} from '../../lib'
1011
import { iconBehavior } from '../../lib/accessibility/'
1112
import { Accessibility } from '../../lib/accessibility/types'
@@ -17,7 +18,7 @@ export type IconXSpacing = 'none' | 'before' | 'after' | 'both'
1718

1819
export type IconSize = 'smallest' | 'smaller' | 'small' | 'medium' | 'large' | 'larger' | 'largest'
1920

20-
export interface IconProps extends UIComponentProps {
21+
export interface IconProps extends UIComponentProps, ColorComponentProps {
2122
/**
2223
* Accessibility behavior if overriden by the user.
2324
* @default iconBehavior
@@ -57,6 +58,7 @@ class Icon extends UIComponent<ReactProps<IconProps>, any> {
5758
...commonPropTypes.createCommon({
5859
children: false,
5960
content: false,
61+
color: true,
6062
}),
6163
accessibility: PropTypes.func,
6264
bordered: PropTypes.bool,

src/themes/teams/components/Icon/iconStyles.ts

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1+
import * as _ from 'lodash'
2+
13
import fontAwesomeIcons from './fontAwesomeIconStyles'
24
import { callable } from '../../../../lib'
35
import { fittedStyle } from '../../../../styles/customCSS'
46
import { ComponentSlotStylesInput, ICSSInJSStyle, FontIconSpec } from '../../../types'
57
import { ResultOf } from '../../../../../types/utils'
6-
import { IconXSpacing, IconProps } from '../../../../components/Icon/Icon'
8+
import { IconXSpacing, IconProps, IconSize } from '../../../../components/Icon/Icon'
79
import { pxToRem } from '../../utils'
810
import { getStyle as getSvgStyle } from './svg'
9-
10-
const sizes = new Map([
11-
['smallest', 7],
12-
['smaller', 10],
13-
['small', 12],
14-
['medium', 16],
15-
['large', 20],
16-
['larger', 32],
17-
['largest', 40],
18-
])
11+
import { IconVariables, IconSizeModifier } from './iconVariables'
12+
13+
const sizes: { [key in IconSize]: number } = {
14+
smallest: 7,
15+
smaller: 10,
16+
small: 12,
17+
medium: 16,
18+
large: 20,
19+
larger: 32,
20+
largest: 40,
21+
}
1922

2023
const getDefaultFontIcon = (iconName: string) => {
2124
return callable(fontAwesomeIcons(iconName).icon)()
@@ -57,7 +60,7 @@ const getXSpacingStyles = (xSpacing: IconXSpacing, horizontalSpace: string): ICS
5760
}
5861
}
5962

60-
const getBorderedStyles = (circular, boxShadowColor): ICSSInJSStyle => {
63+
const getBorderedStyles = (circular: boolean, boxShadowColor: string): ICSSInJSStyle => {
6164
return {
6265
...getPaddedStyle(),
6366

@@ -70,10 +73,11 @@ const getPaddedStyle = (): ICSSInJSStyle => ({
7073
padding: pxToRem(4),
7174
})
7275

73-
const getIconSize = (size, sizeModifier): number => {
76+
const getIconSize = (size: IconSize, sizeModifier: IconSizeModifier): number => {
7477
if (!sizeModifier) {
75-
return sizes.get(size)
78+
return sizes[size]
7679
}
80+
7781
const modifiedSizes = {
7882
large: {
7983
x: 24,
@@ -84,11 +88,12 @@ const getIconSize = (size, sizeModifier): number => {
8488
return modifiedSizes[size] && modifiedSizes[size][sizeModifier]
8589
}
8690

87-
const getIconColor = color => color || 'currentColor'
91+
const getIconColor = (colorProp: string, variables: IconVariables) =>
92+
_.get(variables.colors, colorProp, variables.color || 'currentColor')
8893

89-
const iconStyles: ComponentSlotStylesInput<IconProps, any> = {
94+
const iconStyles: ComponentSlotStylesInput<IconProps, IconVariables> = {
9095
root: ({
91-
props: { disabled, name, size, bordered, circular, xSpacing },
96+
props: { disabled, name, size, bordered, circular, color, xSpacing },
9297
variables: v,
9398
theme,
9499
}): ICSSInJSStyle => {
@@ -105,7 +110,7 @@ const iconStyles: ComponentSlotStylesInput<IconProps, any> = {
105110
...(isFontBased && getFontStyles(getIconSize(size, v.sizeModifier), name)),
106111

107112
...(isFontBased && {
108-
color: getIconColor(v.color),
113+
color: getIconColor(color, v),
109114

110115
...(disabled && {
111116
color: v.disabledColor,
@@ -115,7 +120,7 @@ const iconStyles: ComponentSlotStylesInput<IconProps, any> = {
115120
...getXSpacingStyles(xSpacing, v.horizontalSpace),
116121

117122
...((bordered || v.borderColor || circular) &&
118-
getBorderedStyles(circular, v.borderColor || getIconColor(v.color))),
123+
getBorderedStyles(circular, v.borderColor || getIconColor(color, v))),
119124
}
120125
},
121126

@@ -137,14 +142,14 @@ const iconStyles: ComponentSlotStylesInput<IconProps, any> = {
137142
}
138143
},
139144

140-
svg: ({ props: { size, disabled }, variables: v }): ICSSInJSStyle => {
145+
svg: ({ props: { size, color, disabled }, variables: v }): ICSSInJSStyle => {
141146
const iconSizeInRems = pxToRem(getIconSize(size, v.sizeModifier))
142147

143148
return {
144149
display: 'block',
145150
width: iconSizeInRems,
146151
height: iconSizeInRems,
147-
fill: getIconColor(v.color),
152+
fill: getIconColor(color, v),
148153

149154
...(disabled && {
150155
fill: v.disabledColor,
Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
1+
import { ColorValues } from '../../../types'
2+
import { mapColorsToScheme } from '../../../../lib'
13
import { pxToRem } from '../../utils'
24

3-
export interface IconVariables {
4-
[key: string]: string | number | boolean | undefined
5+
export type IconSizeModifier = 'x' | 'xx'
56

6-
redColor?: string
7-
brandColor?: string
7+
export interface IconVariables {
8+
[key: string]: object | string | number | boolean | undefined
89

9-
outline?: boolean
10+
colors: ColorValues<string>
1011
color?: string
1112
backgroundColor?: string
1213
borderColor?: string
13-
horizontalSpace: string
14-
margin: string
14+
brandColor?: string
1515
secondaryColor: string
16+
redColor?: string
1617
disabledColor: string
18+
19+
horizontalSpace: string
20+
margin: string
21+
outline?: boolean
22+
sizeModifier?: IconSizeModifier
1723
}
1824

25+
const colorVariant = 500
26+
1927
export default (siteVars): IconVariables => ({
20-
outline: undefined,
28+
colors: mapColorsToScheme(siteVars, colorVariant),
2129
color: undefined,
2230
backgroundColor: undefined,
2331
borderColor: undefined,
24-
horizontalSpace: pxToRem(10),
25-
margin: `0 ${pxToRem(8)} 0 0`,
32+
brandColor: siteVars.brandColor,
2633
secondaryColor: siteVars.white,
34+
redColor: siteVars.red,
2735
disabledColor: siteVars.gray06,
2836

29-
redColor: siteVars.red,
30-
brandColor: siteVars.brandColor,
37+
horizontalSpace: pxToRem(10),
38+
margin: `0 ${pxToRem(8)} 0 0`,
39+
outline: undefined,
3140
})

0 commit comments

Comments
 (0)