@cloud-ru/uikit-product-claudia 1.8.4 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +21 -0
  3. package/dist/cjs/components/RateForm/RateForm.d.ts +45 -0
  4. package/dist/cjs/components/RateForm/RateForm.js +27 -0
  5. package/dist/cjs/components/RateForm/components/FieldSubmitButton.d.ts +15 -0
  6. package/dist/cjs/components/RateForm/components/FieldSubmitButton.js +13 -0
  7. package/dist/cjs/components/RateForm/components/TextFieldWithAccordionMessage/TextFieldWithAccordionMessage.d.ts +19 -0
  8. package/dist/cjs/components/RateForm/components/TextFieldWithAccordionMessage/TextFieldWithAccordionMessage.js +56 -0
  9. package/dist/cjs/components/RateForm/components/TextFieldWithAccordionMessage/index.d.ts +1 -0
  10. package/dist/cjs/components/RateForm/components/TextFieldWithAccordionMessage/index.js +17 -0
  11. package/dist/cjs/components/RateForm/components/TextFieldWithAccordionMessage/styles.module.css +62 -0
  12. package/dist/cjs/components/RateForm/constants.d.ts +2 -0
  13. package/dist/cjs/components/RateForm/constants.js +5 -0
  14. package/dist/cjs/components/RateForm/index.d.ts +3 -0
  15. package/dist/cjs/components/RateForm/index.js +21 -0
  16. package/dist/cjs/components/RateForm/styles.module.css +127 -0
  17. package/dist/cjs/components/RateForm/types.d.ts +8 -0
  18. package/dist/cjs/components/RateForm/types.js +2 -0
  19. package/dist/cjs/components/SshField/SshField.d.ts +1 -1
  20. package/dist/cjs/components/SshField/components/MobileFieldAi/MobileFieldAi.d.ts +1 -1
  21. package/dist/cjs/components/index.d.ts +1 -0
  22. package/dist/cjs/components/index.js +1 -0
  23. package/dist/esm/components/RateForm/RateForm.d.ts +45 -0
  24. package/dist/esm/components/RateForm/RateForm.js +21 -0
  25. package/dist/esm/components/RateForm/components/FieldSubmitButton.d.ts +15 -0
  26. package/dist/esm/components/RateForm/components/FieldSubmitButton.js +10 -0
  27. package/dist/esm/components/RateForm/components/TextFieldWithAccordionMessage/TextFieldWithAccordionMessage.d.ts +19 -0
  28. package/dist/esm/components/RateForm/components/TextFieldWithAccordionMessage/TextFieldWithAccordionMessage.js +50 -0
  29. package/dist/esm/components/RateForm/components/TextFieldWithAccordionMessage/index.d.ts +1 -0
  30. package/dist/esm/components/RateForm/components/TextFieldWithAccordionMessage/index.js +1 -0
  31. package/dist/esm/components/RateForm/components/TextFieldWithAccordionMessage/styles.module.css +62 -0
  32. package/dist/esm/components/RateForm/constants.d.ts +2 -0
  33. package/dist/esm/components/RateForm/constants.js +2 -0
  34. package/dist/esm/components/RateForm/index.d.ts +3 -0
  35. package/dist/esm/components/RateForm/index.js +2 -0
  36. package/dist/esm/components/RateForm/styles.module.css +127 -0
  37. package/dist/esm/components/RateForm/types.d.ts +8 -0
  38. package/dist/esm/components/RateForm/types.js +1 -0
  39. package/dist/esm/components/SshField/SshField.d.ts +1 -1
  40. package/dist/esm/components/SshField/components/MobileFieldAi/MobileFieldAi.d.ts +1 -1
  41. package/dist/esm/components/index.d.ts +1 -0
  42. package/dist/esm/components/index.js +1 -0
  43. package/package.json +5 -2
  44. package/src/components/RateForm/RateForm.tsx +136 -0
  45. package/src/components/RateForm/components/FieldSubmitButton.tsx +45 -0
  46. package/src/components/RateForm/components/TextFieldWithAccordionMessage/TextFieldWithAccordionMessage.tsx +147 -0
  47. package/src/components/RateForm/components/TextFieldWithAccordionMessage/index.ts +1 -0
  48. package/src/components/RateForm/components/TextFieldWithAccordionMessage/styles.module.scss +68 -0
  49. package/src/components/RateForm/constants.ts +3 -0
  50. package/src/components/RateForm/index.ts +3 -0
  51. package/src/components/RateForm/styles.module.scss +143 -0
  52. package/src/components/RateForm/types.ts +8 -0
  53. package/src/components/index.ts +1 -0
@@ -0,0 +1,19 @@
1
+ export type TextFieldWithAccordionMessageProps = {
2
+ /** Существующий комментарий */
3
+ comment?: string;
4
+ /** Плейсхолдер для поля ввода */
5
+ placeholder?: string;
6
+ /** Callback при изменении текста */
7
+ onChange?: (value: string) => void;
8
+ /** Callback при отправке */
9
+ onSubmit?: (value: string) => void;
10
+ /** Максимальная длина сообщения */
11
+ maxLength?: number;
12
+ /** Является ли устройство тач-девайсом */
13
+ isTouchDevice?: boolean;
14
+ /** Показывать ли тултип на кнопке отправки */
15
+ showSubmitTooltip?: boolean;
16
+ /** Текст тултипа для кнопки отправки */
17
+ submitTooltipText?: string;
18
+ };
19
+ export declare function TextFieldWithAccordionMessage({ comment, placeholder, onChange, onSubmit, maxLength, isTouchDevice, showSubmitTooltip, submitTooltipText, }: TextFieldWithAccordionMessageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useRef, useState } from 'react';
3
+ import { themeVars } from '@sbercloud/figma-tokens-cloud-platform';
4
+ import { ChevronUpInterfaceSVG } from '@cloud-ru/uikit-product-icons';
5
+ import { Divider } from '@snack-uikit/divider';
6
+ import { FieldTextArea } from '@snack-uikit/fields';
7
+ import { Typography } from '@snack-uikit/typography';
8
+ import { useLayoutEffect } from '@snack-uikit/utils';
9
+ import { MESSAGE_MAX_LENGTH, STATIC_LINE_HEIGHT } from '../../constants';
10
+ import { FieldSubmitButton } from '../FieldSubmitButton';
11
+ import styles from './styles.module.css';
12
+ export function TextFieldWithAccordionMessage({ comment, placeholder, onChange, onSubmit, maxLength = MESSAGE_MAX_LENGTH, isTouchDevice = false, showSubmitTooltip = true, submitTooltipText, }) {
13
+ const textRef = useRef(null);
14
+ const [isMultiLine, setIsMultiLine] = useState(false);
15
+ const [isExpanded, setIsExpanded] = useState(false);
16
+ const [message, setMessage] = useState(comment || '');
17
+ const isValid = typeof message === 'string' && message.trim().length > 0;
18
+ useLayoutEffect(() => {
19
+ if (!comment)
20
+ return;
21
+ setMessage(comment);
22
+ const timeout = setTimeout(() => {
23
+ if (textRef.current) {
24
+ const textHeight = textRef.current.scrollHeight;
25
+ setIsMultiLine(textHeight > STATIC_LINE_HEIGHT * 2 + 5);
26
+ }
27
+ }, 0);
28
+ return () => clearTimeout(timeout);
29
+ }, [comment]);
30
+ const handleClickMessage = () => {
31
+ setIsExpanded(!isExpanded);
32
+ };
33
+ const handleChangeMessage = (value) => {
34
+ const truncatedValue = value.slice(0, maxLength);
35
+ setMessage(truncatedValue);
36
+ onChange === null || onChange === void 0 ? void 0 : onChange(truncatedValue);
37
+ };
38
+ const handleSubmit = () => {
39
+ if (isValid) {
40
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(message);
41
+ }
42
+ };
43
+ const handleKeyDown = event => {
44
+ if (event.key === 'Enter' && !event.shiftKey && !isTouchDevice) {
45
+ event.preventDefault();
46
+ handleSubmit();
47
+ }
48
+ };
49
+ return (_jsxs(_Fragment, { children: [comment && (_jsxs("div", { className: styles.comment, children: [_jsx(Divider, {}), _jsxs("div", { className: styles.container, "data-clickable": isMultiLine || undefined, onClick: isMultiLine ? handleClickMessage : undefined, role: isMultiLine ? 'button' : undefined, children: [_jsx("div", { ref: textRef, className: styles.textContainer, "data-collapsed": (isMultiLine && !isExpanded) || undefined, children: _jsx(Typography.LightBodyS, { className: styles.text, children: message }) }), isMultiLine && (_jsx(ChevronUpInterfaceSVG, { color: themeVars.sys.neutral.textLight, className: styles.textIcon, "data-rotated": !isExpanded || undefined, size: 20 }))] })] })), !comment && (_jsx(FieldTextArea, { value: message, size: 'm', minRows: 1, maxRows: 4, placeholder: placeholder, onChange: handleChangeMessage, onKeyDown: handleKeyDown, spellCheck: true, footer: _jsx("div", { className: styles.actionsFooter, children: _jsx(FieldSubmitButton, { tooltipText: showSubmitTooltip && !isTouchDevice ? submitTooltipText : undefined, className: styles.buttonRight, "data-mobile": isTouchDevice || undefined, active: isValid, onClick: handleSubmit, size: isTouchDevice ? 's' : 'xs' }) }), showClearButton: false }))] }));
50
+ }
@@ -0,0 +1 @@
1
+ export * from './TextFieldWithAccordionMessage';
@@ -0,0 +1 @@
1
+ export * from './TextFieldWithAccordionMessage';
@@ -0,0 +1,62 @@
1
+ .actionsFooter{
2
+ display:flex;
3
+ flex-direction:row;
4
+ justify-content:flex-end;
5
+ align-items:center;
6
+ width:100%;
7
+ padding:0 10px 9px 0;
8
+ cursor:text;
9
+ }
10
+
11
+ .textIcon{
12
+ min-width:20px;
13
+ min-height:20px;
14
+ transition:transform 0.2s ease;
15
+ }
16
+ .textIcon[data-rotated]{
17
+ transform:rotate(180deg);
18
+ }
19
+
20
+ .textContainer{
21
+ flex:1;
22
+ min-width:0;
23
+ line-height:16px;
24
+ }
25
+ .textContainer[data-collapsed]{
26
+ display:-webkit-box;
27
+ -webkit-box-orient:vertical;
28
+ -webkit-line-clamp:2;
29
+ line-clamp:2;
30
+ overflow:hidden;
31
+ text-overflow:ellipsis;
32
+ line-height:16px;
33
+ max-height:32px;
34
+ }
35
+
36
+ .comment{
37
+ width:100%;
38
+ display:flex;
39
+ flex-direction:column;
40
+ justify-content:center;
41
+ align-items:flex-start;
42
+ gap:16px;
43
+ }
44
+
45
+ .text{
46
+ color:var(--sys-neutral-text-light, #8b8e9b);
47
+ line-height:16px;
48
+ }
49
+
50
+ .container{
51
+ display:flex;
52
+ flex-direction:row;
53
+ align-items:flex-end;
54
+ gap:4px;
55
+ width:100%;
56
+ }
57
+ .container svg path{
58
+ fill:var(--sys-neutral-text-light, #8b8e9b);
59
+ }
60
+ .container[data-clickable]{
61
+ cursor:pointer;
62
+ }
@@ -0,0 +1,2 @@
1
+ export declare const MESSAGE_MAX_LENGTH = 255;
2
+ export declare const STATIC_LINE_HEIGHT = 16;
@@ -0,0 +1,2 @@
1
+ export const MESSAGE_MAX_LENGTH = 255;
2
+ export const STATIC_LINE_HEIGHT = 16;
@@ -0,0 +1,3 @@
1
+ export * from './RateForm';
2
+ export type { Grade } from './types';
3
+ export { MESSAGE_MAX_LENGTH, STATIC_LINE_HEIGHT } from './constants';
@@ -0,0 +1,2 @@
1
+ export * from './RateForm';
2
+ export { MESSAGE_MAX_LENGTH, STATIC_LINE_HEIGHT } from './constants';
@@ -0,0 +1,127 @@
1
+ .closeIcon{
2
+ cursor:pointer;
3
+ position:absolute;
4
+ top:8px;
5
+ right:8px;
6
+ opacity:0;
7
+ transition:opacity 0.2s ease;
8
+ will-change:opacity;
9
+ }
10
+
11
+ .feedbackForm{
12
+ position:relative;
13
+ display:flex;
14
+ flex-direction:column;
15
+ align-items:center;
16
+ justify-content:center;
17
+ width:296px;
18
+ background-color:var(--sys-neutral-background2-level, #ffffff);
19
+ border:1px solid var(--sys-neutral-decor-default, #dde0ea);
20
+ border-radius:8px;
21
+ padding:24px;
22
+ gap:16px;
23
+ }
24
+ .feedbackForm:hover .closeIcon{
25
+ opacity:1;
26
+ }
27
+ .feedbackForm[data-touch] .closeIcon{
28
+ opacity:1;
29
+ }
30
+
31
+ .feedbackFormTitle{
32
+ color:var(--sys-neutral-text-main, #41424e);
33
+ }
34
+
35
+ .feedbackFormLoading{
36
+ display:flex;
37
+ flex-direction:column;
38
+ align-items:center;
39
+ justify-content:center;
40
+ width:296px;
41
+ height:141px;
42
+ background-color:var(--sys-neutral-background2-level, #ffffff);
43
+ border:1px solid var(--sys-neutral-decor-default, #dde0ea);
44
+ border-radius:8px;
45
+ padding:24px;
46
+ }
47
+ .feedbackFormLoading[data-loading]{
48
+ cursor:wait;
49
+ }
50
+
51
+ .gradeBlock{
52
+ display:flex;
53
+ flex-direction:row;
54
+ align-items:center;
55
+ justify-content:center;
56
+ gap:14px;
57
+ position:relative;
58
+ }
59
+
60
+ .description{
61
+ color:var(--sys-neutral-text-light, #8b8e9b);
62
+ position:absolute;
63
+ bottom:-12px;
64
+ opacity:0;
65
+ }
66
+
67
+ .grade{
68
+ cursor:pointer;
69
+ display:flex;
70
+ flex-direction:column;
71
+ justify-content:center;
72
+ align-items:center;
73
+ transition:all 0.2s ease;
74
+ height:40px;
75
+ width:36px;
76
+ }
77
+ .grade:hover > .description{
78
+ opacity:1;
79
+ }
80
+
81
+ .gradeIcon{
82
+ transition:all 0.2s ease;
83
+ font-size:32px;
84
+ }
85
+ .gradeIcon:hover{
86
+ font-size:36px !important;
87
+ }
88
+
89
+ .ratingContainer{
90
+ display:flex;
91
+ flex-direction:column;
92
+ justify-content:center;
93
+ align-items:center;
94
+ gap:4px;
95
+ }
96
+
97
+ .ratingTitle{
98
+ display:flex;
99
+ flex-direction:row;
100
+ justify-content:center;
101
+ align-items:center;
102
+ gap:4px;
103
+ color:var(--sys-neutral-text-main, #41424e);
104
+ }
105
+
106
+ .ratingSubtitle{
107
+ color:var(--sys-neutral-text-main, #41424e);
108
+ }
109
+
110
+ .ratingIcon{
111
+ line-height:20px !important;
112
+ }
113
+
114
+ .mobileSubmitButton{
115
+ position:relative !important;
116
+ flex-shrink:0 !important;
117
+ }
118
+ .mobileSubmitButton:after{
119
+ content:"";
120
+ display:flex;
121
+ width:48px;
122
+ height:48px;
123
+ position:absolute;
124
+ top:50%;
125
+ left:50%;
126
+ transform:translate(-50%, -50%);
127
+ }
@@ -0,0 +1,8 @@
1
+ export type Grade = {
2
+ /** Уникальный идентификатор оценки */
3
+ id: string;
4
+ /** Иконка (эмодзи) */
5
+ icon: string;
6
+ /** Описание оценки */
7
+ description: string;
8
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,7 +6,7 @@ export type SshFieldProps = WithLayoutType<Omit<FieldTextAreaProps, 'placeholder
6
6
  /** Колбек отмены действия */
7
7
  onCancel(): void;
8
8
  }>;
9
- export declare const SshField: import("react").ForwardRefExoticComponent<Omit<FieldTextAreaProps, "label" | "size" | "placeholder" | "footer" | "spellCheck" | "required" | "labelTooltip"> & {
9
+ export declare const SshField: import("react").ForwardRefExoticComponent<Omit<FieldTextAreaProps, "label" | "size" | "placeholder" | "spellCheck" | "labelTooltip" | "required" | "footer"> & {
10
10
  /** Колбек действия при отправке */
11
11
  onSubmit(value: string): void;
12
12
  /** Колбек отмены действия */
@@ -1,5 +1,5 @@
1
1
  import { FieldTextAreaProps } from '@cloud-ru/uikit-product-mobile-fields';
2
- export declare const MobileFieldAi: import("react").ForwardRefExoticComponent<Omit<FieldTextAreaProps, "label" | "size" | "placeholder" | "footer" | "spellCheck" | "required" | "labelTooltip"> & {
2
+ export declare const MobileFieldAi: import("react").ForwardRefExoticComponent<Omit<FieldTextAreaProps, "label" | "size" | "placeholder" | "spellCheck" | "labelTooltip" | "required" | "footer"> & {
3
3
  onSubmit(): void;
4
4
  submitEnabled: boolean;
5
5
  } & import("react").RefAttributes<HTMLTextAreaElement>>;
@@ -1,6 +1,7 @@
1
1
  export * from './ButtonClaudia';
2
2
  export * from './ButtonGiga';
3
3
  export * from './ChatStatusAnnouncement';
4
+ export * from './RateForm';
4
5
  export * from './IconGiga';
5
6
  export * from './RecommendPannel';
6
7
  export * from './SshField';
@@ -1,6 +1,7 @@
1
1
  export * from './ButtonClaudia';
2
2
  export * from './ButtonGiga';
3
3
  export * from './ChatStatusAnnouncement';
4
+ export * from './RateForm';
4
5
  export * from './IconGiga';
5
6
  export * from './RecommendPannel';
6
7
  export * from './SshField';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloud-ru/uikit-product-claudia",
3
3
  "title": "Claudia",
4
- "version": "1.8.4",
4
+ "version": "1.9.0",
5
5
  "sideEffects": [
6
6
  "*.css",
7
7
  "*.woff",
@@ -41,8 +41,11 @@
41
41
  "@cloud-ru/uikit-product-mobile-fields": "0.11.31",
42
42
  "@cloud-ru/uikit-product-utils": "8.0.1",
43
43
  "@snack-uikit/button": "0.19.16",
44
+ "@snack-uikit/divider": "3.2.3",
44
45
  "@snack-uikit/drop-zone": "0.9.6",
45
46
  "@snack-uikit/dropdown": "0.5.3",
47
+ "@snack-uikit/fields": "0.51.0",
48
+ "@snack-uikit/icons": "0.27.3",
46
49
  "@snack-uikit/input-private": "4.8.3",
47
50
  "@snack-uikit/link": "0.17.12",
48
51
  "@snack-uikit/loaders": "0.9.9",
@@ -58,5 +61,5 @@
58
61
  "@cloud-ru/uikit-product-locale": "*",
59
62
  "@snack-uikit/figma-tokens": "*"
60
63
  },
61
- "gitHead": "f67d8d3987dc49157789aebe9e083c42d0abf5c3"
64
+ "gitHead": "483e1bfeed59866d6ffbb4fbcc923b2c483e1e45"
62
65
  }
@@ -0,0 +1,136 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { themeVars } from '@sbercloud/figma-tokens-cloud-platform';
5
+ import { CrossSVG } from '@snack-uikit/icons';
6
+ import { Spinner } from '@snack-uikit/loaders';
7
+ import { Typography } from '@snack-uikit/typography';
8
+
9
+ import { TextFieldWithAccordionMessage } from './components/TextFieldWithAccordionMessage';
10
+ import styles from './styles.module.scss';
11
+ import { Grade } from './types';
12
+
13
+ export type RateFormProps = {
14
+ /** Массив доступных оценок */
15
+ grades: Grade[];
16
+ /** Текущая выбранная оценка */
17
+ selectedGrade?: Grade | null;
18
+ /** Заголовок формы (показывается когда оценка не выбрана) */
19
+ title?: string;
20
+ /** Текст "Вы поставили" */
21
+ ratedLabel?: string;
22
+ /** Подзаголовок после выбора оценки */
23
+ ratedSubtitle?: string;
24
+ /** Комментарий пользователя */
25
+ comment?: string;
26
+ /** Состояние загрузки */
27
+ isLoading?: boolean;
28
+ /** Callback при клике на оценку */
29
+ onGradeClick?: (grade: Grade) => void;
30
+ /** Callback при закрытии формы */
31
+ onClose?: () => void;
32
+ /** Callback при изменении комментария */
33
+ onCommentChange?: (comment: string) => void;
34
+ /** Callback при отправке комментария */
35
+ onCommentSubmit?: (comment: string) => void;
36
+ /** Плейсхолдер для поля комментария */
37
+ commentPlaceholder?: string;
38
+ /** Показывать ли кнопку закрытия */
39
+ showCloseButton?: boolean;
40
+ /** Дополнительный className */
41
+ className?: string;
42
+ /** Является ли устройство тач-девайсом */
43
+ isTouchDevice?: boolean;
44
+ /** Текст тултипа для кнопки отправки */
45
+ submitTooltipText?: string;
46
+ /** Render prop для кастомного отображения текстового поля */
47
+ renderTextField?: (props: {
48
+ comment?: string;
49
+ grade: Grade;
50
+ placeholder?: string;
51
+ onChange?: (value: string) => void;
52
+ onSubmit?: (value: string) => void;
53
+ }) => ReactNode;
54
+ };
55
+
56
+ export function RateForm({
57
+ grades,
58
+ selectedGrade,
59
+ title,
60
+ ratedLabel,
61
+ ratedSubtitle,
62
+ comment,
63
+ isLoading = false,
64
+ onGradeClick,
65
+ onClose,
66
+ onCommentChange,
67
+ onCommentSubmit,
68
+ commentPlaceholder,
69
+ showCloseButton = true,
70
+ className,
71
+ isTouchDevice = false,
72
+ submitTooltipText,
73
+ renderTextField,
74
+ }: RateFormProps) {
75
+ if (isLoading) {
76
+ return (
77
+ <div className={cn(styles.feedbackFormLoading, className)} data-loading>
78
+ <Spinner size='s' />
79
+ </div>
80
+ );
81
+ }
82
+
83
+ return (
84
+ <div className={cn(styles.feedbackForm, className)} data-touch={isTouchDevice || undefined}>
85
+ {selectedGrade ? (
86
+ <div className={styles.ratingContainer}>
87
+ <div className={styles.ratingTitle}>
88
+ {ratedLabel && <Typography.SansLabelL>{ratedLabel}</Typography.SansLabelL>}
89
+ <Typography.SansTitleL className={styles.ratingIcon}>{selectedGrade.icon}</Typography.SansTitleL>
90
+ </div>
91
+
92
+ {ratedSubtitle && (
93
+ <Typography.SansBodyM className={styles.ratingSubtitle}>{ratedSubtitle}</Typography.SansBodyM>
94
+ )}
95
+ </div>
96
+ ) : (
97
+ title && <Typography.SansLabelL className={styles.feedbackFormTitle}>{title}</Typography.SansLabelL>
98
+ )}
99
+
100
+ {!selectedGrade && (
101
+ <div className={styles.gradeBlock}>
102
+ {grades.map(grade => (
103
+ <div key={grade.id} className={styles.grade} onClick={() => onGradeClick?.(grade)} role='presentation'>
104
+ <Typography.SansHeadlineL className={styles.gradeIcon}>{grade.icon}</Typography.SansHeadlineL>
105
+ <Typography.LightLabelS className={styles.description}>{grade.description}</Typography.LightLabelS>
106
+ </div>
107
+ ))}
108
+ </div>
109
+ )}
110
+
111
+ {selectedGrade &&
112
+ (renderTextField ? (
113
+ renderTextField({
114
+ comment,
115
+ grade: selectedGrade,
116
+ placeholder: commentPlaceholder,
117
+ onChange: onCommentChange,
118
+ onSubmit: onCommentSubmit,
119
+ })
120
+ ) : (
121
+ <TextFieldWithAccordionMessage
122
+ comment={comment}
123
+ placeholder={commentPlaceholder}
124
+ onChange={onCommentChange}
125
+ onSubmit={onCommentSubmit}
126
+ isTouchDevice={isTouchDevice}
127
+ submitTooltipText={submitTooltipText}
128
+ />
129
+ ))}
130
+
131
+ {showCloseButton && selectedGrade && (
132
+ <CrossSVG className={styles.closeIcon} size={24} color={themeVars.sys.neutral.textSupport} onClick={onClose} />
133
+ )}
134
+ </div>
135
+ );
136
+ }
@@ -0,0 +1,45 @@
1
+ import { ArrowUpSVG } from '@cloud-ru/uikit-product-icons';
2
+ import { ButtonTonal } from '@snack-uikit/button';
3
+ import { Tooltip } from '@snack-uikit/tooltip';
4
+
5
+ export type FieldSubmitButtonProps = {
6
+ /** Активна ли кнопка */
7
+ active: boolean;
8
+ /** Callback при клике */
9
+ onClick: () => void;
10
+ /** Размер кнопки */
11
+ size?: 'xs' | 's';
12
+ /** Дополнительный className */
13
+ className?: string;
14
+ /** Кнопка на всю ширину */
15
+ fullWidth?: boolean;
16
+ /** Текст тултипа */
17
+ tooltipText?: string;
18
+ };
19
+
20
+ export function FieldSubmitButton({
21
+ active,
22
+ onClick,
23
+ size = 'xs',
24
+ className,
25
+ fullWidth,
26
+ tooltipText,
27
+ }: FieldSubmitButtonProps) {
28
+ if (active) {
29
+ return (
30
+ <Tooltip tip={tooltipText} hoverDelayOpen={600} open={tooltipText ? undefined : false}>
31
+ <ButtonTonal
32
+ fullWidth={fullWidth}
33
+ icon={<ArrowUpSVG />}
34
+ size={size}
35
+ appearance='primary'
36
+ type='button'
37
+ onClick={onClick}
38
+ className={className}
39
+ />
40
+ </Tooltip>
41
+ );
42
+ }
43
+
44
+ return <ButtonTonal icon={<ArrowUpSVG />} size={size} disabled className={className} fullWidth={fullWidth} />;
45
+ }