Picker.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. var __create = Object.create;
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __getProtoOf = Object.getPrototypeOf;
  6. var __hasOwnProp = Object.prototype.hasOwnProperty;
  7. var __export = (target, all) => {
  8. for (var name2 in all)
  9. __defProp(target, name2, { get: all[name2], enumerable: true });
  10. };
  11. var __copyProps = (to, from, except, desc) => {
  12. if (from && typeof from === "object" || typeof from === "function") {
  13. for (let key of __getOwnPropNames(from))
  14. if (!__hasOwnProp.call(to, key) && key !== except)
  15. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  16. }
  17. return to;
  18. };
  19. var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  20. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  21. mod
  22. ));
  23. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  24. var stdin_exports = {};
  25. __export(stdin_exports, {
  26. default: () => stdin_default,
  27. pickerProps: () => pickerProps,
  28. pickerSharedProps: () => pickerSharedProps
  29. });
  30. module.exports = __toCommonJS(stdin_exports);
  31. var import_vue = require("vue");
  32. var import_vue2 = require("vue");
  33. var import_utils = require("../utils");
  34. var import_utils2 = require("./utils");
  35. var import_use = require("@vant/use");
  36. var import_use_expose = require("../composables/use-expose");
  37. var import_loading = require("../loading");
  38. var import_PickerColumn = __toESM(require("./PickerColumn"));
  39. var import_PickerToolbar = __toESM(require("./PickerToolbar"));
  40. var import_PickerGroup = require("../picker-group/PickerGroup");
  41. const pickerSharedProps = (0, import_utils.extend)({
  42. loading: Boolean,
  43. readonly: Boolean,
  44. allowHtml: Boolean,
  45. optionHeight: (0, import_utils.makeNumericProp)(44),
  46. showToolbar: import_utils.truthProp,
  47. swipeDuration: (0, import_utils.makeNumericProp)(1e3),
  48. visibleOptionNum: (0, import_utils.makeNumericProp)(6)
  49. }, import_PickerToolbar.pickerToolbarProps);
  50. const pickerProps = (0, import_utils.extend)({}, pickerSharedProps, {
  51. columns: (0, import_utils.makeArrayProp)(),
  52. modelValue: (0, import_utils.makeArrayProp)(),
  53. toolbarPosition: (0, import_utils.makeStringProp)("top"),
  54. columnsFieldNames: Object
  55. });
  56. var stdin_default = (0, import_vue2.defineComponent)({
  57. name: import_utils2.name,
  58. props: pickerProps,
  59. emits: ["confirm", "cancel", "change", "clickOption", "update:modelValue"],
  60. setup(props, {
  61. emit,
  62. slots
  63. }) {
  64. const columnsRef = (0, import_vue2.ref)();
  65. const selectedValues = (0, import_vue2.ref)(props.modelValue.slice(0));
  66. const {
  67. parent
  68. } = (0, import_use.useParent)(import_PickerGroup.PICKER_GROUP_KEY);
  69. const {
  70. children,
  71. linkChildren
  72. } = (0, import_use.useChildren)(import_PickerColumn.PICKER_KEY);
  73. linkChildren();
  74. const fields = (0, import_vue2.computed)(() => (0, import_utils2.assignDefaultFields)(props.columnsFieldNames));
  75. const optionHeight = (0, import_vue2.computed)(() => (0, import_utils.unitToPx)(props.optionHeight));
  76. const columnsType = (0, import_vue2.computed)(() => (0, import_utils2.getColumnsType)(props.columns, fields.value));
  77. const currentColumns = (0, import_vue2.computed)(() => {
  78. const {
  79. columns
  80. } = props;
  81. switch (columnsType.value) {
  82. case "multiple":
  83. return columns;
  84. case "cascade":
  85. return (0, import_utils2.formatCascadeColumns)(columns, fields.value, selectedValues);
  86. default:
  87. return [columns];
  88. }
  89. });
  90. const hasOptions = (0, import_vue2.computed)(() => currentColumns.value.some((options) => options.length));
  91. const selectedOptions = (0, import_vue2.computed)(() => currentColumns.value.map((options, index) => (0, import_utils2.findOptionByValue)(options, selectedValues.value[index], fields.value)));
  92. const selectedIndexes = (0, import_vue2.computed)(() => currentColumns.value.map((options, index) => options.findIndex((option) => option[fields.value.value] === selectedValues.value[index])));
  93. const setValue = (index, value) => {
  94. if (selectedValues.value[index] !== value) {
  95. const newValues = selectedValues.value.slice(0);
  96. newValues[index] = value;
  97. selectedValues.value = newValues;
  98. }
  99. };
  100. const getEventParams = () => ({
  101. selectedValues: selectedValues.value.slice(0),
  102. selectedOptions: selectedOptions.value,
  103. selectedIndexes: selectedIndexes.value
  104. });
  105. const onChange = (value, columnIndex) => {
  106. setValue(columnIndex, value);
  107. if (columnsType.value === "cascade") {
  108. selectedValues.value.forEach((value2, index) => {
  109. const options = currentColumns.value[index];
  110. if (!(0, import_utils2.isOptionExist)(options, value2, fields.value)) {
  111. setValue(index, options.length ? options[0][fields.value.value] : void 0);
  112. }
  113. });
  114. }
  115. emit("change", (0, import_utils.extend)({
  116. columnIndex
  117. }, getEventParams()));
  118. };
  119. const onClickOption = (currentOption, columnIndex) => emit("clickOption", (0, import_utils.extend)({
  120. columnIndex,
  121. currentOption
  122. }, getEventParams()));
  123. const confirm = () => {
  124. children.forEach((child) => child.stopMomentum());
  125. const params = getEventParams();
  126. (0, import_vue2.nextTick)(() => {
  127. emit("confirm", params);
  128. });
  129. return params;
  130. };
  131. const cancel = () => emit("cancel", getEventParams());
  132. const renderColumnItems = () => currentColumns.value.map((options, columnIndex) => (0, import_vue.createVNode)(import_PickerColumn.default, {
  133. "value": selectedValues.value[columnIndex],
  134. "fields": fields.value,
  135. "options": options,
  136. "readonly": props.readonly,
  137. "allowHtml": props.allowHtml,
  138. "optionHeight": optionHeight.value,
  139. "swipeDuration": props.swipeDuration,
  140. "visibleOptionNum": props.visibleOptionNum,
  141. "onChange": (value) => onChange(value, columnIndex),
  142. "onClickOption": (option) => onClickOption(option, columnIndex)
  143. }, {
  144. option: slots.option
  145. }));
  146. const renderMask = (wrapHeight) => {
  147. if (hasOptions.value) {
  148. const frameStyle = {
  149. height: `${optionHeight.value}px`
  150. };
  151. const maskStyle = {
  152. backgroundSize: `100% ${(wrapHeight - optionHeight.value) / 2}px`
  153. };
  154. return [(0, import_vue.createVNode)("div", {
  155. "class": (0, import_utils2.bem)("mask"),
  156. "style": maskStyle
  157. }, null), (0, import_vue.createVNode)("div", {
  158. "class": [import_utils.BORDER_UNSET_TOP_BOTTOM, (0, import_utils2.bem)("frame")],
  159. "style": frameStyle
  160. }, null)];
  161. }
  162. };
  163. const renderColumns = () => {
  164. const wrapHeight = optionHeight.value * +props.visibleOptionNum;
  165. const columnsStyle = {
  166. height: `${wrapHeight}px`
  167. };
  168. return (0, import_vue.createVNode)("div", {
  169. "ref": columnsRef,
  170. "class": (0, import_utils2.bem)("columns"),
  171. "style": columnsStyle
  172. }, [renderColumnItems(), renderMask(wrapHeight)]);
  173. };
  174. const renderToolbar = () => {
  175. if (props.showToolbar && !parent) {
  176. return (0, import_vue.createVNode)(import_PickerToolbar.default, (0, import_vue.mergeProps)((0, import_utils.pick)(props, import_PickerToolbar.pickerToolbarPropKeys), {
  177. "onConfirm": confirm,
  178. "onCancel": cancel
  179. }), (0, import_utils.pick)(slots, import_PickerToolbar.pickerToolbarSlots));
  180. }
  181. };
  182. (0, import_vue2.watch)(currentColumns, (columns) => {
  183. columns.forEach((options, index) => {
  184. if (options.length && !(0, import_utils2.isOptionExist)(options, selectedValues.value[index], fields.value)) {
  185. setValue(index, (0, import_utils2.getFirstEnabledOption)(options)[fields.value.value]);
  186. }
  187. });
  188. }, {
  189. immediate: true
  190. });
  191. let lastEmittedModelValue;
  192. (0, import_vue2.watch)(() => props.modelValue, (newValues) => {
  193. if (!(0, import_utils.isSameValue)(newValues, selectedValues.value) && !(0, import_utils.isSameValue)(newValues, lastEmittedModelValue)) {
  194. selectedValues.value = newValues.slice(0);
  195. }
  196. }, {
  197. deep: true
  198. });
  199. (0, import_vue2.watch)(selectedValues, (newValues) => {
  200. if (!(0, import_utils.isSameValue)(newValues, props.modelValue)) {
  201. lastEmittedModelValue = newValues.slice(0);
  202. emit("update:modelValue", lastEmittedModelValue);
  203. }
  204. }, {
  205. immediate: true
  206. });
  207. (0, import_use.useEventListener)("touchmove", import_utils.preventDefault, {
  208. target: columnsRef
  209. });
  210. const getSelectedOptions = () => selectedOptions.value;
  211. (0, import_use_expose.useExpose)({
  212. confirm,
  213. getSelectedOptions
  214. });
  215. return () => {
  216. var _a, _b;
  217. return (0, import_vue.createVNode)("div", {
  218. "class": (0, import_utils2.bem)()
  219. }, [props.toolbarPosition === "top" ? renderToolbar() : null, props.loading ? (0, import_vue.createVNode)(import_loading.Loading, {
  220. "class": (0, import_utils2.bem)("loading")
  221. }, null) : null, (_a = slots["columns-top"]) == null ? void 0 : _a.call(slots), renderColumns(), (_b = slots["columns-bottom"]) == null ? void 0 : _b.call(slots), props.toolbarPosition === "bottom" ? renderToolbar() : null]);
  222. };
  223. }
  224. });