@veltra/desktop 1.1.12 → 1.1.13

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 (42) hide show
  1. package/dist/components/action/action-group.vue.d.ts +1 -1
  2. package/dist/components/action/action.vue.d.ts +1 -1
  3. package/dist/components/cascade/cascade.vue.d.ts +1 -1
  4. package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
  5. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  6. package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
  7. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
  8. package/dist/components/file-viewer/file-viewer.js +62 -19
  9. package/dist/components/file-viewer/file-viewer.js.map +1 -1
  10. package/dist/components/file-viewer/previewers/image-previewer.js +3 -2
  11. package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
  12. package/dist/components/file-viewer/previewers/pdf-previewer.js +60 -17
  13. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
  14. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js +83 -0
  15. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -0
  16. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js +32 -0
  17. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -0
  18. package/dist/components/file-viewer/style2.css +14 -1
  19. package/dist/components/multi-select/multi-select.vue.d.ts +1 -1
  20. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +1 -1
  21. package/dist/components/number/number.vue.d.ts +1 -1
  22. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  23. package/dist/components/scroll/scroll.js +94 -30
  24. package/dist/components/scroll/scroll.js.map +1 -1
  25. package/dist/components/scroll/style2.css +22 -0
  26. package/dist/components/steps/steps.vue.d.ts +1 -1
  27. package/dist/components/tabs/tabs-horizontal.vue.d.ts +1 -1
  28. package/dist/components/tabs/tabs.vue.d.ts +1 -1
  29. package/dist/components/tip/tip.vue.d.ts +1 -1
  30. package/dist/components/tree/tree.vue.d.ts +1 -1
  31. package/dist/components/tree-select/tree-select.vue.d.ts +1 -1
  32. package/dist/types/scroll.d.ts +6 -1
  33. package/package.json +12 -11
  34. package/src/components/file-viewer/file-viewer.vue +73 -16
  35. package/src/components/file-viewer/previewers/image-previewer.vue +1 -0
  36. package/src/components/file-viewer/previewers/pdf-previewer.vue +67 -14
  37. package/src/components/file-viewer/previewers/pdf-viewport-scroll.vue +112 -0
  38. package/src/components/file-viewer/previewers/pdf-zoom-bridge.vue +33 -0
  39. package/src/components/file-viewer/style.scss +16 -1
  40. package/src/components/scroll/scroll.vue +124 -75
  41. package/src/components/scroll/style.scss +22 -0
  42. package/src/types/scroll.ts +7 -1
@@ -0,0 +1,83 @@
1
+ import _sfc_main$1 from "../../scroll/scroll.js";
2
+ import { Fragment, computed, createCommentVNode, createElementBlock, createVNode, defineComponent, inject, onBeforeUnmount, openBlock, renderSlot, unref, watch, withCtx } from "vue";
3
+ //#region src/components/file-viewer/previewers/pdf-viewport-scroll.vue
4
+ const VIEWPORT_ELEMENT_KEY = "viewport-element";
5
+ const _sfc_main = /* @__PURE__ */ defineComponent({
6
+ name: "FileViewerPdfViewportScroll",
7
+ __name: "pdf-viewport-scroll",
8
+ setup(__props) {
9
+ /** EmbedPDF Viewport 向子树注入的滚动容器 ref */
10
+ const viewportRef = inject(VIEWPORT_ELEMENT_KEY);
11
+ const viewportEl = computed(() => viewportRef?.value ?? null);
12
+ let panState;
13
+ function isInteractiveTarget(target) {
14
+ if (!(target instanceof HTMLElement)) return false;
15
+ return !!target.closest("button, a, input, textarea, select, video, [contenteditable=\"true\"], .u-scroll__bar-x, .u-scroll__bar-y");
16
+ }
17
+ function handlePointerDown(e) {
18
+ if (e.button !== 0 || isInteractiveTarget(e.target)) return;
19
+ const el = viewportEl.value;
20
+ if (!el) return;
21
+ panState = {
22
+ pointerId: e.pointerId,
23
+ startX: e.clientX,
24
+ startY: e.clientY,
25
+ scrollLeft: el.scrollLeft,
26
+ scrollTop: el.scrollTop
27
+ };
28
+ el.classList.add("is-panning");
29
+ el.setPointerCapture(e.pointerId);
30
+ e.preventDefault();
31
+ }
32
+ function handlePointerMove(e) {
33
+ if (!panState || panState.pointerId !== e.pointerId) return;
34
+ const el = viewportEl.value;
35
+ if (!el) return;
36
+ el.scrollLeft = panState.scrollLeft - (e.clientX - panState.startX);
37
+ el.scrollTop = panState.scrollTop - (e.clientY - panState.startY);
38
+ }
39
+ function endPan(e) {
40
+ if (!panState || panState.pointerId !== e.pointerId) return;
41
+ const el = viewportEl.value;
42
+ if (el?.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId);
43
+ el?.classList.remove("is-panning");
44
+ panState = void 0;
45
+ }
46
+ let detachPan;
47
+ watch(viewportEl, (el, _, onCleanup) => {
48
+ detachPan?.();
49
+ detachPan = void 0;
50
+ if (!el) return;
51
+ el.addEventListener("pointerdown", handlePointerDown, { capture: true });
52
+ el.addEventListener("pointermove", handlePointerMove, { capture: true });
53
+ el.addEventListener("pointerup", endPan, { capture: true });
54
+ el.addEventListener("pointercancel", endPan, { capture: true });
55
+ detachPan = () => {
56
+ el.removeEventListener("pointerdown", handlePointerDown, { capture: true });
57
+ el.removeEventListener("pointermove", handlePointerMove, { capture: true });
58
+ el.removeEventListener("pointerup", endPan, { capture: true });
59
+ el.removeEventListener("pointercancel", endPan, { capture: true });
60
+ el.classList.remove("is-panning");
61
+ panState = void 0;
62
+ };
63
+ onCleanup(() => {
64
+ detachPan?.();
65
+ detachPan = void 0;
66
+ });
67
+ }, { immediate: true });
68
+ onBeforeUnmount(() => {
69
+ detachPan?.();
70
+ detachPan = void 0;
71
+ });
72
+ return (_ctx, _cache) => {
73
+ return openBlock(), createElementBlock(Fragment, null, [createCommentVNode(" EmbedPDF Viewport 自带滚动;u-scroll 仅同步自定义滚动条 "), createVNode(unref(_sfc_main$1), { target: viewportEl.value }, {
74
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
75
+ _: 3
76
+ }, 8, ["target"])], 2112);
77
+ };
78
+ }
79
+ });
80
+ //#endregion
81
+ export { _sfc_main as default };
82
+
83
+ //# sourceMappingURL=pdf-viewport-scroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-viewport-scroll.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/pdf-viewport-scroll.vue"],"sourcesContent":["<template>\n <!-- EmbedPDF Viewport 自带滚动;u-scroll 仅同步自定义滚动条 -->\n <u-scroll :target=\"viewportEl\">\n <slot />\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, inject, onBeforeUnmount, type Ref, watch } from 'vue'\n\nimport { UScroll } from '../../scroll'\n\ndefineOptions({ name: 'FileViewerPdfViewportScroll' })\n\n/** EmbedPDF Viewport 向子树注入的滚动容器 ref */\nconst VIEWPORT_ELEMENT_KEY = 'viewport-element'\n\nconst viewportRef = inject<Ref<HTMLDivElement | null>>(VIEWPORT_ELEMENT_KEY)\nconst viewportEl = computed(() => viewportRef?.value ?? null)\n\nlet panState:\n | {\n pointerId: number\n startX: number\n startY: number\n scrollLeft: number\n scrollTop: number\n }\n | undefined\n\nfunction isInteractiveTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false\n return !!target.closest(\n 'button, a, input, textarea, select, video, [contenteditable=\"true\"], .u-scroll__bar-x, .u-scroll__bar-y'\n )\n}\n\nfunction handlePointerDown(e: PointerEvent) {\n if (e.button !== 0 || isInteractiveTarget(e.target)) return\n\n const el = viewportEl.value\n if (!el) return\n\n panState = {\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n scrollLeft: el.scrollLeft,\n scrollTop: el.scrollTop\n }\n el.classList.add('is-panning')\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n}\n\nfunction handlePointerMove(e: PointerEvent) {\n if (!panState || panState.pointerId !== e.pointerId) return\n\n const el = viewportEl.value\n if (!el) return\n\n el.scrollLeft = panState.scrollLeft - (e.clientX - panState.startX)\n el.scrollTop = panState.scrollTop - (e.clientY - panState.startY)\n}\n\nfunction endPan(e: PointerEvent) {\n if (!panState || panState.pointerId !== e.pointerId) return\n\n const el = viewportEl.value\n if (el?.hasPointerCapture(e.pointerId)) {\n el.releasePointerCapture(e.pointerId)\n }\n el?.classList.remove('is-panning')\n panState = undefined\n}\n\nlet detachPan: (() => void) | undefined\n\nwatch(\n viewportEl,\n (el, _, onCleanup) => {\n detachPan?.()\n detachPan = undefined\n if (!el) return\n\n el.addEventListener('pointerdown', handlePointerDown, { capture: true })\n el.addEventListener('pointermove', handlePointerMove, { capture: true })\n el.addEventListener('pointerup', endPan, { capture: true })\n el.addEventListener('pointercancel', endPan, { capture: true })\n\n detachPan = () => {\n el.removeEventListener('pointerdown', handlePointerDown, { capture: true })\n el.removeEventListener('pointermove', handlePointerMove, { capture: true })\n el.removeEventListener('pointerup', endPan, { capture: true })\n el.removeEventListener('pointercancel', endPan, { capture: true })\n el.classList.remove('is-panning')\n panState = undefined\n }\n\n onCleanup(() => {\n detachPan?.()\n detachPan = undefined\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n detachPan?.()\n detachPan = undefined\n})\n</script>\n"],"mappings":";;;AAeA,MAAM,uBAAuB;;;;;;EAE7B,MAAM,cAAc,OAAmC,qBAAoB;EAC3E,MAAM,aAAa,eAAe,aAAa,SAAS,KAAI;EAE5D,IAAI;EAUJ,SAAS,oBAAoB,QAAqC;AAChE,OAAI,EAAE,kBAAkB,aAAc,QAAO;AAC7C,UAAO,CAAC,CAAC,OAAO,QACd,4GACF;;EAGF,SAAS,kBAAkB,GAAiB;AAC1C,OAAI,EAAE,WAAW,KAAK,oBAAoB,EAAE,OAAO,CAAE;GAErD,MAAM,KAAK,WAAW;AACtB,OAAI,CAAC,GAAI;AAET,cAAW;IACT,WAAW,EAAE;IACb,QAAQ,EAAE;IACV,QAAQ,EAAE;IACV,YAAY,GAAG;IACf,WAAW,GAAG;IAChB;AACA,MAAG,UAAU,IAAI,aAAY;AAC7B,MAAG,kBAAkB,EAAE,UAAS;AAChC,KAAE,gBAAe;;EAGnB,SAAS,kBAAkB,GAAiB;AAC1C,OAAI,CAAC,YAAY,SAAS,cAAc,EAAE,UAAW;GAErD,MAAM,KAAK,WAAW;AACtB,OAAI,CAAC,GAAI;AAET,MAAG,aAAa,SAAS,cAAc,EAAE,UAAU,SAAS;AAC5D,MAAG,YAAY,SAAS,aAAa,EAAE,UAAU,SAAS;;EAG5D,SAAS,OAAO,GAAiB;AAC/B,OAAI,CAAC,YAAY,SAAS,cAAc,EAAE,UAAW;GAErD,MAAM,KAAK,WAAW;AACtB,OAAI,IAAI,kBAAkB,EAAE,UAAU,CACpC,IAAG,sBAAsB,EAAE,UAAS;AAEtC,OAAI,UAAU,OAAO,aAAY;AACjC,cAAW,KAAA;;EAGb,IAAI;AAEJ,QACE,aACC,IAAI,GAAG,cAAc;AACpB,gBAAY;AACZ,eAAY,KAAA;AACZ,OAAI,CAAC,GAAI;AAET,MAAG,iBAAiB,eAAe,mBAAmB,EAAE,SAAS,MAAM,CAAA;AACvE,MAAG,iBAAiB,eAAe,mBAAmB,EAAE,SAAS,MAAM,CAAA;AACvE,MAAG,iBAAiB,aAAa,QAAQ,EAAE,SAAS,MAAM,CAAA;AAC1D,MAAG,iBAAiB,iBAAiB,QAAQ,EAAE,SAAS,MAAM,CAAA;AAE9D,qBAAkB;AAChB,OAAG,oBAAoB,eAAe,mBAAmB,EAAE,SAAS,MAAM,CAAA;AAC1E,OAAG,oBAAoB,eAAe,mBAAmB,EAAE,SAAS,MAAM,CAAA;AAC1E,OAAG,oBAAoB,aAAa,QAAQ,EAAE,SAAS,MAAM,CAAA;AAC7D,OAAG,oBAAoB,iBAAiB,QAAQ,EAAE,SAAS,MAAM,CAAA;AACjE,OAAG,UAAU,OAAO,aAAY;AAChC,eAAW,KAAA;;AAGb,mBAAgB;AACd,iBAAY;AACZ,gBAAY,KAAA;KACb;KAEH,EAAE,WAAW,MAAK,CACpB;AAEA,wBAAsB;AACpB,gBAAY;AACZ,eAAY,KAAA;IACb;;2DA7GC,mBAAA,8CAAkD,EAClD,YAEW,MAAA,YAAA,EAAA,EAFA,QAAQ,WAAA,OAAU,EAAA;2BACnB,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { createElementBlock, defineComponent, openBlock, watch } from "vue";
2
+ import { ZoomMode, useZoom } from "@embedpdf/plugin-zoom/vue";
3
+ //#region src/components/file-viewer/previewers/pdf-zoom-bridge.vue
4
+ const _hoisted_1 = {
5
+ hidden: "",
6
+ "aria-hidden": "true"
7
+ };
8
+ const _sfc_main = /* @__PURE__ */ defineComponent({
9
+ name: "FileViewerPdfZoomBridge",
10
+ __name: "pdf-zoom-bridge",
11
+ props: { documentId: {} },
12
+ emits: ["zoom-change"],
13
+ setup(__props, { expose: __expose, emit: __emit }) {
14
+ const props = __props;
15
+ const emit = __emit;
16
+ const { provides: zoom, state } = useZoom(() => props.documentId);
17
+ watch([zoom, () => state.value.currentZoomLevel], () => {
18
+ emit("zoom-change", {
19
+ level: state.value.currentZoomLevel,
20
+ scope: zoom.value
21
+ });
22
+ }, { immediate: true });
23
+ __expose({ resetZoom: () => zoom.value?.requestZoom(ZoomMode.FitPage) });
24
+ return (_ctx, _cache) => {
25
+ return openBlock(), createElementBlock("span", _hoisted_1);
26
+ };
27
+ }
28
+ });
29
+ //#endregion
30
+ export { _sfc_main as default };
31
+
32
+ //# sourceMappingURL=pdf-zoom-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-zoom-bridge.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/pdf-zoom-bridge.vue"],"sourcesContent":["<template>\n <span hidden aria-hidden=\"true\" />\n</template>\n\n<script lang=\"ts\" setup>\nimport { useZoom, ZoomMode, type ZoomScope } from '@embedpdf/plugin-zoom/vue'\nimport { watch } from 'vue'\n\ndefineOptions({ name: 'FileViewerPdfZoomBridge' })\n\nconst props = defineProps<{ documentId: string }>()\n\nconst emit = defineEmits<{\n (e: 'zoom-change', payload: { level: number; scope: ZoomScope | null }): void\n}>()\n\nconst { provides: zoom, state } = useZoom(() => props.documentId)\n\nwatch(\n [zoom, () => state.value.currentZoomLevel],\n () => {\n emit('zoom-change', {\n level: state.value.currentZoomLevel,\n scope: zoom.value\n })\n },\n { immediate: true }\n)\n\ndefineExpose({\n resetZoom: () => zoom.value?.requestZoom(ZoomMode.FitPage)\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;EAUA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAIb,MAAM,EAAE,UAAU,MAAM,UAAU,cAAc,MAAM,WAAU;AAEhE,QACE,CAAC,YAAY,MAAM,MAAM,iBAAiB,QACpC;AACJ,QAAK,eAAe;IAClB,OAAO,MAAM,MAAM;IACnB,OAAO,KAAK;IACb,CAAA;KAEH,EAAE,WAAW,MAAK,CACpB;AAEA,WAAa,EACX,iBAAiB,KAAK,OAAO,YAAY,SAAS,QAAO,EAC1D,CAAA;;uBA9BC,mBAAkC,QAAlC,WAAkC"}
@@ -449,7 +449,6 @@
449
449
  }
450
450
  .u-file-viewer__viewport.is-dragging .u-file-viewer__previewer {
451
451
  transition: none;
452
- pointer-events: none;
453
452
  }
454
453
  .u-file-viewer__empty {
455
454
  width: 100%;
@@ -525,9 +524,23 @@
525
524
  overflow: hidden;
526
525
  }
527
526
  .u-file-viewer__pdf-viewport {
527
+ position: relative;
528
528
  width: 100%;
529
529
  height: 100%;
530
530
  background: transparent;
531
+ cursor: grab;
532
+ }
533
+ .u-file-viewer__pdf-viewport.is-panning {
534
+ cursor: grabbing;
535
+ user-select: none;
536
+ }
537
+ .u-file-viewer__pdf-viewport {
538
+ scrollbar-width: none;
539
+ scrollbar-color: transparent transparent;
540
+ }
541
+ .u-file-viewer__pdf-viewport::-webkit-scrollbar {
542
+ width: 0;
543
+ height: 0;
531
544
  }
532
545
  .u-file-viewer__pdf-page {
533
546
  margin: 24px auto;
@@ -30,11 +30,11 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
30
30
  }>, {
31
31
  disabled: boolean;
32
32
  readonly: boolean;
33
- minWidth: string;
34
33
  labelKey: string;
35
34
  valueKey: string;
36
35
  placeholder: string;
37
36
  clearable: boolean;
37
+ minWidth: string;
38
38
  visibilityLimit: number;
39
39
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
40
40
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -24,13 +24,13 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
24
24
  }>, {
25
25
  disabled: boolean;
26
26
  readonly: boolean;
27
- minWidth: string;
28
27
  expandAll: boolean;
29
28
  labelKey: string;
30
29
  valueKey: string;
31
30
  placeholder: string;
32
31
  clearable: boolean;
33
32
  filterable: boolean;
33
+ minWidth: string;
34
34
  visibilityLimit: number;
35
35
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
36
36
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -3,8 +3,8 @@ import * as _$vue from "vue";
3
3
 
4
4
  //#region src/components/number/number.vue.d.ts
5
5
  declare const __VLS_export: _$vue.DefineComponent<NumberProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<NumberProps> & Readonly<{}>, {
6
- format: "currency" | "percent" | "decimal";
7
6
  duration: number;
7
+ format: "currency" | "percent" | "decimal";
8
8
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
9
9
  declare const _default: typeof __VLS_export;
10
10
  //#endregion
@@ -14,8 +14,8 @@ declare const __VLS_base: _$vue.DefineComponent<PopConfirmProps, {}, {}, {}, {},
14
14
  onConfirm?: (() => any) | undefined;
15
15
  onCancel?: (() => any) | undefined;
16
16
  }>, {
17
- trigger: "hover" | "click";
18
17
  direction: TipDirection;
18
+ trigger: "hover" | "click";
19
19
  icon: _$vue.Component;
20
20
  iconColor: string;
21
21
  confirmText: string;
@@ -1,6 +1,6 @@
1
1
  import { ScrollDIKey } from "./di.js";
2
2
  import _sfc_main$1 from "./scroll-bar.js";
3
- import { computed, createBlock, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, provide, renderSlot, resolveDynamicComponent, shallowRef, unref, withCtx } from "vue";
3
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, provide, renderSlot, resolveDynamicComponent, shallowRef, toValue, unref, watch, withCtx } from "vue";
4
4
  import { useResizeObserver } from "@veltra/compositions";
5
5
  import { bem, withUnit } from "@veltra/utils";
6
6
  import { debounce } from "@cat-kit/core";
@@ -17,48 +17,53 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
17
17
  containerStyle: {},
18
18
  contentClass: {},
19
19
  containerClass: {},
20
- dragDebounce: {}
20
+ dragDebounce: {},
21
+ target: {}
21
22
  },
22
23
  emits: ["scroll", "resize"],
23
24
  setup(__props, { expose: __expose, emit: __emit }) {
24
25
  const props = __props;
25
26
  const emit = __emit;
26
27
  const cls = bem("scroll");
28
+ const isExternal = computed(() => props.target !== void 0);
29
+ const externalTarget = computed(() => isExternal.value ? toValue(props.target) : null);
27
30
  const className = computed(() => {
28
- return [cls.b, bem.is("always", props.always)];
31
+ return [
32
+ cls.b,
33
+ bem.is("always", props.always),
34
+ bem.is("external", isExternal.value)
35
+ ];
29
36
  });
30
37
  const style = computed(() => {
38
+ if (isExternal.value) return {};
31
39
  return { height: withUnit(props.height, "px") };
32
40
  });
33
- /** 内容引用 */
34
41
  const contentRef = shallowRef();
35
- /** 滚动根元素引用 */
36
42
  const scrollRef = shallowRef();
37
- /** 容器引用 */
38
43
  const containerRef = shallowRef();
44
+ const overlayRef = shallowRef();
39
45
  const barX = shallowRef();
40
46
  const barY = shallowRef();
41
47
  const trackSize = {
42
48
  width: 0,
43
49
  height: 0
44
50
  };
45
- useResizeObserver({
46
- targets: [contentRef, scrollRef],
47
- onResize: (entries) => {
48
- if (entries.length && scrollRef.value) {
49
- const { clientHeight, clientWidth } = scrollRef.value;
50
- trackSize.width = clientWidth;
51
- trackSize.height = clientHeight;
52
- barX.value?.setTrackSize(trackSize.width);
53
- barY.value?.setTrackSize(trackSize.height);
54
- updateBar();
55
- emit("resize", entries.map((entry) => entry.target));
56
- }
57
- }
58
- });
51
+ function getScrollContainer() {
52
+ if (isExternal.value) return externalTarget.value ?? void 0;
53
+ return containerRef.value;
54
+ }
55
+ function syncTrackSize() {
56
+ const container = getScrollContainer();
57
+ if (!container) return;
58
+ trackSize.width = container.clientWidth;
59
+ trackSize.height = container.clientHeight;
60
+ barX.value?.setTrackSize(trackSize.width);
61
+ barY.value?.setTrackSize(trackSize.height);
62
+ }
59
63
  const updateBar = () => {
60
- if (!containerRef.value) return;
61
- const { scrollHeight, clientHeight, scrollTop, scrollWidth, clientWidth, scrollLeft } = containerRef.value;
64
+ const container = getScrollContainer();
65
+ if (!container) return;
66
+ const { scrollHeight, clientHeight, scrollTop, scrollWidth, clientWidth, scrollLeft } = container;
62
67
  emit("scroll", {
63
68
  x: scrollLeft,
64
69
  y: scrollTop,
@@ -79,25 +84,57 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
79
84
  } else barX.value?.update(0, 0);
80
85
  };
81
86
  const handleDragX = debounce((offset, size) => {
82
- const container = containerRef.value;
87
+ const container = getScrollContainer();
88
+ if (!container) return;
83
89
  const { clientWidth, scrollWidth } = container;
84
90
  container.scrollLeft = offset / (trackSize.width - size) * (scrollWidth - clientWidth);
85
91
  }, props.dragDebounce ?? 0, false);
86
92
  const handleDragY = debounce((offset, size) => {
87
- const container = containerRef.value;
93
+ const container = getScrollContainer();
94
+ if (!container) return;
88
95
  const { clientHeight, scrollHeight } = container;
89
96
  container.scrollTop = offset / (trackSize.height - size) * (scrollHeight - clientHeight);
90
97
  }, props.dragDebounce ?? 0, false);
91
- const handleScroll = (e) => {
98
+ const handleScroll = () => {
92
99
  updateBar();
93
100
  };
101
+ useResizeObserver({
102
+ targets: [
103
+ contentRef,
104
+ scrollRef,
105
+ () => externalTarget.value ?? null
106
+ ],
107
+ onResize: (entries) => {
108
+ syncTrackSize();
109
+ updateBar();
110
+ if (entries.length) emit("resize", entries.map((entry) => entry.target));
111
+ }
112
+ });
113
+ let detachExternalScroll;
114
+ watch(externalTarget, (el, _, onCleanup) => {
115
+ detachExternalScroll?.();
116
+ detachExternalScroll = void 0;
117
+ if (!el || !isExternal.value) return;
118
+ const onScroll = () => updateBar();
119
+ el.addEventListener("scroll", onScroll, { passive: true });
120
+ detachExternalScroll = () => el.removeEventListener("scroll", onScroll);
121
+ syncTrackSize();
122
+ updateBar();
123
+ onCleanup(() => {
124
+ detachExternalScroll?.();
125
+ detachExternalScroll = void 0;
126
+ });
127
+ }, { immediate: true });
128
+ onBeforeUnmount(() => {
129
+ detachExternalScroll?.();
130
+ });
94
131
  const scrollToLeft = (left) => {
95
- const container = containerRef.value;
132
+ const container = getScrollContainer();
96
133
  if (!container) return;
97
134
  container.scrollTo({ left });
98
135
  };
99
136
  const scrollToTop = (top) => {
100
- const container = containerRef.value;
137
+ const container = getScrollContainer();
101
138
  if (!container) return;
102
139
  container.scrollTo({ top });
103
140
  };
@@ -106,10 +143,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
106
143
  if (position.y !== void 0) scrollToTop(position.y);
107
144
  };
108
145
  provide(ScrollDIKey, { cls });
146
+ const activeContainerRef = shallowRef();
147
+ watch([
148
+ isExternal,
149
+ externalTarget,
150
+ containerRef
151
+ ], () => {
152
+ activeContainerRef.value = getScrollContainer();
153
+ }, { immediate: true });
109
154
  __expose({
110
155
  el: scrollRef,
111
156
  contentRef,
112
- containerRef,
157
+ containerRef: activeContainerRef,
113
158
  scrollTo,
114
159
  update: updateBar
115
160
  });
@@ -119,7 +164,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
119
164
  style: normalizeStyle(style.value),
120
165
  ref_key: "scrollRef",
121
166
  ref: scrollRef
122
- }, [
167
+ }, [!isExternal.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
123
168
  createElementVNode("div", {
124
169
  ref_key: "containerRef",
125
170
  ref: containerRef,
@@ -149,7 +194,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
149
194
  ref_key: "barX",
150
195
  ref: barX
151
196
  }, null, 8, ["class", "onDrag"])
152
- ], 6);
197
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [renderSlot(_ctx.$slots, "default"), externalTarget.value ? (openBlock(), createBlock(Teleport, {
198
+ key: 0,
199
+ to: externalTarget.value
200
+ }, [createElementVNode("div", {
201
+ ref_key: "overlayRef",
202
+ ref: overlayRef,
203
+ class: normalizeClass(unref(cls).e("overlay"))
204
+ }, [createVNode(_sfc_main$1, {
205
+ type: "y",
206
+ class: normalizeClass(unref(cls).e("bar-y")),
207
+ onDrag: unref(handleDragY),
208
+ ref_key: "barY",
209
+ ref: barY
210
+ }, null, 8, ["class", "onDrag"]), createVNode(_sfc_main$1, {
211
+ type: "x",
212
+ class: normalizeClass(unref(cls).e("bar-x")),
213
+ onDrag: unref(handleDragX),
214
+ ref_key: "barX",
215
+ ref: barX
216
+ }, null, 8, ["class", "onDrag"])], 2)], 8, ["to"])) : createCommentVNode("v-if", true)], 64))], 6);
153
217
  };
154
218
  }
155
219
  });
@@ -1 +1 @@
1
- {"version":3,"file":"scroll.js","names":[],"sources":["../../../src/components/scroll/scroll.vue"],"sourcesContent":["<template>\n <div :class=\"className\" :style=\"style\" ref=\"scrollRef\">\n <div\n ref=\"containerRef\"\n :class=\"[cls.e('container'), containerClass]\"\n @scroll.passive=\"handleScroll\"\n :style=\"containerStyle\"\n >\n <component\n ref=\"contentRef\"\n :style=\"contentStyle\"\n :class=\"[cls.e('content'), contentClass]\"\n :is=\"tag\"\n >\n <slot />\n </component>\n </div>\n\n <u-scroll-bar type=\"y\" :class=\"cls.e('bar-y')\" @drag=\"handleDragY\" ref=\"barY\" />\n <u-scroll-bar type=\"x\" :class=\"cls.e('bar-x')\" @drag=\"handleDragX\" ref=\"barX\" />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { debounce } from '@cat-kit/core'\nimport { useResizeObserver } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed, provide, shallowRef } from 'vue'\n\nimport type { ScrollPosition, _ScrollExposed, ScrollProps, ScrollEmits } from '../../types'\nimport { ScrollDIKey } from './di'\nimport UScrollBar from './scroll-bar.vue'\n\ndefineOptions({\n name: 'Scroll'\n})\n\nconst props = withDefaults(defineProps<ScrollProps>(), {\n tag: 'div'\n})\n\nconst emit = defineEmits<ScrollEmits>()\n\ndefineSlots<{\n /** 默认插槽 */\n default(): any\n /** 内容插槽 */\n content(): any\n}>()\n\nconst cls = bem('scroll')\nconst className = computed(() => {\n return [cls.b, bem.is('always', props.always)]\n})\n\n// 样式-------------------------------------------------------------\nconst style = computed<CSSProperties>(() => {\n return {\n height: withUnit(props.height, 'px')\n }\n})\n\n// 模板引用------------------------------------------------\n/** 内容引用 */\nconst contentRef = shallowRef<HTMLElement>()\n/** 滚动根元素引用 */\nconst scrollRef = shallowRef<HTMLElement>()\n/** 容器引用 */\nconst containerRef = shallowRef<HTMLElement>()\nconst barX = shallowRef<InstanceType<typeof UScrollBar>>()\nconst barY = shallowRef<InstanceType<typeof UScrollBar>>()\nconst minSize = 20\n\nconst trackSize = {\n width: 0,\n height: 0\n}\n\nuseResizeObserver({\n targets: [contentRef, scrollRef],\n onResize: (entries) => {\n if (entries.length && scrollRef.value) {\n const { clientHeight, clientWidth } = scrollRef.value\n\n trackSize.width = clientWidth\n trackSize.height = clientHeight\n\n barX.value?.setTrackSize(trackSize.width)\n barY.value?.setTrackSize(trackSize.height)\n updateBar()\n\n emit(\n 'resize',\n entries.map((entry) => entry.target as HTMLElement)\n )\n }\n }\n})\n\n// 更新滚动条\nconst updateBar = () => {\n if (!containerRef.value) return\n\n const {\n scrollHeight,\n clientHeight,\n scrollTop,\n\n scrollWidth,\n clientWidth,\n scrollLeft\n } = containerRef.value\n\n emit('scroll', {\n x: scrollLeft,\n y: scrollTop,\n sw: scrollWidth,\n sh: scrollHeight,\n cw: clientWidth,\n ch: clientHeight\n })\n\n if (scrollHeight !== clientHeight) {\n const barYHeight = Math.max((clientHeight / scrollHeight) * trackSize.height, minSize)\n\n const barYTop = (scrollTop / (scrollHeight - clientHeight)) * (trackSize.height - barYHeight)\n\n barY.value?.update(barYHeight, barYTop)\n } else {\n barY.value?.update(0, 0)\n }\n\n if (scrollWidth !== clientWidth) {\n const barXWidth = Math.max((clientWidth / scrollWidth) * trackSize.width, minSize)\n\n const barXLeft = (scrollLeft / (scrollWidth - clientWidth)) * (trackSize.width - barXWidth)\n\n barX.value?.update(barXWidth, barXLeft)\n } else {\n barX.value?.update(0, 0)\n }\n}\n\n// 滚动条拖拽\nconst handleDragX = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientWidth, scrollWidth } = container\n\n container.scrollLeft = (offset / (trackSize.width - size)) * (scrollWidth - clientWidth)\n },\n props.dragDebounce ?? 0,\n false\n)\n\nconst handleDragY = debounce(\n (offset: number, size: number) => {\n const container = containerRef.value!\n const { clientHeight, scrollHeight } = container\n container.scrollTop = (offset / (trackSize.height - size)) * (scrollHeight - clientHeight)\n },\n props.dragDebounce ?? 0,\n false\n)\n\n// 滚动事件\nconst handleScroll = (e) => {\n updateBar()\n}\n\n// 滚动至------------------------------------------------\nconst scrollToLeft = (left: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n left\n })\n}\n\nconst scrollToTop = (top: number) => {\n const container = containerRef.value\n if (!container) return\n\n container.scrollTo({\n top\n })\n}\n\nconst scrollTo = (position: ScrollPosition) => {\n if (position.x !== undefined) scrollToLeft(position.x)\n if (position.y !== undefined) scrollToTop(position.y)\n}\n\nprovide(ScrollDIKey, {\n cls\n})\n\nconst exposed: _ScrollExposed = {\n el: scrollRef,\n contentRef,\n containerRef,\n scrollTo,\n update: updateBar\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"scroll.js","names":[],"sources":["../../../src/components/scroll/scroll.vue"],"sourcesContent":["<template>\n <div :class=\"className\" :style=\"style\" ref=\"scrollRef\">\n <template v-if=\"!isExternal\">\n <div\n ref=\"containerRef\"\n :class=\"[cls.e('container'), containerClass]\"\n @scroll.passive=\"handleScroll\"\n :style=\"containerStyle\"\n >\n <component\n ref=\"contentRef\"\n :style=\"contentStyle\"\n :class=\"[cls.e('content'), contentClass]\"\n :is=\"tag\"\n >\n <slot />\n </component>\n </div>\n\n <u-scroll-bar type=\"y\" :class=\"cls.e('bar-y')\" @drag=\"handleDragY\" ref=\"barY\" />\n <u-scroll-bar type=\"x\" :class=\"cls.e('bar-x')\" @drag=\"handleDragX\" ref=\"barX\" />\n </template>\n\n <template v-else>\n <slot />\n <Teleport v-if=\"externalTarget\" :to=\"externalTarget\">\n <div ref=\"overlayRef\" :class=\"cls.e('overlay')\">\n <u-scroll-bar type=\"y\" :class=\"cls.e('bar-y')\" @drag=\"handleDragY\" ref=\"barY\" />\n <u-scroll-bar type=\"x\" :class=\"cls.e('bar-x')\" @drag=\"handleDragX\" ref=\"barX\" />\n </div>\n </Teleport>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { debounce } from '@cat-kit/core'\nimport { useResizeObserver } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport {\n type CSSProperties,\n computed,\n onBeforeUnmount,\n provide,\n shallowRef,\n toValue,\n watch\n} from 'vue'\n\nimport type { ScrollPosition, _ScrollExposed, ScrollProps, ScrollEmits } from '../../types'\nimport { ScrollDIKey } from './di'\nimport UScrollBar from './scroll-bar.vue'\n\ndefineOptions({\n name: 'Scroll'\n})\n\nconst props = withDefaults(defineProps<ScrollProps>(), {\n tag: 'div'\n})\n\nconst emit = defineEmits<ScrollEmits>()\n\ndefineSlots<{\n /** 默认插槽 */\n default(): any\n /** 内容插槽 */\n content(): any\n}>()\n\nconst cls = bem('scroll')\n\nconst isExternal = computed(() => props.target !== undefined)\n\nconst externalTarget = computed(() => (isExternal.value ? toValue(props.target) : null))\n\nconst className = computed(() => {\n return [cls.b, bem.is('always', props.always), bem.is('external', isExternal.value)]\n})\n\nconst style = computed<CSSProperties>(() => {\n if (isExternal.value) return {}\n return {\n height: withUnit(props.height, 'px')\n }\n})\n\nconst contentRef = shallowRef<HTMLElement>()\nconst scrollRef = shallowRef<HTMLElement>()\nconst containerRef = shallowRef<HTMLElement>()\nconst overlayRef = shallowRef<HTMLElement>()\nconst barX = shallowRef<InstanceType<typeof UScrollBar>>()\nconst barY = shallowRef<InstanceType<typeof UScrollBar>>()\nconst minSize = 20\n\nconst trackSize = {\n width: 0,\n height: 0\n}\n\nfunction getScrollContainer(): HTMLElement | undefined {\n if (isExternal.value) {\n return externalTarget.value ?? undefined\n }\n return containerRef.value\n}\n\nfunction syncTrackSize() {\n const container = getScrollContainer()\n if (!container) return\n\n trackSize.width = container.clientWidth\n trackSize.height = container.clientHeight\n barX.value?.setTrackSize(trackSize.width)\n barY.value?.setTrackSize(trackSize.height)\n}\n\nconst updateBar = () => {\n const container = getScrollContainer()\n if (!container) return\n\n const { scrollHeight, clientHeight, scrollTop, scrollWidth, clientWidth, scrollLeft } = container\n\n emit('scroll', {\n x: scrollLeft,\n y: scrollTop,\n sw: scrollWidth,\n sh: scrollHeight,\n cw: clientWidth,\n ch: clientHeight\n })\n\n if (scrollHeight !== clientHeight) {\n const barYHeight = Math.max((clientHeight / scrollHeight) * trackSize.height, minSize)\n const barYTop = (scrollTop / (scrollHeight - clientHeight)) * (trackSize.height - barYHeight)\n barY.value?.update(barYHeight, barYTop)\n } else {\n barY.value?.update(0, 0)\n }\n\n if (scrollWidth !== clientWidth) {\n const barXWidth = Math.max((clientWidth / scrollWidth) * trackSize.width, minSize)\n const barXLeft = (scrollLeft / (scrollWidth - clientWidth)) * (trackSize.width - barXWidth)\n barX.value?.update(barXWidth, barXLeft)\n } else {\n barX.value?.update(0, 0)\n }\n}\n\nconst handleDragX = debounce(\n (offset: number, size: number) => {\n const container = getScrollContainer()\n if (!container) return\n const { clientWidth, scrollWidth } = container\n container.scrollLeft = (offset / (trackSize.width - size)) * (scrollWidth - clientWidth)\n },\n props.dragDebounce ?? 0,\n false\n)\n\nconst handleDragY = debounce(\n (offset: number, size: number) => {\n const container = getScrollContainer()\n if (!container) return\n const { clientHeight, scrollHeight } = container\n container.scrollTop = (offset / (trackSize.height - size)) * (scrollHeight - clientHeight)\n },\n props.dragDebounce ?? 0,\n false\n)\n\nconst handleScroll = () => {\n updateBar()\n}\n\nuseResizeObserver({\n targets: [contentRef, scrollRef, () => externalTarget.value ?? null],\n onResize: (entries) => {\n syncTrackSize()\n updateBar()\n if (entries.length) {\n emit(\n 'resize',\n entries.map((entry) => entry.target as HTMLElement)\n )\n }\n }\n})\n\nlet detachExternalScroll: (() => void) | undefined\n\nwatch(\n externalTarget,\n (el, _, onCleanup) => {\n detachExternalScroll?.()\n detachExternalScroll = undefined\n if (!el || !isExternal.value) return\n\n const onScroll = () => updateBar()\n el.addEventListener('scroll', onScroll, { passive: true })\n detachExternalScroll = () => el.removeEventListener('scroll', onScroll)\n syncTrackSize()\n updateBar()\n\n onCleanup(() => {\n detachExternalScroll?.()\n detachExternalScroll = undefined\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n detachExternalScroll?.()\n})\n\nconst scrollToLeft = (left: number) => {\n const container = getScrollContainer()\n if (!container) return\n container.scrollTo({ left })\n}\n\nconst scrollToTop = (top: number) => {\n const container = getScrollContainer()\n if (!container) return\n container.scrollTo({ top })\n}\n\nconst scrollTo = (position: ScrollPosition) => {\n if (position.x !== undefined) scrollToLeft(position.x)\n if (position.y !== undefined) scrollToTop(position.y)\n}\n\nprovide(ScrollDIKey, {\n cls\n})\n\nconst activeContainerRef = shallowRef<HTMLElement>()\n\nwatch(\n [isExternal, externalTarget, containerRef],\n () => {\n activeContainerRef.value = getScrollContainer()\n },\n { immediate: true }\n)\n\nconst exposed: _ScrollExposed = {\n el: scrollRef,\n contentRef,\n containerRef: activeContainerRef,\n scrollTo,\n update: updateBar\n}\n\ndefineExpose(exposed)\n</script>\n"],"mappings":"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"}
@@ -22,6 +22,28 @@
22
22
  overflow: hidden;
23
23
  scroll-behavior: auto;
24
24
  }
25
+ .u-scroll.is-external {
26
+ display: contents;
27
+ }
28
+ .u-scroll__overlay {
29
+ position: absolute;
30
+ inset: 0;
31
+ overflow: hidden;
32
+ pointer-events: none;
33
+ z-index: 2;
34
+ }
35
+ .u-scroll__overlay .u-scroll__bar-x {
36
+ pointer-events: auto;
37
+ }
38
+ .u-scroll__overlay .u-scroll__bar-y {
39
+ pointer-events: auto;
40
+ }
41
+ .u-scroll__overlay:hover > .u-scroll__bar-x {
42
+ opacity: 1;
43
+ }
44
+ .u-scroll__overlay:hover > .u-scroll__bar-y {
45
+ opacity: 1;
46
+ }
25
47
  .u-scroll__container {
26
48
  overflow: auto;
27
49
  height: 100%;
@@ -15,8 +15,8 @@ declare const __VLS_base: _$vue.DefineComponent<StepsProps, {}, {}, {}, {}, _$vu
15
15
  "onUpdate:current"?: ((value?: string | number | undefined) => any) | undefined;
16
16
  "onItem-click"?: ((item: Record<string, any>, index: number) => any) | undefined;
17
17
  }>, {
18
- labelKey: string;
19
18
  direction: "horizontal" | "vertical";
19
+ labelKey: string;
20
20
  finishedStepType: _$_veltra_utils0.ColorType;
21
21
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
22
22
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -24,9 +24,9 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
24
24
  onClick?: ((item: TabItem, index: number) => any) | undefined;
25
25
  }>, {
26
26
  closable: boolean;
27
- block: boolean;
28
27
  rounded: boolean;
29
28
  position: "top" | "bottom";
29
+ block: boolean;
30
30
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
31
31
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
32
  declare const _default: typeof __VLS_export;
@@ -19,9 +19,9 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
19
19
  onClick?: ((item: TabItem, index: number) => any) | undefined;
20
20
  }>, {
21
21
  closable: boolean;
22
- block: boolean;
23
22
  rounded: boolean;
24
23
  position: "left" | "right" | "top" | "bottom";
24
+ block: boolean;
25
25
  keepAlive: boolean;
26
26
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
27
27
  declare const _default: typeof __VLS_export;
@@ -11,10 +11,10 @@ declare const __VLS_base: _$vue.DefineComponent<TipProps, {}, {}, {}, {}, _$vue.
11
11
  }, string, _$vue.PublicProps, Readonly<TipProps> & Readonly<{
12
12
  "onUpdate:visible"?: ((value: boolean) => any) | undefined;
13
13
  }>, {
14
+ direction: TipDirection;
14
15
  trigger: "hover" | "click";
15
16
  contentTag: string;
16
17
  visible: boolean;
17
- direction: TipDirection;
18
18
  content: string;
19
19
  alignment: TipAlign;
20
20
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
@@ -21,11 +21,11 @@ declare const __VLS_base: _$vue.DefineComponent<TreeProps, _TreeExposed, {}, {},
21
21
  "onNode-contextmenu"?: ((event: MouseEvent, node: TreeNode<Record<string, any>>) => any) | undefined;
22
22
  "onSelected-synced"?: ((selected?: Record<string, any> | undefined) => any) | undefined;
23
23
  }>, {
24
- data: Record<string, any>[];
25
24
  expandOnClickNode: boolean;
26
25
  labelKey: string;
27
26
  valueKey: string;
28
27
  childrenKey: string;
28
+ data: Record<string, any>[];
29
29
  checkStrictly: boolean;
30
30
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
31
31
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -26,13 +26,13 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
26
26
  }>, {
27
27
  disabled: boolean;
28
28
  readonly: boolean;
29
- minWidth: string;
30
29
  expandAll: boolean;
31
30
  labelKey: string;
32
31
  valueKey: string;
33
32
  placeholder: string;
34
33
  clearable: boolean;
35
34
  filterable: boolean;
35
+ minWidth: string;
36
36
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
37
37
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
38
  declare const _default: typeof __VLS_export;
@@ -1,4 +1,4 @@
1
- import { CSSProperties, ShallowRef } from "vue";
1
+ import { CSSProperties, MaybeRefOrGetter, ShallowRef } from "vue";
2
2
  import { DeconstructValue } from "@veltra/utils";
3
3
 
4
4
  //#region src/types/scroll.d.ts
@@ -41,6 +41,11 @@ interface ScrollProps {
41
41
  containerClass?: string | string[];
42
42
  /** 拖拽防抖时间 */
43
43
  dragDebounce?: number;
44
+ /**
45
+ * 外部滚动容器(如 EmbedPDF Viewport)。
46
+ * 提供时仅渲染自定义滚动条并同步该元素的滚动,不创建内部滚动容器。
47
+ */
48
+ target?: MaybeRefOrGetter<HTMLElement | null | undefined>;
44
49
  }
45
50
  interface ScrollEmits {
46
51
  /** 滚动事件 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltra/desktop",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -54,6 +54,7 @@
54
54
  "@embedpdf/plugin-render": "^2.14.1",
55
55
  "@embedpdf/plugin-scroll": "^2.14.1",
56
56
  "@embedpdf/plugin-viewport": "^2.14.1",
57
+ "@embedpdf/plugin-zoom": "^2.14.1",
57
58
  "@lexical/history": "^0.43.0",
58
59
  "@lexical/html": "^0.43.0",
59
60
  "@lexical/link": "^0.43.0",
@@ -61,22 +62,22 @@
61
62
  "@lexical/rich-text": "^0.43.0",
62
63
  "@lexical/selection": "^0.43.0",
63
64
  "@lexical/utils": "^0.43.0",
64
- "@veltra/compositions": "1.1.12",
65
- "@veltra/directives": "1.1.12",
66
- "@veltra/icons": "1.1.12",
67
- "@veltra/styles": "1.1.12",
68
- "@veltra/utils": "1.1.12",
65
+ "@veltra/compositions": "1.1.13",
66
+ "@veltra/directives": "1.1.13",
67
+ "@veltra/icons": "1.1.13",
68
+ "@veltra/styles": "1.1.13",
69
+ "@veltra/utils": "1.1.13",
69
70
  "@visactor/vtable": "^1.26.0",
70
71
  "codemirror": "^6.0.2",
71
72
  "docx-preview": "^0.3.7",
72
73
  "lexical": "^0.43.0"
73
74
  },
74
75
  "peerDependencies": {
75
- "@veltra/compositions": "1.1.12",
76
- "@veltra/directives": "1.1.12",
77
- "@veltra/icons": "1.1.12",
78
- "@veltra/styles": "1.1.12",
79
- "@veltra/utils": "1.1.12",
76
+ "@veltra/compositions": "1.1.13",
77
+ "@veltra/directives": "1.1.13",
78
+ "@veltra/icons": "1.1.13",
79
+ "@veltra/styles": "1.1.13",
80
+ "@veltra/utils": "1.1.13",
80
81
  "vue": "^3.5.33"
81
82
  }
82
83
  }