@progress/kendo-react-dropdowns 5.13.0-dev.202304051130 → 5.13.0-dev.202304131123

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.
@@ -18,9 +18,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
18
  }
19
19
  return to.concat(ar || Array.prototype.slice.call(from));
20
20
  };
21
+ var _this = this;
21
22
  import * as React from 'react';
22
23
  import * as PropTypes from 'prop-types';
23
- import { classNames, noop, useRtl, getTabIndex, Keys, guid, kendoThemeMaps, createPropsContext, usePropsContext, IconWrap } from '@progress/kendo-react-common';
24
+ import { classNames, noop, useRtl, getTabIndex, Keys, guid, kendoThemeMaps, createPropsContext, usePropsContext, IconWrap, canUseDOM } from '@progress/kendo-react-common';
24
25
  import { Popup } from '@progress/kendo-react-popup';
25
26
  import { useLocalization } from '@progress/kendo-react-intl';
26
27
  import { TreeView } from '@progress/kendo-react-treeview';
@@ -29,11 +30,14 @@ import { packageMetadata } from './../package-metadata';
29
30
  import { getItemValue, areSame, matchTags } from '../common/utils';
30
31
  import { useDropdownWidth } from './../DropDownTree/useDropdownWidth';
31
32
  import { ListNoData } from './../DropDownTree/ListNoData';
32
- import { messages, nodata } from './../messages';
33
+ import { messages, nodata, adaptiveModeFooterCancel, adaptiveModeFooterApply } from './../messages';
33
34
  import { FloatingLabel } from '@progress/kendo-react-labels';
34
35
  import TagList from '../MultiSelect/TagList';
35
36
  import ClearButton from '../common/ClearButton';
36
37
  import ListFilter from '../common/ListFilter';
38
+ import { AdaptiveMode } from '../common/AdaptiveMode';
39
+ import { ActionSheetContent } from '@progress/kendo-react-layout';
40
+ import { MOBILE_MEDIUM_DEVISE } from '../common/constants';
37
41
  var VALIDATION_MESSAGE = 'Please select a value from the list!';
38
42
  var sizeMap = kendoThemeMaps.sizeMap, roundedMap = kendoThemeMaps.roundedMap;
39
43
  var toLevel = function (hierarchicalIndex) {
@@ -86,6 +90,7 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
86
90
  var targetRef = React.useRef(null);
87
91
  var elementRef = React.useRef(null);
88
92
  var inputRef = React.useRef(null);
93
+ var adaptiveInputRef = React.useRef(null);
89
94
  var selectRef = React.useRef(null);
90
95
  var treeViewRef = React.useRef(null);
91
96
  var skipFocusRef = React.useRef(false);
@@ -95,6 +100,9 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
95
100
  var _p = React.useState(false), openState = _p[0], setOpenState = _p[1];
96
101
  var _q = React.useState(false), focusedState = _q[0], setFocusedState = _q[1];
97
102
  var _r = React.useState(''), filterState = _r[0], setFilterState = _r[1];
103
+ var _s = React.useState(), windowWidth = _s[0], setWindowWidth = _s[1];
104
+ var _t = React.useState([]), currentTreeValue = _t[0], setCurrentTreeValue = _t[1];
105
+ var isAdaptive = !!(windowWidth && windowWidth <= MOBILE_MEDIUM_DEVISE && props.adaptive);
98
106
  var isOpen = opened !== undefined ? opened : openState;
99
107
  var hasValue = Boolean(Array.isArray(value) && value.length);
100
108
  var validity = getValidity({ validationMessage: validationMessage, valid: valid, required: required }, hasValue);
@@ -120,6 +128,15 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
120
128
  }
121
129
  }, [validationMessage, validity]);
122
130
  React.useEffect(setValidity);
131
+ React.useEffect(function () {
132
+ var observerResize = canUseDOM && window.ResizeObserver && new window.ResizeObserver(calculateMedia.bind(_this));
133
+ if ((document === null || document === void 0 ? void 0 : document.body) && observerResize) {
134
+ observerResize.observe(document.body);
135
+ }
136
+ return function () {
137
+ observerResize.disconnect();
138
+ };
139
+ }, []);
123
140
  React.useEffect(function () {
124
141
  if (popupRef.current && isOpen) {
125
142
  popupRef.current.setPosition(popupRef.current._popup);
@@ -151,9 +168,15 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
151
168
  }
152
169
  if (opened === undefined) {
153
170
  setOpenState(true);
171
+ setCurrentTreeValue(value || []);
172
+ if (isAdaptive) {
173
+ setTimeout(function () {
174
+ focusElement(adaptiveInputRef.current);
175
+ }, 300);
176
+ }
154
177
  }
155
178
  }
156
- }, [isOpen, opened, onOpen]);
179
+ }, [isOpen, opened, onOpen, isAdaptive]);
157
180
  var closePopup = React.useCallback(function (event) {
158
181
  if (isOpen) {
159
182
  if (onClose) {
@@ -219,7 +242,9 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
219
242
  var focusEvent = __assign({}, ev);
220
243
  props.onBlur.call(undefined, focusEvent);
221
244
  }
222
- closePopup(ev);
245
+ if (!isAdaptive) {
246
+ closePopup(ev);
247
+ }
223
248
  }
224
249
  }, [focusedState, props.onBlur, isOpen, opened, onClose]);
225
250
  var onWrapperMouseDown = React.useCallback(function () {
@@ -385,33 +410,80 @@ export var MultiSelectTree = React.forwardRef(function (directProps, ref) {
385
410
  }
386
411
  }
387
412
  }, [props.onFilterChange, props.filter, props.textField]);
413
+ var onCancel = React.useCallback(function (event) {
414
+ if (!targetRef.current) {
415
+ return;
416
+ }
417
+ var ev = {
418
+ syntheticEvent: event,
419
+ nativeEvent: event.nativeEvent,
420
+ target: targetRef.current
421
+ };
422
+ if (props.onCancel) {
423
+ props.onCancel.call(undefined, ev);
424
+ }
425
+ ;
426
+ closePopup(ev);
427
+ event.preventDefault();
428
+ }, [props.onCancel, closePopup]);
429
+ var renderAdaptiveListContainer = function () {
430
+ var mobileFilter = props.filterable ? (React.createElement(ListFilter, { value: props.filter === undefined ? filterState : props.filter, inputRef: adaptiveInputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, size: size, rounded: rounded, fillMode: fillMode })) : null;
431
+ var actionSheetProps = {
432
+ adaptiveTitle: props.adaptiveTitle,
433
+ expand: isOpen,
434
+ onClose: function (event) { return props.onCancel ? onCancel(event) : onClear(event); },
435
+ windowWidth: windowWidth,
436
+ mobileFilter: mobileFilter,
437
+ footer: {
438
+ cancelText: localization.toLanguageString(adaptiveModeFooterCancel, messages[adaptiveModeFooterCancel]),
439
+ onCancel: function (event) { return props.onCancel ? onCancel(event) : onClear(event); },
440
+ applyText: localization.toLanguageString(adaptiveModeFooterApply, messages[adaptiveModeFooterApply]),
441
+ onApply: function (event) { return closePopup(event); }
442
+ }
443
+ };
444
+ return (React.createElement(AdaptiveMode, __assign({}, actionSheetProps),
445
+ React.createElement(ActionSheetContent, { className: '!k-overflow-hidden' },
446
+ React.createElement("div", { className: 'k-list-container' },
447
+ React.createElement("div", { className: 'k-list k-list-lg' }, data.length > 0 ? (React.createElement(TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(nodata, messages[nodata]))))))));
448
+ };
449
+ var calculateMedia = React.useCallback(function (entries) {
450
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
451
+ var entry = entries_1[_i];
452
+ setWindowWidth(entry.target.clientWidth);
453
+ }
454
+ ;
455
+ }, []);
388
456
  var NoData = props.listNoData || ListNoData;
389
457
  var localization = useLocalization();
390
458
  var isValid = !validityStyles || validity.valid;
391
459
  var size = props.size, rounded = props.rounded, fillMode = props.fillMode;
392
- var multiselecttree = (React.createElement("span", { className: classNames('k-multiselect k-input', props.className, (_a = {},
393
- _a["k-input-".concat(sizeMap[size] || size)] = size,
394
- _a["k-rounded-".concat(roundedMap[rounded] || rounded)] = rounded,
395
- _a["k-input-".concat(fillMode)] = fillMode,
396
- _a['k-focus'] = focusedState && !disabled,
397
- _a['k-invalid'] = !isValid,
398
- _a['k-disabled'] = disabled,
399
- _a['k-loading'] = props.loading,
400
- _a['k-required'] = required,
401
- _a)), tabIndex: tabIndex, accessKey: props.accessKey, id: id, style: label ? __assign(__assign({}, style), { width: undefined }) : style, dir: dir, ref: elementRef, onKeyDown: disabled ? undefined : onWrapperKeyDown, onMouseDown: onWrapperMouseDown, onFocus: onFocus, onBlur: onBlur, role: "combobox", "aria-haspopup": "true", "aria-expanded": isOpen, "aria-disabled": disabled, "aria-label": label, "aria-labelledby": props.ariaLabelledBy, "aria-describedby": props.ariaDescribedBy, "aria-required": props.required, onClick: disabled ? undefined : onWrapperClick },
402
- React.createElement("div", { id: 'tagslist-' + id, className: classNames('k-input-values k-chip-list k-selection-multiple', (_b = {},
403
- _b["k-chip-list-".concat(sizeMap[size] || size)] = size,
404
- _b)) }, tagsToRenderRef.current.length > 0 && (React.createElement(TagList, { tag: props.tag, onTagDelete: onTagDelete, data: tagsToRenderRef.current, guid: id, focused: focusedTagState ? tagsToRenderRef.current.find(function (t) { return matchTags(t, focusedTagState, dataItemKey); }) : undefined, size: size }))),
405
- !hasValue &&
406
- React.createElement("span", { className: "k-input-inner", role: 'combobox', tabIndex: tabIndex, "aria-expanded": isOpen, "aria-describedby": 'tagslist-' + id, "aria-label": props.ariaLabelledBy },
407
- React.createElement("span", { className: "k-input-value-text" }, "\u00A0")),
408
- props.loading && React.createElement(IconWrap, { className: "k-input-loading-icon", name: 'loading' }),
409
- hasValue && !disabled && React.createElement(ClearButton, { onClick: onClear }),
410
- React.createElement("select", { name: name, ref: selectRef, tabIndex: -1, "aria-hidden": true, title: label, style: { opacity: 0, width: 1, border: 0, zIndex: -1, position: 'absolute', left: '50%' } },
411
- React.createElement("option", { value: props.valueMap ? props.valueMap.call(undefined, value) : value })),
412
- React.createElement(Popup, { popupClass: classNames(popupSettings.popupClass, 'k-list-container', 'k-multiselecttree-popup'), className: classNames(popupSettings.className, { 'k-rtl': dir === 'rtl' }), style: popupStyles, animate: popupSettings.animate, anchor: elementRef.current, show: isOpen, onOpen: onPopupOpened, onClose: onPopupClosed, appendTo: popupSettings.appendTo, ref: popupRef },
413
- props.filterable && (React.createElement(ListFilter, { value: props.filter === undefined ? filterState : props.filter, inputRef: inputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, tabIndex: tabIndex, size: size, rounded: rounded, fillMode: fillMode })),
414
- data.length > 0 ? (React.createElement(TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(nodata, messages[nodata]))))));
460
+ var currentTagsToRender = isAdaptive && isOpen ? currentTreeValue : tagsToRenderRef.current;
461
+ var multiselecttree = (React.createElement(React.Fragment, null,
462
+ React.createElement("span", { className: classNames('k-multiselect k-input', props.className, (_a = {},
463
+ _a["k-input-".concat(sizeMap[size] || size)] = size,
464
+ _a["k-rounded-".concat(roundedMap[rounded] || rounded)] = rounded,
465
+ _a["k-input-".concat(fillMode)] = fillMode,
466
+ _a['k-focus'] = focusedState && !disabled,
467
+ _a['k-invalid'] = !isValid,
468
+ _a['k-disabled'] = disabled,
469
+ _a['k-loading'] = props.loading,
470
+ _a['k-required'] = required,
471
+ _a)), tabIndex: tabIndex, accessKey: props.accessKey, id: id, style: label ? __assign(__assign({}, style), { width: undefined }) : style, dir: dir, ref: elementRef, onKeyDown: disabled ? undefined : onWrapperKeyDown, onMouseDown: onWrapperMouseDown, onFocus: onFocus, onBlur: onBlur, role: "combobox", "aria-haspopup": "true", "aria-expanded": isOpen, "aria-disabled": disabled, "aria-label": label, "aria-labelledby": props.ariaLabelledBy, "aria-describedby": props.ariaDescribedBy, "aria-required": props.required, onClick: disabled ? undefined : onWrapperClick },
472
+ React.createElement("div", { id: 'tagslist-' + id, className: classNames('k-input-values k-chip-list k-selection-multiple', (_b = {},
473
+ _b["k-chip-list-".concat(sizeMap[size] || size)] = size,
474
+ _b)) }, currentTagsToRender.length > 0 && (React.createElement(TagList, { tag: props.tag, onTagDelete: onTagDelete, data: currentTagsToRender, guid: id, focused: focusedTagState ? tagsToRenderRef.current.find(function (t) { return matchTags(t, focusedTagState, dataItemKey); }) : undefined, size: size }))),
475
+ (!hasValue || isAdaptive) &&
476
+ React.createElement("span", { className: "k-input-inner", role: 'combobox', tabIndex: tabIndex, "aria-expanded": isOpen, "aria-describedby": 'tagslist-' + id, "aria-label": props.ariaLabelledBy },
477
+ React.createElement("span", { className: "k-input-value-text" }, "\u00A0")),
478
+ props.loading && React.createElement(IconWrap, { className: "k-input-loading-icon", name: 'loading' }),
479
+ hasValue && !disabled && currentTagsToRender.length > 0 &&
480
+ React.createElement(ClearButton, { onClick: onClear }),
481
+ React.createElement("select", { name: name, ref: selectRef, tabIndex: -1, "aria-hidden": true, title: label, style: { opacity: 0, width: 1, border: 0, zIndex: -1, position: 'absolute', left: '50%' } },
482
+ React.createElement("option", { value: props.valueMap ? props.valueMap.call(undefined, value) : value })),
483
+ !isAdaptive && React.createElement(Popup, { popupClass: classNames(popupSettings.popupClass, 'k-list-container', 'k-multiselecttree-popup'), className: classNames(popupSettings.className, { 'k-rtl': dir === 'rtl' }), style: popupStyles, animate: popupSettings.animate, anchor: elementRef.current, show: isOpen, onOpen: onPopupOpened, onClose: onPopupClosed, appendTo: popupSettings.appendTo, ref: popupRef },
484
+ props.filterable && (React.createElement(ListFilter, { value: props.filter === undefined ? filterState : props.filter, inputRef: inputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, tabIndex: tabIndex, size: size, rounded: rounded, fillMode: fillMode })),
485
+ data.length > 0 ? (React.createElement(TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(nodata, messages[nodata]))))),
486
+ isAdaptive && renderAdaptiveListContainer()));
415
487
  return label ? (React.createElement(FloatingLabel, { label: label, editorValue: hasValue, editorPlaceholder: placeholder, editorValid: isValid, editorDisabled: disabled, editorId: id, style: { width: style ? style.width : undefined }, children: multiselecttree, dir: dir })) : multiselecttree;
416
488
  });
417
489
  var propTypes = {
@@ -466,8 +538,11 @@ var propTypes = {
466
538
  onChange: PropTypes.func,
467
539
  onFilterChange: PropTypes.func,
468
540
  onExpandChange: PropTypes.func,
541
+ onCancel: PropTypes.func,
469
542
  item: PropTypes.func,
470
- listNoData: PropTypes.func
543
+ listNoData: PropTypes.func,
544
+ adaptiveTitle: PropTypes.string,
545
+ adaptive: PropTypes.bool
471
546
  };
472
547
  MultiSelectTree.displayName = 'KendoReactMultiSelectTree';
473
548
  MultiSelectTree.defaultProps = defaultProps;
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { FormComponentProps } from '@progress/kendo-react-common';
3
3
  import { ItemRenderProps } from '@progress/kendo-react-treeview';
4
- import { FilterChangeEvent, OpenEvent, CloseEvent, FocusEvent, BlurEvent, DropdownEvent } from '../common/events';
4
+ import { FilterChangeEvent, OpenEvent, CloseEvent, FocusEvent, BlurEvent, DropdownEvent, CancelEvent } from '../common/events';
5
5
  import { DropDownsPopupSettings } from '../common/settings';
6
6
  import { TagData } from '../MultiSelect/TagList';
7
7
  /**
@@ -64,6 +64,11 @@ export interface MultiSelectTreeFocusEvent extends FocusEvent<MultiSelectTreeHan
64
64
  */
65
65
  export interface MultiSelectTreeBlurEvent extends BlurEvent<MultiSelectTreeHandle> {
66
66
  }
67
+ /**
68
+ * Represents the object of the `onCancel` MultiSelectTree event.
69
+ */
70
+ export interface MultiSelectTreeCancelEvent extends CancelEvent<MultiSelectTreeHandle> {
71
+ }
67
72
  /**
68
73
  * Represents the object of the `onExpandChange` MultiSelectTree event.
69
74
  */
@@ -242,6 +247,10 @@ export interface MultiSelectTreeProps extends FormComponentProps {
242
247
  * Fires each time the value of the MultiSelectTree is about to change ([see examples]({% slug overview_multiselecttree %})).
243
248
  */
244
249
  onChange?: (event: MultiSelectTreeChangeEvent) => void;
250
+ /**
251
+ * Fires each time the popup of the MultiSelectTree is about to cancel in ([adaptive mode]({% slug adaptive_rendering_multiselecttree %})).
252
+ */
253
+ onCancel?: (event: MultiSelectTreeCancelEvent) => void;
245
254
  /**
246
255
  * Fires each time the user types in the filter input
247
256
  * ([see example]({% slug filtering_multiselecttree %}#toc-basic-configuration)).
@@ -300,4 +309,12 @@ export interface MultiSelectTreeProps extends FormComponentProps {
300
309
  * @default `solid`
301
310
  */
302
311
  fillMode?: null | 'solid' | 'flat' | 'outline';
312
+ /**
313
+ * Providing different rendering of the popup element based on the screen dimensions.
314
+ */
315
+ adaptive?: boolean;
316
+ /**
317
+ * Specifies the text that is rendered as title in the adaptive popup.
318
+ */
319
+ adaptiveTitle?: string | React.ReactNode;
303
320
  }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ /** @hidden */
3
+ export interface AdaptiveModeProps {
4
+ navigatable?: boolean;
5
+ navigatableElements?: string[];
6
+ expand: boolean;
7
+ animation?: boolean;
8
+ adaptiveTitle?: string | React.ReactNode;
9
+ onClose?: (event: React.SyntheticEvent) => void;
10
+ windowWidth?: number;
11
+ mobileFilter?: React.ReactNode;
12
+ children: React.ReactNode;
13
+ footer?: {
14
+ cancelText: string;
15
+ onCancel: (event: React.SyntheticEvent) => void;
16
+ applyText: string;
17
+ onApply: (event: React.SyntheticEvent) => void;
18
+ };
19
+ }
20
+ /** @hidden */
21
+ export declare const AdaptiveMode: (props: AdaptiveModeProps) => JSX.Element;
@@ -0,0 +1,45 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import * as React from 'react';
13
+ import { ActionSheet, ActionSheetFooter, ActionSheetHeader } from '@progress/kendo-react-layout';
14
+ import { xIcon } from '@progress/kendo-svg-icons';
15
+ import { Button } from '@progress/kendo-react-buttons';
16
+ /** @hidden */
17
+ var MOBILE_SMALL_DEVISE = 500;
18
+ /** @hidden */
19
+ export var AdaptiveMode = function (props) {
20
+ var footer = props.footer, children = props.children, _a = props.windowWidth, windowWidth = _a === void 0 ? 0 : _a, navigatable = props.navigatable, navigatableElements = props.navigatableElements, expand = props.expand, animation = props.animation, onClose = props.onClose, adaptiveTitle = props.adaptiveTitle, mobileFilter = props.mobileFilter;
21
+ var defaultProps = {
22
+ navigatable: navigatable || false,
23
+ navigatableElements: navigatableElements || [],
24
+ expand: expand,
25
+ animation: animation || true,
26
+ onClose: onClose,
27
+ animationStyles: windowWidth <= MOBILE_SMALL_DEVISE ? { top: 0, width: '100%', height: '100%' } : undefined,
28
+ className: windowWidth <= MOBILE_SMALL_DEVISE
29
+ ? 'k-adaptive-actionsheet k-actionsheet-fullscreen'
30
+ : 'k-adaptive-actionsheet k-actionsheet-bottom'
31
+ };
32
+ return (React.createElement(ActionSheet, __assign({}, defaultProps),
33
+ React.createElement(ActionSheetHeader, { className: 'k-text-center' },
34
+ React.createElement("div", { className: "k-actionsheet-titlebar-group k-hbox" },
35
+ React.createElement("div", { className: "k-actionsheet-title" },
36
+ React.createElement("div", null, adaptiveTitle)),
37
+ React.createElement("div", { className: "k-actionsheet-actions" },
38
+ React.createElement(Button, { tabIndex: 0, "aria-label": "Cancel", "aria-disabled": "false", type: "button", fillMode: "flat", icon: 'x', svgIcon: xIcon, onClick: onClose }))),
39
+ mobileFilter &&
40
+ React.createElement("div", { className: "k-actionsheet-titlebar-group k-actionsheet-filter" }, mobileFilter)),
41
+ children,
42
+ footer && React.createElement(ActionSheetFooter, { className: 'k-actions k-actions-stretched' },
43
+ React.createElement(Button, { size: "large", tabIndex: 0, "aria-label": footer.cancelText, "aria-disabled": "false", type: "button", onClick: function (event) { return footer.onCancel(event); } }, footer.cancelText),
44
+ React.createElement(Button, { tabIndex: 0, themeColor: "primary", size: "large", "aria-label": footer.applyText, "aria-disabled": "false", type: "button", onClick: function (event) { return footer.onApply(event); } }, footer.applyText))));
45
+ };
@@ -60,6 +60,11 @@ export interface FocusEvent<T> extends DropdownEvent<T> {
60
60
  */
61
61
  export interface BlurEvent<T> extends DropdownEvent<T> {
62
62
  }
63
+ /**
64
+ * @hidden
65
+ */
66
+ export interface CancelEvent<T> extends DropdownEvent<T> {
67
+ }
63
68
  /**
64
69
  * @hidden
65
70
  */
@@ -18,6 +18,14 @@ export declare const comboArrowBtnAriaLabelCollapse = "dropdowns.comboArrowBtnAr
18
18
  * @hidden
19
19
  */
20
20
  export declare const dropDownListArrowBtnAriaLabel = "dropdowns.dropDownListArrowBtnAriaLabel";
21
+ /**
22
+ * @hidden
23
+ */
24
+ export declare const adaptiveModeFooterApply = "dropdowns.apply";
25
+ /**
26
+ * @hidden
27
+ */
28
+ export declare const adaptiveModeFooterCancel = "dropdowns.cancel";
21
29
  /**
22
30
  * @hidden
23
31
  */
@@ -27,4 +35,6 @@ export declare const messages: {
27
35
  "dropdowns.comboArrowBtnAriaLabelExpand": string;
28
36
  "dropdowns.comboArrowBtnAriaLabelCollapse": string;
29
37
  "dropdowns.dropDownListArrowBtnAriaLabel": string;
38
+ "dropdowns.apply": string;
39
+ "dropdowns.cancel": string;
30
40
  };
@@ -19,6 +19,14 @@ export var comboArrowBtnAriaLabelCollapse = 'dropdowns.comboArrowBtnAriaLabelCol
19
19
  * @hidden
20
20
  */
21
21
  export var dropDownListArrowBtnAriaLabel = 'dropdowns.dropDownListArrowBtnAriaLabel';
22
+ /**
23
+ * @hidden
24
+ */
25
+ export var adaptiveModeFooterApply = 'dropdowns.apply';
26
+ /**
27
+ * @hidden
28
+ */
29
+ export var adaptiveModeFooterCancel = 'dropdowns.cancel';
22
30
  /**
23
31
  * @hidden
24
32
  */
@@ -28,4 +36,6 @@ export var messages = (_a = {},
28
36
  _a[comboArrowBtnAriaLabelExpand] = 'expand combobox',
29
37
  _a[comboArrowBtnAriaLabelCollapse] = 'collapse combobox',
30
38
  _a[dropDownListArrowBtnAriaLabel] = 'select',
39
+ _a[adaptiveModeFooterApply] = 'Apply',
40
+ _a[adaptiveModeFooterCancel] = 'Cancel',
31
41
  _a);
@@ -5,7 +5,7 @@ export var packageMetadata = {
5
5
  name: '@progress/kendo-react-dropdowns',
6
6
  productName: 'KendoReact',
7
7
  productCodes: ['KENDOUIREACT', 'KENDOUICOMPLETE'],
8
- publishDate: 1680692409,
8
+ publishDate: 1681383607,
9
9
  version: '',
10
10
  licensingDocsUrl: 'https://www.telerik.com/kendo-react-ui/my-license/?utm_medium=product&utm_source=kendoreact&utm_campaign=kendo-ui-react-purchase-license-keys-warning'
11
11
  };
@@ -19,6 +19,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
19
  }
20
20
  return to.concat(ar || Array.prototype.slice.call(from));
21
21
  };
22
+ var _this = this;
22
23
  Object.defineProperty(exports, "__esModule", { value: true });
23
24
  exports.MultiSelectTree = exports.MultiSelectTreePropsContext = void 0;
24
25
  var React = require("react");
@@ -37,6 +38,9 @@ var kendo_react_labels_1 = require("@progress/kendo-react-labels");
37
38
  var TagList_1 = require("../MultiSelect/TagList");
38
39
  var ClearButton_1 = require("../common/ClearButton");
39
40
  var ListFilter_1 = require("../common/ListFilter");
41
+ var AdaptiveMode_1 = require("../common/AdaptiveMode");
42
+ var kendo_react_layout_1 = require("@progress/kendo-react-layout");
43
+ var constants_1 = require("../common/constants");
40
44
  var VALIDATION_MESSAGE = 'Please select a value from the list!';
41
45
  var sizeMap = kendo_react_common_1.kendoThemeMaps.sizeMap, roundedMap = kendo_react_common_1.kendoThemeMaps.roundedMap;
42
46
  var toLevel = function (hierarchicalIndex) {
@@ -89,6 +93,7 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
89
93
  var targetRef = React.useRef(null);
90
94
  var elementRef = React.useRef(null);
91
95
  var inputRef = React.useRef(null);
96
+ var adaptiveInputRef = React.useRef(null);
92
97
  var selectRef = React.useRef(null);
93
98
  var treeViewRef = React.useRef(null);
94
99
  var skipFocusRef = React.useRef(false);
@@ -98,6 +103,9 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
98
103
  var _p = React.useState(false), openState = _p[0], setOpenState = _p[1];
99
104
  var _q = React.useState(false), focusedState = _q[0], setFocusedState = _q[1];
100
105
  var _r = React.useState(''), filterState = _r[0], setFilterState = _r[1];
106
+ var _s = React.useState(), windowWidth = _s[0], setWindowWidth = _s[1];
107
+ var _t = React.useState([]), currentTreeValue = _t[0], setCurrentTreeValue = _t[1];
108
+ var isAdaptive = !!(windowWidth && windowWidth <= constants_1.MOBILE_MEDIUM_DEVISE && props.adaptive);
101
109
  var isOpen = opened !== undefined ? opened : openState;
102
110
  var hasValue = Boolean(Array.isArray(value) && value.length);
103
111
  var validity = getValidity({ validationMessage: validationMessage, valid: valid, required: required }, hasValue);
@@ -123,6 +131,15 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
123
131
  }
124
132
  }, [validationMessage, validity]);
125
133
  React.useEffect(setValidity);
134
+ React.useEffect(function () {
135
+ var observerResize = kendo_react_common_1.canUseDOM && window.ResizeObserver && new window.ResizeObserver(calculateMedia.bind(_this));
136
+ if ((document === null || document === void 0 ? void 0 : document.body) && observerResize) {
137
+ observerResize.observe(document.body);
138
+ }
139
+ return function () {
140
+ observerResize.disconnect();
141
+ };
142
+ }, []);
126
143
  React.useEffect(function () {
127
144
  if (popupRef.current && isOpen) {
128
145
  popupRef.current.setPosition(popupRef.current._popup);
@@ -154,9 +171,15 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
154
171
  }
155
172
  if (opened === undefined) {
156
173
  setOpenState(true);
174
+ setCurrentTreeValue(value || []);
175
+ if (isAdaptive) {
176
+ setTimeout(function () {
177
+ focusElement(adaptiveInputRef.current);
178
+ }, 300);
179
+ }
157
180
  }
158
181
  }
159
- }, [isOpen, opened, onOpen]);
182
+ }, [isOpen, opened, onOpen, isAdaptive]);
160
183
  var closePopup = React.useCallback(function (event) {
161
184
  if (isOpen) {
162
185
  if (onClose) {
@@ -222,7 +245,9 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
222
245
  var focusEvent = __assign({}, ev);
223
246
  props.onBlur.call(undefined, focusEvent);
224
247
  }
225
- closePopup(ev);
248
+ if (!isAdaptive) {
249
+ closePopup(ev);
250
+ }
226
251
  }
227
252
  }, [focusedState, props.onBlur, isOpen, opened, onClose]);
228
253
  var onWrapperMouseDown = React.useCallback(function () {
@@ -388,33 +413,80 @@ exports.MultiSelectTree = React.forwardRef(function (directProps, ref) {
388
413
  }
389
414
  }
390
415
  }, [props.onFilterChange, props.filter, props.textField]);
416
+ var onCancel = React.useCallback(function (event) {
417
+ if (!targetRef.current) {
418
+ return;
419
+ }
420
+ var ev = {
421
+ syntheticEvent: event,
422
+ nativeEvent: event.nativeEvent,
423
+ target: targetRef.current
424
+ };
425
+ if (props.onCancel) {
426
+ props.onCancel.call(undefined, ev);
427
+ }
428
+ ;
429
+ closePopup(ev);
430
+ event.preventDefault();
431
+ }, [props.onCancel, closePopup]);
432
+ var renderAdaptiveListContainer = function () {
433
+ var mobileFilter = props.filterable ? (React.createElement(ListFilter_1.default, { value: props.filter === undefined ? filterState : props.filter, inputRef: adaptiveInputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, size: size, rounded: rounded, fillMode: fillMode })) : null;
434
+ var actionSheetProps = {
435
+ adaptiveTitle: props.adaptiveTitle,
436
+ expand: isOpen,
437
+ onClose: function (event) { return props.onCancel ? onCancel(event) : onClear(event); },
438
+ windowWidth: windowWidth,
439
+ mobileFilter: mobileFilter,
440
+ footer: {
441
+ cancelText: localization.toLanguageString(messages_1.adaptiveModeFooterCancel, messages_1.messages[messages_1.adaptiveModeFooterCancel]),
442
+ onCancel: function (event) { return props.onCancel ? onCancel(event) : onClear(event); },
443
+ applyText: localization.toLanguageString(messages_1.adaptiveModeFooterApply, messages_1.messages[messages_1.adaptiveModeFooterApply]),
444
+ onApply: function (event) { return closePopup(event); }
445
+ }
446
+ };
447
+ return (React.createElement(AdaptiveMode_1.AdaptiveMode, __assign({}, actionSheetProps),
448
+ React.createElement(kendo_react_layout_1.ActionSheetContent, { className: '!k-overflow-hidden' },
449
+ React.createElement("div", { className: 'k-list-container' },
450
+ React.createElement("div", { className: 'k-list k-list-lg' }, data.length > 0 ? (React.createElement(kendo_react_treeview_1.TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(messages_1.nodata, messages_1.messages[messages_1.nodata]))))))));
451
+ };
452
+ var calculateMedia = React.useCallback(function (entries) {
453
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
454
+ var entry = entries_1[_i];
455
+ setWindowWidth(entry.target.clientWidth);
456
+ }
457
+ ;
458
+ }, []);
391
459
  var NoData = props.listNoData || ListNoData_1.ListNoData;
392
460
  var localization = (0, kendo_react_intl_1.useLocalization)();
393
461
  var isValid = !validityStyles || validity.valid;
394
462
  var size = props.size, rounded = props.rounded, fillMode = props.fillMode;
395
- var multiselecttree = (React.createElement("span", { className: (0, kendo_react_common_1.classNames)('k-multiselect k-input', props.className, (_a = {},
396
- _a["k-input-".concat(sizeMap[size] || size)] = size,
397
- _a["k-rounded-".concat(roundedMap[rounded] || rounded)] = rounded,
398
- _a["k-input-".concat(fillMode)] = fillMode,
399
- _a['k-focus'] = focusedState && !disabled,
400
- _a['k-invalid'] = !isValid,
401
- _a['k-disabled'] = disabled,
402
- _a['k-loading'] = props.loading,
403
- _a['k-required'] = required,
404
- _a)), tabIndex: tabIndex, accessKey: props.accessKey, id: id, style: label ? __assign(__assign({}, style), { width: undefined }) : style, dir: dir, ref: elementRef, onKeyDown: disabled ? undefined : onWrapperKeyDown, onMouseDown: onWrapperMouseDown, onFocus: onFocus, onBlur: onBlur, role: "combobox", "aria-haspopup": "true", "aria-expanded": isOpen, "aria-disabled": disabled, "aria-label": label, "aria-labelledby": props.ariaLabelledBy, "aria-describedby": props.ariaDescribedBy, "aria-required": props.required, onClick: disabled ? undefined : onWrapperClick },
405
- React.createElement("div", { id: 'tagslist-' + id, className: (0, kendo_react_common_1.classNames)('k-input-values k-chip-list k-selection-multiple', (_b = {},
406
- _b["k-chip-list-".concat(sizeMap[size] || size)] = size,
407
- _b)) }, tagsToRenderRef.current.length > 0 && (React.createElement(TagList_1.default, { tag: props.tag, onTagDelete: onTagDelete, data: tagsToRenderRef.current, guid: id, focused: focusedTagState ? tagsToRenderRef.current.find(function (t) { return (0, utils_1.matchTags)(t, focusedTagState, dataItemKey); }) : undefined, size: size }))),
408
- !hasValue &&
409
- React.createElement("span", { className: "k-input-inner", role: 'combobox', tabIndex: tabIndex, "aria-expanded": isOpen, "aria-describedby": 'tagslist-' + id, "aria-label": props.ariaLabelledBy },
410
- React.createElement("span", { className: "k-input-value-text" }, "\u00A0")),
411
- props.loading && React.createElement(kendo_react_common_1.IconWrap, { className: "k-input-loading-icon", name: 'loading' }),
412
- hasValue && !disabled && React.createElement(ClearButton_1.default, { onClick: onClear }),
413
- React.createElement("select", { name: name, ref: selectRef, tabIndex: -1, "aria-hidden": true, title: label, style: { opacity: 0, width: 1, border: 0, zIndex: -1, position: 'absolute', left: '50%' } },
414
- React.createElement("option", { value: props.valueMap ? props.valueMap.call(undefined, value) : value })),
415
- React.createElement(kendo_react_popup_1.Popup, { popupClass: (0, kendo_react_common_1.classNames)(popupSettings.popupClass, 'k-list-container', 'k-multiselecttree-popup'), className: (0, kendo_react_common_1.classNames)(popupSettings.className, { 'k-rtl': dir === 'rtl' }), style: popupStyles, animate: popupSettings.animate, anchor: elementRef.current, show: isOpen, onOpen: onPopupOpened, onClose: onPopupClosed, appendTo: popupSettings.appendTo, ref: popupRef },
416
- props.filterable && (React.createElement(ListFilter_1.default, { value: props.filter === undefined ? filterState : props.filter, inputRef: inputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, tabIndex: tabIndex, size: size, rounded: rounded, fillMode: fillMode })),
417
- data.length > 0 ? (React.createElement(kendo_react_treeview_1.TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(messages_1.nodata, messages_1.messages[messages_1.nodata]))))));
463
+ var currentTagsToRender = isAdaptive && isOpen ? currentTreeValue : tagsToRenderRef.current;
464
+ var multiselecttree = (React.createElement(React.Fragment, null,
465
+ React.createElement("span", { className: (0, kendo_react_common_1.classNames)('k-multiselect k-input', props.className, (_a = {},
466
+ _a["k-input-".concat(sizeMap[size] || size)] = size,
467
+ _a["k-rounded-".concat(roundedMap[rounded] || rounded)] = rounded,
468
+ _a["k-input-".concat(fillMode)] = fillMode,
469
+ _a['k-focus'] = focusedState && !disabled,
470
+ _a['k-invalid'] = !isValid,
471
+ _a['k-disabled'] = disabled,
472
+ _a['k-loading'] = props.loading,
473
+ _a['k-required'] = required,
474
+ _a)), tabIndex: tabIndex, accessKey: props.accessKey, id: id, style: label ? __assign(__assign({}, style), { width: undefined }) : style, dir: dir, ref: elementRef, onKeyDown: disabled ? undefined : onWrapperKeyDown, onMouseDown: onWrapperMouseDown, onFocus: onFocus, onBlur: onBlur, role: "combobox", "aria-haspopup": "true", "aria-expanded": isOpen, "aria-disabled": disabled, "aria-label": label, "aria-labelledby": props.ariaLabelledBy, "aria-describedby": props.ariaDescribedBy, "aria-required": props.required, onClick: disabled ? undefined : onWrapperClick },
475
+ React.createElement("div", { id: 'tagslist-' + id, className: (0, kendo_react_common_1.classNames)('k-input-values k-chip-list k-selection-multiple', (_b = {},
476
+ _b["k-chip-list-".concat(sizeMap[size] || size)] = size,
477
+ _b)) }, currentTagsToRender.length > 0 && (React.createElement(TagList_1.default, { tag: props.tag, onTagDelete: onTagDelete, data: currentTagsToRender, guid: id, focused: focusedTagState ? tagsToRenderRef.current.find(function (t) { return (0, utils_1.matchTags)(t, focusedTagState, dataItemKey); }) : undefined, size: size }))),
478
+ (!hasValue || isAdaptive) &&
479
+ React.createElement("span", { className: "k-input-inner", role: 'combobox', tabIndex: tabIndex, "aria-expanded": isOpen, "aria-describedby": 'tagslist-' + id, "aria-label": props.ariaLabelledBy },
480
+ React.createElement("span", { className: "k-input-value-text" }, "\u00A0")),
481
+ props.loading && React.createElement(kendo_react_common_1.IconWrap, { className: "k-input-loading-icon", name: 'loading' }),
482
+ hasValue && !disabled && currentTagsToRender.length > 0 &&
483
+ React.createElement(ClearButton_1.default, { onClick: onClear }),
484
+ React.createElement("select", { name: name, ref: selectRef, tabIndex: -1, "aria-hidden": true, title: label, style: { opacity: 0, width: 1, border: 0, zIndex: -1, position: 'absolute', left: '50%' } },
485
+ React.createElement("option", { value: props.valueMap ? props.valueMap.call(undefined, value) : value })),
486
+ !isAdaptive && React.createElement(kendo_react_popup_1.Popup, { popupClass: (0, kendo_react_common_1.classNames)(popupSettings.popupClass, 'k-list-container', 'k-multiselecttree-popup'), className: (0, kendo_react_common_1.classNames)(popupSettings.className, { 'k-rtl': dir === 'rtl' }), style: popupStyles, animate: popupSettings.animate, anchor: elementRef.current, show: isOpen, onOpen: onPopupOpened, onClose: onPopupClosed, appendTo: popupSettings.appendTo, ref: popupRef },
487
+ props.filterable && (React.createElement(ListFilter_1.default, { value: props.filter === undefined ? filterState : props.filter, inputRef: inputRef, onChange: onFilterChange, onKeyDown: onInputKeyDown, tabIndex: tabIndex, size: size, rounded: rounded, fillMode: fillMode })),
488
+ data.length > 0 ? (React.createElement(kendo_react_treeview_1.TreeView, { ref: treeViewRef, tabIndex: tabIndex, data: data, focusIdField: dataItemKey, textField: props.textField, checkField: checkField, checkIndeterminateField: checkIndeterminateField, expandField: props.expandField, childrenField: subItemsField, expandIcons: true, onItemClick: onChange, onCheckChange: onChange, onExpandChange: onExpand, checkboxes: true, size: size, item: props.item })) : (React.createElement(NoData, null, localization.toLanguageString(messages_1.nodata, messages_1.messages[messages_1.nodata]))))),
489
+ isAdaptive && renderAdaptiveListContainer()));
418
490
  return label ? (React.createElement(kendo_react_labels_1.FloatingLabel, { label: label, editorValue: hasValue, editorPlaceholder: placeholder, editorValid: isValid, editorDisabled: disabled, editorId: id, style: { width: style ? style.width : undefined }, children: multiselecttree, dir: dir })) : multiselecttree;
419
491
  });
420
492
  var propTypes = {
@@ -469,8 +541,11 @@ var propTypes = {
469
541
  onChange: PropTypes.func,
470
542
  onFilterChange: PropTypes.func,
471
543
  onExpandChange: PropTypes.func,
544
+ onCancel: PropTypes.func,
472
545
  item: PropTypes.func,
473
- listNoData: PropTypes.func
546
+ listNoData: PropTypes.func,
547
+ adaptiveTitle: PropTypes.string,
548
+ adaptive: PropTypes.bool
474
549
  };
475
550
  exports.MultiSelectTree.displayName = 'KendoReactMultiSelectTree';
476
551
  exports.MultiSelectTree.defaultProps = defaultProps;