@true-engineering/true-react-common-ui-kit 4.0.0-alpha64 → 4.0.0-alpha66
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.
- package/dist/components/DatePicker/types.d.ts +1 -1
- package/dist/components/FiltersPane/components/Filter/helpers.d.ts +1 -0
- package/dist/components/FiltersPane/components/FilterDateSingle/FilterDateSingle.d.ts +15 -0
- package/dist/components/FiltersPane/components/FilterDateSingle/FilterDateSingle.styles.d.ts +11 -0
- package/dist/components/FiltersPane/components/FilterDateSingle/index.d.ts +2 -0
- package/dist/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.d.ts +1 -5
- package/dist/components/FiltersPane/components/index.d.ts +1 -0
- package/dist/components/FiltersPane/types.d.ts +8 -2
- package/dist/theme/types.d.ts +2 -1
- package/dist/true-react-common-ui-kit.js +237 -175
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/package.json +1 -1
- package/src/components/DatePicker/DatePicker.tsx +2 -0
- package/src/components/DatePicker/types.ts +1 -0
- package/src/components/FiltersPane/FiltersPane.stories.tsx +38 -23
- package/src/components/FiltersPane/FiltersPane.tsx +5 -1
- package/src/components/FiltersPane/components/Filter/Filter.tsx +19 -1
- package/src/components/FiltersPane/components/Filter/helpers.ts +1 -1
- package/src/components/FiltersPane/components/FilterDateSingle/FilterDateSingle.styles.ts +34 -0
- package/src/components/FiltersPane/components/FilterDateSingle/FilterDateSingle.tsx +103 -0
- package/src/components/FiltersPane/components/FilterDateSingle/index.ts +2 -0
- package/src/components/FiltersPane/components/FilterValueView/FilterValueView.tsx +2 -2
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.ts +1 -24
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +6 -43
- package/src/components/FiltersPane/components/index.ts +1 -0
- package/src/components/FiltersPane/constants.ts +2 -0
- package/src/components/FiltersPane/types.ts +12 -1
- package/src/theme/types.ts +2 -0
package/package.json
CHANGED
|
@@ -82,6 +82,7 @@ export const DatePicker = forwardRef<ReactDatePicker, IDatePickerProps>(function
|
|
|
82
82
|
preventOpenOnFocus,
|
|
83
83
|
popperModifiers = [],
|
|
84
84
|
popperPlacement = 'bottom-start',
|
|
85
|
+
popperProps,
|
|
85
86
|
todayButton,
|
|
86
87
|
highlightDates,
|
|
87
88
|
calendarContainer,
|
|
@@ -290,6 +291,7 @@ export const DatePicker = forwardRef<ReactDatePicker, IDatePickerProps>(function
|
|
|
290
291
|
// Убираем дефолтный отступ в 10px из либы
|
|
291
292
|
// https://github.com/Hacker0x01/react-datepicker/blob/db67a58de2b05d2681bdf0a4977b606095d514c4/src/with_floating.tsx#L58
|
|
292
293
|
popperModifiers={[offset(-10), ...popperModifiers]}
|
|
294
|
+
popperProps={popperProps}
|
|
293
295
|
popperPlacement={popperPlacement}
|
|
294
296
|
strictParsing={strictParsing}
|
|
295
297
|
preventOpenOnFocus={preventOpenOnFocus}
|
|
@@ -61,7 +61,8 @@ const fetchOptionsMock = [
|
|
|
61
61
|
|
|
62
62
|
interface ConfigValues extends Record<string, unknown> {
|
|
63
63
|
name: string;
|
|
64
|
-
|
|
64
|
+
datePeriod: IPeriod;
|
|
65
|
+
datePickerSingle: Date;
|
|
65
66
|
select: string;
|
|
66
67
|
multiSelect: string;
|
|
67
68
|
multiSelectWithSearch: IMultiSelectListValues<{ v: string }>;
|
|
@@ -127,25 +128,6 @@ const Story: FC<IFiltersPaneCustomProps<ConfigValues, unknown>> = ({
|
|
|
127
128
|
options: selectOptions,
|
|
128
129
|
},
|
|
129
130
|
|
|
130
|
-
date: {
|
|
131
|
-
name: 'date',
|
|
132
|
-
type: 'dateRange',
|
|
133
|
-
locale: {
|
|
134
|
-
periods: {
|
|
135
|
-
MINE: 'Вот такой',
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
periods: [
|
|
139
|
-
'THIS_MONTH',
|
|
140
|
-
'LAST_MONTH',
|
|
141
|
-
'THIS_YEAR',
|
|
142
|
-
'LAST_YEAR',
|
|
143
|
-
['MINE', myPeriodGetter],
|
|
144
|
-
'CUSTOM',
|
|
145
|
-
],
|
|
146
|
-
isClearable: isClearableFields,
|
|
147
|
-
},
|
|
148
|
-
|
|
149
131
|
multiSelect: {
|
|
150
132
|
name: 'multiSelect',
|
|
151
133
|
type: 'multiSelect',
|
|
@@ -212,6 +194,37 @@ const Story: FC<IFiltersPaneCustomProps<ConfigValues, unknown>> = ({
|
|
|
212
194
|
isClearable: isClearableFields,
|
|
213
195
|
},
|
|
214
196
|
|
|
197
|
+
datePeriod: {
|
|
198
|
+
name: 'Date With Period',
|
|
199
|
+
type: 'dateRange',
|
|
200
|
+
locale: {
|
|
201
|
+
periods: {
|
|
202
|
+
MINE: 'Вот такой',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
periods: [
|
|
206
|
+
'THIS_MONTH',
|
|
207
|
+
'LAST_MONTH',
|
|
208
|
+
'THIS_YEAR',
|
|
209
|
+
'LAST_YEAR',
|
|
210
|
+
['MINE', myPeriodGetter],
|
|
211
|
+
'CUSTOM',
|
|
212
|
+
],
|
|
213
|
+
isClearable: isClearableFields,
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
dateWithoutPeriod: {
|
|
217
|
+
name: 'Date Without Period',
|
|
218
|
+
type: 'dateRangeWithoutPeriod',
|
|
219
|
+
isClearable: isClearableFields,
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
datePickerSingle: {
|
|
223
|
+
name: 'Date Picker Single',
|
|
224
|
+
type: 'datePickerSingle',
|
|
225
|
+
isClearable: isClearableFields,
|
|
226
|
+
},
|
|
227
|
+
|
|
215
228
|
custom: {
|
|
216
229
|
type: 'custom',
|
|
217
230
|
name: 'Custom',
|
|
@@ -249,7 +262,9 @@ const Story: FC<IFiltersPaneCustomProps<ConfigValues, unknown>> = ({
|
|
|
249
262
|
}}
|
|
250
263
|
enabledFilters={[
|
|
251
264
|
'name',
|
|
252
|
-
'
|
|
265
|
+
'datePeriod',
|
|
266
|
+
'dateWithoutPeriod',
|
|
267
|
+
'datePickerSingle',
|
|
253
268
|
'select',
|
|
254
269
|
'multiSelect',
|
|
255
270
|
'multiSelectWithSearch',
|
|
@@ -280,7 +295,7 @@ const meta: Meta<typeof Story> = {
|
|
|
280
295
|
isClearableFields: false,
|
|
281
296
|
isDisabled: false,
|
|
282
297
|
shouldRenderDataId: false,
|
|
283
|
-
containerWidth:
|
|
298
|
+
containerWidth: 800,
|
|
284
299
|
withFieldNameInLabel: true,
|
|
285
300
|
isGroupingEnabled: true,
|
|
286
301
|
checkboxPosition: 'left',
|
|
@@ -288,7 +303,7 @@ const meta: Meta<typeof Story> = {
|
|
|
288
303
|
},
|
|
289
304
|
argTypes: {
|
|
290
305
|
containerWidth: {
|
|
291
|
-
control: { type: 'range', min:
|
|
306
|
+
control: { type: 'range', min: 500, max: 1400, step: 100 },
|
|
292
307
|
},
|
|
293
308
|
checkboxPosition: {
|
|
294
309
|
control: 'inline-radio',
|
|
@@ -148,7 +148,11 @@ export function FiltersPane<Values extends Record<string, unknown>, Content = Va
|
|
|
148
148
|
onChange={(value) => onChangeFilters({ ...values, [filterKey]: value })}
|
|
149
149
|
value={currentValue}
|
|
150
150
|
key={filterKey}
|
|
151
|
-
isDisabled={
|
|
151
|
+
isDisabled={
|
|
152
|
+
isDisabled ||
|
|
153
|
+
filter?.isDisabled ||
|
|
154
|
+
filter?.requiredFilledFilters?.some((item) => !values[item])
|
|
155
|
+
}
|
|
152
156
|
tweakStyles={tweakFilterWrapperStyles}
|
|
153
157
|
data={shouldRenderDataId ? { id: filterKey } : undefined}
|
|
154
158
|
testId={getTestId(testId, `filter-${filterKey}`)}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { getTestId } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import { getLocale } from '../../helpers';
|
|
4
|
+
import { FilterDateSingle } from '../FilterDateSingle';
|
|
4
5
|
import { FilterInterval } from '../FilterInterval';
|
|
5
6
|
import { FilterMultiSelect } from '../FilterMultiSelect';
|
|
6
7
|
import { FilterSelect } from '../FilterSelect';
|
|
7
8
|
import { FilterWithDates } from '../FilterWithDates';
|
|
8
9
|
import { FilterWithPeriod } from '../FilterWithPeriod';
|
|
9
10
|
import type { IFilterWrapperProps } from '../FilterWrapper';
|
|
10
|
-
import { isDatePeriodValue, isMultiSelectValue, isPeriodValue } from './helpers';
|
|
11
|
+
import { isDateOrEmpty, isDatePeriodValue, isMultiSelectValue, isPeriodValue } from './helpers';
|
|
11
12
|
|
|
12
13
|
export interface IFilterProps<Values extends Record<string, unknown>, Key extends keyof Values>
|
|
13
14
|
extends IFilterWrapperProps<Values, Key> {
|
|
@@ -71,6 +72,23 @@ export function Filter<Values extends Record<string, unknown>, Key extends keyof
|
|
|
71
72
|
);
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
if (filter.type === 'datePickerSingle') {
|
|
76
|
+
const preparedValue = isDateOrEmpty(value) ? value : undefined;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<FilterDateSingle
|
|
80
|
+
value={preparedValue}
|
|
81
|
+
onChange={onChange}
|
|
82
|
+
onClose={onClose}
|
|
83
|
+
onEndBtnSubmit={() => onChange(undefined)}
|
|
84
|
+
localeKey={translatesLocaleKey}
|
|
85
|
+
locale={translates}
|
|
86
|
+
testId={getTestId(testId, 'datePicker')}
|
|
87
|
+
{...filter}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
74
92
|
if (filter.type === 'multiSelect') {
|
|
75
93
|
const preparedValue = isMultiSelectValue<any>(value) ? value : undefined;
|
|
76
94
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isEmpty, isString } from '@true-engineering/true-react-platform-helpers';
|
|
2
2
|
import { IDatePeriod, IFilterMultiSelectValues, IPeriod } from '../../types';
|
|
3
3
|
|
|
4
|
-
const isDateOrEmpty = (value: unknown): value is Date | null | undefined =>
|
|
4
|
+
export const isDateOrEmpty = (value: unknown): value is Date | null | undefined =>
|
|
5
5
|
isEmpty(value) || value instanceof Date;
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { colors, createThemedStyles, ITweakStyles } from '../../../../theme';
|
|
2
|
+
import { IButtonStyles } from '../../../Button';
|
|
3
|
+
import { IDatePickerStyles } from '../../../DatePicker';
|
|
4
|
+
import { innerTextButtonStyles } from '../../FiltersPane.styles';
|
|
5
|
+
|
|
6
|
+
export const useStyles = createThemedStyles('FilterDateSingle', {
|
|
7
|
+
root: {
|
|
8
|
+
width: 312,
|
|
9
|
+
background: colors.CLASSIC_WHITE,
|
|
10
|
+
position: 'relative',
|
|
11
|
+
zIndex: 20,
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
container: {
|
|
15
|
+
padding: [8, 20],
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
buttons: {
|
|
19
|
+
display: 'flex',
|
|
20
|
+
flexDirection: 'row-reverse',
|
|
21
|
+
justifyContent: 'space-between',
|
|
22
|
+
padding: 8,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const clearButtonStyles = structuredClone(innerTextButtonStyles);
|
|
27
|
+
|
|
28
|
+
export type IFilterDateSingleStyles = ITweakStyles<
|
|
29
|
+
typeof useStyles,
|
|
30
|
+
{
|
|
31
|
+
tweakDatePicker: IDatePickerStyles;
|
|
32
|
+
tweakClearButton: IButtonStyles;
|
|
33
|
+
}
|
|
34
|
+
>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { FC, useMemo, useRef } from 'react';
|
|
2
|
+
import { enUS, ru } from 'date-fns/locale';
|
|
3
|
+
import { addDataAttributes, getTestId } from '@true-engineering/true-react-platform-helpers';
|
|
4
|
+
import { useTweakStyles } from '../../../../hooks';
|
|
5
|
+
import { ICommonProps } from '../../../../types';
|
|
6
|
+
import { Button } from '../../../Button';
|
|
7
|
+
import { DatePicker, IDatePickerProps } from '../../../DatePicker';
|
|
8
|
+
import { getLocale } from '../../helpers';
|
|
9
|
+
import { IFilterLocaleKey, IPartialFilterLocale } from '../../types';
|
|
10
|
+
import { clearButtonStyles, IFilterDateSingleStyles, useStyles } from './FilterDateSingle.styles';
|
|
11
|
+
|
|
12
|
+
export interface IFilterDateSingleProps
|
|
13
|
+
extends ICommonProps<IFilterDateSingleStyles>,
|
|
14
|
+
Partial<
|
|
15
|
+
Pick<
|
|
16
|
+
IDatePickerProps,
|
|
17
|
+
'label' | 'minDate' | 'maxDate' | 'calendarStartDay' | 'popperModifiers' | 'popperPlacement'
|
|
18
|
+
>
|
|
19
|
+
> {
|
|
20
|
+
value?: Date | null;
|
|
21
|
+
locale?: IPartialFilterLocale;
|
|
22
|
+
localeKey?: IFilterLocaleKey;
|
|
23
|
+
isClearable?: boolean;
|
|
24
|
+
onChange: (value: Date | null) => void;
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
onEndBtnSubmit: () => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const FilterDateSingle: FC<IFilterDateSingleProps> = ({
|
|
30
|
+
value,
|
|
31
|
+
label,
|
|
32
|
+
locale,
|
|
33
|
+
localeKey,
|
|
34
|
+
isClearable,
|
|
35
|
+
tweakStyles,
|
|
36
|
+
onChange,
|
|
37
|
+
onClose,
|
|
38
|
+
onEndBtnSubmit,
|
|
39
|
+
testId,
|
|
40
|
+
data,
|
|
41
|
+
...props
|
|
42
|
+
}) => {
|
|
43
|
+
const classes = useStyles({ theme: tweakStyles });
|
|
44
|
+
|
|
45
|
+
const tweakClearButtonStyles = useTweakStyles({
|
|
46
|
+
innerStyles: clearButtonStyles,
|
|
47
|
+
tweakStyles,
|
|
48
|
+
className: 'tweakClearButton',
|
|
49
|
+
currentComponentName: 'FilterDateSingle',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const tweakDatePickerStyles = useTweakStyles({
|
|
53
|
+
tweakStyles,
|
|
54
|
+
className: 'tweakDatePicker',
|
|
55
|
+
currentComponentName: 'FilterDateSingle',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const popperTargetRef = useRef<HTMLDivElement>(null);
|
|
59
|
+
|
|
60
|
+
const dateLocale = localeKey === 'ru' ? ru : enUS;
|
|
61
|
+
const translates = useMemo(() => getLocale(localeKey, locale), [localeKey, locale]);
|
|
62
|
+
|
|
63
|
+
const handleClear = () => {
|
|
64
|
+
onEndBtnSubmit();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className={classes.root} ref={popperTargetRef} {...addDataAttributes(data, testId)}>
|
|
69
|
+
<div className={classes.container}>
|
|
70
|
+
<DatePicker
|
|
71
|
+
label={label ?? translates.date}
|
|
72
|
+
locale={dateLocale}
|
|
73
|
+
months={translates.months}
|
|
74
|
+
selectedDate={value}
|
|
75
|
+
onChangeDate={(date) => {
|
|
76
|
+
onChange(date);
|
|
77
|
+
onClose?.();
|
|
78
|
+
}}
|
|
79
|
+
tweakStyles={tweakDatePickerStyles}
|
|
80
|
+
popperProps={{ elements: { reference: popperTargetRef?.current } }}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className={classes.buttons}>
|
|
86
|
+
{isClearable && (
|
|
87
|
+
<div>
|
|
88
|
+
<Button
|
|
89
|
+
onClick={handleClear}
|
|
90
|
+
size="s"
|
|
91
|
+
view="text"
|
|
92
|
+
testId={getTestId(testId, 'clear-button')}
|
|
93
|
+
isFullWidth
|
|
94
|
+
tweakStyles={tweakClearButtonStyles}
|
|
95
|
+
>
|
|
96
|
+
{translates.clear}
|
|
97
|
+
</Button>
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
@@ -38,7 +38,7 @@ export function FilterValueView<Values extends Record<string, unknown>, Key exte
|
|
|
38
38
|
|
|
39
39
|
const isMultiple = filter.type === 'custom' && filter.valueViewType === 'multiple';
|
|
40
40
|
const isRange = filter.type === 'custom' && filter.valueViewType === 'range';
|
|
41
|
-
const
|
|
41
|
+
const isDateRange = filter.type === 'dateRange' || filter.type === 'dateRangeWithoutPeriod';
|
|
42
42
|
|
|
43
43
|
const displayValue = (v: unknown): string => {
|
|
44
44
|
if (!isNotEmpty(v)) {
|
|
@@ -108,7 +108,7 @@ export function FilterValueView<Values extends Record<string, unknown>, Key exte
|
|
|
108
108
|
return <span className={classes.text}>{intervals.join(' ')}</span>;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
if (
|
|
111
|
+
if (isDateRange) {
|
|
112
112
|
const { from, to, periodType, label } = value as unknown as IPeriod;
|
|
113
113
|
const hasFrom = from !== undefined && from !== null;
|
|
114
114
|
const hasTo = to !== undefined && to !== null;
|
|
@@ -5,7 +5,7 @@ import { innerTextButtonStyles } from '../../FiltersPane.styles';
|
|
|
5
5
|
|
|
6
6
|
export const useStyles = createThemedStyles('FilterWithDates', {
|
|
7
7
|
root: {
|
|
8
|
-
width:
|
|
8
|
+
width: 312,
|
|
9
9
|
background: colors.CLASSIC_WHITE,
|
|
10
10
|
position: 'relative',
|
|
11
11
|
zIndex: 20,
|
|
@@ -28,35 +28,12 @@ export const useStyles = createThemedStyles('FilterWithDates', {
|
|
|
28
28
|
justifyContent: 'space-between',
|
|
29
29
|
padding: 8,
|
|
30
30
|
},
|
|
31
|
-
|
|
32
|
-
datepicker: {},
|
|
33
31
|
});
|
|
34
32
|
|
|
35
33
|
export const clearButtonStyles = structuredClone(innerTextButtonStyles);
|
|
36
34
|
|
|
37
35
|
export const backButtonStyles = innerTextButtonStyles;
|
|
38
36
|
|
|
39
|
-
const PICKER_TOP_MARGIN = 28;
|
|
40
|
-
const PICKER_WITH_BUTTONS_TOP_MARGIN = 56;
|
|
41
|
-
const START_PICKER_LEFT_MARGIN = -20;
|
|
42
|
-
const END_PICKER_LEFT_MARGIN = -170;
|
|
43
|
-
|
|
44
|
-
export const startDatePickerStyles: IDatePickerStyles = {
|
|
45
|
-
popper: { marginTop: PICKER_TOP_MARGIN, marginLeft: START_PICKER_LEFT_MARGIN },
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const startDatePickerWithButtonStyles: IDatePickerStyles = {
|
|
49
|
-
popper: { marginTop: PICKER_WITH_BUTTONS_TOP_MARGIN, marginLeft: START_PICKER_LEFT_MARGIN },
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const endDatePickerStyles: IDatePickerStyles = {
|
|
53
|
-
popper: { marginTop: PICKER_TOP_MARGIN, marginLeft: END_PICKER_LEFT_MARGIN },
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const endDatePickerWithButtonStyles: IDatePickerStyles = {
|
|
57
|
-
popper: { marginTop: PICKER_WITH_BUTTONS_TOP_MARGIN, marginLeft: END_PICKER_LEFT_MARGIN },
|
|
58
|
-
};
|
|
59
|
-
|
|
60
37
|
export type IFilterWithDatesStyles = ITweakStyles<
|
|
61
38
|
typeof useStyles,
|
|
62
39
|
{
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { FC, useMemo, useRef
|
|
1
|
+
import { FC, useMemo, useRef } from 'react';
|
|
2
2
|
import { isAfter, isBefore } from 'date-fns';
|
|
3
3
|
import { enUS, ru } from 'date-fns/locale';
|
|
4
|
-
import {
|
|
5
|
-
getTestId,
|
|
6
|
-
isNotEmpty,
|
|
7
|
-
addDataAttributes,
|
|
8
|
-
} from '@true-engineering/true-react-platform-helpers';
|
|
4
|
+
import { getTestId, addDataAttributes } from '@true-engineering/true-react-platform-helpers';
|
|
9
5
|
import { useTweakStyles } from '../../../../hooks';
|
|
10
6
|
import { ICommonProps } from '../../../../types';
|
|
11
7
|
import { Button } from '../../../Button';
|
|
@@ -21,11 +17,7 @@ import {
|
|
|
21
17
|
import {
|
|
22
18
|
backButtonStyles,
|
|
23
19
|
clearButtonStyles,
|
|
24
|
-
endDatePickerStyles,
|
|
25
|
-
endDatePickerWithButtonStyles,
|
|
26
20
|
IFilterWithDatesStyles,
|
|
27
|
-
startDatePickerStyles,
|
|
28
|
-
startDatePickerWithButtonStyles,
|
|
29
21
|
useStyles,
|
|
30
22
|
} from './FilterWithDates.styles';
|
|
31
23
|
|
|
@@ -71,26 +63,19 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
71
63
|
currentComponentName: 'FilterWithDates',
|
|
72
64
|
});
|
|
73
65
|
|
|
74
|
-
const hasButtonsRow = isClearable || isNotEmpty(onStartBtnSubmit);
|
|
75
|
-
|
|
76
66
|
const tweakStartDatePickerStyles = useTweakStyles({
|
|
77
|
-
innerStyles: hasButtonsRow ? startDatePickerWithButtonStyles : startDatePickerStyles,
|
|
78
67
|
tweakStyles,
|
|
79
68
|
className: 'tweakStartDatePicker',
|
|
80
69
|
currentComponentName: 'FilterWithDates',
|
|
81
70
|
});
|
|
82
71
|
|
|
83
72
|
const tweakEndDatePickerStyles = useTweakStyles({
|
|
84
|
-
innerStyles: hasButtonsRow ? endDatePickerWithButtonStyles : endDatePickerStyles,
|
|
85
73
|
tweakStyles,
|
|
86
74
|
className: 'tweakEndDatePicker',
|
|
87
75
|
currentComponentName: 'FilterWithDates',
|
|
88
76
|
});
|
|
89
77
|
|
|
90
|
-
const
|
|
91
|
-
const [isOpenTo, setOpenTo] = useState(false);
|
|
92
|
-
|
|
93
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
78
|
+
const popperTargetRef = useRef<HTMLDivElement>(null);
|
|
94
79
|
|
|
95
80
|
const dateLocale = localeKey === 'ru' ? ru : enUS;
|
|
96
81
|
|
|
@@ -99,17 +84,6 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
99
84
|
const handleClear = () => {
|
|
100
85
|
onEndBtnSubmit();
|
|
101
86
|
};
|
|
102
|
-
const isOpenCalendar = isOpenFrom || isOpenTo;
|
|
103
|
-
|
|
104
|
-
const handleFromSelected = (val: Date | null) => {
|
|
105
|
-
onChange({ from: val, to: value?.to ?? null });
|
|
106
|
-
setOpenFrom(false);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const handleToSelected = (val: Date | null) => {
|
|
110
|
-
onChange({ from: value?.from ?? null, to: val });
|
|
111
|
-
setOpenTo(false);
|
|
112
|
-
};
|
|
113
87
|
|
|
114
88
|
const handleChangeFrom = (val: Date | null) => {
|
|
115
89
|
// на самом деле ситуации когда надо переворачивать даты, произойти не может
|
|
@@ -130,7 +104,7 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
130
104
|
};
|
|
131
105
|
|
|
132
106
|
return (
|
|
133
|
-
<div className={classes.root} {...addDataAttributes(data, testId)}>
|
|
107
|
+
<div className={classes.root} ref={popperTargetRef} {...addDataAttributes(data, testId)}>
|
|
134
108
|
<div className={classes.container}>
|
|
135
109
|
<div className={classes.containerItem}>
|
|
136
110
|
<DatePicker
|
|
@@ -143,6 +117,7 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
143
117
|
tweakStyles={tweakStartDatePickerStyles}
|
|
144
118
|
testId={getTestId(testId, 'from')}
|
|
145
119
|
isClearable={isClearable}
|
|
120
|
+
popperProps={{ elements: { reference: popperTargetRef?.current } }}
|
|
146
121
|
{...startPickerProps}
|
|
147
122
|
/>
|
|
148
123
|
</div>
|
|
@@ -157,6 +132,7 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
157
132
|
tweakStyles={tweakEndDatePickerStyles}
|
|
158
133
|
testId={getTestId(testId, 'to')}
|
|
159
134
|
isClearable={isClearable}
|
|
135
|
+
popperProps={{ elements: { reference: popperTargetRef?.current } }}
|
|
160
136
|
{...endPickerProps}
|
|
161
137
|
/>
|
|
162
138
|
</div>
|
|
@@ -192,19 +168,6 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
|
|
|
192
168
|
</div>
|
|
193
169
|
)}
|
|
194
170
|
</div>
|
|
195
|
-
|
|
196
|
-
{isOpenCalendar && (
|
|
197
|
-
<div ref={ref} className={classes.datepicker}>
|
|
198
|
-
<DatePicker
|
|
199
|
-
selectedDate={(isOpenFrom ? value?.from : value?.to) ?? null}
|
|
200
|
-
label=""
|
|
201
|
-
locale={dateLocale}
|
|
202
|
-
months={translates.months}
|
|
203
|
-
isInline
|
|
204
|
-
onChangeDate={isOpenFrom ? handleFromSelected : handleToSelected}
|
|
205
|
-
/>
|
|
206
|
-
</div>
|
|
207
|
-
)}
|
|
208
171
|
</div>
|
|
209
172
|
);
|
|
210
173
|
};
|
|
@@ -37,6 +37,7 @@ export const FilterLocales: Record<string, IFilterLocale> = {
|
|
|
37
37
|
from: 'От',
|
|
38
38
|
to: 'До',
|
|
39
39
|
back: 'Назад',
|
|
40
|
+
date: 'Дата',
|
|
40
41
|
searchPlaceholder: 'Поиск',
|
|
41
42
|
displayedFields: 'Поля для поиска',
|
|
42
43
|
months: [
|
|
@@ -71,6 +72,7 @@ export const FilterLocales: Record<string, IFilterLocale> = {
|
|
|
71
72
|
from: 'From',
|
|
72
73
|
to: 'To',
|
|
73
74
|
back: 'Back',
|
|
75
|
+
date: 'Date',
|
|
74
76
|
searchPlaceholder: 'Search',
|
|
75
77
|
displayedFields: 'Displayed fields',
|
|
76
78
|
months: [
|
|
@@ -4,6 +4,7 @@ import { IDatePickerProps } from '../DatePicker';
|
|
|
4
4
|
import { IMultiSelectListValues } from '../MultiSelectList';
|
|
5
5
|
import { INumberInputProps } from '../NumberInput';
|
|
6
6
|
import type {
|
|
7
|
+
IFilterDateSingleProps,
|
|
7
8
|
IFilterIntervalProps,
|
|
8
9
|
IFilterMultiSelectProps,
|
|
9
10
|
IFilterSelectProps,
|
|
@@ -41,6 +42,8 @@ export interface IPeriod extends IDatePeriod {
|
|
|
41
42
|
|
|
42
43
|
export type IPeriodGetter = () => IDatePeriod;
|
|
43
44
|
|
|
45
|
+
export type IFilterDateSingleValue = Date;
|
|
46
|
+
|
|
44
47
|
export type IFilterWithDatesValue = IDatePeriod;
|
|
45
48
|
|
|
46
49
|
export type MultiSelectOptionType<Value> = Value | undefined extends
|
|
@@ -52,6 +55,7 @@ export type MultiSelectOptionType<Value> = Value | undefined extends
|
|
|
52
55
|
export interface IConfigItemBasicBase<Value> {
|
|
53
56
|
name: ReactNode;
|
|
54
57
|
isInline?: boolean;
|
|
58
|
+
isDisabled?: boolean;
|
|
55
59
|
isClearable?: boolean;
|
|
56
60
|
requiredFilledFilters?: string[];
|
|
57
61
|
localeKey?: IFilterLocaleKey;
|
|
@@ -83,12 +87,17 @@ export type IDateRangeWithoutPeriodConfigItem<Value> = IConfigItemBasicBase<Valu
|
|
|
83
87
|
dateFormat?: string;
|
|
84
88
|
} & Omit<IFilterWithDatesProps, 'value' | 'onChange' | 'onStartBtnSubmit' | 'onEndBtnSubmit'>;
|
|
85
89
|
|
|
86
|
-
// Дата
|
|
90
|
+
// Дата с периодами
|
|
87
91
|
export type IDateRangeConfigItem<Value> = IConfigItemBasicBase<Value> & {
|
|
88
92
|
type: 'dateRange';
|
|
89
93
|
dateFormat?: string;
|
|
90
94
|
} & Omit<IFilterWithPeriodProps, 'value' | 'onChange' | 'setIsOpen'>;
|
|
91
95
|
|
|
96
|
+
// Date Picker для выбора одной даты
|
|
97
|
+
export type IDatePickerSingleConfigItem<Value> = IConfigItemBasicBase<Value> & {
|
|
98
|
+
type: 'datePickerSingle';
|
|
99
|
+
} & Omit<IFilterDateSingleProps, 'value' | 'onChange' | 'onEndBtnSubmit'>;
|
|
100
|
+
|
|
92
101
|
export interface ICustomComponentProps<Value> extends ITestIdProps {
|
|
93
102
|
value?: Value;
|
|
94
103
|
onChange: (v?: Value) => void;
|
|
@@ -127,6 +136,7 @@ export type ConfigItem<Value> =
|
|
|
127
136
|
| ICustomConfigItem<Value>
|
|
128
137
|
| IDateRangeWithoutPeriodConfigItem<Value>
|
|
129
138
|
| IDateRangeConfigItem<Value>
|
|
139
|
+
| IDatePickerSingleConfigItem<Value>
|
|
130
140
|
| IIntervalConfigItem<Value>
|
|
131
141
|
| IBooleanConfigItem<Value>;
|
|
132
142
|
|
|
@@ -145,6 +155,7 @@ export interface IFilterLocale {
|
|
|
145
155
|
from: string;
|
|
146
156
|
to: string;
|
|
147
157
|
back: string;
|
|
158
|
+
date: string;
|
|
148
159
|
months: string[];
|
|
149
160
|
periods: {
|
|
150
161
|
[key: string]: string;
|
package/src/theme/types.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
IDotsPreloaderStyles,
|
|
17
17
|
IFileInputStyles,
|
|
18
18
|
IFileItemStyles,
|
|
19
|
+
IFilterDateSingleStyles,
|
|
19
20
|
IFilterIntervalStyles,
|
|
20
21
|
IFilterSelectStyles,
|
|
21
22
|
IFiltersPaneSearchStyles,
|
|
@@ -103,6 +104,7 @@ export interface IComponentStyles {
|
|
|
103
104
|
FileItem: IFileItemStyles;
|
|
104
105
|
FilterValueView: IFilterValueViewStyles;
|
|
105
106
|
FiltersPane: IFiltersPaneStyles;
|
|
107
|
+
FilterDateSingle: IFilterDateSingleStyles;
|
|
106
108
|
FilterInterval: IFilterIntervalStyles;
|
|
107
109
|
FilterSelect: IFilterSelectStyles;
|
|
108
110
|
FilterWithDates: IFilterWithDatesStyles;
|