qidian-vue-ui 1.3.4 → 1.4.0

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.
@@ -1,4 +1,18 @@
1
- .qd-file-viewer[data-v-b3189b53] {
1
+ .qd-file-viewer[data-v-d9e97271],
2
+ .qd-file-viewer__content[data-v-d9e97271] {
2
3
  width: 100%;
3
4
  height: 100%;
4
5
  }
6
+ .qd-file-viewer--image[data-v-d9e97271] {
7
+ transform: translate3d(0, 0, 0);
8
+ }
9
+ .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer__trigger {
10
+ display: none;
11
+ }
12
+ .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer__modal-box,
13
+ .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer-preview-image {
14
+ animation: none;
15
+ }
16
+ .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer__modal-mask {
17
+ transition: none;
18
+ }
@@ -2,7 +2,7 @@ import './index.css'
2
2
  import _sfc_main from "./index.vue2.mjs";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
5
- const QdFileViewer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b3189b53"]]);
5
+ const QdFileViewer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d9e97271"]]);
6
6
  export {
7
7
  QdFileViewer as default
8
8
  };
@@ -1,7 +1,10 @@
1
1
  import './index.css'
2
- import { defineComponent, computed, createBlock, openBlock, unref } from "vue";
2
+ import { defineComponent, ref, computed, watch, nextTick, createElementBlock, openBlock, normalizeClass, createBlock, unref } from "vue";
3
3
  import { allRenderers } from "@file-viewer/preset-all";
4
4
  import { FileViewer } from "@file-viewer/vue3";
5
+ import { ImageViewer } from "tdesign-vue-next";
6
+ import { isImage } from "../../utils/tools.mjs";
7
+ import { useConfig } from "../config-provider/useConfig.mjs";
5
8
  import { useTheme } from "../../hooks/useTheme.mjs";
6
9
  import QdOfficePdf from "../office/pdf/index.vue.mjs";
7
10
  import merge from "../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/merge.mjs";
@@ -11,11 +14,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
11
14
  props: {
12
15
  src: {},
13
16
  file: {},
14
- options: {}
17
+ options: {},
18
+ attach: {}
15
19
  },
16
20
  setup(__props) {
17
21
  const props = __props;
18
22
  const tdTheme = useTheme();
23
+ const { t } = useConfig("wrapper");
24
+ const rootRef = ref();
25
+ const imageViewerVisible = ref(false);
19
26
  const isPdf = computed(() => {
20
27
  const { file, src } = props;
21
28
  if (file) {
@@ -28,36 +35,85 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
28
35
  }
29
36
  return false;
30
37
  });
38
+ const fileType = computed(() => {
39
+ const { file, src } = props;
40
+ if (file && "type" in file && file.type) return file.type;
41
+ if (file && "name" in file && file.name) return file.name;
42
+ return src || "";
43
+ });
44
+ const isImageFile = computed(() => isImage(fileType.value));
45
+ const imageViewerSource = computed(() => {
46
+ const { file, src } = props;
47
+ if (typeof File !== "undefined" && file instanceof File) return file;
48
+ if (src) return src;
49
+ return void 0;
50
+ });
51
+ const imageViewerImages = computed(
52
+ () => imageViewerSource.value ? [imageViewerSource.value] : []
53
+ );
54
+ const useImageViewer = computed(() => isImageFile.value && !!imageViewerSource.value);
55
+ const resolvedAttach = computed(() => {
56
+ if (rootRef.value) return () => rootRef.value;
57
+ return "body";
58
+ });
59
+ watch(
60
+ useImageViewer,
61
+ (val) => {
62
+ if (!val) {
63
+ imageViewerVisible.value = false;
64
+ return;
65
+ }
66
+ nextTick(() => {
67
+ imageViewerVisible.value = true;
68
+ });
69
+ },
70
+ { immediate: true }
71
+ );
31
72
  return (_ctx, _cache) => {
32
- return isPdf.value ? (openBlock(), createBlock(unref(QdOfficePdf), {
33
- key: 0,
34
- class: "qd-file-viewer",
35
- src: __props.src,
36
- file: __props.file
37
- }, null, 8, ["src", "file"])) : (openBlock(), createBlock(unref(FileViewer), {
38
- key: 1,
39
- class: "qd-file-viewer",
40
- file: __props.file,
41
- url: __props.src,
42
- options: unref(merge)(
43
- {
44
- theme: unref(tdTheme),
45
- toolbar: {
46
- download: false,
47
- exportHtml: false,
48
- print: false
73
+ return openBlock(), createElementBlock("div", {
74
+ ref_key: "rootRef",
75
+ ref: rootRef,
76
+ class: normalizeClass(["qd-file-viewer", useImageViewer.value ? "qd-file-viewer--image" : ""])
77
+ }, [
78
+ useImageViewer.value ? (openBlock(), createBlock(unref(ImageViewer), {
79
+ key: 0,
80
+ visible: imageViewerVisible.value,
81
+ "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => imageViewerVisible.value = $event),
82
+ images: imageViewerImages.value,
83
+ "close-btn": false,
84
+ "close-on-esc-keydown": false,
85
+ "close-on-overlay": false,
86
+ attach: resolvedAttach.value
87
+ }, null, 8, ["visible", "images", "attach"])) : isPdf.value ? (openBlock(), createBlock(unref(QdOfficePdf), {
88
+ key: 1,
89
+ class: "qd-file-viewer__content",
90
+ src: __props.src,
91
+ file: __props.file
92
+ }, null, 8, ["src", "file"])) : (openBlock(), createBlock(unref(FileViewer), {
93
+ key: 2,
94
+ class: "qd-file-viewer__content",
95
+ file: __props.file,
96
+ url: __props.src,
97
+ options: unref(merge)(
98
+ {
99
+ theme: unref(tdTheme),
100
+ toolbar: {
101
+ download: false,
102
+ exportHtml: false,
103
+ print: false
104
+ },
105
+ pdf: {
106
+ defaultNavigationVisible: false
107
+ }
49
108
  },
50
- pdf: {
51
- defaultNavigationVisible: false
109
+ __props.options,
110
+ {
111
+ builtinRenderers: "none",
112
+ renderers: unref(allRenderers)
52
113
  }
53
- },
54
- __props.options,
55
- {
56
- builtinRenderers: "none",
57
- renderers: unref(allRenderers)
58
- }
59
- )
60
- }, null, 8, ["file", "url", "options"]));
114
+ )
115
+ }, null, 8, ["file", "url", "options"]))
116
+ ], 2);
61
117
  };
62
118
  }
63
119
  });
@@ -1,7 +1,9 @@
1
1
  import type { FileRef, FileViewerOptions } from '@file-viewer/vue3';
2
+ import type { QdDialogProps } from '../dialog';
2
3
  export type QdFileViewerFile = FileRef;
3
4
  export interface QdFileViewerProps {
4
5
  src?: string;
5
6
  file?: QdFileViewerFile;
6
7
  options?: Omit<FileViewerOptions, 'builtinRenderers' | 'renderers'>;
8
+ attach?: QdDialogProps['attach'];
7
9
  }
@@ -6,6 +6,7 @@ declare const _default: import("vue").DefineComponent<QdMultiFileViewerProps, {
6
6
  show: typeof show;
7
7
  hide: typeof hide;
8
8
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<QdMultiFileViewerProps> & Readonly<{}>, {
9
- wrapper: QdDialogProps | false;
9
+ wrapper: Omit<QdDialogProps, "attach" | "destroyOnClose"> | false;
10
+ fileViewerOnly: boolean;
10
11
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
12
  export default _default;
@@ -1,11 +1,11 @@
1
1
  import './index.css'
2
2
  import { defineComponent, mergeDefaults, ref, computed, watch, createBlock, openBlock, resolveDynamicComponent, mergeProps, withCtx, createElementBlock, Fragment, createVNode, createElementVNode, unref, renderList, createTextVNode, toDisplayString, createCommentVNode, nextTick } from "vue";
3
3
  import { Menu, MenuItem, Empty, ImageViewer } from "tdesign-vue-next";
4
+ import { isImage } from "../../utils/tools.mjs";
4
5
  import { useConfig } from "../config-provider/useConfig.mjs";
5
6
  import _sfc_main$1 from "../dialog/index.vue.mjs";
6
7
  /* empty css */
7
8
  import QdFileViewer from "../file-viewer/index.vue.mjs";
8
- import { IMAGE_REGEXP } from "../upload/common.mjs";
9
9
  import { qdMultiFileViewerWrapperProps, qdMultiFileViewerProps } from "./props.mjs";
10
10
  import merge from "../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/merge.mjs";
11
11
  const _hoisted_1 = {
@@ -20,6 +20,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
20
20
  index: {},
21
21
  options: {},
22
22
  files: {},
23
+ attach: {},
24
+ fileViewerOnly: { type: Boolean },
23
25
  wrapper: { type: [Object, Boolean] }
24
26
  }, qdMultiFileViewerProps),
25
27
  setup(__props, { expose: __expose }) {
@@ -55,22 +57,25 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
55
57
  });
56
58
  const allFilesAreImages = computed(() => {
57
59
  const files = mergedProps.value.files;
58
- return !!files?.length && files.every((item) => isImage(item) && !!resolveImageViewerSource(item));
60
+ return !!files?.length && files.every((item) => isImage(resolveFileType(item)) && !!resolveImageViewerSource(item));
59
61
  });
62
+ const fileViewerOnly = computed(
63
+ () => mergedProps.value.wrapper === false || mergedProps.value.fileViewerOnly === true
64
+ );
65
+ const useImageViewer = computed(() => allFilesAreImages.value && !fileViewerOnly.value);
60
66
  const imageViewerImages = computed(
61
67
  () => (mergedProps.value.files ?? []).map((item) => resolveImageViewerSource(item) ?? "")
62
68
  );
63
- const imageViewerAttach = computed(() => {
64
- const wrapper = mergedProps.value.wrapper === false ? void 0 : mergedProps.value.wrapper;
65
- return wrapper?.attach ?? wrapperT("attach") ?? "body";
66
- });
67
- const isDialog = computed(() => mergedProps.value.wrapper !== false && !allFilesAreImages.value);
69
+ const resolvedAttach = computed(() => mergedProps.value.attach ?? wrapperT("attach") ?? "body");
70
+ const isDialog = computed(() => mergedProps.value.wrapper !== false && !useImageViewer.value);
68
71
  const dialogProps = computed(() => {
69
72
  const wrapper = mergedProps.value.wrapper === false ? void 0 : mergedProps.value.wrapper;
70
73
  return {
71
74
  ...qdMultiFileViewerWrapperProps,
72
75
  ...wrapper,
73
76
  header: wrapper?.header ?? activeFileName.value,
77
+ attach: resolvedAttach.value,
78
+ destroyOnClose: true,
74
79
  cancelBtn: wrapper?.cancelBtn === void 0 ? t("closeText") : typeof wrapper.cancelBtn === "object" && wrapper.cancelBtn !== null ? { ...wrapper.cancelBtn, content: t("closeText") } : wrapper.cancelBtn
75
80
  };
76
81
  });
@@ -82,9 +87,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
82
87
  if (file && "name" in file && file.name) return file.name;
83
88
  return item.src || item.name || "";
84
89
  }
85
- function isImage(item) {
86
- return IMAGE_REGEXP.test(resolveFileType(item));
87
- }
88
90
  function resolveImageViewerSource(item) {
89
91
  if (typeof File !== "undefined" && item.file instanceof File) return item.file;
90
92
  if (item.src) return item.src;
@@ -117,9 +119,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
117
119
  function show(override) {
118
120
  runtimeOverrides.value = override ?? {};
119
121
  activeIndex.value = normalizeIndex(mergedProps.value.index, mergedProps.value.files);
120
- if (allFilesAreImages.value) {
122
+ if (useImageViewer.value) {
121
123
  imageViewerIndex.value = activeIndex.value;
122
- imageViewerVisible.value = true;
124
+ imageViewerVisible.value = false;
125
+ nextTick(() => {
126
+ imageViewerVisible.value = true;
127
+ });
123
128
  return;
124
129
  }
125
130
  if (!isDialog.value) return;
@@ -139,12 +144,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
139
144
  __expose({ show, hide });
140
145
  return (_ctx, _cache) => {
141
146
  return openBlock(), createBlock(resolveDynamicComponent(wrapperTag.value), mergeProps(wrapperBindings.value, {
142
- class: ["qd-multi-file-viewer", allFilesAreImages.value ? "qd-multi-file-viewer--image" : ""],
147
+ class: ["qd-multi-file-viewer", useImageViewer.value ? "qd-multi-file-viewer--image" : ""],
143
148
  ref_key: "dialogRef",
144
149
  ref: dialogRef
145
150
  }), {
146
151
  default: withCtx(() => [
147
- !allFilesAreImages.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
152
+ !useImageViewer.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
148
153
  mergedProps.value.files?.length ? (openBlock(), createElementBlock("div", _hoisted_1, [
149
154
  createVNode(unref(Menu), {
150
155
  value: activeIndex.value,
@@ -180,7 +185,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
180
185
  index: imageViewerIndex.value,
181
186
  "onUpdate:index": _cache[1] || (_cache[1] = ($event) => imageViewerIndex.value = $event),
182
187
  images: imageViewerImages.value,
183
- attach: imageViewerAttach.value
188
+ attach: resolvedAttach.value
184
189
  }, null, 8, ["visible", "index", "images", "attach"]))
185
190
  ]),
186
191
  _: 1
@@ -11,4 +11,5 @@ export declare const qdMultiFileViewerProps: {
11
11
  readonly confirmBtn: null;
12
12
  readonly footer: false;
13
13
  };
14
+ readonly fileViewerOnly: false;
14
15
  };
@@ -5,7 +5,8 @@ const qdMultiFileViewerWrapperProps = {
5
5
  footer: false
6
6
  };
7
7
  const qdMultiFileViewerProps = {
8
- wrapper: () => qdMultiFileViewerWrapperProps
8
+ wrapper: () => qdMultiFileViewerWrapperProps,
9
+ fileViewerOnly: false
9
10
  };
10
11
  export {
11
12
  qdMultiFileViewerProps,
@@ -10,7 +10,9 @@ export interface QdMultiFileViewerProps {
10
10
  index?: number;
11
11
  options?: QdFileViewerProps['options'];
12
12
  files?: QdMultiFileViewerItem[];
13
- wrapper?: QdDialogProps | false;
13
+ attach?: QdDialogProps['attach'];
14
+ fileViewerOnly?: boolean;
15
+ wrapper?: Omit<QdDialogProps, 'attach' | 'destroyOnClose'> | false;
14
16
  }
15
17
  export interface QdMultiFileViewerInstanceFunctions {
16
18
  show: (props?: Partial<QdMultiFileViewerProps>) => void;
@@ -1,10 +1,11 @@
1
+ import { isImage } from "../../../../utils/tools.mjs";
1
2
  function isImageUrl(url) {
2
- return /\.(jpg|jpeg|png|gif|webp|bmp)(\?.*)?$/i.test(url);
3
+ return isImage(url);
3
4
  }
4
5
  function isImageFile(file) {
5
6
  if (file.type.startsWith("image/")) return true;
6
7
  if (!(file instanceof File)) return false;
7
- return /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(file.name);
8
+ return isImage(file.name);
8
9
  }
9
10
  function loadImage(src) {
10
11
  return new Promise((resolve, reject) => {
@@ -1,25 +1,25 @@
1
- .qd-service-table[data-v-77723bee] {
1
+ .qd-service-table[data-v-5806889d] {
2
2
  height: 100%;
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  }
6
- .qd-service-table[data-v-77723bee] > .t-table__content {
6
+ .qd-service-table[data-v-5806889d] > .t-table__content {
7
7
  flex: 1;
8
8
  }
9
- .qd-service-table[data-v-77723bee] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
9
+ .qd-service-table[data-v-5806889d] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
10
10
  margin-left: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
11
11
  }
12
- .qd-service-table[data-v-77723bee] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
12
+ .qd-service-table[data-v-5806889d] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
13
13
  width: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
14
14
  }
15
- .qd-service-table[data-v-77723bee] .t-affix {
16
- transform: var(--v2846a290);
15
+ .qd-service-table[data-v-5806889d] .t-affix {
16
+ transform: var(--v5ea6151a);
17
17
  }
18
- .qd-service-table--ps-x-fixed[data-v-77723bee] .ps__rail-x {
18
+ .qd-service-table--ps-x-fixed[data-v-5806889d] .ps__rail-x {
19
19
  position: fixed;
20
- left: var(--v4a362512) !important;
21
- bottom: var(--v224f22e0) !important;
20
+ left: var(--v60ce71c8) !important;
21
+ bottom: var(--v6db618c6) !important;
22
22
  }
23
- .qd-service-table--disable-horizontal-scroll[data-v-77723bee] colgroup > col {
23
+ .qd-service-table--disable-horizontal-scroll[data-v-5806889d] colgroup > col {
24
24
  width: auto !important;
25
25
  }
@@ -2,7 +2,7 @@ import './index.css'
2
2
  import _sfc_main from "./index.vue2.mjs";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.mjs";
5
- const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-77723bee"]]);
5
+ const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5806889d"]]);
6
6
  export {
7
7
  QdServiceTable as default
8
8
  };
@@ -307,9 +307,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
307
307
  emit: __emit
308
308
  }) {
309
309
  useCssVars((_ctx) => ({
310
- "v2846a290": affixedHeaderTransform.value,
311
- "v4a362512": tableContentLeft.value,
312
- "v224f22e0": outsideBottom.value
310
+ "v5ea6151a": affixedHeaderTransform.value,
311
+ "v60ce71c8": tableContentLeft.value,
312
+ "v6db618c6": outsideBottom.value
313
313
  }));
314
314
  const props = __props;
315
315
  const emit = __emit;
@@ -355,7 +355,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
355
355
  const tableContentVisible = ref(false);
356
356
  const isScrollSyncing = ref(false);
357
357
  const tableContentRect = reactive(useElementBounding(tableContentEl));
358
- const tableContentLeft = computed(() => `${tableContentRect.left}px`);
358
+ const tableContentLeft = computed(() => `${tableContentRect.left - affixedRailOffsetX.value}px`);
359
359
  const outsideScrollRect = reactive(useElementBounding(outsideScrollEl));
360
360
  const outsideBottom = computed(() => outsideScrollEl.value ? `${window.innerHeight - outsideScrollRect.bottom}px` : "0");
361
361
  const tableHeaderHalfVisible = computed(() => {
@@ -403,6 +403,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
403
403
  stop: outsideTableContentStop
404
404
  } = useMouseInElement(tableContentEl);
405
405
  const affixedHeaderTransform = ref("none");
406
+ const affixedRailOffsetX = ref(0);
406
407
  const affixBaseEl = computed(() => outsideScrollEl.value || tableRef.value?.$el);
407
408
  const reProps = computed(() => {
408
409
  const {
@@ -830,6 +831,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
830
831
  const el = entries[0].target;
831
832
  outsideScrollEl.value = getScrollEl(el);
832
833
  outsideScrollRect.update();
834
+ affixedRailOffsetX.value = getTransformOffset(affixBaseEl.value).x;
833
835
  const headerEl = el.querySelector(".t-table__header");
834
836
  tableHeaderEl.value = headerEl;
835
837
  let headerH = 0;
@@ -1,5 +1,5 @@
1
+ import type { UploadFile } from 'tdesign-vue-next';
1
2
  import type { Slot } from 'vue';
2
3
  export declare function handleAbridgeName(inputName: string, leftCount?: number, rightCount?: number): string;
3
- export declare const IMAGE_REGEXP: RegExp;
4
- export declare function returnFileSize(number: number | undefined): string;
4
+ export declare function getFileType(file: UploadFile): string;
5
5
  export declare function hasSlotContent(slot?: Slot): boolean;
@@ -15,14 +15,8 @@ function handleAbridgeName(inputName, leftCount = 5, rightCount = 7) {
15
15
  }
16
16
  return name.replace(new RegExp(`^(.{${leftLength}})(.+)(.{${rightLength}})$`), "$1…$3");
17
17
  }
18
- const IMAGE_REGEXP = /(.png|.jpg|.jpeg|.jpe|.webp|.avif|.heic|.heif|.svg|.gif|.bmp)/i;
19
- function returnFileSize(number) {
20
- if (!number && number !== 0) return "";
21
- const SIZE_MAP = { KB: 1024, MB: 1048576, GB: 1073741824 };
22
- if (number < SIZE_MAP.KB) return `${number} Bytes`;
23
- if (number < SIZE_MAP.MB) return `${(number / SIZE_MAP.KB).toFixed(1)} KB`;
24
- if (number < SIZE_MAP.GB) return `${(number / SIZE_MAP.MB).toFixed(1)} MB`;
25
- return `${(number / SIZE_MAP.GB).toFixed(1)} GB`;
18
+ function getFileType(file) {
19
+ return file.raw?.type || file.type || file.name || "";
26
20
  }
27
21
  function hasSlotContent(slot) {
28
22
  if (!slot) return false;
@@ -40,8 +34,7 @@ function isValidSlotChild(children) {
40
34
  return true;
41
35
  }
42
36
  export {
43
- IMAGE_REGEXP,
37
+ getFileType,
44
38
  handleAbridgeName,
45
- hasSlotContent,
46
- returnFileSize
39
+ hasSlotContent
47
40
  };
@@ -1,7 +1,9 @@
1
1
  import { defineComponent, computed, createElementBlock, openBlock, mergeProps, createElementVNode, createCommentVNode, toDisplayString, Fragment, renderList, createBlock, unref, resolveDynamicComponent, normalizeClass, createVNode } from "vue";
2
+ import { formatByte } from "qidian-shared";
2
3
  import { TimeFilledIcon, ErrorCircleFilledIcon, CheckCircleFilledIcon, FileIcon } from "tdesign-icons-vue-next";
3
4
  import { Image, Button, Loading } from "tdesign-vue-next";
4
- import { handleAbridgeName, returnFileSize, IMAGE_REGEXP } from "../common.mjs";
5
+ import { isImage } from "../../../utils/tools.mjs";
6
+ import { getFileType, handleAbridgeName } from "../common.mjs";
5
7
  import QdFileIcon from "../../file-icon/index.vue.mjs";
6
8
  const _hoisted_1 = { style: { "min-width": "120px" } };
7
9
  const _hoisted_2 = { style: { "min-width": "120px" } };
@@ -37,15 +39,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
37
39
  const allSuccess = computed(
38
40
  () => props.files.every((file) => file.status === "success" || !file.status)
39
41
  );
40
- function getFileType(file) {
41
- return file.raw?.type || file.type || file.name || "";
42
- }
43
42
  function hasThumbnail(file) {
44
43
  return !(!file.raw && !file.type && file.url);
45
44
  }
46
- function isImage(file) {
47
- return IMAGE_REGEXP.test(getFileType(file));
48
- }
49
45
  function getStatusIcon(status) {
50
46
  const iconMap = {
51
47
  success: CheckCircleFilledIcon,
@@ -97,7 +93,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
97
93
  createElementVNode("td", _hoisted_6, [
98
94
  createElementVNode("span", _hoisted_7, [
99
95
  __props.showThumbnail && hasThumbnail(file) ? (openBlock(), createElementBlock("span", _hoisted_8, [
100
- isImage(file) ? (openBlock(), createBlock(unref(Image), {
96
+ unref(isImage)(unref(getFileType)(file)) ? (openBlock(), createBlock(unref(Image), {
101
97
  key: 0,
102
98
  class: "t-upload__file-thumbnail",
103
99
  src: file.url || file.raw,
@@ -118,7 +114,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
118
114
  }, toDisplayString(__props.abridgeName?.length && file.name ? unref(handleAbridgeName)(file.name, ...__props.abridgeName) : file.name), 9, _hoisted_9)
119
115
  ])
120
116
  ]),
121
- createElementVNode("td", null, toDisplayString(unref(returnFileSize)(file.size)), 1),
117
+ createElementVNode("td", null, toDisplayString(unref(formatByte)(file.size)), 1),
122
118
  createElementVNode("td", null, [
123
119
  createElementVNode("div", _hoisted_10, [
124
120
  (openBlock(), createBlock(resolveDynamicComponent(getStatusIcon(file.status)))),
@@ -1,7 +1,8 @@
1
1
  import { defineComponent, useSlots, computed, createElementBlock, openBlock, createCommentVNode, Fragment, renderList, createBlock, createVNode, createElementVNode, unref, toDisplayString, renderSlot, withCtx, withModifiers, createTextVNode, normalizeClass } from "vue";
2
2
  import { ErrorCircleFilledIcon, DeleteIcon, BrowseIcon, AddIcon } from "tdesign-icons-vue-next";
3
3
  import { Loading, Image, Space, Divider, Link } from "tdesign-vue-next";
4
- import { IMAGE_REGEXP, handleAbridgeName, hasSlotContent } from "../common.mjs";
4
+ import { isImage } from "../../../utils/tools.mjs";
5
+ import { getFileType, handleAbridgeName, hasSlotContent } from "../common.mjs";
5
6
  import QdFileIcon from "../../file-icon/index.vue.mjs";
6
7
  const _hoisted_1 = { class: "t-upload__card" };
7
8
  const _hoisted_2 = {
@@ -49,12 +50,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
49
50
  const showTrigger = computed(
50
51
  () => props.trigger && !props.disabled && (!props.max || props.files.length < props.max)
51
52
  );
52
- function getFileType(file) {
53
- return file.raw?.type || file.type || file.name || "";
54
- }
55
- function isImage(file) {
56
- return IMAGE_REGEXP.test(getFileType(file));
57
- }
58
53
  function fileName(file) {
59
54
  if (!props.abridgeName || !file.name) return file.name ?? "";
60
55
  return handleAbridgeName(file.name, ...props.abridgeName);
@@ -93,7 +88,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
93
88
  ])
94
89
  ])
95
90
  ])) : (openBlock(), createElementBlock("div", _hoisted_6, [
96
- isImage(file) ? (openBlock(), createBlock(unref(Image), {
91
+ unref(isImage)(unref(getFileType)(file)) ? (openBlock(), createBlock(unref(Image), {
97
92
  key: 0,
98
93
  class: "t-upload__card-image",
99
94
  src: file.url || file.raw,
@@ -1,7 +1,8 @@
1
1
  import { defineComponent, useSlots, createElementBlock, openBlock, Fragment, renderList, createElementVNode, createCommentVNode, normalizeClass, createBlock, createVNode, unref, toDisplayString, renderSlot, withCtx, withModifiers, createTextVNode } from "vue";
2
2
  import { ErrorCircleFilledIcon, BrowseIcon, DeleteIcon, CheckCircleFilledIcon, TimeFilledIcon } from "tdesign-icons-vue-next";
3
3
  import { Loading, Image, Space, Divider } from "tdesign-vue-next";
4
- import { handleAbridgeName, IMAGE_REGEXP, hasSlotContent } from "../common.mjs";
4
+ import { isImage } from "../../../utils/tools.mjs";
5
+ import { getFileType, handleAbridgeName, hasSlotContent } from "../common.mjs";
5
6
  import QdFileIcon from "../../file-icon/index.vue.mjs";
6
7
  const _hoisted_1 = { class: "t-upload__card clearfix" };
7
8
  const _hoisted_2 = {
@@ -35,17 +36,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
35
36
  setup(__props) {
36
37
  const props = __props;
37
38
  const slots = useSlots();
38
- function getFileType(file) {
39
- return file.raw?.type || file.type || file.name || "";
40
- }
41
- function isImage(file) {
42
- return IMAGE_REGEXP.test(getFileType(file));
43
- }
44
39
  function handlePreview({ e }, index, file) {
45
40
  props.onPreview?.({ file, index, e });
46
41
  }
47
42
  function canMaskPreview(file) {
48
- return props.disabled && (Boolean(file.url) || Boolean(file.raw)) && file.status !== "progress" && file.status !== "fail" && !hasSlotContent(slots["file-middle-actions"]) && !hasSlotContent(slots["file-actions"]);
43
+ return props.disabled && file.status !== "progress" && file.status !== "fail" && !hasSlotContent(slots["file-middle-actions"]) && !hasSlotContent(slots["file-actions"]);
49
44
  }
50
45
  function handleMaskPreview(e, index, file) {
51
46
  if (!canMaskPreview(file)) return;
@@ -67,7 +62,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
67
62
  ])) : file.status === "fail" ? (openBlock(), createElementBlock("div", _hoisted_3, [
68
63
  createVNode(unref(ErrorCircleFilledIcon)),
69
64
  createElementVNode("p", null, toDisplayString(__props.locale.progress.failText), 1)
70
- ])) : (["waiting", "success"].includes(file.status) || !file.status && file.url) && isImage(file) ? (openBlock(), createBlock(unref(Image), {
65
+ ])) : (["waiting", "success"].includes(file.status) || !file.status && file.url) && unref(isImage)(unref(getFileType)(file)) ? (openBlock(), createBlock(unref(Image), {
71
66
  key: 2,
72
67
  class: "t-upload__card-image",
73
68
  src: file.url || file.raw,
@@ -34,3 +34,5 @@ export declare function getTransformOffset(el?: HTMLElement | null, options?: {
34
34
  x: number;
35
35
  y: number;
36
36
  };
37
+ export declare const IMAGE_REGEXP: RegExp;
38
+ export declare function isImage(value: string): boolean;
@@ -19,8 +19,14 @@ function getTransformOffset(el, options) {
19
19
  }
20
20
  return { x: 0, y: 0 };
21
21
  }
22
+ const IMAGE_REGEXP = /(.png|.jpg|.jpeg|.jpe|.webp|.avif|.heic|.heif|.svg|.gif|.bmp)/i;
23
+ function isImage(value) {
24
+ return IMAGE_REGEXP.test(value);
25
+ }
22
26
  export {
27
+ IMAGE_REGEXP,
23
28
  getPublicUrl,
24
29
  getTransformOffset,
30
+ isImage,
25
31
  useUICsl
26
32
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidian-vue-ui",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "基于 TDesign 的 QiDian Vue UI 组件库",
5
5
  "author": "qidian",
6
6
  "license": "MIT",
@@ -130,7 +130,7 @@
130
130
  "vue-codemirror": "^6.1.1",
131
131
  "vue-echarts": "^8.0.1",
132
132
  "vue-stream-markdown": "1.0.1-beta.1",
133
- "qidian-shared": "1.0.76"
133
+ "qidian-shared": "1.0.77"
134
134
  },
135
135
  "scripts": {
136
136
  "clean": "rm -rf dist",