kamotive_ui 1.2.26 → 1.2.27

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 (34) hide show
  1. package/dist/Icons/IconAttach/IconAttach.js +3 -3
  2. package/dist/Icons/IconBold/IconBold.js +2 -2
  3. package/dist/Icons/IconBulletlist/IconBulletlist.js +6 -6
  4. package/dist/Icons/IconHeader2/IconHeader2.js +2 -2
  5. package/dist/Icons/IconItalic/IconItalic.js +2 -2
  6. package/dist/Icons/IconMultiselect/IconMultiselect.d.ts +9 -0
  7. package/dist/Icons/IconMultiselect/IconMultiselect.js +7 -0
  8. package/dist/Icons/IconRedo/IconRedo.js +2 -2
  9. package/dist/Icons/IconShare/IconShare.d.ts +7 -0
  10. package/dist/Icons/IconShare/IconShare.js +5 -0
  11. package/dist/Icons/IconStrikethrough/IconStrikethrough.js +2 -2
  12. package/dist/Icons/IconSubmit/IconSubmit.js +1 -1
  13. package/dist/Icons/IconUnderline/IconUnderline.js +2 -2
  14. package/dist/Icons/IconUndo/IconUndo.js +2 -2
  15. package/dist/Icons/index.d.ts +2 -0
  16. package/dist/Icons/index.js +2 -0
  17. package/dist/components/Button/Button.js +8 -4
  18. package/dist/components/Comment/Comment.js +11 -10
  19. package/dist/components/Dialog/Dialog.module.css +2 -2
  20. package/dist/components/Dropdown/Dropdown.js +5 -5
  21. package/dist/components/FileItem/FileItem.js +2 -2
  22. package/dist/components/FileLoader/FileLoader.js +19 -3
  23. package/dist/components/IconButton/IconButton.js +9 -4
  24. package/dist/components/Input/Input.js +5 -2
  25. package/dist/components/List/List.js +4 -3
  26. package/dist/components/ProgressBar/ProgressBar.js +2 -2
  27. package/dist/components/Snackbar/Snackbar.d.ts +1 -1
  28. package/dist/components/Snackbar/Snackbar.js +18 -13
  29. package/dist/components/Snackbar/Snackbar.module.css +24 -0
  30. package/dist/components/TextEditor/TextEditor.js +64 -51
  31. package/dist/components/TextEditor/TextEditor.module.css +1 -0
  32. package/dist/components/Tooltip/Tooltip.js +1 -1
  33. package/dist/types/index.d.ts +22 -3
  34. package/package.json +1 -1
@@ -17,9 +17,9 @@ export const IconAttachToString = (color = 'inherit', htmlColor, strokeWidth, on
17
17
  <path
18
18
  d="M6.37877 4.15256L2.88551 7.64632C2.63416 7.9059 2.49642 8.25544 2.50202 8.61952C2.50761 8.9836 2.65609 9.33302 2.91541 9.59238C3.17473 9.85173 3.5241 10.0002 3.88813 10.0058C4.25215 10.0114 4.60165 9.87367 4.86118 9.62229L9.44315 5.04607C9.66417 4.83039 9.83953 4.57234 9.95906 4.28687C10.0786 4.0014 10.1399 3.6942 10.1395 3.38306C10.139 3.07192 10.0768 2.76304 9.95651 2.47432C9.83618 2.1856 9.66009 1.92279 9.43845 1.70113C9.21682 1.47946 8.95405 1.30335 8.66537 1.18299C8.3767 1.06264 8.06786 1.00044 7.75676 1C7.44567 0.999565 7.13851 1.0609 6.85308 1.18044C6.56765 1.29999 6.30964 1.47537 6.094 1.69642L1.48439 6.30669C1.1725 6.6096 0.924855 6.9724 0.755862 7.374C0.58687 7.7756 0.499896 8.208 0.5 8.64604C0.500104 9.08408 0.587283 9.51903 0.756467 9.92561C0.925651 10.3322 1.17347 10.7023 1.4855 11.0144C1.79754 11.3264 2.16757 11.5743 2.57409 11.7435C2.98061 11.9127 3.4155 11.9999 3.85348 12C4.29146 12.0001 4.72379 11.9131 5.12533 11.7441C5.52688 11.5751 5.88963 11.3274 6.19249 11.0155L10.5 6.70734"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-miterlimit="10"
21
- stroke-linecap="round"
22
- stroke-width="${strokeWidth || '1'}"
20
+ strokeMiterlimit="10"
21
+ strokeLinecap="round"
22
+ strokeWidth="${strokeWidth || '1'}"
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -17,9 +17,9 @@ export const IconBoldToString = (color = 'inherit', htmlColor, strokeWidth, onCl
17
17
  <path
18
18
  d="M5.57143 6.5C6.27867 6.5 6.95695 6.21027 7.45705 5.69454C7.95714 5.17882 8.2381 4.47935 8.2381 3.75C8.2381 3.02065 7.95714 2.32118 7.45705 1.80546C6.95695 1.28973 6.27867 1 5.57143 1H1V6.5M5.57143 6.5H1M5.57143 6.5H6.33333C7.04058 6.5 7.71886 6.78973 8.21895 7.30546C8.71905 7.82118 9 8.52065 9 9.25C9 9.97935 8.71905 10.6788 8.21895 11.1945C7.71886 11.7103 7.04058 12 6.33333 12H1V6.5"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
20
+ strokeLinecap="round"
21
21
  stroke-linejoin="round"
22
- stroke-width="${strokeWidth || '1'}"
22
+ strokeWidth="${strokeWidth || '1'}"
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -26,8 +26,8 @@ export const IconBulletlistToString = (color = 'inherit', htmlColor, strokeWidth
26
26
  <path
27
27
  d="M4.50732 0.886665H12.3508"
28
28
  stroke="${htmlColor || "#55534E"}"
29
- stroke-width="${strokeWidth || "1.5"}"
30
- stroke-linecap="round"
29
+ strokeWidth="${strokeWidth || "1.5"}"
30
+ strokeLinecap="round"
31
31
  stroke-linejoin="round"
32
32
  />
33
33
  <path
@@ -37,8 +37,8 @@ export const IconBulletlistToString = (color = 'inherit', htmlColor, strokeWidth
37
37
  <path
38
38
  d="M4.50732 5.5H12.3508"
39
39
  stroke="${htmlColor || "#55534E"}"
40
- stroke-width="${strokeWidth || "1.5"}"
41
- stroke-linecap="round"
40
+ strokeWidth="${strokeWidth || "1.5"}"
41
+ strokeLinecap="round"
42
42
  stroke-linejoin="round"
43
43
  />
44
44
  <path
@@ -48,8 +48,8 @@ export const IconBulletlistToString = (color = 'inherit', htmlColor, strokeWidth
48
48
  <path
49
49
  d="M4.50732 10.1133H12.3508"
50
50
  stroke="${htmlColor || "#55534E"}"
51
- stroke-width="${strokeWidth || "1.5"}"
52
- stroke-linecap="round"
51
+ strokeWidth="${strokeWidth || "1.5"}"
52
+ strokeLinecap="round"
53
53
  stroke-linejoin="round"
54
54
  />
55
55
  </svg>`;
@@ -17,9 +17,9 @@ export const IconHeader2ToString = (color = 'inherit', htmlColor, strokeWidth, o
17
17
  <path
18
18
  d="M1 1H11M6 1V12"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
20
+ strokeLinecap="round"
21
21
  stroke-linejoin="round"
22
- stroke-width="${strokeWidth || '1'}"
22
+ strokeWidth="${strokeWidth || '1'}"
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -17,9 +17,9 @@ export const IconItalicToString = (color = 'inherit', htmlColor, strokeWidth, on
17
17
  <path
18
18
  d="M4.9375 1.25L11.5 1.25M1 11.75H7.5625M8.21875 1.25L4.28125 11.75"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
20
+ strokeLinecap="round"
21
21
  stroke-linejoin="round"
22
- stroke-width="${strokeWidth || '1'}"
22
+ strokeWidth="${strokeWidth || '1'}"
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -0,0 +1,9 @@
1
+ import { CSSProperties, FC } from 'react';
2
+ export declare const IconMultiselect: FC<{
3
+ color?: string;
4
+ htmlColor?: string;
5
+ strokeWidth?: string;
6
+ checkedStrokeWidth?: string;
7
+ style?: CSSProperties;
8
+ checked?: boolean;
9
+ }>;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export const IconMultiselect = ({ color = 'inherit', htmlColor, strokeWidth, checkedStrokeWidth, style, checked = false }) => {
3
+ return (React.createElement("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: color, style: style },
4
+ React.createElement("rect", { x: "5.5", y: "2.5", width: "12", height: "12", rx: "3", stroke: htmlColor || 'currentColor', style: { strokeWidth: strokeWidth || '1.5' } }),
5
+ React.createElement("rect", { x: "2.5", y: "5.5", width: "12", height: "12", rx: "3", fill: "white", stroke: htmlColor || 'currentColor', style: { strokeWidth: strokeWidth || '1.5' } }),
6
+ checked && React.createElement("path", { d: "M4.5 11.5L7.5 15.5C7.93 16.08 8.82 16.03 9.18 15.4L14 7.5", stroke: htmlColor || 'currentColor', style: { strokeWidth: checkedStrokeWidth || '2' }, strokeLinecap: "round" })));
7
+ };
@@ -17,8 +17,8 @@ export const IconRedoToString = (color = 'inherit', htmlColor, strokeWidth, onCl
17
17
  <path
18
18
  d="M1.35059 8C1.35059 4.32927 4.38392 1.34146 8.11059 1.34146C10.3639 1.42683 12.6173 2.62195 13.9173 4.5M14.3506 1V4.41463C14.3506 4.67073 14.1773 4.84146 13.9173 4.84146H10.4506"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
21
- stroke-width="${strokeWidth || '1'}"
20
+ strokeLinecap="round"
21
+ strokeWidth="${strokeWidth || '1'}"
22
22
  />
23
23
  </svg>`;
24
24
  };
@@ -0,0 +1,7 @@
1
+ import { CSSProperties, FC } from 'react';
2
+ export declare const IconShare: FC<{
3
+ color?: string;
4
+ htmlColor?: string;
5
+ strokeWidth?: number;
6
+ style?: CSSProperties;
7
+ }>;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export const IconShare = ({ color = 'inherit', htmlColor, strokeWidth = 1, style }) => {
3
+ return (React.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: color, style: style },
4
+ React.createElement("path", { stroke: htmlColor || 'currentColor', strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", d: "M16 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h2m8-3l-4-4l-4 4m4 9V3" })));
5
+ };
@@ -17,9 +17,9 @@ export const IconStrikethroughToString = (color = 'inherit', htmlColor, strokeWi
17
17
  <path
18
18
  d="M6.5 6.49991C6.42902 6.48382 6.35834 6.46646 6.288 6.44782C5.23133 6.16825 4.352 5.62558 3.78133 4.97346C3.19933 4.30815 2.938 3.52942 3.136 2.79686C3.52933 1.34623 5.578 0.627508 7.71133 1.19325C8.35354 1.36002 8.95966 1.64111 9.5 2.02275M2.78 10.3322C3.35133 10.9843 4.23067 11.5263 5.28733 11.8066C7.42067 12.3723 9.47 11.6549 9.86267 10.2036C10.018 9.63129 9.892 9.0306 9.55267 8.47804M1 6.49991H12"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
20
+ strokeLinecap="round"
21
21
  stroke-linejoin="round"
22
- stroke-width="${strokeWidth || '1'}"
22
+ strokeWidth="${strokeWidth || '1'}"
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -17,7 +17,7 @@ export const IconSubmitToString = (color = 'inherit', htmlColor, strokeWidth, on
17
17
  <path
18
18
  d="M9.5957 0.9C9.60588 0.9 9.61862 0.904148 9.62988 0.915625C9.64163 0.92768 9.65039 0.946815 9.65039 0.969336C9.65038 0.989162 9.64247 1.00515 9.63281 1.01719L9.62891 1.02207L3.72363 7.08359L3.72266 7.08457C3.71706 7.09032 3.71067 7.09391 3.70508 7.09629C3.69967 7.09855 3.69452 7.10017 3.68945 7.10019C3.68423 7.10019 3.67843 7.09866 3.67285 7.09629C3.66738 7.09393 3.66172 7.09015 3.65625 7.08457L3.65527 7.08359L1.07129 4.43223C1.06557 4.42636 1.06042 4.41815 1.05664 4.40879C1.05293 4.39954 1.05082 4.38923 1.05078 4.37852C1.05078 4.36763 1.05286 4.35664 1.05664 4.34727C1.06038 4.33806 1.06567 4.33062 1.07129 4.3248C1.07698 4.31896 1.08316 4.31453 1.08887 4.31211C1.09449 4.30974 1.10018 4.30918 1.10547 4.30918C1.11077 4.30919 1.11644 4.30972 1.12207 4.31211C1.12777 4.31453 1.13396 4.31896 1.13965 4.3248L3.33203 6.5748L3.68945 6.94199L4.04785 6.5748L9.5625 0.915625C9.57359 0.904352 9.58563 0.900112 9.5957 0.9Z"
19
19
  stroke="${htmlColor || "white"}"
20
- stroke-width="${strokeWidth || '1'}"
20
+ strokeWidth="${strokeWidth || '1'}"
21
21
  />
22
22
  </svg>`;
23
23
  };
@@ -17,9 +17,9 @@ export const IconUnderlineToString = (color = 'inherit', htmlColor, strokeWidth,
17
17
  <path
18
18
  d="M10.1667 1V6.14286C10.1667 7.05217 9.78036 7.92424 9.09273 8.56722C8.40509 9.21021 7.47246 9.57143 6.5 9.57143C5.52754 9.57143 4.59491 9.21021 3.90728 8.56722C3.21964 7.92424 2.83333 7.05217 2.83333 6.14286V1M1 13H12"
19
19
  stroke=${htmlColor || '#55534E'}
20
- stroke-linecap="round"
20
+ strokeLinecap="round"
21
21
  stroke-linejoin="round"
22
- stroke-width=${strokeWidth || '1'}
22
+ strokeWidth=${strokeWidth || '1'}
23
23
  />
24
24
  </svg>`;
25
25
  };
@@ -17,8 +17,8 @@ export const IconUndoToString = (color = 'inherit', htmlColor, strokeWidth, onCl
17
17
  <path
18
18
  d="M14.3506 8C14.3506 4.32927 11.3173 1.34146 7.59059 1.34146C5.33725 1.42683 3.08392 2.62195 1.78392 4.5M1.35059 1V4.41463C1.35059 4.67073 1.52392 4.84146 1.78392 4.84146H5.25059"
19
19
  stroke="${htmlColor || "#55534E"}"
20
- stroke-linecap="round"
21
- stroke-width="${strokeWidth || '1'}"
20
+ strokeLinecap="round"
21
+ strokeWidth="${strokeWidth || '1'}"
22
22
  />
23
23
  </svg>`;
24
24
  };
@@ -45,3 +45,5 @@ export { IconFileVideo } from './IconFileVideo/IconFileVideo';
45
45
  export { IconFileDefault } from './IconFileDefault/IconFileDefault';
46
46
  export { IconPencilFilled } from './IconPencilFilled/IconPencilFilled';
47
47
  export { IconDeleteFilled } from './IconDeleteFilled/IconDeleteFilled';
48
+ export { IconShare } from './IconShare/IconShare';
49
+ export { IconMultiselect } from './IconMultiselect/IconMultiselect';
@@ -45,3 +45,5 @@ export { IconFileVideo } from './IconFileVideo/IconFileVideo';
45
45
  export { IconFileDefault } from './IconFileDefault/IconFileDefault';
46
46
  export { IconPencilFilled } from './IconPencilFilled/IconPencilFilled';
47
47
  export { IconDeleteFilled } from './IconDeleteFilled/IconDeleteFilled';
48
+ export { IconShare } from './IconShare/IconShare';
49
+ export { IconMultiselect } from './IconMultiselect/IconMultiselect';
@@ -92,10 +92,14 @@ export const Button = ({ label, variant = 'fill', size = 'md', style, condition,
92
92
  '--button-disabled-color': variant === 'fill' || variant === 'link' ? `color-mix(in srgb, ${color} 80%, white)` : `color-mix(in srgb, ${color} 10%, transparent)`,
93
93
  '--button-disabled-textColor': variant === 'fill' ? `color-mix(in srgb, ${color} 80%, white)` : `color-mix(in srgb, ${color} 50%, transparent)`,
94
94
  } : {}, onClick: onClick, disabled: disabled, "aria-disabled": disabled, type: type, name: name ? name : label ? `button-${label}` : 'button', form: form },
95
- btnIcon && (buttonStyle === 'icon' || buttonStyle === 'default') &&
96
- React.cloneElement(btnIcon, {
95
+ btnIcon && (buttonStyle === 'icon' || buttonStyle === 'default') && (() => {
96
+ var _a;
97
+ const iconElement = btnIcon;
98
+ const defaultStrokeWidth = size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0';
99
+ return React.cloneElement(iconElement, {
97
100
  htmlColor: iconColorStyle,
98
- strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
99
- }),
101
+ strokeWidth: (_a = iconElement.props.strokeWidth) !== null && _a !== void 0 ? _a : defaultStrokeWidth,
102
+ });
103
+ })(),
100
104
  (buttonStyle === 'text' || buttonStyle === 'default') && (React.createElement(Typography, { variant: "Body1" }, label ? label : typeof children === 'string' && children))));
101
105
  };
@@ -6,10 +6,10 @@ import { TextEditor } from '../TextEditor/TextEditor';
6
6
  import { AttachedFilesPreview } from '../AttachedFilesPreview/AttachedFilesPreview';
7
7
  import { IconDeleteFilled, IconPencilFilled } from '../../Icons';
8
8
  import { IconButton } from '../IconButton/IconButton';
9
- export const Comment = ({ id, value, style, className, username, avatar, creationDate, isEdit = false, label, error = false, helperText, onChange, onSubmit, }) => {
9
+ export const Comment = ({ id, value, style, className, username, avatar, creationDate, canAttachFiles = false, files = [], canEdit = false, isEdit = false, label, error = false, helperText, onChange, onSubmit, onDelete, }) => {
10
10
  const [commentText, setCommentText] = useState(value || '');
11
11
  const [isEditMode, setIsEditMode] = useState(isEdit);
12
- const [attachedFiles, setAttachedFiles] = useState([]);
12
+ const [attachedFiles, setAttachedFiles] = useState(files);
13
13
  const wrapperClassess = classNames(styles['wrapper--input'], className, {
14
14
  [styles['wrapper--input-label']]: label,
15
15
  [styles['wrapper--input-helperText']]: error,
@@ -19,10 +19,12 @@ export const Comment = ({ id, value, style, className, username, avatar, creatio
19
19
  const handleEditClick = () => {
20
20
  setIsEditMode((prev) => !prev);
21
21
  };
22
- const handleDeleteClick = () => { };
22
+ const handleDeleteClick = () => {
23
+ onDelete === null || onDelete === void 0 ? void 0 : onDelete(id);
24
+ };
23
25
  const handleSubmit = (value, files) => {
24
26
  if (onSubmit) {
25
- onSubmit();
27
+ onSubmit(value, files);
26
28
  }
27
29
  setCommentText(value);
28
30
  setAttachedFiles(files);
@@ -36,15 +38,14 @@ export const Comment = ({ id, value, style, className, username, avatar, creatio
36
38
  return (React.createElement("div", { className: wrapperClassess, style: style },
37
39
  React.createElement("div", { style: { display: 'flex', justifyContent: 'space-between' } },
38
40
  React.createElement("div", { className: styles.labelWrapper },
39
- React.createElement("div", { className: "profile" },
40
- React.createElement("img", { src: avatar, alt: "Avatar", className: styles.avatar })),
41
+ React.createElement("div", { className: "profile" }, avatar ? (React.createElement("img", { src: avatar, alt: "Avatar", className: styles.avatar })) : (React.createElement("div", { className: styles.avatar }, "\uD83D\uDC64"))),
41
42
  React.createElement("div", { className: styles.infoWrapper },
42
43
  React.createElement(Typography, { variant: "Body2-Medium", className: labelClasses }, username),
43
44
  React.createElement(Typography, { variant: "Caption", className: styles.label, style: { color: '#8E8E93' } }, creationDate))),
44
- React.createElement("div", { className: styles.iconsWrapper },
45
- React.createElement(IconButton, { icon: React.createElement(IconPencilFilled, null), onClick: handleEditClick, size: "sm" }),
46
- React.createElement(IconButton, { icon: React.createElement(IconDeleteFilled, null), onClick: handleDeleteClick, size: "sm" }))),
47
- isEditMode ? (React.createElement(TextEditor, { defaultValue: commentText, onSubmit: handleSubmit, onChange: handleChange, error: error, helperText: helperText, files: attachedFiles })) : (React.createElement("div", { className: styles.commentWrapper },
45
+ canEdit && (React.createElement("div", { className: styles.iconsWrapper },
46
+ React.createElement(IconButton, { icon: React.createElement(IconPencilFilled, null), onClick: handleEditClick, size: "sm", style: { aspectRatio: 0 } }),
47
+ React.createElement(IconButton, { icon: React.createElement(IconDeleteFilled, null), onClick: handleDeleteClick, size: "sm", style: { aspectRatio: 0 } })))),
48
+ isEditMode ? (React.createElement(TextEditor, { defaultValue: commentText, onSubmit: handleSubmit, onChange: handleChange, error: error, helperText: helperText, files: attachedFiles, canAttachFiles: canAttachFiles })) : (React.createElement("div", { className: styles.commentWrapper },
48
49
  attachedFiles.length > 0 && (React.createElement(AttachedFilesPreview, { files: attachedFiles, className: styles.attachedFilesContainer })),
49
50
  React.createElement("div", { id: id, className: inputClassess, dangerouslySetInnerHTML: { __html: commentText || '' } }))),
50
51
  error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText) }, helperText))));
@@ -5,7 +5,7 @@
5
5
  right: 0;
6
6
  bottom: 0;
7
7
  background-color: var(--dialog-overlay);
8
- z-index: 999;
8
+ z-index: 1400;
9
9
  }
10
10
  .dialog {
11
11
  border: none;
@@ -13,7 +13,7 @@
13
13
  box-shadow: 0px 4px 16px var(--dialog-overlay);
14
14
  padding: 30px;
15
15
  background-color: var(--white);
16
- z-index: 1000;
16
+ z-index: 1401;
17
17
  position: fixed;
18
18
  top: 50%;
19
19
  left: 50%;
@@ -172,7 +172,7 @@ export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedIt
172
172
  })))));
173
173
  return showTooltip ? (React.createElement(Tooltip, { label: ((_b = getComparisonValue(item, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left" }, itemContent)) : (itemContent);
174
174
  };
175
- export const Dropdown = ({ options, id, label, placeholder, required = false, value, defaultValue, onChange, getOptionLabel, variant = 'text', size = 'lg', style, className, isLeftLabel = false, isDivider = false, disabled = false, readOnly = false, isOpened = false, error = false, helperText, onClick, onBlur, onFocus, onClose, clearable = true, enableAutocomplete = false, noOptionsText = 'Нет вариантов для выбора', }) => {
175
+ export const Dropdown = ({ options, id, label, placeholder, required = false, value, defaultValue, onChange, getOptionLabel, variant = 'text', size = 'lg', style, className, isLeftLabel = false, isDivider = false, disabled = false, readOnly = false, isOpened = false, error = false, helperText, onClick, onBlur, onFocus, onClose, clearable = true, enableAutocomplete = false, noOptionsText = 'Нет вариантов для выбора', lng = 'ru', }) => {
176
176
  const [isOpen, setIsOpen] = useState(isOpened);
177
177
  const [modifiedOptions, setModifiedOptions] = useState([]);
178
178
  const [selectedItem, setSelectedItem] = useState(null);
@@ -329,7 +329,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
329
329
  setActiveIndex(-1);
330
330
  if (required) {
331
331
  setErrorInput(true);
332
- setErrorInputHelperText(helperText !== null && helperText !== void 0 ? helperText : 'Поле обязательно для заполнения');
332
+ setErrorInputHelperText((helperText !== null && helperText !== void 0 ? helperText : lng === 'ru') ? 'Поле обязательно для заполнения' : 'Field is required');
333
333
  }
334
334
  };
335
335
  const [showSelectedTooltip, setShowSelectedTooltip] = useState(false);
@@ -354,7 +354,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
354
354
  }),
355
355
  isOpen && enableAutocomplete ? (React.createElement("input", { ref: inputRef, type: "text", value: searchValue, className: styles.inlineSearchInput, onChange: handleSearchChange, placeholder: getComparisonValue(selectedItem, getOptionLabel)
356
356
  ? getComparisonValue(selectedItem, getOptionLabel).toString()
357
- : 'Поиск...', onClick: (e) => {
357
+ : lng === 'ru' ? 'Поиск...' : 'Search...', onClick: (e) => {
358
358
  e.stopPropagation();
359
359
  e.preventDefault();
360
360
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
@@ -367,7 +367,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
367
367
  }, onBlur: (e) => {
368
368
  e.stopPropagation();
369
369
  onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
370
- }, onKeyDown: handleKeyDown, autoFocus: true })) : selectedItem ? (getComparisonValue(selectedItem, getOptionLabel)) : (searchValue || ((_a = placeholder !== null && placeholder !== void 0 ? placeholder : label) !== null && _a !== void 0 ? _a : 'Выберите значение'))));
370
+ }, onKeyDown: handleKeyDown, autoFocus: true })) : selectedItem ? (getComparisonValue(selectedItem, getOptionLabel)) : (searchValue || (((_a = placeholder !== null && placeholder !== void 0 ? placeholder : label) !== null && _a !== void 0 ? _a : lng === 'ru') ? 'Выберите значение' : 'Select value'))));
371
371
  return showSelectedTooltip ? (React.createElement("div", { className: styles.textField },
372
372
  React.createElement(Tooltip, { label: ((_b = getComparisonValue(selectedItem, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left", style: { width: '100% !important' } }, textFieldContent))) : (textFieldContent);
373
373
  };
@@ -376,7 +376,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
376
376
  const menu = isOpen && (React.createElement("div", { className: dropdownClassess }, optionsToRender && optionsToRender.length > 0 ? (optionsToRender.map((optionsToRender, index) => {
377
377
  var _a;
378
378
  return (React.createElement(DropdownListItem, { key: (_a = optionsToRender === null || optionsToRender === void 0 ? void 0 : optionsToRender.key) !== null && _a !== void 0 ? _a : index, item: optionsToRender, getOptionLabel: getOptionLabel, size: size, selectedItem: selectedItem, variant: variant, onChange: onChangeHandler, isActive: activeIndex === index, activeIndex: activeIndex, index: index }));
379
- })) : (React.createElement("div", { className: `${styles['item-container']} ${styles['item-block']}`, style: { paddingLeft: '15px' } }, noOptionsText))));
379
+ })) : (React.createElement("div", { className: `${styles['item-container']} ${styles['item-block']}`, style: { paddingLeft: '15px' } }, lng === 'ru' || lng.includes('ru') ? noOptionsText || 'Нет вариантов для выбора' : noOptionsText || 'No options to select'))));
380
380
  return isOpen ? menu : null;
381
381
  };
382
382
  useEffect(() => {
@@ -7,7 +7,7 @@ import { IconClose, IconDownload, IconFile } from '../../Icons';
7
7
  import { Tooltip } from '../Tooltip/Tooltip';
8
8
  import classNames from 'classnames';
9
9
  import { formatFileSize } from '../AttachedFilesPreview/AttachedFilesPreview';
10
- export const FileItem = ({ file, loading = false, error = '', onDownload, onDelete, canDelete = true, canDownload = true, style, isAddedFile, isRejectedFile, }) => {
10
+ export const FileItem = ({ file, loading = false, error = '', onDownload, onDelete, canDelete = true, canDownload = true, style, isAddedFile, isRejectedFile, progressBarWidth }) => {
11
11
  const [isLoadingFinished, setIsLoadingFinished] = useState(false);
12
12
  const [animationDuration, setAnimationDuration] = useState(0);
13
13
  const [maxLength, setMaxLength] = useState(30);
@@ -107,6 +107,6 @@ export const FileItem = ({ file, loading = false, error = '', onDownload, onDele
107
107
  React.createElement("div", { className: styles['fileItemActions'] },
108
108
  !(isAddedFile || isRejectedFile) && canDownload && (React.createElement(IconButton, { className: styles.fileIcon, icon: React.createElement(IconDownload, null), onClick: (e) => handleDownloadClick(e, file), color: "var(--icons-grey)", size: "sm" })),
109
109
  canDelete && (React.createElement(IconButton, { className: styles.fileIcon, icon: React.createElement(IconClose, null), onClick: (e) => handleDeleteClick(e, file.id || ''), color: "var(--icons-grey)", size: "sm" })))),
110
- loading && !isLoadingFinished && (React.createElement(ProgressBar, { animated: true, size: "sm", value: 100, setIsLoadingFinished: setIsLoadingFinished, animationDuration: animationDuration })),
110
+ loading && !isLoadingFinished && (React.createElement(ProgressBar, { animated: true, size: "sm", value: 100, setIsLoadingFinished: setIsLoadingFinished, animationDuration: animationDuration, width: progressBarWidth })),
111
111
  error && (React.createElement(Typography, { variant: "Caption", color: "var(--error-main)" }, error))));
112
112
  };
@@ -9,7 +9,7 @@ export const FileLoader = ({ maxFileSize = 2, maxFileCount = 10, acceptedFormats
9
9
  'image/*': ['.png', '.gif', '.jpeg', '.jpg'],
10
10
  'application/pdf': ['.pdf'],
11
11
  'application/msword': ['.doc', '.docx'],
12
- }, addedFiles, setAddedFiles, filesList = [], canAdd = true, lng = 'ru', className, style, fileValidator }) => {
12
+ }, addedFiles, setAddedFiles, filesList = [], canAdd = true, lng = 'ru', className, style, fileValidator, progressBarWidth }) => {
13
13
  const [isLoadingFiles, setIsLoadingFiles] = useState(false);
14
14
  const [loadingFilesNames, setLoadingFilesNames] = useState([]);
15
15
  const [errorFiles, setErrorFiles] = useState([]);
@@ -43,6 +43,22 @@ export const FileLoader = ({ maxFileSize = 2, maxFileCount = 10, acceptedFormats
43
43
  message: lng === 'ru' || lng.includes('ru') ? `Максимальное количество файлов ${maxFileCount}` : `Maximum number of files ${maxFileCount}`,
44
44
  };
45
45
  }
46
+ if (acceptedFormats) {
47
+ const acceptedExtensions = Object.values(acceptedFormats)
48
+ .reduce((acc, val) => acc.concat(val), []);
49
+ const fileParts = file.name.split('.');
50
+ const fileExtension = fileParts.length > 1
51
+ ? `.${fileParts.pop().toLowerCase()}`
52
+ : '';
53
+ if (!acceptedExtensions.includes(fileExtension)) {
54
+ return {
55
+ code: 'file-invalid-type',
56
+ message: lng === 'ru' || lng.includes('ru')
57
+ ? `Файл должен быть одного из следующих типов: ${acceptedExtensions.join(', ')}`
58
+ : `File must be one of: ${acceptedExtensions.join(', ')}`,
59
+ };
60
+ }
61
+ }
46
62
  if (fileValidator) {
47
63
  const customValidationResult = fileValidator(file);
48
64
  if (customValidationResult) {
@@ -113,7 +129,7 @@ export const FileLoader = ({ maxFileSize = 2, maxFileCount = 10, acceptedFormats
113
129
  }
114
130
  },
115
131
  validator: fileValidatorInner,
116
- accept: acceptedFormats,
132
+ accept: undefined,
117
133
  maxFiles: maxFileCount,
118
134
  disabled: !canAdd,
119
135
  });
@@ -125,7 +141,7 @@ export const FileLoader = ({ maxFileSize = 2, maxFileCount = 10, acceptedFormats
125
141
  setLoadingFilesNames(loadingFilesNames.filter((id) => id !== id));
126
142
  };
127
143
  const acceptedFileItems = addedFilesFormated.map((file) => {
128
- return (React.createElement(FileItem, { key: file.id, file: file, loading: loadingFilesNames.includes(file.filename), onDelete: handleDeleteFiles, isAddedFile: true }));
144
+ return (React.createElement(FileItem, { key: file.id, file: file, loading: loadingFilesNames.includes(file.filename), onDelete: handleDeleteFiles, isAddedFile: true, progressBarWidth: progressBarWidth }));
129
145
  });
130
146
  const handleDeleteRejectedFile = (id) => {
131
147
  setErrorFiles(errorFiles.filter((rejection) => rejection.file.id !== id));
@@ -10,8 +10,13 @@ export const IconButton = ({ icon, size = 'md', color, style, disabled = false,
10
10
  '--hover-border-radius': style.borderRadius,
11
11
  }));
12
12
  return (React.createElement("button", { className: classNames(styles['iconButton'], styles[`iconButton--${size}`], className), disabled: disabled, "aria-disabled": disabled, type: "button", onClick: (e) => onClick(e), style: combinedStyle }, renderIcon &&
13
- React.cloneElement(renderIcon, {
14
- htmlColor: color,
15
- strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
16
- })));
13
+ (() => {
14
+ var _a;
15
+ const iconElement = renderIcon;
16
+ const defaultStrokeWidth = size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0';
17
+ return React.cloneElement(iconElement, {
18
+ htmlColor: color,
19
+ strokeWidth: (_a = iconElement.props.strokeWidth) !== null && _a !== void 0 ? _a : defaultStrokeWidth,
20
+ });
21
+ })()));
17
22
  };
@@ -6,7 +6,7 @@ import { Typography } from '../Typography/Typography';
6
6
  /**
7
7
  * Компонент Input для создания текстовых полей ввода различных стилей и размеров.
8
8
  */
9
- export const Input = ({ id, label, placeholder, size = 'lg', value, style, className, multiline = false, rows = 4, resize = false, disabled = false, readOnly = false, isLeftLabel = false, icon, error = false, helperText, onChange, required = false, }) => {
9
+ export const Input = ({ id, label, placeholder, size = 'lg', value, style, className, multiline = false, rows = 4, resize = false, disabled = false, readOnly = false, isLeftLabel = false, icon, error = false, helperText, onChange, onBlur, required = false, }) => {
10
10
  const [inputLabel, setInputLabel] = useState(label);
11
11
  const handleChange = (event) => {
12
12
  event.stopPropagation();
@@ -21,6 +21,9 @@ export const Input = ({ id, label, placeholder, size = 'lg', value, style, class
21
21
  setInputLabel('');
22
22
  }
23
23
  };
24
+ const handleOnBlur = (event) => {
25
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
26
+ };
24
27
  const wrapperClassess = classNames(styles['wrapper--input'], className, {
25
28
  [styles['wrapper--left']]: isLeftLabel,
26
29
  [styles['wrapper--input-label']]: label && !isLeftLabel && !required,
@@ -43,6 +46,6 @@ export const Input = ({ id, label, placeholder, size = 'lg', value, style, class
43
46
  return (React.createElement("div", { className: wrapperClassess, style: style },
44
47
  inputLabel && (React.createElement(Typography, { variant: "Caption", className: labelClasses }, inputLabel)),
45
48
  icon && React.createElement("div", { className: styles.icon }, icon),
46
- multiline ? (React.createElement("textarea", { id: id, className: inputClassess, value: value, placeholder: placeholder, onChange: handleChange, disabled: disabled, style: { height: `${rows * 20}px` } })) : (React.createElement("input", { id: id, className: inputClassess, value: value, placeholder: placeholder, onChange: handleChange, disabled: disabled, readOnly: readOnly })),
49
+ multiline ? (React.createElement("textarea", { id: id, className: inputClassess, value: value, placeholder: placeholder, onChange: handleChange, onBlur: handleOnBlur, disabled: disabled, style: { height: `${rows * 20}px` } })) : (React.createElement("input", { id: id, className: inputClassess, value: value, placeholder: placeholder, onChange: handleChange, onBlur: handleOnBlur, disabled: disabled, readOnly: readOnly })),
47
50
  error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText, styles[size]) }, helperText))));
48
51
  };
@@ -5,7 +5,7 @@ import { Typography } from '../Typography/Typography';
5
5
  import { Checkbox } from '../Checkbox/Checkbox';
6
6
  import { RadioButton } from '../RadioButton/RadioButton';
7
7
  import { ChevronDown } from '../../Icons';
8
- export const List = ({ onClick, onCheck, onRadioSelect, checked = false, selected = false, disabled = false, label, id, style, className, collapsible = false, open = false, withCheckbox = false, checkboxColor, checkboxFilled, withRadioButton = false, customBullet, customItemBullet, bulletClassName, children, isHeader = false, parentChecked = false, }) => {
8
+ export const List = ({ onClick, onCheck, onRadioSelect, checked = false, selected = false, disabled = false, label, id, style, className, collapsible = false, open = false, withCheckbox = false, checkboxColor, checkboxFilled, withRadioButton = false, customBullet, customItemBullet, bulletClassName, titleContent, children, isHeader = false, parentChecked = false, }) => {
9
9
  const [isOpen, setIsOpen] = useState(open);
10
10
  const [isChecked, setIsChecked] = useState(checked || parentChecked);
11
11
  const childIds = [];
@@ -57,14 +57,15 @@ export const List = ({ onClick, onCheck, onRadioSelect, checked = false, selecte
57
57
  const headerClassNames = classNames(styles.header, className);
58
58
  const contentClassNames = classNames(styles.content, isOpen ? styles['content--expanded'] : styles['content--collapsed']);
59
59
  return (React.createElement("div", { className: styles.collapsibleList },
60
- label && (React.createElement("div", { className: headerClassNames, onClick: handleClick, style: style },
60
+ label || titleContent && (React.createElement("div", { className: headerClassNames, onClick: handleClick, style: style },
61
61
  !isHeader && (React.createElement("div", null,
62
62
  withCheckbox && (React.createElement("span", { onClick: handleCheckboxClick },
63
63
  React.createElement(Checkbox, { checked: isChecked, color: checkboxColor, filled: checkboxFilled, disabled: disabled }))),
64
64
  withRadioButton && (React.createElement("span", { onClick: handleRadioClick },
65
65
  React.createElement(RadioButton, { checked: selected, value: id, disabled: disabled }))),
66
66
  customBullet && React.createElement("span", { className: classNames(styles.bullet, bulletClassName) }, customBullet))),
67
- React.createElement(Typography, { variant: "Body1" }, label),
67
+ label && React.createElement(Typography, { variant: "Body1" }, label),
68
+ titleContent,
68
69
  collapsible && (React.createElement("span", { className: styles.indicator }, isOpen ? React.createElement(ChevronDown, null) : React.createElement(ChevronDown, { rotation: 270 }))))),
69
70
  React.createElement("div", { className: collapsible ? contentClassNames : styles.content, style: { paddingLeft: !label ? 0 : '16px' } }, React.Children.map(children, (child) => {
70
71
  if (React.isValidElement(child)) {
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  /**
6
6
  * Компонент ProgressBar отображает прогресс в виде заполненной полосы.
7
7
  */
8
- export const ProgressBar = ({ value = 0, max = 100, size = 'md', showValue = true, animated = false, animationDuration = 8000, setIsLoadingFinished, }) => {
8
+ export const ProgressBar = ({ value = 0, max = 100, size = 'md', showValue = true, animated = false, animationDuration = 8000, setIsLoadingFinished, width, }) => {
9
9
  const [percent, setPercent] = useState(value);
10
10
  const validPercentage = Math.min(Math.max(value, 0), max);
11
11
  const progressBarClasses = classNames(styles['progress-bar'], styles[size], {
@@ -38,7 +38,7 @@ export const ProgressBar = ({ value = 0, max = 100, size = 'md', showValue = tru
38
38
  }
39
39
  }, [animated, validPercentage, setIsLoadingFinished, animationDuration]);
40
40
  return (React.createElement("div", { className: styles['progress-bar--wrapper'] },
41
- React.createElement("progress", { id: "linear-progress", className: progressBarClasses, value: percent, max: max }),
41
+ React.createElement("progress", { id: "linear-progress", className: progressBarClasses, value: percent, max: max, style: { width: width } }),
42
42
  React.createElement("label", { htmlFor: "progress", className: styles['progress-bar-percentage'] }, showValue && (React.createElement(Typography, { variant: "Body1", color: '#9CA0A7', className: styles['progress-bar-percentage'] },
43
43
  percent,
44
44
  "%")))));
@@ -17,7 +17,7 @@ export declare const icons: {
17
17
  warning: React.JSX.Element;
18
18
  info: React.JSX.Element;
19
19
  };
20
- export declare const title: {
20
+ export declare const title: (lng: string) => {
21
21
  success: string;
22
22
  error: string;
23
23
  warning: string;
@@ -20,35 +20,40 @@ export const icons = {
20
20
  warning: React.createElement(IconWarning, { htmlColor: "#ff9500" }),
21
21
  info: React.createElement(IconInfo, { htmlColor: "#6F6F6F" }),
22
22
  };
23
- export const title = {
24
- success: 'Успешно',
25
- error: 'Ошибка',
26
- warning: 'Внимание',
27
- info: 'Информация',
28
- };
29
- export const Snackbar = ({ children, type, duration = 10000, icon = true, onClose, style }) => {
23
+ export const title = (lng) => ({
24
+ success: lng === 'ru' ? 'Успешно' : 'Success',
25
+ error: lng === 'ru' ? 'Ошибка' : 'Error',
26
+ warning: lng === 'ru' ? 'Внимание' : 'Warning',
27
+ info: lng === 'ru' ? 'Информация' : 'Info',
28
+ });
29
+ export const Snackbar = ({ children, type, duration = 10000, icon = true, onClose, style, lng = 'ru' }) => {
30
30
  const [isVisible, setIsVisible] = useState(true);
31
+ const [isExiting, setIsExiting] = useState(false);
31
32
  useEffect(() => {
32
33
  if (duration > 0) {
33
34
  const timer = setTimeout(() => {
34
- setIsVisible(false);
35
- onClose === null || onClose === void 0 ? void 0 : onClose();
35
+ handleClose();
36
36
  }, duration);
37
37
  return () => clearTimeout(timer);
38
38
  }
39
39
  }, [duration, onClose]);
40
40
  const handleClose = () => {
41
- setIsVisible(false);
42
- onClose === null || onClose === void 0 ? void 0 : onClose();
41
+ setIsExiting(true);
42
+ setTimeout(() => {
43
+ setIsVisible(false);
44
+ onClose === null || onClose === void 0 ? void 0 : onClose();
45
+ }, 300);
43
46
  };
44
47
  if (!isVisible)
45
48
  return null;
46
- const snackbarClasses = classNames(styles['snackbar-wrapper'], styles[`snackbar--${type}`]);
49
+ const snackbarClasses = classNames(styles['snackbar-wrapper'], styles[`snackbar--${type}`], {
50
+ [styles['snackbar-wrapper--exiting']]: isExiting
51
+ });
47
52
  return (React.createElement("div", { className: snackbarClasses, style: style },
48
53
  React.createElement("div", { className: styles['snackbar-textAndIcon'] },
49
54
  icon && icons[type],
50
55
  React.createElement("div", { className: styles['snackbar-text'] },
51
- React.createElement(Typography, { variant: "Body1-Medium", color: 'var(--text-dark)' }, title[type]),
56
+ React.createElement(Typography, { variant: "Body1-Medium", color: 'var(--text-dark)' }, title(lng)[type]),
52
57
  React.createElement(Typography, { variant: "Body1", color: 'var(--text-btn-light)' }, children))),
53
58
  React.createElement("button", { className: styles.button, onClick: handleClose },
54
59
  React.createElement(IconClose, { htmlColor: 'var(--text-btn-light)' }))));
@@ -18,6 +18,10 @@
18
18
  border-radius: 15px;
19
19
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
20
20
  background-color: var(--white);
21
+ animation: fadeIn 0.3s ease-out;
22
+ }
23
+ .snackbar-wrapper--exiting {
24
+ animation: fadeOut 0.3s ease-in forwards;
21
25
  }
22
26
  .snackbar-textAndIcon {
23
27
  gap: 10px;
@@ -60,3 +64,23 @@
60
64
  background: rgba(130, 130, 134, 0.15);
61
65
  border-radius: 2px;
62
66
  }
67
+ @keyframes fadeIn {
68
+ from {
69
+ opacity: 0;
70
+ transform: translateX(-50%) translateY(-10px);
71
+ }
72
+ to {
73
+ opacity: 1;
74
+ transform: translateX(-50%) translateY(0);
75
+ }
76
+ }
77
+ @keyframes fadeOut {
78
+ from {
79
+ opacity: 1;
80
+ transform: translateX(-50%) translateY(0);
81
+ }
82
+ to {
83
+ opacity: 0;
84
+ transform: translateX(-50%) translateY(-10px);
85
+ }
86
+ }
@@ -23,7 +23,7 @@ const getElementFromRange = (range) => {
23
23
  const container = range.commonAncestorContainer;
24
24
  return container.nodeType === Node.TEXT_NODE ? container.parentElement : container;
25
25
  };
26
- export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, helperText, files, required, className, isButtonDisabled, }) => {
26
+ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, helperText, canAttachFiles = false, files, required, className, isButtonDisabled, }) => {
27
27
  const editorRef = useRef(null);
28
28
  const uploaderRef = useRef(null);
29
29
  const submitButtonRef = useRef(null);
@@ -306,50 +306,55 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
306
306
  return prev.filter((f) => f.id !== fileId);
307
307
  });
308
308
  };
309
- const getEditorActions = useCallback(() => [
310
- {
311
- name: 'bold',
312
- icon: IconBoldToString('', '', '1.5'),
313
- title: 'Bold (Ctrl+B)',
314
- result: () => { },
315
- },
316
- {
317
- name: 'italic',
318
- icon: IconItalicToString('', '', '1.5'),
319
- title: 'Italic (Ctrl+I)',
320
- result: () => { },
321
- },
322
- {
323
- name: 'underline',
324
- icon: IconUnderlineToString('', '', '1.5'),
325
- title: 'Underline (Ctrl+U)',
326
- result: () => { },
327
- },
328
- {
329
- name: 'strikethrough',
330
- icon: IconStrikethroughToString('', '', '1.5'),
331
- title: 'Strike-through',
332
- result: () => { },
333
- },
334
- {
335
- name: 'heading2',
336
- icon: IconHeader2ToString('', '', '1.5'),
337
- title: 'Heading 2',
338
- result: () => { },
339
- },
340
- {
341
- name: 'ulist',
342
- icon: IconBulletlistToString(),
343
- title: 'Bullet List',
344
- result: () => { },
345
- },
346
- {
347
- name: 'image',
348
- icon: IconAttachToString('', '', '1.5'),
349
- title: 'Upload Image',
350
- result: () => { },
351
- },
352
- ], []);
309
+ const getEditorActions = useCallback(() => {
310
+ const baseActions = [
311
+ {
312
+ name: 'bold',
313
+ icon: IconBoldToString('', '', '1.5'),
314
+ title: 'Bold (Ctrl+B)',
315
+ result: () => { },
316
+ },
317
+ {
318
+ name: 'italic',
319
+ icon: IconItalicToString('', '', '1.5'),
320
+ title: 'Italic (Ctrl+I)',
321
+ result: () => { },
322
+ },
323
+ {
324
+ name: 'underline',
325
+ icon: IconUnderlineToString('', '', '1.5'),
326
+ title: 'Underline (Ctrl+U)',
327
+ result: () => { },
328
+ },
329
+ {
330
+ name: 'strikethrough',
331
+ icon: IconStrikethroughToString('', '', '1.5'),
332
+ title: 'Strike-through',
333
+ result: () => { },
334
+ },
335
+ {
336
+ name: 'heading2',
337
+ icon: IconHeader2ToString('', '', '1.5'),
338
+ title: 'Heading 2',
339
+ result: () => { },
340
+ },
341
+ {
342
+ name: 'ulist',
343
+ icon: IconBulletlistToString(),
344
+ title: 'Bullet List',
345
+ result: () => { },
346
+ },
347
+ ];
348
+ if (canAttachFiles) {
349
+ baseActions.push({
350
+ name: 'image',
351
+ icon: IconAttachToString('', '', '1.5'),
352
+ title: 'Upload Image',
353
+ result: () => { },
354
+ });
355
+ }
356
+ return baseActions;
357
+ }, [canAttachFiles]);
353
358
  const getEditorClasses = useCallback(() => ({
354
359
  actionbar: styles.pellActionbar,
355
360
  button: styles.pellButton,
@@ -393,11 +398,15 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
393
398
  editorRef.current.appendChild(actionbar);
394
399
  }
395
400
  const buttons = editorRef.current.querySelectorAll(`.${styles.pellButton}`);
396
- const commands = ['bold', 'italic', 'underline', 'strikethrough', 'heading2', 'ulist', 'image'];
401
+ const commands = ['bold', 'italic', 'underline', 'strikethrough', 'heading2', 'ulist'];
402
+ if (canAttachFiles) {
403
+ commands.push('image');
404
+ }
397
405
  buttons.forEach((button, index) => {
398
406
  const command = commands[index];
399
407
  if (command) {
400
408
  const htmlButton = button;
409
+ buttonRefs.current[command] = htmlButton;
401
410
  htmlButton.setAttribute('data-command', command);
402
411
  htmlButton.onclick = null;
403
412
  htmlButton.addEventListener('mousedown', (e) => {
@@ -432,10 +441,10 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
432
441
  };
433
442
  const handleEditorChange = useCallback(() => {
434
443
  updateActiveStates();
435
- }, []);
436
- if (onChange && (editor === null || editor === void 0 ? void 0 : editor.content)) {
437
- onChange(editor.content.innerHTML, attachedFiles);
438
- }
444
+ if (onChange && (editor === null || editor === void 0 ? void 0 : editor.content)) {
445
+ onChange(editor.content.innerHTML, attachedFiles);
446
+ }
447
+ }, [onChange, editor, attachedFiles, updateActiveStates]);
439
448
  const handleSubmit = useCallback(() => {
440
449
  if (!(editor === null || editor === void 0 ? void 0 : editor.content)) {
441
450
  return;
@@ -469,6 +478,7 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
469
478
  };
470
479
  useEffect(() => {
471
480
  if (editorRef.current) {
481
+ editorRef.current.innerHTML = '';
472
482
  const pellEditor = initializePellEditor();
473
483
  pellEditor.content.innerHTML = defaultValue || '';
474
484
  setEditor(pellEditor);
@@ -487,6 +497,9 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
487
497
  pellEditorContent.removeEventListener('keyup', handleKeyUp);
488
498
  pellEditorContent.removeEventListener('mouseup', handleMouseUp);
489
499
  pellEditorContent.removeEventListener('focus', handleFocus);
500
+ if (editorRef.current) {
501
+ editorRef.current.innerHTML = '';
502
+ }
490
503
  };
491
504
  }
492
505
  document.addEventListener('keydown', handleKeyDown);
@@ -524,6 +537,6 @@ export const TextEditor = ({ label, onSubmit, onChange, defaultValue, error, hel
524
537
  React.createElement("div", { className: inputClassess },
525
538
  attachedFiles.length > 0 && (React.createElement(AttachedFilesPreview, { files: attachedFiles, onDelete: (id) => removeAttachedFile(id), className: styles.attachedFilesContainer, isEdit: true })),
526
539
  React.createElement("div", { ref: editorRef }),
527
- React.createElement("input", { ref: uploaderRef, type: "file", style: { display: 'none' }, multiple: true, onChange: handleUploadFiles, accept: ACCEPTED_FILE_TYPES })),
540
+ canAttachFiles && (React.createElement("input", { ref: uploaderRef, type: "file", style: { display: 'none' }, multiple: true, onChange: handleUploadFiles, accept: ACCEPTED_FILE_TYPES }))),
528
541
  error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText) }, helperText))));
529
542
  };
@@ -82,6 +82,7 @@
82
82
  height: 24px;
83
83
  display: flex;
84
84
  align-items: center;
85
+ justify-content: center;
85
86
  border: none;
86
87
  border-radius: 100%;
87
88
  cursor: pointer;
@@ -189,7 +189,7 @@ export const Tooltip = ({ label, children, className, style, overlayChildren = f
189
189
  updateCoords(e.clientX, e.clientY);
190
190
  }
191
191
  };
192
- const tooltipStyles = Object.assign(Object.assign({}, style), { position: 'fixed', left: `${coords.x}px`, top: `${coords.y}px`, backgroundColor: color ? hexToRgba(color, opacity) : `rgba(0, 0, 0, ${opacity})`, zIndex: 1000 });
192
+ const tooltipStyles = Object.assign(Object.assign({}, style), { position: 'fixed', left: `${coords.x}px`, top: `${coords.y}px`, backgroundColor: color ? hexToRgba(color, opacity) : `rgba(0, 0, 0, ${opacity})`, zIndex: 1500 });
193
193
  const tooltipClassNames = classNames(styles.tooltip, isVisible && styles['tooltip--visible'], className);
194
194
  return (React.createElement(React.Fragment, null,
195
195
  React.createElement("div", { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseMove: handleMouseMove, className: styles.wrapper, ref: childrenRef }, children),
@@ -90,6 +90,8 @@ export interface InputProps {
90
90
  helperText?: string;
91
91
  /** Callback при изменении значения */
92
92
  onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
93
+ /** Callback при потере фокуса */
94
+ onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
93
95
  /** Обязательное поле */
94
96
  required?: boolean;
95
97
  }
@@ -222,6 +224,8 @@ export interface DropdownProps {
222
224
  enableAutocomplete?: boolean;
223
225
  /** Текст при отсутствии опций */
224
226
  noOptionsText?: string;
227
+ /** Язык */
228
+ lng?: string;
225
229
  }
226
230
  /** @internal */
227
231
  export interface TypographyProps {
@@ -251,6 +255,8 @@ export interface ProgressBarProps {
251
255
  animationDuration?: number;
252
256
  /**Для выставления флага окончания загрузки */
253
257
  setIsLoadingFinished?: (value: boolean) => void;
258
+ /** Ширина прогресс бара */
259
+ width?: string;
254
260
  }
255
261
  export interface ProgressLoaderProps {
256
262
  /** Значение */
@@ -360,6 +366,8 @@ export type SnackbarProps = {
360
366
  onClose?: () => void;
361
367
  /** Стили передаваемые напрямую */
362
368
  style?: CSSProperties;
369
+ /** Язык */
370
+ lng?: string;
363
371
  };
364
372
  export type TAttachments = {
365
373
  id: string;
@@ -443,6 +451,8 @@ export interface FileItemProps {
443
451
  isAddedFile?: boolean;
444
452
  /** Флаг отклоненного файла */
445
453
  isRejectedFile?: boolean;
454
+ /** Ширина прогресс бара */
455
+ progressBarWidth?: string;
446
456
  }
447
457
  export interface FileLoaderProps {
448
458
  /** Максимальный размер файла */
@@ -467,6 +477,8 @@ export interface FileLoaderProps {
467
477
  style?: React.CSSProperties;
468
478
  /** Функция валидации файла */
469
479
  fileValidator?: (file: File) => FileError | FileError[] | null;
480
+ /** Ширина прогресс бара */
481
+ progressBarWidth?: string;
470
482
  }
471
483
  export interface DialogProps {
472
484
  /** Флаг открытия окна */
@@ -543,6 +555,8 @@ export interface ListItemProps extends BaseListProps {
543
555
  children?: ReactNode;
544
556
  }
545
557
  export interface ListProps extends BaseListProps {
558
+ /** Контент заголовка */
559
+ titleContent?: ReactNode;
546
560
  /** Дочерние элементы */
547
561
  children: React.ReactElement<ListItemProps> | React.ReactElement<ListItemProps>[];
548
562
  /** Возможность раскрытия списка */
@@ -587,6 +601,7 @@ export interface TextEditorProps {
587
601
  defaultValue?: string;
588
602
  error?: boolean;
589
603
  helperText?: string;
604
+ canAttachFiles?: boolean;
590
605
  files?: FilePreview[];
591
606
  required?: boolean;
592
607
  className?: string;
@@ -594,7 +609,7 @@ export interface TextEditorProps {
594
609
  }
595
610
  export interface CommentProps {
596
611
  /** Идентификатор элемента */
597
- id?: string;
612
+ id: string;
598
613
  /** Знчение */
599
614
  value?: string;
600
615
  /** Стили передаваемые напрямую */
@@ -602,8 +617,11 @@ export interface CommentProps {
602
617
  /** Дополнительный класс */
603
618
  className?: string;
604
619
  username: string;
605
- avatar: string;
620
+ avatar?: string | null;
606
621
  creationDate: string;
622
+ canAttachFiles?: boolean;
623
+ files?: FilePreview[];
624
+ canEdit?: boolean;
607
625
  isEdit?: boolean;
608
626
  /** Лейбл */
609
627
  label?: string;
@@ -615,7 +633,8 @@ export interface CommentProps {
615
633
  helperText?: string;
616
634
  /** Callback при изменении значения */
617
635
  onChange?: (value: string, files: FilePreview[]) => void;
618
- onSubmit?: () => {};
636
+ onSubmit?: (value: string, files: FilePreview[]) => void;
637
+ onDelete?: (id: string) => void;
619
638
  }
620
639
  export interface LinkProps {
621
640
  /**Гипертекстовая ссылка */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kamotive_ui",
3
- "version": "1.2.26",
3
+ "version": "1.2.27",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [