Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Component Implementation - Button #34

Merged
merged 74 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
bdde4f5
Finished all variants
narin Nov 6, 2023
4c5dca3
Refactor to use buttonType. Add white variant
narin Nov 8, 2023
73615cb
Add unit tests
narin Nov 8, 2023
6e4cac8
Add color tokens
narin Nov 8, 2023
60208d3
Version bump: tokens-v0.0.13-alpha.0
va-mobile-automation-robot Nov 8, 2023
1265e91
Fix red color values
narin Nov 8, 2023
4c6cb6a
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 8, 2023
20e4377
Add primary-darker color
narin Nov 8, 2023
f8e311a
Version bump: tokens-v0.0.13-alpha.2
va-mobile-automation-robot Nov 8, 2023
cee8a51
Add blue-vivid-30
narin Nov 8, 2023
3c414b1
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 8, 2023
fba51b8
Version bump: tokens-v0.0.13-alpha.3
va-mobile-automation-robot Nov 8, 2023
279daaf
Version bump: tokens-v0.1.0
va-mobile-automation-robot Nov 8, 2023
96971bf
Use tokenized colors
narin Nov 8, 2023
754f314
Remove White story. Add a11yhint in Primary example
narin Nov 8, 2023
1662034
Version bump: components-v0.1.1-alpha.0
va-mobile-automation-robot Nov 8, 2023
a1cd6ff
export VAButton in index.tsx
narin Nov 8, 2023
83ccad2
Version bump: components-v0.1.1-alpha.1
va-mobile-automation-robot Nov 8, 2023
9dfcb9d
Export ButtonTypes
narin Nov 8, 2023
ea6e190
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 8, 2023
3534b11
Version bump: components-v0.1.1-alpha.2
va-mobile-automation-robot Nov 8, 2023
5644693
Refactor VAButton constants and types into enum
narin Nov 8, 2023
80aaac4
Version bump: components-v0.1.1-alpha.3
va-mobile-automation-robot Nov 8, 2023
daaf163
Add tsdoc
narin Nov 8, 2023
488e51c
Export VAButtonVariants
narin Nov 8, 2023
92aafe4
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 8, 2023
dd60e3e
Version bump: components-v0.1.1-alpha.4
va-mobile-automation-robot Nov 8, 2023
36014a9
Remove console log
narin Nov 8, 2023
69a34b2
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 8, 2023
2cdfa2c
Merge branch 'main' into 6870-nr-vabutton
narin Nov 8, 2023
e3e9f4d
Commit updated yarn.lock
narin Nov 8, 2023
f599981
Version bump: components-v0.1.1-alpha.5
va-mobile-automation-robot Nov 8, 2023
3aa460d
Merge branch 'main' into 6870-nr-vabutton
TimRoe Nov 8, 2023
5bee594
Clean up. Add gray colors for base style
narin Nov 9, 2023
2dcccdd
Version bump: tokens-v0.1.1-alpha.0
va-mobile-automation-robot Nov 9, 2023
47d78c5
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
4b59999
Version bump: components-v0.1.1-alpha.6
va-mobile-automation-robot Nov 9, 2023
6bac3e2
Rename VAButton to Button. Refactor styling to use switch statement. …
narin Nov 9, 2023
3718e21
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
3bdd553
Version bump: tokens-v0.1.1-alpha.1
va-mobile-automation-robot Nov 9, 2023
ac99554
Add base variants. Move borderWidth into switch statement
narin Nov 9, 2023
b0fd79c
Add unit tests
narin Nov 9, 2023
a37d505
Version bump: tokens-v0.2.0
va-mobile-automation-robot Nov 9, 2023
a76a7fe
Added a11yLabel example to Base story
narin Nov 9, 2023
3b9b7b8
Bump to use 0.2.0 of tokens
narin Nov 9, 2023
d91c2cc
yarn lock commits
narin Nov 9, 2023
87e8d98
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
a36f94e
Commit root yarn.lock
narin Nov 9, 2023
2902e3e
Version bump: components-v0.1.1-alpha.7
va-mobile-automation-robot Nov 9, 2023
5b9ecde
Add @storybook/addon-docs. Add docs link to Button story
narin Nov 9, 2023
1dffeeb
Version bump: components-v0.1.1-alpha.9
va-mobile-automation-robot Nov 9, 2023
d9ec113
Separate storybook utils
narin Nov 9, 2023
39a42a4
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
5479bb3
Version bump: components-v0.1.1-alpha.10
va-mobile-automation-robot Nov 9, 2023
41697b2
Fix storybook util import
narin Nov 9, 2023
0efee64
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
51b03a2
Version bump: components-v0.1.1-alpha.11
va-mobile-automation-robot Nov 9, 2023
1feef56
Isolate @storybook/addon-docs imports
narin Nov 9, 2023
76b1a9b
Version bump: components-v0.1.1-alpha.12
va-mobile-automation-robot Nov 9, 2023
f0b50d1
Add missing react import
narin Nov 9, 2023
76e3cee
Merge branch '6870-nr-vabutton' of github.com:department-of-veterans-…
narin Nov 9, 2023
252de4a
Version bump: components-v0.1.1-alpha.13
va-mobile-automation-robot Nov 9, 2023
68b132b
webStorybookColorScheme fix, storybook-dark-mode devDependency'd
TimRoe Nov 15, 2023
747e61c
Set enum string values
narin Nov 16, 2023
9f6a783
Update/add a11y labels and hints
narin Nov 16, 2023
ce5d3a5
Group variant tests
narin Nov 16, 2023
c1ccd01
Grouped tests with default (primary) variant
narin Nov 16, 2023
fe1be63
Cleaned up pressed logic
narin Nov 16, 2023
72ce74c
Combined imports
narin Nov 16, 2023
13fa90c
Version bump: components-v0.1.1-alpha.14
va-mobile-automation-robot Nov 16, 2023
c78fb9c
Further fixing webStorybookColorScheme, removing DOM stuff from npm p…
TimRoe Nov 16, 2023
e27de2d
Version bump: components-v0.1.1-alpha.15
va-mobile-automation-robot Nov 16, 2023
3e74b2e
Version bump: components-v0.2.0
va-mobile-automation-robot Nov 16, 2023
6e53452
Trigger GitHub status checks
narin Nov 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ try {
const getStories = () => {
return {
"./src/components/SegmentedControl/SegmentedControl.stories.tsx": require("../../src/components/SegmentedControl/SegmentedControl.stories.tsx"),
"./src/components/VAButton/VAButton.stories.tsx": require("../../src/components/VAButton/VAButton.stories.tsx"),
};
};

Expand Down
4 changes: 2 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@department-of-veterans-affairs/mobile-component-library",
"version": "0.1.0",
"version": "0.1.1-alpha.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just adding a preemptive note that should bump to 0.2.0 in the pre-merge publish.

"description": "VA Design System Mobile Component Library",
"main": "src/index.tsx",
"scripts": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://department-of-veterans-affairs.github.io/va-mobile-library",
"dependencies": {
"@department-of-veterans-affairs/mobile-tokens": "0.0.10",
"@department-of-veterans-affairs/mobile-tokens": "0.1.0",
"@os-team/i18next-react-native-language-detector": "^1.0.28",
"i18next": "^23.4.3",
"react-i18next": "^13.0.3",
Expand Down
56 changes: 56 additions & 0 deletions packages/components/src/components/VAButton/VAButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Meta, StoryObj } from '@storybook/react-native'
import { VAButton, VAButtonProps, VAButtonVariants } from './VAButton'
import { View } from 'react-native'
import React from 'react'

const meta: Meta<VAButtonProps> = {
title: 'VAButton',
component: VAButton,
argTypes: {
onPress: {
action: 'onPress event',
},
},

decorators: [
(Story) => (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Story />
</View>
),
],
}

export default meta

type Story = StoryObj<VAButtonProps>

export const Primary: Story = {
storyName: 'Primary',
args: {
narin marked this conversation as resolved.
Show resolved Hide resolved
label: 'Button text',
a11yHint: 'My hint',
},
}

export const Secondary: Story = {
storyName: 'Secondary',
args: {
buttonType: VAButtonVariants.Secondary,
label: 'Button text',
},
}

narin marked this conversation as resolved.
Show resolved Hide resolved
export const Destructive: Story = {
storyName: 'Destructive',
args: {
buttonType: VAButtonVariants.Destructive,
label: 'Button text',
},
}
38 changes: 38 additions & 0 deletions packages/components/src/components/VAButton/VAButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'react-native'
import { RenderAPI, fireEvent, render } from '@testing-library/react-native'
import React from 'react'
// Note: test renderer must be required after react-native.
import 'jest-styled-components'
import { ReactTestInstance } from 'react-test-renderer'

import { VAButton } from './VAButton'

describe('VAButton', () => {
narin marked this conversation as resolved.
Show resolved Hide resolved
let component: RenderAPI
let testInstance: ReactTestInstance

const onPressSpy = jest.fn()

const initializeTestInstance = (): void => {
component = render(<VAButton label="Button text" onPress={onPressSpy} />)

testInstance = component.UNSAFE_root
}

beforeEach(() => {
initializeTestInstance()
})

it('initializes correctly', async () => {
expect(component).toBeTruthy()
})

it('should call onChange', async () => {
fireEvent.press(testInstance)
expect(onPressSpy).toBeCalled()
})

it('should render label', async () => {
expect(component.findByText('Button text')).toBeTruthy()
})
})
153 changes: 153 additions & 0 deletions packages/components/src/components/VAButton/VAButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import * as DesignTokens from '@department-of-veterans-affairs/mobile-tokens'
import {
AccessibilityState,
Pressable,
PressableStateCallbackType,
Text,
TextStyle,
ViewStyle,
useColorScheme,
} from 'react-native'
import React from 'react'

import { webStorybookColorScheme } from '../../utils'

export enum VAButtonVariants {
Primary,
Secondary,
Destructive,
White,
}

export type VAButtonProps = {
/** text appearing in the button */
label: string
/** function called when button is pressed */
onPress: () => void
/** optional accessibility state */
accessibilityState?: AccessibilityState
/** text to use as the accessibility hint */
a11yHint?: string
/** specifies button styling type. defaults to primary if none specified */
buttonType?: VAButtonVariants
/** a string value used to set the buttons testID/accessibility label */
narin marked this conversation as resolved.
Show resolved Hide resolved
testID?: string
}

export const VAButton: React.FC<VAButtonProps> = ({
narin marked this conversation as resolved.
Show resolved Hide resolved
label,
onPress,
accessibilityState,
a11yHint,
buttonType,
testID,
}) => {
const colorScheme = webStorybookColorScheme() || useColorScheme()
const isDestructive = buttonType === VAButtonVariants.Destructive
const isSecondary = buttonType === VAButtonVariants.Secondary
const isWhite = buttonType === VAButtonVariants.White

let bgColor: string,
bgColorPressed: string,
textColor: string,
textColorPressed: string,
borderColor: string = 'none',
borderColorPressed: string = 'none'

if (isWhite) {
narin marked this conversation as resolved.
Show resolved Hide resolved
// This is a one-off, mobile app only variant. Colors are not tokenized
bgColor = DesignTokens.colorWhite
bgColorPressed = '#ffffffb3'
textColor = '#003e73'
} else if (colorScheme === 'light') {
bgColor = DesignTokens.colorUswdsSystemColorBlueVivid60
bgColorPressed = DesignTokens.colorUswdsSystemColorBlueWarmVivid80
textColor = DesignTokens.colorGrayLightest
textColorPressed = DesignTokens.colorGrayLightest

if (isDestructive) {
bgColor = DesignTokens.colorUswdsSystemColorRedVivid60
bgColorPressed = DesignTokens.colorUswdsSystemColorRedVivid80
} else if (isSecondary) {
bgColor = DesignTokens.colorWhite
bgColorPressed = DesignTokens.colorWhite
borderColor = DesignTokens.colorUswdsSystemColorBlueVivid60
borderColorPressed = DesignTokens.colorUswdsSystemColorBlueWarmVivid80
textColor = DesignTokens.colorUswdsSystemColorBlueVivid60
textColorPressed = DesignTokens.colorUswdsSystemColorBlueWarmVivid80
}
} else {
bgColor = DesignTokens.colorUswdsSystemColorBlueVivid30
bgColorPressed = DesignTokens.colorPrimaryAltLightest
textColor = DesignTokens.colorBlack
textColorPressed = DesignTokens.colorBlack

if (isDestructive) {
bgColor = DesignTokens.colorUswdsSystemColorRedVivid40
bgColorPressed = DesignTokens.colorSecondaryLightest
} else if (isSecondary) {
bgColor = DesignTokens.colorBlack
bgColorPressed = DesignTokens.colorBlack
borderColor = DesignTokens.colorUswdsSystemColorBlueVivid60
borderColorPressed = DesignTokens.colorWhite
textColor = DesignTokens.colorUswdsSystemColorBlueVivid30
textColorPressed = DesignTokens.colorWhite
}
}

/**
* Get button styling based on pressed state
* @param pressed - boolean for pressed state
* @returns ViewStyle for background
*/
const getBackgroundStyle = ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe fine to leave it be for now, but wonder if we should make a more generalized function to handle this behavior. Could also be used by the util function PressableOpacityStyle I'd made as a convenient specific case as well as for getTextStyle below.

Basically a function that takes:

  • Consistent styles that don't change
  • Pressed styles
  • Non-pressed styles
    and pulls some complexity out of living at the component level by just passing style const's.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't have time to implement something like this with me leaving for vacation, but I agree it could be useful as we're likely to be styling Pressable's in the future. I've created a ticket to work on this util function: https://github.com/department-of-veterans-affairs/va-mobile-app/issues/7240

pressed,
}: PressableStateCallbackType): ViewStyle => ({
alignSelf: 'stretch',
alignItems: 'center',
padding: 10,
backgroundColor: pressed ? bgColorPressed : bgColor,
borderRadius: 4,
borderWidth: isSecondary ? 2 : 0,
borderColor: isSecondary
? pressed
? borderColorPressed
: borderColor
: 'none',
})

/**
* Get text styling based on pressed state
* @param pressed - boolean for pressed state
* @returns TextStyle for text
*/
const getTextStyle = (pressed: boolean): TextStyle => {
// TODO: Replace with typography tokens
const font: TextStyle = {
fontFamily: 'SourceSansPro-Bold',
fontSize: 20,
lineHeight: 30,
}

return {
...font,
color: pressed ? textColorPressed : textColor,
}
}

return (
<Pressable
style={getBackgroundStyle}
onPress={onPress}
accessibilityHint={a11yHint}
accessibilityRole="button"
narin marked this conversation as resolved.
Show resolved Hide resolved
accessible={true}
accessibilityState={accessibilityState || {}}
narin marked this conversation as resolved.
Show resolved Hide resolved
testID={testID || label}
>
{({ pressed }: PressableStateCallbackType) => (
<Text style={getTextStyle(pressed)}>{label}</Text>
)}
</Pressable>
)
}
1 change: 1 addition & 0 deletions packages/components/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ if (expoApp && App.initiateExpo) {

// Export components here so they are exported through npm
export { SegmentedControl } from './components/SegmentedControl/SegmentedControl'
export { VAButton, VAButtonVariants } from './components/VAButton/VAButton'
10 changes: 5 additions & 5 deletions packages/components/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2929,7 +2929,7 @@ __metadata:
"@babel/plugin-transform-react-jsx": ^7.22.15
"@babel/preset-env": ^7.22.15
"@babel/preset-typescript": ^7.22.15
"@department-of-veterans-affairs/mobile-tokens": 0.0.10
"@department-of-veterans-affairs/mobile-tokens": 0.1.0
"@expo/webpack-config": ^19.0.0
"@os-team/i18next-react-native-language-detector": ^1.0.28
"@react-native-async-storage/async-storage": 1.18.2
Expand Down Expand Up @@ -2988,10 +2988,10 @@ __metadata:
languageName: unknown
linkType: soft

"@department-of-veterans-affairs/mobile-tokens@npm:0.0.10":
version: 0.0.10
resolution: "@department-of-veterans-affairs/mobile-tokens@npm:0.0.10"
checksum: 7590c87fb87e72891fe270f9dc53be8af3d0471d43cd448ead234b40d3f1fd5612740f049c121062c2beffd2597e81fa4e705e808bf3dc3110c33fbc1213f928
"@department-of-veterans-affairs/mobile-tokens@npm:0.1.0":
version: 0.1.0
resolution: "@department-of-veterans-affairs/mobile-tokens@npm:0.1.0"
checksum: 4d44c25ed247254b39df746b4de9d518d80c8624d973d5277a11a9f9d011155a59cf24aee0dc9aaae493db409a60b75b00f1a05dc5f18317efaf64f5f472ff99
languageName: node
linkType: hard

Expand Down
2 changes: 1 addition & 1 deletion packages/tokens/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@department-of-veterans-affairs/mobile-tokens",
"version": "0.0.12",
"version": "0.1.0",
"description": "VA Design System Mobile Token Library",
"main": "dist/js/tokens.js",
"types": "dist/index.d.ts",
Expand Down
36 changes: 36 additions & 0 deletions packages/tokens/src/tokens/colors.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
{
"color": {
"primary": {
"darker": {
"value": "#003e73"
},
"alt": {
"lightest": {
"value": "#e1f3f8"
}
}
},
"secondary": {
"lightest": {
"value": "#f9dede"
}
},
"white": {
"value": "#fff",
"attributes": {
"category": "color"
}
},
"black": {
"value": "#000000"
},
"gray": {
"*": {
"value": "#5b616b",
Expand Down Expand Up @@ -197,6 +215,24 @@
"cool-light"
]
}
},
"uswds-system-color-blue-vivid-30": {
"value": "#58b4ff"
},
"uswds-system-color-blue-vivid-60": {
"value": "#005ea2"
},
"uswds-system-color-blue-warm-vivid-80": {
"value": "#162e51"
},
"uswds-system-color-red-vivid-40": {
"value": "#FB5A47"
},
"uswds-system-color-red-vivid-60": {
"value": "#b50909"
},
"uswds-system-color-red-vivid-80": {
"value": "#5C1111"
}
}
}
11 changes: 2 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2707,7 +2707,7 @@ __metadata:
"@babel/plugin-transform-react-jsx": ^7.22.15
"@babel/preset-env": ^7.22.15
"@babel/preset-typescript": ^7.22.15
"@department-of-veterans-affairs/mobile-tokens": 0.0.10
"@department-of-veterans-affairs/mobile-tokens": 0.1.0
"@expo/webpack-config": ^19.0.0
"@os-team/i18next-react-native-language-detector": ^1.0.28
"@react-native-async-storage/async-storage": 1.18.2
Expand Down Expand Up @@ -2766,14 +2766,7 @@ __metadata:
languageName: unknown
linkType: soft

"@department-of-veterans-affairs/mobile-tokens@npm:0.0.10":
version: 0.0.10
resolution: "@department-of-veterans-affairs/mobile-tokens@npm:0.0.10"
checksum: 7590c87fb87e72891fe270f9dc53be8af3d0471d43cd448ead234b40d3f1fd5612740f049c121062c2beffd2597e81fa4e705e808bf3dc3110c33fbc1213f928
languageName: node
linkType: hard

"@department-of-veterans-affairs/mobile-tokens@workspace:packages/tokens":
"@department-of-veterans-affairs/[email protected], @department-of-veterans-affairs/mobile-tokens@workspace:packages/tokens":
version: 0.0.0-use.local
resolution: "@department-of-veterans-affairs/mobile-tokens@workspace:packages/tokens"
dependencies:
Expand Down
Loading