@mingto/mt-ui 1.1.42 → 1.1.45

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.
package/dist/index.es.js CHANGED
@@ -4704,6 +4704,9 @@ function useLocale() {
4704
4704
  //#region src/hooks/use-namespace/index.ts
4705
4705
  var defaultNamespace = "mt";
4706
4706
  var statePrefix$1 = "is-";
4707
+ function toKebabCase(key) {
4708
+ return key.replace(/([A-Z])/g, "-$1").toLowerCase();
4709
+ }
4707
4710
  function _bem$1(namespace, block, blockSuffix, element, modifier) {
4708
4711
  let cls = `${namespace}-${block}`;
4709
4712
  if (blockSuffix) cls += `-${blockSuffix}`;
@@ -4733,12 +4736,12 @@ function useNamespace(block, namespaceOverrides) {
4733
4736
  };
4734
4737
  const cssVar = (object) => {
4735
4738
  const styles = {};
4736
- for (const key in object) if (object[key]) styles[`--${namespace.value}-${key}`] = object[key];
4739
+ for (const key in object) if (object[key]) styles[`--${namespace.value}-${toKebabCase(key)}`] = object[key];
4737
4740
  return styles;
4738
4741
  };
4739
4742
  const cssVarBlock = (object) => {
4740
4743
  const styles = {};
4741
- for (const key in object) if (object[key]) styles[`--${namespace.value}-${block}-${key}`] = object[key];
4744
+ for (const key in object) if (object[key]) styles[`--${namespace.value}-${block}-${toKebabCase(key)}`] = object[key];
4742
4745
  return styles;
4743
4746
  };
4744
4747
  const cssVarName = (name) => `--${namespace.value}-${name}`;
@@ -8297,7 +8300,7 @@ var dialog_default = /* @__PURE__ */ defineComponent({
8297
8300
  return (_ctx, _cache) => {
8298
8301
  return openBlock(), createBlock(unref(MtTeleport), { to: props.appendTo }, {
8299
8302
  default: withCtx(() => [createVNode(Transition, {
8300
- name: unref(ns).em("overlay", "fade"),
8303
+ name: `${unref(ns).e("overlay")}-fade`,
8301
8304
  onAfterLeave: handleAfterLeave
8302
8305
  }, {
8303
8306
  default: withCtx(() => [withDirectives(createVNode(unref(MtOverlay), {
@@ -19339,6 +19342,8 @@ var MtTabs = withInstall$1(/* @__PURE__ */ defineComponent({
19339
19342
  const emits = __emit;
19340
19343
  const ns = useNamespace("tabs");
19341
19344
  const tabsRef = ref();
19345
+ const barStyles = ref({});
19346
+ const lineStyles = ref({});
19342
19347
  const currentTabName = computed({
19343
19348
  get() {
19344
19349
  return props.modelValue;
@@ -19353,35 +19358,51 @@ var MtTabs = withInstall$1(/* @__PURE__ */ defineComponent({
19353
19358
  onChange,
19354
19359
  type: props.type
19355
19360
  });
19356
- const barStyles = computed(() => {
19357
- const styles = {};
19358
- if (tabsRef.value) children.forEach((child, index) => {
19359
- const $el = tabsRef.value.querySelector(`#tab-${index}`);
19360
- if (!$el) return;
19361
- if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) return;
19362
- styles.width = `${$el.clientWidth}px`;
19363
- styles.left = `${$el.offsetLeft}px`;
19364
- });
19365
- return styles;
19366
- });
19367
- const lineStyles = computed(() => {
19361
+ function getActiveTabElement() {
19362
+ if (!tabsRef.value) return null;
19363
+ for (let index = 0; index < children.length; index++) {
19364
+ const child = children[index];
19365
+ if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) continue;
19366
+ return tabsRef.value.querySelector(`#tab-${index}`);
19367
+ }
19368
+ return null;
19369
+ }
19370
+ async function updateActiveStyles() {
19371
+ await nextTick();
19372
+ const $el = getActiveTabElement();
19373
+ if (!$el) {
19374
+ barStyles.value = {};
19375
+ lineStyles.value = {};
19376
+ return;
19377
+ }
19378
+ barStyles.value = {
19379
+ width: `${$el.clientWidth}px`,
19380
+ left: `${$el.offsetLeft}px`
19381
+ };
19368
19382
  const styles = {};
19369
- if (tabsRef.value) children.forEach((child, index) => {
19370
- const $el = tabsRef.value.querySelector(`#tab-${index}`);
19371
- if (!$el) return;
19372
- if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) return;
19373
- const tabStyles = window.getComputedStyle($el);
19374
- styles.width = `${$el.clientWidth - beParsedAsNumber(tabStyles.paddingLeft) - beParsedAsNumber(tabStyles.paddingRight)}px`;
19375
- styles.left = `${$el.offsetLeft + beParsedAsNumber(tabStyles.paddingLeft)}px`;
19376
- });
19377
- return styles;
19378
- });
19383
+ const tabStyles = window.getComputedStyle($el);
19384
+ styles.width = `${$el.clientWidth - beParsedAsNumber(tabStyles.paddingLeft) - beParsedAsNumber(tabStyles.paddingRight)}px`;
19385
+ styles.left = `${$el.offsetLeft + beParsedAsNumber(tabStyles.paddingLeft)}px`;
19386
+ lineStyles.value = styles;
19387
+ }
19379
19388
  const tabsClasses = computed(() => {
19380
19389
  return [ns.b(), ns.m(props.type)];
19381
19390
  });
19382
19391
  function onChange(tabName) {
19383
19392
  currentTabName.value = tabName;
19384
19393
  }
19394
+ watch(() => [
19395
+ currentTabName.value,
19396
+ children.length,
19397
+ props.type
19398
+ ], updateActiveStyles, { flush: "post" });
19399
+ onMounted(() => {
19400
+ updateActiveStyles();
19401
+ window.addEventListener("resize", updateActiveStyles);
19402
+ });
19403
+ onBeforeUnmount(() => {
19404
+ window.removeEventListener("resize", updateActiveStyles);
19405
+ });
19385
19406
  return (_ctx, _cache) => {
19386
19407
  return openBlock(), createElementBlock("div", {
19387
19408
  ref_key: "tabsRef",
@@ -20816,10 +20837,88 @@ var upload_image_copper_vue_vue_type_script_setup_true_lang_default = /* @__PURE
20816
20837
  copperPromiseDeferred?.resolve(newFile);
20817
20838
  });
20818
20839
  }
20819
- const isApplyingScale = ref(false);
20820
- async function applyImageScale(url) {
20840
+ function fitSize(maxWidth, maxHeight, aspectRatio) {
20841
+ let width = maxWidth;
20842
+ let height = width / aspectRatio;
20843
+ if (height > maxHeight) {
20844
+ height = maxHeight;
20845
+ width = height * aspectRatio;
20846
+ }
20847
+ return {
20848
+ width: Math.max(Math.round(width), 1),
20849
+ height: Math.max(Math.round(height), 1)
20850
+ };
20851
+ }
20852
+ function getInitialCropSize(image) {
20853
+ const cropper = cropperRef.value;
20854
+ const containerWidth = cropper?.w || 0;
20855
+ const containerHeight = cropper?.h || 0;
20856
+ const maxWidth = containerWidth * .82;
20857
+ const maxHeight = containerHeight * .82;
20858
+ const cropWidth = Number(cropperProps.value.autoCropWidth || 0);
20859
+ const cropHeight = Number(cropperProps.value.autoCropHeight || 0);
20860
+ if (cropWidth > 0 && cropHeight > 0) return {
20861
+ width: Math.min(cropWidth, containerWidth),
20862
+ height: Math.min(cropHeight, containerHeight)
20863
+ };
20864
+ const fixedNumber = cropperProps.value.fixedNumber || [1, 1];
20865
+ const aspectRatio = cropperProps.value.fixed ? fixedNumber[0] / fixedNumber[1] : image.width / image.height;
20866
+ const fittedSize = fitSize(maxWidth, maxHeight, aspectRatio);
20867
+ if (cropWidth > 0) return fitSize(Math.min(cropWidth, containerWidth), maxHeight, aspectRatio);
20868
+ if (cropHeight > 0) return fitSize(maxWidth, Math.min(cropHeight, containerHeight), aspectRatio);
20869
+ return fittedSize;
20870
+ }
20871
+ function centerCropBox(width, height) {
20872
+ const cropper = cropperRef.value;
20873
+ if (!cropper?.goAutoCrop) return;
20874
+ const nextWidth = width || cropper.cropW;
20875
+ const nextHeight = height || cropper.cropH;
20876
+ if (!nextWidth || !nextHeight) return;
20877
+ cropper.goAutoCrop(nextWidth, nextHeight);
20878
+ }
20879
+ function fitImageToCropBox() {
20880
+ const cropper = cropperRef.value;
20881
+ if (!cropper?.trueWidth || !cropper?.trueHeight || !cropper?.cropW || !cropper?.cropH) return;
20882
+ const scale = Math.min(cropper.cropW / cropper.trueWidth, cropper.cropH / cropper.trueHeight);
20883
+ const scaledWidth = cropper.trueWidth * scale;
20884
+ const scaledHeight = cropper.trueHeight * scale;
20885
+ cropper.scale = scale;
20886
+ cropper.x = cropper.cropOffsertX + (cropper.cropW - scaledWidth) / 2 - (cropper.trueWidth - scaledWidth) / 2;
20887
+ cropper.y = cropper.cropOffsertY + (cropper.cropH - scaledHeight) / 2 - (cropper.trueHeight - scaledHeight) / 2;
20888
+ enlarge.value = 1 / scale;
20889
+ }
20890
+ function waitCropperReady() {
20891
+ return new Promise((resolve) => {
20892
+ let observer = null;
20893
+ const cleanup = () => {
20894
+ observer?.disconnect();
20895
+ if (scaleIntervalId) {
20896
+ clearInterval(scaleIntervalId);
20897
+ scaleIntervalId = null;
20898
+ }
20899
+ };
20900
+ const check = () => {
20901
+ const cropper = cropperRef.value;
20902
+ if (cropper?.w && cropper?.h && cropper?.trueWidth && cropper?.trueHeight) {
20903
+ cleanup();
20904
+ resolve();
20905
+ }
20906
+ };
20907
+ observer = new MutationObserver(check);
20908
+ const cropperElement = cropperRef.value?.$el;
20909
+ if (cropperElement) observer.observe(cropperElement, {
20910
+ childList: true,
20911
+ subtree: true,
20912
+ attributes: true
20913
+ });
20914
+ scaleIntervalId = setInterval(check, 50);
20915
+ check();
20916
+ });
20917
+ }
20918
+ const isApplyingInitialCrop = ref(false);
20919
+ async function applyInitialCrop(url) {
20821
20920
  try {
20822
- isApplyingScale.value = true;
20921
+ isApplyingInitialCrop.value = true;
20823
20922
  const image = new Image();
20824
20923
  image.crossOrigin = "anonymous";
20825
20924
  await new Promise((resolve, reject) => {
@@ -20827,54 +20926,18 @@ var upload_image_copper_vue_vue_type_script_setup_true_lang_default = /* @__PURE
20827
20926
  image.onerror = () => reject(/* @__PURE__ */ new Error(`Failed to load image: ${url}`));
20828
20927
  image.src = url;
20829
20928
  });
20830
- await new Promise((resolve) => {
20831
- let observer = null;
20832
- const cleanup = () => {
20833
- observer?.disconnect();
20834
- if (scaleIntervalId) {
20835
- clearInterval(scaleIntervalId);
20836
- scaleIntervalId = null;
20837
- }
20838
- };
20839
- const checkCropper = () => {
20840
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20841
- cleanup();
20842
- resolve();
20843
- return;
20844
- }
20845
- observer = new MutationObserver(() => {
20846
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20847
- cleanup();
20848
- resolve();
20849
- }
20850
- });
20851
- if (cropperRef.value?.$el) observer.observe(cropperRef.value.$el, {
20852
- childList: true,
20853
- subtree: true,
20854
- attributes: true
20855
- });
20856
- scaleIntervalId = setInterval(() => {
20857
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20858
- cleanup();
20859
- resolve();
20860
- }
20861
- }, 50);
20862
- checkCropper();
20863
- };
20864
- checkCropper();
20865
- });
20929
+ await nextTick();
20930
+ await waitCropperReady();
20866
20931
  if (cropperRef.value) {
20867
- const imageNumber = [image.width, image.height];
20868
- const cropNumber = [cropperRef.value.cropW, cropperRef.value.cropH];
20869
- let scale = 1;
20870
- if (imageNumber[0] / imageNumber[1] >= cropNumber[0] / cropNumber[1]) scale = cropNumber[1] / imageNumber[1];
20871
- else scale = cropNumber[0] / imageNumber[0];
20872
- cropperRef.value.scale = scale;
20932
+ const cropSize = getInitialCropSize(image);
20933
+ centerCropBox(cropSize.width, cropSize.height);
20934
+ await nextTick();
20935
+ fitImageToCropBox();
20873
20936
  }
20874
20937
  } catch (error) {
20875
- console.error("应用图片缩放失败:", error);
20938
+ console.error("应用初始裁剪框失败:", error);
20876
20939
  } finally {
20877
- isApplyingScale.value = false;
20940
+ isApplyingInitialCrop.value = false;
20878
20941
  }
20879
20942
  }
20880
20943
  __expose({
@@ -20893,7 +20956,7 @@ var upload_image_copper_vue_vue_type_script_setup_true_lang_default = /* @__PURE
20893
20956
  }
20894
20957
  dialogVisible.value = true;
20895
20958
  copperPromiseDeferred = new Deferred();
20896
- if (cropperProps.value.autoCropScale) applyImageScale(filePath.value);
20959
+ if (cropperProps.value.autoCropScale) applyInitialCrop(filePath.value);
20897
20960
  const newFile = await copperPromiseDeferred.promise;
20898
20961
  copperPromiseDeferred = null;
20899
20962
  URL.revokeObjectURL(filePath.value);
@@ -20919,7 +20982,7 @@ var upload_image_copper_vue_vue_type_script_setup_true_lang_default = /* @__PURE
20919
20982
  }, {
20920
20983
  default: withCtx(() => [createVNode(unref(MtDialogConfirmLayout), {
20921
20984
  loading: loading.value,
20922
- disabled: isApplyingScale.value,
20985
+ disabled: isApplyingInitialCrop.value,
20923
20986
  "confirm-text": unref(t)("mt.upload.confirm"),
20924
20987
  "cancel-text": unref(t)("mt.upload.cancel"),
20925
20988
  onCancel: handleCancel,
@@ -20928,7 +20991,7 @@ var upload_image_copper_vue_vue_type_script_setup_true_lang_default = /* @__PURE
20928
20991
  default: withCtx(() => [filePath.value ? (openBlock(), createElementBlock("div", {
20929
20992
  key: 0,
20930
20993
  class: normalizeClass(unref(ns).e("content"))
20931
- }, [isApplyingScale.value ? (openBlock(), createElementBlock("div", {
20994
+ }, [isApplyingInitialCrop.value ? (openBlock(), createElementBlock("div", {
20932
20995
  key: 0,
20933
20996
  class: normalizeClass(unref(ns).e("loading"))
20934
20997
  }, [createVNode(unref(MtLoading), { size: 80 })], 2)) : createCommentVNode("", true), createVNode(unref(M), mergeProps({
@@ -20965,7 +21028,7 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
20965
21028
  };
20966
21029
  //#endregion
20967
21030
  //#region src/upload/src/upload-image-copper.vue
20968
- var upload_image_copper_default = /* @__PURE__ */ _plugin_vue_export_helper_default(upload_image_copper_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-01619ce0"]]);
21031
+ var upload_image_copper_default = /* @__PURE__ */ _plugin_vue_export_helper_default(upload_image_copper_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-47a8b76d"]]);
20969
21032
  //#endregion
20970
21033
  //#region src/upload/src/layout/upload-image-grid-layout.vue
20971
21034
  var upload_image_grid_layout_default = /* @__PURE__ */ defineComponent({
package/dist/index.umd.js CHANGED
@@ -4733,6 +4733,9 @@
4733
4733
  //#region src/hooks/use-namespace/index.ts
4734
4734
  var defaultNamespace = "mt";
4735
4735
  var statePrefix$1 = "is-";
4736
+ function toKebabCase(key) {
4737
+ return key.replace(/([A-Z])/g, "-$1").toLowerCase();
4738
+ }
4736
4739
  function _bem$1(namespace, block, blockSuffix, element, modifier) {
4737
4740
  let cls = `${namespace}-${block}`;
4738
4741
  if (blockSuffix) cls += `-${blockSuffix}`;
@@ -4762,12 +4765,12 @@
4762
4765
  };
4763
4766
  const cssVar = (object) => {
4764
4767
  const styles = {};
4765
- for (const key in object) if (object[key]) styles[`--${namespace.value}-${key}`] = object[key];
4768
+ for (const key in object) if (object[key]) styles[`--${namespace.value}-${toKebabCase(key)}`] = object[key];
4766
4769
  return styles;
4767
4770
  };
4768
4771
  const cssVarBlock = (object) => {
4769
4772
  const styles = {};
4770
- for (const key in object) if (object[key]) styles[`--${namespace.value}-${block}-${key}`] = object[key];
4773
+ for (const key in object) if (object[key]) styles[`--${namespace.value}-${block}-${toKebabCase(key)}`] = object[key];
4771
4774
  return styles;
4772
4775
  };
4773
4776
  const cssVarName = (name) => `--${namespace.value}-${name}`;
@@ -8352,7 +8355,7 @@
8352
8355
  return (_ctx, _cache) => {
8353
8356
  return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(MtTeleport), { to: props.appendTo }, {
8354
8357
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)(vue.Transition, {
8355
- name: (0, vue.unref)(ns).em("overlay", "fade"),
8358
+ name: `${(0, vue.unref)(ns).e("overlay")}-fade`,
8356
8359
  onAfterLeave: handleAfterLeave
8357
8360
  }, {
8358
8361
  default: (0, vue.withCtx)(() => [(0, vue.withDirectives)((0, vue.createVNode)((0, vue.unref)(MtOverlay), {
@@ -19413,6 +19416,8 @@ triggerRef });
19413
19416
  const emits = __emit;
19414
19417
  const ns = useNamespace("tabs");
19415
19418
  const tabsRef = (0, vue.ref)();
19419
+ const barStyles = (0, vue.ref)({});
19420
+ const lineStyles = (0, vue.ref)({});
19416
19421
  const currentTabName = (0, vue.computed)({
19417
19422
  get() {
19418
19423
  return props.modelValue;
@@ -19427,35 +19432,51 @@ triggerRef });
19427
19432
  onChange,
19428
19433
  type: props.type
19429
19434
  });
19430
- const barStyles = (0, vue.computed)(() => {
19431
- const styles = {};
19432
- if (tabsRef.value) children.forEach((child, index) => {
19433
- const $el = tabsRef.value.querySelector(`#tab-${index}`);
19434
- if (!$el) return;
19435
- if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) return;
19436
- styles.width = `${$el.clientWidth}px`;
19437
- styles.left = `${$el.offsetLeft}px`;
19438
- });
19439
- return styles;
19440
- });
19441
- const lineStyles = (0, vue.computed)(() => {
19435
+ function getActiveTabElement() {
19436
+ if (!tabsRef.value) return null;
19437
+ for (let index = 0; index < children.length; index++) {
19438
+ const child = children[index];
19439
+ if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) continue;
19440
+ return tabsRef.value.querySelector(`#tab-${index}`);
19441
+ }
19442
+ return null;
19443
+ }
19444
+ async function updateActiveStyles() {
19445
+ await (0, vue.nextTick)();
19446
+ const $el = getActiveTabElement();
19447
+ if (!$el) {
19448
+ barStyles.value = {};
19449
+ lineStyles.value = {};
19450
+ return;
19451
+ }
19452
+ barStyles.value = {
19453
+ width: `${$el.clientWidth}px`,
19454
+ left: `${$el.offsetLeft}px`
19455
+ };
19442
19456
  const styles = {};
19443
- if (tabsRef.value) children.forEach((child, index) => {
19444
- const $el = tabsRef.value.querySelector(`#tab-${index}`);
19445
- if (!$el) return;
19446
- if (!child.exposed || !isTabContext(child.exposed) || !child.exposed.isActive.value) return;
19447
- const tabStyles = window.getComputedStyle($el);
19448
- styles.width = `${$el.clientWidth - (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingLeft) - (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingRight)}px`;
19449
- styles.left = `${$el.offsetLeft + (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingLeft)}px`;
19450
- });
19451
- return styles;
19452
- });
19457
+ const tabStyles = window.getComputedStyle($el);
19458
+ styles.width = `${$el.clientWidth - (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingLeft) - (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingRight)}px`;
19459
+ styles.left = `${$el.offsetLeft + (0, _mingto_tools.beParsedAsNumber)(tabStyles.paddingLeft)}px`;
19460
+ lineStyles.value = styles;
19461
+ }
19453
19462
  const tabsClasses = (0, vue.computed)(() => {
19454
19463
  return [ns.b(), ns.m(props.type)];
19455
19464
  });
19456
19465
  function onChange(tabName) {
19457
19466
  currentTabName.value = tabName;
19458
19467
  }
19468
+ (0, vue.watch)(() => [
19469
+ currentTabName.value,
19470
+ children.length,
19471
+ props.type
19472
+ ], updateActiveStyles, { flush: "post" });
19473
+ (0, vue.onMounted)(() => {
19474
+ updateActiveStyles();
19475
+ window.addEventListener("resize", updateActiveStyles);
19476
+ });
19477
+ (0, vue.onBeforeUnmount)(() => {
19478
+ window.removeEventListener("resize", updateActiveStyles);
19479
+ });
19459
19480
  return (_ctx, _cache) => {
19460
19481
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
19461
19482
  ref_key: "tabsRef",
@@ -20894,10 +20915,88 @@ triggerRef });
20894
20915
  copperPromiseDeferred?.resolve(newFile);
20895
20916
  });
20896
20917
  }
20897
- const isApplyingScale = (0, vue.ref)(false);
20898
- async function applyImageScale(url) {
20918
+ function fitSize(maxWidth, maxHeight, aspectRatio) {
20919
+ let width = maxWidth;
20920
+ let height = width / aspectRatio;
20921
+ if (height > maxHeight) {
20922
+ height = maxHeight;
20923
+ width = height * aspectRatio;
20924
+ }
20925
+ return {
20926
+ width: Math.max(Math.round(width), 1),
20927
+ height: Math.max(Math.round(height), 1)
20928
+ };
20929
+ }
20930
+ function getInitialCropSize(image) {
20931
+ const cropper = cropperRef.value;
20932
+ const containerWidth = cropper?.w || 0;
20933
+ const containerHeight = cropper?.h || 0;
20934
+ const maxWidth = containerWidth * .82;
20935
+ const maxHeight = containerHeight * .82;
20936
+ const cropWidth = Number(cropperProps.value.autoCropWidth || 0);
20937
+ const cropHeight = Number(cropperProps.value.autoCropHeight || 0);
20938
+ if (cropWidth > 0 && cropHeight > 0) return {
20939
+ width: Math.min(cropWidth, containerWidth),
20940
+ height: Math.min(cropHeight, containerHeight)
20941
+ };
20942
+ const fixedNumber = cropperProps.value.fixedNumber || [1, 1];
20943
+ const aspectRatio = cropperProps.value.fixed ? fixedNumber[0] / fixedNumber[1] : image.width / image.height;
20944
+ const fittedSize = fitSize(maxWidth, maxHeight, aspectRatio);
20945
+ if (cropWidth > 0) return fitSize(Math.min(cropWidth, containerWidth), maxHeight, aspectRatio);
20946
+ if (cropHeight > 0) return fitSize(maxWidth, Math.min(cropHeight, containerHeight), aspectRatio);
20947
+ return fittedSize;
20948
+ }
20949
+ function centerCropBox(width, height) {
20950
+ const cropper = cropperRef.value;
20951
+ if (!cropper?.goAutoCrop) return;
20952
+ const nextWidth = width || cropper.cropW;
20953
+ const nextHeight = height || cropper.cropH;
20954
+ if (!nextWidth || !nextHeight) return;
20955
+ cropper.goAutoCrop(nextWidth, nextHeight);
20956
+ }
20957
+ function fitImageToCropBox() {
20958
+ const cropper = cropperRef.value;
20959
+ if (!cropper?.trueWidth || !cropper?.trueHeight || !cropper?.cropW || !cropper?.cropH) return;
20960
+ const scale = Math.min(cropper.cropW / cropper.trueWidth, cropper.cropH / cropper.trueHeight);
20961
+ const scaledWidth = cropper.trueWidth * scale;
20962
+ const scaledHeight = cropper.trueHeight * scale;
20963
+ cropper.scale = scale;
20964
+ cropper.x = cropper.cropOffsertX + (cropper.cropW - scaledWidth) / 2 - (cropper.trueWidth - scaledWidth) / 2;
20965
+ cropper.y = cropper.cropOffsertY + (cropper.cropH - scaledHeight) / 2 - (cropper.trueHeight - scaledHeight) / 2;
20966
+ enlarge.value = 1 / scale;
20967
+ }
20968
+ function waitCropperReady() {
20969
+ return new Promise((resolve) => {
20970
+ let observer = null;
20971
+ const cleanup = () => {
20972
+ observer?.disconnect();
20973
+ if (scaleIntervalId) {
20974
+ clearInterval(scaleIntervalId);
20975
+ scaleIntervalId = null;
20976
+ }
20977
+ };
20978
+ const check = () => {
20979
+ const cropper = cropperRef.value;
20980
+ if (cropper?.w && cropper?.h && cropper?.trueWidth && cropper?.trueHeight) {
20981
+ cleanup();
20982
+ resolve();
20983
+ }
20984
+ };
20985
+ observer = new MutationObserver(check);
20986
+ const cropperElement = cropperRef.value?.$el;
20987
+ if (cropperElement) observer.observe(cropperElement, {
20988
+ childList: true,
20989
+ subtree: true,
20990
+ attributes: true
20991
+ });
20992
+ scaleIntervalId = setInterval(check, 50);
20993
+ check();
20994
+ });
20995
+ }
20996
+ const isApplyingInitialCrop = (0, vue.ref)(false);
20997
+ async function applyInitialCrop(url) {
20899
20998
  try {
20900
- isApplyingScale.value = true;
20999
+ isApplyingInitialCrop.value = true;
20901
21000
  const image = new Image();
20902
21001
  image.crossOrigin = "anonymous";
20903
21002
  await new Promise((resolve, reject) => {
@@ -20905,54 +21004,18 @@ triggerRef });
20905
21004
  image.onerror = () => reject(/* @__PURE__ */ new Error(`Failed to load image: ${url}`));
20906
21005
  image.src = url;
20907
21006
  });
20908
- await new Promise((resolve) => {
20909
- let observer = null;
20910
- const cleanup = () => {
20911
- observer?.disconnect();
20912
- if (scaleIntervalId) {
20913
- clearInterval(scaleIntervalId);
20914
- scaleIntervalId = null;
20915
- }
20916
- };
20917
- const checkCropper = () => {
20918
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20919
- cleanup();
20920
- resolve();
20921
- return;
20922
- }
20923
- observer = new MutationObserver(() => {
20924
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20925
- cleanup();
20926
- resolve();
20927
- }
20928
- });
20929
- if (cropperRef.value?.$el) observer.observe(cropperRef.value.$el, {
20930
- childList: true,
20931
- subtree: true,
20932
- attributes: true
20933
- });
20934
- scaleIntervalId = setInterval(() => {
20935
- if (cropperRef.value && cropperRef.value.cropW && cropperRef.value.cropH) {
20936
- cleanup();
20937
- resolve();
20938
- }
20939
- }, 50);
20940
- checkCropper();
20941
- };
20942
- checkCropper();
20943
- });
21007
+ await (0, vue.nextTick)();
21008
+ await waitCropperReady();
20944
21009
  if (cropperRef.value) {
20945
- const imageNumber = [image.width, image.height];
20946
- const cropNumber = [cropperRef.value.cropW, cropperRef.value.cropH];
20947
- let scale = 1;
20948
- if (imageNumber[0] / imageNumber[1] >= cropNumber[0] / cropNumber[1]) scale = cropNumber[1] / imageNumber[1];
20949
- else scale = cropNumber[0] / imageNumber[0];
20950
- cropperRef.value.scale = scale;
21010
+ const cropSize = getInitialCropSize(image);
21011
+ centerCropBox(cropSize.width, cropSize.height);
21012
+ await (0, vue.nextTick)();
21013
+ fitImageToCropBox();
20951
21014
  }
20952
21015
  } catch (error) {
20953
- console.error("应用图片缩放失败:", error);
21016
+ console.error("应用初始裁剪框失败:", error);
20954
21017
  } finally {
20955
- isApplyingScale.value = false;
21018
+ isApplyingInitialCrop.value = false;
20956
21019
  }
20957
21020
  }
20958
21021
  __expose({
@@ -20971,7 +21034,7 @@ triggerRef });
20971
21034
  }
20972
21035
  dialogVisible.value = true;
20973
21036
  copperPromiseDeferred = new Deferred();
20974
- if (cropperProps.value.autoCropScale) applyImageScale(filePath.value);
21037
+ if (cropperProps.value.autoCropScale) applyInitialCrop(filePath.value);
20975
21038
  const newFile = await copperPromiseDeferred.promise;
20976
21039
  copperPromiseDeferred = null;
20977
21040
  URL.revokeObjectURL(filePath.value);
@@ -20997,7 +21060,7 @@ triggerRef });
20997
21060
  }, {
20998
21061
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(MtDialogConfirmLayout), {
20999
21062
  loading: loading.value,
21000
- disabled: isApplyingScale.value,
21063
+ disabled: isApplyingInitialCrop.value,
21001
21064
  "confirm-text": (0, vue.unref)(t)("mt.upload.confirm"),
21002
21065
  "cancel-text": (0, vue.unref)(t)("mt.upload.cancel"),
21003
21066
  onCancel: handleCancel,
@@ -21006,7 +21069,7 @@ triggerRef });
21006
21069
  default: (0, vue.withCtx)(() => [filePath.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
21007
21070
  key: 0,
21008
21071
  class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("content"))
21009
- }, [isApplyingScale.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
21072
+ }, [isApplyingInitialCrop.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
21010
21073
  key: 0,
21011
21074
  class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("loading"))
21012
21075
  }, [(0, vue.createVNode)((0, vue.unref)(MtLoading), { size: 80 })], 2)) : (0, vue.createCommentVNode)("", true), (0, vue.createVNode)((0, vue.unref)(M), (0, vue.mergeProps)({
@@ -21043,7 +21106,7 @@ triggerRef });
21043
21106
  };
21044
21107
  //#endregion
21045
21108
  //#region src/upload/src/upload-image-copper.vue
21046
- var upload_image_copper_default = /* @__PURE__ */ _plugin_vue_export_helper_default(upload_image_copper_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-01619ce0"]]);
21109
+ var upload_image_copper_default = /* @__PURE__ */ _plugin_vue_export_helper_default(upload_image_copper_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-47a8b76d"]]);
21047
21110
  //#endregion
21048
21111
  //#region src/upload/src/layout/upload-image-grid-layout.vue
21049
21112
  var upload_image_grid_layout_default = /* @__PURE__ */ (0, vue.defineComponent)({
package/dist/style.css CHANGED
@@ -3468,6 +3468,7 @@
3468
3468
  }
3469
3469
  .mt-tab--card.is-active {
3470
3470
  color: var(--mt-color-blue-5d89f7);
3471
+ background-color: var(--mt-color-white-ffffff);
3471
3472
  }
3472
3473
  .mt-tab--line {
3473
3474
  height: 40px;
@@ -3631,12 +3632,12 @@
3631
3632
  .mt-upload-file-list-layout--empty {
3632
3633
  margin-bottom: 0;
3633
3634
  }.vue-cropper[data-v-a742df44]{position:relative;width:100%;height:100%;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;direction:ltr;touch-action:none;text-align:left;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-box[data-v-a742df44],.cropper-box-canvas[data-v-a742df44],.cropper-drag-box[data-v-a742df44],.cropper-crop-box[data-v-a742df44],.cropper-face[data-v-a742df44]{position:absolute;top:0;right:0;bottom:0;left:0;-webkit-user-select:none;user-select:none}.cropper-box-canvas img[data-v-a742df44]{position:relative;text-align:left;-webkit-user-select:none;user-select:none;transform:none;max-width:none;max-height:none}.cropper-box[data-v-a742df44]{overflow:hidden}.cropper-move[data-v-a742df44]{cursor:move}.cropper-crop[data-v-a742df44]{cursor:crosshair}.cropper-modal[data-v-a742df44]{background:rgba(0,0,0,.5)}.cropper-view-box[data-v-a742df44]{display:block;overflow:hidden;width:100%;height:100%;outline:1px solid #39f;outline-color:#3399ffbf;-webkit-user-select:none;user-select:none}.cropper-view-box img[data-v-a742df44]{-webkit-user-select:none;user-select:none;text-align:left;max-width:none;max-height:none}.cropper-face[data-v-a742df44]{top:0;left:0;background-color:#fff;opacity:.1}.crop-info[data-v-a742df44]{position:absolute;left:0;min-width:65px;text-align:center;color:#fff;line-height:20px;background-color:#000c;font-size:12px}.crop-line[data-v-a742df44]{position:absolute;display:block;width:100%;height:100%;opacity:.1}.line-w[data-v-a742df44]{top:-3px;left:0;height:5px;cursor:n-resize}.line-a[data-v-a742df44]{top:0;left:-3px;width:5px;cursor:w-resize}.line-s[data-v-a742df44]{bottom:-3px;left:0;height:5px;cursor:s-resize}.line-d[data-v-a742df44]{top:0;right:-3px;width:5px;cursor:e-resize}.crop-point[data-v-a742df44]{position:absolute;width:8px;height:8px;opacity:.75;background-color:#39f;border-radius:100%}.point1[data-v-a742df44]{top:-4px;left:-4px;cursor:nw-resize}.point2[data-v-a742df44]{top:-5px;left:50%;margin-left:-3px;cursor:n-resize}.point3[data-v-a742df44]{top:-4px;right:-4px;cursor:ne-resize}.point4[data-v-a742df44]{top:50%;left:-4px;margin-top:-3px;cursor:w-resize}.point5[data-v-a742df44]{top:50%;right:-4px;margin-top:-3px;cursor:e-resize}.point6[data-v-a742df44]{bottom:-5px;left:-4px;cursor:sw-resize}.point7[data-v-a742df44]{bottom:-5px;left:50%;margin-left:-3px;cursor:s-resize}.point8[data-v-a742df44]{bottom:-5px;right:-4px;cursor:se-resize}@media screen and (max-width: 500px){.crop-point[data-v-a742df44]{position:absolute;width:20px;height:20px;opacity:.45;background-color:#39f;border-radius:100%}.point1[data-v-a742df44]{top:-10px;left:-10px}.point2[data-v-a742df44],.point4[data-v-a742df44],.point5[data-v-a742df44],.point7[data-v-a742df44]{display:none}.point3[data-v-a742df44]{top:-10px;right:-10px}.point4[data-v-a742df44]{top:0;left:0}.point6[data-v-a742df44]{bottom:-10px;left:-10px}.point8[data-v-a742df44]{bottom:-10px;right:-10px}}
3634
- .mt-image-copper__content[data-v-01619ce0] {
3635
+ .mt-image-copper__content[data-v-47a8b76d] {
3635
3636
  position: relative;
3636
3637
  width: 80vh;
3637
3638
  height: 80vh;
3638
3639
  }
3639
- .mt-image-copper__loading[data-v-01619ce0] {
3640
+ .mt-image-copper__loading[data-v-47a8b76d] {
3640
3641
  position: absolute;
3641
3642
  top: 0;
3642
3643
  left: 0;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mingto/mt-ui",
3
3
  "type": "module",
4
- "version": "1.1.42",
4
+ "version": "1.1.45",
5
5
  "description": "UI组件库",
6
6
  "publishConfig": {
7
7
  "access": "public"