@true-engineering/true-react-common-ui-kit 3.56.2 → 3.58.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 (36) hide show
  1. package/dist/components/FloatDocActions/FloatDocActions.d.ts +6 -0
  2. package/dist/components/FloatDocActions/FloatDocActions.stories.d.ts +8 -0
  3. package/dist/components/FloatDocActions/FloatDocActions.styles.d.ts +8 -0
  4. package/dist/components/FloatDocActions/components/DocActions/DocActions.d.ts +12 -0
  5. package/dist/components/FloatDocActions/components/DocActions/DocActions.styles.d.ts +6 -0
  6. package/dist/components/FloatDocActions/components/DocActions/constants.d.ts +1 -0
  7. package/dist/components/FloatDocActions/components/DocActions/index.d.ts +4 -0
  8. package/dist/components/FloatDocActions/components/DocActions/types.d.ts +2 -0
  9. package/dist/components/FloatDocActions/components/index.d.ts +1 -0
  10. package/dist/components/FloatDocActions/constants.d.ts +1 -0
  11. package/dist/components/FloatDocActions/index.d.ts +3 -0
  12. package/dist/components/Input/Input.d.ts +1 -1
  13. package/dist/components/Modal/Modal.styles.d.ts +1 -1
  14. package/dist/components/Notification/Notification.styles.d.ts +1 -1
  15. package/dist/components/Toaster/Toaster.styles.d.ts +1 -1
  16. package/dist/components/index.d.ts +1 -0
  17. package/dist/theme/types.d.ts +2 -1
  18. package/dist/true-react-common-ui-kit.js +826 -549
  19. package/dist/true-react-common-ui-kit.js.map +1 -1
  20. package/dist/true-react-common-ui-kit.umd.cjs +826 -549
  21. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  22. package/package.json +1 -1
  23. package/src/components/FloatDocActions/FloatDocActions.stories.tsx +117 -0
  24. package/src/components/FloatDocActions/FloatDocActions.styles.ts +12 -0
  25. package/src/components/FloatDocActions/FloatDocActions.tsx +34 -0
  26. package/src/components/FloatDocActions/components/DocActions/DocActions.styles.ts +29 -0
  27. package/src/components/FloatDocActions/components/DocActions/DocActions.tsx +43 -0
  28. package/src/components/FloatDocActions/components/DocActions/constants.ts +1 -0
  29. package/src/components/FloatDocActions/components/DocActions/index.ts +4 -0
  30. package/src/components/FloatDocActions/components/DocActions/types.ts +3 -0
  31. package/src/components/FloatDocActions/components/index.ts +1 -0
  32. package/src/components/FloatDocActions/constants.ts +1 -0
  33. package/src/components/FloatDocActions/index.ts +3 -0
  34. package/src/components/Input/Input.tsx +7 -3
  35. package/src/components/index.ts +1 -0
  36. package/src/theme/types.ts +5 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@true-engineering/true-react-common-ui-kit",
3
- "version": "3.56.2",
3
+ "version": "3.58.0",
4
4
  "description": "True Engineering React UI Kit with theming support",
5
5
  "author": "True Engineering (https://trueengineering.ru)",
6
6
  "keywords": [
@@ -0,0 +1,117 @@
1
+ import { FC, useState } from 'react';
2
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
+ import type { Meta, StoryObj } from '@storybook/react';
4
+ import { Button } from '../Button';
5
+ import { Checkbox, ICheckboxProps } from '../Checkbox';
6
+ import { NewMoreMenu } from '../NewMoreMenu';
7
+ import { TextButton } from '../TextButton';
8
+ import {
9
+ FloatDocActions as FloatDocActionsComponent,
10
+ IFloatDocActionsProps,
11
+ } from './FloatDocActions';
12
+ import { DOC_ACTIONS_VIEWS } from './components';
13
+
14
+ const DATA_LENGTH = 300;
15
+
16
+ const Actions: FC = () => (
17
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
18
+ <TextButton icon="trash-can" view="custom">
19
+ Удалить
20
+ </TextButton>
21
+ <TextButton icon="pencil">Редактировать</TextButton>
22
+ <Button view="secondary">Отказать</Button>
23
+ <Button>Одобрить</Button>
24
+ <NewMoreMenu items={[]} />
25
+ </div>
26
+ );
27
+
28
+ const DocActionsWithData: FC<IFloatDocActionsProps> = (props) => {
29
+ const [isOpen, setIsOpen] = useState(false);
30
+ const [state, setState] = useState<Set<number>>(new Set());
31
+
32
+ const handleToggle = () => {
33
+ setIsOpen((prevState) => !prevState);
34
+ };
35
+
36
+ const handleSelectRow: ICheckboxProps<number>['onSelect'] = ({ value }) => {
37
+ if (isNotEmpty(value)) {
38
+ setState((prev) => {
39
+ const newSet = new Set(prev);
40
+ if (newSet.has(value)) {
41
+ newSet.delete(value);
42
+ } else {
43
+ newSet.add(value);
44
+ }
45
+ return newSet;
46
+ });
47
+ }
48
+ };
49
+
50
+ const handleSelectAll: ICheckboxProps<never>['onSelect'] = ({ isSelected }) => {
51
+ console.log('isSelected:', isSelected);
52
+
53
+ setState(
54
+ isSelected ? new Set<number>(Array.from({ length: DATA_LENGTH }, (_, i) => i)) : new Set(),
55
+ );
56
+ };
57
+
58
+ const isAllRowsSelected = state.size === DATA_LENGTH;
59
+ const title = props.title + ': ' + state.size;
60
+
61
+ return (
62
+ <div style={{ display: 'flex', gap: '50px' }}>
63
+ <div style={{ position: 'sticky', top: '50px', height: '50px' }}>
64
+ <Button onClick={handleToggle}>Toggle</Button>
65
+ </div>
66
+ <div style={{ width: '1000px' }}>
67
+ <table style={{ width: '100%', borderCollapse: 'collapse' }}>
68
+ {Array.from({ length: DATA_LENGTH }, (_, index) => (
69
+ <tr key={index} style={{ border: '1px solid skyblue' }}>
70
+ <td style={{ padding: '5px', display: 'flex', gap: '12px' }}>
71
+ {isOpen && (
72
+ <Checkbox value={index} isChecked={state.has(index)} onSelect={handleSelectRow} />
73
+ )}
74
+ <div>Строка {index + 1}</div>
75
+ </td>
76
+ </tr>
77
+ ))}
78
+ </table>
79
+ <div style={{ position: 'sticky', bottom: '12px', left: '8px', right: '18px' }}>
80
+ <FloatDocActionsComponent
81
+ {...props}
82
+ title={title}
83
+ isOpen={isOpen}
84
+ isChecked={isAllRowsSelected}
85
+ isSemiChecked={!isAllRowsSelected && state.size !== 0}
86
+ onSelect={handleSelectAll}
87
+ >
88
+ <Actions />
89
+ </FloatDocActionsComponent>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ );
94
+ };
95
+
96
+ const meta: Meta<typeof DocActionsWithData> = {
97
+ title: 'Table/FloatDocActions',
98
+ component: DocActionsWithData,
99
+ args: {
100
+ title: 'Выбрано',
101
+ view: 'neutral',
102
+ },
103
+ argTypes: {
104
+ view: { options: DOC_ACTIONS_VIEWS, control: 'inline-radio' },
105
+ },
106
+ parameters: {
107
+ controls: {
108
+ exclude: ['actions'],
109
+ },
110
+ },
111
+ };
112
+
113
+ export default meta;
114
+
115
+ type Story = StoryObj<typeof FloatDocActionsComponent>;
116
+
117
+ export const Default: Story = {};
@@ -0,0 +1,12 @@
1
+ import { createUseStyles } from 'react-jss';
2
+ import { animations, ITweakStyles } from '../../theme';
3
+ import { IDocActionsStyles } from './components';
4
+
5
+ export const useStyles = createUseStyles({
6
+ ...animations.slideUp,
7
+ });
8
+
9
+ export type IFloatDocActionsStyles = ITweakStyles<
10
+ typeof useStyles,
11
+ { tweakDocActions: IDocActionsStyles }
12
+ >;
@@ -0,0 +1,34 @@
1
+ import { FC } from 'react';
2
+ import { CSSTransition } from 'react-transition-group';
3
+ import { DocActions, IDocActionsProps } from './components';
4
+ import { DEFAULT_TIMEOUT } from './constants';
5
+ import { useStyles } from './FloatDocActions.styles';
6
+
7
+ export interface IFloatDocActionsProps extends IDocActionsProps {
8
+ isOpen: boolean;
9
+ }
10
+
11
+ export const FloatDocActions: FC<IFloatDocActionsProps> = ({
12
+ isOpen,
13
+ children,
14
+ ...docActionsProps
15
+ }) => {
16
+ const classes = useStyles();
17
+
18
+ return (
19
+ <CSSTransition
20
+ in={isOpen}
21
+ timeout={DEFAULT_TIMEOUT}
22
+ mountOnEnter
23
+ unmountOnExit
24
+ classNames={{
25
+ enter: classes['slide-up-enter'],
26
+ enterActive: classes['slide-up-enter-active'],
27
+ exit: classes['slide-up-exit'],
28
+ exitActive: classes['slide-up-exit-active'],
29
+ }}
30
+ >
31
+ <DocActions {...docActionsProps}>{children}</DocActions>
32
+ </CSSTransition>
33
+ );
34
+ };
@@ -0,0 +1,29 @@
1
+ import { createThemedStyles, ITweakStyles } from '../../../../theme';
2
+ import { ICheckboxStyles } from '../../../Checkbox';
3
+
4
+ export const useStyles = createThemedStyles('DocActions', {
5
+ docActions: {
6
+ display: 'grid',
7
+ alignItems: 'center',
8
+ gridTemplateColumns: 'max-content 1fr',
9
+ },
10
+
11
+ neutral: {},
12
+
13
+ inverse: {},
14
+
15
+ counterWrapper: {},
16
+
17
+ title: {},
18
+
19
+ actionsWrapper: {
20
+ justifySelf: 'end',
21
+ },
22
+ });
23
+
24
+ export type IDocActionsStyles = ITweakStyles<
25
+ typeof useStyles,
26
+ {
27
+ tweakCheckbox: ICheckboxStyles;
28
+ }
29
+ >;
@@ -0,0 +1,43 @@
1
+ import { FC, ReactNode } from 'react';
2
+ import clsx from 'clsx';
3
+ import { useTweakStyles } from '../../../../hooks';
4
+ import { ICommonProps } from '../../../../types';
5
+ import { Checkbox, ICheckboxProps } from '../../../Checkbox';
6
+ import { IDocActionsView } from './types';
7
+ import { IDocActionsStyles, useStyles } from './DocActions.styles';
8
+
9
+ export interface IDocActionsProps
10
+ extends Omit<ICheckboxProps<never>, 'tweakStyles'>,
11
+ ICommonProps<IDocActionsStyles> {
12
+ title: string;
13
+ /** @default 'neutral' */
14
+ view?: IDocActionsView;
15
+ children: ReactNode;
16
+ }
17
+
18
+ export const DocActions: FC<IDocActionsProps> = ({
19
+ title,
20
+ view = 'neutral',
21
+ children,
22
+ tweakStyles,
23
+ ...checkBoxProps
24
+ }) => {
25
+ const classes = useStyles({ theme: tweakStyles });
26
+
27
+ const tweakCheckboxStyles = useTweakStyles({
28
+ tweakStyles,
29
+ className: 'tweakCheckbox',
30
+ currentComponentName: 'DocActions',
31
+ });
32
+
33
+ return (
34
+ <div className={clsx(classes.docActions, classes[view])}>
35
+ <div className={classes.counterWrapper}>
36
+ <Checkbox tweakStyles={tweakCheckboxStyles} {...checkBoxProps}>
37
+ <span className={classes.title}>{title}</span>
38
+ </Checkbox>
39
+ </div>
40
+ <div className={classes.actionsWrapper}>{children}</div>
41
+ </div>
42
+ );
43
+ };
@@ -0,0 +1 @@
1
+ export const DOC_ACTIONS_VIEWS = ['neutral', 'inverse'] as const;
@@ -0,0 +1,4 @@
1
+ export * from './DocActions';
2
+ export * from './types';
3
+ export * from './constants';
4
+ export type { IDocActionsStyles } from './DocActions.styles';
@@ -0,0 +1,3 @@
1
+ import { DOC_ACTIONS_VIEWS } from './constants';
2
+
3
+ export type IDocActionsView = (typeof DOC_ACTIONS_VIEWS)[number];
@@ -0,0 +1 @@
1
+ export * from './DocActions';
@@ -0,0 +1 @@
1
+ export const DEFAULT_TIMEOUT = 150;
@@ -0,0 +1,3 @@
1
+ export * from './FloatDocActions';
2
+ export * from './components';
3
+ export type { IFloatDocActionsStyles } from './FloatDocActions.styles';
@@ -80,7 +80,11 @@ export interface IInputProps
80
80
  shouldFocusOnMount?: boolean;
81
81
  /** @default false */
82
82
  shouldAlwaysShowPlaceholder?: boolean;
83
- onChange: (value: string, event: FormEvent<HTMLInputElement>) => void;
83
+ onChange: (
84
+ value: string,
85
+ event: FormEvent<HTMLInputElement>,
86
+ eventType: 'change' | 'clear',
87
+ ) => void;
84
88
  onIconClick?: () => void;
85
89
  }
86
90
 
@@ -139,7 +143,7 @@ export const Input = forwardRef<HTMLInputElement, IInputProps>(
139
143
  const inputRef = useRef<HTMLInputElement>(null);
140
144
 
141
145
  const handleChange = (event: FormEvent<HTMLInputElement>) => {
142
- onChange(event.currentTarget.value, event);
146
+ onChange(event.currentTarget.value, event, 'change');
143
147
  };
144
148
 
145
149
  const handleFocus = (event: FocusEvent<HTMLInputElement>) => {
@@ -155,7 +159,7 @@ export const Input = forwardRef<HTMLInputElement, IInputProps>(
155
159
  // для SmartInput нужен event, иначе onChange не вызовется
156
160
  const handleOnInputClear = async (event: MouseEvent<HTMLDivElement>) => {
157
161
  // await не убирать (важно для порядка выполнения (сначала onChange, затем focus)
158
- await onChange('', event as any);
162
+ await onChange('', event as any, 'clear');
159
163
  const input = (ref as MutableRefObject<HTMLInputElement>) ?? inputRef;
160
164
  input.current?.focus();
161
165
  };
@@ -13,6 +13,7 @@ export * from './FileItem';
13
13
  export * from './FiltersPane';
14
14
  export * from './Flag';
15
15
  export * from './FlexibleTable';
16
+ export * from './FloatDocActions';
16
17
  export * from './Icon';
17
18
  export * from './IconButton';
18
19
  export * from './IncrementInput';
@@ -13,7 +13,10 @@ import type {
13
13
  IDatePickerHeaderStyles,
14
14
  IDatePickerStyles,
15
15
  IDescriptionStyles,
16
+ IDocActionsStyles,
16
17
  IDotsPreloaderStyles,
18
+ IFileInputStyles,
19
+ IFileItemStyles,
17
20
  IFilterIntervalStyles,
18
21
  IFilterSelectStyles,
19
22
  IFiltersPaneSearchStyles,
@@ -37,6 +40,7 @@ import type {
37
40
  IMultiSelectInputStyles,
38
41
  IMultiSelectListStyles,
39
42
  IMultiSelectStyles,
43
+ INewMoreMenuStyles,
40
44
  INotificationStyles,
41
45
  IPhoneInputCountryListStyles,
42
46
  IPhoneInputStyles,
@@ -59,9 +63,6 @@ import type {
59
63
  IToasterStyles,
60
64
  ITooltipStyles,
61
65
  IWithPopupStyles,
62
- INewMoreMenuStyles,
63
- IFileInputStyles,
64
- IFileItemStyles,
65
66
  IWithTooltipStyles,
66
67
  } from '../components';
67
68
 
@@ -91,6 +92,7 @@ export interface IComponentStyles {
91
92
  DatePicker: IDatePickerStyles;
92
93
  DatePickerHeader: IDatePickerHeaderStyles;
93
94
  Description: IDescriptionStyles;
95
+ DocActions: IDocActionsStyles;
94
96
  DotsPreloader: IDotsPreloaderStyles;
95
97
  SvgPreloader: ISvgPreloaderStyles;
96
98
  FileInput: IFileInputStyles;