Skip to content

Commit

Permalink
Added overridablecomponent to input
Browse files Browse the repository at this point in the history
  • Loading branch information
mimarz committed Sep 5, 2022
1 parent 6e5184b commit 47a2c52
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 86 deletions.
5 changes: 5 additions & 0 deletions packages/eds-core-react/src/components/Input/Input.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,8 @@ Compact `Input` using `EdsProvider`.


<Story id="inputs-input--with-adornments" />

### Casted as textarea


<Story id="inputs-input--casted" />
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,7 @@ WithAdornments.decorators = [
)
},
]

export const casted: Story<InputProps> = (args) => {
return <Input as="textarea" {...args} />
}
180 changes: 94 additions & 86 deletions packages/eds-core-react/src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
spacingsTemplate,
outlineTemplate,
useToken,
OverridableComponent,
} from '@equinor/eds-utils'
import { inputToken as tokens } from './Input.tokens'
import type { InputToken } from './Input.tokens'
Expand Down Expand Up @@ -128,95 +129,102 @@ export type InputProps = {
leftAdornments?: ReactNode
/** Right adornments */
rightAdornments?: ReactNode
/** Cast the input to another element */
as?: 'input' | 'textarea'
} & InputHTMLAttributes<HTMLInputElement>

export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
{
variant,
disabled = false,
type = 'text',
leftAdornments,
rightAdornments,
readOnly,
className,
style,
...other
},
ref,
) {
const inputVariant = tokens[variant] ? tokens[variant] : tokens.input
const { density } = useEds()
const token = useToken({ density }, inputVariant)()

const [rightAdornmentsRef, setRightAdornmentsRef] = useState<HTMLDivElement>()
const [leftAdornmentsRef, setLeftAdornmentsRef] = useState<HTMLDivElement>()

const rightAdornmentsWidth = useCallback(() => {
if (rightAdornmentsRef) {
return rightAdornmentsRef.offsetWidth
export const Input: OverridableComponent<InputProps, HTMLInputElement> =
forwardRef<HTMLInputElement, InputProps>(function Input(
{
variant,
disabled = false,
type = 'text',
leftAdornments,
rightAdornments,
readOnly,
className,
style,
...other
},
ref,
) {
const inputVariant = tokens[variant] ? tokens[variant] : tokens.input
const { density } = useEds()
const token = useToken({ density }, inputVariant)()

const [rightAdornmentsRef, setRightAdornmentsRef] =
useState<HTMLDivElement>()
const [leftAdornmentsRef, setLeftAdornmentsRef] = useState<HTMLDivElement>()

const rightAdornmentsWidth = useCallback(() => {
if (rightAdornmentsRef) {
return rightAdornmentsRef.offsetWidth
}
return 0
}, [rightAdornmentsRef])()

const leftAdornmentsWidth = useCallback(() => {
if (leftAdornmentsRef) {
return leftAdornmentsRef.offsetWidth
}
return 0
}, [leftAdornmentsRef])()

const updatedToken = useCallback(
(): ComponentToken => ({
...token,
spacings: {
...token.spacings,
left: `${leftAdornmentsWidth + parseInt(token.spacings.left)}px`,
right: `${rightAdornmentsWidth + parseInt(token.spacings.right)}px`,
},
}),
[leftAdornmentsWidth, rightAdornmentsWidth, token],
)()

const inputProps = {
ref,
type,
disabled,
readOnly,
token: updatedToken,
style: {
resize: style?.resize,
},
...other,
}
return 0
}, [rightAdornmentsRef])()

const leftAdornmentsWidth = useCallback(() => {
if (leftAdornmentsRef) {
return leftAdornmentsRef.offsetWidth
const containerProps = {
disabled,
readOnly,
className,
style,
token: updatedToken,
}
return 0
}, [leftAdornmentsRef])()

const updatedToken = useCallback(
(): ComponentToken => ({
...token,
spacings: {
...token.spacings,
left: `${leftAdornmentsWidth + parseInt(token.spacings.left)}px`,
right: `${rightAdornmentsWidth + parseInt(token.spacings.right)}px`,
},
}),
[leftAdornmentsWidth, rightAdornmentsWidth, token],
)()

const inputProps = {
ref,
type,
disabled,
readOnly,
token: updatedToken,
...other,
}

const containerProps = {
disabled,
readOnly,
className,
style,
token: updatedToken,
}

const leftAdornmentProps = {
ref: setLeftAdornmentsRef,
token: updatedToken,
}
const rightAdornmentProps = {
ref: setRightAdornmentsRef,
token: updatedToken,
}

return (
// Not using <ThemeProvider> because of cascading styling messing with adornments
<Container {...containerProps}>
{leftAdornments ? (
<LeftAdornments {...leftAdornmentProps}>
{leftAdornments}
</LeftAdornments>
) : null}
<StyledInput {...inputProps} />
{rightAdornments ? (
<RightAdornments {...rightAdornmentProps}>
{rightAdornments}
</RightAdornments>
) : null}
</Container>
)
})
const leftAdornmentProps = {
ref: setLeftAdornmentsRef,
token: updatedToken,
}
const rightAdornmentProps = {
ref: setRightAdornmentsRef,
token: updatedToken,
}

return (
// Not using <ThemeProvider> because of cascading styling messing with adornments
<Container {...containerProps}>
{leftAdornments ? (
<LeftAdornments {...leftAdornmentProps}>
{leftAdornments}
</LeftAdornments>
) : null}
<StyledInput {...inputProps} />
{rightAdornments ? (
<RightAdornments {...rightAdornmentProps}>
{rightAdornments}
</RightAdornments>
) : null}
</Container>
)
})

0 comments on commit 47a2c52

Please sign in to comment.