util-88d32f50.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. import { p as pickerSharedProps, P as Picker } from "./index-0f48f786.js";
  2. import { e as extend, o as makeArrayProp, q as padZero, s as clamp, c as createNamespace, v as isDate, x as isSameValue, y as pick, w as withInstall, t as truthProp, n as numericProp, m as makeNumericProp, z as makeStringProp, u as useChildren, A as useScrollParent, k as isDef, C as useClickAway, D as useEventListener, E as useRect, F as windowHeight, H as HAPTICS_FEEDBACK, a as useParent, G as unknownProp, g as getZIndexStyle, J as getContainingBlock, I as Icon, K as BORDER_BOTTOM } from "./index-487cde8c.js";
  3. import { u as useExpose } from "./use-scope-id-0b5b8615.js";
  4. import { d as defineComponent, r as ref, a as computed, w as watch, c as createVNode, m as mergeProps, n as reactive, T as Teleport, h as withDirectives, v as vShow } from "./index-5e4623ce.js";
  5. import { C as Cell } from "./index-8540448e.js";
  6. import { P as Popup } from "./index-eef3af38.js";
  7. import { u as useId } from "./index-41ec7e28.js";
  8. import { u as usePlaceholder } from "./use-placeholder-16d7c5d7.js";
  9. const sharedProps = extend({}, pickerSharedProps, {
  10. modelValue: makeArrayProp(),
  11. filter: Function,
  12. formatter: {
  13. type: Function,
  14. default: (type, option) => option
  15. }
  16. });
  17. const pickerInheritKeys = Object.keys(pickerSharedProps);
  18. function times(n, iteratee) {
  19. if (n < 0) {
  20. return [];
  21. }
  22. const result = Array(n);
  23. let index2 = -1;
  24. while (++index2 < n) {
  25. result[index2] = iteratee(index2);
  26. }
  27. return result;
  28. }
  29. const getMonthEndDay = (year, month) => 32 - new Date(year, month - 1, 32).getDate();
  30. const genOptions = (min, max, type, formatter, filter, values) => {
  31. const options = times(max - min + 1, (index2) => {
  32. const value = padZero(min + index2);
  33. return formatter(type, {
  34. text: value,
  35. value
  36. });
  37. });
  38. return filter ? filter(type, options, values) : options;
  39. };
  40. const formatValueRange = (values, columns) => values.map((value, index2) => {
  41. const column = columns[index2];
  42. if (column.length) {
  43. const minValue = +column[0].value;
  44. const maxValue = +column[column.length - 1].value;
  45. return padZero(clamp(+value, minValue, maxValue));
  46. }
  47. return value;
  48. });
  49. const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
  50. const [name$3] = createNamespace("date-picker");
  51. const datePickerProps = extend({}, sharedProps, {
  52. columnsType: {
  53. type: Array,
  54. default: () => ["year", "month", "day"]
  55. },
  56. minDate: {
  57. type: Date,
  58. default: () => new Date(currentYear - 10, 0, 1),
  59. validator: isDate
  60. },
  61. maxDate: {
  62. type: Date,
  63. default: () => new Date(currentYear + 10, 11, 31),
  64. validator: isDate
  65. }
  66. });
  67. var stdin_default$3 = defineComponent({
  68. name: name$3,
  69. props: datePickerProps,
  70. emits: ["confirm", "cancel", "change", "update:modelValue"],
  71. setup(props, {
  72. emit,
  73. slots
  74. }) {
  75. const currentValues = ref(props.modelValue);
  76. const updatedByExternalSources = ref(false);
  77. const pickerRef = ref();
  78. const genYearOptions = () => {
  79. const minYear = props.minDate.getFullYear();
  80. const maxYear = props.maxDate.getFullYear();
  81. return genOptions(minYear, maxYear, "year", props.formatter, props.filter);
  82. };
  83. const isMinYear = (year) => year === props.minDate.getFullYear();
  84. const isMaxYear = (year) => year === props.maxDate.getFullYear();
  85. const isMinMonth = (month) => month === props.minDate.getMonth() + 1;
  86. const isMaxMonth = (month) => month === props.maxDate.getMonth() + 1;
  87. const getValue = (type) => {
  88. const {
  89. minDate,
  90. columnsType
  91. } = props;
  92. const index2 = columnsType.indexOf(type);
  93. const value = updatedByExternalSources.value ? props.modelValue[index2] : currentValues.value[index2];
  94. if (value) {
  95. return +value;
  96. }
  97. switch (type) {
  98. case "year":
  99. return minDate.getFullYear();
  100. case "month":
  101. return minDate.getMonth() + 1;
  102. case "day":
  103. return minDate.getDate();
  104. }
  105. };
  106. const genMonthOptions = () => {
  107. const year = getValue("year");
  108. const minMonth = isMinYear(year) ? props.minDate.getMonth() + 1 : 1;
  109. const maxMonth = isMaxYear(year) ? props.maxDate.getMonth() + 1 : 12;
  110. return genOptions(minMonth, maxMonth, "month", props.formatter, props.filter);
  111. };
  112. const genDayOptions = () => {
  113. const year = getValue("year");
  114. const month = getValue("month");
  115. const minDate = isMinYear(year) && isMinMonth(month) ? props.minDate.getDate() : 1;
  116. const maxDate = isMaxYear(year) && isMaxMonth(month) ? props.maxDate.getDate() : getMonthEndDay(year, month);
  117. return genOptions(minDate, maxDate, "day", props.formatter, props.filter);
  118. };
  119. const confirm = () => {
  120. var _a;
  121. return (_a = pickerRef.value) == null ? void 0 : _a.confirm();
  122. };
  123. const getSelectedDate = () => currentValues.value;
  124. const columns = computed(() => props.columnsType.map((type) => {
  125. switch (type) {
  126. case "year":
  127. return genYearOptions();
  128. case "month":
  129. return genMonthOptions();
  130. case "day":
  131. return genDayOptions();
  132. default:
  133. return [];
  134. }
  135. }));
  136. watch(currentValues, (newValues) => {
  137. if (!isSameValue(newValues, props.modelValue)) {
  138. emit("update:modelValue", newValues);
  139. }
  140. });
  141. watch(() => props.modelValue, (newValues, oldValues) => {
  142. updatedByExternalSources.value = isSameValue(oldValues, currentValues.value);
  143. newValues = formatValueRange(newValues, columns.value);
  144. if (!isSameValue(newValues, currentValues.value)) {
  145. currentValues.value = newValues;
  146. }
  147. updatedByExternalSources.value = false;
  148. }, {
  149. immediate: true
  150. });
  151. const onChange = (...args) => emit("change", ...args);
  152. const onCancel = (...args) => emit("cancel", ...args);
  153. const onConfirm = (...args) => emit("confirm", ...args);
  154. useExpose({
  155. confirm,
  156. getSelectedDate
  157. });
  158. return () => createVNode(Picker, mergeProps({
  159. "ref": pickerRef,
  160. "modelValue": currentValues.value,
  161. "onUpdate:modelValue": ($event) => currentValues.value = $event,
  162. "columns": columns.value,
  163. "onChange": onChange,
  164. "onCancel": onCancel,
  165. "onConfirm": onConfirm
  166. }, pick(props, pickerInheritKeys)), slots);
  167. }
  168. });
  169. const DatePicker = withInstall(stdin_default$3);
  170. const [name$2, bem$2] = createNamespace("dropdown-menu");
  171. const dropdownMenuProps = {
  172. overlay: truthProp,
  173. zIndex: numericProp,
  174. duration: makeNumericProp(0.2),
  175. direction: makeStringProp("down"),
  176. activeColor: String,
  177. autoLocate: Boolean,
  178. closeOnClickOutside: truthProp,
  179. closeOnClickOverlay: truthProp,
  180. swipeThreshold: numericProp
  181. };
  182. const DROPDOWN_KEY = Symbol(name$2);
  183. var stdin_default$2 = defineComponent({
  184. name: name$2,
  185. props: dropdownMenuProps,
  186. setup(props, {
  187. slots
  188. }) {
  189. const id = useId();
  190. const root = ref();
  191. const barRef = ref();
  192. const offset = ref(0);
  193. const {
  194. children,
  195. linkChildren
  196. } = useChildren(DROPDOWN_KEY);
  197. const scrollParent = useScrollParent(root);
  198. const opened = computed(() => children.some((item) => item.state.showWrapper));
  199. const scrollable = computed(() => props.swipeThreshold && children.length > +props.swipeThreshold);
  200. const barStyle = computed(() => {
  201. if (opened.value && isDef(props.zIndex)) {
  202. return {
  203. zIndex: +props.zIndex + 1
  204. };
  205. }
  206. });
  207. const close = () => {
  208. children.forEach((item) => {
  209. item.toggle(false);
  210. });
  211. };
  212. const onClickAway = () => {
  213. if (props.closeOnClickOutside) {
  214. close();
  215. }
  216. };
  217. const updateOffset = () => {
  218. if (barRef.value) {
  219. const rect = useRect(barRef);
  220. if (props.direction === "down") {
  221. offset.value = rect.bottom;
  222. } else {
  223. offset.value = windowHeight.value - rect.top;
  224. }
  225. }
  226. };
  227. const onScroll = () => {
  228. if (opened.value) {
  229. updateOffset();
  230. }
  231. };
  232. const toggleItem = (active) => {
  233. children.forEach((item, index2) => {
  234. if (index2 === active) {
  235. item.toggle();
  236. } else if (item.state.showPopup) {
  237. item.toggle(false, {
  238. immediate: true
  239. });
  240. }
  241. });
  242. };
  243. const renderTitle = (item, index2) => {
  244. const {
  245. showPopup
  246. } = item.state;
  247. const {
  248. disabled,
  249. titleClass
  250. } = item;
  251. return createVNode("div", {
  252. "id": `${id}-${index2}`,
  253. "role": "button",
  254. "tabindex": disabled ? void 0 : 0,
  255. "class": [bem$2("item", {
  256. disabled,
  257. grow: scrollable.value
  258. }), {
  259. [HAPTICS_FEEDBACK]: !disabled
  260. }],
  261. "onClick": () => {
  262. if (!disabled) {
  263. toggleItem(index2);
  264. }
  265. }
  266. }, [createVNode("span", {
  267. "class": [bem$2("title", {
  268. down: showPopup === (props.direction === "down"),
  269. active: showPopup
  270. }), titleClass],
  271. "style": {
  272. color: showPopup ? props.activeColor : ""
  273. }
  274. }, [createVNode("div", {
  275. "class": "van-ellipsis"
  276. }, [item.renderTitle()])])]);
  277. };
  278. useExpose({
  279. close
  280. });
  281. linkChildren({
  282. id,
  283. props,
  284. offset,
  285. updateOffset
  286. });
  287. useClickAway(root, onClickAway);
  288. useEventListener("scroll", onScroll, {
  289. target: scrollParent,
  290. passive: true
  291. });
  292. return () => {
  293. var _a;
  294. return createVNode("div", {
  295. "ref": root,
  296. "class": bem$2()
  297. }, [createVNode("div", {
  298. "ref": barRef,
  299. "style": barStyle.value,
  300. "class": bem$2("bar", {
  301. opened: opened.value,
  302. scrollable: scrollable.value
  303. })
  304. }, [children.map(renderTitle)]), (_a = slots.default) == null ? void 0 : _a.call(slots)]);
  305. };
  306. }
  307. });
  308. const [name$1, bem$1] = createNamespace("dropdown-item");
  309. const dropdownItemProps = {
  310. title: String,
  311. options: makeArrayProp(),
  312. disabled: Boolean,
  313. teleport: [String, Object],
  314. lazyRender: truthProp,
  315. modelValue: unknownProp,
  316. titleClass: unknownProp
  317. };
  318. var stdin_default$1 = defineComponent({
  319. name: name$1,
  320. inheritAttrs: false,
  321. props: dropdownItemProps,
  322. emits: ["open", "opened", "close", "closed", "change", "update:modelValue"],
  323. setup(props, {
  324. emit,
  325. slots,
  326. attrs
  327. }) {
  328. const state = reactive({
  329. showPopup: false,
  330. transition: true,
  331. showWrapper: false
  332. });
  333. const wrapperRef = ref();
  334. const {
  335. parent,
  336. index: index2
  337. } = useParent(DROPDOWN_KEY);
  338. if (!parent) {
  339. return;
  340. }
  341. const getEmitter = (name2) => () => emit(name2);
  342. const onOpen = getEmitter("open");
  343. const onClose = getEmitter("close");
  344. const onOpened = getEmitter("opened");
  345. const onClosed = () => {
  346. state.showWrapper = false;
  347. emit("closed");
  348. };
  349. const onClickWrapper = (event) => {
  350. if (props.teleport) {
  351. event.stopPropagation();
  352. }
  353. };
  354. const toggle = (show = !state.showPopup, options = {}) => {
  355. if (show === state.showPopup) {
  356. return;
  357. }
  358. state.showPopup = show;
  359. state.transition = !options.immediate;
  360. if (show) {
  361. parent.updateOffset();
  362. state.showWrapper = true;
  363. }
  364. };
  365. const renderTitle = () => {
  366. if (slots.title) {
  367. return slots.title();
  368. }
  369. if (props.title) {
  370. return props.title;
  371. }
  372. const match = props.options.find((option) => option.value === props.modelValue);
  373. return match ? match.text : "";
  374. };
  375. const renderOption = (option) => {
  376. const {
  377. activeColor
  378. } = parent.props;
  379. const {
  380. disabled
  381. } = option;
  382. const active = option.value === props.modelValue;
  383. const onClick = () => {
  384. if (disabled) {
  385. return;
  386. }
  387. state.showPopup = false;
  388. if (option.value !== props.modelValue) {
  389. emit("update:modelValue", option.value);
  390. emit("change", option.value);
  391. }
  392. };
  393. const renderIcon = () => {
  394. if (active) {
  395. return createVNode(Icon, {
  396. "class": bem$1("icon"),
  397. "color": disabled ? void 0 : activeColor,
  398. "name": "success"
  399. }, null);
  400. }
  401. };
  402. return createVNode(Cell, {
  403. "role": "menuitem",
  404. "key": String(option.value),
  405. "icon": option.icon,
  406. "title": option.text,
  407. "class": bem$1("option", {
  408. active,
  409. disabled
  410. }),
  411. "style": {
  412. color: active ? activeColor : ""
  413. },
  414. "tabindex": active ? 0 : -1,
  415. "clickable": !disabled,
  416. "onClick": onClick
  417. }, {
  418. value: renderIcon
  419. });
  420. };
  421. const renderContent = () => {
  422. const {
  423. offset
  424. } = parent;
  425. const {
  426. autoLocate,
  427. zIndex,
  428. overlay,
  429. duration,
  430. direction,
  431. closeOnClickOverlay
  432. } = parent.props;
  433. const style = getZIndexStyle(zIndex);
  434. let offsetValue = offset.value;
  435. if (autoLocate && wrapperRef.value) {
  436. const offsetParent = getContainingBlock(wrapperRef.value);
  437. if (offsetParent) {
  438. offsetValue -= useRect(offsetParent).top;
  439. }
  440. }
  441. if (direction === "down") {
  442. style.top = `${offsetValue}px`;
  443. } else {
  444. style.bottom = `${offsetValue}px`;
  445. }
  446. return withDirectives(createVNode("div", mergeProps({
  447. "ref": wrapperRef,
  448. "style": style,
  449. "class": bem$1([direction]),
  450. "onClick": onClickWrapper
  451. }, attrs), [createVNode(Popup, {
  452. "show": state.showPopup,
  453. "onUpdate:show": ($event) => state.showPopup = $event,
  454. "role": "menu",
  455. "class": bem$1("content"),
  456. "overlay": overlay,
  457. "position": direction === "down" ? "top" : "bottom",
  458. "duration": state.transition ? duration : 0,
  459. "lazyRender": props.lazyRender,
  460. "overlayStyle": {
  461. position: "absolute"
  462. },
  463. "aria-labelledby": `${parent.id}-${index2.value}`,
  464. "closeOnClickOverlay": closeOnClickOverlay,
  465. "onOpen": onOpen,
  466. "onClose": onClose,
  467. "onOpened": onOpened,
  468. "onClosed": onClosed
  469. }, {
  470. default: () => {
  471. var _a;
  472. return [props.options.map(renderOption), (_a = slots.default) == null ? void 0 : _a.call(slots)];
  473. }
  474. })]), [[vShow, state.showWrapper]]);
  475. };
  476. useExpose({
  477. state,
  478. toggle,
  479. renderTitle
  480. });
  481. return () => {
  482. if (props.teleport) {
  483. return createVNode(Teleport, {
  484. "to": props.teleport
  485. }, {
  486. default: () => [renderContent()]
  487. });
  488. }
  489. return renderContent();
  490. };
  491. }
  492. });
  493. const DropdownItem = withInstall(stdin_default$1);
  494. const DropdownMenu = withInstall(stdin_default$2);
  495. const [name, bem] = createNamespace("nav-bar");
  496. const navBarProps = {
  497. title: String,
  498. fixed: Boolean,
  499. zIndex: numericProp,
  500. border: truthProp,
  501. leftText: String,
  502. rightText: String,
  503. leftDisabled: Boolean,
  504. rightDisabled: Boolean,
  505. leftArrow: Boolean,
  506. placeholder: Boolean,
  507. safeAreaInsetTop: Boolean,
  508. clickable: truthProp
  509. };
  510. var stdin_default = defineComponent({
  511. name,
  512. props: navBarProps,
  513. emits: ["clickLeft", "clickRight"],
  514. setup(props, {
  515. emit,
  516. slots
  517. }) {
  518. const navBarRef = ref();
  519. const renderPlaceholder = usePlaceholder(navBarRef, bem);
  520. const onClickLeft = (event) => {
  521. if (!props.leftDisabled) {
  522. emit("clickLeft", event);
  523. }
  524. };
  525. const onClickRight = (event) => {
  526. if (!props.rightDisabled) {
  527. emit("clickRight", event);
  528. }
  529. };
  530. const renderLeft = () => {
  531. if (slots.left) {
  532. return slots.left();
  533. }
  534. return [props.leftArrow && createVNode(Icon, {
  535. "class": bem("arrow"),
  536. "name": "arrow-left"
  537. }, null), props.leftText && createVNode("span", {
  538. "class": bem("text")
  539. }, [props.leftText])];
  540. };
  541. const renderRight = () => {
  542. if (slots.right) {
  543. return slots.right();
  544. }
  545. return createVNode("span", {
  546. "class": bem("text")
  547. }, [props.rightText]);
  548. };
  549. const renderNavBar = () => {
  550. const {
  551. title,
  552. fixed,
  553. border,
  554. zIndex
  555. } = props;
  556. const style = getZIndexStyle(zIndex);
  557. const hasLeft = props.leftArrow || props.leftText || slots.left;
  558. const hasRight = props.rightText || slots.right;
  559. return createVNode("div", {
  560. "ref": navBarRef,
  561. "style": style,
  562. "class": [bem({
  563. fixed
  564. }), {
  565. [BORDER_BOTTOM]: border,
  566. "van-safe-area-top": props.safeAreaInsetTop
  567. }]
  568. }, [createVNode("div", {
  569. "class": bem("content")
  570. }, [hasLeft && createVNode("div", {
  571. "class": [bem("left", {
  572. disabled: props.leftDisabled
  573. }), props.clickable && !props.leftDisabled ? HAPTICS_FEEDBACK : ""],
  574. "onClick": onClickLeft
  575. }, [renderLeft()]), createVNode("div", {
  576. "class": [bem("title"), "van-ellipsis"]
  577. }, [slots.title ? slots.title() : title]), hasRight && createVNode("div", {
  578. "class": [bem("right", {
  579. disabled: props.rightDisabled
  580. }), props.clickable && !props.rightDisabled ? HAPTICS_FEEDBACK : ""],
  581. "onClick": onClickRight
  582. }, [renderRight()])])]);
  583. };
  584. return () => {
  585. if (props.fixed && props.placeholder) {
  586. return renderPlaceholder(renderNavBar);
  587. }
  588. return renderNavBar();
  589. };
  590. }
  591. });
  592. const NavBar = withInstall(stdin_default);
  593. const index$2 = "";
  594. const index$1 = "";
  595. const index = "";
  596. const getDateTimeAgo = function(month_count) {
  597. const currentDate = /* @__PURE__ */ new Date();
  598. let currentYear2 = currentDate.getFullYear();
  599. let currentMonth = currentDate.getMonth();
  600. let currentDay = currentDate.getDate();
  601. let year = 0;
  602. let month = 0;
  603. let y = Math.trunc(month_count / 12);
  604. let m = month_count % 12;
  605. if (m < currentMonth) {
  606. year = currentYear2 - y;
  607. month = currentMonth - m;
  608. } else {
  609. year = currentYear2 - y - 1;
  610. month = currentMonth + 12 - m;
  611. }
  612. return new Date(year, month, currentDay);
  613. };
  614. export {
  615. DatePicker as D,
  616. NavBar as N,
  617. DropdownMenu as a,
  618. DropdownItem as b,
  619. getDateTimeAgo as g
  620. };