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

plasma-new-hope: TextArea height / width fixes #1261

Merged
merged 8 commits into from
Jun 25, 2024
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ const meta: Meta<TextAreaProps> = {
'onBlur',
]),
},
args: {
autoResize: false,
minAuto: 0,
maxAuto: 0,
},
Comment on lines +62 to +66
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

добавил руками свойства autoResize, которые пропали при изменении типов

};

export default meta;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PropsTable, Description } from '@site/src/components';

## Использование
Компонент `TextArea` может содержать иконку (или кнопку) справа.
Для этого используйте свойство и `contentRight`:
Для этого используйте свойство `contentRight`:

```tsx live
import React from 'react';
Expand All @@ -31,16 +31,55 @@ export function App() {
}
```

Также можно регулировать высоту и ширину, используя свойства `height` и `width`,
### Размеры компонента
Высоту и ширину можно регулировать с помощью свойств `height` и `width`,
указав значения в `rem` или соответствующие свойствам css значения.
`height` и `width` отвечают за **всю** высоту и ширину компонента.

## Autoresize
```tsx live
import React from 'react';
import { TextArea } from '@salutejs/{{ package }}';

export function App() {
return (
<div>
<TextArea
placeholder="Введите значение"
defaultValue="Значение"
height={10}
width={20}
/>
</div>
);
}
```

Свойства `rows` и `cols` указываются в абсолютных единицах, отвечают за фиксированное количество строк и столбцов.

```tsx live
import React from 'react';
import { TextArea } from '@salutejs/{{ package }}';

export function App() {
return (
<div>
<TextArea
placeholder="Введите значение"
defaultValue="Значение"
rows={5}
cols={20}
/>
</div>
);
}
```

### Autoresize
Также можно включить автоматическое регулирование высоты поля ввода по длине контента внутри (параметра `value`).
Для этого необходимо использовать свойство `autoResize`.
При этом, если пользователь вручную регулирует высоту(`resize`), то она так и остается пользовательской.

В этом режиме можно указать крайние значения высоты поля ввода, используя свойства `autoMin`, `autoMax`,
указав их в `rem`.
Свойства `minAuto`, `maxAuto` указываются в абсолютных единицах и отвечают за минимальное и максимальное количество строк.

```tsx live
import React from 'react';
Expand Down Expand Up @@ -85,4 +124,4 @@ export function App() {
</div>
);
}
```
```
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ export const textAreaRoot = (Root: RootProps<HTMLTextAreaElement, TextAreaProps>
readOnly,
label,
labelPlacement,
autoResize,
rows,
value: value || uncontrolledValue || defaultValue,
...(rows ? { rows } : { autoResize }),
},
focused,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
import { TextareaHTMLAttributes } from '../../types';

type Only<T, U, R> = {
[P in keyof T]: T[P];
} &
{
[P in keyof U]?: never;
} &
{
[P in keyof R]?: never;
};

type OneOf<T, U, R> = Only<T, U, R> | Only<U, T, R> | Only<R, T, U>;

export type TextAreaPropsAutoResize = {
/**
* Автоматическая высота поля ввода.
*/
autoResize?: boolean;
/**
* Максимальная высота поля ввода в автоматическом режиме (в абсолютных единицах).
* @example maxAuto="5", maxAuto={5}
*/
maxAuto?: number;
/**
* Минимальная высота поля ввода в автоматическом режиме (в абсолютных единицах).
Yakutoc marked this conversation as resolved.
Show resolved Hide resolved
* @example minAuto="5", minAuto={5}
*/
minAuto?: number;
};

export type TextAreaPropsHeightWidth = {
/**
* Высота текстового поля, значения в rem. Отвечает за ВСЮ высоту компонента.
* @example height="10", height={10}
*/
height?: number | string;
/**
* Ширина текстового поля, значения в rem. Отвечает за ВСЮ ширину компонента.
* @example width="10", width={10}
*/
width?: number | string;
};

export type TextAreaPropsRowsCols = {
/**
* Высота текстового поля (в абсолютных единицах) – фиксированное число отображаемых строк без прокрутки.
*/
rows?: number;
/**
* Ширина текстового поля (в абсолютных единицах) – фиксированное число столбцов.
*/
cols?: number;
};

export type TextAreaDimensionsProps = OneOf<TextAreaPropsAutoResize, TextAreaPropsHeightWidth, TextAreaPropsRowsCols>;

export interface TextAreaPropsBase {
/**
* Статус компонента: заполнен успешно / с предупреждением / с ошибкой.
Expand All @@ -23,16 +78,6 @@ export interface TextAreaPropsBase {
* @deprecated устаревшее свойство
*/
resize?: 'none' | 'both' | 'horizontal' | 'vertical';
/**
* Высота текстового поля, значения в rem
* @example height="10", height={10}
*/
height?: number | string;
/**
* Ширина текстового поля, значения в rem
* @example width="10", width={10}
*/
width?: number | string;
/**
* Вспомогательный текст снизу слева для поля ввода.
* @deprecated свойство устарело, необходимо использовать `leftHelper`.
Expand All @@ -46,18 +91,6 @@ export interface TextAreaPropsBase {
* Вспомогательный текст снизу справа для поля ввода.
*/
rightHelper?: string;
/**
* Автоматическая высота поля ввода.
*/
autoResize?: boolean;
/**
* Максимальная высота поля ввода в автоматическом режиме(в rem).
*/
maxAuto?: number;
/**
* Минимальная высота поля ввода в автоматическом режиме(в rem).
*/
minAuto?: number;
}

export interface TextAreaPropsExtends extends TextAreaPropsBase {
Expand All @@ -71,4 +104,6 @@ export interface TextAreaPropsExtends extends TextAreaPropsBase {
view?: string;
}

export type TextAreaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & TextAreaPropsExtends;
export type TextAreaProps = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'rows' | 'cols'> &
TextAreaPropsExtends &
TextAreaDimensionsProps;
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const useAutoResize = <T extends HTMLTextAreaElement>(
active: boolean,
ref: MutableRefObject<T | null>,
value?: string | ReadonlyArray<string> | number,
minHeight?: number,
maxHeight?: number,
minAuto?: number,
maxAuto?: number,
) => {
const isManualResize = useRef<boolean>(false);
const previousHeight = useRef<number | undefined>();
Expand All @@ -21,9 +21,19 @@ export const useAutoResize = <T extends HTMLTextAreaElement>(
return;
}

ref.current.style.height = `${minHeight ? minHeight + 1 : '0'}rem`;
const scrollHeight = ref.current.scrollHeight / ROOT_FONT_SIZE;
const newHeight = Math.min(scrollHeight, maxHeight ? maxHeight + 1 : scrollHeight);
const style = getComputedStyle(ref.current);
const lineHeight = parseInt(style.lineHeight, 10);
const lineHeightInRem = lineHeight / ROOT_FONT_SIZE;

const minAutoHeight = minAuto ? minAuto * lineHeightInRem : 0;
ref.current.style.height = `${minAutoHeight}rem`;

const lines = Math.floor(ref.current.scrollHeight / lineHeight);
const newScrollHeight = lines * lineHeightInRem;

const maxAutoHeight = maxAuto ? maxAuto * lineHeightInRem : newScrollHeight;

const newHeight = Math.min(newScrollHeight, maxAutoHeight);

ref.current.style.height = `${newHeight}rem`;
previousHeight.current = newHeight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ const meta: Meta<TextAreaProps> = {
'helperBlock',
]),
},
args: {
autoResize: false,
minAuto: 0,
maxAuto: 0,
},
Comment on lines +66 to +70
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

аналогично

};

export default meta;
Expand Down
32 changes: 31 additions & 1 deletion packages/sdds-serv/api/sdds-serv.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,37 @@ negative: string;
disabled: {
true: string;
};
}> & TextareaHTMLAttributes<HTMLTextAreaElement> & TextAreaPropsExtends & RefAttributes<HTMLTextAreaElement>>;
}> & ((Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "rows" | "cols"> & TextAreaPropsExtends & {
autoResize?: boolean | undefined;
maxAuto?: number | undefined;
minAuto?: number | undefined;
} & {
height?: undefined;
width?: undefined;
} & {
rows?: undefined;
cols?: undefined;
} & RefAttributes<HTMLTextAreaElement>) | (Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "rows" | "cols"> & TextAreaPropsExtends & {
height?: string | number | undefined;
width?: string | number | undefined;
} & {
autoResize?: undefined;
maxAuto?: undefined;
minAuto?: undefined;
} & {
rows?: undefined;
cols?: undefined;
} & RefAttributes<HTMLTextAreaElement>) | (Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "rows" | "cols"> & TextAreaPropsExtends & {
rows?: number | undefined;
cols?: number | undefined;
} & {
autoResize?: undefined;
maxAuto?: undefined;
minAuto?: undefined;
} & {
height?: undefined;
width?: undefined;
} & RefAttributes<HTMLTextAreaElement>))>;

// @public
export const TextField: FunctionComponent<PropsType< {
Expand Down
49 changes: 44 additions & 5 deletions website/plasma-web-docs/docs/components/TextArea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PropsTable, Description, StorybookLink } from '@site/src/components';

## Использование
Компонент `TextArea` может содержать иконку (или кнопку) справа.
Для этого используйте свойство и `contentRight`:
Для этого используйте свойство `contentRight`:

```tsx live
import React from 'react';
Expand All @@ -32,16 +32,55 @@ export function App() {
}
```

Также можно регулировать высоту и ширину, используя свойства `height` и `width`,
### Размеры компонента
Высоту и ширину можно регулировать с помощью свойств `height` и `width`,
указав значения в `rem` или соответствующие свойствам css значения.
`height` и `width` отвечают за **всю** высоту и ширину компонента.

## Autoresize
```tsx live
import React from 'react';
import { TextArea } from '@salutejs/plasma-web';

export function App() {
return (
<div>
<TextArea
placeholder="Введите значение"
defaultValue="Значение"
height={10}
width={20}
/>
</div>
);
}
```

Свойства `rows` и `cols` указываются в абсолютных единицах, отвечают за фиксированное количество строк и столбцов.

```tsx live
import React from 'react';
import { TextArea } from '@salutejs/plasma-web';

export function App() {
return (
<div>
<TextArea
placeholder="Введите значение"
defaultValue="Значение"
rows={5}
cols={20}
/>
</div>
);
}
```

### Autoresize
Также можно включить автоматическое регулирование высоты поля ввода по длине контента внутри (параметра `value`).
Для этого необходимо использовать свойство `autoResize`.
При этом, если пользователь вручную регулирует высоту(`resize`), то она так и остается пользовательской.

В этом режиме можно указать крайние значения высоты поля ввода, используя свойства `autoMin`, `autoMax`,
указав их в `rem`.
Свойства `minAuto`, `maxAuto` указываются в абсолютных единицах и отвечают за минимальное и максимальное количество строк.

```tsx live
import React from 'react';
Expand Down
Loading
Loading