Skip to content

Commit

Permalink
✨ Adornments support in Input component (#2354)
Browse files Browse the repository at this point in the history
* 🚧 WIP

* 📝 Added story

* wip

* 🚧 WIP

* 🚧 WIP

* 🚧 wip

* 🚚 Moved over `Input` adornment changes

* ♻️ Added `OldInput` for interim development

* 🐛 Fixed textarea outline

* ♻️ back to new input

* 🔥 removed OldInput

* Testing something old

* updated snapshots

* its something

* ♻️ working version before testing styles

* ♻️ Further testing and tweaking

* 📸 ✅ Updated test & snapshots

* ♻️ working example

* 🚚 Moved typographymixin

* ♻️ Started cleaning up helpertext
  • Loading branch information
mimarz committed Oct 4, 2022
1 parent 11507e8 commit c7c70f0
Show file tree
Hide file tree
Showing 24 changed files with 1,019 additions and 345 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const selectTokens: ComponentToken = {
entities: {
button: {
height: '24px',
width: '24px',
spacings: {
left: spacingSmall,
right: spacingSmall,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,6 @@ const Container = styled.div`
position: relative;
`

const StyledInput = styled(Input)(
({
theme: {
entities: { button },
},
}) => {
return css`
padding-right: calc(
${button.spacings.left} + ${button.spacings.right} +
(${button.height} * 2)
);
`
},
)

const StyledList = styled(List)(
({ theme }) => css`
background-color: ${theme.background};
Expand All @@ -75,11 +60,8 @@ const StyledButton = styled(Button)(
entities: { button },
},
}) => css`
position: absolute;
height: ${button.height};
width: ${button.height};
right: ${button.spacings.right};
top: ${button.spacings.top};
`,
)

Expand Down Expand Up @@ -589,7 +571,7 @@ function AutocompleteInner<T>(
/>

<Container {...getComboboxProps()}>
<StyledInput
<Input
{...getInputProps(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
getDropdownProps({
Expand All @@ -602,30 +584,38 @@ function AutocompleteInner<T>(
readOnly={readOnly}
onFocus={openSelect}
onClick={openSelect}
rightAdornmentsWidth={24 * 2 + 8 + 8}
rightAdornments={
<>
{showClearButton && (
<StyledButton
variant="ghost_icon"
disabled={disabled || readOnly}
aria-label={'clear options'}
title="clear"
onClick={clear}
>
<Icon data={close} size={16} />
</StyledButton>
)}
{!readOnly && (
<StyledButton
variant="ghost_icon"
{...getToggleButtonProps({
disabled: disabled || readOnly,
})}
aria-label={'toggle options'}
title="open"
>
<Icon
data={isOpen ? arrow_drop_up : arrow_drop_down}
></Icon>
</StyledButton>
)}
</>
}
{...other}
/>
{showClearButton && (
<StyledButton
variant="ghost_icon"
disabled={disabled || readOnly}
aria-label={'clear options'}
title="clear"
onClick={clear}
style={{ right: 32 }}
>
<Icon data={close} size={16} />
</StyledButton>
)}
<StyledButton
variant="ghost_icon"
{...getToggleButtonProps({ disabled: disabled || readOnly })}
aria-label={'toggle options'}
title="open"
>
{!readOnly && (
<Icon data={isOpen ? arrow_drop_up : arrow_drop_down}></Icon>
)}
</StyledButton>
</Container>
{disablePortal ? (
optionsList
Expand Down
7 changes: 6 additions & 1 deletion packages/eds-core-react/src/components/Input/Input.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ It's important to link the `Input` to the corresponding label.

Compact `Input` using `EdsProvider`.

<Story id="inputs-input--compact" />
<Story id="inputs-input--compact" />

### With Adornments


<Story id="inputs-input--with-adornments" />
131 changes: 129 additions & 2 deletions packages/eds-core-react/src/components/Input/Input.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { useState, useEffect } from 'react'
import { Story, ComponentMeta } from '@storybook/react'
import { anchor } from '@equinor/eds-icons'
import { Input, InputProps, Label, EdsProvider, Density } from '../..'
import { Story } from '@storybook/react/types-6-0'
import { ComponentMeta } from '@storybook/react'
import styled from 'styled-components'
import { Stack } from './../../../.storybook/components'
import page from './Input.docs.mdx'
import { Button } from '../Button'
import { Icon } from '../Icon'

export default {
title: 'Inputs/Input',
Expand Down Expand Up @@ -198,3 +201,127 @@ Compact.decorators = [
)
},
]

const SmallButton = styled(Button)`
height: 24px;
width: 24px;
`

export const WithAdornments: Story<InputProps> = () => {
return (
<EdsProvider>
<Label htmlFor="adornments-default" label="Default" />
<Input
type="text"
id="adornments-default"
placeholder="Placeholder text Placeholder text"
leftAdornmentsWidth={40}
leftAdornments={<SmallButton variant="ghost_icon">IT</SmallButton>}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
<Label htmlFor="adornments-error" label="Error" />
<Input
type="text"
id="adornments-error"
variant="error"
leftAdornmentsWidth={40}
leftAdornments={<SmallButton variant="ghost_icon">IT</SmallButton>}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
<Label htmlFor="adornments-warning" label="Warning" />
<Input
type="text"
id="adornments-warning"
variant="warning"
leftAdornmentsWidth={40}
leftAdornments={<SmallButton variant="ghost_icon">IT</SmallButton>}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
<Label htmlFor="adornments-success" label="Success" />
<Input
type="text"
id="adornments-success"
variant="success"
leftAdornmentsWidth={40}
leftAdornments={<SmallButton variant="ghost_icon">IT</SmallButton>}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
<Label htmlFor="adornments-disabled" label="Disabled" />
<Input
type="text"
id="adornments-disabled"
disabled
placeholder="Placeholder text Placeholder text"
value="Some text Some textSome textSome text"
leftAdornmentsWidth={40}
leftAdornments={
<>
<SmallButton disabled variant="ghost_icon">
IT
</SmallButton>
</>
}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
<Label htmlFor="adornments-readonly" label="Readonly" />
<Input
type="text"
id="adornments-readonly"
readOnly
leftAdornmentsWidth={40}
leftAdornments={
<>
<SmallButton variant="ghost_icon">IT</SmallButton>
</>
}
rightAdornmentsWidth={52}
rightAdornments={
<>
unit
<Icon data={anchor} size={18}></Icon>
</>
}
/>
</EdsProvider>
)
}

WithAdornments.decorators = [
(Story) => {
return (
<Stack direction="column" align="start">
<Story />
</Stack>
)
},
]
51 changes: 21 additions & 30 deletions packages/eds-core-react/src/components/Input/Input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@ import { Input } from './Input'
import * as tokens from './Input.tokens'
import { trimSpaces } from '@equinor/eds-utils'

const {
error: {
states: { active: activeError },
},
success: {
states: { active: activeSuccess },
},
warning: {
states: { active: activeWarning },
},
} = tokens

afterEach(cleanup)

describe('Input', () => {
Expand Down Expand Up @@ -57,12 +45,13 @@ describe('Input', () => {
<Input id="test-success" variant="success" />
</label>,
)
const inputNode = screen.getByLabelText(label)
// eslint-disable-next-line testing-library/no-node-access
const inputWrapper = screen.getByLabelText(label).parentElement

expect(inputNode).toHaveStyleRule(
expect(inputWrapper).toHaveStyleRule(
'outline',
`${activeSuccess.outline.width} solid ${trimSpaces(
activeSuccess.outline.color,
`${tokens.input.outline.width} solid ${trimSpaces(
tokens.success.outline.color,
)}`,
)
})
Expand All @@ -75,12 +64,13 @@ describe('Input', () => {
<Input id="test-warning" variant="warning" />
</label>,
)
const inputNode = screen.getByLabelText(label)
// eslint-disable-next-line testing-library/no-node-access
const inputWrapper = screen.getByLabelText(label).parentElement

expect(inputNode).toHaveStyleRule(
expect(inputWrapper).toHaveStyleRule(
'outline',
`${activeWarning.outline.width} solid ${trimSpaces(
activeWarning.outline.color,
`${tokens.input.outline.width} solid ${trimSpaces(
tokens.warning.outline.color,
)}`,
)
})
Expand All @@ -93,32 +83,33 @@ describe('Input', () => {
<Input id="test-error" variant="error" />
</label>,
)
const inputNode = screen.getByLabelText(label)
// eslint-disable-next-line testing-library/no-node-access
const inputWrapper = screen.getByLabelText(label).parentElement

expect(inputNode).toHaveStyleRule(
expect(inputWrapper).toHaveStyleRule(
'outline',
`${activeError.outline.width} solid ${trimSpaces(
activeError.outline.color,
`${tokens.input.outline.width} solid ${trimSpaces(
tokens.error.outline.color,
)}`,
)
})

const StyledTextField = styled(Input)`
const StyledInput = styled(Input)`
margin-top: 48px;
`
it('Can extend the css of the component', () => {
render(
<StyledTextField
<StyledInput
id="test-css-extend"
variant="error"
value="textfield"
readOnly
/>,
)

expect(screen.getByDisplayValue('textfield')).toHaveStyleRule(
'margin-top',
'48px',
)
// eslint-disable-next-line testing-library/no-node-access
const inputWrapper = screen.getByDisplayValue('textfield').parentElement

expect(inputWrapper).toHaveStyleRule('margin-top', '48px')
})
})
Loading

0 comments on commit c7c70f0

Please sign in to comment.