@true-engineering/true-react-common-ui-kit 3.0.0-alpha.0 → 3.0.0-alpha.10

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 (70) hide show
  1. package/LICENSE +201 -201
  2. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  3. package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.d.ts +1 -5
  4. package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -3
  5. package/dist/components/Flag/augment.d.ts +1 -1
  6. package/dist/components/FlexibleTable/FlexibleTable.d.ts +5 -2
  7. package/dist/components/FlexibleTable/FlexibleTable.styles.d.ts +1 -1
  8. package/dist/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.d.ts +2 -2
  9. package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.d.ts +2 -2
  10. package/dist/components/FlexibleTable/helpers.d.ts +1 -0
  11. package/dist/components/FlexibleTable/types.d.ts +1 -1
  12. package/dist/components/Icon/complexIcons/augment.d.ts +1 -1
  13. package/dist/components/MultiSelectList/MultiSelectList.d.ts +1 -2
  14. package/dist/components/Switch/Switch.d.ts +1 -1
  15. package/dist/helpers/phone.d.ts +1 -1
  16. package/dist/hooks/index.d.ts +1 -0
  17. package/dist/hooks/use-mixed-styles.d.ts +1 -0
  18. package/dist/true-react-common-ui-kit.js +719 -411
  19. package/dist/true-react-common-ui-kit.js.map +1 -1
  20. package/dist/true-react-common-ui-kit.umd.cjs +719 -411
  21. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  22. package/dist/vite-env.d.ts +1 -1
  23. package/package.json +1 -1
  24. package/src/components/AddButton/AddButton.stories.tsx +21 -21
  25. package/src/components/Checkbox/Checkbox.styles.ts +1 -0
  26. package/src/components/Checkbox/Checkbox.tsx +1 -1
  27. package/src/components/Colors/Colors.stories.tsx +7 -7
  28. package/src/components/DateInput/DateInput.tsx +1 -9
  29. package/src/components/DateInput/constants.ts +2 -2
  30. package/src/components/DatePicker/DatePicker.stories.tsx +1 -0
  31. package/src/components/DatePicker/DatePicker.tsx +1 -3
  32. package/src/components/FiltersPane/FiltersPane.stories.tsx +0 -8
  33. package/src/components/FiltersPane/components/FilterInterval/FilterInterval.styles.ts +2 -1
  34. package/src/components/FiltersPane/components/FilterSelect/FilterSelect.styles.ts +3 -1
  35. package/src/components/FiltersPane/components/FilterSelect/FilterSelect.tsx +1 -6
  36. package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.ts +2 -1
  37. package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.ts +1 -0
  38. package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.tsx +1 -4
  39. package/src/components/FiltersPane/types.ts +1 -1
  40. package/src/components/Flag/augment.d.ts +1 -1
  41. package/src/components/FlexibleTable/FlexibleTable.stories.tsx +16 -14
  42. package/src/components/FlexibleTable/FlexibleTable.styles.ts +4 -10
  43. package/src/components/FlexibleTable/FlexibleTable.tsx +23 -17
  44. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.ts +4 -0
  45. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +2 -2
  46. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +2 -2
  47. package/src/components/FlexibleTable/helpers.ts +4 -0
  48. package/src/components/FlexibleTable/types.ts +1 -1
  49. package/src/components/Icon/complexIcons/augment.d.ts +1 -1
  50. package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
  51. package/src/components/Icon/complexIcons/index.ts +1 -1
  52. package/src/components/MoreMenu/MoreMenu.stories.tsx +46 -46
  53. package/src/components/MultiSelectList/MultiSelectList.styles.ts +4 -0
  54. package/src/components/MultiSelectList/MultiSelectList.tsx +1 -3
  55. package/src/components/NumberInput/index.ts +1 -1
  56. package/src/components/PhoneInput/types.ts +16 -16
  57. package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
  58. package/src/components/Select/Select.styles.ts +5 -3
  59. package/src/components/Select/constants.ts +2 -2
  60. package/src/components/Select/types.ts +1 -1
  61. package/src/components/Switch/Switch.tsx +2 -2
  62. package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
  63. package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
  64. package/src/components/Tooltip/types.ts +1 -1
  65. package/src/helpers/phone.ts +1 -1
  66. package/src/helpers/popper-helpers.ts +17 -17
  67. package/src/hooks/index.ts +1 -0
  68. package/src/hooks/use-is-mounted.ts +15 -15
  69. package/src/hooks/use-mixed-styles.ts +14 -0
  70. package/src/vite-env.d.ts +1 -1
@@ -1 +1 @@
1
- /// <reference types="vite/client" />
1
+ /// <reference types="vite/client" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@true-engineering/true-react-common-ui-kit",
3
- "version": "3.0.0-alpha.0",
3
+ "version": "3.0.0-alpha.10",
4
4
  "description": "True Engineering React UI Kit with theming support",
5
5
  "author": "True Engineering (https://trueengineering.ru)",
6
6
  "keywords": [
@@ -1,21 +1,21 @@
1
- import { ComponentStory } from '@storybook/react';
2
- import { AddButton } from './AddButton';
3
-
4
- export default {
5
- title: 'AddButton',
6
- component: AddButton,
7
- };
8
-
9
- const Template: ComponentStory<typeof AddButton> = (args) => (
10
- <AddButton {...args} onClick={console.log} />
11
- );
12
-
13
- export const Default = Template.bind({});
14
-
15
- Default.args = {
16
- text: 'Добавить билет',
17
- isDisabled: false,
18
- isFullWidth: false,
19
- };
20
-
21
- Default.parameters = { controls: { exclude: ['onClick'] } };
1
+ import { ComponentStory } from '@storybook/react';
2
+ import { AddButton } from './AddButton';
3
+
4
+ export default {
5
+ title: 'AddButton',
6
+ component: AddButton,
7
+ };
8
+
9
+ const Template: ComponentStory<typeof AddButton> = (args) => (
10
+ <AddButton {...args} onClick={console.log} />
11
+ );
12
+
13
+ export const Default = Template.bind({});
14
+
15
+ Default.args = {
16
+ text: 'Добавить билет',
17
+ isDisabled: false,
18
+ isFullWidth: false,
19
+ };
20
+
21
+ Default.parameters = { controls: { exclude: ['onClick'] } };
@@ -4,6 +4,7 @@ export const useStyles = createThemedStyles('Checkbox', {
4
4
  root: {
5
5
  cursor: 'pointer',
6
6
  display: 'flex',
7
+ alignItems: 'center',
7
8
  gap: 14,
8
9
  width: 'fit-content',
9
10
  },
@@ -12,7 +12,7 @@ import { useStyles, ICheckboxStyles } from './Checkbox.styles';
12
12
 
13
13
  export interface ICheckboxProps<V> extends ICommonProps<ICheckboxStyles> {
14
14
  children?: ReactNode;
15
- isChecked?: boolean;
15
+ isChecked: boolean | undefined;
16
16
  isSemiChecked?: boolean;
17
17
  isDisabled?: boolean;
18
18
  isReadonly?: boolean;
@@ -1,7 +1,7 @@
1
- import { Colors } from './Colors';
2
-
3
- export default {
4
- title: 'Colors',
5
- };
6
-
7
- export const Default = (): JSX.Element => <Colors />;
1
+ import { Colors } from './Colors';
2
+
3
+ export default {
4
+ title: 'Colors',
5
+ };
6
+
7
+ export const Default = (): JSX.Element => <Colors />;
@@ -1,6 +1,5 @@
1
1
  import { FormEvent, MouseEvent, forwardRef, ChangeEvent } from 'react';
2
2
  import clsx from 'clsx';
3
- import { addDataTestId, getTestId } from '@true-engineering/true-react-platform-helpers';
4
3
  import { addDataAttributes } from '../../helpers';
5
4
  import { useTweakStyles } from '../../hooks';
6
5
  import { ICommonProps } from '../../types';
@@ -33,7 +32,6 @@ export const DateInput = forwardRef<HTMLInputElement, IDateInputProps>(
33
32
  data,
34
33
  isRange,
35
34
  tweakStyles,
36
- testId,
37
35
  onClick,
38
36
  onChange,
39
37
  ...inputProps
@@ -70,12 +68,7 @@ export const DateInput = forwardRef<HTMLInputElement, IDateInputProps>(
70
68
  };
71
69
 
72
70
  return (
73
- <div
74
- className={clsx(classes.root, className)}
75
- onClick={onClick}
76
- {...addDataTestId(testId)}
77
- {...addDataAttributes(data)}
78
- >
71
+ <div className={clsx(classes.root, className)} onClick={onClick} {...addDataAttributes(data)}>
79
72
  <Input
80
73
  {...inputProps}
81
74
  ref={ref}
@@ -84,7 +77,6 @@ export const DateInput = forwardRef<HTMLInputElement, IDateInputProps>(
84
77
  placeholder={
85
78
  placeholder ?? (isRange ? EMPTY_DATE_RANGE_INPUT_VALUE : EMPTY_DATE_INPUT_VALUE)
86
79
  }
87
- testId={getTestId(testId, 'input')}
88
80
  tweakStyles={tweakInputStyles}
89
81
  onChange={handleChange}
90
82
  beforeMaskedStateChange={beforeMaskedStateChange}
@@ -1,2 +1,2 @@
1
- export const EMPTY_DATE_INPUT_VALUE = '__.__.____';
2
- export const EMPTY_DATE_RANGE_INPUT_VALUE = `${EMPTY_DATE_INPUT_VALUE} - ${EMPTY_DATE_INPUT_VALUE}`;
1
+ export const EMPTY_DATE_INPUT_VALUE = '__.__.____';
2
+ export const EMPTY_DATE_RANGE_INPUT_VALUE = `${EMPTY_DATE_INPUT_VALUE} - ${EMPTY_DATE_INPUT_VALUE}`;
@@ -47,6 +47,7 @@ const Template: ComponentStory<typeof DatePicker> = (args) => {
47
47
  <DatePicker
48
48
  {...args}
49
49
  locale={ru}
50
+ testId="datepicker"
50
51
  months={months}
51
52
  selectedDate={date}
52
53
  startDate={startDate}
@@ -4,7 +4,6 @@ import 'react-datepicker/dist/react-datepicker.css';
4
4
  import clsx from 'clsx';
5
5
  import { isAfter, isBefore, isValid } from 'date-fns';
6
6
  import {
7
- addDataTestId,
8
7
  isEmpty,
9
8
  isNotEmpty,
10
9
  isStringNotEmpty,
@@ -40,7 +39,6 @@ export const DatePicker = forwardRef<ReactDatePicker, IDatePickerProps>(
40
39
  (
41
40
  {
42
41
  data,
43
- testId,
44
42
  selectedDate = null,
45
43
  minDate,
46
44
  maxDate,
@@ -234,7 +232,7 @@ export const DatePicker = forwardRef<ReactDatePicker, IDatePickerProps>(
234
232
  }, [selectedDate, startDate, endDate]);
235
233
 
236
234
  return (
237
- <div className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
235
+ <div className={classes.root} {...addDataAttributes(data)}>
238
236
  <DatePickerComponent
239
237
  ref={ref}
240
238
  minDate={minDate}
@@ -72,7 +72,6 @@ type ConfigValues = {
72
72
 
73
73
  interface IFiltersPaneWithCustomProps<Values, Content> extends IFiltersPaneProps<Values, Content> {
74
74
  containerWidth: number;
75
- multiselectWidth: number;
76
75
  isSearchDisabled: boolean;
77
76
  isSearchAutosizeable: boolean;
78
77
  shouldShowSettingsButton: boolean;
@@ -83,7 +82,6 @@ interface IFiltersPaneWithCustomProps<Values, Content> extends IFiltersPaneProps
83
82
 
84
83
  function FiltersPaneWithCustomProps<Values, Content>({
85
84
  containerWidth,
86
- multiselectWidth,
87
85
  isSearchDisabled,
88
86
  isSearchAutosizeable,
89
87
  shouldShowSettingsButton,
@@ -141,7 +139,6 @@ function FiltersPaneWithCustomProps<Values, Content>({
141
139
  multiSelect: {
142
140
  name: 'multiSelect',
143
141
  type: 'multiSelect',
144
- width: multiselectWidth,
145
142
  pageSize: 15,
146
143
  checkboxPosition,
147
144
  isGroupingEnabled,
@@ -163,7 +160,6 @@ function FiltersPaneWithCustomProps<Values, Content>({
163
160
  isGroupingEnabled,
164
161
  checkboxPosition,
165
162
  searchMaxLength: 12,
166
- width: multiselectWidth,
167
163
  fetchOptions: (q?: string): Promise<Array<{ v: string }>> => {
168
164
  if (q === '' || q === 'undefined' || q === '123') {
169
165
  return new Promise((resolve) => setTimeout(() => resolve([])));
@@ -265,9 +261,6 @@ export default {
265
261
  containerWidth: {
266
262
  control: { type: 'range', min: 100, max: 1000, step: 100 },
267
263
  },
268
- multiselectWidth: {
269
- control: { type: 'range', min: 100, max: 400, step: 50 },
270
- },
271
264
  checkboxPosition: {
272
265
  control: 'inline-radio',
273
266
  options: ['left', 'right'],
@@ -288,7 +281,6 @@ Default.args = {
288
281
  hasClearButton: true,
289
282
  isDisabled: false,
290
283
  containerWidth: 400,
291
- multiselectWidth: 200,
292
284
  withFieldNameInLabel: true,
293
285
  isGroupingEnabled: true,
294
286
  checkboxPosition: 'left',
@@ -1,3 +1,4 @@
1
+ import cloneDeep from 'lodash-es/cloneDeep';
1
2
  import { colors, createThemedStyles, ITweakStyles } from '../../../../theme';
2
3
  import { IButtonStyles } from '../../../Button';
3
4
  import { IInputStyles } from '../../../Input';
@@ -49,7 +50,7 @@ export const inputStyles: IInputStyles = {
49
50
  },
50
51
  };
51
52
 
52
- export const clearButtonStyles = innerTextButtonStyles;
53
+ export const clearButtonStyles = cloneDeep(innerTextButtonStyles);
53
54
 
54
55
  export type IFilterIntervalStyles = ITweakStyles<
55
56
  typeof useStyles,
@@ -1,3 +1,4 @@
1
+ import cloneDeep from 'lodash-es/cloneDeep';
1
2
  import { colors, createThemedStyles, helpers, ITweakStyles } from '../../../../theme';
2
3
  import { IButtonStyles } from '../../../Button';
3
4
  import { ISearchInputStyles } from '../../../SearchInput';
@@ -8,6 +9,7 @@ const LIST_GAP = 12;
8
9
 
9
10
  export const useStyles = createThemedStyles('FilterSelect', {
10
11
  root: {
12
+ width: 220,
11
13
  background: colors.CLASSIC_WHITE,
12
14
  },
13
15
 
@@ -127,7 +129,7 @@ export const searchInputStyles: ISearchInputStyles = {
127
129
  },
128
130
  };
129
131
 
130
- export const clearButtonStyles = innerTextButtonStyles;
132
+ export const clearButtonStyles = cloneDeep(innerTextButtonStyles);
131
133
 
132
134
  export type IFilterSelectStyles = ITweakStyles<
133
135
  typeof useStyles,
@@ -30,10 +30,6 @@ export interface IFilterSelectProps<Value> extends ICommonProps<IFilterSelectSty
30
30
  * @default false
31
31
  */
32
32
  isGroupingEnabled?: boolean;
33
- /**
34
- * @default `220px`
35
- */
36
- width?: string | number;
37
33
  localeKey?: IFilterLocaleKey;
38
34
  locale?: Partial<ISelectLocale>;
39
35
  options?: Value[];
@@ -54,7 +50,6 @@ export function FilterSelect<Value>({
54
50
  value,
55
51
  isSearchEnabled = false,
56
52
  isGroupingEnabled = false,
57
- width = 220,
58
53
  localeKey,
59
54
  locale,
60
55
  onChange,
@@ -225,7 +220,7 @@ export function FilterSelect<Value>({
225
220
  }, []);
226
221
 
227
222
  return (
228
- <div className={classes.root} style={{ width }} {...addDataAttributes(data)}>
223
+ <div className={classes.root} {...addDataAttributes(data)}>
229
224
  {isSearchEnabled && (
230
225
  <div className={classes.dropdownInput}>
231
226
  <SearchInput
@@ -1,3 +1,4 @@
1
+ import cloneDeep from 'lodash-es/cloneDeep';
1
2
  import { colors, createThemedStyles, ITweakStyles } from '../../../../theme';
2
3
  import { IButtonStyles } from '../../../Button';
3
4
  import { IDatePickerStyles } from '../../../DatePicker';
@@ -31,7 +32,7 @@ export const useStyles = createThemedStyles('FilterWithDates', {
31
32
  datepicker: {},
32
33
  });
33
34
 
34
- export const clearButtonStyles = innerTextButtonStyles;
35
+ export const clearButtonStyles = cloneDeep(innerTextButtonStyles);
35
36
 
36
37
  export const backButtonStyles = innerTextButtonStyles;
37
38
 
@@ -104,6 +104,7 @@ export const selectStyles: ISelectStyles = {
104
104
  borderBottomLeftRadius: 6,
105
105
  borderBottomRightRadius: 6,
106
106
  boxShadow: 'none',
107
+ width: '100%',
107
108
  },
108
109
  };
109
110
 
@@ -7,7 +7,7 @@ import { Icon } from '../../../Icon';
7
7
  import { SearchInput } from '../../../SearchInput';
8
8
  import { getLocale } from '../../helpers';
9
9
  import { IFilterLocaleKey, IFiltersPaneSearchPayload, IPartialFilterLocale } from '../../types';
10
- import { FilterSelect, IFilterSelectProps } from '../FilterSelect';
10
+ import { FilterSelect } from '../FilterSelect';
11
11
  import {
12
12
  useStyles,
13
13
  IFiltersPaneSearchStyles,
@@ -26,7 +26,6 @@ export interface IFiltersPaneSearchProps<Value> extends ICommonProps<IFiltersPan
26
26
  getValueView?: (value: Value) => ReactNode;
27
27
  getValueId?: (value: Value) => string;
28
28
  getValueString?: (value: Value) => string;
29
- selectWidth?: IFilterSelectProps<Value>['width'];
30
29
  hasClearSelectButton?: boolean;
31
30
  isDisabled?: boolean;
32
31
  isSelectSearchEnabled?: boolean;
@@ -43,7 +42,6 @@ export function FiltersPaneSearch<Value>({
43
42
  getValueId,
44
43
  getValueView,
45
44
  getValueString,
46
- selectWidth = '100%',
47
45
  hasClearSelectButton,
48
46
  isDisabled = false,
49
47
  isSelectSearchEnabled = true,
@@ -155,7 +153,6 @@ export function FiltersPaneSearch<Value>({
155
153
  localeKey={localeKey}
156
154
  locale={translates}
157
155
  onChange={handleFieldsChange}
158
- width={selectWidth}
159
156
  isSearchEnabled={isSelectSearchEnabled}
160
157
  hasClearButton={hasClearSelectButton}
161
158
  testId={testId !== undefined ? `${testId}-dropdown` : undefined}
@@ -152,5 +152,5 @@ export type ISelectLocaleKey = keyof typeof SelectLocales;
152
152
 
153
153
  export type IFilterWithDateDatePickerProps = Omit<
154
154
  IDatePickerProps,
155
- 'onChange' | 'value' | 'locale' | 'months' | 'selectedDate' | 'tweakStyles' // TODO: rethink
155
+ 'onChange' | 'value' | 'locale' | 'months' | 'selectedDate' | 'tweakStyles'
156
156
  >;
@@ -1 +1 @@
1
- declare module 'country-flag-icons/react/3x2';
1
+ declare module 'country-flag-icons/react/3x2';
@@ -1,7 +1,7 @@
1
1
  import { FC } from 'react';
2
2
  import { ComponentStory } from '@storybook/react';
3
3
  import { FlexibleTable } from './FlexibleTable';
4
- import { FlexibleTableConfigType } from './types';
4
+ import { IFlexibleTableConfigType } from './types';
5
5
  import { IFlexibleTableStyles } from './FlexibleTable.styles';
6
6
 
7
7
  export default {
@@ -25,7 +25,7 @@ interface ITableContent {
25
25
  const Temp: FC<{ value: string | undefined }> = ({ value }) => <>{value}</>;
26
26
  const Temp1: FC<{ value: string }> = ({ value }) => <>{value}</>;
27
27
 
28
- const config: FlexibleTableConfigType<ITableContent> = {
28
+ const config: IFlexibleTableConfigType<ITableContent> = {
29
29
  contractCode: {
30
30
  title: 'Contract Code',
31
31
  },
@@ -315,18 +315,20 @@ const tweak: IFlexibleTableStyles = {
315
315
  };
316
316
 
317
317
  const Template: ComponentStory<typeof FlexibleTable<ITableContent>> = (args) => (
318
- <FlexibleTable<ITableContent>
319
- {...args}
320
- uniqueField="contractCode"
321
- expandableRowComponent={(item, _, close) =>
322
- item.contractCode === 'OB_UT_M119' ? (
323
- <div onClick={close}>всем привет :) {item.contractCode}</div>
324
- ) : null
325
- }
326
- tweakStyles={tweak}
327
- content={content}
328
- config={config}
329
- />
318
+ <div style={{ width: 500, overflow: 'auto' }}>
319
+ <FlexibleTable<ITableContent>
320
+ {...args}
321
+ uniqueField="contractCode"
322
+ expandableRowComponent={(item, _, close) =>
323
+ item.contractCode === 'OB_UT_M119' ? (
324
+ <div onClick={close}>всем привет :) {item.contractCode}</div>
325
+ ) : null
326
+ }
327
+ tweakStyles={tweak}
328
+ content={content}
329
+ config={config}
330
+ />
331
+ </div>
330
332
  );
331
333
 
332
334
  export const Default = Template.bind({});
@@ -22,16 +22,6 @@ export const useStyles = createThemedStyles('FlexibleTable', {
22
22
  maxHeight: '100%',
23
23
  },
24
24
 
25
- horizontallyScrolled: {
26
- '& $cellSticky': {
27
- boxShadow: '4px 0 4px rgba(0, 0, 0, 0.05)',
28
- },
29
-
30
- '& $headerSticky::before': {
31
- boxShadow: '4px 0 4px rgba(0, 0, 0, 0.05)',
32
- },
33
- },
34
-
35
25
  loader: {
36
26
  position: 'sticky',
37
27
  left: 0,
@@ -75,6 +65,10 @@ export const useStyles = createThemedStyles('FlexibleTable', {
75
65
  pointerEvents: 'none',
76
66
  zIndex: 1,
77
67
  transition: ['box-shadow', '0.25s', 'ease-in-out'],
68
+
69
+ '[data-scrolled] &': {
70
+ boxShadow: '4px 0 4px rgba(0, 0, 0, 0.05)',
71
+ },
78
72
  },
79
73
 
80
74
  '&::after': {
@@ -1,11 +1,13 @@
1
1
  import { ReactNode, RefObject, useCallback, useEffect, useRef, useState } from 'react';
2
2
  import clsx from 'clsx';
3
+ import { addDataTestId, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
4
  import { addDataAttributes } from '../../helpers';
4
5
  import { useTweakStyles } from '../../hooks';
5
6
  import { ICommonProps } from '../../types';
6
7
  import { ThemedPreloader } from '../ThemedPreloader';
7
8
  import { FlexibleTableRow } from './components';
8
- import { FlexibleTableConfigType, IInfinityScrollConfig, ITitleComponent } from './types';
9
+ import { hasHorizontalScrollBar } from './helpers';
10
+ import { IFlexibleTableConfigType, IInfinityScrollConfig, ITitleComponent } from './types';
9
11
  import { useStyles, IFlexibleTableStyles } from './FlexibleTable.styles';
10
12
 
11
13
  // TODO: Заменить Record<string, any> на Record<string, unknown>
@@ -15,10 +17,13 @@ export interface IFlexibleTableProps<Values extends Record<string, any>>
15
17
  headerContent?: Partial<Record<keyof Values, any>>;
16
18
  enabledColumns?: Array<keyof Values>;
17
19
  activeRows?: number[];
18
- config?: FlexibleTableConfigType<Values>;
20
+ config?: IFlexibleTableConfigType<Values>;
19
21
  isHorizontallyScrollable?: boolean;
20
22
  isFirstColumnSticky?: boolean;
21
23
  infinityScrollConfig?: IInfinityScrollConfig;
24
+ /**
25
+ * @default Индекс строки
26
+ */
22
27
  uniqueField?: keyof Values;
23
28
  onHeadClick?: (column: keyof Values) => void;
24
29
  // TODO: Заменить string на Generic Values[uniqueField]
@@ -63,6 +68,7 @@ export function FlexibleTable<Values extends Record<string, any>>({
63
68
 
64
69
  const observer = useRef<IntersectionObserver>();
65
70
  const scrollRef = useRef<HTMLDivElement>(null);
71
+ const ref = refForScroll ?? scrollRef;
66
72
 
67
73
  const initIntersectionObserver = useCallback(
68
74
  (node: HTMLDivElement) => {
@@ -97,7 +103,7 @@ export function FlexibleTable<Values extends Record<string, any>>({
97
103
  );
98
104
 
99
105
  useEffect(() => {
100
- const scrollContainer = (refForScroll ?? scrollRef).current;
106
+ const scrollContainer = ref.current;
101
107
  if (scrollContainer === null || !isHorizontallyScrollable || !isFirstColumnSticky) {
102
108
  return;
103
109
  }
@@ -110,13 +116,14 @@ export function FlexibleTable<Values extends Record<string, any>>({
110
116
 
111
117
  return (
112
118
  <div
113
- ref={refForScroll ?? scrollRef}
114
- className={clsx(
115
- isHorizontallyScrollable && classes.scroll,
116
- isHorizontallyScrolled && classes.horizontallyScrolled,
117
- )}
119
+ ref={ref}
120
+ className={clsx({ [classes.scroll]: isHorizontallyScrollable })}
121
+ {...addDataAttributes({
122
+ scrolled: isHorizontallyScrolled ? true : undefined,
123
+ scrollable: isHorizontallyScrollable && hasHorizontalScrollBar(ref.current),
124
+ })}
118
125
  >
119
- <table className={classes.root} data-testid={testId} {...addDataAttributes(data)}>
126
+ <table className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
120
127
  <thead>
121
128
  <tr className={classes.headerRow}>
122
129
  {(enabledColumns || Object.keys(content[0])).map((key, idx) => {
@@ -131,11 +138,10 @@ export function FlexibleTable<Values extends Record<string, any>>({
131
138
 
132
139
  return (
133
140
  <th
134
- className={clsx(
135
- classes.header,
136
- isFirstColumnSticky && idx === 0 && classes.headerSticky,
137
- isFirstColumnSticky && idx === 1 && classes.headerSecond,
138
- )}
141
+ className={clsx(classes.header, {
142
+ [classes.headerSticky]: isFirstColumnSticky && idx === 0,
143
+ [classes.headerSecond]: isFirstColumnSticky && idx === 1,
144
+ })}
139
145
  style={{
140
146
  minWidth: itemConfig?.minWidth,
141
147
  width: itemConfig?.width,
@@ -163,17 +169,17 @@ export function FlexibleTable<Values extends Record<string, any>>({
163
169
  </tr>
164
170
  )}
165
171
 
166
- {content.map((item, idx) => (
172
+ {content.map((item, i) => (
167
173
  <FlexibleTableRow
168
174
  item={item}
169
175
  uniqueField={uniqueField}
170
- isActive={activeRows?.includes(idx) ?? false}
176
+ isActive={activeRows?.includes(i) ?? false}
171
177
  isFirstColumnSticky={isFirstColumnSticky}
172
178
  onRowClick={onRowClick}
173
179
  onRowHover={onRowHover}
174
180
  enabledColumns={enabledColumns}
175
181
  config={config}
176
- key={uniqueField ? item[uniqueField] : idx}
182
+ key={isNotEmpty(uniqueField) ? item[uniqueField] : i}
177
183
  rowAttributes={rowAttributes}
178
184
  tweakStyles={tweakTableRowStyles}
179
185
  expandableRowComponent={expandableRowComponent}
@@ -18,6 +18,10 @@ export const useStyles = createThemedStyles('FlexibleTableCell', {
18
18
  paddingLeft: 24,
19
19
  paddingRight: 12,
20
20
  ...getTransition(['box-shadow']),
21
+
22
+ '[data-scrolled] &': {
23
+ boxShadow: '4px 0 4px rgba(0, 0, 0, 0.05)',
24
+ },
21
25
  },
22
26
 
23
27
  second: {
@@ -3,14 +3,14 @@ import clsx from 'clsx';
3
3
  import { format } from 'date-fns';
4
4
  import type { ICommonProps } from '../../../../types';
5
5
  import { DEFAULT_DATE_FORMAT } from '../../constants';
6
- import type { FlexibleTableConfigType } from '../../types';
6
+ import type { IFlexibleTableConfigType } from '../../types';
7
7
  import { useStyles, IFlexibleTableCellStyles } from './FlexibleTableCell.styles';
8
8
 
9
9
  export interface IFlexibleTableCellProps<Values extends Record<string, any>>
10
10
  extends Pick<ICommonProps<IFlexibleTableCellStyles>, 'tweakStyles'> {
11
11
  item: Values;
12
12
  columnName: keyof Values;
13
- config?: FlexibleTableConfigType<Values>;
13
+ config?: IFlexibleTableConfigType<Values>;
14
14
  isFocusedRow?: boolean;
15
15
  isSecond?: boolean;
16
16
  isSticky?: boolean;
@@ -3,7 +3,7 @@ import clsx from 'clsx';
3
3
  import { addDataAttributes } from '../../../../helpers';
4
4
  import { useTweakStyles } from '../../../../hooks';
5
5
  import { ICommonProps, IDataAttributes } from '../../../../types';
6
- import { FlexibleTableConfigType, INestedComponent } from '../../types';
6
+ import { IFlexibleTableConfigType, INestedComponent } from '../../types';
7
7
  import FlexibleTableCell from '../FlexibleTableCell/FlexibleTableCell';
8
8
  import { useStyles, IFlexibleTableRowStyles } from './FlexibleTableRow.styles';
9
9
 
@@ -14,7 +14,7 @@ export interface IFlexibleTableRowProps<Values extends Record<string, any>>
14
14
  uniqueField?: keyof Values;
15
15
  isFirstColumnSticky?: boolean;
16
16
  isActive: boolean;
17
- config?: FlexibleTableConfigType<Values>;
17
+ config?: IFlexibleTableConfigType<Values>;
18
18
  enabledColumns?: Array<keyof Values>;
19
19
  rowAttributes?: Array<keyof Values>;
20
20
  expandableRowComponent?(item: Values, isOpen: boolean, close: () => void): ReactNode;
@@ -0,0 +1,4 @@
1
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
2
+
3
+ export const hasHorizontalScrollBar = (el: HTMLElement | null | undefined): boolean =>
4
+ isNotEmpty(el) && el.scrollWidth !== el.clientWidth;
@@ -19,7 +19,7 @@ export type IValueComponent<Values, Value> = (props: {
19
19
  onSetNestedComponent: (component?: ReactNode) => void;
20
20
  }) => JSX.Element | ReactNode;
21
21
 
22
- export type FlexibleTableConfigType<Values> = {
22
+ export type IFlexibleTableConfigType<Values> = {
23
23
  [Key in keyof Values]?: {
24
24
  title?: ReactNode;
25
25
  titleComponent?: ITitleComponent<unknown>;
@@ -1 +1 @@
1
- declare module '*.svg?raw';
1
+ declare module '*.svg?raw';