-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* 🎨 more accessibility * 🎨 add tel type * 🎨 remove logs * 🎨 update documentation with eds feature request link * 🎨 fix typo * 🎨update to small text and remove placeholders
- Loading branch information
1 parent
42c73ab
commit 8464530
Showing
10 changed files
with
970 additions
and
749 deletions.
There are no files selected for viewing
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
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
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
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,65 @@ | ||
import { forwardRef, useState, TextareaHTMLAttributes, useCallback, CSSProperties } from 'react' | ||
import { mergeRefs, useAutoResize } from '@equinor/eds-utils' | ||
import { SharedTextFieldProps } from './TextField' | ||
import { Input } from '@equinor/eds-core-react' | ||
|
||
export type TextareaProps = { | ||
/** Type */ | ||
type?: string | ||
/** Read Only */ | ||
readOnly?: boolean | ||
/** Specifies max rows for multiline */ | ||
rowsMax?: number | ||
} & SharedTextFieldProps & | ||
TextareaHTMLAttributes<HTMLTextAreaElement> | ||
|
||
/** Temporary. Until feature request, | ||
* https://github.com/equinor/design-system/issues/3622, | ||
* is resolved */ | ||
export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea( | ||
{ variant, disabled = false, type = 'text', rowsMax = 10, className = '', ...other }, | ||
ref, | ||
) { | ||
const [textareaEl, setTextareaEl] = useState<HTMLTextAreaElement | null>(null) | ||
let fontSize = 16 | ||
|
||
if (textareaEl) { | ||
fontSize = parseInt(window.getComputedStyle(textareaEl).fontSize) | ||
} | ||
|
||
const padding = 12 //6px from InputToken in EDS | ||
const maxHeight = parseFloat('1.5') * fontSize * rowsMax + padding | ||
//@ts-ignore: textareaEl is required, null is handled in hook | ||
useAutoResize(textareaEl, rowsMax ? maxHeight : undefined) | ||
|
||
const combinedRef = useCallback(() => mergeRefs<HTMLTextAreaElement>(ref, setTextareaEl), [setTextareaEl, ref])() | ||
|
||
const inputProps = { | ||
ref: combinedRef, | ||
type, | ||
disabled, | ||
variant, | ||
...other, | ||
style: { height: 'auto' }, | ||
className, | ||
} | ||
|
||
const leftAdornmentStyles = { | ||
style: { alignItems: 'flex-start' }, | ||
} | ||
const rightAdornmentStyles = { | ||
style: { | ||
alignItems: 'flex-start', | ||
pointerEvents: 'none' as CSSProperties['pointerEvents'], | ||
}, | ||
} | ||
|
||
return ( | ||
<Input | ||
as="textarea" | ||
rightAdornmentsProps={rightAdornmentStyles} | ||
leftAdornmentsProps={leftAdornmentStyles} | ||
{...inputProps} | ||
/> | ||
) | ||
}) |
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,141 @@ | ||
import { InputProps, Input } from '@equinor/eds-core-react' | ||
import { ReactNode, InputHTMLAttributes, forwardRef, ForwardedRef, useId, TextareaHTMLAttributes } from 'react' | ||
import envisTwMerge from '../../twMerge' | ||
import { Textarea } from './TextArea' | ||
|
||
export type Variants = 'error' | 'warning' | 'success' | ||
|
||
export type SharedTextFieldProps = { | ||
/** Variants */ | ||
variant?: Variants | ||
/** Description,shown below label */ | ||
description?: ReactNode | ||
/** Input unique id. This is required to ensure accesibility */ | ||
id: string | ||
/** Label text */ | ||
label?: ReactNode | ||
/** Meta text */ | ||
meta?: ReactNode | ||
/** Unit text */ | ||
unit?: string | ||
/** Helper text */ | ||
helperText?: string | ||
/** Input ref */ | ||
inputRef?: ForwardedRef<HTMLInputElement> | ||
/** InputIcon */ | ||
inputIcon?: ReactNode | ||
/** HelperIcon */ | ||
helperIcon?: ReactNode | ||
helperTextClassName?: string | ||
/** If `true` a `textarea` is rendered for multiline support. Make sure to use `textareaRef` if you need to access reference element */ | ||
multiline?: boolean | ||
/** Maximum number of rows if `multiline` is set to `true` */ | ||
rowsMax?: number | ||
/** Textarea ref when multiline is set to `true` */ | ||
textareaRef?: ForwardedRef<HTMLTextAreaElement> | ||
} & InputProps | ||
|
||
type TextFieldProps = SharedTextFieldProps & | ||
(TextareaHTMLAttributes<HTMLTextAreaElement> | InputHTMLAttributes<HTMLInputElement>) | ||
|
||
type FieldProps = SharedTextFieldProps & { | ||
multiline: boolean | ||
} & React.HTMLAttributes<HTMLTextAreaElement | HTMLInputElement> | ||
/** Proxy component for working around typescript and element type switching */ | ||
const Field = forwardRef<HTMLTextAreaElement | HTMLInputElement, FieldProps>(function Field(props, ref) { | ||
return props.multiline ? ( | ||
<Textarea ref={ref as ForwardedRef<HTMLTextAreaElement>} {...props} className={`[&_textarea]:text-base`} /> | ||
) : ( | ||
<Input ref={ref as ForwardedRef<HTMLInputElement>} {...props} className={`[&_input]:text-base`} /> | ||
) | ||
}) | ||
|
||
/** Temporary. Until feature request | ||
* https://github.com/equinor/design-system/issues/3622 | ||
* is resolved */ | ||
export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(function TextField( | ||
{ | ||
id, | ||
label, | ||
description, | ||
unit, | ||
helperText, | ||
placeholder, | ||
disabled, | ||
inputIcon, | ||
helperIcon, | ||
variant, | ||
className = '', | ||
helperTextClassName = '', | ||
multiline = false, | ||
rowsMax, | ||
textareaRef, | ||
inputRef, | ||
...other | ||
}, | ||
ref, | ||
) { | ||
const helperTextId = useId() | ||
const inputDescriptionId = useId() | ||
const hasRightAdornments = Boolean(unit || inputIcon) | ||
let fieldProps = { | ||
'aria-invalid': variant === 'error' || undefined, | ||
disabled, | ||
placeholder, | ||
id, | ||
variant, | ||
rightAdornments: hasRightAdornments && ( | ||
<> | ||
{inputIcon} | ||
<span>{unit}</span> | ||
</> | ||
), | ||
ref: inputRef || textareaRef, | ||
rowsMax, | ||
multiline, | ||
...other, | ||
} | ||
|
||
if (helperText || description) { | ||
fieldProps = { | ||
'aria-describedby': `${helperText ? helperTextId : ''}${helperText && description ? ' ' : ''}${ | ||
description ? inputDescriptionId : '' | ||
}`, | ||
...fieldProps, | ||
} | ||
} | ||
|
||
const variantClassName = { | ||
error: 'text-clear-red-100', | ||
success: 'text-norwegian-woods-100', | ||
warning: '', | ||
} | ||
|
||
return ( | ||
<div ref={ref} className={envisTwMerge(``, className)}> | ||
<label htmlFor={id} className="mx-2 text-base font-medium"> | ||
{label} | ||
</label> | ||
{!!description && ( | ||
<div id={inputDescriptionId} className="px-2 pt-2 pb-1 text-xs font-normal"> | ||
{description} | ||
</div> | ||
)} | ||
<Field {...fieldProps} /> | ||
{!!helperText && ( | ||
<div | ||
id={helperTextId} | ||
className={envisTwMerge( | ||
`${ | ||
variant ? variantClassName[variant] : '' | ||
} mt-2 ml-2 grid auto-cols-auto gap-2 items-start justify-start whitespace-pre-line font-semibold`, | ||
helperTextClassName, | ||
)} | ||
> | ||
{helperIcon && helperIcon} | ||
{helperText} | ||
</div> | ||
)} | ||
</div> | ||
) | ||
}) |
Oops, something went wrong.