@vkontakte/vkui 6.7.0 → 6.7.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 (133) hide show
  1. package/dist/cjs/components/AppRoot/AppRoot.d.ts.map +1 -1
  2. package/dist/cjs/components/AppRoot/AppRoot.js +9 -3
  3. package/dist/cjs/components/AppRoot/AppRoot.js.map +1 -1
  4. package/dist/cjs/components/BaseGallery/CarouselBase/CarouselBase.d.ts.map +1 -1
  5. package/dist/cjs/components/BaseGallery/CarouselBase/CarouselBase.js +9 -0
  6. package/dist/cjs/components/BaseGallery/CarouselBase/CarouselBase.js.map +1 -1
  7. package/dist/cjs/components/CustomSelect/CustomSelect.d.ts +12 -2
  8. package/dist/cjs/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  9. package/dist/cjs/components/CustomSelect/CustomSelect.js +72 -52
  10. package/dist/cjs/components/CustomSelect/CustomSelect.js.map +1 -1
  11. package/dist/cjs/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  12. package/dist/cjs/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  13. package/dist/cjs/components/CustomSelect/CustomSelectInput.js +24 -19
  14. package/dist/cjs/components/CustomSelect/CustomSelectInput.js.map +1 -1
  15. package/dist/cjs/components/HorizontalScroll/HorizontalScroll.d.ts +0 -2
  16. package/dist/cjs/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
  17. package/dist/cjs/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  18. package/dist/cjs/components/Select/Select.js +2 -1
  19. package/dist/cjs/components/Select/Select.js.map +1 -1
  20. package/dist/cjs/components/SimpleCell/SimpleCell.d.ts +4 -2
  21. package/dist/cjs/components/SimpleCell/SimpleCell.d.ts.map +1 -1
  22. package/dist/cjs/components/SimpleCell/SimpleCell.js.map +1 -1
  23. package/dist/cjs/components/Spacing/Spacing.js +1 -1
  24. package/dist/cjs/components/Spacing/Spacing.js.map +1 -1
  25. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  26. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +3 -0
  27. package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  28. package/dist/components/AppRoot/AppRoot.d.ts.map +1 -1
  29. package/dist/components/AppRoot/AppRoot.js +9 -3
  30. package/dist/components/AppRoot/AppRoot.js.map +1 -1
  31. package/dist/components/BaseGallery/CarouselBase/CarouselBase.d.ts.map +1 -1
  32. package/dist/components/BaseGallery/CarouselBase/CarouselBase.js +10 -1
  33. package/dist/components/BaseGallery/CarouselBase/CarouselBase.js.map +1 -1
  34. package/dist/components/CustomSelect/CustomSelect.d.ts +12 -2
  35. package/dist/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  36. package/dist/components/CustomSelect/CustomSelect.js +64 -44
  37. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  38. package/dist/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  39. package/dist/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  40. package/dist/components/CustomSelect/CustomSelectInput.js +24 -19
  41. package/dist/components/CustomSelect/CustomSelectInput.js.map +1 -1
  42. package/dist/components/HorizontalScroll/HorizontalScroll.d.ts +0 -2
  43. package/dist/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
  44. package/dist/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  45. package/dist/components/Select/Select.js +2 -1
  46. package/dist/components/Select/Select.js.map +1 -1
  47. package/dist/components/SimpleCell/SimpleCell.d.ts +4 -2
  48. package/dist/components/SimpleCell/SimpleCell.d.ts.map +1 -1
  49. package/dist/components/SimpleCell/SimpleCell.js.map +1 -1
  50. package/dist/components/Spacing/Spacing.js +1 -1
  51. package/dist/components/Spacing/Spacing.js.map +1 -1
  52. package/dist/components.css +3 -3
  53. package/dist/components.css.map +1 -1
  54. package/dist/components.js.tmp +128 -162
  55. package/dist/cssm/components/AppRoot/AppRoot.d.ts.map +1 -1
  56. package/dist/cssm/components/AppRoot/AppRoot.js +9 -3
  57. package/dist/cssm/components/AppRoot/AppRoot.js.map +1 -1
  58. package/dist/cssm/components/BaseGallery/CarouselBase/CarouselBase.d.ts.map +1 -1
  59. package/dist/cssm/components/BaseGallery/CarouselBase/CarouselBase.js +10 -1
  60. package/dist/cssm/components/BaseGallery/CarouselBase/CarouselBase.js.map +1 -1
  61. package/dist/cssm/components/CellButton/CellButton.module.css +9 -2
  62. package/dist/cssm/components/CustomSelect/CustomSelect.d.ts +12 -2
  63. package/dist/cssm/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  64. package/dist/cssm/components/CustomSelect/CustomSelect.js +60 -41
  65. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  66. package/dist/cssm/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  67. package/dist/cssm/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  68. package/dist/cssm/components/CustomSelect/CustomSelectInput.js +21 -16
  69. package/dist/cssm/components/CustomSelect/CustomSelectInput.js.map +1 -1
  70. package/dist/cssm/components/CustomSelect/CustomSelectInput.module.css +40 -74
  71. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.d.ts +0 -2
  72. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
  73. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  74. package/dist/cssm/components/Select/Select.js +2 -1
  75. package/dist/cssm/components/Select/Select.js.map +1 -1
  76. package/dist/cssm/components/SimpleCell/SimpleCell.d.ts +4 -2
  77. package/dist/cssm/components/SimpleCell/SimpleCell.d.ts.map +1 -1
  78. package/dist/cssm/components/SimpleCell/SimpleCell.js.map +1 -1
  79. package/dist/cssm/components/SimpleCell/SimpleCell.module.css +4 -2
  80. package/dist/cssm/components/Spacing/Spacing.js +1 -1
  81. package/dist/cssm/components/Spacing/Spacing.js.map +1 -1
  82. package/dist/cssm/components/Spacing/Spacing.module.css +1 -2
  83. package/dist/cssm/components/TabsItem/TabsItem.module.css +1 -1
  84. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  85. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +3 -0
  86. package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  87. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
  88. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +3 -0
  89. package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
  90. package/dist/vkui.css +3 -3
  91. package/dist/vkui.css.map +1 -1
  92. package/dist/vkui.js.tmp +128 -162
  93. package/package.json +1 -1
  94. package/src/components/AppRoot/AppRoot.tsx +16 -13
  95. package/src/components/BaseGallery/CarouselBase/CarouselBase.tsx +16 -1
  96. package/src/components/CellButton/CellButton.module.css +5 -1
  97. package/src/components/CustomSelect/CustomSelect.tsx +101 -53
  98. package/src/components/CustomSelect/CustomSelectInput.module.css +35 -55
  99. package/src/components/CustomSelect/CustomSelectInput.tsx +35 -24
  100. package/src/components/HorizontalScroll/HorizontalScroll.tsx +0 -2
  101. package/src/components/Select/Select.tsx +2 -2
  102. package/src/components/SimpleCell/SimpleCell.module.css +3 -1
  103. package/src/components/SimpleCell/SimpleCell.tsx +4 -2
  104. package/src/components/Spacing/Spacing.module.css +1 -2
  105. package/src/components/Spacing/Spacing.tsx +1 -1
  106. package/src/components/TabsItem/TabsItem.module.css +1 -1
  107. package/src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts +3 -0
  108. package/dist/cjs/components/CustomSelect/helpers.d.ts +0 -8
  109. package/dist/cjs/components/CustomSelect/helpers.d.ts.map +0 -1
  110. package/dist/cjs/components/CustomSelect/helpers.js +0 -76
  111. package/dist/cjs/components/CustomSelect/helpers.js.map +0 -1
  112. package/dist/cjs/components/CustomSelect/types.d.ts +0 -12
  113. package/dist/cjs/components/CustomSelect/types.d.ts.map +0 -1
  114. package/dist/cjs/components/CustomSelect/types.js +0 -6
  115. package/dist/cjs/components/CustomSelect/types.js.map +0 -1
  116. package/dist/components/CustomSelect/helpers.d.ts +0 -8
  117. package/dist/components/CustomSelect/helpers.d.ts.map +0 -1
  118. package/dist/components/CustomSelect/helpers.js +0 -48
  119. package/dist/components/CustomSelect/helpers.js.map +0 -1
  120. package/dist/components/CustomSelect/types.d.ts +0 -12
  121. package/dist/components/CustomSelect/types.d.ts.map +0 -1
  122. package/dist/components/CustomSelect/types.js +0 -3
  123. package/dist/components/CustomSelect/types.js.map +0 -1
  124. package/dist/cssm/components/CustomSelect/helpers.d.ts +0 -8
  125. package/dist/cssm/components/CustomSelect/helpers.d.ts.map +0 -1
  126. package/dist/cssm/components/CustomSelect/helpers.js +0 -44
  127. package/dist/cssm/components/CustomSelect/helpers.js.map +0 -1
  128. package/dist/cssm/components/CustomSelect/types.d.ts +0 -12
  129. package/dist/cssm/components/CustomSelect/types.d.ts.map +0 -1
  130. package/dist/cssm/components/CustomSelect/types.js +0 -3
  131. package/dist/cssm/components/CustomSelect/types.js.map +0 -1
  132. package/src/components/CustomSelect/helpers.tsx +0 -61
  133. package/src/components/CustomSelect/types.ts +0 -15
package/dist/vkui.js.tmp CHANGED
@@ -5671,8 +5671,8 @@ function AppRoot_unsupported_iterable_to_array(o, minLen) {
5671
5671
  }, [
5672
5672
  scroll
5673
5673
  ]);
5674
- var content = /*#__PURE__*/ React.createElement(AppRootContext.Provider, {
5675
- value: {
5674
+ var contextValue = React.useMemo(function() {
5675
+ return {
5676
5676
  appRoot: appRootRef,
5677
5677
  portalRoot: portalRootRef,
5678
5678
  embedded: mode === 'embedded',
@@ -5682,7 +5682,15 @@ function AppRoot_unsupported_iterable_to_array(o, minLen) {
5682
5682
  get keyboardInput () {
5683
5683
  return isKeyboardInputActiveRef.current;
5684
5684
  }
5685
- }
5685
+ };
5686
+ }, [
5687
+ disablePortal,
5688
+ isKeyboardInputActiveRef,
5689
+ layout,
5690
+ mode
5691
+ ]);
5692
+ var content = /*#__PURE__*/ React.createElement(AppRootContext.Provider, {
5693
+ value: contextValue
5686
5694
  }, /*#__PURE__*/ React.createElement(ScrollController, {
5687
5695
  elRef: appRootRef
5688
5696
  }, children));
@@ -13653,6 +13661,9 @@ var whileElementsMounted = function() {
13653
13661
  var handleFocusOnReference = useStableCallback(function() {
13654
13662
  // Повторный вызов события фокуса - следствие клика на reference-элемент
13655
13663
  if (shownLocalState.shown) {
13664
+ if (!closeAfterClick && shownLocalState.reason === 'hover') {
13665
+ return;
13666
+ }
13656
13667
  commitShownLocalState(false, 'focus');
13657
13668
  return;
13658
13669
  }
@@ -15070,7 +15081,7 @@ var sizesClassNames = {
15070
15081
  "style"
15071
15082
  ]);
15072
15083
  return /*#__PURE__*/ React.createElement(RootComponent, Spacing_object_spread_props(Spacing_object_spread({}, restProps), {
15073
- style: Spacing_object_spread({}, typeof size === 'number' && Spacing_define_property({}, CUSTOM_CSS_TOKEN_FOR_USER_GAP, size), style),
15084
+ style: Spacing_object_spread({}, typeof size === 'number' && Spacing_define_property({}, CUSTOM_CSS_TOKEN_FOR_USER_GAP, "".concat(size, "px")), style),
15074
15085
  baseClassName: classNames("vkuiSpacing", typeof size === 'string' && sizesClassNames[size])
15075
15086
  }));
15076
15087
  };
@@ -30110,11 +30121,20 @@ var CarouselBase_CarouselBase = function(_param) {
30110
30121
  align,
30111
30122
  slideWidth
30112
30123
  ]);
30124
+ var calculateMinDeltaXToSlide = function() {
30125
+ return slidesManager.current.slides[slideIndex].width * SLIDE_THRESHOLD;
30126
+ };
30113
30127
  var slideLeft = function(event) {
30128
+ if (slideIndex > 0) {
30129
+ shiftXCurrentRef.current += calculateMinDeltaXToSlide();
30130
+ }
30114
30131
  onChange === null || onChange === void 0 ? void 0 : onChange((slideIndex - 1 + slidesManager.current.slides.length) % slidesManager.current.slides.length);
30115
30132
  onPrevClick === null || onPrevClick === void 0 ? void 0 : onPrevClick(event);
30116
30133
  };
30117
30134
  var slideRight = function(event) {
30135
+ if (slideIndex < slidesManager.current.slides.length - 1) {
30136
+ shiftXCurrentRef.current -= calculateMinDeltaXToSlide();
30137
+ }
30118
30138
  onChange === null || onChange === void 0 ? void 0 : onChange((slideIndex + 1) % slidesManager.current.slides.length);
30119
30139
  onNextClick === null || onNextClick === void 0 ? void 0 : onNextClick(event);
30120
30140
  };
@@ -39260,7 +39280,7 @@ function ChipsSelect_unsupported_iterable_to_array(o, minLen) {
39260
39280
 
39261
39281
 
39262
39282
 
39263
- var ChipsSelect_findIndexAfter = function() {
39283
+ var findIndexAfter = function() {
39264
39284
  var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], startIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : -1;
39265
39285
  if (startIndex >= options.length - 1) {
39266
39286
  return -1;
@@ -39269,7 +39289,7 @@ var ChipsSelect_findIndexAfter = function() {
39269
39289
  return i > startIndex && (!isNotServicePreset(option) || !option.disabled);
39270
39290
  });
39271
39291
  };
39272
- var ChipsSelect_findIndexBefore = function() {
39292
+ var findIndexBefore = function() {
39273
39293
  var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], endIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : options.length;
39274
39294
  var result = -1;
39275
39295
  if (endIndex <= 0) {
@@ -39428,11 +39448,11 @@ var ChipsSelect_findIndexBefore = function() {
39428
39448
  var focusOption = function(nextIndex, type) {
39429
39449
  var index = nextIndex === null ? -1 : nextIndex;
39430
39450
  if (type === FOCUS_ACTION_NEXT) {
39431
- var _$nextIndex = ChipsSelect_findIndexAfter(options, index);
39432
- index = _$nextIndex === -1 ? ChipsSelect_findIndexAfter(options) : _$nextIndex; // Следующий за index или первый валидный до index
39451
+ var _$nextIndex = findIndexAfter(options, index);
39452
+ index = _$nextIndex === -1 ? findIndexAfter(options) : _$nextIndex; // Следующий за index или первый валидный до index
39433
39453
  } else if (type === FOCUS_ACTION_PREV) {
39434
- var beforeIndex = ChipsSelect_findIndexBefore(options, index);
39435
- index = beforeIndex === -1 ? ChipsSelect_findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index
39454
+ var beforeIndex = findIndexBefore(options, index);
39455
+ index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index
39436
39456
  }
39437
39457
  focusOptionByIndex(index, focusedOptionIndex);
39438
39458
  };
@@ -41713,6 +41733,8 @@ function CustomSelectInput_object_without_properties_loose(source, excluded) {
41713
41733
 
41714
41734
 
41715
41735
 
41736
+
41737
+
41716
41738
  var CustomSelectInput_sizeYClassNames = {
41717
41739
  none: "vkuiCustomSelectInput--sizeY-none",
41718
41740
  compact: "vkuiCustomSelectInput--sizeY-compact"
@@ -41721,7 +41743,7 @@ var CustomSelectInput_sizeYClassNames = {
41721
41743
  * @since 5.10.0
41722
41744
  * @private
41723
41745
  */ var CustomSelectInput_CustomSelectInput = function(_param) {
41724
- var _param_align = _param.align, align = _param_align === void 0 ? 'left' : _param_align, getRef = _param.getRef, className = _param.className, getRootRef = _param.getRootRef, style = _param.style, before = _param.before, after = _param.after, status = _param.status, selectedOptionLabel = _param.selectedOptionLabel, _param_selectType = _param.selectType, selectType = _param_selectType === void 0 ? 'default' : _param_selectType, multiline = _param.multiline, disabled = _param.disabled, fetching = _param.fetching, labelTextTestId = _param.labelTextTestId, searchable = _param.searchable, restInputProps = CustomSelectInput_object_without_properties(_param, [
41746
+ var _param_align = _param.align, align = _param_align === void 0 ? 'left' : _param_align, getRef = _param.getRef, className = _param.className, getRootRef = _param.getRootRef, style = _param.style, before = _param.before, after = _param.after, status = _param.status, children = _param.children, placeholder = _param.placeholder, _param_selectType = _param.selectType, selectType = _param_selectType === void 0 ? 'default' : _param_selectType, multiline = _param.multiline, disabled = _param.disabled, fetching = _param.fetching, labelTextTestId = _param.labelTextTestId, restProps = CustomSelectInput_object_without_properties(_param, [
41725
41747
  "align",
41726
41748
  "getRef",
41727
41749
  "className",
@@ -41730,32 +41752,35 @@ var CustomSelectInput_sizeYClassNames = {
41730
41752
  "before",
41731
41753
  "after",
41732
41754
  "status",
41733
- "selectedOptionLabel",
41755
+ "children",
41756
+ "placeholder",
41734
41757
  "selectType",
41735
41758
  "multiline",
41736
41759
  "disabled",
41737
41760
  "fetching",
41738
- "labelTextTestId",
41739
- "searchable"
41761
+ "labelTextTestId"
41740
41762
  ]);
41741
41763
  var _useAdaptivity = useAdaptivity(), _useAdaptivity_sizeY = _useAdaptivity.sizeY, sizeY = _useAdaptivity_sizeY === void 0 ? 'none' : _useAdaptivity_sizeY;
41764
+ var title = children || placeholder;
41765
+ var showLabelOrPlaceholder = !Boolean(restProps.value);
41742
41766
  var handleRootRef = useExternRef(getRootRef);
41743
- var platform = usePlatform();
41744
- var input = /*#__PURE__*/ React.createElement(SelectTypography, CustomSelectInput_object_spread_props(CustomSelectInput_object_spread({
41745
- selectType: selectType,
41767
+ var focusWithin = useFocusWithin(handleRootRef);
41768
+ var input = /*#__PURE__*/ React.createElement(Text, CustomSelectInput_object_spread_props(CustomSelectInput_object_spread({
41746
41769
  type: "text"
41747
- }, restInputProps), {
41770
+ }, restProps), {
41748
41771
  disabled: disabled && !fetching,
41749
- readOnly: restInputProps.readOnly || !searchable || disabled && fetching,
41772
+ readOnly: restProps.readOnly || disabled && fetching,
41750
41773
  Component: "input",
41751
41774
  normalize: false,
41752
- className: "vkuiCustomSelectInput__input",
41753
- getRootRef: getRef
41775
+ className: classNames("vkuiCustomSelectInput__el", (restProps.readOnly || showLabelOrPlaceholder && !focusWithin) && "vkuiCustomSelectInput__el--cursor-pointer"),
41776
+ getRootRef: getRef,
41777
+ placeholder: children ? '' : placeholder
41754
41778
  }));
41779
+ var platform = usePlatform();
41755
41780
  return /*#__PURE__*/ React.createElement(FormField, {
41756
41781
  Component: "div",
41757
41782
  style: style,
41758
- className: classNames("vkuiCustomSelectInput", align === 'right' && "vkuiCustomSelectInput--align-right", align === 'center' && "vkuiCustomSelectInput--align-center", !selectedOptionLabel && "vkuiCustomSelectInput--empty", multiline && "vkuiCustomSelectInput--multiline", sizeY !== 'regular' && CustomSelectInput_sizeYClassNames[sizeY], before && "vkuiCustomSelectInput--hasBefore", after && "vkuiCustomSelectInput--hasAfter", className),
41783
+ className: classNames("vkuiCustomSelectInput", align === 'right' && "vkuiCustomSelectInput--align-right", align === 'center' && "vkuiCustomSelectInput--align-center", !children && "vkuiCustomSelectInput--empty", multiline && "vkuiCustomSelectInput--multiline", sizeY !== 'regular' && CustomSelectInput_sizeYClassNames[sizeY], before && "vkuiCustomSelectInput--hasBefore", after && "vkuiCustomSelectInput--hasAfter", className),
41759
41784
  getRootRef: handleRootRef,
41760
41785
  before: before,
41761
41786
  after: after,
@@ -41764,97 +41789,17 @@ var CustomSelectInput_sizeYClassNames = {
41764
41789
  status: status
41765
41790
  }, /*#__PURE__*/ React.createElement("div", {
41766
41791
  className: "vkuiCustomSelectInput__input-group"
41767
- }, !searchable && platform === 'ios' ? /*#__PURE__*/ React.createElement(VisuallyHidden, null, input) : input, /*#__PURE__*/ React.createElement("div", {
41768
- className: classNames("vkuiCustomSelectInput__label-wrapper", className),
41792
+ }, /*#__PURE__*/ React.createElement("div", {
41793
+ className: classNames("vkuiCustomSelectInput__container", className),
41769
41794
  tabIndex: -1,
41770
41795
  "aria-hidden": true,
41771
41796
  "data-testid": labelTextTestId
41772
41797
  }, /*#__PURE__*/ React.createElement(SelectTypography, {
41773
41798
  selectType: selectType,
41774
- className: "vkuiCustomSelectInput__label"
41775
- }, selectedOptionLabel || restInputProps.placeholder))));
41799
+ className: "vkuiCustomSelectInput__title"
41800
+ }, showLabelOrPlaceholder && title)), restProps.readOnly && platform === 'ios' ? /*#__PURE__*/ React.createElement(VisuallyHidden, null, input) : input));
41776
41801
  };
41777
41802
 
41778
- ;// CONCATENATED MODULE: ./src/components/CustomSelect/helpers.tsx
41779
- function helpers_object_without_properties(source, excluded) {
41780
- if (source == null) return {};
41781
- var target = helpers_object_without_properties_loose(source, excluded);
41782
- var key, i;
41783
- if (Object.getOwnPropertySymbols) {
41784
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
41785
- for(i = 0; i < sourceSymbolKeys.length; i++){
41786
- key = sourceSymbolKeys[i];
41787
- if (excluded.indexOf(key) >= 0) continue;
41788
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
41789
- target[key] = source[key];
41790
- }
41791
- }
41792
- return target;
41793
- }
41794
- function helpers_object_without_properties_loose(source, excluded) {
41795
- if (source == null) return {};
41796
- var target = {};
41797
- var sourceKeys = Object.keys(source);
41798
- var key, i;
41799
- for(i = 0; i < sourceKeys.length; i++){
41800
- key = sourceKeys[i];
41801
- if (excluded.indexOf(key) >= 0) continue;
41802
- target[key] = source[key];
41803
- }
41804
- return target;
41805
- }
41806
-
41807
-
41808
-
41809
- var helpers_findIndexAfter = function() {
41810
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], startIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : -1;
41811
- if (startIndex >= options.length - 1) {
41812
- return -1;
41813
- }
41814
- return options.findIndex(function(option, i) {
41815
- return i > startIndex && !option.disabled;
41816
- });
41817
- };
41818
- var helpers_findIndexBefore = function() {
41819
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], endIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : options.length;
41820
- var result = -1;
41821
- if (endIndex <= 0) {
41822
- return result;
41823
- }
41824
- for(var i = endIndex - 1; i >= 0; i--){
41825
- var option = options[i];
41826
- if (!option.disabled) {
41827
- result = i;
41828
- break;
41829
- }
41830
- }
41831
- return result;
41832
- };
41833
- function helpers_findSelectedIndex() {
41834
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], value = arguments.length > 1 ? arguments[1] : void 0, withClear = arguments.length > 2 ? arguments[2] : void 0;
41835
- if (withClear && value === '') {
41836
- return -1;
41837
- }
41838
- var _options_findIndex;
41839
- return (_options_findIndex = options.findIndex(function(item) {
41840
- value = typeof item.value === 'number' ? Number(value) : value;
41841
- return item.value === value;
41842
- })) !== null && _options_findIndex !== void 0 ? _options_findIndex : -1;
41843
- }
41844
- function helpers_calculateInputValueFromOptions() {
41845
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], selectValue = arguments.length > 1 ? arguments[1] : void 0;
41846
- var selectedOption = options.find(function(option) {
41847
- return option.value === selectValue;
41848
- });
41849
- return selectedOption ? getTextFromChildren(selectedOption.label) : '';
41850
- }
41851
- function helpers_defaultRenderOptionFn(_param) {
41852
- var option = _param.option, props = helpers_object_without_properties(_param, [
41853
- "option"
41854
- ]);
41855
- return /*#__PURE__*/ React.createElement(CustomSelectOption, props);
41856
- }
41857
-
41858
41803
  ;// CONCATENATED MODULE: ./src/components/CustomSelect/CustomSelect.module.css
41859
41804
  // extracted by mini-css-extract-plugin
41860
41805
 
@@ -42003,10 +41948,36 @@ function CustomSelect_unsupported_iterable_to_array(o, minLen) {
42003
41948
 
42004
41949
 
42005
41950
 
41951
+
41952
+
42006
41953
  var CustomSelect_sizeYClassNames = {
42007
41954
  none: "vkuiCustomSelect--sizeY-none",
42008
41955
  compact: "vkuiCustomSelect--sizeY-compact"
42009
41956
  };
41957
+ var CustomSelect_findIndexAfter = function() {
41958
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], startIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : -1;
41959
+ if (startIndex >= options.length - 1) {
41960
+ return -1;
41961
+ }
41962
+ return options.findIndex(function(option, i) {
41963
+ return i > startIndex && !option.disabled;
41964
+ });
41965
+ };
41966
+ var CustomSelect_findIndexBefore = function() {
41967
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], endIndex = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : options.length;
41968
+ var result = -1;
41969
+ if (endIndex <= 0) {
41970
+ return result;
41971
+ }
41972
+ for(var i = endIndex - 1; i >= 0; i--){
41973
+ var option = options[i];
41974
+ if (!option.disabled) {
41975
+ result = i;
41976
+ break;
41977
+ }
41978
+ }
41979
+ return result;
41980
+ };
42010
41981
  var CustomSelect_warn = warnOnce('CustomSelect');
42011
41982
  var checkOptionsValueType = function(options) {
42012
41983
  if (new Set(options.map(function(item) {
@@ -42015,9 +41986,26 @@ var checkOptionsValueType = function(options) {
42015
41986
  CustomSelect_warn('Некоторые значения ваших опций имеют разные типы. onChange всегда возвращает строковый тип.', 'error');
42016
41987
  }
42017
41988
  };
41989
+ function defaultRenderOptionFn(_param) {
41990
+ var option = _param.option, props = CustomSelect_object_without_properties(_param, [
41991
+ "option"
41992
+ ]);
41993
+ return /*#__PURE__*/ React.createElement(CustomSelectOption, props);
41994
+ }
42018
41995
  var handleOptionDown = function(e) {
42019
41996
  e.preventDefault();
42020
41997
  };
41998
+ function findSelectedIndex() {
41999
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], value = arguments.length > 1 ? arguments[1] : void 0, withClear = arguments.length > 2 ? arguments[2] : void 0;
42000
+ if (withClear && value === '') {
42001
+ return -1;
42002
+ }
42003
+ var _options_findIndex;
42004
+ return (_options_findIndex = options.findIndex(function(item) {
42005
+ value = typeof item.value === 'number' ? Number(value) : value;
42006
+ return item.value === value;
42007
+ })) !== null && _options_findIndex !== void 0 ? _options_findIndex : -1;
42008
+ }
42021
42009
  var filter = function(options, inputValue, filterFn) {
42022
42010
  return typeof filterFn === 'function' ? options.filter(function(option) {
42023
42011
  return filterFn(inputValue, option);
@@ -42072,16 +42060,13 @@ var filter = function(options, inputValue, filterFn) {
42072
42060
  var scrollBoxRef = React.useRef(null);
42073
42061
  var selectElRef = useExternRef(getRef);
42074
42062
  var optionsWrapperRef = React.useRef(null);
42075
- var selectInputRef = useExternRef(getSelectInputRef);
42076
42063
  var _React_useState1 = CustomSelect_sliced_to_array(React.useState(-1), 2), focusedOptionIndex = _React_useState1[0], setFocusedOptionIndex = _React_useState1[1];
42077
42064
  var _React_useState2 = CustomSelect_sliced_to_array(React.useState(props.value !== undefined), 2), isControlledOutside = _React_useState2[0], setIsControlledOutside = _React_useState2[1];
42078
- var _React_useState3 = CustomSelect_sliced_to_array(React.useState(function() {
42065
+ var _React_useState3 = CustomSelect_sliced_to_array(React.useState(''), 2), inputValue = _React_useState3[0], setInputValue = _React_useState3[1];
42066
+ var _React_useState4 = CustomSelect_sliced_to_array(React.useState(function() {
42079
42067
  var _props_value, _ref;
42080
42068
  return (_ref = (_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : defaultValue) !== null && _ref !== void 0 ? _ref : allowClearButton ? '' : undefined;
42081
- }), 2), nativeSelectValue = _React_useState3[0], setNativeSelectValue = _React_useState3[1];
42082
- var _React_useState4 = CustomSelect_sliced_to_array(React.useState(function() {
42083
- return calculateInputValueFromOptions(optionsProp, nativeSelectValue);
42084
- }), 2), inputValue = _React_useState4[0], setInputValue = _React_useState4[1];
42069
+ }), 2), nativeSelectValue = _React_useState4[0], setNativeSelectValue = _React_useState4[1];
42085
42070
  var _React_useState5 = CustomSelect_sliced_to_array(React.useState(popupDirection), 2), popperPlacement = _React_useState5[0], setPopperPlacement = _React_useState5[1];
42086
42071
  var _React_useState6 = CustomSelect_sliced_to_array(React.useState(optionsProp), 2), options = _React_useState6[0], setOptions = _React_useState6[1];
42087
42072
  var _props_value;
@@ -42208,6 +42193,7 @@ var filter = function(options, inputValue, filterFn) {
42208
42193
  * Сброс происходит в одном из эффекте `updateOptionsAndSelectedOptionIndex()`.
42209
42194
  */ var close = React.useCallback(function() {
42210
42195
  resetKeyboardInput();
42196
+ setInputValue('');
42211
42197
  setOpened(false);
42212
42198
  resetFocusedOption();
42213
42199
  onClose === null || onClose === void 0 ? void 0 : onClose();
@@ -42218,8 +42204,8 @@ var filter = function(options, inputValue, filterFn) {
42218
42204
  ]);
42219
42205
  var selectOption = React.useCallback(function(index) {
42220
42206
  var item = options[index];
42221
- close();
42222
42207
  setNativeSelectValue(item === null || item === void 0 ? void 0 : item.value);
42208
+ close();
42223
42209
  var shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync = isControlledOutside && props.value !== nativeSelectValue && nativeSelectValue === (item === null || item === void 0 ? void 0 : item.value);
42224
42210
  if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {
42225
42211
  var _selectElRef_current;
@@ -42263,23 +42249,18 @@ var filter = function(options, inputValue, filterFn) {
42263
42249
  bubbles: true
42264
42250
  });
42265
42251
  (_selectElRef_current = selectElRef.current) === null || _selectElRef_current === void 0 ? void 0 : _selectElRef_current.dispatchEvent(event);
42266
- setInputValue(calculateInputValueFromOptions(optionsProp, nativeSelectValue));
42267
42252
  }, [
42268
42253
  close,
42269
- selectElRef,
42270
- optionsProp,
42271
- nativeSelectValue
42254
+ selectElRef
42272
42255
  ]);
42273
42256
  var onFocus = React.useCallback(function() {
42274
- var _selectElRef_current, _selectInputRef_current;
42257
+ var _selectElRef_current;
42275
42258
  var event = new Event('focusin', {
42276
42259
  bubbles: true
42277
42260
  });
42278
42261
  (_selectElRef_current = selectElRef.current) === null || _selectElRef_current === void 0 ? void 0 : _selectElRef_current.dispatchEvent(event);
42279
- (_selectInputRef_current = selectInputRef.current) === null || _selectInputRef_current === void 0 ? void 0 : _selectInputRef_current.select();
42280
42262
  }, [
42281
- selectElRef,
42282
- selectInputRef
42263
+ selectElRef
42283
42264
  ]);
42284
42265
  var onClick = React.useCallback(function() {
42285
42266
  if (opened) {
@@ -42300,11 +42281,11 @@ var filter = function(options, inputValue, filterFn) {
42300
42281
  var focusOption = React.useCallback(function(type) {
42301
42282
  var index = focusedOptionIndex;
42302
42283
  if (type === 'next') {
42303
- var nextIndex = findIndexAfter(options, index);
42304
- index = nextIndex === -1 ? findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index
42284
+ var nextIndex = CustomSelect_findIndexAfter(options, index);
42285
+ index = nextIndex === -1 ? CustomSelect_findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index
42305
42286
  } else if (type === 'prev') {
42306
- var beforeIndex = findIndexBefore(options, index);
42307
- index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index
42287
+ var beforeIndex = CustomSelect_findIndexBefore(options, index);
42288
+ index = beforeIndex === -1 ? CustomSelect_findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index
42308
42289
  }
42309
42290
  focusOptionByIndex(index);
42310
42291
  }, [
@@ -42312,38 +42293,21 @@ var filter = function(options, inputValue, filterFn) {
42312
42293
  focusedOptionIndex,
42313
42294
  options
42314
42295
  ]);
42315
- React.useEffect(function filterOptions() {
42296
+ React.useEffect(function updateOptionsAndSelectedOptionIndex() {
42297
+ var _props_value, _ref;
42298
+ var value = (_ref = (_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : nativeSelectValue) !== null && _ref !== void 0 ? _ref : defaultValue;
42316
42299
  var options = searchable && inputValue !== undefined ? filter(optionsProp, inputValue, filterFn) : optionsProp;
42317
42300
  setOptions(options);
42301
+ setSelectedOptionIndex(findSelectedIndex(options, value, allowClearButton));
42318
42302
  }, [
42319
42303
  filterFn,
42320
42304
  inputValue,
42305
+ nativeSelectValue,
42321
42306
  optionsProp,
42322
- searchable
42323
- ]);
42324
- var _props_value1, _ref;
42325
- var selectValue = (_ref = (_props_value1 = props.value) !== null && _props_value1 !== void 0 ? _props_value1 : nativeSelectValue) !== null && _ref !== void 0 ? _ref : defaultValue;
42326
- React.useEffect(function updateSelectedOptionIndexOnValueChange() {
42327
- setSelectedOptionIndex(findSelectedIndex(options, selectValue, allowClearButton));
42328
- }, [
42329
- selectValue,
42330
- allowClearButton,
42331
- options
42332
- ]);
42333
- var prevSelectValueRef = React.useRef(selectValue);
42334
- React.useEffect(function updateInputValueOnSelectValueChange() {
42335
- if (prevSelectValueRef.current === selectValue) {
42336
- return;
42337
- }
42338
- setInputValue(calculateInputValueFromOptions(optionsProp, selectValue));
42339
- }, [
42340
- selectValue,
42341
- optionsProp
42342
- ]);
42343
- React.useEffect(function updatePrevSelectValue() {
42344
- prevSelectValueRef.current = selectValue;
42345
- }, [
42346
- selectValue
42307
+ defaultValue,
42308
+ props.value,
42309
+ searchable,
42310
+ allowClearButton
42347
42311
  ]);
42348
42312
  var onNativeSelectChange = function(e) {
42349
42313
  var newSelectedOptionIndex = findSelectedIndex(options, e.currentTarget.value, allowClearButton);
@@ -42508,6 +42472,7 @@ var filter = function(options, inputValue, filterFn) {
42508
42472
  renderDropdown,
42509
42473
  renderOption
42510
42474
  ]);
42475
+ var selectInputRef = useExternRef(getSelectInputRef);
42511
42476
  var focusOnInputTimerRef = React.useRef();
42512
42477
  var focusOnInput = React.useCallback(function() {
42513
42478
  clearTimeout(focusOnInputTimerRef.current);
@@ -42588,14 +42553,11 @@ var filter = function(options, inputValue, filterFn) {
42588
42553
  selectInputRef
42589
42554
  ]);
42590
42555
  var preventInputBlurWhenClickInsideFocusedSelectArea = function(e) {
42591
- var _selectInputRef_current;
42592
42556
  // Так как инпут больше не оборачивается пустым лэйблом, то клик внутри обертки,
42593
42557
  // но вне инпута (например по иконке дропдауна), будет убирать фокус с инпута.
42594
42558
  // Чтобы в такой ситуации отключить blur инпута мы превентим mousedown событие обёртки
42595
42559
  var isInputFocused = document && document.activeElement === selectInputRef.current;
42596
- var clickTarget = e.target;
42597
- var inputClicked = (_selectInputRef_current = selectInputRef.current) === null || _selectInputRef_current === void 0 ? void 0 : _selectInputRef_current.contains(clickTarget);
42598
- if (isInputFocused && !inputClicked) {
42560
+ if (isInputFocused) {
42599
42561
  e.preventDefault();
42600
42562
  }
42601
42563
  };
@@ -42604,19 +42566,23 @@ var filter = function(options, inputValue, filterFn) {
42604
42566
  var selectInputAriaProps = {
42605
42567
  'role': 'combobox',
42606
42568
  'aria-controls': popupAriaId,
42569
+ 'aria-owns': popupAriaId,
42607
42570
  'aria-expanded': opened,
42608
42571
  'aria-activedescendant': ariaActiveDescendantId && opened ? "".concat(popupAriaId, "-").concat(ariaActiveDescendantId) : undefined,
42609
42572
  'aria-labelledby': ariaLabelledBy,
42610
42573
  'aria-haspopup': 'listbox',
42611
42574
  'aria-autocomplete': 'none'
42612
42575
  };
42576
+ var focusWithin = useFocusWithin(handleRootRef);
42613
42577
  return /*#__PURE__*/ React.createElement("div", {
42614
42578
  className: classNames("vkuiCustomSelect", sizeY !== 'regular' && CustomSelect_sizeYClassNames[sizeY], className),
42615
42579
  style: style,
42616
42580
  ref: handleRootRef,
42617
42581
  onClick: passClickAndFocusToInputOnClick,
42618
42582
  onMouseDown: preventInputBlurWhenClickInsideFocusedSelectArea
42619
- }, /*#__PURE__*/ React.createElement(CustomSelectInput, CustomSelect_object_spread_props(CustomSelect_object_spread({
42583
+ }, focusWithin && selected && !opened && /*#__PURE__*/ React.createElement(VisuallyHidden, {
42584
+ "aria-live": "polite"
42585
+ }, selected.label), /*#__PURE__*/ React.createElement(CustomSelectInput, CustomSelect_object_spread_props(CustomSelect_object_spread({
42620
42586
  autoComplete: "off",
42621
42587
  autoCapitalize: "none",
42622
42588
  autoCorrect: "off",
@@ -42626,7 +42592,7 @@ var filter = function(options, inputValue, filterFn) {
42626
42592
  onFocus: onFocus,
42627
42593
  onBlur: onBlur,
42628
42594
  className: openedClassNames,
42629
- searchable: searchable,
42595
+ readOnly: !searchable,
42630
42596
  fetching: fetching,
42631
42597
  value: inputValue,
42632
42598
  onKeyUp: handleKeyUp,
@@ -42635,9 +42601,8 @@ var filter = function(options, inputValue, filterFn) {
42635
42601
  onClick: onClick,
42636
42602
  before: before,
42637
42603
  after: afterIcons,
42638
- selectType: selectType,
42639
- selectedOptionLabel: selected === null || selected === void 0 ? void 0 : selected.label
42640
- })), /*#__PURE__*/ React.createElement("select", {
42604
+ selectType: selectType
42605
+ }), selected === null || selected === void 0 ? void 0 : selected.label), /*#__PURE__*/ React.createElement("select", {
42641
42606
  ref: selectElRef,
42642
42607
  name: name,
42643
42608
  onChange: onNativeSelectChange,
@@ -42993,10 +42958,11 @@ function Select_object_without_properties_loose(source, excluded) {
42993
42958
  }, props)), deviceType.mobile && /*#__PURE__*/ React.createElement(NativeSelect, Select_object_spread({
42994
42959
  className: classNames(className, deviceType.mobile.className)
42995
42960
  }, nativeProps), options.map(function(param) {
42996
- var label = param.label, value = param.value;
42961
+ var label = param.label, value = param.value, disabled = param.disabled;
42997
42962
  return /*#__PURE__*/ React.createElement("option", {
42998
42963
  value: value,
42999
- key: "".concat(value)
42964
+ key: "".concat(value),
42965
+ disabled: disabled
43000
42966
  }, label);
43001
42967
  })));
43002
42968
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "6.7.0",
2
+ "version": "6.7.2",
3
3
  "name": "@vkontakte/vkui",
4
4
  "description": "VKUI library",
5
5
  "main": "dist/cjs/index.js",
@@ -198,20 +198,23 @@ export const AppRoot = ({
198
198
  [scroll],
199
199
  );
200
200
 
201
+ const contextValue = React.useMemo(
202
+ () => ({
203
+ appRoot: appRootRef,
204
+ portalRoot: portalRootRef,
205
+ embedded: mode === 'embedded',
206
+ mode,
207
+ disablePortal,
208
+ layout,
209
+ get keyboardInput() {
210
+ return isKeyboardInputActiveRef.current;
211
+ },
212
+ }),
213
+ [disablePortal, isKeyboardInputActiveRef, layout, mode],
214
+ );
215
+
201
216
  const content = (
202
- <AppRootContext.Provider
203
- value={{
204
- appRoot: appRootRef,
205
- portalRoot: portalRootRef,
206
- embedded: mode === 'embedded',
207
- mode,
208
- disablePortal,
209
- layout,
210
- get keyboardInput() {
211
- return isKeyboardInputActiveRef.current;
212
- },
213
- }}
214
- >
217
+ <AppRootContext.Provider value={contextValue}>
215
218
  <ScrollController elRef={appRootRef}>{children}</ScrollController>
216
219
  </AppRootContext.Provider>
217
220
  );
@@ -11,7 +11,12 @@ import { RootComponent } from '../../RootComponent/RootComponent';
11
11
  import { ScrollArrow } from '../../ScrollArrow/ScrollArrow';
12
12
  import { type CustomTouchEvent, Touch } from '../../Touch/Touch';
13
13
  import { type BaseGalleryProps, type GallerySlidesState } from '../types';
14
- import { ANIMATION_DURATION, CONTROL_ELEMENTS_STATE, SLIDES_MANAGER_STATE } from './constants';
14
+ import {
15
+ ANIMATION_DURATION,
16
+ CONTROL_ELEMENTS_STATE,
17
+ SLIDE_THRESHOLD,
18
+ SLIDES_MANAGER_STATE,
19
+ } from './constants';
15
20
  import { calculateIndent, getLoopPoints, getTargetIndex } from './helpers';
16
21
  import { useSlideAnimation } from './hooks';
17
22
  import type { ControlElementsState, SlidesManagerState } from './types';
@@ -253,7 +258,14 @@ export const CarouselBase = ({
253
258
 
254
259
  useIsomorphicLayoutEffect(initializeSlides, [align, slideWidth]);
255
260
 
261
+ const calculateMinDeltaXToSlide = () => {
262
+ return slidesManager.current.slides[slideIndex].width * SLIDE_THRESHOLD;
263
+ };
264
+
256
265
  const slideLeft = (event: React.MouseEvent) => {
266
+ if (slideIndex > 0) {
267
+ shiftXCurrentRef.current += calculateMinDeltaXToSlide();
268
+ }
257
269
  onChange?.(
258
270
  (slideIndex - 1 + slidesManager.current.slides.length) % slidesManager.current.slides.length,
259
271
  );
@@ -261,6 +273,9 @@ export const CarouselBase = ({
261
273
  };
262
274
 
263
275
  const slideRight = (event: React.MouseEvent) => {
276
+ if (slideIndex < slidesManager.current.slides.length - 1) {
277
+ shiftXCurrentRef.current -= calculateMinDeltaXToSlide();
278
+ }
264
279
  onChange?.((slideIndex + 1) % slidesManager.current.slides.length);
265
280
  onNextClick?.(event);
266
281
  };
@@ -38,7 +38,11 @@
38
38
 
39
39
  /* stylelint-disable-next-line selector-pseudo-class-disallowed-list */
40
40
  .CellButton--centered :global(.vkuiIcon) {
41
- padding-inline-end: 8px;
41
+ /* компенсируем отступ заданные в SimpleCell__before */
42
+ margin-inline-end: calc(
43
+ -1 * var(--vkui_internal--SimpleCell-before-inline-padding-end, var(--vkui--spacing_size_xl))
44
+ );
45
+ padding-inline-end: var(--vkui--spacing_size_m);
42
46
  }
43
47
 
44
48
  .CellButton {