Skip to content

Commit

Permalink
Merge pull request #304 from i-pip/feat/input-textarea-copy
Browse files Browse the repository at this point in the history
Feat/InputTextArea copy
  • Loading branch information
MildTomato authored Jan 2, 2022
2 parents 38a4b09 + e828575 commit 30b91b9
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 30 deletions.
8 changes: 8 additions & 0 deletions src/components/Input/Input.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
@apply absolute inset-y-0 right-0 pl-3 pr-1 flex items-center;
}

.sbui-textarea-actions-container {
@apply absolute inset-y-1 right-0 pl-3 pr-1 flex items-start;
}

.sbui-textarea-actions-container__items {
@apply flex items-center;
}

/*
Input sizes
*/
Expand Down
9 changes: 9 additions & 0 deletions src/components/Input/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const withCustomStyle = (args: any) => <Input {...args} />

export const textArea = (args: any) => <Input.TextArea {...args} />

export const textAreaWithCopy = (args: any) => <Input.TextArea {...args} />

export const textAreaWithLimit = (args: any) => <Input.TextArea {...args} />

export const withRevealAndCopy = (args: any) => <Input {...args} />
Expand Down Expand Up @@ -91,6 +93,13 @@ textArea.args = {
label: 'This is a text area',
}

textAreaWithCopy.args = {
copy: true,
rows: 3,
type: 'text',
label: 'This is a text area',
}

textAreaWithLimit.args = {
type: 'text',
label: 'This is a text area, with 10 rows',
Expand Down
96 changes: 66 additions & 30 deletions src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ export interface TextAreaProps
size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
borderless?: boolean
validation?: (x: any) => void
copy?: boolean
actions?: React.ReactNode
}

function TextArea({
Expand Down Expand Up @@ -230,15 +232,28 @@ function TextArea({
size,
borderless = false,
validation,
copy = false,
actions,
...props
}: TextAreaProps) {
const [charLength, setCharLength] = useState(0)
const [copyLabel, setCopyLabel] = useState('Copy')

let classes = [InputStyles['sbui-input']]
if (error) classes.push(InputStyles['sbui-input--error'])
if (icon) classes.push(InputStyles['sbui-input--with-icon'])
if (size) classes.push(InputStyles[`sbui-input--${size}`])
if (borderless) classes.push(InputStyles['sbui-input--borderless'])
function onCopy(value: any) {
navigator.clipboard.writeText(value).then(
function () {
/* clipboard successfully set */
setCopyLabel('Copied')
setTimeout(function () {
setCopyLabel('Copy')
}, 3000)
},
function () {
/* clipboard write failed */
setCopyLabel('Failed to copy')
}
)
}

const {
formContextOnChange,
Expand Down Expand Up @@ -267,6 +282,12 @@ function TextArea({
if (validation) fieldLevelValidation(id, validation(value))
}, [])

let classes = [InputStyles['sbui-input']]
if (error) classes.push(InputStyles['sbui-input--error'])
if (icon) classes.push(InputStyles['sbui-input--with-icon'])
if (size) classes.push(InputStyles[`sbui-input--${size}`])
if (borderless) classes.push(InputStyles['sbui-input--borderless'])

return (
<FormLayout
className={className}
Expand All @@ -281,32 +302,47 @@ function TextArea({
style={style}
size={size}
>
<textarea
disabled={disabled}
id={id}
name={name}
rows={rows}
cols={100}
placeholder={placeholder}
onChange={onInputChange}
onFocus={onFocus ? (event) => onFocus(event) : undefined}
onBlur={onBlur}
onKeyDown={onKeyDown ? (event) => onKeyDown(event) : undefined}
value={value}
className={classes.join(' ')}
maxLength={limit}
{...props}
>
{value}
</textarea>
{limit && (
<Typography.Text
type="secondary"
style={{ marginTop: '0.5rem', display: 'block' }}
<div className={InputStyles['sbui-input-container']}>
<textarea
disabled={disabled}
id={id}
name={name}
rows={rows}
cols={100}
placeholder={placeholder}
onChange={onInputChange}
onFocus={onFocus ? (event) => onFocus(event) : undefined}
onBlur={onBlur}
onKeyDown={onKeyDown ? (event) => onKeyDown(event) : undefined}
value={value}
className={classes.join(' ')}
maxLength={limit}
{...props}
>
{charLength}/{limit}
</Typography.Text>
)}
{value}
</textarea>
{copy || error || actions ? (
<div className={InputStyles['sbui-textarea-actions-container']}>
<Space
className={InputStyles['sbui-textarea-actions-container__items']}
size={1}
>
{error && <InputErrorIcon size={size} />}
{copy && (
<Button
size="tiny"
type="default"
onClick={() => onCopy(value)}
icon={<IconCopy />}
>
{copyLabel}
</Button>
)}
{actions && actions}
</Space>
</div>
) : null}
</div>
</FormLayout>
)
}
Expand Down

0 comments on commit 30b91b9

Please sign in to comment.