@via-profit/ui-kit 0.2.1-alpha.1 → 0.2.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.
Files changed (143) hide show
  1. package/Autocomplete/AutocompleteContainer.d.ts +33 -6
  2. package/Autocomplete/AutocompleteContainer.js +48 -36
  3. package/Autocomplete/AutocompleteItem.d.ts +1 -1
  4. package/Autocomplete/AutocompleteTextField.d.ts +3 -0
  5. package/Autocomplete/AutocompleteTextField.js +63 -1
  6. package/Autocomplete/OverrideMenuList.d.ts +4 -0
  7. package/Autocomplete/OverrideMenuList.js +39 -0
  8. package/Autocomplete/context.d.ts +9 -1
  9. package/Autocomplete/context.js +15 -1
  10. package/Autocomplete/index.js +9 -10
  11. package/Autocomplete2/Autocomplete2.d.ts +12 -0
  12. package/Autocomplete2/Autocomplete2.js +83 -0
  13. package/Autocomplete2/Autocomplete2TextField.d.ts +7 -0
  14. package/Autocomplete2/Autocomplete2TextField.js +39 -0
  15. package/Autocomplete2/index.d.ts +2 -0
  16. package/Autocomplete2/index.js +7 -0
  17. package/Avatar/index.js +1 -1
  18. package/Badge/BadgeDeleteButton.js +6 -6
  19. package/Badge/BadgeOutlined.js +2 -2
  20. package/Badge/BadgeStandard.js +1 -1
  21. package/Button/ButtonOutlined.js +1 -1
  22. package/Button/ButtonPlain.js +1 -1
  23. package/Button/ButtonStandard.js +4 -11
  24. package/Calendar/CalendarCell.js +6 -2
  25. package/Calendar/CalendarComponent.d.ts +226 -0
  26. package/Calendar/CalendarComponent.js +572 -0
  27. package/Calendar/CalendarControlButton.js +16 -9
  28. package/Calendar/CalendarDayBadge.js +1 -1
  29. package/Calendar/CalendarEmptyCell.d.ts +2 -2
  30. package/Calendar/CalendarEmptyCell.js +8 -3
  31. package/Calendar/CalendarHeading.js +2 -1
  32. package/Calendar/CalendarSubheading.js +3 -2
  33. package/Calendar/CalendarWeekDayCell.d.ts +10 -0
  34. package/Calendar/CalendarWeekDayCell.js +32 -0
  35. package/Calendar/CalendarWeekDayWeekNumber.d.ts +7 -0
  36. package/Calendar/CalendarWeekDayWeekNumber.js +38 -0
  37. package/Calendar/CalendarWeekRow.d.ts +2 -2
  38. package/Calendar/CalendarWeekRow.js +2 -1
  39. package/Calendar/CalendarWeekRowButton.d.ts +13 -0
  40. package/Calendar/CalendarWeekRowButton.js +31 -0
  41. package/Calendar/CalendarYearsSelector.d.ts +39 -1
  42. package/Calendar/CalendarYearsSelector.js +52 -16
  43. package/Calendar/IconChevronDown.d.ts +3 -0
  44. package/Calendar/IconChevronDown.js +31 -0
  45. package/Calendar/index.d.ts +7 -224
  46. package/Calendar/index.js +19 -281
  47. package/Calendar/use-calendar.d.ts +1 -1
  48. package/Color/Color.d.ts +138 -0
  49. package/Color/Color.js +324 -0
  50. package/Color/ColorGenerator.d.ts +29 -0
  51. package/Color/ColorGenerator.js +141 -0
  52. package/Color/ColorParser.d.ts +20 -0
  53. package/Color/ColorParser.js +284 -0
  54. package/Color/index.d.ts +4 -122
  55. package/Color/index.js +18 -473
  56. package/CountryFlags/SwiperOverview.d.ts +257 -0
  57. package/CountryFlags/SwiperOverview.js +524 -0
  58. package/DatePicker/index.d.ts +2 -17
  59. package/DatePicker/index.js +47 -61
  60. package/DatePicker/useDatePickerFormat.js +5 -5
  61. package/ErrorBoundary/Fallback.d.ts +3 -0
  62. package/ErrorBoundary/Fallback.js +51 -0
  63. package/ErrorBoundary/RenderError.d.ts +6 -0
  64. package/ErrorBoundary/RenderError.js +80 -0
  65. package/ErrorBoundary/index.d.ts +7 -11
  66. package/ErrorBoundary/index.js +4 -51
  67. package/LoadingIndicator/Spinner.d.ts +5 -3
  68. package/LoadingIndicator/Spinner.js +61 -32
  69. package/LoadingIndicator/index.d.ts +3 -3
  70. package/LoadingIndicator/index.js +15 -2
  71. package/MaskedField/index.d.ts +2 -1
  72. package/MaskedField/index.js +52 -43
  73. package/MaskedField/useMasked.js +7 -5
  74. package/Menu/AutoHeightWrapper.d.ts +6 -0
  75. package/Menu/AutoHeightWrapper.js +43 -0
  76. package/Menu/MeasuredItem.d.ts +10 -0
  77. package/Menu/MeasuredItem.js +51 -0
  78. package/Menu/MenuContainer.d.ts +51 -18
  79. package/Menu/MenuContainer.js +19 -12
  80. package/Menu/MenuItem.d.ts +24 -7
  81. package/Menu/MenuItem.js +13 -6
  82. package/Menu/MenuList.d.ts +4 -2
  83. package/Menu/MenuList.js +26 -6
  84. package/Menu/VirtualizedItem.d.ts +22 -0
  85. package/Menu/VirtualizedItem.js +69 -0
  86. package/Menu/VirtualizedList.d.ts +18 -0
  87. package/Menu/VirtualizedList.js +28 -0
  88. package/Menu/VirtualizedListComponent.d.ts +20 -0
  89. package/Menu/VirtualizedListComponent.js +305 -0
  90. package/Menu/index.d.ts +3 -1
  91. package/Menu/index.js +2 -0
  92. package/Popper/Popper.d.ts +7 -80
  93. package/Popper/Popper.js +26 -12
  94. package/Popper/PopperContainer.js +1 -1
  95. package/Popper/usePopprer.d.ts +88 -3
  96. package/Popper/usePopprer.js +240 -65
  97. package/Selectbox/SelectboxButton.d.ts +5 -0
  98. package/Selectbox/SelectboxButton.js +48 -8
  99. package/Selectbox/SelectboxButtonWrapper.d.ts +2 -0
  100. package/Selectbox/SelectboxButtonWrapper.js +1 -17
  101. package/Selectbox/SelectboxMenu.d.ts +12 -0
  102. package/Selectbox/SelectboxMenu.js +50 -0
  103. package/Selectbox/index.d.ts +5 -5
  104. package/Selectbox/index.js +115 -97
  105. package/Surface/index.js +1 -1
  106. package/Swiper/Swiper.d.ts +57 -0
  107. package/Swiper/Swiper.js +412 -0
  108. package/Swiper/SwiperContainer.d.ts +7 -0
  109. package/Swiper/SwiperContainer.js +15 -0
  110. package/Swiper/SwiperSlide.d.ts +12 -0
  111. package/Swiper/SwiperSlide.js +58 -0
  112. package/Swiper/SwiperSlidesRenderer.d.ts +11 -0
  113. package/Swiper/SwiperSlidesRenderer.js +74 -0
  114. package/Swiper/SwiperTrack.d.ts +18 -0
  115. package/Swiper/SwiperTrack.js +55 -0
  116. package/Swiper/SwiperWrapper.d.ts +16 -0
  117. package/Swiper/SwiperWrapper.js +60 -0
  118. package/Swiper/index.d.ts +7 -0
  119. package/Swiper/index.js +26 -0
  120. package/Switch/SwitchDot.js +1 -1
  121. package/Switch/SwitchTrack.js +1 -1
  122. package/TextField/TextFieldContainer.d.ts +2 -2
  123. package/TextField/TextFieldContainer.js +5 -3
  124. package/TextField/TextFieldErrorText.d.ts +2 -2
  125. package/TextField/TextFieldErrorText.js +5 -4
  126. package/TextField/TextFieldIconWrapper.d.ts +3 -3
  127. package/TextField/TextFieldIconWrapper.js +5 -3
  128. package/TextField/TextFieldInput.d.ts +2 -2
  129. package/TextField/TextFieldInput.js +6 -4
  130. package/TextField/TextFieldInputWrapper.d.ts +2 -2
  131. package/TextField/TextFieldInputWrapper.js +5 -3
  132. package/TextField/TextFieldLabel.d.ts +2 -2
  133. package/TextField/TextFieldLabel.js +5 -3
  134. package/TextField/TextFieldLabelAsterisk.d.ts +2 -2
  135. package/TextField/TextFieldLabelAsterisk.js +5 -3
  136. package/TextField/index.d.ts +8 -1
  137. package/TextField/index.js +49 -22
  138. package/ThemeProvider/createTheme.js +2 -2
  139. package/package.json +1 -1
  140. package/Calendar/reducer.d.ts +0 -17
  141. package/Calendar/reducer.js +0 -50
  142. /package/Calendar/{IconChevronRight.d.ts → CalendarIconNext.d.ts} +0 -0
  143. /package/Calendar/{IconChevronRight.js → CalendarIconNext.js} +0 -0
@@ -1,4 +1,18 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  var __rest = (this && this.__rest) || function (s, e) {
3
17
  var t = {};
4
18
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -17,63 +31,58 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
31
  const react_1 = __importDefault(require("react"));
18
32
  const useMasked_1 = require("./useMasked");
19
33
  const TextField_1 = __importDefault(require("../TextField"));
34
+ __exportStar(require("./useMasked"), exports);
20
35
  const MaskedField = (props, ref) => {
21
36
  const { value: propValue, mask, parseInput, onChange, transform } = props, nativeProps = __rest(props, ["value", "mask", "parseInput", "onChange", "transform"]);
22
- const propValueRef = react_1.default.useRef(propValue);
23
- const textInputRef = react_1.default.useRef(null);
24
- const decoratorsErrorDisplayed = react_1.default.useRef(false);
25
37
  const masked = (0, useMasked_1.useMasked)();
26
38
  const parseInputFn = parseInput || masked.parseInput;
27
- const getMask = react_1.default.useCallback((input) => {
28
- const currentMask = typeof mask === 'function' ? mask(input) : mask;
29
- if (!decoratorsErrorDisplayed.current &&
30
- currentMask.find(elem => typeof elem === 'string' &&
31
- typeof parseInput === 'undefined' &&
32
- elem.match(/[0-9a-zа-яё]/i))) {
33
- decoratorsErrorDisplayed.current = true;
34
- console.warn(`[MaskedField component] You use symbols as decorators, which should be replaced with RegExp or provide the «parseInput» function instead`);
35
- }
36
- return currentMask;
37
- }, [mask, parseInput]);
39
+ const inputRef = react_1.default.useRef(null);
40
+ const lastPropValue = react_1.default.useRef(propValue);
41
+ const getMask = react_1.default.useCallback((input) => (typeof mask === 'function' ? mask(input) : mask), [mask]);
38
42
  const getInputValue = react_1.default.useCallback((v) => {
39
43
  var _a;
40
- const mask = getMask(v || '');
41
- const parsed = parseInputFn(v || '', mask, ((_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) || 0);
42
- const { text } = masked.formatParsedInput(parsed.text, mask, parsed.caret);
43
- return text;
44
- }, [getMask, masked, parseInputFn]);
44
+ const m = getMask(v);
45
+ const parsed = parseInputFn(v, m, ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) || 0);
46
+ const formatted = masked.formatParsedInput(parsed.text, m, parsed.caret);
47
+ return formatted.text;
48
+ }, [getMask, parseInputFn, masked]);
45
49
  const [inputValue, setInputValue] = react_1.default.useState(getInputValue(propValue || ''));
50
+ // Обновление при изменении внешнего значения
46
51
  react_1.default.useEffect(() => {
47
- if (propValueRef.current !== propValue) {
48
- propValueRef.current = propValue;
52
+ if (lastPropValue.current !== propValue) {
53
+ lastPropValue.current = propValue;
49
54
  setInputValue(getInputValue(propValue || ''));
50
55
  }
51
- }, [getInputValue, getMask, parseInputFn, masked, propValue]);
56
+ }, [propValue, getInputValue]);
52
57
  const handleOnChange = react_1.default.useCallback(event => {
53
58
  var _a;
54
- const mask = getMask(event.currentTarget.value);
55
- const parsed = parseInputFn(event.currentTarget.value, mask, ((_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) || 0);
56
- const { caret, isValid, text } = masked.formatParsedInput(parsed.text, mask, parsed.caret);
57
- const transformedText = transform ? transform(text) : text;
58
- setInputValue(transformedText);
59
+ const raw = event.currentTarget.value;
60
+ const caret = ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) || 0;
61
+ const m = getMask(raw);
62
+ const parsed = parseInputFn(raw, m, caret);
63
+ const formatted = masked.formatParsedInput(parsed.text, m, parsed.caret);
64
+ const finalText = transform ? transform(formatted.text) : formatted.text;
65
+ setInputValue(finalText);
59
66
  onChange({
60
- caret,
61
- isValid,
62
- text: transformedText,
67
+ caret: formatted.caret,
68
+ isValid: formatted.isValid,
69
+ text: finalText,
63
70
  });
64
- setTimeout(() => {
71
+ // Устанавливаем caret после рендера
72
+ requestAnimationFrame(() => {
65
73
  var _a;
66
- (_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(caret, caret);
67
- }, 15);
68
- }, [getMask, masked, transform, onChange, parseInputFn]);
69
- return (react_1.default.createElement(TextField_1.default, Object.assign({ ref: ref }, nativeProps, { type: "text", value: inputValue, onChange: handleOnChange, inputRef: elem => {
70
- textInputRef.current = elem;
71
- if (typeof nativeProps.inputRef === 'function') {
72
- nativeProps.inputRef(elem);
73
- }
74
- if (nativeProps.inputRef !== null && typeof nativeProps.inputRef === 'object') {
75
- nativeProps.inputRef.current = elem;
76
- }
77
- } })));
74
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(formatted.caret, formatted.caret);
75
+ });
76
+ }, [getMask, parseInputFn, masked, transform, onChange]);
77
+ const setInputRef = react_1.default.useCallback((elem) => {
78
+ inputRef.current = elem;
79
+ if (typeof nativeProps.inputRef === 'function') {
80
+ nativeProps.inputRef(elem);
81
+ }
82
+ else if (nativeProps.inputRef && typeof nativeProps.inputRef === 'object') {
83
+ nativeProps.inputRef.current = elem;
84
+ }
85
+ }, [nativeProps]);
86
+ return (react_1.default.createElement(TextField_1.default, Object.assign({ ref: ref }, nativeProps, { type: "text", value: inputValue, onChange: handleOnChange, inputRef: setInputRef })));
78
87
  };
79
88
  exports.default = react_1.default.forwardRef(MaskedField);
@@ -12,13 +12,12 @@ const useMasked = () => {
12
12
  caret: 0,
13
13
  };
14
14
  value
15
- .replace(/\s/, '')
15
+ .replace(/\s+/g, '')
16
16
  .split('')
17
17
  .forEach((character, charIndex) => {
18
18
  const isMatch = mask.some(pattern => {
19
19
  if (typeof pattern === 'string') {
20
- return false;
21
- // return character === pattern && character;
20
+ return character === pattern && character;
22
21
  }
23
22
  if (pattern instanceof RegExp) {
24
23
  return new RegExp(pattern).test(character);
@@ -45,7 +44,9 @@ const useMasked = () => {
45
44
  if (parsedValue === '') {
46
45
  return data;
47
46
  }
48
- for (let patternIndex = 0; patternIndex < mask.length; patternIndex++) {
47
+ let patternIndex = 0;
48
+ for (patternIndex = 0; patternIndex < mask.length; patternIndex++) {
49
+ data.isValid = false;
49
50
  if (data.charIndex >= parsedValue.length) {
50
51
  break;
51
52
  }
@@ -57,6 +58,7 @@ const useMasked = () => {
57
58
  if (pattern instanceof RegExp && new RegExp(pattern).test(char)) {
58
59
  data.text = `${data.text}${char}`;
59
60
  data.charIndex += 1;
61
+ data.isValid = true;
60
62
  }
61
63
  // If char is correct (equal with pattern string)
62
64
  // then accept char into text
@@ -79,7 +81,7 @@ const useMasked = () => {
79
81
  const result = {
80
82
  text: data.text,
81
83
  caret: data.caret,
82
- isValid: data.text.length >= mask.length,
84
+ isValid: data.isValid,
83
85
  };
84
86
  return result;
85
87
  }, []);
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export type AutoHeightWrapperProps = {
3
+ readonly children: (height: number) => React.ReactNode;
4
+ };
5
+ declare const AutoHeightWrapper: (props: AutoHeightWrapperProps) => React.JSX.Element;
6
+ export default AutoHeightWrapper;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const React = __importStar(require("react"));
27
+ const AutoHeightWrapper = (props) => {
28
+ const { children } = props;
29
+ const ref = React.useRef(null);
30
+ const [height, setHeight] = React.useState(0);
31
+ React.useLayoutEffect(() => {
32
+ const el = ref.current;
33
+ if (!el)
34
+ return;
35
+ const ro = new ResizeObserver(() => {
36
+ setHeight(el.clientHeight);
37
+ });
38
+ ro.observe(el);
39
+ return () => ro.disconnect();
40
+ }, []);
41
+ return (React.createElement("div", { "data-virt-elem": "AutoHeightWrapper", ref: ref, style: { height: '100%', overflow: 'hidden' } }, height > 0 && children(height)));
42
+ };
43
+ exports.default = AutoHeightWrapper;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export type MeasuredItemProps = {
3
+ readonly index: number;
4
+ readonly top: number;
5
+ readonly isFixed: boolean;
6
+ readonly updateHeight: (index: number, height: number) => void;
7
+ readonly children: React.ReactNode;
8
+ };
9
+ declare const MeasuredItem: React.FC<MeasuredItemProps>;
10
+ export default MeasuredItem;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const React = __importStar(require("react"));
27
+ const MeasuredItem = props => {
28
+ const { index, top, isFixed, updateHeight, children } = props;
29
+ const ref = React.useRef(null);
30
+ React.useLayoutEffect(() => {
31
+ if (isFixed)
32
+ return; // в фиксированном режиме измерять не нужно
33
+ const el = ref.current;
34
+ if (!el)
35
+ return;
36
+ const measure = () => {
37
+ const h = el.offsetHeight;
38
+ updateHeight(index, h);
39
+ };
40
+ measure();
41
+ const ro = new ResizeObserver(measure);
42
+ ro.observe(el);
43
+ return () => ro.disconnect();
44
+ }, [index, updateHeight, isFixed]);
45
+ return (React.createElement("div", { ref: ref, style: {
46
+ position: 'absolute',
47
+ top,
48
+ width: '100%',
49
+ } }, children));
50
+ };
51
+ exports.default = MeasuredItem;
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { MenuListProps } from './MenuList';
3
- import { AnchorPos, PopperProps } from '../Popper';
4
- import type { MenuItemCommonProps } from './MenuItem';
3
+ import { AnchorPos, PopperProps, PositionStrategy } from '../Popper';
4
+ import type { MenuItemProps } from './MenuItem';
5
5
  export type AnchorElement<E extends HTMLElement = HTMLElement> = E;
6
6
  export type Children<T> = (data: {
7
7
  item: T;
8
8
  index: number;
9
- }, itemProps: MenuItemCommonProps) => React.ReactNode;
9
+ }, itemProps: MenuItemProps) => React.ReactNode;
10
10
  export interface MenuProps<T, Multiple extends boolean | undefined = undefined> {
11
11
  /**
12
12
  * List of items
@@ -46,9 +46,9 @@ export interface MenuProps<T, Multiple extends boolean | undefined = undefined>
46
46
  /**
47
47
  * An HTML element. It's used to set the position of the menu.
48
48
  * \
49
- * **Default**: `false`
49
+ * **Default**: `null`
50
50
  */
51
- readonly anchorElement?: AnchorElement | null;
51
+ readonly anchorElement: AnchorElement | null;
52
52
  /**
53
53
  * A function that extract key for each item\
54
54
  * (for details: [React List and keys](https://react.dev/learn/rendering-lists))\
@@ -66,7 +66,7 @@ export interface MenuProps<T, Multiple extends boolean | undefined = undefined>
66
66
  * ```
67
67
  */
68
68
  /**
69
- * Close list if click outside of the list and anchor element\
69
+ * Close list if click outside the list and anchor element\
70
70
  * \
71
71
  * **Default**: `true`
72
72
  */
@@ -87,20 +87,52 @@ export interface MenuProps<T, Multiple extends boolean | undefined = undefined>
87
87
  /**
88
88
  * Anchor position\
89
89
  * \
90
- * Default: `auto`
90
+ * Default: `bottom`
91
91
  */
92
92
  readonly anchorPos?: AnchorPos;
93
+ readonly onAnchorPosChanged?: (anchorPos: AnchorPos) => void;
94
+ /**
95
+ * When enabled, the popper will automatically try to find the best placement
96
+ * if the preferred placement doesn't fit in the viewport.
97
+ * The component will iterate through possible placements until it finds one that fits.
98
+ *
99
+ * **Default**: `true`
100
+ * ```
101
+ */
102
+ readonly autoFlip?: boolean;
103
+ /**
104
+ * Additional offset (in pixels) from the anchor element.
105
+ * Positive values move the popper away from the anchor, negative values move it closer.
106
+ *
107
+ * @default `0`
108
+ * ```
109
+ */
110
+ readonly offset?: number;
111
+ /**
112
+ * The positioning strategy to use.
113
+ * - `'fixed'`: Positions relative to the viewport. Works reliably in all cases.
114
+ * - `'absolute'`: Positions relative to the nearest positioned ancestor.
115
+ * When using 'absolute', make sure a parent element has `position: relative`.
116
+ *
117
+ * **Default**: `'`absolute`'`
118
+ * ```
119
+ */
120
+ readonly positionStrategy?: PositionStrategy;
121
+ /**
122
+ * Minimum distance (in pixels) that the popper must maintain from the viewport edges.
123
+ * Used to prevent the popper from being positioned too close to the screen boundaries.
124
+ * The popper will try to flip to another placement if it cannot maintain this margin.
125
+ *
126
+ * **Default**: `8`
127
+ * ```
128
+ */
129
+ readonly viewportMargin?: number;
93
130
  /**
94
131
  * Should menu will be closed when item selected\
95
132
  * \
96
133
  * **Default**: if **multiple** is true then `false` otherwise - `true`
97
134
  */
98
135
  readonly closeOnSelect?: boolean;
99
- /**
100
- * Do not use react portal\
101
- * \
102
- * **Default**: `false`
103
- */
104
136
  /**
105
137
  * Popper z-index\
106
138
  * \
@@ -161,33 +193,34 @@ export type MenuRef = {
161
193
  */
162
194
  selectItem: (index: number) => void;
163
195
  /**
164
- * Hightlight specified item by index
196
+ * Highlight specified item by index
165
197
  */
166
198
  highlightIndex: (index: number) => void;
167
199
  /**
168
200
  * Highlight the previous item relative to the currently highlighted one
169
201
  */
170
- hightlightPrevItem: () => void;
202
+ highlightPrevItem: () => void;
171
203
  /**
172
204
  * Highlight the next item relative to the currently highlighted one
173
205
  */
174
- hightlightNextItem: () => void;
206
+ highlightNextItem: () => void;
175
207
  /**
176
208
  * Highlight the first item in list
177
209
  */
178
- hightlightFirstItem: () => void;
210
+ highlightFirstItem: () => void;
179
211
  /**
180
212
  * Highlight the last item in list
181
213
  */
182
- hightlightLastItem: () => void;
214
+ highlightLastItem: () => void;
183
215
  /**
184
216
  * Select highlighted item in list
185
217
  */
186
- selectHightlightedItem: () => void;
218
+ selectHighlightedItem: () => void;
187
219
  /**
188
220
  * Returns the list HTML container
189
221
  */
190
222
  getListElement: () => HTMLDivElement | null;
223
+ setActualPlacement: (placement: AnchorPos) => void;
191
224
  };
192
225
  export type Value<T, Multiple> = Multiple extends undefined | undefined ? T | null : readonly T[];
193
226
  export type GetOptionSelected<T> = (payload: {
@@ -33,7 +33,8 @@ const Popper_1 = __importDefault(require("../Popper"));
33
33
  const ClickOutside_1 = __importDefault(require("../ClickOutside"));
34
34
  const onRequestCloseDefault = () => undefined;
35
35
  const MenuContainer = react_1.default.forwardRef((props, ref) => {
36
- const { items, value, anchorElement, overrides, children, closeOutsideClick = true, isOpen = false, anchorPos = 'bottom', multiple = false, autofocus = true, closeOnSelect = !multiple, onRequestClose = onRequestCloseDefault, zIndex, onSelectItem, getOptionSelected, } = props;
36
+ const { items, value, anchorElement = null, overrides, children, closeOutsideClick = true, isOpen = false, anchorPos = 'bottom', positionStrategy, autoFlip, viewportMargin, offset, multiple = false, autofocus = true, closeOnSelect = !multiple, onRequestClose = onRequestCloseDefault, onAnchorPosChanged, zIndex, onSelectItem, getOptionSelected, } = props;
37
+ const [actualPlacement, setActualPlacement] = react_1.default.useState(anchorPos);
37
38
  const overridesMap = react_1.default.useMemo(() => ({
38
39
  List: (overrides === null || overrides === void 0 ? void 0 : overrides.List) || MenuList_1.default,
39
40
  Popper: (overrides === null || overrides === void 0 ? void 0 : overrides.Popper) || Popper_1.default,
@@ -187,14 +188,15 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
187
188
  focus: () => { var _a; return (_a = menuListRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
188
189
  scrollToIndex: (idx) => scrollToIndex(idx),
189
190
  highlightIndex: (idx) => highlightIndex(idx),
190
- hightlightPrevItem: () => hightlightPrevItem(),
191
- hightlightNextItem: () => hightlightNextItem(),
192
- hightlightFirstItem: () => hightlightFirstItem(),
193
- hightlightLastItem: () => hightlightLastItem(),
191
+ highlightPrevItem: () => hightlightPrevItem(),
192
+ highlightNextItem: () => hightlightNextItem(),
193
+ highlightFirstItem: () => hightlightFirstItem(),
194
+ highlightLastItem: () => hightlightLastItem(),
194
195
  scrollToFirstSelected: () => scrollToFirstSelected(),
195
- selectHightlightedItem: () => selectHightlightedItem(),
196
+ selectHighlightedItem: () => selectHightlightedItem(),
196
197
  selectItem: (idx) => selectItem(idx),
197
198
  getListElement: () => menuListRef.current,
199
+ setActualPlacement: placement => setActualPlacement(placement),
198
200
  }), [
199
201
  scrollToIndex,
200
202
  highlightIndex,
@@ -324,9 +326,9 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
324
326
  */
325
327
  react_1.default.useEffect(() => {
326
328
  const indexes = getSelectedIndexes();
327
- // If elements in selectedIndexesRef and indexes are not equale
328
- if ((selectedIndexesRef.current.length === indexes.length &&
329
- selectedIndexesRef.current.every(value => indexes.includes(value))) === false) {
329
+ // If elements in selectedIndexesRef and indexes are not equal
330
+ if (!(selectedIndexesRef.current.length === indexes.length &&
331
+ selectedIndexesRef.current.every(value => indexes.includes(value)))) {
330
332
  selectedIndexesRef.current = indexes;
331
333
  dispatch({
332
334
  type: 'setMenuState',
@@ -355,9 +357,14 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
355
357
  }));
356
358
  }
357
359
  }, [dispatch]);
358
- return (react_1.default.createElement(ClickOutside_1.default, { onOutsideClick: onRequestClose, mouseEvent: closeOutsideClick ? 'onMouseDown' : false },
359
- react_1.default.createElement(overridesMap.Popper, { isOpen: Boolean(isOpen), ref: menuPopperRef, zIndex: zIndex, anchorPos: anchorPos, anchorElement: anchorElement },
360
- react_1.default.createElement(overridesMap.List, { isOpen: Boolean(isOpen), ref: menuListRef, onKeyDown: listKeydownEvent }, items.map((item, index) => children({
360
+ return (react_1.default.createElement(ClickOutside_1.default, { onOutsideClick: onRequestClose, mouseEvent: isOpen && closeOutsideClick ? 'onMouseDown' : false },
361
+ react_1.default.createElement(overridesMap.Popper, { isOpen: Boolean(isOpen), ref: menuPopperRef, zIndex: zIndex, anchorPos: actualPlacement, anchorElement: anchorElement, onAnchorPosChanged: newPlacement => {
362
+ setActualPlacement(newPlacement);
363
+ if (typeof onAnchorPosChanged === 'function') {
364
+ onAnchorPosChanged(newPlacement);
365
+ }
366
+ }, positionStrategy: positionStrategy, autoFlip: autoFlip, viewportMargin: viewportMargin, offset: offset },
367
+ react_1.default.createElement(overridesMap.List, { anchorPos: actualPlacement, isOpen: Boolean(isOpen), ref: menuListRef, onKeyDown: listKeydownEvent }, items.map((item, index) => children({
361
368
  item,
362
369
  index,
363
370
  }, {
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
- export type MenuItemProps = React.HTMLAttributes<HTMLDivElement> & MenuItemCommonProps;
3
- export type MenuItemCommonProps = {
2
+ export type MenuItemProps = React.HTMLAttributes<HTMLDivElement> & {
4
3
  /**
5
4
  * Selected flag
6
5
  */
@@ -13,13 +12,31 @@ export type MenuItemCommonProps = {
13
12
  * React key
14
13
  */
15
14
  readonly key: React.Key;
16
- readonly onMouseEnter: React.MouseEventHandler<HTMLDivElement>;
17
- readonly onMouseLeave: React.MouseEventHandler<HTMLDivElement>;
18
- readonly onClick: React.MouseEventHandler<HTMLDivElement>;
19
15
  /**
20
16
  * Icon or another JSX element placed before button label
21
17
  */
22
- readonly startIcon?: JSX.Element;
18
+ readonly startIcon?: React.ReactNode;
23
19
  };
24
- declare const MenuItem: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & MenuItemCommonProps & React.RefAttributes<HTMLDivElement>>;
20
+ /**
21
+ * @deprecated Use `MenuItemProps` instead
22
+ */
23
+ export type MenuItemCommonProps = MenuItemProps;
24
+ export declare const MenuItem: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
25
+ /**
26
+ * Selected flag
27
+ */
28
+ readonly selected: boolean;
29
+ /**
30
+ * Hovered flag
31
+ */
32
+ readonly hovered: boolean;
33
+ /**
34
+ * React key
35
+ */
36
+ readonly key: React.Key;
37
+ /**
38
+ * Icon or another JSX element placed before button label
39
+ */
40
+ readonly startIcon?: React.ReactNode;
41
+ } & React.RefAttributes<HTMLDivElement>>;
25
42
  export default MenuItem;
package/Menu/MenuItem.js CHANGED
@@ -14,10 +14,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MenuItem = void 0;
17
18
  const react_1 = __importDefault(require("react"));
18
19
  const styled_1 = __importDefault(require("@emotion/styled"));
19
20
  const react_2 = require("@emotion/react");
20
- const InnerContainer = styled_1.default.div `
21
+ const StyledMenuItem = styled_1.default.div `
21
22
  cursor: pointer;
22
23
  user-select: none;
23
24
  display: flex;
@@ -53,11 +54,17 @@ const InnerContainer = styled_1.default.div `
53
54
  const ItemIconWrapper = styled_1.default.span `
54
55
  margin-right: 0.5em;
55
56
  `;
56
- const MenuItem = react_1.default.forwardRef((props, ref) => {
57
+ exports.MenuItem = react_1.default.forwardRef((props, ref) => {
57
58
  const { children, selected, hovered, onMouseEnter, onMouseLeave, onClick, startIcon } = props, nativeProps = __rest(props, ["children", "selected", "hovered", "onMouseEnter", "onMouseLeave", "onClick", "startIcon"]);
58
- return (react_1.default.createElement(InnerContainer, Object.assign({}, nativeProps, { ref: ref, onMouseLeave: onMouseLeave, onMouseEnter: onMouseEnter, onClick: onClick, selected: selected, hovered: hovered }),
59
- typeof startIcon !== 'undefined' && startIcon !== null && (react_1.default.createElement(ItemIconWrapper, null, startIcon)),
59
+ const renderStartIcon = react_1.default.useCallback(() => {
60
+ if (!startIcon) {
61
+ return null;
62
+ }
63
+ return react_1.default.createElement(ItemIconWrapper, null, startIcon);
64
+ }, [startIcon]);
65
+ return (react_1.default.createElement(StyledMenuItem, Object.assign({}, nativeProps, { ref: ref, onMouseLeave: onMouseLeave, onMouseEnter: onMouseEnter, onClick: onClick, selected: selected, hovered: hovered }),
66
+ renderStartIcon(),
60
67
  children));
61
68
  });
62
- MenuItem.displayName = 'MenuItem';
63
- exports.default = MenuItem;
69
+ exports.MenuItem.displayName = 'MenuItem';
70
+ exports.default = exports.MenuItem;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
+ import { AnchorPos } from '../Popper';
2
3
  export interface MenuListProps extends React.HTMLAttributes<HTMLDivElement> {
3
4
  readonly isOpen: boolean;
5
+ readonly anchorPos: AnchorPos;
4
6
  }
5
- declare const _default: React.ForwardRefExoticComponent<MenuListProps & React.RefAttributes<HTMLDivElement>>;
6
- export default _default;
7
+ export declare const MenuList: React.ForwardRefExoticComponent<MenuListProps & React.RefAttributes<HTMLDivElement>>;
8
+ export default MenuList;
package/Menu/MenuList.js CHANGED
@@ -14,8 +14,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MenuList = void 0;
17
18
  const react_1 = __importDefault(require("react"));
18
19
  const styled_1 = __importDefault(require("@emotion/styled"));
20
+ const react_2 = require("@emotion/react");
19
21
  const StyledMenuList = styled_1.default.div `
20
22
  display: flex;
21
23
  flex-direction: column;
@@ -23,12 +25,14 @@ const StyledMenuList = styled_1.default.div `
23
25
  opacity: ${props => (props.$isOpen ? 1 : 0)};
24
26
  background-color: ${({ theme }) => theme.color.surface.toString()};
25
27
  border-radius: ${({ theme }) => theme.shape.radiusFactor * 2}em;
26
- box-shadow: 0 4px 24px ${({ theme }) => theme.color.surface.darken(50).alpha(0.6).toString()};
28
+ box-shadow: 0 0.5em 1.5em ${({ theme }) => theme.color.surface.darken(50).alpha(0.6).toString()};
29
+
27
30
  &:focus {
28
31
  outline-style: solid;
29
32
  outline-width: 0.14em;
30
33
  outline-color: ${({ theme }) => theme.color.accentPrimary.toString()};
31
34
  }
35
+
32
36
  & ::-webkit-scrollbar {
33
37
  width: 0.6rem;
34
38
  height: 0.6rem;
@@ -55,13 +59,29 @@ const StyledMenuList = styled_1.default.div `
55
59
  & ::-webkit-scrollbar-thumb:vertical:hover {
56
60
  background: ${({ theme }) => theme.color.accentPrimary.toString()};
57
61
  }
62
+
58
63
  box-sizing: border-box;
59
64
  overflow-y: auto;
60
65
  padding: 0.4em;
61
66
  max-height: 18em;
67
+ min-width: 10em;
68
+
69
+ max-width: 100%;
70
+
71
+ ${({ $fixedWidth }) => $fixedWidth &&
72
+ (0, react_2.css) `
73
+ min-width: 10em;
74
+ max-width: 16em;
75
+ `}
76
+
77
+ ${({ $anchorPos, theme }) => $anchorPos === 'top-fill' &&
78
+ (0, react_2.css) `
79
+ box-shadow: 0 -0.5em 1.5em ${theme.color.surface.darken(50).alpha(0.6).toString()};
80
+ `};
62
81
  `;
63
- const MenuList = (props, ref) => {
64
- const { isOpen, children } = props, nativeProps = __rest(props, ["isOpen", "children"]);
65
- return (react_1.default.createElement(StyledMenuList, Object.assign({ tabIndex: -1, "$isOpen": isOpen }, nativeProps, { ref: ref }), children));
66
- };
67
- exports.default = react_1.default.forwardRef(MenuList);
82
+ exports.MenuList = react_1.default.forwardRef((props, ref) => {
83
+ const { isOpen, anchorPos, children } = props, nativeProps = __rest(props, ["isOpen", "anchorPos", "children"]);
84
+ return (react_1.default.createElement(StyledMenuList, Object.assign({ tabIndex: -1, "$isOpen": isOpen, "$anchorPos": anchorPos, "$fixedWidth": !['bottom-fill', 'top-fill'].includes(anchorPos) }, nativeProps, { ref: ref }), children));
85
+ });
86
+ exports.MenuList.displayName = 'MenuList';
87
+ exports.default = exports.MenuList;
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ export type VirtualizedItemProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {
3
+ readonly key: string;
4
+ readonly index: number;
5
+ readonly style: React.CSSProperties;
6
+ readonly setItemHeight: (index: number, height: number) => void;
7
+ readonly isActiveOnScroll: boolean;
8
+ readonly children: VirtualizedItemChildren;
9
+ };
10
+ export type VirtualizedItemChildren = (params: {
11
+ readonly index: number;
12
+ readonly isActiveOnScroll: boolean;
13
+ }) => React.ReactNode;
14
+ export declare const VirtualizedItem: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children"> & {
15
+ readonly key: string;
16
+ readonly index: number;
17
+ readonly style: React.CSSProperties;
18
+ readonly setItemHeight: (index: number, height: number) => void;
19
+ readonly isActiveOnScroll: boolean;
20
+ readonly children: VirtualizedItemChildren;
21
+ } & React.RefAttributes<HTMLDivElement>>;
22
+ export default VirtualizedItem;