qidian-vue-ui 1.5.2 → 1.7.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,18 +1,18 @@
1
- .qd-file-viewer[data-v-d9e97271],
2
- .qd-file-viewer__content[data-v-d9e97271] {
1
+ .qd-file-viewer[data-v-a1dee402],
2
+ .qd-file-viewer__content[data-v-a1dee402] {
3
3
  width: 100%;
4
4
  height: 100%;
5
5
  }
6
- .qd-file-viewer--image[data-v-d9e97271] {
6
+ .qd-file-viewer--image[data-v-a1dee402] {
7
7
  transform: translate3d(0, 0, 0);
8
8
  }
9
- .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer__trigger {
9
+ .qd-file-viewer--image[data-v-a1dee402] .t-image-viewer__trigger {
10
10
  display: none;
11
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 {
12
+ .qd-file-viewer--image[data-v-a1dee402] .t-image-viewer__modal-box,
13
+ .qd-file-viewer--image[data-v-a1dee402] .t-image-viewer-preview-image {
14
14
  animation: none;
15
15
  }
16
- .qd-file-viewer--image[data-v-d9e97271] .t-image-viewer__modal-mask {
16
+ .qd-file-viewer--image[data-v-a1dee402] .t-image-viewer__modal-mask {
17
17
  transition: none;
18
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-d9e97271"]]);
5
+ const QdFileViewer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a1dee402"]]);
6
6
  export {
7
7
  QdFileViewer as default
8
8
  };
@@ -4,7 +4,6 @@ import { allRenderers } from "@file-viewer/preset-all";
4
4
  import { FileViewer } from "@file-viewer/vue3";
5
5
  import { ImageViewer } from "tdesign-vue-next";
6
6
  import { isImage } from "../../utils/tools.mjs";
7
- import { useConfig } from "../config-provider/useConfig.mjs";
8
7
  import { useTheme } from "../../hooks/useTheme.mjs";
9
8
  import QdOfficePdf from "../office/pdf/index.vue.mjs";
10
9
  import merge from "../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/merge.mjs";
@@ -20,9 +19,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
20
19
  setup(__props) {
21
20
  const props = __props;
22
21
  const tdTheme = useTheme();
23
- const { t } = useConfig("wrapper");
22
+ const SVG_PLACEHOLDER_PNG = (() => {
23
+ if (typeof document === "undefined") return "";
24
+ const canvas = document.createElement("canvas");
25
+ canvas.width = 800;
26
+ canvas.height = 600;
27
+ return canvas.toDataURL("image/png");
28
+ })();
24
29
  const rootRef = ref();
25
30
  const imageViewerVisible = ref(false);
31
+ const svgReady = ref(false);
26
32
  const isPdf = computed(() => {
27
33
  const { file, src } = props;
28
34
  if (file) {
@@ -35,6 +41,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
35
41
  }
36
42
  return false;
37
43
  });
44
+ const isSvg = computed(() => {
45
+ const { file, src } = props;
46
+ if (file) {
47
+ if ("type" in file && file.type === "image/svg+xml") return true;
48
+ if ("name" in file && file.name.endsWith(".svg")) return true;
49
+ }
50
+ if (src) {
51
+ const pathname = new URL(src, "https://x").pathname;
52
+ if (pathname.endsWith(".svg")) return true;
53
+ }
54
+ return false;
55
+ });
38
56
  const fileType = computed(() => {
39
57
  const { file, src } = props;
40
58
  if (file && "type" in file && file.type) return file.type;
@@ -48,23 +66,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
48
66
  if (src) return src;
49
67
  return void 0;
50
68
  });
51
- const imageViewerImages = computed(
52
- () => imageViewerSource.value ? [imageViewerSource.value] : []
53
- );
69
+ const imageViewerImages = computed(() => {
70
+ const source = imageViewerSource.value;
71
+ if (!source) return [];
72
+ if (isSvg.value) {
73
+ return svgReady.value ? [{ mainImage: source, thumbnail: source, isSvg: true }] : [SVG_PLACEHOLDER_PNG];
74
+ }
75
+ return [source];
76
+ });
54
77
  const useImageViewer = computed(() => isImageFile.value && !!imageViewerSource.value);
55
78
  const resolvedAttach = computed(() => {
56
79
  if (rootRef.value) return () => rootRef.value;
57
80
  return "body";
58
81
  });
59
82
  watch(
60
- useImageViewer,
61
- (val) => {
62
- if (!val) {
83
+ [useImageViewer, imageViewerSource],
84
+ () => {
85
+ if (!useImageViewer.value) {
63
86
  imageViewerVisible.value = false;
87
+ svgReady.value = false;
64
88
  return;
65
89
  }
90
+ svgReady.value = false;
66
91
  nextTick(() => {
67
92
  imageViewerVisible.value = true;
93
+ nextTick(() => {
94
+ svgReady.value = true;
95
+ });
68
96
  });
69
97
  },
70
98
  { immediate: true }
@@ -20,4 +20,5 @@ export * from './service';
20
20
  export * from './service-dialog-table-select';
21
21
  export * from './service-popup-table-select';
22
22
  export * from './service-select';
23
+ export * from './steps';
23
24
  export * from './upload';
@@ -32,6 +32,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
32
32
  const imageViewerIndex = ref(0);
33
33
  const { t } = useConfig("multiFileViewer");
34
34
  const { t: wrapperT } = useConfig("wrapper");
35
+ const SVG_PLACEHOLDER_PNG = (() => {
36
+ if (typeof document === "undefined") return "";
37
+ const canvas = document.createElement("canvas");
38
+ canvas.width = 800;
39
+ canvas.height = 600;
40
+ return canvas.toDataURL("image/png");
41
+ })();
42
+ const svgReady = ref(false);
35
43
  const mergedProps = computed(() => ({
36
44
  ...props,
37
45
  ...runtimeOverrides.value
@@ -64,7 +72,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
64
72
  );
65
73
  const useImageViewer = computed(() => allFilesAreImages.value && !fileViewerOnly.value);
66
74
  const imageViewerImages = computed(
67
- () => (mergedProps.value.files ?? []).map((item) => resolveImageViewerSource(item) ?? "")
75
+ () => (mergedProps.value.files ?? []).map((item) => {
76
+ const source = resolveImageViewerSource(item);
77
+ if (isSvgItem(item) && source) {
78
+ return svgReady.value ? { mainImage: source, thumbnail: source, isSvg: true } : SVG_PLACEHOLDER_PNG;
79
+ }
80
+ return source ?? "";
81
+ })
68
82
  );
69
83
  const resolvedAttach = computed(() => mergedProps.value.attach ?? wrapperT("attach") ?? "body");
70
84
  const isDialog = computed(() => mergedProps.value.wrapper !== false && !useImageViewer.value);
@@ -92,6 +106,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
92
106
  if (item.src) return item.src;
93
107
  return void 0;
94
108
  }
109
+ function isSvgItem(item) {
110
+ const file = item.file;
111
+ if (file) {
112
+ if ("type" in file && file.type === "image/svg+xml") return true;
113
+ if ("name" in file && file.name.endsWith(".svg")) return true;
114
+ }
115
+ if (item.src) {
116
+ const pathname = new URL(item.src, "https://x").pathname;
117
+ if (pathname.endsWith(".svg")) return true;
118
+ }
119
+ return false;
120
+ }
95
121
  function normalizeIndex(index, files) {
96
122
  if (!files?.length) return 0;
97
123
  if (index === void 0 || index < 0 || index >= files.length) return 0;
@@ -121,9 +147,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
121
147
  activeIndex.value = normalizeIndex(mergedProps.value.index, mergedProps.value.files);
122
148
  if (useImageViewer.value) {
123
149
  imageViewerIndex.value = activeIndex.value;
150
+ svgReady.value = false;
124
151
  imageViewerVisible.value = false;
125
152
  nextTick(() => {
126
153
  imageViewerVisible.value = true;
154
+ nextTick(() => {
155
+ svgReady.value = true;
156
+ });
127
157
  });
128
158
  return;
129
159
  }
@@ -131,6 +161,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
131
161
  nextTick(() => dialogRef.value?.show());
132
162
  }
133
163
  function hide() {
164
+ svgReady.value = false;
134
165
  if (imageViewerVisible.value) imageViewerVisible.value = false;
135
166
  if (!isDialog.value) return;
136
167
  dialogRef.value?.hide();
@@ -1,6 +1,6 @@
1
1
  export declare const qdOrgSelectProps: {
2
2
  readonly showFullDeptPath: true;
3
- readonly manual: true;
3
+ readonly manual: undefined;
4
4
  readonly showArrow: true;
5
5
  readonly popupVisible: undefined;
6
6
  readonly disabled: undefined;
@@ -1,4 +1,4 @@
1
- .qd-service-select__load[data-v-340599bc] {
1
+ .qd-service-select__load[data-v-90dbce79] {
2
2
  width: 100%;
3
3
  border-top: 1px solid var(--td-component-stroke);
4
4
  padding: 6px;
@@ -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 QdServiceSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-340599bc"]]);
5
+ const QdServiceSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-90dbce79"]]);
6
6
  export {
7
7
  QdServiceSelect as default
8
8
  };
@@ -1,5 +1,5 @@
1
1
  import './index.css'
2
- import { defineComponent, mergeDefaults, computed, ref, watch, onMounted, onActivated, onDeactivated, createBlock, openBlock, unref, mergeProps, isRef, createSlots, withCtx, renderSlot, createCommentVNode, renderList, normalizeProps, guardReactiveProps } from "vue";
2
+ import { defineComponent, mergeDefaults, computed, ref, unref, watch, onMounted, onActivated, onDeactivated, createBlock, openBlock, mergeProps, isRef, createSlots, withCtx, renderSlot, createCommentVNode, renderList, normalizeProps, guardReactiveProps } from "vue";
3
3
  import { useVModels } from "../../node_modules/.pnpm/@vueuse_core@14.2.0_vue@3.5.26_typescript@5.9.3_/node_modules/@vueuse/core/dist/index.mjs";
4
4
  import { isEmpty, useServiceLoadMore, toArr, extractSlotsWithoutPrefix, checkSameObject } from "qidian-shared";
5
5
  import { Select, Loading } from "tdesign-vue-next";
@@ -181,6 +181,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
181
181
  onChange,
182
182
  ...selectOptions
183
183
  } = props;
184
+ const mergedManual = manual ?? unref(pagination) !== false;
184
185
  const rePopupProps = popupProps || {};
185
186
  rePopupProps.onScrollToBottom = (context) => {
186
187
  popupProps?.onScrollToBottom?.(context);
@@ -250,7 +251,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
250
251
  },
251
252
  serviceOptions: {
252
253
  service,
253
- manual,
254
+ manual: mergedManual,
254
255
  transformParams: mergedTransformParams,
255
256
  transformRes,
256
257
  pagination,
@@ -1,5 +1,5 @@
1
1
  export declare const qdServiceSelectProps: {
2
- readonly manual: true;
2
+ readonly manual: undefined;
3
3
  readonly showArrow: true;
4
4
  readonly popupVisible: undefined;
5
5
  readonly disabled: undefined;
@@ -1,5 +1,5 @@
1
1
  const qdServiceSelectProps = {
2
- manual: true,
2
+ manual: void 0,
3
3
  showArrow: true,
4
4
  popupVisible: void 0,
5
5
  disabled: void 0,
@@ -0,0 +1,211 @@
1
+ .qd-steps[data-v-3fae5c44] {
2
+ display: grid;
3
+ gap: var(--td-comp-paddingTB-xs);
4
+ }
5
+ .qd-steps__nav[data-v-3fae5c44] {
6
+ display: flex;
7
+ align-items: center;
8
+ width: 100%;
9
+ }
10
+ .qd-steps__phases[data-v-3fae5c44] {
11
+ display: flex;
12
+ align-items: center;
13
+ flex-wrap: wrap;
14
+ }
15
+ .qd-steps__phase[data-v-3fae5c44] {
16
+ display: inline-flex;
17
+ align-items: center;
18
+ gap: var(--td-size-3);
19
+ padding: var(--td-size-1) var(--td-comp-paddingLR-s) var(--td-size-1) var(--td-comp-paddingLR-xs);
20
+ border-radius: var(--td-radius-round);
21
+ transition: all 0.15s;
22
+ }
23
+ .qd-steps__phase--clickable[data-v-3fae5c44] {
24
+ cursor: pointer;
25
+ }
26
+ .qd-steps__phase--done[data-v-3fae5c44] {
27
+ color: var(--td-text-color-secondary);
28
+ }
29
+ .qd-steps__phase--done .qd-steps__phase-icon[data-v-3fae5c44] {
30
+ background-color: var(--td-success-color);
31
+ color: var(--td-text-color-anti);
32
+ border-color: transparent;
33
+ }
34
+ .qd-steps__phase--done .qd-steps__phase-name[data-v-3fae5c44] {
35
+ color: var(--td-text-color-secondary);
36
+ }
37
+ .qd-steps__phase--done.qd-steps__phase--clickable[data-v-3fae5c44]:hover {
38
+ background-color: var(--td-bg-color-container-hover);
39
+ }
40
+ .qd-steps__phase--active[data-v-3fae5c44] {
41
+ background-color: var(--td-brand-color-light);
42
+ }
43
+ .qd-steps__phase--active .qd-steps__phase-icon[data-v-3fae5c44] {
44
+ background-color: var(--td-brand-color);
45
+ color: var(--td-text-color-anti);
46
+ border-color: transparent;
47
+ box-shadow: var(--td-shadow-1);
48
+ }
49
+ .qd-steps__phase--active .qd-steps__phase-name[data-v-3fae5c44] {
50
+ color: var(--td-text-color-brand);
51
+ font-weight: 700;
52
+ }
53
+ .qd-steps__phase--pending[data-v-3fae5c44] {
54
+ opacity: 0.6;
55
+ }
56
+ .qd-steps__phase-icon[data-v-3fae5c44] {
57
+ width: calc(var(--td-comp-size-xxxs) + var(--td-size-1));
58
+ height: calc(var(--td-comp-size-xxxs) + var(--td-size-1));
59
+ border-radius: var(--td-radius-circle);
60
+ display: inline-flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ font-size: var(--td-font-size-mark-small);
64
+ font-weight: 700;
65
+ line-height: 1;
66
+ flex-shrink: 0;
67
+ background-color: var(--td-bg-color-secondarycontainer);
68
+ color: var(--td-text-color-placeholder);
69
+ border: calc(var(--td-size-1) / 2) solid var(--td-component-stroke);
70
+ transition: all 0.15s;
71
+ }
72
+ .qd-steps__phase-name[data-v-3fae5c44] {
73
+ font-size: var(--td-font-size-body-small);
74
+ color: var(--td-text-color-placeholder);
75
+ font-weight: 600;
76
+ white-space: nowrap;
77
+ transition: color 0.15s;
78
+ }
79
+ .qd-steps__separator[data-v-3fae5c44] {
80
+ color: var(--td-text-color-placeholder);
81
+ margin: 0 var(--td-comp-margin-s);
82
+ font-size: var(--td-font-size-body-large);
83
+ line-height: 1;
84
+ transform: translateY(calc(var(--td-size-1) / -2));
85
+ }
86
+ .qd-steps__separator--done[data-v-3fae5c44] {
87
+ color: var(--td-success-color);
88
+ }
89
+ .qd-steps__divider[data-v-3fae5c44] {
90
+ border-top: calc(var(--td-size-1) / 2) solid var(--td-border-level-1-color);
91
+ }
92
+ .qd-steps__substeps[data-v-3fae5c44] {
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: space-between;
96
+ width: 100%;
97
+ gap: var(--td-comp-margin-m);
98
+ margin-top: 0;
99
+ padding-bottom: 0;
100
+ }
101
+ .qd-steps__substep-list[data-v-3fae5c44] {
102
+ display: flex;
103
+ align-items: center;
104
+ flex-wrap: wrap;
105
+ gap: var(--td-size-1);
106
+ }
107
+ .qd-steps__substep[data-v-3fae5c44] {
108
+ display: inline-flex;
109
+ align-items: center;
110
+ border-radius: var(--td-radius-medium);
111
+ padding: var(--td-size-2) var(--td-comp-paddingLR-s);
112
+ gap: var(--td-size-3);
113
+ transition: all 0.12s;
114
+ }
115
+ .qd-steps__substep--clickable[data-v-3fae5c44] {
116
+ cursor: pointer;
117
+ }
118
+ .qd-steps__substep[data-v-3fae5c44]:hover {
119
+ background-color: var(--td-bg-color-container-hover);
120
+ }
121
+ .qd-steps__substep:hover .qd-steps__substep-name[data-v-3fae5c44] {
122
+ color: var(--td-text-color-primary);
123
+ }
124
+ .qd-steps__substep--done .qd-steps__substep-no[data-v-3fae5c44] {
125
+ color: var(--td-success-color);
126
+ background-color: transparent;
127
+ }
128
+ .qd-steps__substep--done .qd-steps__substep-no[data-v-3fae5c44]::before {
129
+ background-color: var(--td-success-color);
130
+ border-color: transparent;
131
+ }
132
+ .qd-steps__substep--done .qd-steps__substep-name[data-v-3fae5c44] {
133
+ color: var(--td-text-color-primary);
134
+ }
135
+ .qd-steps__substep--active[data-v-3fae5c44] {
136
+ background-color: var(--td-bg-color-container-hover);
137
+ }
138
+ .qd-steps__substep--active .qd-steps__substep-no[data-v-3fae5c44] {
139
+ color: var(--td-text-color-brand);
140
+ background-color: transparent;
141
+ }
142
+ .qd-steps__substep--active .qd-steps__substep-no[data-v-3fae5c44]::before {
143
+ background-color: var(--td-brand-color);
144
+ border-color: transparent;
145
+ box-shadow: 0 0 0 var(--td-size-1) var(--td-brand-color-light);
146
+ }
147
+ .qd-steps__substep--active .qd-steps__substep-name[data-v-3fae5c44] {
148
+ color: var(--td-text-color-brand);
149
+ font-weight: 700;
150
+ }
151
+ .qd-steps__substep--pending[data-v-3fae5c44] {
152
+ color: var(--td-text-color-placeholder);
153
+ }
154
+ .qd-steps__substep--pending .qd-steps__substep-no[data-v-3fae5c44] {
155
+ color: var(--td-text-color-disabled);
156
+ }
157
+ .qd-steps__substep--pending .qd-steps__substep-no[data-v-3fae5c44]::before {
158
+ border-color: var(--td-component-border);
159
+ }
160
+ .qd-steps__substep--pending .qd-steps__substep-name[data-v-3fae5c44] {
161
+ color: var(--td-text-color-placeholder);
162
+ }
163
+ .qd-steps__substep-no[data-v-3fae5c44] {
164
+ position: relative;
165
+ display: inline-flex;
166
+ align-items: center;
167
+ justify-content: center;
168
+ min-width: 0;
169
+ padding: 0;
170
+ padding-left: calc(var(--td-size-4) + var(--td-size-1));
171
+ font-size: var(--td-font-size-mark-small);
172
+ font-weight: 700;
173
+ line-height: 1.45;
174
+ color: var(--td-text-color-disabled);
175
+ background-color: transparent;
176
+ }
177
+ .qd-steps__substep-no[data-v-3fae5c44]::before {
178
+ content: '';
179
+ position: absolute;
180
+ left: 0;
181
+ top: 50%;
182
+ width: var(--td-size-3);
183
+ height: var(--td-size-3);
184
+ border-radius: var(--td-radius-circle);
185
+ border: calc(var(--td-size-1) / 2) solid var(--td-component-stroke);
186
+ box-sizing: border-box;
187
+ transform: translateY(-50%);
188
+ transition: all 0.12s;
189
+ }
190
+ .qd-steps__substep-name[data-v-3fae5c44] {
191
+ font-size: var(--td-font-size-body-small);
192
+ font-weight: 600;
193
+ color: var(--td-text-color-secondary);
194
+ white-space: nowrap;
195
+ transition: color 0.12s;
196
+ }
197
+ .qd-steps__indicator[data-v-3fae5c44] {
198
+ flex: none;
199
+ margin-left: auto;
200
+ padding: 0;
201
+ border: none;
202
+ font-size: var(--td-font-size-body-small);
203
+ font-weight: 600;
204
+ color: var(--td-text-color-placeholder);
205
+ white-space: nowrap;
206
+ background-color: transparent;
207
+ }
208
+ .qd-steps__indicator b[data-v-3fae5c44] {
209
+ color: var(--td-text-color-primary);
210
+ font-weight: 700;
211
+ }
@@ -0,0 +1,2 @@
1
+ export { default as QdSteps } from './index.vue';
2
+ export type { QdStepsProps, QdStepsGroup } from './types';
@@ -0,0 +1,10 @@
1
+ import type { QdStepsProps } from './types';
2
+ declare const _default: import("vue").DefineComponent<QdStepsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ jump: (stepIndex: number) => any;
4
+ }, string, import("vue").PublicProps, Readonly<QdStepsProps> & Readonly<{
5
+ onJump?: ((stepIndex: number) => any) | undefined;
6
+ }>, {
7
+ maxReachedStep: number;
8
+ canJumpTo: (stepIndex: number) => boolean;
9
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import './index.css'
2
+ import _sfc_main from "./index.vue2.mjs";
3
+ /* empty css */
4
+ import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
5
+ const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-3fae5c44"]]);
6
+ export {
7
+ index as default
8
+ };
@@ -0,0 +1,158 @@
1
+ import './index.css'
2
+ import { defineComponent, mergeDefaults, computed, createElementBlock, openBlock, createElementVNode, createCommentVNode, Fragment, renderList, createBlock, normalizeClass, toDisplayString, unref, createTextVNode } from "vue";
3
+ import { ChevronRightSIcon } from "tdesign-icons-vue-next";
4
+ import { qdStepsProps } from "./props.mjs";
5
+ const _hoisted_1 = { class: "qd-steps" };
6
+ const _hoisted_2 = { class: "qd-steps__nav" };
7
+ const _hoisted_3 = { class: "qd-steps__phases" };
8
+ const _hoisted_4 = ["onClick"];
9
+ const _hoisted_5 = {
10
+ key: 0,
11
+ class: "qd-steps__phase-icon"
12
+ };
13
+ const _hoisted_6 = {
14
+ key: 1,
15
+ class: "qd-steps__phase-icon"
16
+ };
17
+ const _hoisted_7 = {
18
+ key: 2,
19
+ class: "qd-steps__phase-icon"
20
+ };
21
+ const _hoisted_8 = { class: "qd-steps__phase-name" };
22
+ const _hoisted_9 = { class: "qd-steps__substeps" };
23
+ const _hoisted_10 = { class: "qd-steps__substep-list" };
24
+ const _hoisted_11 = ["onClick"];
25
+ const _hoisted_12 = { class: "qd-steps__substep-no" };
26
+ const _hoisted_13 = { class: "qd-steps__substep-name" };
27
+ const _hoisted_14 = { class: "qd-steps__indicator" };
28
+ const _sfc_main = /* @__PURE__ */ defineComponent({
29
+ ...{
30
+ name: "QdSteps"
31
+ },
32
+ __name: "index",
33
+ props: /* @__PURE__ */ mergeDefaults({
34
+ options: {},
35
+ current: {},
36
+ maxReachedStep: {},
37
+ canJumpTo: { type: Function }
38
+ }, qdStepsProps),
39
+ emits: ["jump"],
40
+ setup(__props, { emit: __emit }) {
41
+ const props = __props;
42
+ const emit = __emit;
43
+ const flatSteps = computed(() => props.options.flatMap((group) => getPhaseStepLabels(group)));
44
+ const reachedStep = computed(() => props.maxReachedStep ?? props.current);
45
+ const hasSubSteps = computed(() => props.options.some((group) => group.steps?.length));
46
+ const currentPhaseIndex = computed(
47
+ () => props.options.findIndex((group) => getPhaseStepIndexes(group).includes(props.current))
48
+ );
49
+ const currentPhaseStepIndexes = computed(() => {
50
+ const group = props.options[currentPhaseIndex.value];
51
+ if (!group) return [];
52
+ return getPhaseStepIndexes(group);
53
+ });
54
+ function getPhaseFirstStepIndex(group) {
55
+ return getPhaseStepIndexes(group)[0];
56
+ }
57
+ function getPhaseStepLabels(group) {
58
+ return group.steps?.length ? group.steps : [group.title];
59
+ }
60
+ function getPhaseStepIndexes(group) {
61
+ const startIndex = props.options.slice(0, props.options.indexOf(group)).reduce((total, item) => total + getPhaseStepLabels(item).length, 0);
62
+ return getPhaseStepLabels(group).map((_, index) => startIndex + index);
63
+ }
64
+ function getPhaseStatus(group) {
65
+ const stepIndexes = getPhaseStepIndexes(group);
66
+ const isActive = stepIndexes.includes(props.current);
67
+ if (isActive) return "active";
68
+ const isDone = stepIndexes.every((stepIndex) => stepIndex <= reachedStep.value);
69
+ if (isDone) return "done";
70
+ return "pending";
71
+ }
72
+ function getStepStatus(stepIndex) {
73
+ if (stepIndex === props.current) return "active";
74
+ if (stepIndex < props.current || stepIndex <= reachedStep.value) return "done";
75
+ return "pending";
76
+ }
77
+ function handlePhaseClick(phase) {
78
+ const stepIndex = getPhaseFirstStepIndex(phase);
79
+ if (!props.canJumpTo(stepIndex)) return;
80
+ emit("jump", stepIndex);
81
+ }
82
+ function handleStepClick(stepIndex) {
83
+ if (!props.canJumpTo(stepIndex)) return;
84
+ emit("jump", stepIndex);
85
+ }
86
+ return (_ctx, _cache) => {
87
+ return openBlock(), createElementBlock("div", _hoisted_1, [
88
+ createElementVNode("div", _hoisted_2, [
89
+ createElementVNode("div", _hoisted_3, [
90
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (phase, pi) => {
91
+ return openBlock(), createElementBlock(Fragment, { key: pi }, [
92
+ createElementVNode("div", {
93
+ class: normalizeClass([
94
+ "qd-steps__phase",
95
+ {
96
+ "qd-steps__phase--done": getPhaseStatus(phase) === "done",
97
+ "qd-steps__phase--active": getPhaseStatus(phase) === "active",
98
+ "qd-steps__phase--pending": getPhaseStatus(phase) === "pending",
99
+ "qd-steps__phase--clickable": __props.canJumpTo(getPhaseFirstStepIndex(phase))
100
+ }
101
+ ]),
102
+ onClick: ($event) => handlePhaseClick(phase)
103
+ }, [
104
+ getPhaseStatus(phase) === "done" ? (openBlock(), createElementBlock("span", _hoisted_5, "✓")) : getPhaseStatus(phase) === "active" ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(pi + 1), 1)) : (openBlock(), createElementBlock("span", _hoisted_7, toDisplayString(pi + 1), 1)),
105
+ createElementVNode("span", _hoisted_8, toDisplayString(phase.title), 1)
106
+ ], 10, _hoisted_4),
107
+ pi < __props.options.length - 1 ? (openBlock(), createBlock(unref(ChevronRightSIcon), {
108
+ key: 0,
109
+ class: normalizeClass([
110
+ "qd-steps__separator",
111
+ { "qd-steps__separator--done": getPhaseStatus(phase) === "done" }
112
+ ])
113
+ }, null, 8, ["class"])) : createCommentVNode("", true)
114
+ ], 64);
115
+ }), 128))
116
+ ])
117
+ ]),
118
+ hasSubSteps.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
119
+ _cache[1] || (_cache[1] = createElementVNode("div", { class: "qd-steps__divider" }, null, -1)),
120
+ createElementVNode("div", _hoisted_9, [
121
+ createElementVNode("div", _hoisted_10, [
122
+ (openBlock(true), createElementBlock(Fragment, null, renderList(currentPhaseStepIndexes.value, (stepIndex, subIndex) => {
123
+ return openBlock(), createElementBlock("div", {
124
+ key: stepIndex,
125
+ class: normalizeClass([
126
+ "qd-steps__substep",
127
+ `qd-steps__substep--${getStepStatus(stepIndex)}`,
128
+ {
129
+ "qd-steps__substep--clickable": __props.canJumpTo(stepIndex)
130
+ }
131
+ ]),
132
+ onClick: ($event) => handleStepClick(stepIndex)
133
+ }, [
134
+ createElementVNode("span", _hoisted_12, [
135
+ getStepStatus(stepIndex) === "done" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
136
+ createTextVNode("✓")
137
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
138
+ createTextVNode(toDisplayString(currentPhaseIndex.value + 1) + "." + toDisplayString(subIndex + 1), 1)
139
+ ], 64))
140
+ ]),
141
+ createElementVNode("span", _hoisted_13, toDisplayString(flatSteps.value[stepIndex]), 1)
142
+ ], 10, _hoisted_11);
143
+ }), 128))
144
+ ]),
145
+ createElementVNode("div", _hoisted_14, [
146
+ _cache[0] || (_cache[0] = createTextVNode(" 第 ", -1)),
147
+ createElementVNode("b", null, toDisplayString(__props.current + 1), 1),
148
+ createTextVNode(" / " + toDisplayString(flatSteps.value.length) + " 步 ", 1)
149
+ ])
150
+ ])
151
+ ], 64)) : createCommentVNode("", true)
152
+ ]);
153
+ };
154
+ }
155
+ });
156
+ export {
157
+ _sfc_main as default
158
+ };
@@ -0,0 +1,4 @@
1
+ export declare const qdStepsProps: {
2
+ readonly maxReachedStep: undefined;
3
+ readonly canJumpTo: () => boolean;
4
+ };
@@ -0,0 +1,7 @@
1
+ const qdStepsProps = {
2
+ maxReachedStep: void 0,
3
+ canJumpTo: () => false
4
+ };
5
+ export {
6
+ qdStepsProps
7
+ };
@@ -0,0 +1,10 @@
1
+ export interface QdStepsGroup {
2
+ title: string;
3
+ steps?: string[];
4
+ }
5
+ export interface QdStepsProps {
6
+ options: QdStepsGroup[];
7
+ current: number;
8
+ maxReachedStep?: number;
9
+ canJumpTo?: (stepIndex: number) => boolean;
10
+ }
package/dist/index.mjs CHANGED
@@ -44,8 +44,9 @@ import { defineQdServiceDialogTableSelect } from "./components/service-dialog-ta
44
44
  import { default as default32 } from "./components/service-popup-table-select/index.vue.mjs";
45
45
  import { defineQdServicePopupTableSelect } from "./components/service-popup-table-select/define.mjs";
46
46
  import { default as default33 } from "./components/service-select/index.vue.mjs";
47
+ import { default as default34 } from "./components/steps/index.vue.mjs";
47
48
  import { qdUploadAcceptMap } from "./components/upload/config.mjs";
48
- import { default as default34 } from "./components/upload/index.vue.mjs";
49
+ import { default as default35 } from "./components/upload/index.vue.mjs";
49
50
  import { hasPermi, hasPermiDirective } from "./directive/hasPermi.mjs";
50
51
  import { hasRole, hasRoleDirective } from "./directive/hasRole.mjs";
51
52
  import { useAgentChat } from "./hooks/useAgentChat/index.mjs";
@@ -99,7 +100,8 @@ export {
99
100
  default32 as QdServicePopupTableSelect,
100
101
  default33 as QdServiceSelect,
101
102
  default30 as QdServiceTable,
102
- default34 as QdUpload,
103
+ default34 as QdSteps,
104
+ default35 as QdUpload,
103
105
  auth,
104
106
  defineQdCrudList,
105
107
  defineQdCrudTable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidian-vue-ui",
3
- "version": "1.5.2",
3
+ "version": "1.7.0",
4
4
  "description": "基于 TDesign 的 QiDian Vue UI 组件库",
5
5
  "author": "qidian",
6
6
  "license": "MIT",