diff --git a/src/components/Form/Textarea.tsx b/src/components/Form/Textarea.tsx deleted file mode 100644 index 01d66ecb1..000000000 --- a/src/components/Form/Textarea.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import React, { Component, ChangeEvent, FocusEvent } from 'react'; -import { - HtmlLabel, - HtmlTextarea, - HtmlTextareaProps, - HtmlSpan, - HtmlDiv, -} from '../../reset'; -import { VisuallyHidden } from '../Visually-hidden/Visually-hidden'; -import { Paragraph } from '../Paragraph/Paragraph'; -import classnames from 'classnames'; -import { idGenerator } from '../../utils/uuid'; - -const baseClassName = 'fi-textarea'; -const textareaClassNames = { - label: `${baseClassName}_label`, - optionalText: `${baseClassName}_optionalText`, - textareaContainer: `${baseClassName}_textarea-element-container`, - textarea: `${baseClassName}_textarea`, - hintText: `${baseClassName}_hintText`, - statusText: `${baseClassName}_statusText`, -}; - -export interface TextareaProps extends HtmlTextareaProps { - /** Custom classname to extend or customize */ - className?: string; - /** Disable usage */ - disabled?: boolean; - /** Event handler to execute when clicked */ - onClick?: () => void; - /** To execute on textarea text change */ - onChange?: (event: ChangeEvent) => void; - /** To execute on textarea text onBlur */ - onBlur?: (event: FocusEvent) => void; - /** Label */ - labelText: string; - /** Hide or show label. Label element is always present, but can be visually hidden. - * @default visible - */ - labelMode?: 'hidden' | 'visible'; - /** Placeholder text for input. Use only as visual aid, not for instructions. */ - visualPlaceholder?: string; - /** Text content for textarea */ - children?: string; - /** Hint text to be shown below the component */ - hintText?: string; - /** - * 'default' | 'error' - * @default default - */ - status?: 'default' | 'error'; - /** Status text to be shown below the component and hint text. Use e.g. for validation error */ - statusText?: string; - /** Resize mode of the textarea - 'both' | 'vertical' | 'horizontal' | 'none' - @default 'vertical' - */ - resize?: 'both' | 'vertical' | 'horizontal' | 'none'; - /** Optional text that is shown after labelText. Will be wrapped in parentheses. */ - optionalText?: string; - /** Unique id - * @default uuidV4 - */ - id?: string; - /** Input name */ - name?: string; -} - -export class Textarea extends Component { - labelText = (forId: string) => { - const { labelMode, labelText, optionalText } = this.props; - const hideLabel = labelMode === 'hidden'; - - return hideLabel ? ( - - - {labelText} - {optionalText && `(${optionalText})`} - - - ) : ( - - - {labelText} - {optionalText && ( - - {` (${optionalText})`} - - )} - - - ); - }; - - hintText = (id: string) => { - const { hintText } = this.props; - - return ( - hintText && ( - - {hintText} - - ) - ); - }; - - statusText = (id: string) => { - const { statusText, disabled } = this.props; - return ( - statusText && - !disabled && ( - - {statusText} - - ) - ); - }; - - render() { - const { - id: propId, - className, - disabled = false, - children, - onClick, - labelMode, - labelText, - hintText, - status, - statusText, - visualPlaceholder, - resize: dismissResize, - optionalText, - ...passProps - } = this.props; - - const onClickProps = !!disabled ? {} : { onMouseDown: onClick }; - const id = idGenerator(propId); - const statusTextId = `${id}-statusText`; - const hintTextId = `${id}-hintText`; - - const getDescribedBy = () => { - if (statusText || hintText || this.props['aria-describedby']) { - return { - 'aria-describedby': [ - ...(statusText ? [statusTextId] : []), - ...(hintText ? [hintTextId] : []), - this.props['aria-describedby'], - ].join(' '), - }; - } - return {}; - }; - - return ( - - {this.labelText(id)} - {this.hintText(hintTextId)} - - - - {this.statusText(statusTextId)} - - ); - } -} diff --git a/src/components/index.ts b/src/components/index.ts index f5822ddda..702537451 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -28,7 +28,6 @@ export { export { Expander, ExpanderProps } from './Expander/Expander'; export { Paragraph, ParagraphProps } from './Paragraph/Paragraph'; export { Text, TextProps } from './Text/Text'; -export { Textarea, TextareaProps } from './Form/Textarea'; export { VisuallyHidden } from './Visually-hidden/Visually-hidden'; export { RadioButton, RadioButtonProps } from './Form/RadioButton'; export { diff --git a/src/components/utils/aria.ts b/src/components/utils/aria.ts deleted file mode 100644 index 39e406322..000000000 --- a/src/components/utils/aria.ts +++ /dev/null @@ -1,15 +0,0 @@ -const ifAriaNoLabel = (ariaLabel?: string) => !!ariaLabel || ariaLabel === ''; - -export const ariaLabelOrHidden = (ariaLabel?: string) => { - return ifAriaNoLabel(ariaLabel) - ? { 'aria-label': ariaLabel, role: 'img' } - : { 'aria-hidden': true }; -}; - -/** - * Set element ability to be focusable based on aria-label - * @param {String} ariaLabel optional aria-label - */ -export const ariaFocusableNoLabel = (ariaLabel?: string) => { - return ifAriaNoLabel(ariaLabel) ? {} : { focusable: false }; -}; diff --git a/src/core/Form/Textarea/Textarea.baseStyles.tsx b/src/core/Form/Textarea/Textarea.baseStyles.tsx index a981afc6c..7f0a9cca5 100644 --- a/src/core/Form/Textarea/Textarea.baseStyles.tsx +++ b/src/core/Form/Textarea/Textarea.baseStyles.tsx @@ -15,21 +15,14 @@ export const baseStyles = withSuomifiTheme( display: flex; flex-direction: column; color: ${theme.colors.blackBase}; + width: 290px; - & .fi-textarea_label { - ${font({ theme })('actionElementInnerTextBold')}; - color: ${theme.colors.blackBase}; + & .fi-label-text_label-span { + margin-bottom: 0; } - & .fi-textarea_optionalText { - ${theme.typography.bodyTextSmall}; - } - - & .fi-textarea_hintText { - display: block; - color: ${theme.colors.blackBase}; - ${theme.typography.bodyTextSmall}; - word-break: break-word; + & .fi-hint-text { + margin-bottom: 0; } & .fi-textarea_textarea-element-container { @@ -65,13 +58,9 @@ export const baseStyles = withSuomifiTheme( } } - & .fi-textarea_statusText { + & .fi-status-text { display: block; - margin-top: ${theme.spacing.xxs}; - font-size: 14px; line-height: 18px; - font-weight: 600; - word-break: break-word; } &.fi-textarea--disabled { @@ -87,11 +76,11 @@ export const baseStyles = withSuomifiTheme( & .fi-textarea_textarea { border: 2px solid ${theme.colors.alertBase}; } - - & .fi-textarea_statusText { - color: ${theme.colors.alertBase}; - } } } + + &.fi-textarea--full-width { + width: 100%; + } `, ); diff --git a/src/core/Form/Textarea/Textarea.md b/src/core/Form/Textarea/Textarea.md index e7b1fbab2..0f185457f 100644 --- a/src/core/Form/Textarea/Textarea.md +++ b/src/core/Form/Textarea/Textarea.md @@ -55,3 +55,22 @@ import { Textarea } from 'suomifi-ui-components'; ; ``` + +```js +import { Textarea } from 'suomifi-ui-components'; + +<> + + + +; +``` diff --git a/src/core/Form/Textarea/Textarea.test.tsx b/src/core/Form/Textarea/Textarea.test.tsx index 329552a7b..ba7f4479e 100644 --- a/src/core/Form/Textarea/Textarea.test.tsx +++ b/src/core/Form/Textarea/Textarea.test.tsx @@ -31,7 +31,20 @@ describe('props', () => { it('should have label text with correct class', () => { const { getByText } = render(DefaultTextareaComponent); const label = getByText('Label here'); - expect(label).toHaveClass('fi-textarea_label'); + expect(label).toHaveClass('fi-label-text_label-span'); + }); + + it('has user given aria-describedby on textarea', () => { + const { getByRole } = render( +