-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [WIP] Push up icon changes * Introduce assets * Create script to generate Icon types based on icons in assets directory * Change Icon component to use SVGs. Create script to auto generate SVG types. Use an svg transformer to allow for importing SVGs as components * Update ignores on Icon.assets * Update generate-assets script to add ignores * Remove icon test - SVG mock issue. Update Icon docs with color prop * Fix useStyles for other components * Update Icon README * Correct read me * Reintroduce react-native-svg-asset-plugin * Provide better typing for svg * Create AvatarIcon * Create IconButton * fix test
- Loading branch information
Showing
17 changed files
with
424 additions
and
0 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
app/component-library/components/AvatarIcon/AvatarIcon.stories.tsx
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,21 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react-native'; | ||
import { select } from '@storybook/addon-knobs'; | ||
import { BaseAvatarSize } from '../BaseAvatar'; | ||
import { IconName } from '../Icon'; | ||
import AvatarIcon from './AvatarIcon'; | ||
|
||
storiesOf(' Component Library / AvatarIcon', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => { | ||
const groupId = 'Props'; | ||
const sizeSelector = select( | ||
'size', | ||
BaseAvatarSize, | ||
BaseAvatarSize.Md, | ||
groupId, | ||
); | ||
const iconSelector = select('name', IconName, IconName.LockFilled, groupId); | ||
|
||
return <AvatarIcon size={sizeSelector} icon={iconSelector} />; | ||
}); |
35 changes: 35 additions & 0 deletions
35
app/component-library/components/AvatarIcon/AvatarIcon.styles.ts
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,35 @@ | ||
import { StyleSheet, ViewStyle } from 'react-native'; | ||
import { | ||
AvatarIconStyleSheet, | ||
AvatarIconStyleSheetVars, | ||
} from './AvatarIcon.types'; | ||
import { Theme } from '../../../util/theme/models'; | ||
|
||
/** | ||
* Style sheet function for AvatarIcon component. | ||
* | ||
* @param params Style sheet params. | ||
* @param params.theme App theme from ThemeContext. | ||
* @param params.vars Inputs that the style sheet depends on. | ||
* @returns StyleSheet object. | ||
*/ | ||
const styleSheet = (params: { | ||
theme: Theme; | ||
vars: AvatarIconStyleSheetVars; | ||
}): AvatarIconStyleSheet => { | ||
const { theme, vars } = params; | ||
const { colors } = theme; | ||
const { style } = vars; | ||
return StyleSheet.create({ | ||
base: Object.assign( | ||
{ | ||
backgroundColor: colors.primary.muted, | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
} as ViewStyle, | ||
style, | ||
) as ViewStyle, | ||
}); | ||
}; | ||
|
||
export default styleSheet; |
14 changes: 14 additions & 0 deletions
14
app/component-library/components/AvatarIcon/AvatarIcon.test.tsx
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,14 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import AvatarIcon from './AvatarIcon'; | ||
import { BaseAvatarSize } from '../BaseAvatar'; | ||
import { IconName } from '../Icon'; | ||
|
||
describe('AvatarIcon', () => { | ||
it('should render correctly', () => { | ||
const wrapper = shallow( | ||
<AvatarIcon size={BaseAvatarSize.Lg} icon={IconName.AddSquareFilled} />, | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); |
28 changes: 28 additions & 0 deletions
28
app/component-library/components/AvatarIcon/AvatarIcon.tsx
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,28 @@ | ||
/* eslint-disable react/prop-types */ | ||
import React from 'react'; | ||
import { useStyles } from '../../../component-library/hooks'; | ||
import BaseAvatar, { BaseAvatarSize } from '../BaseAvatar'; | ||
import Icon, { IconSize } from '../Icon'; | ||
import stylesheet from './AvatarIcon.styles'; | ||
import { AvatarIconProps, IconSizeByAvatarSize } from './AvatarIcon.types'; | ||
|
||
const iconSizeByAvatarSize: IconSizeByAvatarSize = { | ||
[BaseAvatarSize.Xs]: IconSize.Xs, | ||
[BaseAvatarSize.Sm]: IconSize.Sm, | ||
[BaseAvatarSize.Md]: IconSize.Md, | ||
[BaseAvatarSize.Lg]: IconSize.Lg, | ||
[BaseAvatarSize.Xl]: IconSize.Xl, | ||
}; | ||
|
||
const AvatarIcon = ({ size, icon, style, ...props }: AvatarIconProps) => { | ||
const { styles, theme } = useStyles(stylesheet, { style }); | ||
const iconSize = iconSizeByAvatarSize[size]; | ||
|
||
return ( | ||
<BaseAvatar size={size} style={styles.base} {...props}> | ||
<Icon name={icon} size={iconSize} color={theme.colors.primary.default} /> | ||
</BaseAvatar> | ||
); | ||
}; | ||
|
||
export default AvatarIcon; |
35 changes: 35 additions & 0 deletions
35
app/component-library/components/AvatarIcon/AvatarIcon.types.ts
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,35 @@ | ||
import { ViewStyle } from 'react-native'; | ||
import { | ||
BaseAvatarProps, | ||
BaseAvatarSize, | ||
} from '../BaseAvatar/BaseAvatar.types'; | ||
import { IconProps, IconSize } from '../Icon/Icon.types'; | ||
|
||
/** | ||
* AvatarIcon component props. | ||
*/ | ||
export interface AvatarIconProps extends BaseAvatarProps { | ||
/** | ||
* Icon to use. | ||
*/ | ||
icon: IconProps['name']; | ||
} | ||
|
||
/** | ||
* AvatarIcon component style sheet. | ||
*/ | ||
export interface AvatarIconStyleSheet { | ||
base: ViewStyle; | ||
} | ||
|
||
/** | ||
* Style sheet input parameters. | ||
*/ | ||
export type AvatarIconStyleSheetVars = Pick<AvatarIconProps, 'style'>; | ||
|
||
/** | ||
* Mapping of IconSize by BaseAvatarSize. | ||
*/ | ||
export type IconSizeByAvatarSize = { | ||
[key in BaseAvatarSize]: IconSize; | ||
}; |
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,23 @@ | ||
# AvatarIcon | ||
|
||
AvatarIcon is a component that renders an icon contained within an avatar. This component is based on the [BaseAvatar](../BaseAvatar/BaseAvatar.tsx) component. | ||
|
||
## Props | ||
|
||
This component extends [BaseAvatarProps](../BaseAvatar/BaseAvatar.types.ts#L17) from `BaseAvatar` component. | ||
|
||
### `size` | ||
|
||
Enum to select between size variants. | ||
|
||
| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> | | ||
| :----------------------------------------------------- | :------------------------------------------------------ | | ||
| [BaseAvatarSize](../BaseAvatar/BaseAvatar.types.ts#L6) | Yes | | ||
|
||
### `icon` | ||
|
||
Icon to use. | ||
|
||
| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> | | ||
| :-------------------------------------------------- | :------------------------------------------------------ | | ||
| [IconName](../Icon/Icon.types.ts#L53) | Yes | |
20 changes: 20 additions & 0 deletions
20
app/component-library/components/AvatarIcon/__snapshots__/AvatarIcon.test.tsx.snap
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 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`AvatarIcon should render correctly 1`] = ` | ||
<BaseAvatar | ||
size="40" | ||
style={ | ||
Object { | ||
"alignItems": "center", | ||
"backgroundColor": "#037DD619", | ||
"justifyContent": "center", | ||
} | ||
} | ||
> | ||
<Icon | ||
color="#037DD6" | ||
name="AddSquareFilled" | ||
size="24" | ||
/> | ||
</BaseAvatar> | ||
`; |
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 @@ | ||
export { default } from './AvatarIcon'; |
30 changes: 30 additions & 0 deletions
30
app/component-library/components/IconButton/IconButton.stories.tsx
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,30 @@ | ||
/* eslint-disable no-console */ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react-native'; | ||
import { select, boolean } from '@storybook/addon-knobs'; | ||
import { IconName } from '../Icon'; | ||
import IconButton from './IconButton'; | ||
import { IconButtonVariant } from './IconButton.types'; | ||
|
||
storiesOf(' Component Library / IconButton', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => { | ||
const groupId = 'Props'; | ||
const iconSelector = select('icon', IconName, IconName.LockFilled, groupId); | ||
const variantSelector = select( | ||
'variant', | ||
IconButtonVariant, | ||
IconButtonVariant.Primary, | ||
groupId, | ||
); | ||
const disabledSelector = boolean('disabled', false, groupId); | ||
|
||
return ( | ||
<IconButton | ||
variant={variantSelector} | ||
icon={iconSelector} | ||
disabled={disabledSelector} | ||
onPress={() => console.log("I'm clicked!")} | ||
/> | ||
); | ||
}); |
32 changes: 32 additions & 0 deletions
32
app/component-library/components/IconButton/IconButton.styles.ts
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,32 @@ | ||
import { StyleSheet, ViewStyle } from 'react-native'; | ||
import { | ||
IconButtonStyleSheet, | ||
IconButtonStyleSheetVars, | ||
} from './IconButton.types'; | ||
|
||
/** | ||
* Style sheet function for IconButton component. | ||
* | ||
* @param params Style sheet params. | ||
* @param params.vars Inputs that the style sheet depends on. | ||
* @returns StyleSheet object. | ||
*/ | ||
const styleSheet = (params: { | ||
vars: IconButtonStyleSheetVars; | ||
}): IconButtonStyleSheet => { | ||
const { vars } = params; | ||
const { style } = vars; | ||
return StyleSheet.create({ | ||
base: Object.assign( | ||
{ | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
height: 32, | ||
width: 32, | ||
} as ViewStyle, | ||
style, | ||
) as ViewStyle, | ||
}); | ||
}; | ||
|
||
export default styleSheet; |
18 changes: 18 additions & 0 deletions
18
app/component-library/components/IconButton/IconButton.test.tsx
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,18 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import { IconName } from '../Icon'; | ||
import IconButton from './IconButton'; | ||
import { IconButtonVariant } from './IconButton.types'; | ||
|
||
describe('IconButton', () => { | ||
it('should render correctly', () => { | ||
const wrapper = shallow( | ||
<IconButton | ||
variant={IconButtonVariant.Primary} | ||
icon={IconName.AddSquareFilled} | ||
onPress={jest.fn} | ||
/>, | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); |
69 changes: 69 additions & 0 deletions
69
app/component-library/components/IconButton/IconButton.tsx
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,69 @@ | ||
/* eslint-disable react/prop-types */ | ||
import React, { useCallback, useMemo, useState } from 'react'; | ||
import { GestureResponderEvent, TouchableOpacity } from 'react-native'; | ||
import { useStyles } from '../../../component-library/hooks'; | ||
import Icon, { IconSize } from '../Icon'; | ||
import stylesheet from './IconButton.styles'; | ||
import { IconButtonProps, IconButtonVariant } from './IconButton.types'; | ||
|
||
const IconButton = ({ | ||
icon, | ||
variant, | ||
disabled, | ||
onPressIn, | ||
onPressOut, | ||
style, | ||
...props | ||
}: IconButtonProps) => { | ||
const { | ||
styles, | ||
theme: { colors }, | ||
} = useStyles(stylesheet, { style }); | ||
const [pressed, setPressed] = useState(false); | ||
const iconColor = useMemo(() => { | ||
let color: string; | ||
if (disabled) { | ||
color = colors.icon.muted; | ||
} else { | ||
switch (variant) { | ||
case IconButtonVariant.Primary: | ||
color = pressed ? colors.primary.alternative : colors.primary.default; | ||
break; | ||
case IconButtonVariant.Secondary: | ||
color = pressed ? colors.icon.alternative : colors.icon.default; | ||
break; | ||
} | ||
} | ||
return color; | ||
}, [colors, variant, disabled, pressed]); | ||
|
||
const triggerOnPressedIn = useCallback( | ||
(e: GestureResponderEvent) => { | ||
setPressed(true); | ||
onPressIn?.(e); | ||
}, | ||
[setPressed, onPressIn], | ||
); | ||
|
||
const triggerOnPressedOut = useCallback( | ||
(e: GestureResponderEvent) => { | ||
setPressed(false); | ||
onPressOut?.(e); | ||
}, | ||
[setPressed, onPressOut], | ||
); | ||
|
||
return ( | ||
<TouchableOpacity | ||
style={styles.base} | ||
onPressIn={triggerOnPressedIn} | ||
onPressOut={triggerOnPressedOut} | ||
activeOpacity={1} | ||
{...props} | ||
> | ||
<Icon name={icon} size={IconSize.Lg} color={iconColor} /> | ||
</TouchableOpacity> | ||
); | ||
}; | ||
|
||
export default IconButton; |
37 changes: 37 additions & 0 deletions
37
app/component-library/components/IconButton/IconButton.types.ts
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,37 @@ | ||
import { TouchableOpacityProps, ViewStyle } from 'react-native'; | ||
import { IconProps } from '../Icon/Icon.types'; | ||
|
||
export enum IconButtonVariant { | ||
Primary = 'Primary', | ||
Secondary = 'Secondary', | ||
} | ||
|
||
/** | ||
* IconButton component props. | ||
*/ | ||
export interface IconButtonProps extends TouchableOpacityProps { | ||
/** | ||
* Icon to use. | ||
*/ | ||
icon: IconProps['name']; | ||
/** | ||
* Function to trigger when pressed. | ||
*/ | ||
onPress: () => void; | ||
/** | ||
* Enum to select between variants. | ||
*/ | ||
variant: IconButtonVariant; | ||
} | ||
|
||
/** | ||
* IconButton component style sheet. | ||
*/ | ||
export interface IconButtonStyleSheet { | ||
base: ViewStyle; | ||
} | ||
|
||
/** | ||
* Style sheet input parameters. | ||
*/ | ||
export type IconButtonStyleSheetVars = Pick<IconButtonProps, 'style'>; |
Oops, something went wrong.