DropdownItem.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. var __defProp = Object.defineProperty;
  2. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  3. var __getOwnPropNames = Object.getOwnPropertyNames;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __export = (target, all) => {
  6. for (var name2 in all)
  7. __defProp(target, name2, { get: all[name2], enumerable: true });
  8. };
  9. var __copyProps = (to, from, except, desc) => {
  10. if (from && typeof from === "object" || typeof from === "function") {
  11. for (let key of __getOwnPropNames(from))
  12. if (!__hasOwnProp.call(to, key) && key !== except)
  13. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  14. }
  15. return to;
  16. };
  17. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  18. var stdin_exports = {};
  19. __export(stdin_exports, {
  20. default: () => stdin_default,
  21. dropdownItemProps: () => dropdownItemProps
  22. });
  23. module.exports = __toCommonJS(stdin_exports);
  24. var import_vue = require("vue");
  25. var import_utils = require("../utils");
  26. var import_DropdownMenu = require("../dropdown-menu/DropdownMenu");
  27. var import_use = require("@vant/use");
  28. var import_use_expose = require("../composables/use-expose");
  29. var import_cell = require("../cell");
  30. var import_icon = require("../icon");
  31. var import_popup = require("../popup");
  32. const [name, bem] = (0, import_utils.createNamespace)("dropdown-item");
  33. const dropdownItemProps = {
  34. title: String,
  35. options: (0, import_utils.makeArrayProp)(),
  36. disabled: Boolean,
  37. teleport: [String, Object],
  38. lazyRender: import_utils.truthProp,
  39. modelValue: import_utils.unknownProp,
  40. titleClass: import_utils.unknownProp
  41. };
  42. var stdin_default = (0, import_vue.defineComponent)({
  43. name,
  44. inheritAttrs: false,
  45. props: dropdownItemProps,
  46. emits: ["open", "opened", "close", "closed", "change", "update:modelValue"],
  47. setup(props, {
  48. emit,
  49. slots,
  50. attrs
  51. }) {
  52. const state = (0, import_vue.reactive)({
  53. showPopup: false,
  54. transition: true,
  55. showWrapper: false
  56. });
  57. const wrapperRef = (0, import_vue.ref)();
  58. const {
  59. parent,
  60. index
  61. } = (0, import_use.useParent)(import_DropdownMenu.DROPDOWN_KEY);
  62. if (!parent) {
  63. if (process.env.NODE_ENV !== "production") {
  64. console.error("[Vant] <DropdownItem> must be a child component of <DropdownMenu>.");
  65. }
  66. return;
  67. }
  68. const getEmitter = (name2) => () => emit(name2);
  69. const onOpen = getEmitter("open");
  70. const onClose = getEmitter("close");
  71. const onOpened = getEmitter("opened");
  72. const onClosed = () => {
  73. state.showWrapper = false;
  74. emit("closed");
  75. };
  76. const onClickWrapper = (event) => {
  77. if (props.teleport) {
  78. event.stopPropagation();
  79. }
  80. };
  81. const toggle = (show = !state.showPopup, options = {}) => {
  82. if (show === state.showPopup) {
  83. return;
  84. }
  85. state.showPopup = show;
  86. state.transition = !options.immediate;
  87. if (show) {
  88. parent.updateOffset();
  89. state.showWrapper = true;
  90. }
  91. };
  92. const renderTitle = () => {
  93. if (slots.title) {
  94. return slots.title();
  95. }
  96. if (props.title) {
  97. return props.title;
  98. }
  99. const match = props.options.find((option) => option.value === props.modelValue);
  100. return match ? match.text : "";
  101. };
  102. const renderOption = (option) => {
  103. const {
  104. activeColor
  105. } = parent.props;
  106. const {
  107. disabled
  108. } = option;
  109. const active = option.value === props.modelValue;
  110. const onClick = () => {
  111. if (disabled) {
  112. return;
  113. }
  114. state.showPopup = false;
  115. if (option.value !== props.modelValue) {
  116. emit("update:modelValue", option.value);
  117. emit("change", option.value);
  118. }
  119. };
  120. const renderIcon = () => {
  121. if (active) {
  122. return (0, import_vue.createVNode)(import_icon.Icon, {
  123. "class": bem("icon"),
  124. "color": disabled ? void 0 : activeColor,
  125. "name": "success"
  126. }, null);
  127. }
  128. };
  129. return (0, import_vue.createVNode)(import_cell.Cell, {
  130. "role": "menuitem",
  131. "key": String(option.value),
  132. "icon": option.icon,
  133. "title": option.text,
  134. "class": bem("option", {
  135. active,
  136. disabled
  137. }),
  138. "style": {
  139. color: active ? activeColor : ""
  140. },
  141. "tabindex": active ? 0 : -1,
  142. "clickable": !disabled,
  143. "onClick": onClick
  144. }, {
  145. value: renderIcon
  146. });
  147. };
  148. const renderContent = () => {
  149. const {
  150. offset
  151. } = parent;
  152. const {
  153. autoLocate,
  154. zIndex,
  155. overlay,
  156. duration,
  157. direction,
  158. closeOnClickOverlay
  159. } = parent.props;
  160. const style = (0, import_utils.getZIndexStyle)(zIndex);
  161. let offsetValue = offset.value;
  162. if (autoLocate && wrapperRef.value) {
  163. const offsetParent = (0, import_utils.getContainingBlock)(wrapperRef.value);
  164. if (offsetParent) {
  165. offsetValue -= (0, import_use.useRect)(offsetParent).top;
  166. }
  167. }
  168. if (direction === "down") {
  169. style.top = `${offsetValue}px`;
  170. } else {
  171. style.bottom = `${offsetValue}px`;
  172. }
  173. return (0, import_vue.withDirectives)((0, import_vue.createVNode)("div", (0, import_vue.mergeProps)({
  174. "ref": wrapperRef,
  175. "style": style,
  176. "class": bem([direction]),
  177. "onClick": onClickWrapper
  178. }, attrs), [(0, import_vue.createVNode)(import_popup.Popup, {
  179. "show": state.showPopup,
  180. "onUpdate:show": ($event) => state.showPopup = $event,
  181. "role": "menu",
  182. "class": bem("content"),
  183. "overlay": overlay,
  184. "position": direction === "down" ? "top" : "bottom",
  185. "duration": state.transition ? duration : 0,
  186. "lazyRender": props.lazyRender,
  187. "overlayStyle": {
  188. position: "absolute"
  189. },
  190. "aria-labelledby": `${parent.id}-${index.value}`,
  191. "data-allow-mismatch": "attribute",
  192. "closeOnClickOverlay": closeOnClickOverlay,
  193. "onOpen": onOpen,
  194. "onClose": onClose,
  195. "onOpened": onOpened,
  196. "onClosed": onClosed
  197. }, {
  198. default: () => {
  199. var _a;
  200. return [props.options.map(renderOption), (_a = slots.default) == null ? void 0 : _a.call(slots)];
  201. }
  202. })]), [[import_vue.vShow, state.showWrapper]]);
  203. };
  204. (0, import_use_expose.useExpose)({
  205. state,
  206. toggle,
  207. renderTitle
  208. });
  209. return () => {
  210. if (props.teleport) {
  211. return (0, import_vue.createVNode)(import_vue.Teleport, {
  212. "to": props.teleport
  213. }, {
  214. default: () => [renderContent()]
  215. });
  216. }
  217. return renderContent();
  218. };
  219. }
  220. });