Skip to content

Commit

Permalink
feat(fields): add Textarea (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele committed Nov 29, 2022
1 parent 8feddd3 commit 0cd9b13
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/fields/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useCallback, useMemo, useRef } from 'react'
import { Input } from 'rsuite'
import styled from 'styled-components'

import type { MutableRefObject, TextareaHTMLAttributes } from 'react'
import type { Promisable } from 'type-fest'

export type TextareaProps = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'defaultValue' | 'onChange' | 'value'> & {
defaultValue?: string
name: string
onChange?: (nextValue: string | undefined) => Promisable<void>
}
export function Textarea({ onChange, rows = 3, ...originalProps }: TextareaProps) {
const inputRef = useRef() as MutableRefObject<HTMLTextAreaElement>

const key = useMemo(
() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`,
[originalProps.defaultValue, originalProps.name]
)

const handleChange = useCallback(() => {
if (!onChange) {
return
}

const nextValue = inputRef.current.value.trim()
const normalizedNextValue = nextValue.length ? nextValue : undefined

onChange(normalizedNextValue)
}, [onChange])

return <StyledInput key={key} ref={inputRef} as="textarea" onChange={handleChange} rows={rows} {...originalProps} />
}

export const StyledInput = styled(Input)``
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { DateRangePicker } from './fields/DateRangePicker'
export { DatePicker } from './fields/DatePicker'
export { MultiSelect } from './fields/MultiSelect'
export { Select } from './fields/Select'
export { Textarea } from './fields/Textarea'
export { TextInput } from './fields/TextInput'

export { FormikCheckbox } from './formiks/FormikCheckbox'
Expand All @@ -25,6 +26,7 @@ export type { DateRangePickerProps } from './fields/DateRangePicker'
export type { DatePickerProps } from './fields/DatePicker'
export type { MultiSelectProps } from './fields/MultiSelect'
export type { SelectProps } from './fields/Select'
export type { TextareaProps } from './fields/Textarea'
export type { TextInputProps } from './fields/TextInput'

export type { FormikCheckboxProps } from './formiks/FormikCheckbox'
Expand Down
39 changes: 39 additions & 0 deletions stories/fields/Textarea.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useState } from 'react'

import { Textarea } from '../../src'
import { Output } from '../_components/Output'

import type { TextareaProps } from '../../src'

const args: TextareaProps = {
defaultValue: undefined,
name: 'myTextarea'
}

export default {
title: 'Fields/Textarea',
component: Textarea,

argTypes: {
defaultValue: {
control: 'text'
},
isMulti: {
control: 'boolean'
}
},

args
}

export function _Textarea(props: TextareaProps) {
const [outputValue, setOutputValue] = useState<string | undefined | '∅'>('∅')

return (
<>
<Textarea {...props} onChange={setOutputValue} />

{outputValue !== '∅' && <Output value={outputValue} />}
</>
)
}

0 comments on commit 0cd9b13

Please sign in to comment.