Picker.js 9.9 KB

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