@snack-uikit/fields 0.29.2-preview-eb3592d8.0 → 0.29.2

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.
@@ -38,9 +38,9 @@ import { useDateField } from './hooks';
38
38
  import { useFocusHandlers } from './hooks/useFocusHandlers';
39
39
  import { useHandlers } from './hooks/useHandlers';
40
40
  import styles from './styles.module.scss';
41
- import { Mode } from './types';
41
+ import { parseDate } from './utils';
42
42
 
43
- type InputProps = Pick<InputPrivateProps, 'id' | 'name' | 'disabled' | 'readonly' | 'onFocus' | 'onBlur'>;
43
+ type InputProps = Pick<InputPrivateProps, 'id' | 'name' | 'value' | 'disabled' | 'readonly' | 'onFocus' | 'onBlur'>;
44
44
 
45
45
  type WrapperProps = Pick<
46
46
  FieldDecoratorProps,
@@ -62,10 +62,8 @@ type FieldDateOwnProps = {
62
62
  open?: boolean;
63
63
  /** Колбек открытия пикера */
64
64
  onOpenChange?(value: boolean): void;
65
- /** Значение поля */
66
- value?: Date;
67
65
  /** Колбек смены значения */
68
- onChange?(value: Date | undefined): void;
66
+ onChange?(value: string): void;
69
67
  /** Отображение кнопки копирования */
70
68
  showCopyButton?: boolean;
71
69
  /**
@@ -75,7 +73,6 @@ type FieldDateOwnProps = {
75
73
  showClearButton?: boolean;
76
74
  /** Текущая локаль календаря */
77
75
  locale?: Intl.Locale;
78
- mode: Mode;
79
76
  } & Pick<CalendarProps, 'buildCellProps'>;
80
77
 
81
78
  export type FieldDateProps = WithSupportProps<FieldDateOwnProps & InputProps & WrapperProps>;
@@ -83,7 +80,7 @@ export type FieldDateProps = WithSupportProps<FieldDateOwnProps & InputProps & W
83
80
  const CALENDAR_SIZE_MAP: Record<Size, CalendarProps['size']> = {
84
81
  [SIZE.S]: 's',
85
82
  [SIZE.M]: 'm',
86
- [SIZE.L]: 'l',
83
+ [SIZE.L]: 'm',
87
84
  };
88
85
 
89
86
  export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
@@ -114,7 +111,6 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
114
111
  locale = DEFAULT_LOCALE,
115
112
  buildCellProps,
116
113
  error,
117
- mode,
118
114
  ...rest
119
115
  },
120
116
  ref,
@@ -143,7 +139,7 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
143
139
  );
144
140
 
145
141
  const handleClear = useCallback(() => {
146
- onChange && onChange(undefined);
142
+ onChange && onChange('');
147
143
  if (localRef.current?.value) {
148
144
  localRef.current.value = '';
149
145
  }
@@ -157,9 +153,8 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
157
153
  }
158
154
  }, [onChange, required, setIsOpen]);
159
155
 
160
- const valueToCopy = (mode === 'date' ? valueProp?.toLocaleDateString() : valueProp?.toLocaleString()) ?? '';
161
156
  const clearButtonSettings = useClearButton({ clearButtonRef, showClearButton, size, onClear: handleClear });
162
- const copyButtonSettings = useCopyButton({ copyButtonRef, showCopyButton, size, valueToCopy });
157
+ const copyButtonSettings = useCopyButton({ copyButtonRef, showCopyButton, size, valueToCopy: valueProp || '' });
163
158
  const calendarIcon: ButtonProps = useMemo(
164
159
  () => ({
165
160
  active: false,
@@ -191,13 +186,9 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
191
186
  readonly,
192
187
  locale,
193
188
  setIsOpen,
194
- mode,
195
189
  });
196
190
 
197
- const setInputFocusFromButtons = useCallback(
198
- () => setInputFocus(mode === 'date' ? SlotKey.Year : SlotKey.Seconds),
199
- [mode, setInputFocus],
200
- );
191
+ const setInputFocusFromButtons = useCallback(() => setInputFocus(SlotKey.Year), [setInputFocus]);
201
192
 
202
193
  const {
203
194
  postfixButtons,
@@ -213,15 +204,11 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
213
204
  submitKeys: ['Enter', 'Space', 'Tab'],
214
205
  });
215
206
 
207
+ // TODO: do not hardcode locale here
216
208
  const handleSelectDate = (date: Date) => {
217
- onChange && onChange(date);
209
+ onChange && onChange(date.toLocaleDateString(DEFAULT_LOCALE));
218
210
  localRef.current?.focus();
219
211
  setIsOpen(false);
220
-
221
- if (localRef.current) {
222
- localRef.current.value =
223
- mode === 'date' ? date.toLocaleDateString(DEFAULT_LOCALE) : date.toLocaleString(DEFAULT_LOCALE);
224
- }
225
212
  };
226
213
 
227
214
  const handleCalendarFocusLeave: CalendarProps['onFocusLeave'] = () => {
@@ -246,6 +233,12 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
246
233
  }
247
234
  }, [open]);
248
235
 
236
+ useEffect(() => {
237
+ if (localRef.current) {
238
+ localRef.current.value = valueProp;
239
+ }
240
+ }, [valueProp]);
241
+
249
242
  const onFocusByKeyboard = useCallback(
250
243
  (e: FocusEvent<HTMLInputElement>) => {
251
244
  setInputFocus();
@@ -303,9 +296,9 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
303
296
  content={
304
297
  <div className={styles.calendarWrapper} data-size={size}>
305
298
  <Calendar
306
- mode={mode}
299
+ mode='date'
307
300
  size={CALENDAR_SIZE_MAP[size]}
308
- value={valueProp}
301
+ value={valueProp ? parseDate(valueProp) : undefined}
309
302
  onChangeValue={handleSelectDate}
310
303
  buildCellProps={buildCellProps}
311
304
  navigationStartRef={element => {
@@ -317,7 +310,6 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
317
310
  onFocusLeave={handleCalendarFocusLeave}
318
311
  locale={locale}
319
312
  data-test-id='field-date__calendar'
320
- fitToContainer={false}
321
313
  />
322
314
  </div>
323
315
  }
@@ -1,77 +1,33 @@
1
- import { Mode, Slot } from './types';
1
+ import { Slot } from './types';
2
2
 
3
3
  export enum SlotKey {
4
4
  Day = 'D',
5
5
  Month = 'M',
6
6
  Year = 'Y',
7
- Hours = 'h',
8
- Minutes = 'm',
9
- Seconds = 's',
10
7
  }
11
8
 
12
- export const MODES = {
13
- Date: 'date',
14
- DateTime: 'date-time',
15
- } as const;
16
-
17
- export const MASK: Record<Mode, Record<string, string>> = {
18
- [MODES.Date]: {
19
- 'ru-RU': 'ДД.ММ.ГГГГ',
20
- 'en-US': 'DD.MM.YYYY',
21
- },
22
- [MODES.DateTime]: {
23
- 'ru-RU': 'ДД.ММ.ГГГГ, чч:мм:сс',
24
- 'en-US': 'DD.MM.YYYY, hh:mm:ss',
25
- },
9
+ export const MASK: Record<string, string> = {
10
+ 'ru-RU': 'ДД.ММ.ГГГГ',
11
+ 'en-US': 'DD.MM.YYYY',
26
12
  };
27
13
 
28
14
  export const DEFAULT_LOCALE = new Intl.Locale('ru-RU');
29
15
 
30
- const DATE_SLOTS = {
16
+ export const SLOTS: Record<SlotKey | string, Slot> = {
31
17
  [SlotKey.Day]: { start: 0, end: 2, max: 31, min: 1 },
32
18
  [SlotKey.Month]: { start: 3, end: 5, max: 12, min: 1 },
33
19
  [SlotKey.Year]: { start: 6, end: 10, max: 2100, min: 1900 },
34
- };
35
-
36
- export const SLOTS: Record<Mode, Record<SlotKey | string, Slot>> = {
37
- [MODES.Date]: DATE_SLOTS,
38
- [MODES.DateTime]: {
39
- ...DATE_SLOTS,
40
- [SlotKey.Hours]: { start: 12, end: 14, max: 23, min: 0 },
41
- [SlotKey.Minutes]: { start: 15, end: 17, max: 59, min: 0 },
42
- [SlotKey.Seconds]: { start: 18, end: 20, max: 59, min: 0 },
43
- },
44
- };
45
-
46
- const RU_DATE_SLOTS_PLACEHOLDER = {
47
- [SlotKey.Day]: 'ДД',
48
- [SlotKey.Month]: 'ММ',
49
- [SlotKey.Year]: 'ГГГГ',
50
- };
51
-
52
- const EN_DATE_SLOTS_PLACEHOLDER = {
53
- [SlotKey.Day]: 'DD',
54
- [SlotKey.Month]: 'MM',
55
- [SlotKey.Year]: 'YYYY',
56
- };
20
+ } as const;
57
21
 
58
- export const SLOTS_PLACEHOLDER: Record<Mode, Record<string, Partial<Record<SlotKey, string>>>> = {
59
- [MODES.Date]: {
60
- 'ru-RU': RU_DATE_SLOTS_PLACEHOLDER,
61
- 'en-US': EN_DATE_SLOTS_PLACEHOLDER,
22
+ export const SLOTS_PLACEHOLDER: Record<string, Record<string, string>> = {
23
+ 'ru-RU': {
24
+ [SlotKey.Day]: 'ДД',
25
+ [SlotKey.Month]: 'ММ',
26
+ [SlotKey.Year]: 'ГГГГ',
62
27
  },
63
- [MODES.DateTime]: {
64
- 'ru-RU': {
65
- ...RU_DATE_SLOTS_PLACEHOLDER,
66
- [SlotKey.Hours]: 'чч',
67
- [SlotKey.Minutes]: 'мм',
68
- [SlotKey.Seconds]: 'сс',
69
- },
70
- 'en-US': {
71
- ...EN_DATE_SLOTS_PLACEHOLDER,
72
- [SlotKey.Hours]: 'hh',
73
- [SlotKey.Minutes]: 'mm',
74
- [SlotKey.Seconds]: 'ss',
75
- },
28
+ 'en-US': {
29
+ [SlotKey.Day]: 'DD',
30
+ [SlotKey.Month]: 'MM',
31
+ [SlotKey.Year]: 'YYYY',
76
32
  },
77
33
  };
@@ -3,48 +3,29 @@ import { ChangeEvent, FocusEventHandler, KeyboardEvent, RefObject, useCallback,
3
3
  import { isBrowser } from '@snack-uikit/utils';
4
4
 
5
5
  import { DEFAULT_LOCALE, MASK, SlotKey, SLOTS, SLOTS_PLACEHOLDER } from '../constants';
6
- import { Mode } from '../types';
7
- import { getNextSlotKey, getPrevSlotKey, getSlotKey, parseDate } from '../utils';
6
+ import { getNextSlotKey, getPrevSlotKey, getSlotKey } from '../utils';
8
7
  import { useDateFieldHelpers } from './useDateFieldHelpers';
9
- import { useDateTimeFieldHelpers } from './useDateTimeFieldHelpers';
10
8
 
11
9
  type UseDateFieldProps = {
12
10
  inputRef: RefObject<HTMLInputElement>;
13
- onChange?(value: Date | undefined): void;
11
+ onChange?(value: string): void;
14
12
  readonly?: boolean;
15
13
  locale?: Intl.Locale;
16
14
  setIsOpen(v: boolean): void;
17
- mode: Mode;
18
15
  };
19
16
 
20
- type FocusSlot = SlotKey.Day | SlotKey.Year | SlotKey.Seconds | 'auto';
21
-
22
- export function useDateField({
23
- inputRef,
24
- onChange,
25
- readonly,
26
- locale = DEFAULT_LOCALE,
27
- setIsOpen,
28
- mode,
29
- }: UseDateFieldProps) {
30
- const dateHelpers = useDateFieldHelpers(inputRef);
31
- const dateTimeHelpers = useDateTimeFieldHelpers(inputRef);
32
-
33
- const { setFocus, updateSlot, getSlot, isLikeDate, isAllSelected, tryToCompleteInput, isValidInput } =
34
- mode === 'date' ? dateHelpers : dateTimeHelpers;
17
+ type FocusSlot = SlotKey.Day | SlotKey.Year | 'auto';
35
18
 
19
+ export function useDateField({ inputRef, onChange, readonly, locale = DEFAULT_LOCALE, setIsOpen }: UseDateFieldProps) {
20
+ const { setFocus, updateSlot, getSlot, isLikeDate, isAllSelected, isValidInput, tryToCompleteInput } =
21
+ useDateFieldHelpers(inputRef);
36
22
  const focusSlotRef = useRef<FocusSlot>(SlotKey.Day);
37
23
 
38
- const mask = useMemo(
39
- () => MASK[mode][locale.baseName] || MASK[mode][DEFAULT_LOCALE.baseName],
40
- [locale.baseName, mode],
41
- );
42
- const getNextSlotKeyHandler = getNextSlotKey(mode);
43
- const getPrevSlotKeyHandler = getPrevSlotKey(mode);
24
+ const mask = useMemo(() => MASK[locale.baseName] || MASK[DEFAULT_LOCALE.baseName], [locale]);
44
25
 
45
- const slotsPlaceholder = useMemo(
46
- () => SLOTS_PLACEHOLDER[mode][locale.baseName] || SLOTS_PLACEHOLDER[mode][DEFAULT_LOCALE.baseName],
47
- [locale.baseName, mode],
26
+ const slotsPlaceHolder = useMemo(
27
+ () => SLOTS_PLACEHOLDER[locale.baseName] || SLOTS_PLACEHOLDER[DEFAULT_LOCALE.baseName],
28
+ [locale.baseName],
48
29
  );
49
30
 
50
31
  const setInputFocus = useCallback(
@@ -76,14 +57,14 @@ export function useDateField({
76
57
  return;
77
58
  }
78
59
 
79
- const slotKey = getSlotKey(inputRef.current.selectionStart, mode);
60
+ const slotKey = getSlotKey(inputRef.current.selectionStart);
80
61
 
81
62
  if (slotKey) {
82
- const { start, end } = SLOTS[mode][slotKey];
63
+ const { start, end } = SLOTS[slotKey];
83
64
  inputRef.current.setSelectionRange(start, end);
84
65
  }
85
66
  },
86
- [inputRef, isLikeDate, mask, mode, readonly, setFocus],
67
+ [inputRef, isLikeDate, mask, readonly, setFocus],
87
68
  );
88
69
 
89
70
  const handleClick = useCallback(() => {
@@ -91,35 +72,35 @@ export function useDateField({
91
72
  }, [setInputFocus]);
92
73
 
93
74
  const handleChange: (value: string, e?: ChangeEvent<HTMLInputElement> | undefined) => void = () => {
94
- onChange && isLikeDate() && onChange(parseDate(inputRef.current?.value || ''));
75
+ onChange && isLikeDate() && onChange(inputRef.current?.value || '');
95
76
  };
96
77
 
97
78
  const checkInputAndGoNext = useCallback(
98
79
  (slotKey: string) => {
99
- if (slotKey === (mode === 'date' ? SlotKey.Year : SlotKey.Seconds) && tryToCompleteInput()) {
80
+ if (slotKey === SlotKey.Year && tryToCompleteInput()) {
100
81
  return;
101
82
  }
102
83
 
103
84
  if (isValidInput()) {
104
- setFocus(getNextSlotKeyHandler(slotKey));
85
+ setFocus(getNextSlotKey(slotKey));
105
86
  return;
106
87
  }
107
88
 
108
89
  switch (slotKey) {
109
90
  case SlotKey.Day:
110
- updateSlot(SlotKey.Month, slotsPlaceholder?.[SlotKey.Month] ?? '');
91
+ updateSlot(SlotKey.Month, slotsPlaceHolder[SlotKey.Month]);
111
92
  setFocus(SlotKey.Month);
112
93
  return;
113
94
  case SlotKey.Year:
114
95
  case SlotKey.Month:
115
- updateSlot(SlotKey.Day, slotsPlaceholder?.[SlotKey.Day] ?? '');
96
+ updateSlot(SlotKey.Day, slotsPlaceHolder[SlotKey.Day]);
116
97
  setFocus(SlotKey.Day);
117
98
  return;
118
99
  default:
119
- setFocus(getNextSlotKeyHandler(slotKey));
100
+ setFocus(getNextSlotKey(slotKey));
120
101
  }
121
102
  },
122
- [mode, tryToCompleteInput, isValidInput, setFocus, getNextSlotKeyHandler, updateSlot, slotsPlaceholder],
103
+ [tryToCompleteInput, isValidInput, setFocus, slotsPlaceHolder, updateSlot],
123
104
  );
124
105
 
125
106
  const handleKeyDown = useCallback(
@@ -144,25 +125,25 @@ export function useDateField({
144
125
  }
145
126
 
146
127
  const clickIndex = inputRef.current.selectionStart;
147
- const slotKey = getSlotKey(clickIndex, mode);
128
+ const slotKey = getSlotKey(clickIndex);
148
129
 
149
130
  if (slotKey) {
150
131
  const value = getSlot(slotKey);
151
- const { max } = SLOTS[mode][slotKey];
132
+ const { max } = SLOTS[slotKey];
152
133
 
153
134
  const numberValue = Number(value) || 0;
154
135
 
155
136
  if (e.key === 'ArrowRight') {
156
- if (isAllSelected() || slotKey === (mode === 'date' ? SlotKey.Year : SlotKey.Seconds)) {
137
+ if (isAllSelected() || slotKey === SlotKey.Year) {
157
138
  inputRef.current.selectionStart = inputRef.current.value.length;
158
139
  return;
159
140
  }
160
- setFocus(getNextSlotKeyHandler(slotKey));
141
+ setFocus(getNextSlotKey(slotKey));
161
142
  return;
162
143
  }
163
144
 
164
145
  if (e.key === 'ArrowLeft') {
165
- setFocus(getPrevSlotKeyHandler(slotKey));
146
+ setFocus(getPrevSlotKey(slotKey));
166
147
  return;
167
148
  }
168
149
 
@@ -171,7 +152,7 @@ export function useDateField({
171
152
  inputRef.current.value = mask;
172
153
  setFocus(SlotKey.Day);
173
154
  } else {
174
- updateSlot(slotKey, slotsPlaceholder[slotKey] ?? '');
155
+ updateSlot(slotKey, slotsPlaceHolder[slotKey]);
175
156
  }
176
157
  }
177
158
 
@@ -208,26 +189,22 @@ export function useDateField({
208
189
  }
209
190
  }
210
191
  }
211
- const newDate = parseDate(isLikeDate() ? inputRef.current.value : '');
212
- onChange?.(newDate);
192
+ onChange?.(isLikeDate() ? inputRef.current.value : '');
213
193
  }
214
194
  }
215
195
  },
216
196
  [
217
197
  checkInputAndGoNext,
218
- getNextSlotKeyHandler,
219
- getPrevSlotKeyHandler,
220
198
  getSlot,
221
199
  inputRef,
222
200
  isAllSelected,
223
201
  isLikeDate,
224
202
  mask,
225
- mode,
226
203
  onChange,
227
204
  readonly,
228
205
  setFocus,
229
206
  setIsOpen,
230
- slotsPlaceholder,
207
+ slotsPlaceHolder,
231
208
  tryToCompleteInput,
232
209
  updateSlot,
233
210
  ],
@@ -6,7 +6,7 @@ export function useDateFieldHelpers(inputRef: RefObject<HTMLInputElement>) {
6
6
  const setFocus = useCallback(
7
7
  (slotKey: string) => {
8
8
  if (inputRef.current) {
9
- const { start, end } = SLOTS.date[slotKey];
9
+ const { start, end } = SLOTS[slotKey];
10
10
 
11
11
  inputRef.current.setSelectionRange(start, end);
12
12
  }
@@ -22,7 +22,7 @@ export function useDateFieldHelpers(inputRef: RefObject<HTMLInputElement>) {
22
22
  const getSlot = useCallback(
23
23
  (slotKey: string) => {
24
24
  if (inputRef.current) {
25
- return inputRef.current.value.slice(SLOTS.date[slotKey].start, SLOTS.date[slotKey].end);
25
+ return inputRef.current.value.slice(SLOTS[slotKey].start, SLOTS[slotKey].end);
26
26
  }
27
27
 
28
28
  return '';
@@ -32,7 +32,7 @@ export function useDateFieldHelpers(inputRef: RefObject<HTMLInputElement>) {
32
32
 
33
33
  const isLikeDate = useCallback(() => {
34
34
  if (inputRef.current) {
35
- return Object.keys(SLOTS.date).every(slotKey => getSlot(slotKey) && Number.isInteger(Number(getSlot(slotKey))));
35
+ return Object.keys(SLOTS).every(slotKey => getSlot(slotKey) && Number.isInteger(Number(getSlot(slotKey))));
36
36
  }
37
37
  return false;
38
38
  }, [getSlot, inputRef]);
@@ -56,7 +56,7 @@ export function useDateFieldHelpers(inputRef: RefObject<HTMLInputElement>) {
56
56
  const month = parseInt(getSlot(SlotKey.Month), 10);
57
57
  const year = parseInt(getSlot(SlotKey.Year), 10);
58
58
 
59
- const { min, max } = SLOTS.date[SlotKey.Year];
59
+ const { min, max } = SLOTS[SlotKey.Year];
60
60
 
61
61
  const isCompleted = Boolean(day && month && year >= min && year <= max);
62
62
 
@@ -72,7 +72,7 @@ export function useDateFieldHelpers(inputRef: RefObject<HTMLInputElement>) {
72
72
  const updateSlot = useCallback(
73
73
  (slotKey: string, slotValue: number | string) => {
74
74
  if (inputRef.current) {
75
- const { start, end, max } = SLOTS.date[slotKey];
75
+ const { start, end, max } = SLOTS[slotKey];
76
76
 
77
77
  inputRef.current.value =
78
78
  inputRef.current.value.slice(0, start) +
@@ -1,12 +1,6 @@
1
- import { ValueOf } from '@snack-uikit/utils';
2
-
3
- import { MODES } from './constants';
4
-
5
1
  export type Slot = {
6
2
  start: number;
7
3
  end: number;
8
4
  max: number;
9
5
  min: number;
10
6
  };
11
-
12
- export type Mode = ValueOf<typeof MODES>;
@@ -1,18 +1,18 @@
1
1
  import { SlotKey, SLOTS } from './constants';
2
- import { Mode } from './types';
3
2
 
4
- export function getSlotKey(index: number | null, mode: Mode): SlotKey | null {
3
+ export function getSlotKey(index: number | null) {
5
4
  if (index !== null) {
6
- for (const key in SLOTS[mode]) {
7
- if (index >= SLOTS[mode][key].start && index <= SLOTS[mode][key].end) {
8
- return key as SlotKey;
5
+ for (const key in SLOTS) {
6
+ if (index >= SLOTS[key].start && index <= SLOTS[key].end) {
7
+ return key;
9
8
  }
10
9
  }
11
10
  }
12
11
 
13
12
  return null;
14
13
  }
15
- export function getNextSlotKeyWithDate(slotKey: string | null) {
14
+
15
+ export function getNextSlotKey(slotKey: string | null) {
16
16
  switch (slotKey) {
17
17
  case SlotKey.Day: {
18
18
  return SlotKey.Month;
@@ -25,7 +25,7 @@ export function getNextSlotKeyWithDate(slotKey: string | null) {
25
25
  }
26
26
  }
27
27
 
28
- export function getPrevSlotKeyWithDate(slotKey: string | null) {
28
+ export function getPrevSlotKey(slotKey: string | null) {
29
29
  switch (slotKey) {
30
30
  case SlotKey.Year: {
31
31
  return SlotKey.Month;
@@ -38,82 +38,12 @@ export function getPrevSlotKeyWithDate(slotKey: string | null) {
38
38
  }
39
39
  }
40
40
 
41
- export function getNextSlotKeyWithTime(slotKey: string | null) {
42
- switch (slotKey) {
43
- case SlotKey.Day: {
44
- return SlotKey.Month;
45
- }
46
- case SlotKey.Month: {
47
- return SlotKey.Year;
48
- }
49
- case SlotKey.Year: {
50
- return SlotKey.Hours;
51
- }
52
- case SlotKey.Hours: {
53
- return SlotKey.Minutes;
54
- }
55
- case SlotKey.Minutes:
56
- case SlotKey.Seconds:
57
- default: {
58
- return SlotKey.Seconds;
59
- }
60
- }
61
- }
62
-
63
- export function getPrevSlotKeyWithTime(slotKey: string | null) {
64
- switch (slotKey) {
65
- case SlotKey.Seconds: {
66
- return SlotKey.Minutes;
67
- }
68
- case SlotKey.Minutes: {
69
- return SlotKey.Hours;
70
- }
71
- case SlotKey.Hours: {
72
- return SlotKey.Year;
73
- }
74
- case SlotKey.Year: {
75
- return SlotKey.Month;
76
- }
77
- case SlotKey.Month:
78
- case SlotKey.Day:
79
- default: {
80
- return SlotKey.Day;
81
- }
82
- }
83
- }
84
-
85
- export function getNextSlotKey(mode: Mode) {
86
- return mode === 'date' ? getNextSlotKeyWithDate : getNextSlotKeyWithTime;
87
- }
88
-
89
- export function getPrevSlotKey(mode: Mode) {
90
- return mode === 'date' ? getPrevSlotKeyWithDate : getPrevSlotKeyWithTime;
91
- }
92
-
93
41
  /**
94
42
  * Преобразует строковое значение поля FieldDate в тип Date
95
43
  * @function helper
96
44
  */
97
45
 
98
- export function parseDate(value: string) {
99
- if (!value) {
100
- return undefined;
101
- }
102
-
103
- const [date, time] = value.split(', ');
104
- const dateValues = date.split('.');
105
- const year = Number(dateValues[2]);
106
- const month = Number(dateValues[1]) - 1;
107
- const day = Number(dateValues[0]);
108
-
109
- if (time) {
110
- const timeValues = time.split(':');
111
- const hours = timeValues[0] ? Number(timeValues[0]) : undefined;
112
- const minutes = timeValues[1] ? Number(timeValues[1]) : undefined;
113
- const seconds = timeValues[2] ? Number(timeValues[2]) : undefined;
114
-
115
- return new Date(year, month, day, hours, minutes, seconds);
116
- }
117
-
118
- return new Date(year, month, day);
46
+ export function parseDate(date: string) {
47
+ const values = date.split('.');
48
+ return new Date(Number(values[2]), Number(values[1]) - 1, Number(values[0]));
119
49
  }
@@ -1,10 +0,0 @@
1
- import { RefObject } from 'react';
2
- export declare function useDateTimeFieldHelpers(inputRef: RefObject<HTMLInputElement>): {
3
- isAllSelected: () => boolean;
4
- tryToCompleteInput: () => boolean;
5
- getSlot: (slotKey: string) => string;
6
- updateSlot: (slotKey: string, slotValue: number | string) => void;
7
- setFocus: (slotKey: string) => void;
8
- isLikeDate: () => boolean;
9
- isValidInput: () => boolean;
10
- };
@@ -1,75 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { SlotKey, SLOTS } from '../constants';
3
- export function useDateTimeFieldHelpers(inputRef) {
4
- const setFocus = useCallback((slotKey) => {
5
- if (inputRef.current) {
6
- const { start, end } = SLOTS['date-time'][slotKey];
7
- inputRef.current.setSelectionRange(start, end);
8
- }
9
- }, [inputRef]);
10
- const isAllSelected = useCallback(() => { var _a, _b, _c; return ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value.length) === ((_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.selectionEnd) && ((_c = inputRef.current) === null || _c === void 0 ? void 0 : _c.selectionStart) === 0; }, [inputRef]);
11
- const getSlot = useCallback((slotKey) => {
12
- if (inputRef.current) {
13
- return inputRef.current.value.slice(SLOTS['date-time'][slotKey].start, SLOTS['date-time'][slotKey].end);
14
- }
15
- return '';
16
- }, [inputRef]);
17
- const isLikeDate = useCallback(() => {
18
- if (inputRef.current) {
19
- return Object.keys(SLOTS['date-time']).every(slotKey => getSlot(slotKey) && Number.isInteger(Number(getSlot(slotKey))));
20
- }
21
- return false;
22
- }, [getSlot, inputRef]);
23
- const isValidInput = useCallback(() => {
24
- const day = parseInt(getSlot(SlotKey.Day), 10);
25
- const month = parseInt(getSlot(SlotKey.Month), 10);
26
- const year = parseInt(getSlot(SlotKey.Year), 10);
27
- if (!month || !day) {
28
- return true;
29
- }
30
- const date = new Date(year || /* високосный год = */ 2020, month - 1, day);
31
- return date.getDate() === day;
32
- }, [getSlot]);
33
- const tryToCompleteInput = useCallback(() => {
34
- var _a;
35
- const day = parseInt(getSlot(SlotKey.Day), 10);
36
- const month = parseInt(getSlot(SlotKey.Month), 10);
37
- const year = parseInt(getSlot(SlotKey.Year), 10);
38
- const hours = parseInt(getSlot(SlotKey.Hours), 10);
39
- const minutes = parseInt(getSlot(SlotKey.Minutes), 10);
40
- const seconds = parseInt(getSlot(SlotKey.Seconds), 10);
41
- const { min, max } = SLOTS['date-time'][SlotKey.Year];
42
- const isCompleted = Boolean(day &&
43
- month &&
44
- year >= min &&
45
- year <= max &&
46
- hours !== undefined &&
47
- minutes !== undefined &&
48
- seconds !== undefined);
49
- if (isCompleted && inputRef.current) {
50
- const lastPosition = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value.length;
51
- inputRef.current.selectionStart = lastPosition;
52
- inputRef.current.selectionEnd = lastPosition;
53
- }
54
- return isCompleted;
55
- }, [getSlot, inputRef]);
56
- const updateSlot = useCallback((slotKey, slotValue) => {
57
- if (inputRef.current) {
58
- const { start, end, max } = SLOTS['date-time'][slotKey];
59
- inputRef.current.value =
60
- inputRef.current.value.slice(0, start) +
61
- slotValue.toString().padStart(max.toString().length, '0') +
62
- inputRef.current.value.slice(end);
63
- setFocus(slotKey);
64
- }
65
- }, [inputRef, setFocus]);
66
- return {
67
- isAllSelected,
68
- tryToCompleteInput,
69
- getSlot,
70
- updateSlot,
71
- setFocus,
72
- isLikeDate,
73
- isValidInput,
74
- };
75
- }