zartui 3.1.93 → 3.1.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/es/composables/use-media-download.d.ts +20 -0
  2. package/es/composables/use-media-download.mjs +111 -0
  3. package/es/image-preview/ImagePreview.d.ts +2 -5
  4. package/es/image-preview/ImagePreview.mjs +32 -79
  5. package/es/image-preview/function-call.mjs +4 -1
  6. package/es/image-preview/index.css +1 -1
  7. package/es/image-preview/index.d.ts +1 -2
  8. package/es/image-preview/style/index.mjs +2 -0
  9. package/es/image-preview/types.d.ts +3 -1
  10. package/es/index.d.ts +1 -1
  11. package/es/index.mjs +1 -1
  12. package/es/media-picker/MediaPicker.d.ts +1 -1
  13. package/es/media-picker/MediaPicker.mjs +54 -36
  14. package/es/media-picker/index.d.ts +2 -2
  15. package/es/media-picker/style/index.mjs +3 -1
  16. package/es/media-player/MediaPlayer.d.ts +21 -0
  17. package/es/media-player/MediaPlayer.mjs +25 -2
  18. package/es/media-player/index.css +1 -1
  19. package/es/media-player/index.d.ts +14 -0
  20. package/es/media-player/style/index.mjs +4 -0
  21. package/es/photo-picker/index.d.ts +2 -2
  22. package/es/photo-picker/style/index.mjs +2 -0
  23. package/es/uploader/style/index.mjs +2 -0
  24. package/lib/composables/use-media-download.d.ts +20 -0
  25. package/lib/composables/use-media-download.js +138 -0
  26. package/lib/image-preview/ImagePreview.d.ts +2 -5
  27. package/lib/image-preview/ImagePreview.js +32 -79
  28. package/lib/image-preview/function-call.js +4 -1
  29. package/lib/image-preview/index.css +1 -1
  30. package/lib/image-preview/index.d.ts +1 -2
  31. package/lib/image-preview/style/index.js +2 -0
  32. package/lib/image-preview/types.d.ts +3 -1
  33. package/lib/index.css +1 -1
  34. package/lib/index.d.ts +1 -1
  35. package/lib/index.js +1 -1
  36. package/lib/media-picker/MediaPicker.d.ts +1 -1
  37. package/lib/media-picker/MediaPicker.js +51 -35
  38. package/lib/media-picker/index.d.ts +2 -2
  39. package/lib/media-picker/style/index.js +3 -1
  40. package/lib/media-player/MediaPlayer.d.ts +21 -0
  41. package/lib/media-player/MediaPlayer.js +25 -2
  42. package/lib/media-player/index.css +1 -1
  43. package/lib/media-player/index.d.ts +14 -0
  44. package/lib/media-player/style/index.js +4 -0
  45. package/lib/photo-picker/index.d.ts +2 -2
  46. package/lib/photo-picker/style/index.js +2 -0
  47. package/lib/uploader/style/index.js +2 -0
  48. package/lib/web-types.json +1 -1
  49. package/lib/zartui.cjs.js +196 -105
  50. package/lib/zartui.es.js +196 -105
  51. package/lib/zartui.js +204 -113
  52. package/lib/zartui.min.js +2 -2
  53. package/package.json +2 -2
@@ -2,10 +2,15 @@ import { createTextVNode as _createTextVNode, createVNode as _createVNode } from
2
2
  import { createNamespace, isIOS, isWeixin, makeArrayProp, makeStringProp } from "../utils/index.mjs";
3
3
  import { defineComponent, nextTick, ref } from "vue";
4
4
  import ZtPopup from "../popup/index.mjs";
5
+ import ZtIcon from "../icon/index.mjs";
6
+ import { useMediaDownload } from "../composables/use-media-download.mjs";
5
7
  const mediaPlayerProps = {
6
8
  show: Boolean,
7
9
  mediaType: makeStringProp("file"),
8
10
  mediaUrl: makeStringProp(""),
11
+ fileName: makeStringProp(""),
12
+ showDownload: Boolean,
13
+ downloadAction: Function,
9
14
  /** 视频播放时的控件展示列表,参考:https://wicg.github.io/controls-list/explainer.html */
10
15
  controlsList: makeArrayProp([]),
11
16
  teleport: [String, Object]
@@ -20,6 +25,15 @@ var stdin_default = defineComponent({
20
25
  }) {
21
26
  const audioRef = ref();
22
27
  const videoRef = ref();
28
+ const {
29
+ downloading,
30
+ download
31
+ } = useMediaDownload(props);
32
+ const onDownload = () => download({
33
+ index: 0,
34
+ url: props.mediaUrl,
35
+ fileName: props.fileName
36
+ });
23
37
  const getMediaElement = () => {
24
38
  let player;
25
39
  if (props.mediaType === "audio") {
@@ -66,7 +80,7 @@ var stdin_default = defineComponent({
66
80
  "src": props.mediaUrl,
67
81
  "ref": videoRef,
68
82
  "controls": true,
69
- "controlslist": props.controlsList.join(" "),
83
+ "controlslist": [.../* @__PURE__ */ new Set([...props.controlsList, "nodownload"])].join(" "),
70
84
  "autoplay": true,
71
85
  "id": "video",
72
86
  "webkit-playsinline": true,
@@ -102,7 +116,16 @@ var stdin_default = defineComponent({
102
116
  "type": "button",
103
117
  "class": bem("cancel-btn"),
104
118
  "onClick": onClose
105
- }, [_createTextVNode("\u5173\u95ED")])])]
119
+ }, [_createTextVNode("\u5173\u95ED")]), props.showDownload && props.mediaType === "video" && props.mediaUrl && !props.mediaUrl.startsWith("data:") && _createVNode("button", {
120
+ "type": "button",
121
+ "class": bem("download-btn"),
122
+ "aria-label": "\u4E0B\u8F7D\u89C6\u9891",
123
+ "disabled": downloading.value,
124
+ "onClick": onDownload
125
+ }, [_createVNode(ZtIcon, {
126
+ "name": "download",
127
+ "size": "24"
128
+ }, null)])])]
106
129
  });
107
130
  }
108
131
  });
@@ -1 +1 @@
1
- .zt-media-player{background-color:var(--zt-background);font-size:0}.zt-media-player__video{width:100%;height:400px;max-height:70%;background-color:rgba(0,0,0,.8)}.zt-media-player__audio{width:100%}.zt-media-player__cancel{padding:8px 16px;color:var(--zt-text-color)}.zt-media-player__cancel-btn{width:100%;border:none;cursor:pointer;background-color:var(--zt-gray-a04);border-radius:20px;height:44px;font-size:var(--zt-font-size-lg);color:var(--zt-text-color);line-height:var(--zt-line-height-lg)}.zt-media-player__cancel-btn:active{opacity:var(--zt-active-opacity)}
1
+ .zt-media-player{background-color:var(--zt-background);font-size:0}.zt-media-player__video{width:100%;height:400px;max-height:70%;background-color:rgba(0,0,0,.8)}.zt-media-player__audio{width:100%}.zt-media-player__cancel{display:flex;align-items:center;gap:12px;padding:8px 16px;color:var(--zt-text-color)}.zt-media-player__download-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:44px;height:44px;padding:0;border:none;border-radius:20px;background-color:var(--zt-gray-a04);color:var(--zt-text-color);cursor:pointer}.zt-media-player__download-btn:active{opacity:var(--zt-active-opacity)}.zt-media-player__cancel-btn{flex:1;min-width:0;width:100%;border:none;cursor:pointer;background-color:var(--zt-gray-a04);border-radius:20px;height:44px;font-size:var(--zt-font-size-lg);color:var(--zt-text-color);line-height:var(--zt-line-height-lg)}.zt-media-player__cancel-btn:active{opacity:var(--zt-active-opacity)}
@@ -8,6 +8,12 @@ export declare const MediaPlayer: import("../utils").WithInstall<import("vue").D
8
8
  type: import("vue").PropType<string>;
9
9
  default: string;
10
10
  };
11
+ fileName: {
12
+ type: import("vue").PropType<string>;
13
+ default: string;
14
+ };
15
+ showDownload: BooleanConstructor;
16
+ downloadAction: import("vue").PropType<(params: import("..").DownloadActionParams) => boolean>;
11
17
  controlsList: {
12
18
  type: import("vue").PropType<string[]>;
13
19
  default: () => string[];
@@ -23,6 +29,12 @@ export declare const MediaPlayer: import("../utils").WithInstall<import("vue").D
23
29
  type: import("vue").PropType<string>;
24
30
  default: string;
25
31
  };
32
+ fileName: {
33
+ type: import("vue").PropType<string>;
34
+ default: string;
35
+ };
36
+ showDownload: BooleanConstructor;
37
+ downloadAction: import("vue").PropType<(params: import("..").DownloadActionParams) => boolean>;
26
38
  controlsList: {
27
39
  type: import("vue").PropType<string[]>;
28
40
  default: () => string[];
@@ -33,8 +45,10 @@ export declare const MediaPlayer: import("../utils").WithInstall<import("vue").D
33
45
  }>, {
34
46
  show: boolean;
35
47
  controlsList: string[];
48
+ showDownload: boolean;
36
49
  mediaType: import("..").MediaType;
37
50
  mediaUrl: string;
51
+ fileName: string;
38
52
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
39
53
  export default MediaPlayer;
40
54
  export type { MediaPlayerProps } from './MediaPlayer';
@@ -3,4 +3,8 @@ import "../../badge/index.css";
3
3
  import "../../icon/index.css";
4
4
  import "../../overlay/index.css";
5
5
  import "../../popup/index.css";
6
+ import "../../loading/index.css";
7
+ import "../../toast/index.css";
8
+ import "../../button/index.css";
9
+ import "../../dialog/index.css";
6
10
  import "../index.css";
@@ -2,7 +2,7 @@ export declare const PhotoPicker: import("../utils").WithInstall<import("vue").D
2
2
  disabled: BooleanConstructor;
3
3
  showTitle: BooleanConstructor;
4
4
  showDownload: BooleanConstructor;
5
- downloadAction: import("vue").PropType<(params: import("../image-preview/ImagePreview").DownloadActionParams) => boolean>;
5
+ downloadAction: import("vue").PropType<(params: import("..").DownloadActionParams) => boolean>;
6
6
  useFileNameAsLabel: BooleanConstructor;
7
7
  title: {
8
8
  type: import("vue").PropType<string>;
@@ -59,7 +59,7 @@ export declare const PhotoPicker: import("../utils").WithInstall<import("vue").D
59
59
  disabled: BooleanConstructor;
60
60
  showTitle: BooleanConstructor;
61
61
  showDownload: BooleanConstructor;
62
- downloadAction: import("vue").PropType<(params: import("../image-preview/ImagePreview").DownloadActionParams) => boolean>;
62
+ downloadAction: import("vue").PropType<(params: import("..").DownloadActionParams) => boolean>;
63
63
  useFileNameAsLabel: BooleanConstructor;
64
64
  title: {
65
65
  type: import("vue").PropType<string>;
@@ -6,6 +6,8 @@ import "../../overlay/index.css";
6
6
  import "../../popup/index.css";
7
7
  import "../../loading/index.css";
8
8
  import "../../toast/index.css";
9
+ import "../../button/index.css";
10
+ import "../../dialog/index.css";
9
11
  import "../../action-sheet/index.css";
10
12
  import "../../swipe/index.css";
11
13
  import "../../swipe-item/index.css";
@@ -6,6 +6,8 @@ import "../../overlay/index.css";
6
6
  import "../../popup/index.css";
7
7
  import "../../loading/index.css";
8
8
  import "../../toast/index.css";
9
+ import "../../button/index.css";
10
+ import "../../dialog/index.css";
9
11
  import "../../swipe/index.css";
10
12
  import "../../swipe-item/index.css";
11
13
  import "../../image-preview/index.css";
@@ -0,0 +1,20 @@
1
+ export type DownloadActionParams = {
2
+ index: number;
3
+ url?: string;
4
+ title?: string;
5
+ fileName?: string;
6
+ };
7
+ export type FileDownloadOptions = {
8
+ url: string;
9
+ fileName?: string;
10
+ title?: string;
11
+ index?: number;
12
+ };
13
+ export declare function useMediaDownload(props: {
14
+ showDownload: boolean;
15
+ downloadAction?: (params: DownloadActionParams) => boolean;
16
+ }): {
17
+ downloading: import("vue").Ref<boolean, boolean>;
18
+ download: (params: DownloadActionParams, confirm?: boolean) => Promise<void>;
19
+ downloadFile: (options: FileDownloadOptions) => Promise<void>;
20
+ };
@@ -0,0 +1,138 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __export = (target, all) => {
25
+ for (var name in all)
26
+ __defProp(target, name, { get: all[name], enumerable: true });
27
+ };
28
+ var __copyProps = (to, from, except, desc) => {
29
+ if (from && typeof from === "object" || typeof from === "function") {
30
+ for (let key of __getOwnPropNames(from))
31
+ if (!__hasOwnProp.call(to, key) && key !== except)
32
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
33
+ }
34
+ return to;
35
+ };
36
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
37
+ // If the importer is in node compatibility mode or this is not an ESM
38
+ // file that has been converted to a CommonJS file using a Babel-
39
+ // compatible transform (i.e. "__esModule" has not been set), then set
40
+ // "default" to the CommonJS "module.exports" for node compatibility.
41
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
42
+ mod
43
+ ));
44
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
45
+ var __async = (__this, __arguments, generator) => {
46
+ return new Promise((resolve, reject) => {
47
+ var fulfilled = (value) => {
48
+ try {
49
+ step(generator.next(value));
50
+ } catch (e) {
51
+ reject(e);
52
+ }
53
+ };
54
+ var rejected = (value) => {
55
+ try {
56
+ step(generator.throw(value));
57
+ } catch (e) {
58
+ reject(e);
59
+ }
60
+ };
61
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
62
+ step((generator = generator.apply(__this, __arguments)).next());
63
+ });
64
+ };
65
+ var stdin_exports = {};
66
+ __export(stdin_exports, {
67
+ useMediaDownload: () => useMediaDownload
68
+ });
69
+ module.exports = __toCommonJS(stdin_exports);
70
+ var import_vue = require("vue");
71
+ var import_dialog = require("../dialog");
72
+ var import_toast = require("../toast");
73
+ function useMediaDownload(props) {
74
+ const downloading = (0, import_vue.ref)(false);
75
+ const downloadInBrowser = (params) => {
76
+ const link = document.createElement("a");
77
+ link.href = params.url;
78
+ link.download = params.fileName || "";
79
+ document.body.appendChild(link);
80
+ link.click();
81
+ link.remove();
82
+ };
83
+ const download = (params, confirm = false) => __async(this, null, function* () {
84
+ var _a, _b, _c;
85
+ if (!props.showDownload || downloading.value || !params.url || params.url.startsWith("data:")) {
86
+ return;
87
+ }
88
+ downloading.value = true;
89
+ try {
90
+ if (confirm) {
91
+ try {
92
+ yield (0, import_dialog.showConfirmDialog)({ message: "\u9644\u4EF6\u683C\u5F0F\u6682\u4E0D\u652F\u6301\u9884\u89C8\uFF0C\u662F\u5426\u4E0B\u8F7D\u539F\u6587\u4EF6" });
93
+ } catch (action) {
94
+ if (action !== "cancel") {
95
+ throw action;
96
+ }
97
+ return;
98
+ }
99
+ }
100
+ if (!props.showDownload || ((_a = props.downloadAction) == null ? void 0 : _a.call(props, params))) {
101
+ return;
102
+ }
103
+ let file;
104
+ try {
105
+ const sdk = yield import("@egova/universal-js-sdk");
106
+ file = (_b = sdk.getJSI()) == null ? void 0 : _b.file;
107
+ } catch (e) {
108
+ downloadInBrowser(params);
109
+ return;
110
+ }
111
+ if (!(file == null ? void 0 : file.download)) {
112
+ downloadInBrowser(params);
113
+ return;
114
+ }
115
+ (0, import_toast.showLoadingToast)({ message: "\u4E0B\u8F7D\u4E2D...", forbidClick: true, duration: 0 });
116
+ try {
117
+ const result = yield file.download({ url: params.url });
118
+ const displayPath = (_c = result == null ? void 0 : result.tempFilePath) == null ? void 0 : _c.replace(/^\/storage\/emulated\/0\//, "");
119
+ (0, import_toast.closeToast)();
120
+ (0, import_toast.showSuccessToast)({
121
+ message: displayPath ? `\u4E0B\u8F7D\u6210\u529F
122
+ \u4FDD\u5B58\u8DEF\u5F84\uFF1A${displayPath}` : "\u4E0B\u8F7D\u6210\u529F",
123
+ duration: 5e3
124
+ });
125
+ } catch (e) {
126
+ (0, import_toast.closeToast)();
127
+ (0, import_toast.showFailToast)("\u4E0B\u8F7D\u5931\u8D25");
128
+ }
129
+ } finally {
130
+ downloading.value = false;
131
+ }
132
+ });
133
+ const downloadFile = (options) => {
134
+ var _a;
135
+ return download(__spreadProps(__spreadValues({}, options), { index: (_a = options.index) != null ? _a : -1 }), true);
136
+ };
137
+ return { downloading, download, downloadFile };
138
+ }
@@ -1,12 +1,9 @@
1
1
  import type { PropType, CSSProperties, ExtractPropTypes } from 'vue';
2
2
  import { Interceptor } from '../utils';
3
3
  import { PopupCloseIconPosition } from '../popup';
4
+ import type { DownloadActionParams } from '../composables/use-media-download';
4
5
  import { ImageItem } from './types';
5
- export type DownloadActionParams = {
6
- index: number;
7
- url?: string;
8
- title?: string;
9
- };
6
+ export type { DownloadActionParams, FileDownloadOptions } from '../composables/use-media-download';
10
7
  export declare const imagePreviewProps: {
11
8
  show: BooleanConstructor;
12
9
  loop: {
@@ -25,26 +25,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  mod
26
26
  ));
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
- var __async = (__this, __arguments, generator) => {
29
- return new Promise((resolve, reject) => {
30
- var fulfilled = (value) => {
31
- try {
32
- step(generator.next(value));
33
- } catch (e) {
34
- reject(e);
35
- }
36
- };
37
- var rejected = (value) => {
38
- try {
39
- step(generator.throw(value));
40
- } catch (e) {
41
- reject(e);
42
- }
43
- };
44
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
45
- step((generator = generator.apply(__this, __arguments)).next());
46
- });
47
- };
48
28
  var stdin_exports = {};
49
29
  __export(stdin_exports, {
50
30
  default: () => stdin_default,
@@ -59,8 +39,7 @@ var import_icon = require("../icon");
59
39
  var import_swipe = require("../swipe");
60
40
  var import_popup = require("../popup");
61
41
  var import_ImagePreviewItem = __toESM(require("./ImagePreviewItem"));
62
- var import_Download = require("./svg/Download");
63
- var import_toast = require("../toast");
42
+ var import_use_media_download = require("../composables/use-media-download");
64
43
  const [name, bem] = (0, import_utils.createNamespace)("image-preview");
65
44
  const popupProps = ["show", "transition", "overlayStyle", "closeOnPopstate", "teleport"];
66
45
  const imagePreviewProps = {
@@ -97,8 +76,13 @@ var stdin_default = (0, import_vue.defineComponent)({
97
76
  slots
98
77
  }) {
99
78
  const swipeRef = (0, import_vue.ref)();
79
+ const {
80
+ downloading,
81
+ download,
82
+ downloadFile
83
+ } = (0, import_use_media_download.useMediaDownload)(props);
100
84
  const state = (0, import_vue.reactive)({
101
- active: 0,
85
+ active: +props.startPosition,
102
86
  rootWidth: 0,
103
87
  rootHeight: 0,
104
88
  disableZoom: false
@@ -136,71 +120,38 @@ var stdin_default = (0, import_vue.defineComponent)({
136
120
  }, [props.images[state.active].title]);
137
121
  }
138
122
  };
139
- const onDownload = () => __async(this, null, function* () {
123
+ const onDownload = () => {
140
124
  var _a, _b, _c;
141
- const downloadParams = {
125
+ return download({
142
126
  index: state.active,
143
127
  url: (_a = props.images[state.active]) == null ? void 0 : _a.url,
144
- title: (_b = props.images[state.active]) == null ? void 0 : _b.title
145
- };
146
- if (props.downloadAction) {
147
- const result = props.downloadAction(downloadParams);
148
- if (result) {
149
- return;
150
- }
151
- }
152
- try {
153
- let universalJsSdk = yield import("@egova/universal-js-sdk");
154
- if (universalJsSdk && universalJsSdk.getJSI && downloadParams.url) {
155
- let fileJsi = (_c = universalJsSdk.getJSI()) == null ? void 0 : _c.file;
156
- if (fileJsi && fileJsi.download) {
157
- (0, import_toast.showLoadingToast)({
158
- message: "\u4E0B\u8F7D\u4E2D...",
159
- forbidClick: true,
160
- duration: 0
161
- });
162
- fileJsi.download({
163
- url: downloadParams.url
164
- }).then(({
165
- tempFilePath
166
- }) => {
167
- (0, import_toast.closeToast)();
168
- (0, import_toast.showSuccessToast)("\u4E0B\u8F7D\u6210\u529F");
169
- }).catch(() => {
170
- (0, import_toast.closeToast)();
171
- (0, import_toast.showFailToast)("\u4E0B\u8F7D\u5931\u8D25");
172
- });
173
- return;
174
- } else {
175
- (0, import_toast.showFailToast)("\u5F53\u524D\u73AF\u5883\u6682\u4E0D\u652F\u6301\u4E0B\u8F7D");
176
- }
177
- }
178
- } catch (e) {
179
- console.log(e.message);
180
- }
181
- });
128
+ title: (_b = props.images[state.active]) == null ? void 0 : _b.title,
129
+ fileName: (_c = props.images[state.active]) == null ? void 0 : _c.fileName
130
+ });
131
+ };
132
+ const renderDownloadIcon = () => (0, import_vue.createVNode)("button", {
133
+ "type": "button",
134
+ "class": bem("download-icon"),
135
+ "aria-label": "\u4E0B\u8F7D\u539F\u56FE",
136
+ "disabled": downloading.value,
137
+ "onClick": onDownload
138
+ }, [(0, import_vue.createVNode)(import_icon.Icon, {
139
+ "name": "download",
140
+ "size": "24"
141
+ }, null)]);
182
142
  const renderIndex = () => {
183
143
  const image = props.images[state.active];
184
- const showDownload = props.showDownload && !image.url.startsWith("data:");
144
+ const showDownload = props.showDownload && (image == null ? void 0 : image.url) && !image.url.startsWith("data:");
185
145
  if (props.showIndex || showDownload) {
186
- if (props.showIndex && slots.index) {
187
- return (0, import_vue.createVNode)("div", {
188
- "class": bem("index")
189
- }, [slots.index({
190
- index: state.active
191
- })]);
192
- }
193
146
  return (0, import_vue.createVNode)("div", {
194
147
  "class": bem("index")
195
- }, [props.showIndex && renderIndexText(), props.showIndex && renderImageTitle(), showDownload && renderDownloadIcon()]);
148
+ }, [props.showIndex && (0, import_vue.createVNode)("div", {
149
+ "class": bem("index-content")
150
+ }, [slots.index ? slots.index({
151
+ index: state.active
152
+ }) : [renderIndexText(), renderImageTitle()]]), showDownload && renderDownloadIcon()]);
196
153
  }
197
154
  };
198
- const renderDownloadIcon = () => {
199
- return (0, import_vue.createVNode)("div", {
200
- "class": bem("download-icon"),
201
- "onClick": onDownload
202
- }, [(0, import_Download.Download)(bem)]);
203
- };
204
155
  const renderCover = () => {
205
156
  if (slots.cover) {
206
157
  return (0, import_vue.createVNode)("div", {
@@ -262,7 +213,8 @@ var stdin_default = (0, import_vue.defineComponent)({
262
213
  return (_a = swipeRef.value) == null ? void 0 : _a.swipeTo(index, options);
263
214
  };
264
215
  (0, import_use_expose.useExpose)({
265
- swipeTo
216
+ swipeTo,
217
+ downloadFile
266
218
  });
267
219
  (0, import_vue.onMounted)(() => {
268
220
  resize();
@@ -292,6 +244,7 @@ var stdin_default = (0, import_vue.defineComponent)({
292
244
  return () => (0, import_vue.createVNode)(import_popup.Popup, (0, import_vue.mergeProps)({
293
245
  "class": [bem(), props.className],
294
246
  "overlayClass": [bem("overlay"), props.overlayClass],
247
+ "onClick": (event) => event.stopPropagation(),
295
248
  "onClosed": onClosed,
296
249
  "onUpdate:show": updateShow
297
250
  }, (0, import_utils.pick)(props, popupProps)), {
@@ -47,6 +47,8 @@ const defaultConfig = {
47
47
  className: "",
48
48
  showIndex: true,
49
49
  closeable: false,
50
+ showDownload: false,
51
+ downloadAction: void 0,
50
52
  closeIcon: "clear",
51
53
  transition: void 0,
52
54
  beforeClose: void 0,
@@ -95,7 +97,8 @@ const showImagePreview = (options, startPosition = 0) => {
95
97
  }
96
98
  return {
97
99
  url: opt.url,
98
- title: opt.title || ""
100
+ title: opt.title || "",
101
+ fileName: opt.fileName
99
102
  };
100
103
  }),
101
104
  startPosition
@@ -1 +1 @@
1
- :root{--zt-image-preview-index-height: 48px;--zt-image-preview-index-background: var(--zt-gray-a4);--zt-image-preview-index-text-color: var(--zt-white);--zt-image-preview-overlay-background: rgba(0, 0, 0, .9);--zt-image-preview-close-icon-color: var(--zt-gray-5);--zt-image-preview-close-icon-margin: var(--zt-padding-md);--zt-image-preview-close-icon-z-index: 1;--zt-image-preview-error-font-size: 36px}:root[zt-theme-size=large]{--zt-image-preview-error-font-size: 42px}.zt-image-preview{position:fixed;top:0;left:0;width:100%;height:100%;max-width:none;background-color:transparent;transform:none}.zt-image-preview__swipe{height:100%}.zt-image-preview__swipe-item{display:flex;align-items:center;justify-content:center;overflow:hidden}.zt-image-preview__cover{position:absolute;top:0;left:0}.zt-image-preview__image,.zt-image-preview__image-wrap{width:100%;transition-property:transform}.zt-image-preview__image--vertical,.zt-image-preview__image-wrap--vertical{width:auto;height:100%}.zt-image-preview__image img,.zt-image-preview__image-wrap img,.zt-image-preview__image video,.zt-image-preview__image-wrap video{-webkit-user-drag:none}.zt-image-preview__image .zt-image__error,.zt-image-preview__image-wrap .zt-image__error{top:30%;height:40%}.zt-image-preview__image .zt-image__error-icon,.zt-image-preview__image-wrap .zt-image__error-icon{font-size:var(--zt-image-preview-error-font-size)}.zt-image-preview__image .zt-image__loading,.zt-image-preview__image-wrap .zt-image__loading{background-color:transparent}.zt-image-preview__index{box-sizing:border-box;display:flex;align-items:center;position:absolute;bottom:0;left:0;width:100%;height:var(--zt-image-preview-index-height);padding:0 16px;background-color:var(--zt-image-preview-index-background);color:var(--zt-image-preview-index-text-color);overflow:hidden}.zt-image-preview__index-number{height:var(--zt-line-height-xl);background:rgba(45,75,115,.8);border-radius:2px;font-size:var(--zt-font-size-sm);text-align:center;line-height:var(--zt-line-height-xl);padding:0 8px}.zt-image-preview__title{flex-shrink:0;margin-left:8px;margin-right:8px;font-size:var(--zt-font-size-md);line-height:var(--zt-line-height-md)}.zt-image-preview__download-icon{display:flex;align-items:center;justify-content:center;margin-left:auto;cursor:pointer;padding:4px}.zt-image-preview__download-icon svg{width:20px;height:20px}.zt-image-preview__overlay{background:var(--zt-image-preview-overlay-background)}.zt-image-preview__close-icon{position:absolute;z-index:var(--zt-image-preview-close-icon-z-index);color:var(--zt-image-preview-close-icon-color);font-size:var(--zt-font-size-xxxl)}.zt-image-preview__close-icon--top-left{top:var(--zt-image-preview-close-icon-margin);left:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--top-right{top:var(--zt-image-preview-close-icon-margin);right:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--bottom-left{bottom:var(--zt-image-preview-close-icon-margin);left:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--bottom-right{right:var(--zt-image-preview-close-icon-margin);bottom:var(--zt-image-preview-close-icon-margin)}
1
+ :root{--zt-image-preview-index-height: 48px;--zt-image-preview-index-background: var(--zt-gray-a4);--zt-image-preview-index-text-color: var(--zt-white);--zt-image-preview-overlay-background: rgba(0, 0, 0, .9);--zt-image-preview-close-icon-color: var(--zt-gray-5);--zt-image-preview-close-icon-margin: var(--zt-padding-md);--zt-image-preview-close-icon-z-index: 1;--zt-image-preview-error-font-size: 36px}:root[zt-theme-size=large]{--zt-image-preview-error-font-size: 42px}.zt-image-preview{position:fixed;top:0;left:0;width:100%;height:100%;max-width:none;background-color:transparent;transform:none}.zt-image-preview__swipe{height:100%}.zt-image-preview__swipe-item{display:flex;align-items:center;justify-content:center;overflow:hidden}.zt-image-preview__cover{position:absolute;top:0;left:0}.zt-image-preview__image,.zt-image-preview__image-wrap{width:100%;transition-property:transform}.zt-image-preview__image--vertical,.zt-image-preview__image-wrap--vertical{width:auto;height:100%}.zt-image-preview__image img,.zt-image-preview__image-wrap img,.zt-image-preview__image video,.zt-image-preview__image-wrap video{-webkit-user-drag:none}.zt-image-preview__image .zt-image__error,.zt-image-preview__image-wrap .zt-image__error{top:30%;height:40%}.zt-image-preview__image .zt-image__error-icon,.zt-image-preview__image-wrap .zt-image__error-icon{font-size:var(--zt-image-preview-error-font-size)}.zt-image-preview__image .zt-image__loading,.zt-image-preview__image-wrap .zt-image__loading{background-color:transparent}.zt-image-preview__index{box-sizing:border-box;display:flex;align-items:center;position:absolute;bottom:0;left:0;width:100%;height:var(--zt-image-preview-index-height);padding:0 16px;background-color:var(--zt-image-preview-index-background);color:var(--zt-image-preview-index-text-color);overflow:hidden}.zt-image-preview__index-number{height:var(--zt-line-height-xl);background:rgba(45,75,115,.8);border-radius:2px;font-size:var(--zt-font-size-sm);text-align:center;line-height:var(--zt-line-height-xl);padding:0 8px}.zt-image-preview__title{flex-shrink:0;margin-left:8px;margin-right:8px;font-size:var(--zt-font-size-md);line-height:var(--zt-line-height-md)}.zt-image-preview__index-content{display:flex;align-items:center;flex:1;min-width:0;height:100%;overflow:hidden}.zt-image-preview__download-icon{display:flex;align-items:center;border:0;background:transparent;color:inherit;flex-shrink:0;margin-left:auto;padding:4px;cursor:pointer}.zt-image-preview__overlay{background:var(--zt-image-preview-overlay-background)}.zt-image-preview__close-icon{position:absolute;z-index:var(--zt-image-preview-close-icon-z-index);color:var(--zt-image-preview-close-icon-color);font-size:var(--zt-font-size-xxxl)}.zt-image-preview__close-icon--top-left{top:var(--zt-image-preview-close-icon-margin);left:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--top-right{top:var(--zt-image-preview-close-icon-margin);right:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--bottom-left{bottom:var(--zt-image-preview-close-icon-margin);left:var(--zt-image-preview-close-icon-margin)}.zt-image-preview__close-icon--bottom-right{right:var(--zt-image-preview-close-icon-margin);bottom:var(--zt-image-preview-close-icon-margin)}
@@ -1,4 +1,3 @@
1
- import type { ImagePreviewProps } from './ImagePreview';
2
1
  export declare const ImagePreview: import("../utils").WithInstall<import("vue").DefineComponent<import("vue").ExtractPropTypes<{
3
2
  show: BooleanConstructor;
4
3
  loop: {
@@ -148,7 +147,7 @@ export declare const ImagePreview: import("../utils").WithInstall<import("vue").
148
147
  export default ImagePreview;
149
148
  export { imagePreviewProps } from './ImagePreview';
150
149
  export { showImagePreview } from './function-call';
151
- export type { ImagePreviewProps };
150
+ export type { ImagePreviewProps, DownloadActionParams, FileDownloadOptions } from './ImagePreview';
152
151
  export type { ImageItem, ImagePreviewOptions, ImagePreviewInstance, ImagePreviewScaleEventParams, ImagePreviewThemeVars, } from './types';
153
152
  declare module 'vue' {
154
153
  interface GlobalComponents {
@@ -6,6 +6,8 @@ require("../../overlay/index.css");
6
6
  require("../../popup/index.css");
7
7
  require("../../loading/index.css");
8
8
  require("../../toast/index.css");
9
+ require("../../button/index.css");
10
+ require("../../dialog/index.css");
9
11
  require("../../swipe/index.css");
10
12
  require("../../swipe-item/index.css");
11
13
  require("../index.css");
@@ -2,10 +2,11 @@ import type { CSSProperties, TeleportProps, ComponentPublicInstance } from 'vue'
2
2
  import type { Interceptor } from '../utils';
3
3
  import type { SwipeToOptions } from '../swipe';
4
4
  import type { PopupCloseIconPosition } from '../popup';
5
- import type { DownloadActionParams, ImagePreviewProps } from './ImagePreview';
5
+ import type { DownloadActionParams, FileDownloadOptions, ImagePreviewProps } from './ImagePreview';
6
6
  export type ImageItem = {
7
7
  url: string;
8
8
  title?: string;
9
+ fileName?: string;
9
10
  };
10
11
  export type ImagePreviewOptions = {
11
12
  loop?: boolean;
@@ -41,6 +42,7 @@ export type ImagePreviewScaleEventParams = {
41
42
  index: number;
42
43
  };
43
44
  export type ImagePreviewExpose = {
45
+ downloadFile: (options: FileDownloadOptions) => Promise<void>;
44
46
  swipeTo: (index: number, options?: SwipeToOptions) => void;
45
47
  };
46
48
  export type ImagePreviewInstance = ComponentPublicInstance<ImagePreviewProps, ImagePreviewExpose>;