select-dropdown.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var lodashUnified = require('lodash-unified');
  5. var groupItem = require('./group-item.js');
  6. var optionItem = require('./option-item.js');
  7. var useProps = require('./useProps.js');
  8. var token = require('./token.js');
  9. var fixedSizeList = require('../../virtual-list/src/components/fixed-size-list.js');
  10. var dynamicSizeList = require('../../virtual-list/src/components/dynamic-size-list.js');
  11. var index = require('../../../hooks/use-namespace/index.js');
  12. var types = require('../../../utils/types.js');
  13. var core = require('@vueuse/core');
  14. var aria = require('../../../constants/aria.js');
  15. var shared = require('@vue/shared');
  16. const props = {
  17. loading: Boolean,
  18. data: {
  19. type: Array,
  20. required: true
  21. },
  22. hoveringIndex: Number,
  23. width: Number
  24. };
  25. var ElSelectMenu = vue.defineComponent({
  26. name: "ElSelectDropdown",
  27. props,
  28. setup(props2, {
  29. slots,
  30. expose
  31. }) {
  32. const select = vue.inject(token.selectV2InjectionKey);
  33. const ns = index.useNamespace("select");
  34. const {
  35. getLabel,
  36. getValue,
  37. getDisabled
  38. } = useProps.useProps(select.props);
  39. const cachedHeights = vue.ref([]);
  40. const listRef = vue.ref();
  41. const size = vue.computed(() => props2.data.length);
  42. vue.watch(() => size.value, () => {
  43. var _a, _b;
  44. (_b = (_a = select.tooltipRef.value).updatePopper) == null ? void 0 : _b.call(_a);
  45. });
  46. const isSized = vue.computed(() => types.isUndefined(select.props.estimatedOptionHeight));
  47. const listProps = vue.computed(() => {
  48. if (isSized.value) {
  49. return {
  50. itemSize: select.props.itemHeight
  51. };
  52. }
  53. return {
  54. estimatedSize: select.props.estimatedOptionHeight,
  55. itemSize: (idx) => cachedHeights.value[idx]
  56. };
  57. });
  58. const contains = (arr = [], target) => {
  59. const {
  60. props: {
  61. valueKey
  62. }
  63. } = select;
  64. if (!shared.isObject(target)) {
  65. return arr.includes(target);
  66. }
  67. return arr && arr.some((item) => {
  68. return vue.toRaw(lodashUnified.get(item, valueKey)) === lodashUnified.get(target, valueKey);
  69. });
  70. };
  71. const isEqual = (selected, target) => {
  72. if (!shared.isObject(target)) {
  73. return selected === target;
  74. } else {
  75. const {
  76. valueKey
  77. } = select.props;
  78. return lodashUnified.get(selected, valueKey) === lodashUnified.get(target, valueKey);
  79. }
  80. };
  81. const isItemSelected = (modelValue, target) => {
  82. if (select.props.multiple) {
  83. return contains(modelValue, getValue(target));
  84. }
  85. return isEqual(modelValue, getValue(target));
  86. };
  87. const isItemDisabled = (modelValue, selected) => {
  88. const {
  89. disabled,
  90. multiple,
  91. multipleLimit
  92. } = select.props;
  93. return disabled || !selected && (multiple ? multipleLimit > 0 && modelValue.length >= multipleLimit : false);
  94. };
  95. const isItemHovering = (target) => props2.hoveringIndex === target;
  96. const scrollToItem = (index) => {
  97. const list = listRef.value;
  98. if (list) {
  99. list.scrollToItem(index);
  100. }
  101. };
  102. const resetScrollTop = () => {
  103. const list = listRef.value;
  104. if (list) {
  105. list.resetScrollTop();
  106. }
  107. };
  108. const exposed = {
  109. listRef,
  110. isSized,
  111. isItemDisabled,
  112. isItemHovering,
  113. isItemSelected,
  114. scrollToItem,
  115. resetScrollTop
  116. };
  117. expose(exposed);
  118. const Item = (itemProps) => {
  119. const {
  120. index,
  121. data,
  122. style
  123. } = itemProps;
  124. const sized = vue.unref(isSized);
  125. const {
  126. itemSize,
  127. estimatedSize
  128. } = vue.unref(listProps);
  129. const {
  130. modelValue
  131. } = select.props;
  132. const {
  133. onSelect,
  134. onHover
  135. } = select;
  136. const item = data[index];
  137. if (item.type === "Group") {
  138. return vue.createVNode(groupItem["default"], {
  139. "item": item,
  140. "style": style,
  141. "height": sized ? itemSize : estimatedSize
  142. }, null);
  143. }
  144. const isSelected = isItemSelected(modelValue, item);
  145. const isDisabled = isItemDisabled(modelValue, isSelected);
  146. const isHovering = isItemHovering(index);
  147. return vue.createVNode(optionItem["default"], vue.mergeProps(itemProps, {
  148. "selected": isSelected,
  149. "disabled": getDisabled(item) || isDisabled,
  150. "created": !!item.created,
  151. "hovering": isHovering,
  152. "item": item,
  153. "onSelect": onSelect,
  154. "onHover": onHover
  155. }), {
  156. default: (props3) => {
  157. var _a;
  158. return ((_a = slots.default) == null ? void 0 : _a.call(slots, props3)) || vue.createVNode("span", null, [getLabel(item)]);
  159. }
  160. });
  161. };
  162. const {
  163. onKeyboardNavigate,
  164. onKeyboardSelect
  165. } = select;
  166. const onForward = () => {
  167. onKeyboardNavigate("forward");
  168. };
  169. const onBackward = () => {
  170. onKeyboardNavigate("backward");
  171. };
  172. const onKeydown = (e) => {
  173. const {
  174. code
  175. } = e;
  176. const {
  177. tab,
  178. esc,
  179. down,
  180. up,
  181. enter,
  182. numpadEnter
  183. } = aria.EVENT_CODE;
  184. if ([esc, down, up, enter, numpadEnter].includes(code)) {
  185. e.preventDefault();
  186. e.stopPropagation();
  187. }
  188. switch (code) {
  189. case tab:
  190. case esc:
  191. break;
  192. case down:
  193. onForward();
  194. break;
  195. case up:
  196. onBackward();
  197. break;
  198. case enter:
  199. case numpadEnter:
  200. onKeyboardSelect();
  201. break;
  202. }
  203. };
  204. return () => {
  205. var _a, _b, _c, _d;
  206. const {
  207. data,
  208. width
  209. } = props2;
  210. const {
  211. height,
  212. multiple,
  213. scrollbarAlwaysOn
  214. } = select.props;
  215. const isScrollbarAlwaysOn = vue.computed(() => {
  216. return core.isIOS ? true : scrollbarAlwaysOn;
  217. });
  218. const List = vue.unref(isSized) ? fixedSizeList["default"] : dynamicSizeList["default"];
  219. return vue.createVNode("div", {
  220. "class": [ns.b("dropdown"), ns.is("multiple", multiple)],
  221. "style": {
  222. width: `${width}px`
  223. }
  224. }, [(_a = slots.header) == null ? void 0 : _a.call(slots), ((_b = slots.loading) == null ? void 0 : _b.call(slots)) || ((_c = slots.empty) == null ? void 0 : _c.call(slots)) || vue.createVNode(List, vue.mergeProps({
  225. "ref": listRef
  226. }, vue.unref(listProps), {
  227. "className": ns.be("dropdown", "list"),
  228. "scrollbarAlwaysOn": isScrollbarAlwaysOn.value,
  229. "data": data,
  230. "height": height,
  231. "width": width,
  232. "total": data.length,
  233. "onKeydown": onKeydown
  234. }), {
  235. default: (props3) => vue.createVNode(Item, props3, null)
  236. }), (_d = slots.footer) == null ? void 0 : _d.call(slots)]);
  237. };
  238. }
  239. });
  240. exports["default"] = ElSelectMenu;
  241. //# sourceMappingURL=select-dropdown.js.map