@snack-uikit/chips 0.18.0 → 0.19.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 (39) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +22 -1
  3. package/dist/cjs/components/ChipChoice/components/ChipChoiceDate.d.ts +9 -2
  4. package/dist/cjs/components/ChipChoice/components/ChipChoiceDate.js +46 -10
  5. package/dist/cjs/components/ChipChoice/components/ChipChoiceDateRange.js +2 -1
  6. package/dist/cjs/components/ChipChoice/components/ChipChoiceTime.d.ts +12 -0
  7. package/dist/cjs/components/ChipChoice/components/ChipChoiceTime.js +123 -0
  8. package/dist/cjs/components/ChipChoice/components/index.d.ts +1 -0
  9. package/dist/cjs/components/ChipChoice/components/index.js +2 -1
  10. package/dist/cjs/components/ChipChoice/constants.d.ts +4 -1
  11. package/dist/cjs/components/ChipChoice/constants.js +10 -2
  12. package/dist/cjs/components/ChipChoice/index.d.ts +3 -2
  13. package/dist/cjs/components/ChipChoice/index.js +1 -0
  14. package/dist/cjs/components/ChipChoiceRow/components/constants.d.ts +1 -0
  15. package/dist/cjs/components/ChipChoiceRow/components/constants.js +1 -0
  16. package/dist/cjs/components/ChipChoiceRow/types.d.ts +7 -1
  17. package/dist/esm/components/ChipChoice/components/ChipChoiceDate.d.ts +9 -2
  18. package/dist/esm/components/ChipChoice/components/ChipChoiceDate.js +35 -10
  19. package/dist/esm/components/ChipChoice/components/ChipChoiceDateRange.js +3 -3
  20. package/dist/esm/components/ChipChoice/components/ChipChoiceTime.d.ts +12 -0
  21. package/dist/esm/components/ChipChoice/components/ChipChoiceTime.js +64 -0
  22. package/dist/esm/components/ChipChoice/components/index.d.ts +1 -0
  23. package/dist/esm/components/ChipChoice/components/index.js +1 -0
  24. package/dist/esm/components/ChipChoice/constants.d.ts +4 -1
  25. package/dist/esm/components/ChipChoice/constants.js +8 -0
  26. package/dist/esm/components/ChipChoice/index.d.ts +3 -2
  27. package/dist/esm/components/ChipChoice/index.js +2 -1
  28. package/dist/esm/components/ChipChoiceRow/components/constants.d.ts +1 -0
  29. package/dist/esm/components/ChipChoiceRow/components/constants.js +1 -0
  30. package/dist/esm/components/ChipChoiceRow/types.d.ts +7 -1
  31. package/package.json +6 -6
  32. package/src/components/ChipChoice/components/ChipChoiceDate.tsx +62 -12
  33. package/src/components/ChipChoice/components/ChipChoiceDateRange.tsx +3 -2
  34. package/src/components/ChipChoice/components/ChipChoiceTime.tsx +125 -0
  35. package/src/components/ChipChoice/components/index.ts +1 -0
  36. package/src/components/ChipChoice/constants.ts +11 -1
  37. package/src/components/ChipChoice/index.ts +10 -1
  38. package/src/components/ChipChoiceRow/components/constants.ts +1 -0
  39. package/src/components/ChipChoiceRow/types.ts +5 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 0.19.0 (2024-10-31)
7
+
8
+
9
+ ### Features
10
+
11
+ * **PDS-438:** add ChipChoiceTime ([805b98a](https://github.com/cloud-ru-tech/snack-uikit/commit/805b98a2927ff0b38b704cae8f7b0beef3369469))
12
+ * **PDS-438:** chip-choice - hide day in mode=month, add mode=date-time ([3108090](https://github.com/cloud-ru-tech/snack-uikit/commit/310809000629677374ded8280e73249eabe6410e))
13
+
14
+
15
+ ### BREAKING CHANGES
16
+
17
+
18
+ * **PDS-438:** add showSeconds prop, remove locale prop ([0235eb7](https://github.com/cloud-ru-tech/snack-uikit/commit/0235eb7a5a7f7d8ac5e4e7cb03fe6e2408682b54))
19
+
20
+
21
+
22
+
6
23
  # 0.18.0 (2024-10-28)
7
24
 
8
25
 
package/README.md CHANGED
@@ -221,7 +221,8 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
221
221
  | defaultValue | `Date` | - | Значение компонента по-умолчанию |
222
222
  | onChange | `(value: Date) => void` | - | Колбек смены значения |
223
223
  | valueRender | `(value?: Date) => ReactNode` | - | Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение |
224
- | mode | "date" \| "month" | - | |
224
+ | mode | "date" \| "month" \| "date-time" | - | |
225
+ | showSeconds | `boolean` | - | |
225
226
  ## ChipChoice.DateRange
226
227
  ### Props
227
228
  | name | type | default value | description |
@@ -242,6 +243,26 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
242
243
  | defaultValue | `Range` | - | Значение компонента по умолчанию |
243
244
  | onChange | `(value: Range) => void` | - | Колбек смены значения |
244
245
  | valueRender | `(value?: Range) => ReactNode` | - | Колбек формирующий строковое представление выбранного значения. Принимает массив выбранных значений |
246
+ ## ChipChoice.Time
247
+ ### Props
248
+ | name | type | default value | description |
249
+ |------|------|---------------|-------------|
250
+ | label | `string` | - | Лейбл |
251
+ | disabled | `boolean` | - | Деактивирован ли компонент |
252
+ | loading | `boolean` | - | Состояние загрузки |
253
+ | icon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка |
254
+ | className | `string` | - | CSS-класс |
255
+ | tabIndex | `number` | - | HTML tab index |
256
+ | size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
257
+ | onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
258
+ | showClearButton | `boolean` | true | Отображение кнопки очистки значения |
259
+ | placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
260
+ | dropDownClassName | `string` | - | |
261
+ | value | `TimeValue` | - | Выбранное значение. |
262
+ | defaultValue | `TimeValue` | - | Значение по-умолчанию для uncontrolled. |
263
+ | showSeconds | `boolean` | - | Показывать ли секунды |
264
+ | onChange | `(value: TimeValue) => void` | - | Колбек смены значения |
265
+ | valueRender | `(value?: TimeValue) => ReactNode` | - | Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение |
245
266
  ## isAccordionOption
246
267
  ### Props
247
268
  | name | type | default value | description |
@@ -1,6 +1,10 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CalendarProps } from '@snack-uikit/calendar';
3
3
  import { ChipChoiceCommonProps } from '../types';
4
+ type ChipChoiceDateWithSeconds = {
5
+ mode?: 'date-time';
6
+ showSeconds?: boolean;
7
+ };
4
8
  export type ChipChoiceDateProps = ChipChoiceCommonProps & {
5
9
  /** Значение компонента */
6
10
  value?: Date;
@@ -11,5 +15,8 @@ export type ChipChoiceDateProps = ChipChoiceCommonProps & {
11
15
  /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
12
16
  valueRender?(value?: Date): ReactNode;
13
17
  mode?: Exclude<CalendarProps['mode'], 'range'>;
14
- };
15
- export declare function ChipChoiceDate({ size, value, defaultValue, onChange, valueRender, dropDownClassName, mode, ...rest }: ChipChoiceDateProps): import("react/jsx-runtime").JSX.Element;
18
+ } & (ChipChoiceDateWithSeconds | {
19
+ mode?: 'date' | 'month';
20
+ });
21
+ export declare function ChipChoiceDate({ size, value, defaultValue, onChange, valueRender, dropDownClassName, mode, placement, widthStrategy, ...rest }: ChipChoiceDateProps): import("react/jsx-runtime").JSX.Element;
22
+ export {};
@@ -23,6 +23,7 @@ const constants_2 = require("../constants");
23
23
  const hooks_1 = require("../hooks");
24
24
  const ChipChoiceBase_1 = require("./ChipChoiceBase");
25
25
  function ChipChoiceDate(_a) {
26
+ var _b;
26
27
  var {
27
28
  size = constants_1.SIZE.S,
28
29
  value,
@@ -30,14 +31,17 @@ function ChipChoiceDate(_a) {
30
31
  onChange,
31
32
  valueRender,
32
33
  dropDownClassName,
33
- mode = 'date'
34
+ mode = 'date',
35
+ placement,
36
+ widthStrategy
34
37
  } = _a,
35
- rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "mode"]);
38
+ rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "mode", "placement", "widthStrategy"]);
36
39
  const [selectedValue, setSelectedValue] = (0, utils_1.useValueControl)({
37
40
  value,
38
41
  defaultValue,
39
42
  onChange
40
43
  });
44
+ const showSeconds = mode === 'date-time' ? (_b = rest.showSeconds) !== null && _b !== void 0 ? _b : true : undefined;
41
45
  const localRef = (0, react_1.useRef)(null);
42
46
  const [open, setOpen] = (0, react_1.useState)(false);
43
47
  const handleOnKeyDown = (0, hooks_1.useHandleOnKeyDown)({
@@ -53,20 +57,52 @@ function ChipChoiceDate(_a) {
53
57
  const {
54
58
  t
55
59
  } = (0, locale_1.useLocale)('Chips');
56
- const valueToRender = valueRender ? valueRender(selectedValue) : selectedValue && new Date(selectedValue).toLocaleDateString() || t('allLabel');
60
+ const valueToRender = (0, react_1.useMemo)(() => {
61
+ if (valueRender) {
62
+ return valueRender(selectedValue);
63
+ }
64
+ if (!selectedValue) return t('allLabel');
65
+ const date = new Date(selectedValue);
66
+ if (mode === 'date-time') {
67
+ return date.toLocaleString(constants_2.DEFAULT_LOCALE, {
68
+ year: 'numeric',
69
+ month: 'numeric',
70
+ day: 'numeric',
71
+ hour: '2-digit',
72
+ minute: '2-digit',
73
+ second: showSeconds ? '2-digit' : undefined
74
+ });
75
+ }
76
+ return date.toLocaleDateString(constants_2.DEFAULT_LOCALE, {
77
+ year: 'numeric',
78
+ month: 'numeric',
79
+ day: mode === 'date' ? 'numeric' : undefined
80
+ });
81
+ }, [mode, selectedValue, showSeconds, t, valueRender]);
57
82
  const clearValue = () => setSelectedValue(undefined);
83
+ const handleChangeValue = (0, react_1.useCallback)(value => {
84
+ setSelectedValue(value);
85
+ closeDroplist();
86
+ }, [closeDroplist, setSelectedValue]);
87
+ const navigationStartRef = (0, react_1.useRef)(null);
88
+ const focusNavigationStartItem = () => setTimeout(() => {
89
+ var _a;
90
+ return (_a = navigationStartRef.current) === null || _a === void 0 ? void 0 : _a.focus();
91
+ }, 0);
58
92
  return (0, jsx_runtime_1.jsx)(dropdown_1.Dropdown, {
59
93
  content: (0, jsx_runtime_1.jsx)(calendar_1.Calendar, {
60
94
  mode: mode,
61
95
  size: constants_2.CALENDAR_SIZE_MAP[size],
62
96
  value: selectedValue,
63
- onChangeValue: value => {
64
- setSelectedValue(value);
65
- closeDroplist();
66
- },
67
- navigationStartRef: element => element === null || element === void 0 ? void 0 : element.focus(),
68
- onFocusLeave: closeDroplist
97
+ fitToContainer: false,
98
+ onChangeValue: handleChangeValue,
99
+ navigationStartRef: navigationStartRef,
100
+ onFocusLeave: closeDroplist,
101
+ showSeconds: showSeconds,
102
+ locale: constants_2.DEFAULT_LOCALE
69
103
  }),
104
+ placement: placement,
105
+ widthStrategy: widthStrategy,
70
106
  outsideClick: true,
71
107
  triggerRef: localRef,
72
108
  open: open,
@@ -79,7 +115,7 @@ function ChipChoiceDate(_a) {
79
115
  value: selectedValue,
80
116
  valueToRender: valueToRender,
81
117
  size: size,
82
- onKeyDown: handleOnKeyDown()
118
+ onKeyDown: handleOnKeyDown(focusNavigationStartItem)
83
119
  }))
84
120
  });
85
121
  }
@@ -29,7 +29,7 @@ function defaultRangeFormatter(_ref) {
29
29
  } = _ref;
30
30
  if (!value || !value.length) return allLabel;
31
31
  const [from, to] = value;
32
- return `${from.toLocaleDateString()} ${constants_1.DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString()}`;
32
+ return `${from.toLocaleDateString(constants_2.DEFAULT_LOCALE)} ${constants_1.DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString(constants_2.DEFAULT_LOCALE)}`;
33
33
  }
34
34
  function ChipChoiceDateRange(_a) {
35
35
  var {
@@ -71,6 +71,7 @@ function ChipChoiceDateRange(_a) {
71
71
  setSelectedValue(value);
72
72
  closeDroplist();
73
73
  },
74
+ locale: constants_2.DEFAULT_LOCALE,
74
75
  // bug with focus
75
76
  // navigationStartRef={element => element?.focus()}
76
77
  onFocusLeave: closeDroplist
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ import { TimePickerProps } from '@snack-uikit/calendar';
3
+ import { ChipChoiceCommonProps } from '../types';
4
+ type TimeValue = TimePickerProps['value'];
5
+ export type ChipChoiceTimeProps = Omit<ChipChoiceCommonProps, 'widthStrategy'> & Pick<TimePickerProps, 'value' | 'defaultValue' | 'showSeconds'> & {
6
+ /** Колбек смены значения */
7
+ onChange?(value: TimeValue): void;
8
+ /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
9
+ valueRender?(value?: TimeValue): ReactNode;
10
+ };
11
+ export declare function ChipChoiceTime({ size, value, defaultValue, onChange, valueRender, dropDownClassName, showSeconds, placement, ...rest }: ChipChoiceTimeProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ var __rest = void 0 && (void 0).__rest || function (s, e) {
4
+ var t = {};
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
8
+ }
9
+ return t;
10
+ };
11
+ Object.defineProperty(exports, "__esModule", {
12
+ value: true
13
+ });
14
+ exports.ChipChoiceTime = ChipChoiceTime;
15
+ const jsx_runtime_1 = require("react/jsx-runtime");
16
+ const react_1 = require("react");
17
+ const calendar_1 = require("@snack-uikit/calendar");
18
+ const dropdown_1 = require("@snack-uikit/dropdown");
19
+ const locale_1 = require("@snack-uikit/locale");
20
+ const utils_1 = require("@snack-uikit/utils");
21
+ const constants_1 = require("../../../constants");
22
+ const constants_2 = require("../constants");
23
+ const hooks_1 = require("../hooks");
24
+ const ChipChoiceBase_1 = require("./ChipChoiceBase");
25
+ const getStringTimeValue = (time, _ref) => {
26
+ let {
27
+ showSeconds,
28
+ locale
29
+ } = _ref;
30
+ var _a, _b, _c;
31
+ if (!time) {
32
+ return '';
33
+ }
34
+ const date = new Date();
35
+ date.setHours((_a = time.hours) !== null && _a !== void 0 ? _a : 0);
36
+ date.setMinutes((_b = time.minutes) !== null && _b !== void 0 ? _b : 0);
37
+ date.setSeconds((_c = time.seconds) !== null && _c !== void 0 ? _c : 0);
38
+ return date.toLocaleTimeString(locale, {
39
+ hour: 'numeric',
40
+ minute: 'numeric',
41
+ second: showSeconds ? 'numeric' : undefined
42
+ });
43
+ };
44
+ function ChipChoiceTime(_a) {
45
+ var {
46
+ size = constants_1.SIZE.S,
47
+ value,
48
+ defaultValue,
49
+ onChange,
50
+ valueRender,
51
+ dropDownClassName,
52
+ showSeconds = true,
53
+ placement
54
+ } = _a,
55
+ rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "showSeconds", "placement"]);
56
+ const [selectedValue, setSelectedValue] = (0, utils_1.useValueControl)({
57
+ value,
58
+ defaultValue,
59
+ onChange
60
+ });
61
+ const localRef = (0, react_1.useRef)(null);
62
+ const [open, setOpen] = (0, react_1.useState)(false);
63
+ const handleOnKeyDown = (0, hooks_1.useHandleOnKeyDown)({
64
+ setOpen
65
+ });
66
+ const closeDroplist = (0, react_1.useCallback)(() => {
67
+ setOpen(false);
68
+ setTimeout(() => {
69
+ var _a;
70
+ return (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
71
+ }, 0);
72
+ }, []);
73
+ const {
74
+ t
75
+ } = (0, locale_1.useLocale)('Chips');
76
+ const valueToRender = (0, react_1.useMemo)(() => {
77
+ if (valueRender) {
78
+ return valueRender(selectedValue);
79
+ }
80
+ if (!selectedValue) return t('allLabel');
81
+ return getStringTimeValue(selectedValue, {
82
+ showSeconds,
83
+ locale: constants_2.DEFAULT_LOCALE
84
+ });
85
+ }, [selectedValue, showSeconds, t, valueRender]);
86
+ const clearValue = () => setSelectedValue(undefined);
87
+ const handleChangeValue = (0, react_1.useCallback)(value => {
88
+ setSelectedValue(value);
89
+ closeDroplist();
90
+ }, [closeDroplist, setSelectedValue]);
91
+ const navigationStartRef = (0, react_1.useRef)(null);
92
+ const focusNavigationStartItem = () => setTimeout(() => {
93
+ var _a;
94
+ return (_a = navigationStartRef.current) === null || _a === void 0 ? void 0 : _a.focus();
95
+ }, 0);
96
+ return (0, jsx_runtime_1.jsx)(dropdown_1.Dropdown, {
97
+ content: (0, jsx_runtime_1.jsx)(calendar_1.TimePicker, {
98
+ size: constants_2.TIME_PICKER_SIZE_MAP[size],
99
+ value: selectedValue,
100
+ fitToContainer: false,
101
+ onChangeValue: handleChangeValue,
102
+ navigationStartRef: navigationStartRef,
103
+ onFocusLeave: closeDroplist,
104
+ showSeconds: showSeconds
105
+ }),
106
+ placement: placement,
107
+ widthStrategy: 'auto',
108
+ outsideClick: true,
109
+ triggerRef: localRef,
110
+ open: open,
111
+ onOpenChange: setOpen,
112
+ className: dropDownClassName,
113
+ "data-test-id": constants_1.CHIP_CHOICE_TEST_IDS.droplist,
114
+ children: (0, jsx_runtime_1.jsx)(ChipChoiceBase_1.ChipChoiceBase, Object.assign({}, rest, {
115
+ ref: localRef,
116
+ onClearButtonClick: clearValue,
117
+ value: selectedValue,
118
+ valueToRender: valueToRender,
119
+ size: size,
120
+ onKeyDown: handleOnKeyDown(focusNavigationStartItem)
121
+ }))
122
+ });
123
+ }
@@ -3,3 +3,4 @@ export * from './ChipChoiceSingle';
3
3
  export * from './ChipChoiceMultiple';
4
4
  export * from './ChipChoiceDate';
5
5
  export * from './ChipChoiceDateRange';
6
+ export * from './ChipChoiceTime';
@@ -26,4 +26,5 @@ __exportStar(require("./ChipChoiceCustom"), exports);
26
26
  __exportStar(require("./ChipChoiceSingle"), exports);
27
27
  __exportStar(require("./ChipChoiceMultiple"), exports);
28
28
  __exportStar(require("./ChipChoiceDate"), exports);
29
- __exportStar(require("./ChipChoiceDateRange"), exports);
29
+ __exportStar(require("./ChipChoiceDateRange"), exports);
30
+ __exportStar(require("./ChipChoiceTime"), exports);
@@ -1,4 +1,4 @@
1
- import { CalendarProps } from '@snack-uikit/calendar';
1
+ import { CalendarProps, TimePickerProps } from '@snack-uikit/calendar';
2
2
  import { DroplistProps } from '@snack-uikit/list';
3
3
  import { Size } from '../../types';
4
4
  export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
@@ -8,11 +8,14 @@ export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
8
8
  l: "xs";
9
9
  };
10
10
  export declare const CALENDAR_SIZE_MAP: Record<Size, CalendarProps['size']>;
11
+ export declare const TIME_PICKER_SIZE_MAP: Record<Size, TimePickerProps['size']>;
11
12
  export declare const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']>;
12
13
  export declare const CHIP_CHOICE_TYPE: {
13
14
  readonly Multiple: "multiple";
14
15
  readonly Date: "date";
16
+ readonly DateTime: "date-time";
15
17
  readonly DateRange: "date-range";
16
18
  readonly Single: "single";
17
19
  readonly Custom: "custom";
18
20
  };
21
+ export declare const DEFAULT_LOCALE: Intl.Locale;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.CHIP_CHOICE_TYPE = exports.DROPLIST_SIZE_MAP = exports.CALENDAR_SIZE_MAP = exports.BUTTON_CLEAR_VALUE_SIZE_MAP = void 0;
6
+ exports.DEFAULT_LOCALE = exports.CHIP_CHOICE_TYPE = exports.DROPLIST_SIZE_MAP = exports.TIME_PICKER_SIZE_MAP = exports.CALENDAR_SIZE_MAP = exports.BUTTON_CLEAR_VALUE_SIZE_MAP = void 0;
7
7
  const constants_1 = require("../../constants");
8
8
  exports.BUTTON_CLEAR_VALUE_SIZE_MAP = {
9
9
  [constants_1.SIZE.Xs]: constants_1.BUTTON_SIZE.Xxs,
@@ -17,6 +17,12 @@ exports.CALENDAR_SIZE_MAP = {
17
17
  [constants_1.SIZE.M]: 'm',
18
18
  [constants_1.SIZE.L]: 'm'
19
19
  };
20
+ exports.TIME_PICKER_SIZE_MAP = {
21
+ [constants_1.SIZE.Xs]: 's',
22
+ [constants_1.SIZE.S]: 's',
23
+ [constants_1.SIZE.M]: 'm',
24
+ [constants_1.SIZE.L]: 'l'
25
+ };
20
26
  exports.DROPLIST_SIZE_MAP = {
21
27
  [constants_1.SIZE.Xs]: 's',
22
28
  [constants_1.SIZE.S]: 's',
@@ -26,7 +32,9 @@ exports.DROPLIST_SIZE_MAP = {
26
32
  exports.CHIP_CHOICE_TYPE = {
27
33
  Multiple: 'multiple',
28
34
  Date: 'date',
35
+ DateTime: 'date-time',
29
36
  DateRange: 'date-range',
30
37
  Single: 'single',
31
38
  Custom: 'custom'
32
- };
39
+ };
40
+ exports.DEFAULT_LOCALE = new Intl.Locale('ru-RU');
@@ -1,11 +1,12 @@
1
- import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps, ChipChoiceMultiple, ChipChoiceSingle, CustomContentRenderProps } from './components';
1
+ import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps, ChipChoiceMultiple, ChipChoiceSingle, ChipChoiceTime, ChipChoiceTimeProps, CustomContentRenderProps } from './components';
2
2
  export type { FilterOption, ChipChoiceMultipleProps, ChipChoiceSingleProps, ContentRenderProps } from './types';
3
- export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps };
3
+ export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps, ChipChoiceTimeProps, };
4
4
  export declare namespace ChipChoice {
5
5
  const Custom: typeof ChipChoiceCustom;
6
6
  const Single: typeof ChipChoiceSingle;
7
7
  const Multiple: typeof ChipChoiceMultiple;
8
8
  const Date: typeof ChipChoiceDate;
9
9
  const DateRange: typeof ChipChoiceDateRange;
10
+ const Time: typeof ChipChoiceTime;
10
11
  }
11
12
  export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
@@ -12,6 +12,7 @@ var ChipChoice;
12
12
  ChipChoice.Multiple = components_1.ChipChoiceMultiple;
13
13
  ChipChoice.Date = components_1.ChipChoiceDate;
14
14
  ChipChoice.DateRange = components_1.ChipChoiceDateRange;
15
+ ChipChoice.Time = components_1.ChipChoiceTime;
15
16
  })(ChipChoice || (exports.ChipChoice = ChipChoice = {}));
16
17
  var utils_1 = require("./utils");
17
18
  Object.defineProperty(exports, "isAccordionOption", {
@@ -2,6 +2,7 @@ export declare const MAP_CHIP_TYPE_TO_COMPONENT: {
2
2
  single: typeof import("../../ChipChoice/components").ChipChoiceSingle;
3
3
  multiple: typeof import("../../ChipChoice/components").ChipChoiceMultiple;
4
4
  date: typeof import("../../ChipChoice/components").ChipChoiceDate;
5
+ "date-time": typeof import("../../ChipChoice/components").ChipChoiceDate;
5
6
  "date-range": typeof import("../../ChipChoice/components").ChipChoiceDateRange;
6
7
  custom: typeof import("../../ChipChoice/components").ChipChoiceCustom;
7
8
  };
@@ -10,6 +10,7 @@ exports.MAP_CHIP_TYPE_TO_COMPONENT = {
10
10
  [constants_1.CHIP_CHOICE_TYPE.Single]: ChipChoice_1.ChipChoice.Single,
11
11
  [constants_1.CHIP_CHOICE_TYPE.Multiple]: ChipChoice_1.ChipChoice.Multiple,
12
12
  [constants_1.CHIP_CHOICE_TYPE.Date]: ChipChoice_1.ChipChoice.Date,
13
+ [constants_1.CHIP_CHOICE_TYPE.DateTime]: ChipChoice_1.ChipChoice.Date,
13
14
  [constants_1.CHIP_CHOICE_TYPE.DateRange]: ChipChoice_1.ChipChoice.DateRange,
14
15
  [constants_1.CHIP_CHOICE_TYPE.Custom]: ChipChoice_1.ChipChoice.Custom
15
16
  };
@@ -15,6 +15,12 @@ type ChipChoiceSingleType = {
15
15
  type ChipChoiceDateType = {
16
16
  type: typeof CHIP_CHOICE_TYPE.Date;
17
17
  } & ChipChoiceDateProps;
18
+ type ChipChoiceDateTimeType = {
19
+ type: typeof CHIP_CHOICE_TYPE.DateTime;
20
+ } & Omit<ChipChoiceDateProps, 'mode'> & {
21
+ mode: 'date-time';
22
+ showSeconds?: boolean;
23
+ };
18
24
  type ChipChoiceDateRangeType = {
19
25
  type: typeof CHIP_CHOICE_TYPE.DateRange;
20
26
  } & ChipChoiceDateRangeProps;
@@ -23,7 +29,7 @@ type ChipChoiceCustomType = {
23
29
  } & ChipChoiceCustomProps;
24
30
  export type ChipChoiceProps = {
25
31
  id: string;
26
- } & (ChipChoiceMultipleType | ChipChoiceSingleType | ChipChoiceDateType | ChipChoiceDateRangeType | ChipChoiceCustomType);
32
+ } & (ChipChoiceMultipleType | ChipChoiceSingleType | ChipChoiceDateType | ChipChoiceDateTimeType | ChipChoiceDateRangeType | ChipChoiceCustomType);
27
33
  export type OmitBetter<T, K extends keyof any> = T extends any ? Pick<T, Exclude<keyof T, K>> : never;
28
34
  export type FilterValue = Parameters<ChipChoiceProps['onChange']>[number];
29
35
  export {};
@@ -1,6 +1,10 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CalendarProps } from '@snack-uikit/calendar';
3
3
  import { ChipChoiceCommonProps } from '../types';
4
+ type ChipChoiceDateWithSeconds = {
5
+ mode?: 'date-time';
6
+ showSeconds?: boolean;
7
+ };
4
8
  export type ChipChoiceDateProps = ChipChoiceCommonProps & {
5
9
  /** Значение компонента */
6
10
  value?: Date;
@@ -11,5 +15,8 @@ export type ChipChoiceDateProps = ChipChoiceCommonProps & {
11
15
  /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
12
16
  valueRender?(value?: Date): ReactNode;
13
17
  mode?: Exclude<CalendarProps['mode'], 'range'>;
14
- };
15
- export declare function ChipChoiceDate({ size, value, defaultValue, onChange, valueRender, dropDownClassName, mode, ...rest }: ChipChoiceDateProps): import("react/jsx-runtime").JSX.Element;
18
+ } & (ChipChoiceDateWithSeconds | {
19
+ mode?: 'date' | 'month';
20
+ });
21
+ export declare function ChipChoiceDate({ size, value, defaultValue, onChange, valueRender, dropDownClassName, mode, placement, widthStrategy, ...rest }: ChipChoiceDateProps): import("react/jsx-runtime").JSX.Element;
22
+ export {};
@@ -10,18 +10,20 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
- import { useCallback, useRef, useState } from 'react';
13
+ import { useCallback, useMemo, useRef, useState } from 'react';
14
14
  import { Calendar } from '@snack-uikit/calendar';
15
15
  import { Dropdown } from '@snack-uikit/dropdown';
16
16
  import { useLocale } from '@snack-uikit/locale';
17
17
  import { useValueControl } from '@snack-uikit/utils';
18
18
  import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
19
- import { CALENDAR_SIZE_MAP } from '../constants';
19
+ import { CALENDAR_SIZE_MAP, DEFAULT_LOCALE } from '../constants';
20
20
  import { useHandleOnKeyDown } from '../hooks';
21
21
  import { ChipChoiceBase } from './ChipChoiceBase';
22
22
  export function ChipChoiceDate(_a) {
23
- var { size = SIZE.S, value, defaultValue, onChange, valueRender, dropDownClassName, mode = 'date' } = _a, rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "mode"]);
23
+ var _b;
24
+ var { size = SIZE.S, value, defaultValue, onChange, valueRender, dropDownClassName, mode = 'date', placement, widthStrategy } = _a, rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "mode", "placement", "widthStrategy"]);
24
25
  const [selectedValue, setSelectedValue] = useValueControl({ value, defaultValue, onChange });
26
+ const showSeconds = mode === 'date-time' ? ((_b = rest.showSeconds) !== null && _b !== void 0 ? _b : true) : undefined;
25
27
  const localRef = useRef(null);
26
28
  const [open, setOpen] = useState(false);
27
29
  const handleOnKeyDown = useHandleOnKeyDown({ setOpen });
@@ -30,12 +32,35 @@ export function ChipChoiceDate(_a) {
30
32
  setTimeout(() => { var _a; return (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
31
33
  }, []);
32
34
  const { t } = useLocale('Chips');
33
- const valueToRender = valueRender
34
- ? valueRender(selectedValue)
35
- : (selectedValue && new Date(selectedValue).toLocaleDateString()) || t('allLabel');
35
+ const valueToRender = useMemo(() => {
36
+ if (valueRender) {
37
+ return valueRender(selectedValue);
38
+ }
39
+ if (!selectedValue)
40
+ return t('allLabel');
41
+ const date = new Date(selectedValue);
42
+ if (mode === 'date-time') {
43
+ return date.toLocaleString(DEFAULT_LOCALE, {
44
+ year: 'numeric',
45
+ month: 'numeric',
46
+ day: 'numeric',
47
+ hour: '2-digit',
48
+ minute: '2-digit',
49
+ second: showSeconds ? '2-digit' : undefined,
50
+ });
51
+ }
52
+ return date.toLocaleDateString(DEFAULT_LOCALE, {
53
+ year: 'numeric',
54
+ month: 'numeric',
55
+ day: mode === 'date' ? 'numeric' : undefined,
56
+ });
57
+ }, [mode, selectedValue, showSeconds, t, valueRender]);
36
58
  const clearValue = () => setSelectedValue(undefined);
37
- return (_jsx(Dropdown, { content: _jsx(Calendar, { mode: mode, size: CALENDAR_SIZE_MAP[size], value: selectedValue, onChangeValue: (value) => {
38
- setSelectedValue(value);
39
- closeDroplist();
40
- }, navigationStartRef: element => element === null || element === void 0 ? void 0 : element.focus(), onFocusLeave: closeDroplist }), outsideClick: true, triggerRef: localRef, open: open, onOpenChange: setOpen, className: dropDownClassName, "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: localRef, onClearButtonClick: clearValue, value: selectedValue, valueToRender: valueToRender, size: size, onKeyDown: handleOnKeyDown() })) }));
59
+ const handleChangeValue = useCallback((value) => {
60
+ setSelectedValue(value);
61
+ closeDroplist();
62
+ }, [closeDroplist, setSelectedValue]);
63
+ const navigationStartRef = useRef(null);
64
+ const focusNavigationStartItem = () => setTimeout(() => { var _a; return (_a = navigationStartRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
65
+ return (_jsx(Dropdown, { content: _jsx(Calendar, { mode: mode, size: CALENDAR_SIZE_MAP[size], value: selectedValue, fitToContainer: false, onChangeValue: handleChangeValue, navigationStartRef: navigationStartRef, onFocusLeave: closeDroplist, showSeconds: showSeconds, locale: DEFAULT_LOCALE }), placement: placement, widthStrategy: widthStrategy, outsideClick: true, triggerRef: localRef, open: open, onOpenChange: setOpen, className: dropDownClassName, "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: localRef, onClearButtonClick: clearValue, value: selectedValue, valueToRender: valueToRender, size: size, onKeyDown: handleOnKeyDown(focusNavigationStartItem) })) }));
41
66
  }
@@ -16,14 +16,14 @@ import { Calendar } from '@snack-uikit/calendar';
16
16
  import { Dropdown } from '@snack-uikit/dropdown';
17
17
  import { useLocale } from '@snack-uikit/locale';
18
18
  import { CHIP_CHOICE_TEST_IDS, DEFAULT_EMPTY_VALUE, SIZE } from '../../../constants';
19
- import { CALENDAR_SIZE_MAP } from '../constants';
19
+ import { CALENDAR_SIZE_MAP, DEFAULT_LOCALE } from '../constants';
20
20
  import { useHandleOnKeyDown } from '../hooks';
21
21
  import { ChipChoiceBase } from './ChipChoiceBase';
22
22
  function defaultRangeFormatter({ value, allLabel }) {
23
23
  if (!value || !value.length)
24
24
  return allLabel;
25
25
  const [from, to] = value;
26
- return `${from.toLocaleDateString()} ${DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString()}`;
26
+ return `${from.toLocaleDateString(DEFAULT_LOCALE)} ${DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString(DEFAULT_LOCALE)}`;
27
27
  }
28
28
  export function ChipChoiceDateRange(_a) {
29
29
  var { size = SIZE.S, value, defaultValue, onChange, valueRender, dropDownClassName } = _a, rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName"]);
@@ -43,7 +43,7 @@ export function ChipChoiceDateRange(_a) {
43
43
  return (_jsx(Dropdown, { content: _jsx(Calendar, { mode: 'range', size: CALENDAR_SIZE_MAP[size], value: selectedValue, onChangeValue: value => {
44
44
  setSelectedValue(value);
45
45
  closeDroplist();
46
- },
46
+ }, locale: DEFAULT_LOCALE,
47
47
  // bug with focus
48
48
  // navigationStartRef={element => element?.focus()}
49
49
  onFocusLeave: closeDroplist }), outsideClick: true, triggerRef: localRef, open: open, "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, onOpenChange: setOpen, className: dropDownClassName, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: localRef, onClearButtonClick: clearValue, value: selectedValue, valueToRender: valueToRender, size: size, onKeyDown: handleOnKeyDown() })) }));
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ import { TimePickerProps } from '@snack-uikit/calendar';
3
+ import { ChipChoiceCommonProps } from '../types';
4
+ type TimeValue = TimePickerProps['value'];
5
+ export type ChipChoiceTimeProps = Omit<ChipChoiceCommonProps, 'widthStrategy'> & Pick<TimePickerProps, 'value' | 'defaultValue' | 'showSeconds'> & {
6
+ /** Колбек смены значения */
7
+ onChange?(value: TimeValue): void;
8
+ /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
9
+ valueRender?(value?: TimeValue): ReactNode;
10
+ };
11
+ export declare function ChipChoiceTime({ size, value, defaultValue, onChange, valueRender, dropDownClassName, showSeconds, placement, ...rest }: ChipChoiceTimeProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,64 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { useCallback, useMemo, useRef, useState } from 'react';
14
+ import { TimePicker } from '@snack-uikit/calendar';
15
+ import { Dropdown } from '@snack-uikit/dropdown';
16
+ import { useLocale } from '@snack-uikit/locale';
17
+ import { useValueControl } from '@snack-uikit/utils';
18
+ import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
19
+ import { DEFAULT_LOCALE, TIME_PICKER_SIZE_MAP } from '../constants';
20
+ import { useHandleOnKeyDown } from '../hooks';
21
+ import { ChipChoiceBase } from './ChipChoiceBase';
22
+ const getStringTimeValue = (time, { showSeconds, locale }) => {
23
+ var _a, _b, _c;
24
+ if (!time) {
25
+ return '';
26
+ }
27
+ const date = new Date();
28
+ date.setHours((_a = time.hours) !== null && _a !== void 0 ? _a : 0);
29
+ date.setMinutes((_b = time.minutes) !== null && _b !== void 0 ? _b : 0);
30
+ date.setSeconds((_c = time.seconds) !== null && _c !== void 0 ? _c : 0);
31
+ return date.toLocaleTimeString(locale, {
32
+ hour: 'numeric',
33
+ minute: 'numeric',
34
+ second: showSeconds ? 'numeric' : undefined,
35
+ });
36
+ };
37
+ export function ChipChoiceTime(_a) {
38
+ var { size = SIZE.S, value, defaultValue, onChange, valueRender, dropDownClassName, showSeconds = true, placement } = _a, rest = __rest(_a, ["size", "value", "defaultValue", "onChange", "valueRender", "dropDownClassName", "showSeconds", "placement"]);
39
+ const [selectedValue, setSelectedValue] = useValueControl({ value, defaultValue, onChange });
40
+ const localRef = useRef(null);
41
+ const [open, setOpen] = useState(false);
42
+ const handleOnKeyDown = useHandleOnKeyDown({ setOpen });
43
+ const closeDroplist = useCallback(() => {
44
+ setOpen(false);
45
+ setTimeout(() => { var _a; return (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
46
+ }, []);
47
+ const { t } = useLocale('Chips');
48
+ const valueToRender = useMemo(() => {
49
+ if (valueRender) {
50
+ return valueRender(selectedValue);
51
+ }
52
+ if (!selectedValue)
53
+ return t('allLabel');
54
+ return getStringTimeValue(selectedValue, { showSeconds, locale: DEFAULT_LOCALE });
55
+ }, [selectedValue, showSeconds, t, valueRender]);
56
+ const clearValue = () => setSelectedValue(undefined);
57
+ const handleChangeValue = useCallback((value) => {
58
+ setSelectedValue(value);
59
+ closeDroplist();
60
+ }, [closeDroplist, setSelectedValue]);
61
+ const navigationStartRef = useRef(null);
62
+ const focusNavigationStartItem = () => setTimeout(() => { var _a; return (_a = navigationStartRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
63
+ return (_jsx(Dropdown, { content: _jsx(TimePicker, { size: TIME_PICKER_SIZE_MAP[size], value: selectedValue, fitToContainer: false, onChangeValue: handleChangeValue, navigationStartRef: navigationStartRef, onFocusLeave: closeDroplist, showSeconds: showSeconds }), placement: placement, widthStrategy: 'auto', outsideClick: true, triggerRef: localRef, open: open, onOpenChange: setOpen, className: dropDownClassName, "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: localRef, onClearButtonClick: clearValue, value: selectedValue, valueToRender: valueToRender, size: size, onKeyDown: handleOnKeyDown(focusNavigationStartItem) })) }));
64
+ }
@@ -3,3 +3,4 @@ export * from './ChipChoiceSingle';
3
3
  export * from './ChipChoiceMultiple';
4
4
  export * from './ChipChoiceDate';
5
5
  export * from './ChipChoiceDateRange';
6
+ export * from './ChipChoiceTime';
@@ -3,3 +3,4 @@ export * from './ChipChoiceSingle';
3
3
  export * from './ChipChoiceMultiple';
4
4
  export * from './ChipChoiceDate';
5
5
  export * from './ChipChoiceDateRange';
6
+ export * from './ChipChoiceTime';
@@ -1,4 +1,4 @@
1
- import { CalendarProps } from '@snack-uikit/calendar';
1
+ import { CalendarProps, TimePickerProps } from '@snack-uikit/calendar';
2
2
  import { DroplistProps } from '@snack-uikit/list';
3
3
  import { Size } from '../../types';
4
4
  export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
@@ -8,11 +8,14 @@ export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
8
8
  l: "xs";
9
9
  };
10
10
  export declare const CALENDAR_SIZE_MAP: Record<Size, CalendarProps['size']>;
11
+ export declare const TIME_PICKER_SIZE_MAP: Record<Size, TimePickerProps['size']>;
11
12
  export declare const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']>;
12
13
  export declare const CHIP_CHOICE_TYPE: {
13
14
  readonly Multiple: "multiple";
14
15
  readonly Date: "date";
16
+ readonly DateTime: "date-time";
15
17
  readonly DateRange: "date-range";
16
18
  readonly Single: "single";
17
19
  readonly Custom: "custom";
18
20
  };
21
+ export declare const DEFAULT_LOCALE: Intl.Locale;
@@ -11,6 +11,12 @@ export const CALENDAR_SIZE_MAP = {
11
11
  [SIZE.M]: 'm',
12
12
  [SIZE.L]: 'm',
13
13
  };
14
+ export const TIME_PICKER_SIZE_MAP = {
15
+ [SIZE.Xs]: 's',
16
+ [SIZE.S]: 's',
17
+ [SIZE.M]: 'm',
18
+ [SIZE.L]: 'l',
19
+ };
14
20
  export const DROPLIST_SIZE_MAP = {
15
21
  [SIZE.Xs]: 's',
16
22
  [SIZE.S]: 's',
@@ -20,7 +26,9 @@ export const DROPLIST_SIZE_MAP = {
20
26
  export const CHIP_CHOICE_TYPE = {
21
27
  Multiple: 'multiple',
22
28
  Date: 'date',
29
+ DateTime: 'date-time',
23
30
  DateRange: 'date-range',
24
31
  Single: 'single',
25
32
  Custom: 'custom',
26
33
  };
34
+ export const DEFAULT_LOCALE = new Intl.Locale('ru-RU');
@@ -1,11 +1,12 @@
1
- import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps, ChipChoiceMultiple, ChipChoiceSingle, CustomContentRenderProps } from './components';
1
+ import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps, ChipChoiceMultiple, ChipChoiceSingle, ChipChoiceTime, ChipChoiceTimeProps, CustomContentRenderProps } from './components';
2
2
  export type { FilterOption, ChipChoiceMultipleProps, ChipChoiceSingleProps, ContentRenderProps } from './types';
3
- export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps };
3
+ export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps, ChipChoiceTimeProps, };
4
4
  export declare namespace ChipChoice {
5
5
  const Custom: typeof ChipChoiceCustom;
6
6
  const Single: typeof ChipChoiceSingle;
7
7
  const Multiple: typeof ChipChoiceMultiple;
8
8
  const Date: typeof ChipChoiceDate;
9
9
  const DateRange: typeof ChipChoiceDateRange;
10
+ const Time: typeof ChipChoiceTime;
10
11
  }
11
12
  export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
@@ -1,4 +1,4 @@
1
- import { ChipChoiceCustom, ChipChoiceDate, ChipChoiceDateRange, ChipChoiceMultiple, ChipChoiceSingle, } from './components';
1
+ import { ChipChoiceCustom, ChipChoiceDate, ChipChoiceDateRange, ChipChoiceMultiple, ChipChoiceSingle, ChipChoiceTime, } from './components';
2
2
  export var ChipChoice;
3
3
  (function (ChipChoice) {
4
4
  ChipChoice.Custom = ChipChoiceCustom;
@@ -6,5 +6,6 @@ export var ChipChoice;
6
6
  ChipChoice.Multiple = ChipChoiceMultiple;
7
7
  ChipChoice.Date = ChipChoiceDate;
8
8
  ChipChoice.DateRange = ChipChoiceDateRange;
9
+ ChipChoice.Time = ChipChoiceTime;
9
10
  })(ChipChoice || (ChipChoice = {}));
10
11
  export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
@@ -2,6 +2,7 @@ export declare const MAP_CHIP_TYPE_TO_COMPONENT: {
2
2
  single: typeof import("../../ChipChoice/components").ChipChoiceSingle;
3
3
  multiple: typeof import("../../ChipChoice/components").ChipChoiceMultiple;
4
4
  date: typeof import("../../ChipChoice/components").ChipChoiceDate;
5
+ "date-time": typeof import("../../ChipChoice/components").ChipChoiceDate;
5
6
  "date-range": typeof import("../../ChipChoice/components").ChipChoiceDateRange;
6
7
  custom: typeof import("../../ChipChoice/components").ChipChoiceCustom;
7
8
  };
@@ -4,6 +4,7 @@ export const MAP_CHIP_TYPE_TO_COMPONENT = {
4
4
  [CHIP_CHOICE_TYPE.Single]: ChipChoice.Single,
5
5
  [CHIP_CHOICE_TYPE.Multiple]: ChipChoice.Multiple,
6
6
  [CHIP_CHOICE_TYPE.Date]: ChipChoice.Date,
7
+ [CHIP_CHOICE_TYPE.DateTime]: ChipChoice.Date,
7
8
  [CHIP_CHOICE_TYPE.DateRange]: ChipChoice.DateRange,
8
9
  [CHIP_CHOICE_TYPE.Custom]: ChipChoice.Custom,
9
10
  };
@@ -15,6 +15,12 @@ type ChipChoiceSingleType = {
15
15
  type ChipChoiceDateType = {
16
16
  type: typeof CHIP_CHOICE_TYPE.Date;
17
17
  } & ChipChoiceDateProps;
18
+ type ChipChoiceDateTimeType = {
19
+ type: typeof CHIP_CHOICE_TYPE.DateTime;
20
+ } & Omit<ChipChoiceDateProps, 'mode'> & {
21
+ mode: 'date-time';
22
+ showSeconds?: boolean;
23
+ };
18
24
  type ChipChoiceDateRangeType = {
19
25
  type: typeof CHIP_CHOICE_TYPE.DateRange;
20
26
  } & ChipChoiceDateRangeProps;
@@ -23,7 +29,7 @@ type ChipChoiceCustomType = {
23
29
  } & ChipChoiceCustomProps;
24
30
  export type ChipChoiceProps = {
25
31
  id: string;
26
- } & (ChipChoiceMultipleType | ChipChoiceSingleType | ChipChoiceDateType | ChipChoiceDateRangeType | ChipChoiceCustomType);
32
+ } & (ChipChoiceMultipleType | ChipChoiceSingleType | ChipChoiceDateType | ChipChoiceDateTimeType | ChipChoiceDateRangeType | ChipChoiceCustomType);
27
33
  export type OmitBetter<T, K extends keyof any> = T extends any ? Pick<T, Exclude<keyof T, K>> : never;
28
34
  export type FilterValue = Parameters<ChipChoiceProps['onChange']>[number];
29
35
  export {};
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Chips",
7
- "version": "0.18.0",
7
+ "version": "0.19.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -36,12 +36,12 @@
36
36
  "license": "Apache-2.0",
37
37
  "scripts": {},
38
38
  "dependencies": {
39
- "@snack-uikit/button": "0.19.0",
40
- "@snack-uikit/calendar": "0.10.0",
39
+ "@snack-uikit/button": "0.19.1",
40
+ "@snack-uikit/calendar": "0.11.0",
41
41
  "@snack-uikit/dropdown": "0.4.0",
42
42
  "@snack-uikit/icons": "0.24.0",
43
- "@snack-uikit/list": "0.20.0",
44
- "@snack-uikit/loaders": "0.7.0",
43
+ "@snack-uikit/list": "0.21.0",
44
+ "@snack-uikit/loaders": "0.7.1",
45
45
  "@snack-uikit/utils": "3.5.0",
46
46
  "classnames": "2.3.2",
47
47
  "fuzzy-search": "3.2.1",
@@ -54,5 +54,5 @@
54
54
  "peerDependencies": {
55
55
  "@snack-uikit/locale": "*"
56
56
  },
57
- "gitHead": "8499829efa0c118b704de17411ae2328a024adb5"
57
+ "gitHead": "b7163c6f939105eb34cabec64c9e983ac7958c26"
58
58
  }
@@ -1,4 +1,4 @@
1
- import { ReactNode, useCallback, useRef, useState } from 'react';
1
+ import { ReactNode, useCallback, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Calendar, CalendarProps } from '@snack-uikit/calendar';
4
4
  import { Dropdown } from '@snack-uikit/dropdown';
@@ -6,11 +6,16 @@ import { useLocale } from '@snack-uikit/locale';
6
6
  import { useValueControl } from '@snack-uikit/utils';
7
7
 
8
8
  import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
9
- import { CALENDAR_SIZE_MAP } from '../constants';
9
+ import { CALENDAR_SIZE_MAP, DEFAULT_LOCALE } from '../constants';
10
10
  import { useHandleOnKeyDown } from '../hooks';
11
11
  import { ChipChoiceCommonProps } from '../types';
12
12
  import { ChipChoiceBase } from './ChipChoiceBase';
13
13
 
14
+ type ChipChoiceDateWithSeconds = {
15
+ mode?: 'date-time';
16
+ showSeconds?: boolean;
17
+ };
18
+
14
19
  export type ChipChoiceDateProps = ChipChoiceCommonProps & {
15
20
  /** Значение компонента */
16
21
  value?: Date;
@@ -21,7 +26,12 @@ export type ChipChoiceDateProps = ChipChoiceCommonProps & {
21
26
  /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
22
27
  valueRender?(value?: Date): ReactNode;
23
28
  mode?: Exclude<CalendarProps['mode'], 'range'>;
24
- };
29
+ } & (
30
+ | ChipChoiceDateWithSeconds
31
+ | {
32
+ mode?: 'date' | 'month';
33
+ }
34
+ );
25
35
 
26
36
  export function ChipChoiceDate({
27
37
  size = SIZE.S,
@@ -31,10 +41,14 @@ export function ChipChoiceDate({
31
41
  valueRender,
32
42
  dropDownClassName,
33
43
  mode = 'date',
44
+ placement,
45
+ widthStrategy,
34
46
  ...rest
35
47
  }: ChipChoiceDateProps) {
36
48
  const [selectedValue, setSelectedValue] = useValueControl<Date>({ value, defaultValue, onChange });
37
49
 
50
+ const showSeconds = mode === 'date-time' ? ((rest as ChipChoiceDateWithSeconds).showSeconds ?? true) : undefined;
51
+
38
52
  const localRef = useRef<HTMLDivElement>(null);
39
53
 
40
54
  const [open, setOpen] = useState<boolean>(false);
@@ -47,12 +61,46 @@ export function ChipChoiceDate({
47
61
 
48
62
  const { t } = useLocale('Chips');
49
63
 
50
- const valueToRender = valueRender
51
- ? valueRender(selectedValue)
52
- : (selectedValue && new Date(selectedValue).toLocaleDateString()) || t('allLabel');
64
+ const valueToRender = useMemo(() => {
65
+ if (valueRender) {
66
+ return valueRender(selectedValue);
67
+ }
68
+
69
+ if (!selectedValue) return t('allLabel');
70
+
71
+ const date = new Date(selectedValue);
72
+
73
+ if (mode === 'date-time') {
74
+ return date.toLocaleString(DEFAULT_LOCALE, {
75
+ year: 'numeric',
76
+ month: 'numeric',
77
+ day: 'numeric',
78
+ hour: '2-digit',
79
+ minute: '2-digit',
80
+ second: showSeconds ? '2-digit' : undefined,
81
+ });
82
+ }
83
+
84
+ return date.toLocaleDateString(DEFAULT_LOCALE, {
85
+ year: 'numeric',
86
+ month: 'numeric',
87
+ day: mode === 'date' ? 'numeric' : undefined,
88
+ });
89
+ }, [mode, selectedValue, showSeconds, t, valueRender]);
53
90
 
54
91
  const clearValue = () => setSelectedValue(undefined);
55
92
 
93
+ const handleChangeValue = useCallback(
94
+ (value: Date) => {
95
+ setSelectedValue(value);
96
+ closeDroplist();
97
+ },
98
+ [closeDroplist, setSelectedValue],
99
+ );
100
+
101
+ const navigationStartRef = useRef<HTMLButtonElement>(null);
102
+ const focusNavigationStartItem = () => setTimeout(() => navigationStartRef.current?.focus(), 0);
103
+
56
104
  return (
57
105
  <Dropdown
58
106
  content={
@@ -60,14 +108,16 @@ export function ChipChoiceDate({
60
108
  mode={mode}
61
109
  size={CALENDAR_SIZE_MAP[size]}
62
110
  value={selectedValue}
63
- onChangeValue={(value: Date) => {
64
- setSelectedValue(value);
65
- closeDroplist();
66
- }}
67
- navigationStartRef={element => element?.focus()}
111
+ fitToContainer={false}
112
+ onChangeValue={handleChangeValue}
113
+ navigationStartRef={navigationStartRef}
68
114
  onFocusLeave={closeDroplist}
115
+ showSeconds={showSeconds}
116
+ locale={DEFAULT_LOCALE}
69
117
  />
70
118
  }
119
+ placement={placement}
120
+ widthStrategy={widthStrategy}
71
121
  outsideClick
72
122
  triggerRef={localRef}
73
123
  open={open}
@@ -82,7 +132,7 @@ export function ChipChoiceDate({
82
132
  value={selectedValue}
83
133
  valueToRender={valueToRender}
84
134
  size={size}
85
- onKeyDown={handleOnKeyDown()}
135
+ onKeyDown={handleOnKeyDown(focusNavigationStartItem)}
86
136
  />
87
137
  </Dropdown>
88
138
  );
@@ -6,7 +6,7 @@ import { Dropdown } from '@snack-uikit/dropdown';
6
6
  import { useLocale } from '@snack-uikit/locale';
7
7
 
8
8
  import { CHIP_CHOICE_TEST_IDS, DEFAULT_EMPTY_VALUE, SIZE } from '../../../constants';
9
- import { CALENDAR_SIZE_MAP } from '../constants';
9
+ import { CALENDAR_SIZE_MAP, DEFAULT_LOCALE } from '../constants';
10
10
  import { useHandleOnKeyDown } from '../hooks';
11
11
  import { ChipChoiceCommonProps } from '../types';
12
12
  import { ChipChoiceBase } from './ChipChoiceBase';
@@ -34,7 +34,7 @@ function defaultRangeFormatter({ value, allLabel }: DefaultRangeFormatterProps)
34
34
 
35
35
  const [from, to] = value;
36
36
 
37
- return `${from.toLocaleDateString()} ${DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString()}`;
37
+ return `${from.toLocaleDateString(DEFAULT_LOCALE)} ${DEFAULT_EMPTY_VALUE} ${to.toLocaleDateString(DEFAULT_LOCALE)}`;
38
38
  }
39
39
 
40
40
  export function ChipChoiceDateRange({
@@ -78,6 +78,7 @@ export function ChipChoiceDateRange({
78
78
  setSelectedValue(value);
79
79
  closeDroplist();
80
80
  }}
81
+ locale={DEFAULT_LOCALE}
81
82
  // bug with focus
82
83
  // navigationStartRef={element => element?.focus()}
83
84
  onFocusLeave={closeDroplist}
@@ -0,0 +1,125 @@
1
+ import { ReactNode, useCallback, useMemo, useRef, useState } from 'react';
2
+
3
+ import { TimePicker, TimePickerProps } from '@snack-uikit/calendar';
4
+ import { Dropdown } from '@snack-uikit/dropdown';
5
+ import { useLocale } from '@snack-uikit/locale';
6
+ import { useValueControl } from '@snack-uikit/utils';
7
+
8
+ import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
9
+ import { DEFAULT_LOCALE, TIME_PICKER_SIZE_MAP } from '../constants';
10
+ import { useHandleOnKeyDown } from '../hooks';
11
+ import { ChipChoiceCommonProps } from '../types';
12
+ import { ChipChoiceBase } from './ChipChoiceBase';
13
+
14
+ const getStringTimeValue = (
15
+ time: TimePickerProps['value'],
16
+ { showSeconds, locale }: Pick<TimePickerProps, 'showSeconds'> & { locale: Intl.Locale },
17
+ ) => {
18
+ if (!time) {
19
+ return '';
20
+ }
21
+
22
+ const date = new Date();
23
+ date.setHours(time.hours ?? 0);
24
+ date.setMinutes(time.minutes ?? 0);
25
+ date.setSeconds(time.seconds ?? 0);
26
+
27
+ return date.toLocaleTimeString(locale, {
28
+ hour: 'numeric',
29
+ minute: 'numeric',
30
+ second: showSeconds ? 'numeric' : undefined,
31
+ });
32
+ };
33
+
34
+ type TimeValue = TimePickerProps['value'];
35
+
36
+ export type ChipChoiceTimeProps = Omit<ChipChoiceCommonProps, 'widthStrategy'> &
37
+ Pick<TimePickerProps, 'value' | 'defaultValue' | 'showSeconds'> & {
38
+ /** Колбек смены значения */
39
+ onChange?(value: TimeValue): void;
40
+ /** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение */
41
+ valueRender?(value?: TimeValue): ReactNode;
42
+ };
43
+
44
+ export function ChipChoiceTime({
45
+ size = SIZE.S,
46
+ value,
47
+ defaultValue,
48
+ onChange,
49
+ valueRender,
50
+ dropDownClassName,
51
+ showSeconds = true,
52
+ placement,
53
+ ...rest
54
+ }: ChipChoiceTimeProps) {
55
+ const [selectedValue, setSelectedValue] = useValueControl<TimeValue>({ value, defaultValue, onChange });
56
+
57
+ const localRef = useRef<HTMLDivElement>(null);
58
+
59
+ const [open, setOpen] = useState<boolean>(false);
60
+ const handleOnKeyDown = useHandleOnKeyDown({ setOpen });
61
+
62
+ const closeDroplist = useCallback(() => {
63
+ setOpen(false);
64
+ setTimeout(() => localRef.current?.focus(), 0);
65
+ }, []);
66
+
67
+ const { t } = useLocale('Chips');
68
+
69
+ const valueToRender = useMemo(() => {
70
+ if (valueRender) {
71
+ return valueRender(selectedValue);
72
+ }
73
+
74
+ if (!selectedValue) return t('allLabel');
75
+
76
+ return getStringTimeValue(selectedValue, { showSeconds, locale: DEFAULT_LOCALE });
77
+ }, [selectedValue, showSeconds, t, valueRender]);
78
+
79
+ const clearValue = () => setSelectedValue(undefined);
80
+
81
+ const handleChangeValue = useCallback(
82
+ (value: TimeValue) => {
83
+ setSelectedValue(value);
84
+ closeDroplist();
85
+ },
86
+ [closeDroplist, setSelectedValue],
87
+ );
88
+
89
+ const navigationStartRef = useRef<HTMLButtonElement>(null);
90
+ const focusNavigationStartItem = () => setTimeout(() => navigationStartRef.current?.focus(), 0);
91
+
92
+ return (
93
+ <Dropdown
94
+ content={
95
+ <TimePicker
96
+ size={TIME_PICKER_SIZE_MAP[size]}
97
+ value={selectedValue}
98
+ fitToContainer={false}
99
+ onChangeValue={handleChangeValue}
100
+ navigationStartRef={navigationStartRef}
101
+ onFocusLeave={closeDroplist}
102
+ showSeconds={showSeconds}
103
+ />
104
+ }
105
+ placement={placement}
106
+ widthStrategy='auto'
107
+ outsideClick
108
+ triggerRef={localRef}
109
+ open={open}
110
+ onOpenChange={setOpen}
111
+ className={dropDownClassName}
112
+ data-test-id={CHIP_CHOICE_TEST_IDS.droplist}
113
+ >
114
+ <ChipChoiceBase
115
+ {...rest}
116
+ ref={localRef}
117
+ onClearButtonClick={clearValue}
118
+ value={selectedValue}
119
+ valueToRender={valueToRender}
120
+ size={size}
121
+ onKeyDown={handleOnKeyDown(focusNavigationStartItem)}
122
+ />
123
+ </Dropdown>
124
+ );
125
+ }
@@ -3,3 +3,4 @@ export * from './ChipChoiceSingle';
3
3
  export * from './ChipChoiceMultiple';
4
4
  export * from './ChipChoiceDate';
5
5
  export * from './ChipChoiceDateRange';
6
+ export * from './ChipChoiceTime';
@@ -1,4 +1,4 @@
1
- import { CalendarProps } from '@snack-uikit/calendar';
1
+ import { CalendarProps, TimePickerProps } from '@snack-uikit/calendar';
2
2
  import { DroplistProps } from '@snack-uikit/list';
3
3
 
4
4
  import { BUTTON_SIZE, SIZE } from '../../constants';
@@ -18,6 +18,13 @@ export const CALENDAR_SIZE_MAP: Record<Size, CalendarProps['size']> = {
18
18
  [SIZE.L]: 'm',
19
19
  };
20
20
 
21
+ export const TIME_PICKER_SIZE_MAP: Record<Size, TimePickerProps['size']> = {
22
+ [SIZE.Xs]: 's',
23
+ [SIZE.S]: 's',
24
+ [SIZE.M]: 'm',
25
+ [SIZE.L]: 'l',
26
+ };
27
+
21
28
  export const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']> = {
22
29
  [SIZE.Xs]: 's',
23
30
  [SIZE.S]: 's',
@@ -28,7 +35,10 @@ export const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']> = {
28
35
  export const CHIP_CHOICE_TYPE = {
29
36
  Multiple: 'multiple',
30
37
  Date: 'date',
38
+ DateTime: 'date-time',
31
39
  DateRange: 'date-range',
32
40
  Single: 'single',
33
41
  Custom: 'custom',
34
42
  } as const;
43
+
44
+ export const DEFAULT_LOCALE = new Intl.Locale('ru-RU');
@@ -7,11 +7,19 @@ import {
7
7
  ChipChoiceDateRangeProps,
8
8
  ChipChoiceMultiple,
9
9
  ChipChoiceSingle,
10
+ ChipChoiceTime,
11
+ ChipChoiceTimeProps,
10
12
  CustomContentRenderProps,
11
13
  } from './components';
12
14
 
13
15
  export type { FilterOption, ChipChoiceMultipleProps, ChipChoiceSingleProps, ContentRenderProps } from './types';
14
- export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps };
16
+ export type {
17
+ ChipChoiceCustomProps,
18
+ ChipChoiceDateProps,
19
+ ChipChoiceDateRangeProps,
20
+ CustomContentRenderProps,
21
+ ChipChoiceTimeProps,
22
+ };
15
23
 
16
24
  export namespace ChipChoice {
17
25
  export const Custom = ChipChoiceCustom;
@@ -19,6 +27,7 @@ export namespace ChipChoice {
19
27
  export const Multiple = ChipChoiceMultiple;
20
28
  export const Date = ChipChoiceDate;
21
29
  export const DateRange = ChipChoiceDateRange;
30
+ export const Time = ChipChoiceTime;
22
31
  }
23
32
 
24
33
  export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
@@ -5,6 +5,7 @@ export const MAP_CHIP_TYPE_TO_COMPONENT = {
5
5
  [CHIP_CHOICE_TYPE.Single]: ChipChoice.Single,
6
6
  [CHIP_CHOICE_TYPE.Multiple]: ChipChoice.Multiple,
7
7
  [CHIP_CHOICE_TYPE.Date]: ChipChoice.Date,
8
+ [CHIP_CHOICE_TYPE.DateTime]: ChipChoice.Date,
8
9
  [CHIP_CHOICE_TYPE.DateRange]: ChipChoice.DateRange,
9
10
  [CHIP_CHOICE_TYPE.Custom]: ChipChoice.Custom,
10
11
  };
@@ -21,6 +21,10 @@ type ChipChoiceDateType = {
21
21
  type: typeof CHIP_CHOICE_TYPE.Date;
22
22
  } & ChipChoiceDateProps;
23
23
 
24
+ type ChipChoiceDateTimeType = {
25
+ type: typeof CHIP_CHOICE_TYPE.DateTime;
26
+ } & Omit<ChipChoiceDateProps, 'mode'> & { mode: 'date-time'; showSeconds?: boolean };
27
+
24
28
  type ChipChoiceDateRangeType = {
25
29
  type: typeof CHIP_CHOICE_TYPE.DateRange;
26
30
  } & ChipChoiceDateRangeProps;
@@ -35,6 +39,7 @@ export type ChipChoiceProps = {
35
39
  | ChipChoiceMultipleType
36
40
  | ChipChoiceSingleType
37
41
  | ChipChoiceDateType
42
+ | ChipChoiceDateTimeType
38
43
  | ChipChoiceDateRangeType
39
44
  | ChipChoiceCustomType
40
45
  );