Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(TextArea|TextInput): add note prop into TextArea and TextInput #895

Merged
merged 2 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.idea
.vscode
.history
.DS_Store
*.log

Expand Down
1 change: 1 addition & 0 deletions src/components/controls/TextArea/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
| type | `string` | `-` | The control's type |
| value | `string` | `-` | The control's value |
| view | `'normal' \| 'clear'` | `'normal'` | The control's view. `'normal'` by default |
| note | `React.ReactNode` | `-` | An optional element displayed under the lower right corner of the control and sharing the place with the error container |
18 changes: 18 additions & 0 deletions src/components/controls/TextArea/TextArea.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,28 @@ $block: '.#{variables.$ns-new}text-area';
}
}

&__outer-additional-content {
display: flex;
justify-content: space-between;
vertical-align: top;
}

&__note {
margin-left: auto;
}

&__error {
@include mixins.text-body-1();

color: var(--g-color-text-danger);

&:not(:last-child) {
margin-right: var(--g-spacing-2);
}
}

&__note,
&__error {
margin-top: 2px;
}

Expand Down
10 changes: 9 additions & 1 deletion src/components/controls/TextArea/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export type TextAreaProps = BaseInputControlProps<HTMLTextAreaElement> & {
minRows?: number;
/** The number of maximum visible text lines for the control. Ignored if `rows` is specified */
maxRows?: number;
/** An optional element displayed under the lower right corner of the control and sharing the place with the error container */
note?: React.ReactNode;
};
export type TextAreaPin = InputControlPin;
export type TextAreaSize = InputControlSize;
Expand Down Expand Up @@ -54,6 +56,7 @@ export const TextArea = React.forwardRef<HTMLSpanElement, TextAreaProps>(functio
className,
qa,
controlProps,
note,
onUpdate,
onChange,
} = props;
Expand Down Expand Up @@ -156,7 +159,12 @@ export const TextArea = React.forwardRef<HTMLSpanElement, TextAreaProps>(functio
/>
)}
</span>
{isErrorMsgVisible && <div className={b('error')}>{error}</div>}
{(isErrorMsgVisible || note) && (
<div className={b('outer-additional-content')}>
{isErrorMsgVisible && <div className={b('error')}>{error}</div>}
{note && <div className={b('note')}>{note}</div>}
</div>
)}
</span>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import block from 'bem-cn-lite';

import {Checkbox} from '../../../Checkbox';
import {Text} from '../../../Text';
import {TextArea} from '../TextArea';
import type {TextAreaProps} from '../TextArea';

Expand Down Expand Up @@ -64,6 +65,21 @@ export function TextAreaShowcase() {
controlProps={{style: {resize: 'vertical'}}}
rows={4}
/>
<TextArea
{...textAreaProps}
placeholder="with note"
rows={4}
note={<Text color="secondary">Additional</Text>}
/>
<TextArea
{...textAreaProps}
placeholder="with counter and long error message"
rows={4}
note={<Text color="secondary">Additional</Text>}
error={
'It happened a very very very very very very very very very very very very very very very very very very very very very long validation error'
}
/>
</div>
</div>
</div>
Expand Down
10 changes: 7 additions & 3 deletions src/components/controls/TextArea/__tests__/TextArea.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ describe('TextArea', () => {
});

test('render error message with error prop', () => {
const {container} = render(<TextArea error="Some Error" />);
render(<TextArea error="Some Error" />);

// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
expect(container.querySelector('.g-text-area__error')).toBeInTheDocument();
Zveroboev marked this conversation as resolved.
Show resolved Hide resolved
expect(screen.getByText('Some Error')).toBeVisible();
});

test('render note container with note prop', () => {
render(<TextArea error="Some Error" note={<div>Additional</div>} />);

expect(screen.getByText('Additional')).toBeVisible();
});

test('do not show error without error prop', () => {
const {container} = render(<TextArea />);

Expand Down
61 changes: 31 additions & 30 deletions src/components/controls/TextInput/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
| Property | Type | Default | Description |
| :----------- | :-------------------------------------------- | :-------------- | :--------------------------------------------------------------------------------------------------- |
| autoComplete | `boolean \| string` | `-` | The control's `autocomplete` attribute |
| autoFocus | `boolean` | `-` | The control's `autofocus` attribute |
| className | `string` | `-` | The control's wrapper class name |
| controlProps | `React.InputHTMLAttributes<HTMLInputElement>` | `-` | The control's html attributes |
| controlRef | `React.Ref<HTMLInputElement>` | `-` | React ref provided to the control |
| defaultValue | `string` | `-` | The control's default value. Use when the component is not controlled |
| disabled | `boolean` | `false` | Indicates that the user cannot interact with the control |
| error | `boolean \| string` | `-` | Shows error state and optional message if property identified as a string |
| hasClear | `boolean` | `false` | Shows icon for clearing control's value |
| id | `string` | `-` | The control's `id` attribute |
| label | `string` | `-` | Help text rendered to the left of the input node |
| leftContent | `React.ReactNode` | `-` | User`s node rendered before label and input |
| name | `string` | `-` | The control's `name` attribute. Will be autogenerated if not specified |
| onBlur | `function` | `-` | Fires when the control lost focus. Provides focus event as an callback's argument |
| onChange | `function` | `-` | Fires when the input’s value is changed by the user. Provides change event as an callback's argument |
| onFocus | `function` | `-` | Fires when the control gets focus. Provides focus event as an callback's argument |
| onKeyDown | `function` | `-` | Fires when a key is pressed. Provides keyboard event as an callback's argument |
| onKeyUp | `function` | `-` | Fires when a key is released. Provides keyboard event as an callback's argument |
| onUpdate | `function` | `-` | Fires when the input’s value is changed by the user. Provides new value as an callback's argument |
| pin | `string` | `'round-round'` | The control's border view. `'round-round'` by default |
| placeholder | `string` | `-` | Text that appears in the control when it has no value set |
| qa | `string` | `-` | Test id attribute (`data-qa`) |
| rightContent | `React.ReactNode` | `-` | User`s node rendered after input node and clear button |
| size | `'s' \| 'm' \| 'l' \| 'xl'` | `'m'` | The control's size. `'m'` by default |
| tabIndex | `string` | `-` | The control's `tabindex` attribute |
| type | `string` | `-` | The control's type |
| value | `string` | `-` | The control's value |
| view | `'normal' \| 'clear'` | `'normal'` | The control's view. `'normal'` by default |
| Property | Type | Default | Description |
| :----------- | :-------------------------------------------- | :-------------- | :----------------------------------------------------------------------------------------------------------------------- |
| autoComplete | `boolean \| string` | `-` | The control's `autocomplete` attribute |
| autoFocus | `boolean` | `-` | The control's `autofocus` attribute |
| className | `string` | `-` | The control's wrapper class name |
| controlProps | `React.InputHTMLAttributes<HTMLInputElement>` | `-` | The control's html attributes |
| controlRef | `React.Ref<HTMLInputElement>` | `-` | React ref provided to the control |
| defaultValue | `string` | `-` | The control's default value. Use when the component is not controlled |
| disabled | `boolean` | `false` | Indicates that the user cannot interact with the control |
| error | `boolean \| string` | `-` | Shows error state and optional message if property identified as a string |
| hasClear | `boolean` | `false` | Shows icon for clearing control's value |
| id | `string` | `-` | The control's `id` attribute |
| label | `string` | `-` | Help text rendered to the left of the input node |
| leftContent | `React.ReactNode` | `-` | User`s node rendered before label and input |
| name | `string` | `-` | The control's `name` attribute. Will be autogenerated if not specified |
| onBlur | `function` | `-` | Fires when the control lost focus. Provides focus event as an callback's argument |
| onChange | `function` | `-` | Fires when the input’s value is changed by the user. Provides change event as an callback's argument |
| onFocus | `function` | `-` | Fires when the control gets focus. Provides focus event as an callback's argument |
| onKeyDown | `function` | `-` | Fires when a key is pressed. Provides keyboard event as an callback's argument |
| onKeyUp | `function` | `-` | Fires when a key is released. Provides keyboard event as an callback's argument |
| onUpdate | `function` | `-` | Fires when the input’s value is changed by the user. Provides new value as an callback's argument |
| pin | `string` | `'round-round'` | The control's border view. `'round-round'` by default |
| placeholder | `string` | `-` | Text that appears in the control when it has no value set |
| qa | `string` | `-` | Test id attribute (`data-qa`) |
| rightContent | `React.ReactNode` | `-` | User`s node rendered after input node and clear button |
| size | `'s' \| 'm' \| 'l' \| 'xl'` | `'m'` | The control's size. `'m'` by default |
| tabIndex | `string` | `-` | The control's `tabindex` attribute |
| type | `string` | `-` | The control's type |
| value | `string` | `-` | The control's value |
| view | `'normal' \| 'clear'` | `'normal'` | The control's view. `'normal'` by default |
| note | `React.ReactNode` | `-` | An optional element displayed under the lower right corner of the control and sharing the place with the error container |
18 changes: 18 additions & 0 deletions src/components/controls/TextInput/TextInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,28 @@ $block: '.#{variables.$ns}text-input';
flex-shrink: 0;
}

&__outer-additional-content {
display: flex;
justify-content: space-between;
vertical-align: top;
}

&__note {
margin-left: auto;
}

&__error {
@include mixins.text-body-1();

color: var(--g-color-text-danger);

&:not(:last-child) {
margin-right: var(--g-spacing-2);
}
}

&__note,
&__error {
margin-top: 2px;
}

Expand Down
10 changes: 9 additions & 1 deletion src/components/controls/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export type TextInputProps = BaseInputControlProps<HTMLInputElement> & {
leftContent?: React.ReactNode;
/** User`s node rendered after input node and clear button */
rightContent?: React.ReactNode;
/** An optional element displayed under the lower right corner of the control and sharing the place with the error container */
note?: React.ReactNode;
};
export type TextInputPin = InputControlPin;
export type TextInputSize = InputControlSize;
Expand Down Expand Up @@ -61,6 +63,7 @@ export const TextInput = React.forwardRef<HTMLSpanElement, TextInputProps>(funct
controlProps: originalControlProps,
leftContent,
rightContent,
note,
onUpdate,
onChange,
} = props;
Expand Down Expand Up @@ -206,7 +209,12 @@ export const TextInput = React.forwardRef<HTMLSpanElement, TextInputProps>(funct
</AdditionalContent>
)}
</span>
{isErrorMsgVisible && <div className={b('error')}>{error}</div>}
{(isErrorMsgVisible || note) && (
<div className={b('outer-additional-content')}>
{isErrorMsgVisible && <div className={b('error')}>{error}</div>}
{note && <div className={b('note')}>{note}</div>}
</div>
)}
</span>
);
});
Loading
Loading