@via-profit/ui-kit 0.2.2 → 0.2.4

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.
@@ -0,0 +1,489 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.usePopper = exports.findScrollableAncestor = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ /**
9
+ * Finds the closest scrollable ancestor of an element.
10
+ * A scrollable element is one that has overflow set to auto, scroll, or overlay
11
+ * and has content that overflows, allowing scrolling.
12
+ *
13
+ * @param element - The element to start searching from
14
+ * @param includeHidden - Whether to consider elements with overflow: hidden
15
+ * @returns The closest scrollable ancestor or window if none found
16
+ */
17
+ const findScrollableAncestor = (element, includeHidden = false) => {
18
+ if (!element) {
19
+ return null;
20
+ }
21
+ // Helper to check if an element is scrollable
22
+ const isScrollable = (el) => {
23
+ const style = window.getComputedStyle(el);
24
+ const overflow = style.overflow + style.overflowY + style.overflowX;
25
+ // Check if element has overflow that enables scrolling
26
+ const hasOverflow = overflow.includes('auto') ||
27
+ overflow.includes('scroll') ||
28
+ (includeHidden && overflow.includes('hidden'));
29
+ if (!hasOverflow) {
30
+ return false;
31
+ }
32
+ // Check if element actually has scrollable content
33
+ return el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth;
34
+ };
35
+ // Start from parent (skip the element itself)
36
+ let parent = element.parentElement;
37
+ while (parent) {
38
+ if (isScrollable(parent)) {
39
+ return parent;
40
+ }
41
+ parent = parent.parentElement;
42
+ }
43
+ // If no scrollable ancestor found, return window (which is scrollable)
44
+ return window;
45
+ };
46
+ exports.findScrollableAncestor = findScrollableAncestor;
47
+ const usePopper = (props) => {
48
+ const { anchorElement, anchorPos = 'auto', positionStrategy = 'fixed', autoFlip = false, offset = 0, viewportMargin = 10, isOpen = false, alternativePlacements, } = props;
49
+ const isMountedRef = react_1.default.useRef(false);
50
+ const isPositioningRef = react_1.default.useRef(false);
51
+ const [actualPlacement, setActualPlacement] = react_1.default.useState(anchorPos);
52
+ const [style, setStyle] = react_1.default.useState(null);
53
+ const [isVisible, setIsVisible] = react_1.default.useState(false);
54
+ const popperRef = react_1.default.useRef(null);
55
+ // Finding the nearest scrollable ancestor
56
+ const scrollableAncestor = react_1.default.useMemo(() => {
57
+ if (!anchorElement || typeof window === 'undefined') {
58
+ return null;
59
+ }
60
+ return (0, exports.findScrollableAncestor)(anchorElement);
61
+ }, [anchorElement]);
62
+ // Synchronizing actualPlacement with anchorPos
63
+ react_1.default.useEffect(() => {
64
+ if (actualPlacement !== anchorPos) {
65
+ setActualPlacement(anchorPos);
66
+ }
67
+ }, [actualPlacement, anchorPos]);
68
+ const getPositionStyle = react_1.default.useCallback((props) => {
69
+ var _a;
70
+ const { place, anchorRect, popperRect, forViewportCheck = false } = props;
71
+ const [direction, modifier = ''] = place.split('-');
72
+ let left = anchorRect.left;
73
+ let top = anchorRect.top;
74
+ let width = undefined;
75
+ // Calculating the position relative to the viewport
76
+ switch (direction) {
77
+ case 'top':
78
+ top = anchorRect.top - popperRect.height - offset;
79
+ if (modifier === 'fill') {
80
+ left = anchorRect.left;
81
+ width = anchorRect.width;
82
+ }
83
+ else if (modifier === 'left' || modifier === 'start') {
84
+ left = anchorRect.left;
85
+ }
86
+ else if (modifier === 'right' || modifier === 'end') {
87
+ left = anchorRect.right - popperRect.width;
88
+ }
89
+ else {
90
+ left = anchorRect.left + (anchorRect.width - popperRect.width) / 2;
91
+ }
92
+ break;
93
+ case 'bottom':
94
+ top = anchorRect.bottom + offset;
95
+ if (modifier === 'fill') {
96
+ left = anchorRect.left;
97
+ width = anchorRect.width;
98
+ }
99
+ else if (modifier === 'left' || modifier === 'start') {
100
+ left = anchorRect.left;
101
+ }
102
+ else if (modifier === 'right' || modifier === 'end') {
103
+ left = anchorRect.right - popperRect.width;
104
+ }
105
+ else {
106
+ left = anchorRect.left + (anchorRect.width - popperRect.width) / 2;
107
+ }
108
+ break;
109
+ case 'left':
110
+ left = anchorRect.left - popperRect.width - offset;
111
+ if (modifier === 'top' || modifier === 'start') {
112
+ top = anchorRect.top;
113
+ }
114
+ else if (modifier === 'bottom' || modifier === 'end') {
115
+ top = anchorRect.bottom - popperRect.height;
116
+ }
117
+ else {
118
+ top = anchorRect.top + (anchorRect.height - popperRect.height) / 2;
119
+ }
120
+ break;
121
+ case 'right':
122
+ left = anchorRect.right + offset;
123
+ if (modifier === 'top' || modifier === 'start') {
124
+ top = anchorRect.top;
125
+ }
126
+ else if (modifier === 'bottom' || modifier === 'end') {
127
+ top = anchorRect.bottom - popperRect.height;
128
+ }
129
+ else {
130
+ top = anchorRect.top + (anchorRect.height - popperRect.height) / 2;
131
+ }
132
+ break;
133
+ default:
134
+ left = anchorRect.left + (anchorRect.width - popperRect.width) / 2;
135
+ top = anchorRect.bottom + offset;
136
+ }
137
+ // Returning the viewport coordinates for verification or the final coordinates
138
+ if (forViewportCheck) {
139
+ return { left, top, width };
140
+ }
141
+ // For the final positioning, we take into account the strategy
142
+ if (positionStrategy === 'absolute') {
143
+ // Для absolute позиционирования нужно учитывать:
144
+ // 1. Прокрутку страницы (scrollX/scrollY)
145
+ // 2. Позицию относительно ближайшего positioned ancestor
146
+ // Получаем offset родителя с позиционированием
147
+ let offsetParent = ((_a = popperRef.current) === null || _a === void 0 ? void 0 : _a.offsetParent) || null;
148
+ // Если нет offsetParent или это body, используем document.documentElement
149
+ if (!offsetParent || offsetParent === document.body) {
150
+ offsetParent = document.documentElement;
151
+ }
152
+ const offsetParentRect = offsetParent.getBoundingClientRect();
153
+ // Вычисляем позицию относительно offsetParent
154
+ // left/top уже относительно viewport, вычитаем позицию offsetParent
155
+ let relativeLeft = left - offsetParentRect.left;
156
+ let relativeTop = top - offsetParentRect.top;
157
+ // Добавляем прокрутку offsetParent (если он скроллится)
158
+ if (offsetParent !== document.documentElement && offsetParent !== document.body) {
159
+ relativeLeft += offsetParent.scrollLeft || 0;
160
+ relativeTop += offsetParent.scrollTop || 0;
161
+ }
162
+ else {
163
+ // Для document.documentElement используем window.scroll
164
+ relativeLeft += window.scrollX;
165
+ relativeTop += window.scrollY;
166
+ }
167
+ return {
168
+ left: relativeLeft,
169
+ top: relativeTop,
170
+ width,
171
+ };
172
+ }
173
+ return { left, top, width };
174
+ }, [offset, positionStrategy]);
175
+ const clampPopperToContainer = react_1.default.useCallback((style, popperRect) => {
176
+ if (positionStrategy === 'absolute') {
177
+ return style;
178
+ }
179
+ const viewportMinLeft = viewportMargin;
180
+ const viewportMaxLeft = window.innerWidth - popperRect.width - viewportMargin;
181
+ const viewportMinTop = viewportMargin;
182
+ const viewportMaxTop = window.innerHeight - popperRect.height - viewportMargin;
183
+ return {
184
+ left: Math.max(viewportMinLeft, Math.min(style.left, viewportMaxLeft)),
185
+ top: Math.max(viewportMinTop, Math.min(style.top, viewportMaxTop)),
186
+ width: style.width,
187
+ };
188
+ }, [positionStrategy, viewportMargin]);
189
+ const checkIfViewportFits = react_1.default.useCallback((style, popperRect) => {
190
+ const left = style.left;
191
+ const top = style.top;
192
+ const right = left + popperRect.width;
193
+ const bottom = top + popperRect.height;
194
+ const viewportWidth = window.innerWidth;
195
+ const viewportHeight = window.innerHeight;
196
+ const isWithinHorizontal = left >= viewportMargin && right <= viewportWidth - viewportMargin;
197
+ const isWithinVertical = top >= viewportMargin && bottom <= viewportHeight - viewportMargin;
198
+ return isWithinHorizontal && isWithinVertical;
199
+ }, [viewportMargin]);
200
+ const placementsOrder = react_1.default.useMemo(() => {
201
+ const basePlacements = {
202
+ top: ['top', 'top-left', 'top-right', 'top-start', 'top-end'],
203
+ bottom: ['bottom', 'bottom-left', 'bottom-right', 'bottom-start', 'bottom-end'],
204
+ left: ['left', 'left-top', 'left-bottom'],
205
+ right: ['right', 'right-top', 'right-bottom'],
206
+ };
207
+ const allPlacements = [
208
+ ...basePlacements.top,
209
+ ...basePlacements.bottom,
210
+ ...basePlacements.left,
211
+ ...basePlacements.right,
212
+ ];
213
+ const order = {};
214
+ allPlacements.forEach(placement => {
215
+ const [direction] = placement.split('-');
216
+ // Priority: same direction > opposite > the rest
217
+ const opposite = direction === 'top'
218
+ ? 'bottom'
219
+ : direction === 'bottom'
220
+ ? 'top'
221
+ : direction === 'left'
222
+ ? 'right'
223
+ : 'left';
224
+ order[placement] = [
225
+ placement,
226
+ ...basePlacements[direction].filter(p => p !== placement),
227
+ ...(basePlacements[opposite] || []),
228
+ ...(direction !== 'left' && direction !== 'right' ? basePlacements.left : []),
229
+ ...(direction !== 'left' && direction !== 'right' ? basePlacements.right : []),
230
+ ];
231
+ });
232
+ // console.log(order);
233
+ return order;
234
+ }, []);
235
+ // #region Get Preferred Placements
236
+ const getPreferredPlacements = react_1.default.useCallback((preferredPlacement, anchorRect, popperRect) => {
237
+ var _a, _b, _c, _d, _e, _f, _g, _h;
238
+ const tryPlacement = (placement) => {
239
+ const viewportStyle = getPositionStyle({
240
+ place: placement,
241
+ anchorRect,
242
+ popperRect,
243
+ forViewportCheck: true,
244
+ });
245
+ if (!checkIfViewportFits(viewportStyle, popperRect)) {
246
+ return null;
247
+ }
248
+ const finalStyle = getPositionStyle({
249
+ place: placement,
250
+ anchorRect,
251
+ popperRect,
252
+ forViewportCheck: false,
253
+ });
254
+ return {
255
+ found: true,
256
+ placement,
257
+ style: clampPopperToContainer(finalStyle, popperRect),
258
+ };
259
+ };
260
+ const fallback = (placement) => {
261
+ const finalStyle = getPositionStyle({
262
+ place: placement,
263
+ anchorRect,
264
+ popperRect,
265
+ forViewportCheck: false,
266
+ });
267
+ return {
268
+ found: false,
269
+ placement,
270
+ style: clampPopperToContainer(finalStyle, popperRect),
271
+ };
272
+ };
273
+ const isAuto = preferredPlacement.startsWith('auto');
274
+ const isFill = preferredPlacement.endsWith('fill');
275
+ // -------------------------------------------------------
276
+ // 1. EXPLICIT (top, bottom, left, right, top-left, ...)
277
+ // -------------------------------------------------------
278
+ if (!isAuto && !isFill) {
279
+ if (!autoFlip) {
280
+ return (_a = tryPlacement(preferredPlacement)) !== null && _a !== void 0 ? _a : fallback(preferredPlacement);
281
+ }
282
+ // Формируем порядок без дубликатов
283
+ const order = Array.from(new Set([
284
+ preferredPlacement,
285
+ ...((_b = alternativePlacements === null || alternativePlacements === void 0 ? void 0 : alternativePlacements.filter(p => !p.startsWith('auto') && !p.endsWith('fill'))) !== null && _b !== void 0 ? _b : []),
286
+ ...((_c = placementsOrder[preferredPlacement]) !== null && _c !== void 0 ? _c : []),
287
+ ]));
288
+ for (const p of order) {
289
+ const r = tryPlacement(p);
290
+ if (r)
291
+ return r;
292
+ }
293
+ return fallback(preferredPlacement);
294
+ }
295
+ // -------------------------------------------------------
296
+ // 2. FILL (bottom-fill, top-fill)
297
+ // -------------------------------------------------------
298
+ if (isFill) {
299
+ const [dir] = preferredPlacement.split('-');
300
+ if (!autoFlip) {
301
+ return (_d = tryPlacement(preferredPlacement)) !== null && _d !== void 0 ? _d : fallback(preferredPlacement);
302
+ }
303
+ const opposite = dir === 'bottom' ? 'top-fill' : 'bottom-fill';
304
+ // Формируем порядок: fill сначала, потом обычные позиции из альтернатив, потом дефолтные
305
+ const order = Array.from(new Set([
306
+ preferredPlacement,
307
+ opposite,
308
+ // Обычные позиции из alternativePlacements (не auto и не fill)
309
+ ...((_e = alternativePlacements === null || alternativePlacements === void 0 ? void 0 : alternativePlacements.filter(p => !p.startsWith('auto') && !p.endsWith('fill'))) !== null && _e !== void 0 ? _e : []),
310
+ // Обычные позиции из дефолтного порядка (не fill)
311
+ ...((_g = (_f = placementsOrder[preferredPlacement]) === null || _f === void 0 ? void 0 : _f.filter(p => !p.endsWith('fill'))) !== null && _g !== void 0 ? _g : []),
312
+ ]));
313
+ for (const p of order) {
314
+ const r = tryPlacement(p);
315
+ if (r)
316
+ return r;
317
+ }
318
+ return fallback(preferredPlacement);
319
+ }
320
+ // -------------------------------------------------------
321
+ // 3. AUTO
322
+ // -------------------------------------------------------
323
+ if (isAuto) {
324
+ // Если autoFlip выключен - просто используем дефолтное направление
325
+ if (!autoFlip) {
326
+ const [, dir = 'bottom'] = preferredPlacement.split('-');
327
+ const defaultPlacement = dir;
328
+ return (_h = tryPlacement(defaultPlacement)) !== null && _h !== void 0 ? _h : fallback(defaultPlacement);
329
+ }
330
+ const [, dir = 'bottom'] = preferredPlacement.split('-');
331
+ const base = (alternativePlacements === null || alternativePlacements === void 0 ? void 0 : alternativePlacements.length)
332
+ ? alternativePlacements
333
+ : [
334
+ 'bottom',
335
+ 'bottom-start',
336
+ 'bottom-end',
337
+ 'bottom-left',
338
+ 'bottom-right',
339
+ 'top',
340
+ 'top-left',
341
+ 'top-right',
342
+ 'top-start',
343
+ 'top-end',
344
+ 'left',
345
+ 'left-top',
346
+ 'left-bottom',
347
+ 'right',
348
+ 'right-top',
349
+ 'right-bottom',
350
+ ];
351
+ const sorted = [...base].sort((a, b) => {
352
+ const ad = a.split('-')[0];
353
+ const bd = b.split('-')[0];
354
+ if (ad === dir && bd !== dir)
355
+ return -1;
356
+ if (ad !== dir && bd === dir)
357
+ return 1;
358
+ return 0;
359
+ });
360
+ for (const p of sorted) {
361
+ const r = tryPlacement(p);
362
+ if (r)
363
+ return r;
364
+ }
365
+ return fallback(dir);
366
+ }
367
+ // -------------------------------------------------------
368
+ // 4. SUPER FALLBACK
369
+ // -------------------------------------------------------
370
+ return fallback('bottom');
371
+ }, [
372
+ autoFlip,
373
+ getPositionStyle,
374
+ checkIfViewportFits,
375
+ clampPopperToContainer,
376
+ placementsOrder,
377
+ alternativePlacements,
378
+ ]);
379
+ // #region Calculate Position
380
+ const calculatePosition = react_1.default.useCallback(() => {
381
+ if (!anchorElement || !popperRef.current) {
382
+ return;
383
+ }
384
+ const anchorRect = anchorElement.getBoundingClientRect();
385
+ const popperRect = popperRef.current.getBoundingClientRect();
386
+ const { style, placement, found } = getPreferredPlacements(anchorPos, anchorRect, popperRect);
387
+ if (found) {
388
+ setActualPlacement(placement);
389
+ }
390
+ setStyle(style);
391
+ }, [anchorElement, anchorPos, getPreferredPlacements]);
392
+ /**
393
+ * Open / Close popper logic
394
+ */
395
+ react_1.default.useEffect(() => {
396
+ if (!isOpen) {
397
+ setIsVisible(false);
398
+ setStyle(null);
399
+ }
400
+ else if (anchorElement && isOpen && popperRef.current) {
401
+ calculatePosition();
402
+ setIsVisible(true);
403
+ }
404
+ }, [anchorElement, getPreferredPlacements, isOpen, calculatePosition]);
405
+ /**
406
+ * The anchor element changes
407
+ */
408
+ react_1.default.useEffect(() => {
409
+ if (!isOpen || !anchorElement) {
410
+ return;
411
+ }
412
+ const observer = new MutationObserver(() => {
413
+ window.requestAnimationFrame(() => {
414
+ // console.log('The anchor element was change');
415
+ calculatePosition();
416
+ });
417
+ });
418
+ observer.observe(anchorElement, {
419
+ attributes: true,
420
+ childList: true,
421
+ subtree: true,
422
+ });
423
+ // eslint-disable-next-line consistent-return
424
+ return () => {
425
+ observer.disconnect();
426
+ };
427
+ }, [isOpen, anchorElement, calculatePosition]);
428
+ /**
429
+ * On scroll - recalculate position
430
+ */
431
+ react_1.default.useEffect(() => {
432
+ if (!isOpen || !scrollableAncestor) {
433
+ return;
434
+ }
435
+ const handleScroll = () => {
436
+ window.requestAnimationFrame(() => {
437
+ calculatePosition();
438
+ });
439
+ };
440
+ // parent scroll listener
441
+ if (scrollableAncestor instanceof HTMLElement) {
442
+ scrollableAncestor.addEventListener('scroll', handleScroll, { passive: true });
443
+ }
444
+ else if (scrollableAncestor === window) {
445
+ window.addEventListener('scroll', handleScroll, { passive: true });
446
+ }
447
+ // eslint-disable-next-line consistent-return
448
+ return () => {
449
+ if (scrollableAncestor instanceof HTMLElement) {
450
+ scrollableAncestor.removeEventListener('scroll', handleScroll);
451
+ }
452
+ else if (scrollableAncestor === window) {
453
+ window.removeEventListener('scroll', handleScroll);
454
+ }
455
+ };
456
+ }, [isOpen, scrollableAncestor, calculatePosition]);
457
+ /**
458
+ * On window resize - recalculate position
459
+ */
460
+ react_1.default.useEffect(() => {
461
+ if (!isOpen) {
462
+ return;
463
+ }
464
+ const handleResize = () => {
465
+ window.requestAnimationFrame(() => {
466
+ calculatePosition();
467
+ });
468
+ };
469
+ // parent scroll listener
470
+ window.addEventListener('resize', handleResize);
471
+ // eslint-disable-next-line consistent-return
472
+ return () => {
473
+ window.removeEventListener('resize', handleResize);
474
+ };
475
+ }, [calculatePosition, isOpen]);
476
+ return {
477
+ actualPlacement,
478
+ style,
479
+ popperRef,
480
+ isVisible,
481
+ scrollableAncestor,
482
+ calculatePosition,
483
+ setActualPlacement,
484
+ setStyle,
485
+ setIsVisible,
486
+ };
487
+ };
488
+ exports.usePopper = usePopper;
489
+ exports.default = exports.usePopper;
@@ -66,39 +66,14 @@ const StyledSelectboxButton = (0, styled_1.default)(Button_1.default) `
66
66
  }
67
67
  `}
68
68
  transition: none;
69
- ${({ theme, $isOpen, $anchorPos }) => $isOpen &&
70
- $anchorPos &&
71
- ['bottom-fill', 'top-fill'].includes($anchorPos) &&
72
- (0, react_1.css) `
73
- border-width: 1px;
74
- border-style: solid;
75
- border-color: ${theme.isDark
76
- ? theme.color.textPrimary.darken(100).toString()
77
- : theme.color.textPrimary.lighten(150).toString()};
78
- `};
79
-
80
- ${({ $anchorPos, $isOpen }) => $isOpen &&
81
- $anchorPos === 'bottom-fill' &&
82
- (0, react_1.css) `
83
- border-bottom-left-radius: 0;
84
- border-bottom-right-radius: 0;
85
- border-bottom: 0;
86
- `};
87
-
88
- ${({ $anchorPos, $isOpen }) => $isOpen &&
89
- $anchorPos === 'top-fill' &&
90
- (0, react_1.css) `
91
- border-top-left-radius: 0;
92
- border-top-right-radius: 0;
93
- border-top: 0;
94
- `};
69
+
95
70
  `;
96
71
  const StyledButtonTextWrapper = (0, styled_1.default)(ButtonTextWrapper_1.default) `
97
72
  flex: 1;
98
73
  `;
99
74
  const SelectboxButton = (props, ref) => {
100
75
  const { children, fullWidth, error, anchorPos, isOpen } = props, nativeProps = __rest(props, ["children", "fullWidth", "error", "anchorPos", "isOpen"]);
101
- return (React.createElement(StyledSelectboxButton, Object.assign({ "$fullWidth": fullWidth, "$error": error }, nativeProps, { "$isOpen": isOpen, "$anchorPos": anchorPos, overrides: {
76
+ return (React.createElement(StyledSelectboxButton, Object.assign({ "$fullWidth": fullWidth, "$error": error }, nativeProps, { "$isOpen": isOpen, overrides: {
102
77
  TextWrapper: StyledButtonTextWrapper,
103
78
  }, ref: ref }), children));
104
79
  };
@@ -1,9 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { MenuProps, MenuRef } from '../Menu';
3
- import { AnchorPos } from '../Popper';
4
3
  import { OnChange } from 'Selectbox';
5
4
  export interface SelectbosMenuProps<T, Multiple extends boolean | undefined = undefined> extends MenuProps<T, Multiple> {
6
- readonly actualPlacement: AnchorPos;
7
5
  readonly onChange?: OnChange<T, Multiple>;
8
6
  }
9
7
  declare const _default: <T, Multiple extends boolean | undefined = undefined>(props: SelectbosMenuProps<T, Multiple> & {
@@ -22,15 +22,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
25
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
38
  };
28
39
  Object.defineProperty(exports, "__esModule", { value: true });
29
40
  const React = __importStar(require("react"));
30
41
  const Menu_1 = __importDefault(require("../Menu"));
31
- const OverrideMenuList_1 = __importDefault(require("../Autocomplete/OverrideMenuList"));
32
42
  const SelectboxMenu = React.forwardRef((props, ref) => {
33
- const { actualPlacement, multiple, items, value, isOpen, anchorElement, getOptionSelected, onChange, onRequestClose, children, onAnchorPosChanged, } = props;
43
+ const { multiple, items, value, isOpen, anchorPos, anchorElement, getOptionSelected, onChange, onRequestClose, children } = props, restMenuProps = __rest(props, ["multiple", "items", "value", "isOpen", "anchorPos", "anchorElement", "getOptionSelected", "onChange", "onRequestClose", "children"]);
34
44
  const handleSelectItem = React.useCallback((item) => {
35
45
  onChange === null || onChange === void 0 ? void 0 : onChange(item);
36
46
  }, [onChange]);
@@ -42,9 +52,7 @@ const SelectboxMenu = React.forwardRef((props, ref) => {
42
52
  anchorElement === null || anchorElement === void 0 ? void 0 : anchorElement.focus();
43
53
  }
44
54
  }, [onRequestClose, anchorElement]);
45
- return (React.createElement(Menu_1.default, { ref: ref, offset: 0, anchorPos: actualPlacement, onAnchorPosChanged: onAnchorPosChanged, multiple: multiple, items: items, value: value, isOpen: isOpen && items.length > 0, autofocus: true, anchorElement: anchorElement, closeOutsideClick: false, getOptionSelected: getOptionSelected, onSelectItem: handleSelectItem, overrides: {
46
- List: OverrideMenuList_1.default,
47
- }, closeOnSelect: !multiple, onRequestClose: handleRequestClose }, ({ index, item }, itemProps) => children({ index, item: item }, itemProps)));
55
+ return (React.createElement(Menu_1.default, Object.assign({ ref: ref, offset: 0, anchorPos: anchorPos, multiple: multiple, items: items, value: value, isOpen: isOpen && items.length > 0, autofocus: true, anchorElement: anchorElement, closeOutsideClick: false, getOptionSelected: getOptionSelected, onSelectItem: handleSelectItem, closeOnSelect: !multiple, onRequestClose: handleRequestClose }, restMenuProps), ({ index, item }, itemProps) => children({ index, item: item }, itemProps)));
48
56
  });
49
57
  SelectboxMenu.displayName = 'SelectboxMenu';
50
58
  exports.default = React.memo(SelectboxMenu);
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { GetOptionSelected, OnRequestClose, Value } from '../Menu';
3
- import type { MenuItemCommonProps } from '../Menu/MenuItem';
3
+ import type { MenuItemProps } from '../Menu/MenuItem';
4
4
  import SelectboxItem from '../Menu/MenuItem';
5
5
  import { SelectboxButtonProps } from './SelectboxButton';
6
6
  import { SelectboxChevronIconProps } from './SelectboxChevronIcon';
7
- import { AnchorPos } from '../Popper';
7
+ import { AnchorPos, PositionStrategy } from '../Popper';
8
8
  import { TextFieldLabelProps } from '../TextField/TextFieldLabel';
9
9
  import { TextFieldLabelAsteriskProps } from '../TextField/TextFieldLabelAsterisk';
10
10
  import { TextFieldErrorTextProps } from '../TextField/TextFieldErrorText';
@@ -36,6 +36,8 @@ export interface SelectboxProps<T, Multiple extends boolean | undefined = undefi
36
36
  * Default: `bottom`
37
37
  */
38
38
  readonly anchorPos?: AnchorPos;
39
+ readonly positionStrategy?: PositionStrategy;
40
+ readonly autoFlip?: boolean;
39
41
  /**
40
42
  * Text field loading state\
41
43
  * If `true` then text field has been contained the loading indicator, otherwise - nop
@@ -154,7 +156,7 @@ export interface SelectboxOverrides {
154
156
  export type Children<T> = (data: {
155
157
  item: T;
156
158
  index: number;
157
- }, itemProps: MenuItemCommonProps) => React.ReactNode;
159
+ }, itemProps: MenuItemProps) => React.ReactNode;
158
160
  export type ItemToString<T, Multiple extends boolean | undefined = undefined> = (item: Multiple extends undefined ? T : readonly T[]) => string;
159
161
  export type OnChange<T, Multiple extends boolean | undefined = undefined> = (item: Value<T, Multiple>) => void;
160
162
  declare const _default: <T, Multiple extends boolean | undefined = undefined>(props: SelectboxProps<T, Multiple> & {
@@ -70,9 +70,8 @@ const generateGuid = () => {
70
70
  ].join('-');
71
71
  };
72
72
  const Selectbox = React.forwardRef((props, ref) => {
73
- const { items, value, multiple, isOpen = false, isLoading = false, anchorPos = 'bottom-fill', fullWidth = false, children, onChange, selectedItemToString, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides, id, label, onFocus, requiredAsterisk, error, errorText, notSetLabel = 'Not set' } = props, nativeButtonProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "anchorPos", "fullWidth", "children", "onChange", "selectedItemToString", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides", "id", "label", "onFocus", "requiredAsterisk", "error", "errorText", "notSetLabel"]);
73
+ const { items, value, multiple, isOpen = false, isLoading = false, anchorPos = 'bottom-fill', fullWidth = false, children, onChange, selectedItemToString, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides, id, label, onFocus, requiredAsterisk, error, errorText, notSetLabel = 'Not set', autoFlip = true, positionStrategy } = props, nativeButtonProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "anchorPos", "fullWidth", "children", "onChange", "selectedItemToString", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides", "id", "label", "onFocus", "requiredAsterisk", "error", "errorText", "notSetLabel", "autoFlip", "positionStrategy"]);
74
74
  const menuRef = React.useRef(null);
75
- const [actualPlacement, setActualPlacement] = React.useState(anchorPos);
76
75
  const [anchorElement, setAnchorElement] = React.useState(null);
77
76
  const overridesMap = React.useMemo(() => (Object.assign(Object.assign({}, DEFAULT_OVERRIDES), overrides)), [overrides]);
78
77
  const inputID = React.useMemo(() => {
@@ -136,7 +135,8 @@ const Selectbox = React.forwardRef((props, ref) => {
136
135
  }, [handleMouseDown]);
137
136
  const buttonProps = React.useMemo(() => (Object.assign({ fullWidth,
138
137
  error,
139
- isOpen, anchorPos: actualPlacement, endIcon: isLoading ? React.createElement(Spinner_1.default, null) : React.createElement(overridesMap.Icon, { isOpen: isOpen }) }, nativeButtonProps)), [fullWidth, error, isOpen, actualPlacement, isLoading, overridesMap, nativeButtonProps]);
138
+ isOpen,
139
+ anchorPos, endIcon: isLoading ? React.createElement(Spinner_1.default, null) : React.createElement(overridesMap.Icon, { isOpen: isOpen }) }, nativeButtonProps)), [fullWidth, error, isOpen, anchorPos, isLoading, overridesMap, nativeButtonProps]);
140
140
  const labelProps = React.useMemo(() => ({
141
141
  htmlFor: inputID,
142
142
  error,
@@ -151,7 +151,7 @@ const Selectbox = React.forwardRef((props, ref) => {
151
151
  React.createElement(overridesMap.ButtonWrapper, { fullWidth: fullWidth, error: error, isOpen: isOpen },
152
152
  React.createElement(overridesMap.Button, Object.assign({}, buttonProps, { onClick: handleButtonClick, ref: setRefs }), renderValueAsString())),
153
153
  React.createElement(overridesMap.ErrorText, { error: error }, errorText),
154
- React.createElement(SelectboxMenu_1.default, { actualPlacement: actualPlacement, multiple: multiple, items: items, value: value, isOpen: isOpen, anchorElement: anchorElement, getOptionSelected: getOptionSelected, onChange: onChange, onRequestClose: onRequestClose, onAnchorPosChanged: setActualPlacement, ref: menuRef }, children)));
154
+ React.createElement(SelectboxMenu_1.default, { multiple: multiple, items: items, value: value, isOpen: isOpen, anchorPos: anchorPos, positionStrategy: positionStrategy, autoFlip: autoFlip, alternativePlacements: ['bottom-fill', 'top-fill'], anchorElement: anchorElement, getOptionSelected: getOptionSelected, onChange: onChange, onRequestClose: onRequestClose, ref: menuRef }, children)));
155
155
  });
156
156
  Selectbox.displayName = 'Selectbox';
157
157
  exports.default = Selectbox;
@@ -30,7 +30,6 @@ export type SwiperProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>
30
30
  readonly autoplay?: boolean;
31
31
  readonly autoplayInterval?: number;
32
32
  readonly pauseOnHover?: boolean;
33
- readonly keyboardControl?: boolean;
34
33
  readonly threshold?: number;
35
34
  readonly resistance?: boolean;
36
35
  readonly slidesPerView?: number;
@@ -47,7 +46,6 @@ export declare const Swiper: React.ForwardRefExoticComponent<Omit<React.HTMLAttr
47
46
  readonly autoplay?: boolean | undefined;
48
47
  readonly autoplayInterval?: number | undefined;
49
48
  readonly pauseOnHover?: boolean | undefined;
50
- readonly keyboardControl?: boolean | undefined;
51
49
  readonly threshold?: number | undefined;
52
50
  readonly resistance?: boolean | undefined;
53
51
  readonly slidesPerView?: number | undefined;