Skip to content

Commit 347ecb8

Browse files
Fix incorrect default border color for TextInput (#1587)
Resolves #1581
1 parent e284655 commit 347ecb8

File tree

5 files changed

+88
-71
lines changed

5 files changed

+88
-71
lines changed

src/file-picker/__tests__/__snapshots__/FilePicker.test.js.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exports[`<FilePicker /> snapshot - multiple files selected 1`] = `
1212
/>
1313
<input
1414
aria-invalid="false"
15-
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_1px-solid-transparent ub-b-lft_1px-solid-transparent ub-b-rgt_1px-solid-transparent ub-b-top_1px-solid-transparent ub-otln_iu2jf4 ub-txt-deco_none ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-ln-ht_16px ub-fnt-sze_12px ub-color_474d66 ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
15+
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_none ub-b-lft_none ub-b-rgt_none ub-b-top_none ub-otln_iu2jf4 ub-txt-deco_none ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-b-btm-stl_solid ub-b-lft-stl_solid ub-b-rgt-stl_solid ub-b-top-stl_solid ub-b-btm-wdt_1px ub-b-lft-wdt_1px ub-b-rgt-wdt_1px ub-b-top-wdt_1px ub-color_474d66 ub-fnt-sze_12px ub-ln-ht_16px ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
1616
placeholder="Select a file to upload…"
1717
readonly=""
1818
spellcheck="true"
@@ -40,7 +40,7 @@ exports[`<FilePicker /> snapshot - no file selected 1`] = `
4040
/>
4141
<input
4242
aria-invalid="false"
43-
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_1px-solid-transparent ub-b-lft_1px-solid-transparent ub-b-rgt_1px-solid-transparent ub-b-top_1px-solid-transparent ub-otln_iu2jf4 ub-txt-deco_none ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-ln-ht_16px ub-fnt-sze_12px ub-color_474d66 ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
43+
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_none ub-b-lft_none ub-b-rgt_none ub-b-top_none ub-otln_iu2jf4 ub-txt-deco_none ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-b-btm-stl_solid ub-b-lft-stl_solid ub-b-rgt-stl_solid ub-b-top-stl_solid ub-b-btm-wdt_1px ub-b-lft-wdt_1px ub-b-rgt-wdt_1px ub-b-top-wdt_1px ub-color_474d66 ub-fnt-sze_12px ub-ln-ht_16px ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
4444
placeholder="Select a file to upload…"
4545
readonly=""
4646
spellcheck="true"
@@ -68,7 +68,7 @@ exports[`<FilePicker /> snapshot - one file seleted 1`] = `
6868
/>
6969
<input
7070
aria-invalid="false"
71-
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_1px-solid-transparent ub-b-lft_1px-solid-transparent ub-b-rgt_1px-solid-transparent ub-b-top_1px-solid-transparent ub-otln_iu2jf4 ub-txt-deco_none ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-ln-ht_16px ub-fnt-sze_12px ub-color_474d66 ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
71+
class="evergreen-file-picker-text-input ub-w_280px ub-fnt-fam_b77syt ub-b-btm_none ub-b-lft_none ub-b-rgt_none ub-b-top_none ub-otln_iu2jf4 ub-txt-deco_none ub-b-btm-clr_d8dae5 ub-b-lft-clr_d8dae5 ub-b-rgt-clr_d8dae5 ub-b-top-clr_d8dae5 ub-bblr_4px ub-bbrr_0-important ub-btlr_4px ub-btrr_0-important ub-b-btm-stl_solid ub-b-lft-stl_solid ub-b-rgt-stl_solid ub-b-top-stl_solid ub-b-btm-wdt_1px ub-b-lft-wdt_1px ub-b-rgt-wdt_1px ub-b-top-wdt_1px ub-color_474d66 ub-fnt-sze_12px ub-ln-ht_16px ub-pl_12px ub-pr_12px ub-tstn_n1akt6 ub-h_32px ub-bg-clr_white ub-color_8f95b2_1b2gqua ub-crsr_not-allowed_10nxvc1 ub-bg-clr_F4F5F9_10nxvc1 ub-color_696f8c_10nxvc1 ub-z-idx_2_1bcl2f4 ub-bs_13po50p_1bcl2f4 ub-b-btm-clr_ADC2FF_1bcl2f4 ub-b-lft-clr_ADC2FF_1bcl2f4 ub-b-rgt-clr_ADC2FF_1bcl2f4 ub-b-top-clr_ADC2FF_1bcl2f4 ub-b-btm-clr_D14343_fpx4do ub-b-lft-clr_D14343_fpx4do ub-b-rgt-clr_D14343_fpx4do ub-b-top-clr_D14343_fpx4do ub-flx_1 ub-txt-ovrf_ellipsis ub-f-wght_400 ub-ltr-spc_0 ub-box-szg_border-box"
7272
placeholder="Select a file to upload…"
7373
readonly=""
7474
spellcheck="true"

src/file-uploader/stories/index.stories.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Button } from '../../buttons'
55
import { MimeType } from '../../constants'
66
import { FileUploader, FileCard } from '../../file-uploader'
77
import { majorScale } from '../../scales'
8+
import { TextInput } from '../../text-input'
89
import { toaster } from '../../toaster'
910
import { Label, Code, ListItem } from '../../typography'
1011
import getIconFromType from '../src/utils/get-icon-from-type'
@@ -76,6 +77,10 @@ storiesOf('file-uploader', module)
7677
label="Custom validation message"
7778
validationMessage="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum metus elit, varius non euismod non, tempor sit amet sem. Praesent quis eros finibus, tempor diam quis, lacinia tortor."
7879
/>
80+
81+
{/* https://github.com/segmentio/evergreen/issues/1581 */}
82+
<FileUploaderState label="#1581 With TextInput rendered on same page" />
83+
<TextInput />
7984
</Box>
8085
))
8186
.add('FileCard', () => (
Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import React, { useState } from 'react'
2-
import { render } from '@testing-library/react'
2+
import { render, screen } from '@testing-library/react'
33
import userEvent from '@testing-library/user-event'
4-
import { TextInput, TextInputField } from '../'
4+
import { TextInput } from '../'
55
import { mockRef } from '../../test/utils'
6+
import colors from '../../themes/default/tokens/colors'
67

78
function makeTextInputFixture(props = {}) {
89
return <TextInput data-testid="input" {...props} />
910
}
1011

11-
function makeTextInputFieldFixture(props = {}) {
12-
return <TextInputField data-testid="input" label="Name" {...props} />
13-
}
14-
1512
describe('TextInput', () => {
1613
it('should forward ref to underlying <input />', () => {
1714
const ref = mockRef()
@@ -26,16 +23,15 @@ describe('TextInput', () => {
2623
})
2724

2825
it('should accept placeholder text', () => {
29-
const { getByPlaceholderText } = render(makeTextInputFixture({ placeholder: 'Enter text here' }))
26+
render(makeTextInputFixture({ placeholder: 'Enter text here' }))
3027

31-
expect(getByPlaceholderText('Enter text here')).toBeInTheDocument()
28+
expect(screen.getByPlaceholderText('Enter text here')).toBeInTheDocument()
3229
})
3330

3431
it('should set an invalid state if `isInvalid` is `true`', () => {
35-
const { getByTestId } = render(makeTextInputFixture({ isInvalid: true }))
36-
const input = getByTestId('input')
32+
render(makeTextInputFixture({ isInvalid: true }))
3733

38-
expect(input).toHaveAttribute('aria-invalid', 'true')
34+
expect(screen.getByTestId('input')).toHaveAttribute('aria-invalid', 'true')
3935
})
4036

4137
it('should accept an `onChange` handler to be a controlled component', () => {
@@ -51,60 +47,56 @@ describe('TextInput', () => {
5147
)
5248
}
5349

54-
const { getByDisplayValue, getByTestId } = render(<ControlledTextInput />)
55-
const input = getByTestId('input')
50+
render(<ControlledTextInput />)
51+
const input = screen.getByTestId('input')
5652
userEvent.click(input)
5753

5854
expect(document.activeElement).toEqual(input)
5955
userEvent.type(input, 'Testing')
60-
expect(getByDisplayValue('Testing')).toEqual(input)
56+
expect(screen.getByDisplayValue('Testing')).toEqual(input)
6157
})
6258

6359
it('should not be interactive if `disabled` is passed in', () => {
64-
const { getByDisplayValue, getByTestId } = render(makeTextInputFixture({ disabled: true }))
65-
const input = getByTestId('input')
60+
render(makeTextInputFixture({ disabled: true }))
61+
const input = screen.getByTestId('input')
6662
userEvent.type(input, 'Testing')
6763

68-
expect(() => getByDisplayValue('Testing')).toThrowError()
69-
expect(getByDisplayValue('')).toEqual(input)
70-
})
71-
})
72-
73-
describe('TextInputField', () => {
74-
it('Should render without crashing', () => {
75-
expect(() => render(makeTextInputFieldFixture())).not.toThrow()
76-
})
77-
78-
it('Should have expected accessible name when `label` prop', () => {
79-
const { getByLabelText, getByTestId } = render(makeTextInputFieldFixture())
80-
expect(getByLabelText('Name')).toBeInTheDocument()
81-
expect(getByTestId('input')).toHaveAccessibleName('Name')
82-
})
83-
84-
it('Should add hint text to accessible description when `hint` prop provided', () => {
85-
const { getByTestId, getByText } = render(makeTextInputFieldFixture({ hint: 'Enter a value in the input' }))
86-
expect(getByText('Enter a value in the input')).toBeInTheDocument()
87-
expect(getByTestId('input')).toHaveAccessibleDescription('Enter a value in the input')
88-
})
89-
90-
it('Should render an astrix when `required` is passed in', () => {
91-
const { getByTitle } = render(makeTextInputFieldFixture({ required: true }))
92-
expect(getByTitle('This field is required.')).toBeInTheDocument()
64+
expect(() => screen.getByDisplayValue('Testing')).toThrowError()
65+
expect(screen.getByDisplayValue('')).toEqual(input)
9366
})
9467

95-
it('Should render a `validationMessage` when passed in', () => {
96-
const { getByTestId, getByText } = render(makeTextInputFieldFixture({ validationMessage: 'Please enter a value.' }))
97-
expect(getByText('Please enter a value.')).toBeInTheDocument()
98-
expect(getByTestId('input')).toHaveAccessibleDescription('Please enter a value.')
68+
it.each([undefined, 'default'])('should render with gray400 border when appearance is %p', appearance => {
69+
render(makeTextInputFixture({ appearance }))
70+
71+
// For some reason we were applying a border: 1px solid transparent style and then overriding it with
72+
// the individual borderColor style, see https://github.com/segmentio/evergreen/issues/1581
73+
expect(screen.getByTestId('input')).not.toHaveStyle({
74+
borderTop: '1px solid transparent',
75+
borderBottom: '1px solid transparent',
76+
borderLeft: '1px solid transparent',
77+
borderRight: '1px solid transparent'
78+
})
79+
80+
// ui-box splits the borderColor prop into individual sides/styles, so border: colors.gray400
81+
// won't pass this test
82+
expect(screen.getByTestId('input')).toHaveStyle({
83+
borderTopColor: colors.gray400,
84+
borderBottomColor: colors.gray400,
85+
borderLeftColor: colors.gray400,
86+
borderRightColor: colors.gray400
87+
})
9988
})
10089

101-
it('Should correctly compose an accessible description from multiple hints', () => {
102-
const { getByTestId, getByText } = render(
103-
makeTextInputFieldFixture({ description: 'A description.', hint: 'Am hint.', validationMessage: 'Try again.' })
104-
)
105-
expect(getByText('A description.')).toBeInTheDocument()
106-
expect(getByText('Am hint.')).toBeInTheDocument()
107-
expect(getByText('Try again.')).toBeInTheDocument()
108-
expect(getByTestId('input')).toHaveAccessibleDescription('A description. Try again. Am hint.')
90+
it('should render with transparent border when appearance is none', () => {
91+
render(makeTextInputFixture({ appearance: 'none' }))
92+
93+
// For some reason we were applying a border: 1px solid transparent style and then overriding it with
94+
// the individual borderColor style, see https://github.com/segmentio/evergreen/issues/1581
95+
expect(screen.getByTestId('input')).toHaveStyle({
96+
borderTop: '1px solid transparent',
97+
borderBottom: '1px solid transparent',
98+
borderLeft: '1px solid transparent',
99+
borderRight: '1px solid transparent'
100+
})
109101
})
110102
})
Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import { render } from '@testing-library/react'
2+
import { render, screen } from '@testing-library/react'
33
import { TextInputField } from '../'
44

55
function makeTextInputFieldFixture(props = {}) {
@@ -11,23 +11,40 @@ describe('TextInputField', () => {
1111
expect(() => render(makeTextInputFieldFixture())).not.toThrow()
1212
})
1313

14-
it('should render a required `label` when passed in', () => {
15-
const { getByLabelText } = render(makeTextInputFieldFixture())
16-
expect(getByLabelText('Name')).toBeInTheDocument()
14+
it('should have expected accessible name when `label` prop', () => {
15+
render(makeTextInputFieldFixture())
16+
17+
expect(screen.getByLabelText('Name')).toBeInTheDocument()
18+
expect(screen.getByTestId('input')).toHaveAccessibleName('Name')
1719
})
1820

19-
it('should render a `hint` underneath the input', () => {
20-
const { getByText } = render(makeTextInputFieldFixture({ hint: 'Enter a value in the input' }))
21-
expect(getByText('Enter a value in the input')).toBeInTheDocument()
21+
it('should add hint text to accessible description when `hint` prop provided', () => {
22+
render(makeTextInputFieldFixture({ hint: 'Enter a value in the input' }))
23+
expect(screen.getByText('Enter a value in the input')).toBeInTheDocument()
24+
expect(screen.getByTestId('input')).toHaveAccessibleDescription('Enter a value in the input')
2225
})
2326

2427
it('should render an astrix when `required` is passed in', () => {
25-
const { getByTitle } = render(makeTextInputFieldFixture({ required: true }))
26-
expect(getByTitle('This field is required.')).toBeInTheDocument()
28+
render(makeTextInputFieldFixture({ required: true }))
29+
30+
expect(screen.getByTitle('This field is required.')).toBeInTheDocument()
31+
})
32+
33+
it('should render a `validationMessage` when passed in', () => {
34+
render(makeTextInputFieldFixture({ validationMessage: 'Please enter a value.' }))
35+
36+
expect(screen.getByText('Please enter a value.')).toBeInTheDocument()
37+
expect(screen.getByTestId('input')).toHaveAccessibleDescription('Please enter a value.')
2738
})
2839

29-
it('should not render a `validationMessage` when passed in', () => {
30-
const { getByText } = render(makeTextInputFieldFixture({ validationMessage: 'Please enter a value' }))
31-
expect(getByText('Please enter a value')).toBeInTheDocument()
40+
it('should correctly compose an accessible description from multiple hints', () => {
41+
render(
42+
makeTextInputFieldFixture({ description: 'A description.', hint: 'Am hint.', validationMessage: 'Try again.' })
43+
)
44+
45+
expect(screen.getByText('A description.')).toBeInTheDocument()
46+
expect(screen.getByText('Am hint.')).toBeInTheDocument()
47+
expect(screen.getByText('Try again.')).toBeInTheDocument()
48+
expect(screen.getByTestId('input')).toHaveAccessibleDescription('A description. Try again. Am hint.')
3249
})
3350
})

src/themes/default/components/input.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
const baseStyle = {
2+
borderColor: 'colors.gray400',
23
borderRadius: 'radii.1',
4+
borderStyle: 'solid',
5+
borderWidth: 1,
6+
color: 'colors.default',
37
fontFamily: 'fontFamilies.ui',
4-
lineHeight: 'lineHeights.0',
58
fontSize: 'fontSizes.1',
6-
border: '1px solid transparent',
7-
color: 'colors.default',
9+
lineHeight: 'lineHeights.0',
810
paddingX: 12,
911
transition: 'box-shadow 80ms ease-in-out',
1012

@@ -39,6 +41,7 @@ const appearances = {
3941
}
4042
},
4143
none: {
44+
borderColor: 'transparent',
4245
backgroundColor: 'transparent'
4346
}
4447
}

0 commit comments

Comments
 (0)