fantasia-ui 0.3.1 → 0.3.3

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.
@@ -5859,46 +5859,41 @@
5859
5859
 
5860
5860
  .f-table {
5861
5861
  position: relative;
5862
+ display: flex;
5863
+ flex-direction: column;
5862
5864
  border: 1px solid #e2e8f0;
5863
5865
  border-radius: 6px;
5864
5866
  overflow: hidden;
5865
5867
  min-height: 14rem;
5866
5868
  }
5867
- .f-table__loading {
5868
- position: absolute;
5869
- inset: 0;
5870
- background: rgba(255, 255, 255, 0.7);
5871
- backdrop-filter: blur(2px);
5872
- display: flex;
5873
- justify-content: center;
5874
- align-items: center;
5875
- flex-direction: column;
5876
- gap: 0.625rem;
5877
- z-index: 10;
5878
- }
5879
5869
  .f-table__scroll {
5880
5870
  position: relative;
5871
+ flex: 1;
5872
+ min-height: 0;
5881
5873
  width: 100%;
5882
- height: 100%;
5883
5874
  overflow: auto;
5884
5875
  }
5885
5876
  .f-table__inner {
5886
5877
  width: 100%;
5878
+ min-width: 100%;
5887
5879
  border-collapse: collapse;
5888
5880
  font-size: 0.75rem;
5889
5881
  text-align: left;
5890
5882
  table-layout: auto;
5891
- min-width: 100%;
5892
5883
  }
5893
5884
  .f-table__inner th,
5894
5885
  .f-table__inner td {
5895
- padding: 0.625rem;
5886
+ padding: 0 0.625rem;
5896
5887
  border-right: 1px solid #e2e8f0;
5897
5888
  }
5898
5889
  .f-table__inner th:last-child,
5899
5890
  .f-table__inner td:last-child {
5900
5891
  border-right: none;
5901
5892
  }
5893
+ .f-table__inner th {
5894
+ padding-top: 0.625rem;
5895
+ padding-bottom: 0.625rem;
5896
+ }
5902
5897
  .f-table__col--index {
5903
5898
  width: 3rem;
5904
5899
  }
@@ -5946,6 +5941,12 @@
5946
5941
  font-weight: 800;
5947
5942
  color: #64748b;
5948
5943
  }
5944
+ .f-table__text {
5945
+ display: block;
5946
+ overflow: hidden;
5947
+ text-overflow: ellipsis;
5948
+ white-space: nowrap;
5949
+ }
5949
5950
  .f-table__spacer td {
5950
5951
  padding: 0;
5951
5952
  border: none;
@@ -5957,6 +5958,26 @@
5957
5958
  font-weight: 700;
5958
5959
  background: rgba(248, 250, 252, 0.5);
5959
5960
  }
5961
+ .f-table__tip {
5962
+ position: fixed;
5963
+ z-index: 3000;
5964
+ max-width: 320px;
5965
+ padding: 6px 10px;
5966
+ border-radius: 6px;
5967
+ background: rgba(15, 23, 42, 0.96);
5968
+ color: #f8fafc;
5969
+ font-size: 12px;
5970
+ line-height: 1.5;
5971
+ word-break: break-all;
5972
+ pointer-events: none;
5973
+ box-shadow: 0 8px 18px rgba(15, 23, 42, 0.18);
5974
+ }
5975
+ .f-table__tip.is-top {
5976
+ transform: translate(-50%, -100%);
5977
+ }
5978
+ .f-table__tip.is-bottom {
5979
+ transform: translate(-50%, 0);
5980
+ }
5960
5981
 
5961
5982
  .f-tabs {
5962
5983
  width: 100%;
@@ -7521,10 +7542,10 @@ to {
7521
7542
  .f-tag--plain.default[data-v-19e20dd3] {
7522
7543
  color: var(--text-muted);
7523
7544
  border: 1px solid var(--border2);
7524
- }.f-tooltip[data-v-37ae9256] {
7545
+ }.f-tooltip[data-v-398a5be6] {
7525
7546
  display: contents;
7526
7547
  }
7527
- .f-tooltip-wrapper[data-v-37ae9256] {
7548
+ .f-tooltip-wrapper[data-v-398a5be6] {
7528
7549
  position: fixed;
7529
7550
  z-index: 999;
7530
7551
  padding: 5px 9px;
@@ -7539,7 +7560,7 @@ to {
7539
7560
  word-break: break-word;
7540
7561
  white-space: pre-wrap;
7541
7562
  }
7542
- .f-tooltip-wrapper .f-tooltip-arrow[data-v-37ae9256] {
7563
+ .f-tooltip-wrapper .f-tooltip-arrow[data-v-398a5be6] {
7543
7564
  position: absolute;
7544
7565
  width: 6px;
7545
7566
  height: 6px;
@@ -7548,32 +7569,32 @@ to {
7548
7569
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
7549
7570
  transform: rotate(45deg);
7550
7571
  }
7551
- .f-tooltip-wrapper.is-top .f-tooltip-arrow[data-v-37ae9256] {
7572
+ .f-tooltip-wrapper.is-top .f-tooltip-arrow[data-v-398a5be6] {
7552
7573
  bottom: -3px;
7553
7574
  left: 50%;
7554
7575
  translate: -50% 0;
7555
7576
  }
7556
- .f-tooltip-wrapper.is-bottom .f-tooltip-arrow[data-v-37ae9256] {
7577
+ .f-tooltip-wrapper.is-bottom .f-tooltip-arrow[data-v-398a5be6] {
7557
7578
  top: -3px;
7558
7579
  left: 50%;
7559
7580
  translate: -50% 0;
7560
7581
  }
7561
- .f-tooltip-wrapper.is-left .f-tooltip-arrow[data-v-37ae9256] {
7582
+ .f-tooltip-wrapper.is-left .f-tooltip-arrow[data-v-398a5be6] {
7562
7583
  right: -3px;
7563
7584
  top: 50%;
7564
7585
  translate: 0 -50%;
7565
7586
  }
7566
- .f-tooltip-wrapper.is-right .f-tooltip-arrow[data-v-37ae9256] {
7587
+ .f-tooltip-wrapper.is-right .f-tooltip-arrow[data-v-398a5be6] {
7567
7588
  left: -3px;
7568
7589
  top: 50%;
7569
7590
  translate: 0 -50%;
7570
7591
  }
7571
- .f-tooltip-enter-active[data-v-37ae9256],
7572
- .f-tooltip-leave-active[data-v-37ae9256] {
7592
+ .f-tooltip-enter-active[data-v-398a5be6],
7593
+ .f-tooltip-leave-active[data-v-398a5be6] {
7573
7594
  transition: opacity 0.15s ease, transform 0.15s ease;
7574
7595
  }
7575
- .f-tooltip-enter-from[data-v-37ae9256],
7576
- .f-tooltip-leave-to[data-v-37ae9256] {
7596
+ .f-tooltip-enter-from[data-v-398a5be6],
7597
+ .f-tooltip-leave-to[data-v-398a5be6] {
7577
7598
  opacity: 0;
7578
7599
  transform: scale(0.92);
7579
7600
  }.f-progress[data-v-95060470] {
@@ -10511,47 +10532,47 @@ to {
10511
10532
  }
10512
10533
  .f-form--size-large[data-v-7e90ebac] {
10513
10534
  gap: 24px;
10514
- }.f-form-item[data-v-42312371] {
10535
+ }.f-form-item[data-v-c1ead052] {
10515
10536
  display: flex;
10516
10537
  font-size: 12px;
10517
10538
  margin-bottom: 18px;
10518
10539
  }
10519
- .f-form-item.is-label-top[data-v-42312371] {
10540
+ .f-form-item.is-label-top[data-v-c1ead052] {
10520
10541
  flex-direction: column;
10521
10542
  }
10522
- .f-form-item.is-label-top .f-form-item__label[data-v-42312371] {
10543
+ .f-form-item.is-label-top .f-form-item__label[data-v-c1ead052] {
10523
10544
  margin-bottom: 6px;
10524
10545
  }
10525
- .f-form-item.is-label-left[data-v-42312371], .f-form-item.is-label-right[data-v-42312371] {
10546
+ .f-form-item.is-label-left[data-v-c1ead052], .f-form-item.is-label-right[data-v-c1ead052] {
10526
10547
  flex-direction: row;
10527
10548
  align-items: flex-start;
10528
10549
  }
10529
- .f-form-item.is-label-left .f-form-item__label[data-v-42312371], .f-form-item.is-label-right .f-form-item__label[data-v-42312371] {
10550
+ .f-form-item.is-label-left .f-form-item__label[data-v-c1ead052], .f-form-item.is-label-right .f-form-item__label[data-v-c1ead052] {
10530
10551
  margin-right: 12px;
10531
10552
  padding-top: 8px;
10532
10553
  flex-shrink: 0;
10533
10554
  }
10534
- .f-form-item.is-size-small .f-form-item__label[data-v-42312371] {
10555
+ .f-form-item.is-size-small .f-form-item__label[data-v-c1ead052] {
10535
10556
  font-size: 12px;
10536
10557
  }
10537
- .f-form-item.is-size-large .f-form-item__label[data-v-42312371] {
10558
+ .f-form-item.is-size-large .f-form-item__label[data-v-c1ead052] {
10538
10559
  font-size: 16px;
10539
10560
  }
10540
- .f-form-item__label[data-v-42312371] {
10561
+ .f-form-item__label[data-v-c1ead052] {
10541
10562
  color: #374151;
10542
10563
  font-size: 13px;
10543
10564
  font-weight: 500;
10544
10565
  }
10545
- .f-form-item__label .star[data-v-42312371] {
10566
+ .f-form-item__label .star[data-v-c1ead052] {
10546
10567
  color: #f43f5e;
10547
10568
  margin-right: 2px;
10548
10569
  }
10549
- .f-form-item__content[data-v-42312371] {
10570
+ .f-form-item__content[data-v-c1ead052] {
10550
10571
  flex: 1;
10551
10572
  min-width: 0;
10552
10573
  position: relative;
10553
10574
  }
10554
- .f-form-item__error[data-v-42312371] {
10575
+ .f-form-item__error[data-v-c1ead052] {
10555
10576
  position: absolute;
10556
10577
  top: 100%;
10557
10578
  left: 4px;
@@ -10560,12 +10581,12 @@ to {
10560
10581
  margin-top: 2px;
10561
10582
  line-height: 1.4;
10562
10583
  }
10563
- .err-slide-enter-active[data-v-42312371],
10564
- .err-slide-leave-active[data-v-42312371] {
10584
+ .err-slide-enter-active[data-v-c1ead052],
10585
+ .err-slide-leave-active[data-v-c1ead052] {
10565
10586
  transition: opacity 0.2s ease, transform 0.2s ease;
10566
10587
  }
10567
- .err-slide-enter-from[data-v-42312371],
10568
- .err-slide-leave-to[data-v-42312371] {
10588
+ .err-slide-enter-from[data-v-c1ead052],
10589
+ .err-slide-leave-to[data-v-c1ead052] {
10569
10590
  opacity: 0;
10570
10591
  transform: translateY(-4px);
10571
10592
  }.f-checkbox[data-v-eeeb70b5] {
@@ -11242,105 +11263,126 @@ to {
11242
11263
  .f-editor__textarea[data-v-48883044]::placeholder {
11243
11264
  color: #475569;
11244
11265
  opacity: 0.7;
11245
- }.f-table[data-v-ce2c2d93] {
11266
+ }.f-table[data-v-5ae2ec2c] {
11246
11267
  position: relative;
11268
+ display: flex;
11269
+ flex-direction: column;
11247
11270
  border: 1px solid #e2e8f0;
11248
11271
  border-radius: 6px;
11249
11272
  overflow: hidden;
11250
11273
  min-height: 14rem;
11251
11274
  }
11252
- .f-table__loading[data-v-ce2c2d93] {
11253
- position: absolute;
11254
- inset: 0;
11255
- background: rgba(255, 255, 255, 0.7);
11256
- backdrop-filter: blur(2px);
11257
- display: flex;
11258
- justify-content: center;
11259
- align-items: center;
11260
- flex-direction: column;
11261
- gap: 0.625rem;
11262
- z-index: 10;
11263
- }
11264
- .f-table__scroll[data-v-ce2c2d93] {
11275
+ .f-table__scroll[data-v-5ae2ec2c] {
11265
11276
  position: relative;
11277
+ flex: 1;
11278
+ min-height: 0;
11266
11279
  width: 100%;
11267
- height: 100%;
11268
11280
  overflow: auto;
11269
11281
  }
11270
- .f-table__inner[data-v-ce2c2d93] {
11282
+ .f-table__inner[data-v-5ae2ec2c] {
11271
11283
  width: 100%;
11284
+ min-width: 100%;
11272
11285
  border-collapse: collapse;
11273
11286
  font-size: 0.75rem;
11274
11287
  text-align: left;
11275
11288
  table-layout: auto;
11276
- min-width: 100%;
11277
11289
  }
11278
- .f-table__inner th[data-v-ce2c2d93],
11279
- .f-table__inner td[data-v-ce2c2d93] {
11280
- padding: 0.625rem;
11290
+ .f-table__inner th[data-v-5ae2ec2c],
11291
+ .f-table__inner td[data-v-5ae2ec2c] {
11292
+ padding: 0 0.625rem;
11281
11293
  border-right: 1px solid #e2e8f0;
11282
11294
  }
11283
- .f-table__inner th[data-v-ce2c2d93]:last-child,
11284
- .f-table__inner td[data-v-ce2c2d93]:last-child {
11295
+ .f-table__inner th[data-v-5ae2ec2c]:last-child,
11296
+ .f-table__inner td[data-v-5ae2ec2c]:last-child {
11285
11297
  border-right: none;
11286
11298
  }
11287
- .f-table__col--index[data-v-ce2c2d93] {
11299
+ .f-table__inner th[data-v-5ae2ec2c] {
11300
+ padding-top: 0.625rem;
11301
+ padding-bottom: 0.625rem;
11302
+ }
11303
+ .f-table__col--index[data-v-5ae2ec2c] {
11288
11304
  width: 3rem;
11289
11305
  }
11290
- .f-table__head[data-v-ce2c2d93] {
11306
+ .f-table__head[data-v-5ae2ec2c] {
11291
11307
  position: sticky;
11292
11308
  top: 0;
11293
11309
  z-index: 2;
11294
11310
  background: #1e293b;
11295
11311
  color: #ffffff;
11296
11312
  }
11297
- .f-table__th[data-v-ce2c2d93] {
11313
+ .f-table__th[data-v-5ae2ec2c] {
11298
11314
  font-weight: 700;
11299
11315
  text-align: center;
11300
11316
  }
11301
- .f-table__th--index[data-v-ce2c2d93] {
11317
+ .f-table__th--index[data-v-5ae2ec2c] {
11302
11318
  background: #0f172a;
11303
11319
  width: 3rem;
11304
11320
  }
11305
- .f-table__th-inner[data-v-ce2c2d93] {
11321
+ .f-table__th-inner[data-v-5ae2ec2c] {
11306
11322
  display: flex;
11307
11323
  flex-direction: column;
11308
11324
  align-items: center;
11309
11325
  gap: 0.25rem;
11310
11326
  }
11311
- .f-table__row[data-v-ce2c2d93] {
11327
+ .f-table__row[data-v-5ae2ec2c] {
11312
11328
  border-bottom: 1px solid #e2e8f0;
11313
11329
  }
11314
- .f-table__row[data-v-ce2c2d93]:hover {
11330
+ .f-table__row[data-v-5ae2ec2c]:hover {
11315
11331
  background: rgba(248, 250, 252, 0.7);
11316
11332
  }
11317
- .f-table__td[data-v-ce2c2d93] {
11333
+ .f-table__td[data-v-5ae2ec2c] {
11318
11334
  text-align: center;
11319
11335
  font-size: 0.6875rem;
11320
11336
  overflow: hidden;
11321
11337
  text-overflow: ellipsis;
11322
11338
  white-space: nowrap;
11323
11339
  }
11324
- .f-table__td--muted[data-v-ce2c2d93] {
11340
+ .f-table__td--muted[data-v-5ae2ec2c] {
11325
11341
  color: #94a3b8;
11326
11342
  text-decoration: line-through;
11327
11343
  opacity: 0.6;
11328
11344
  }
11329
- .f-table__td--index[data-v-ce2c2d93] {
11345
+ .f-table__td--index[data-v-5ae2ec2c] {
11330
11346
  background: rgba(248, 250, 252, 0.5);
11331
11347
  font-weight: 800;
11332
11348
  color: #64748b;
11333
11349
  }
11334
- .f-table__spacer td[data-v-ce2c2d93] {
11350
+ .f-table__text[data-v-5ae2ec2c] {
11351
+ display: block;
11352
+ overflow: hidden;
11353
+ text-overflow: ellipsis;
11354
+ white-space: nowrap;
11355
+ }
11356
+ .f-table__spacer td[data-v-5ae2ec2c] {
11335
11357
  padding: 0;
11336
11358
  border: none;
11337
11359
  }
11338
- .f-table__empty[data-v-ce2c2d93] {
11360
+ .f-table__empty[data-v-5ae2ec2c] {
11339
11361
  padding: 3rem 0;
11340
11362
  text-align: center;
11341
11363
  color: #94a3b8;
11342
11364
  font-weight: 700;
11343
11365
  background: rgba(248, 250, 252, 0.5);
11366
+ }
11367
+ .f-table__tip[data-v-5ae2ec2c] {
11368
+ position: fixed;
11369
+ z-index: 3000;
11370
+ max-width: 320px;
11371
+ padding: 6px 10px;
11372
+ border-radius: 6px;
11373
+ background: rgba(15, 23, 42, 0.96);
11374
+ color: #f8fafc;
11375
+ font-size: 12px;
11376
+ line-height: 1.5;
11377
+ word-break: break-all;
11378
+ pointer-events: none;
11379
+ box-shadow: 0 8px 18px rgba(15, 23, 42, 0.18);
11380
+ }
11381
+ .f-table__tip.is-top[data-v-5ae2ec2c] {
11382
+ transform: translate(-50%, -100%);
11383
+ }
11384
+ .f-table__tip.is-bottom[data-v-5ae2ec2c] {
11385
+ transform: translate(-50%, 0);
11344
11386
  }.f-upload[data-v-45a5af2d] {
11345
11387
  display: flex;
11346
11388
  flex-direction: column;
@@ -37,7 +37,7 @@ var __async = (__this, __arguments, generator) => {
37
37
  step((generator = generator.apply(__this, __arguments)).next());
38
38
  });
39
39
  };
40
- import { defineComponent, computed, createElementBlock, openBlock, normalizeStyle, unref, renderSlot, normalizeClass, createCommentVNode, Fragment, renderList, createElementVNode, toDisplayString, ref, watch, createVNode, withDirectives, Transition, withCtx, vShow, mergeModels, useModel, inject, createBlock, resolveDynamicComponent, nextTick, onUnmounted, Teleport, withModifiers, withKeys, isRef, vModelText, createTextVNode, TransitionGroup, useSlots, Comment as Comment$1, Text, provide, onMounted, readonly, onBeforeUnmount, reactive, toRefs, createStaticVNode, h, render } from "vue";
40
+ import { defineComponent, computed, createElementBlock, openBlock, normalizeStyle, unref, renderSlot, normalizeClass, createCommentVNode, Fragment, renderList, createElementVNode, toDisplayString, ref, watch, createVNode, withDirectives, Transition, withCtx, vShow, mergeModels, useModel, inject, createBlock, resolveDynamicComponent, nextTick, onUnmounted, Teleport, withModifiers, withKeys, isRef, vModelText, createTextVNode, TransitionGroup, useSlots, Comment as Comment$1, Text, provide, onMounted, readonly, reactive, onBeforeUnmount, toRefs, createStaticVNode, h, render } from "vue";
41
41
  import { CloseCircleOutline, EyeOutline, EyeOffOutline, StarOutline, StarHalf, Star, ChevronDownOutline, ChevronBackOutline, EllipsisHorizontal, ChevronForwardOutline, CloseCircle, Close, Person, InformationCircleOutline, WarningOutline, AlertCircleOutline, CheckmarkCircleOutline, CloudUpload, CheckmarkCircle, AlertCircle, DocumentOutline, Reload, RemoveOutline, AddOutline, ChevronUpOutline, InformationCircle, CloseOutline, Warning } from "@vicons/ionicons5";
42
42
  import { useEventListener } from "@vueuse/core";
43
43
  const _sfc_main$S = /* @__PURE__ */ defineComponent({
@@ -1009,6 +1009,16 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
1009
1009
  const visible = ref(false);
1010
1010
  const position = ref({ top: 0, left: 0 });
1011
1011
  let showTimer = null;
1012
+ const getAnchorRect = () => {
1013
+ const root = triggerRef.value;
1014
+ if (!root) return null;
1015
+ const el = root.firstElementChild;
1016
+ if (el) return el.getBoundingClientRect();
1017
+ const range = document.createRange();
1018
+ range.selectNodeContents(root);
1019
+ const rect = range.getBoundingClientRect();
1020
+ return rect.width || rect.height ? rect : null;
1021
+ };
1012
1022
  const show = () => {
1013
1023
  if (props.disabled) return;
1014
1024
  showTimer = setTimeout(() => {
@@ -1021,11 +1031,12 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
1021
1031
  visible.value = false;
1022
1032
  };
1023
1033
  const updatePosition = () => {
1024
- var _a, _b;
1025
1034
  if (!tooltipRef.value) return;
1026
- const triggerEl = (_b = (_a = triggerRef.value) == null ? void 0 : _a.firstElementChild) != null ? _b : triggerRef.value;
1027
- if (!triggerEl) return;
1028
- const trigger = triggerEl.getBoundingClientRect();
1035
+ const trigger = getAnchorRect();
1036
+ if (!trigger) {
1037
+ visible.value = false;
1038
+ return;
1039
+ }
1029
1040
  const tooltip = tooltipRef.value.getBoundingClientRect();
1030
1041
  const gap = props.offset;
1031
1042
  const [side, align] = props.placement.split("-");
@@ -1096,7 +1107,7 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
1096
1107
  };
1097
1108
  }
1098
1109
  });
1099
- const FTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-37ae9256"]]);
1110
+ const FTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-398a5be6"]]);
1100
1111
  const _hoisted_1$w = { class: "f-progress" };
1101
1112
  const _hoisted_2$q = {
1102
1113
  key: 0,
@@ -2077,7 +2088,7 @@ const _sfc_main$r = /* @__PURE__ */ defineComponent({
2077
2088
  })
2078
2089
  }, [
2079
2090
  unref(isRequired) ? (openBlock(), createElementBlock("span", _hoisted_1$n, "*")) : createCommentVNode("", true),
2080
- createTextVNode(" " + toDisplayString(_ctx.label) + "锛? ", 1)
2091
+ createTextVNode(" " + toDisplayString(_ctx.label), 1)
2081
2092
  ], 4)) : createCommentVNode("", true),
2082
2093
  createElementVNode("div", _hoisted_2$l, [
2083
2094
  renderSlot(_ctx.$slots, "default", {}, void 0, true),
@@ -2092,7 +2103,7 @@ const _sfc_main$r = /* @__PURE__ */ defineComponent({
2092
2103
  };
2093
2104
  }
2094
2105
  });
2095
- const FFormItem = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-42312371"]]);
2106
+ const FFormItem = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-c1ead052"]]);
2096
2107
  const _hoisted_1$m = { class: "f-checkbox__wrapper" };
2097
2108
  const _hoisted_2$k = ["checked", "disabled"];
2098
2109
  const _hoisted_3$j = {
@@ -2807,39 +2818,35 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
2807
2818
  }
2808
2819
  });
2809
2820
  const FEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-48883044"]]);
2810
- const _hoisted_1$e = { class: "f-table" };
2821
+ const _hoisted_1$e = { class: "f-table__inner" };
2811
2822
  const _hoisted_2$c = {
2812
- key: 0,
2813
- class: "f-table__loading"
2814
- };
2815
- const _hoisted_3$c = { class: "f-table__inner" };
2816
- const _hoisted_4$9 = {
2817
2823
  key: 0,
2818
2824
  class: "f-table__col--index"
2819
2825
  };
2820
- const _hoisted_5$6 = { class: "f-table__head" };
2821
- const _hoisted_6$5 = {
2826
+ const _hoisted_3$c = { class: "f-table__head" };
2827
+ const _hoisted_4$9 = {
2822
2828
  key: 0,
2823
2829
  class: "f-table__th f-table__th--index"
2824
2830
  };
2825
- const _hoisted_7$2 = { class: "f-table__th-inner" };
2826
- const _hoisted_8$1 = { class: "f-table__body" };
2827
- const _hoisted_9 = {
2831
+ const _hoisted_5$6 = { class: "f-table__th-inner" };
2832
+ const _hoisted_6$5 = {
2828
2833
  key: 0,
2829
2834
  class: "f-table__spacer"
2830
2835
  };
2831
- const _hoisted_10 = ["colspan"];
2832
- const _hoisted_11 = {
2836
+ const _hoisted_7$2 = ["colspan"];
2837
+ const _hoisted_8$1 = {
2833
2838
  key: 0,
2834
2839
  class: "f-table__td f-table__td--index"
2835
2840
  };
2836
- const _hoisted_12 = { key: 2 };
2837
- const _hoisted_13 = ["colspan"];
2838
- const _hoisted_14 = {
2841
+ const _hoisted_9 = ["data-tooltip"];
2842
+ const _hoisted_10 = { key: 2 };
2843
+ const _hoisted_11 = ["colspan"];
2844
+ const _hoisted_12 = {
2839
2845
  key: 3,
2840
2846
  class: "f-table__spacer"
2841
2847
  };
2842
- const _hoisted_15 = ["colspan"];
2848
+ const _hoisted_13 = ["colspan"];
2849
+ const TIP_HALF_WIDTH = 160;
2843
2850
  const _sfc_main$i = /* @__PURE__ */ defineComponent({
2844
2851
  __name: "FTable",
2845
2852
  props: {
@@ -2848,9 +2855,10 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2848
2855
  rowHeight: { default: 40 },
2849
2856
  overscan: { default: 5 },
2850
2857
  showIndex: { type: Boolean, default: true },
2851
- loading: { type: Boolean, default: false },
2852
- loadingText: { default: "鍔犺浇涓?.." },
2853
- emptyText: { default: "鏆傛棤鏁版嵁" }
2858
+ emptyText: { default: "暂无数据" },
2859
+ rowKey: {},
2860
+ height: {},
2861
+ overflowTooltip: { type: Boolean, default: false }
2854
2862
  },
2855
2863
  setup(__props) {
2856
2864
  const props = __props;
@@ -2858,14 +2866,16 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2858
2866
  const scrollTop = ref(0);
2859
2867
  const viewportHeight = ref(0);
2860
2868
  const colSpan = computed(() => props.columns.length + (props.showIndex ? 1 : 0));
2861
- const startIndex = computed(() => {
2862
- const raw = Math.floor(scrollTop.value / props.rowHeight) - props.overscan;
2863
- return Math.max(0, raw);
2869
+ const rootStyle = computed(() => {
2870
+ if (props.height === void 0) return void 0;
2871
+ return { height: typeof props.height === "number" ? `${props.height}px` : props.height };
2864
2872
  });
2873
+ const startIndex = computed(
2874
+ () => Math.max(0, Math.floor(scrollTop.value / props.rowHeight) - props.overscan)
2875
+ );
2865
2876
  const endIndex = computed(() => {
2866
2877
  const visible = Math.ceil(viewportHeight.value / props.rowHeight);
2867
- const raw = startIndex.value + visible + props.overscan * 2;
2868
- return Math.min(props.data.length - 1, raw);
2878
+ return Math.min(props.data.length - 1, startIndex.value + visible + props.overscan * 2);
2869
2879
  });
2870
2880
  const visibleRows = computed(
2871
2881
  () => props.data.slice(startIndex.value, endIndex.value + 1).map((row, i) => ({
@@ -2877,24 +2887,56 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2877
2887
  const offsetBottom = computed(
2878
2888
  () => Math.max(0, (props.data.length - endIndex.value - 1) * props.rowHeight)
2879
2889
  );
2880
- const onScroll = (e) => {
2881
- scrollTop.value = e.target.scrollTop;
2890
+ const getKey = (row, index) => {
2891
+ var _a;
2892
+ return props.rowKey ? (_a = row[props.rowKey]) != null ? _a : index : index;
2882
2893
  };
2883
2894
  const formatCell = (val) => {
2884
- if (val === null || val === void 0) return "-";
2895
+ if (val === null || val === void 0) return "";
2885
2896
  if (typeof val === "object") return JSON.stringify(val);
2886
2897
  return String(val);
2887
2898
  };
2899
+ const tip = reactive({
2900
+ show: false,
2901
+ text: "",
2902
+ top: 0,
2903
+ left: 0,
2904
+ placement: "top"
2905
+ });
2906
+ const hideTip = () => {
2907
+ if (tip.show) tip.show = false;
2908
+ };
2909
+ const onBodyOver = (e) => {
2910
+ var _a, _b;
2911
+ const el = e.target.closest(".f-table__text");
2912
+ if (!el) return hideTip();
2913
+ const colFlag = el.dataset.tooltip;
2914
+ const enabled = colFlag === void 0 ? props.overflowTooltip : colFlag === "1";
2915
+ if (!enabled || el.scrollWidth <= el.clientWidth) return hideTip();
2916
+ const r = el.getBoundingClientRect();
2917
+ const placeTop = r.top > 48;
2918
+ const center = r.left + r.width / 2;
2919
+ tip.text = (_b = (_a = el.textContent) == null ? void 0 : _a.trim()) != null ? _b : "";
2920
+ tip.left = Math.max(
2921
+ TIP_HALF_WIDTH + 8,
2922
+ Math.min(center, window.innerWidth - TIP_HALF_WIDTH - 8)
2923
+ );
2924
+ tip.top = placeTop ? r.top - 8 : r.bottom + 8;
2925
+ tip.placement = placeTop ? "top" : "bottom";
2926
+ tip.show = true;
2927
+ };
2928
+ const onScroll = (e) => {
2929
+ scrollTop.value = e.target.scrollTop;
2930
+ hideTip();
2931
+ };
2888
2932
  let ro = null;
2889
2933
  onMounted(() => {
2890
- if (scrollEl.value) {
2891
- viewportHeight.value = scrollEl.value.clientHeight;
2892
- ro = new ResizeObserver(([entry]) => {
2893
- if (entry)
2894
- viewportHeight.value = entry.contentRect.height;
2895
- });
2896
- ro.observe(scrollEl.value);
2897
- }
2934
+ if (!scrollEl.value) return;
2935
+ viewportHeight.value = scrollEl.value.clientHeight;
2936
+ ro = new ResizeObserver(([entry]) => {
2937
+ if (entry) viewportHeight.value = entry.contentRect.height;
2938
+ });
2939
+ ro.observe(scrollEl.value);
2898
2940
  });
2899
2941
  onBeforeUnmount(() => {
2900
2942
  ro == null ? void 0 : ro.disconnect();
@@ -2902,22 +2944,22 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2902
2944
  watch(() => props.data, () => {
2903
2945
  if (scrollEl.value) scrollEl.value.scrollTop = 0;
2904
2946
  scrollTop.value = 0;
2947
+ hideTip();
2905
2948
  });
2906
2949
  return (_ctx, _cache) => {
2907
- return openBlock(), createElementBlock("div", _hoisted_1$e, [
2908
- _ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_2$c, [
2909
- _cache[0] || (_cache[0] = createElementVNode("span", { class: "spinner" }, null, -1)),
2910
- createElementVNode("span", null, toDisplayString(_ctx.loadingText), 1)
2911
- ])) : createCommentVNode("", true),
2950
+ return openBlock(), createElementBlock("div", {
2951
+ class: "f-table",
2952
+ style: normalizeStyle(unref(rootStyle))
2953
+ }, [
2912
2954
  createElementVNode("div", {
2913
2955
  class: "f-table__scroll",
2914
2956
  ref_key: "scrollEl",
2915
2957
  ref: scrollEl,
2916
- onScroll
2958
+ onScrollPassive: onScroll
2917
2959
  }, [
2918
- createElementVNode("table", _hoisted_3$c, [
2960
+ createElementVNode("table", _hoisted_1$e, [
2919
2961
  createElementVNode("colgroup", null, [
2920
- _ctx.showIndex ? (openBlock(), createElementBlock("col", _hoisted_4$9)) : createCommentVNode("", true),
2962
+ _ctx.showIndex ? (openBlock(), createElementBlock("col", _hoisted_2$c)) : createCommentVNode("", true),
2921
2963
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.columns, (col) => {
2922
2964
  var _a, _b;
2923
2965
  return openBlock(), createElementBlock("col", {
@@ -2929,16 +2971,16 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2929
2971
  }, null, 4);
2930
2972
  }), 128))
2931
2973
  ]),
2932
- createElementVNode("thead", _hoisted_5$6, [
2974
+ createElementVNode("thead", _hoisted_3$c, [
2933
2975
  createElementVNode("tr", null, [
2934
- _ctx.showIndex ? (openBlock(), createElementBlock("th", _hoisted_6$5, "#")) : createCommentVNode("", true),
2976
+ _ctx.showIndex ? (openBlock(), createElementBlock("th", _hoisted_4$9, "#")) : createCommentVNode("", true),
2935
2977
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.columns, (col) => {
2936
2978
  return openBlock(), createElementBlock("th", {
2937
2979
  key: col.key,
2938
2980
  class: normalizeClass(["f-table__th", col.thClass])
2939
2981
  }, [
2940
2982
  renderSlot(_ctx.$slots, `header-${col.key}`, { column: col }, () => [
2941
- createElementVNode("div", _hoisted_7$2, [
2983
+ createElementVNode("div", _hoisted_5$6, [
2942
2984
  createElementVNode("span", null, toDisplayString(col.label), 1)
2943
2985
  ])
2944
2986
  ], true)
@@ -2946,23 +2988,29 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2946
2988
  }), 128))
2947
2989
  ])
2948
2990
  ]),
2949
- createElementVNode("tbody", _hoisted_8$1, [
2950
- unref(offsetTop) > 0 ? (openBlock(), createElementBlock("tr", _hoisted_9, [
2991
+ createElementVNode("tbody", {
2992
+ class: "f-table__body",
2993
+ onMouseover: onBodyOver,
2994
+ onMouseleave: hideTip
2995
+ }, [
2996
+ unref(offsetTop) > 0 ? (openBlock(), createElementBlock("tr", _hoisted_6$5, [
2951
2997
  createElementVNode("td", {
2952
2998
  colspan: unref(colSpan),
2953
2999
  style: normalizeStyle({ height: unref(offsetTop) + "px" })
2954
- }, null, 12, _hoisted_10)
3000
+ }, null, 12, _hoisted_7$2)
2955
3001
  ])) : createCommentVNode("", true),
2956
3002
  unref(visibleRows).length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(visibleRows), ({ row, index }) => {
2957
3003
  return openBlock(), createElementBlock("tr", {
2958
- key: index,
2959
- class: "f-table__row"
3004
+ key: getKey(row, index),
3005
+ class: "f-table__row",
3006
+ style: normalizeStyle({ height: _ctx.rowHeight + "px" })
2960
3007
  }, [
2961
- _ctx.showIndex ? (openBlock(), createElementBlock("td", _hoisted_11, toDisplayString(index + 1), 1)) : createCommentVNode("", true),
3008
+ _ctx.showIndex ? (openBlock(), createElementBlock("td", _hoisted_8$1, toDisplayString(index + 1), 1)) : createCommentVNode("", true),
2962
3009
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.columns, (col) => {
2963
3010
  return openBlock(), createElementBlock("td", {
2964
3011
  key: col.key,
2965
- class: normalizeClass(["f-table__td", col.tdClass])
3012
+ class: normalizeClass(["f-table__td", col.tdClass]),
3013
+ style: normalizeStyle(col.width ? { maxWidth: col.width } : void 0)
2966
3014
  }, [
2967
3015
  _ctx.$slots[`cell-${col.key}`] ? renderSlot(_ctx.$slots, `cell-${col.key}`, {
2968
3016
  key: 0,
@@ -2976,19 +3024,15 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2976
3024
  value: row[col.key],
2977
3025
  index,
2978
3026
  col
2979
- }, void 0, true) : (openBlock(), createBlock(FTooltip, {
3027
+ }, void 0, true) : (openBlock(), createElementBlock("span", {
2980
3028
  key: 2,
2981
- content: formatCell(row[col.key])
2982
- }, {
2983
- default: withCtx(() => [
2984
- createTextVNode(toDisplayString(formatCell(row[col.key])), 1)
2985
- ]),
2986
- _: 2
2987
- }, 1032, ["content"]))
2988
- ], 2);
3029
+ class: "f-table__text",
3030
+ "data-tooltip": col.tooltip === void 0 ? void 0 : col.tooltip ? "1" : "0"
3031
+ }, toDisplayString(formatCell(row[col.key])), 9, _hoisted_9))
3032
+ ], 6);
2989
3033
  }), 128))
2990
- ]);
2991
- }), 128)) : !_ctx.loading ? (openBlock(), createElementBlock("tr", _hoisted_12, [
3034
+ ], 4);
3035
+ }), 128)) : (openBlock(), createElementBlock("tr", _hoisted_10, [
2992
3036
  createElementVNode("td", {
2993
3037
  colspan: unref(colSpan),
2994
3038
  class: "f-table__empty"
@@ -2996,22 +3040,29 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
2996
3040
  renderSlot(_ctx.$slots, "empty", {}, () => [
2997
3041
  createTextVNode(toDisplayString(_ctx.emptyText), 1)
2998
3042
  ], true)
2999
- ], 8, _hoisted_13)
3000
- ])) : createCommentVNode("", true),
3001
- unref(offsetBottom) > 0 ? (openBlock(), createElementBlock("tr", _hoisted_14, [
3043
+ ], 8, _hoisted_11)
3044
+ ])),
3045
+ unref(offsetBottom) > 0 ? (openBlock(), createElementBlock("tr", _hoisted_12, [
3002
3046
  createElementVNode("td", {
3003
3047
  colspan: unref(colSpan),
3004
3048
  style: normalizeStyle({ height: unref(offsetBottom) + "px" })
3005
- }, null, 12, _hoisted_15)
3049
+ }, null, 12, _hoisted_13)
3006
3050
  ])) : createCommentVNode("", true)
3007
- ])
3051
+ ], 32)
3008
3052
  ])
3009
- ], 544)
3010
- ]);
3053
+ ], 544),
3054
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
3055
+ unref(tip).show ? (openBlock(), createElementBlock("div", {
3056
+ key: 0,
3057
+ class: normalizeClass(["f-table__tip", `is-${unref(tip).placement}`]),
3058
+ style: normalizeStyle({ top: unref(tip).top + "px", left: unref(tip).left + "px" })
3059
+ }, toDisplayString(unref(tip).text), 7)) : createCommentVNode("", true)
3060
+ ]))
3061
+ ], 4);
3011
3062
  };
3012
3063
  }
3013
3064
  });
3014
- const FTable = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-ce2c2d93"]]);
3065
+ const FTable = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-5ae2ec2c"]]);
3015
3066
  const _hoisted_1$d = { class: "f-upload" };
3016
3067
  const _hoisted_2$b = ["accept", "multiple"];
3017
3068
  const _hoisted_3$b = { class: "f-upload__zone" };
@@ -1010,6 +1010,16 @@ var __async = (__this, __arguments, generator) => {
1010
1010
  const visible = vue.ref(false);
1011
1011
  const position = vue.ref({ top: 0, left: 0 });
1012
1012
  let showTimer = null;
1013
+ const getAnchorRect = () => {
1014
+ const root = triggerRef.value;
1015
+ if (!root) return null;
1016
+ const el = root.firstElementChild;
1017
+ if (el) return el.getBoundingClientRect();
1018
+ const range = document.createRange();
1019
+ range.selectNodeContents(root);
1020
+ const rect = range.getBoundingClientRect();
1021
+ return rect.width || rect.height ? rect : null;
1022
+ };
1013
1023
  const show = () => {
1014
1024
  if (props.disabled) return;
1015
1025
  showTimer = setTimeout(() => {
@@ -1022,11 +1032,12 @@ var __async = (__this, __arguments, generator) => {
1022
1032
  visible.value = false;
1023
1033
  };
1024
1034
  const updatePosition = () => {
1025
- var _a, _b;
1026
1035
  if (!tooltipRef.value) return;
1027
- const triggerEl = (_b = (_a = triggerRef.value) == null ? void 0 : _a.firstElementChild) != null ? _b : triggerRef.value;
1028
- if (!triggerEl) return;
1029
- const trigger = triggerEl.getBoundingClientRect();
1036
+ const trigger = getAnchorRect();
1037
+ if (!trigger) {
1038
+ visible.value = false;
1039
+ return;
1040
+ }
1030
1041
  const tooltip = tooltipRef.value.getBoundingClientRect();
1031
1042
  const gap = props.offset;
1032
1043
  const [side, align] = props.placement.split("-");
@@ -1097,7 +1108,7 @@ var __async = (__this, __arguments, generator) => {
1097
1108
  };
1098
1109
  }
1099
1110
  });
1100
- const FTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-37ae9256"]]);
1111
+ const FTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-398a5be6"]]);
1101
1112
  const _hoisted_1$w = { class: "f-progress" };
1102
1113
  const _hoisted_2$q = {
1103
1114
  key: 0,
@@ -2078,7 +2089,7 @@ var __async = (__this, __arguments, generator) => {
2078
2089
  })
2079
2090
  }, [
2080
2091
  vue.unref(isRequired) ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$n, "*")) : vue.createCommentVNode("", true),
2081
- vue.createTextVNode(" " + vue.toDisplayString(_ctx.label) + "锛? ", 1)
2092
+ vue.createTextVNode(" " + vue.toDisplayString(_ctx.label), 1)
2082
2093
  ], 4)) : vue.createCommentVNode("", true),
2083
2094
  vue.createElementVNode("div", _hoisted_2$l, [
2084
2095
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true),
@@ -2093,7 +2104,7 @@ var __async = (__this, __arguments, generator) => {
2093
2104
  };
2094
2105
  }
2095
2106
  });
2096
- const FFormItem = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-42312371"]]);
2107
+ const FFormItem = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-c1ead052"]]);
2097
2108
  const _hoisted_1$m = { class: "f-checkbox__wrapper" };
2098
2109
  const _hoisted_2$k = ["checked", "disabled"];
2099
2110
  const _hoisted_3$j = {
@@ -2808,39 +2819,35 @@ var __async = (__this, __arguments, generator) => {
2808
2819
  }
2809
2820
  });
2810
2821
  const FEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-48883044"]]);
2811
- const _hoisted_1$e = { class: "f-table" };
2822
+ const _hoisted_1$e = { class: "f-table__inner" };
2812
2823
  const _hoisted_2$c = {
2813
- key: 0,
2814
- class: "f-table__loading"
2815
- };
2816
- const _hoisted_3$c = { class: "f-table__inner" };
2817
- const _hoisted_4$9 = {
2818
2824
  key: 0,
2819
2825
  class: "f-table__col--index"
2820
2826
  };
2821
- const _hoisted_5$6 = { class: "f-table__head" };
2822
- const _hoisted_6$5 = {
2827
+ const _hoisted_3$c = { class: "f-table__head" };
2828
+ const _hoisted_4$9 = {
2823
2829
  key: 0,
2824
2830
  class: "f-table__th f-table__th--index"
2825
2831
  };
2826
- const _hoisted_7$2 = { class: "f-table__th-inner" };
2827
- const _hoisted_8$1 = { class: "f-table__body" };
2828
- const _hoisted_9 = {
2832
+ const _hoisted_5$6 = { class: "f-table__th-inner" };
2833
+ const _hoisted_6$5 = {
2829
2834
  key: 0,
2830
2835
  class: "f-table__spacer"
2831
2836
  };
2832
- const _hoisted_10 = ["colspan"];
2833
- const _hoisted_11 = {
2837
+ const _hoisted_7$2 = ["colspan"];
2838
+ const _hoisted_8$1 = {
2834
2839
  key: 0,
2835
2840
  class: "f-table__td f-table__td--index"
2836
2841
  };
2837
- const _hoisted_12 = { key: 2 };
2838
- const _hoisted_13 = ["colspan"];
2839
- const _hoisted_14 = {
2842
+ const _hoisted_9 = ["data-tooltip"];
2843
+ const _hoisted_10 = { key: 2 };
2844
+ const _hoisted_11 = ["colspan"];
2845
+ const _hoisted_12 = {
2840
2846
  key: 3,
2841
2847
  class: "f-table__spacer"
2842
2848
  };
2843
- const _hoisted_15 = ["colspan"];
2849
+ const _hoisted_13 = ["colspan"];
2850
+ const TIP_HALF_WIDTH = 160;
2844
2851
  const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
2845
2852
  __name: "FTable",
2846
2853
  props: {
@@ -2849,9 +2856,10 @@ var __async = (__this, __arguments, generator) => {
2849
2856
  rowHeight: { default: 40 },
2850
2857
  overscan: { default: 5 },
2851
2858
  showIndex: { type: Boolean, default: true },
2852
- loading: { type: Boolean, default: false },
2853
- loadingText: { default: "鍔犺浇涓?.." },
2854
- emptyText: { default: "鏆傛棤鏁版嵁" }
2859
+ emptyText: { default: "暂无数据" },
2860
+ rowKey: {},
2861
+ height: {},
2862
+ overflowTooltip: { type: Boolean, default: false }
2855
2863
  },
2856
2864
  setup(__props) {
2857
2865
  const props = __props;
@@ -2859,14 +2867,16 @@ var __async = (__this, __arguments, generator) => {
2859
2867
  const scrollTop = vue.ref(0);
2860
2868
  const viewportHeight = vue.ref(0);
2861
2869
  const colSpan = vue.computed(() => props.columns.length + (props.showIndex ? 1 : 0));
2862
- const startIndex = vue.computed(() => {
2863
- const raw = Math.floor(scrollTop.value / props.rowHeight) - props.overscan;
2864
- return Math.max(0, raw);
2870
+ const rootStyle = vue.computed(() => {
2871
+ if (props.height === void 0) return void 0;
2872
+ return { height: typeof props.height === "number" ? `${props.height}px` : props.height };
2865
2873
  });
2874
+ const startIndex = vue.computed(
2875
+ () => Math.max(0, Math.floor(scrollTop.value / props.rowHeight) - props.overscan)
2876
+ );
2866
2877
  const endIndex = vue.computed(() => {
2867
2878
  const visible = Math.ceil(viewportHeight.value / props.rowHeight);
2868
- const raw = startIndex.value + visible + props.overscan * 2;
2869
- return Math.min(props.data.length - 1, raw);
2879
+ return Math.min(props.data.length - 1, startIndex.value + visible + props.overscan * 2);
2870
2880
  });
2871
2881
  const visibleRows = vue.computed(
2872
2882
  () => props.data.slice(startIndex.value, endIndex.value + 1).map((row, i) => ({
@@ -2878,24 +2888,56 @@ var __async = (__this, __arguments, generator) => {
2878
2888
  const offsetBottom = vue.computed(
2879
2889
  () => Math.max(0, (props.data.length - endIndex.value - 1) * props.rowHeight)
2880
2890
  );
2881
- const onScroll = (e) => {
2882
- scrollTop.value = e.target.scrollTop;
2891
+ const getKey = (row, index) => {
2892
+ var _a;
2893
+ return props.rowKey ? (_a = row[props.rowKey]) != null ? _a : index : index;
2883
2894
  };
2884
2895
  const formatCell = (val) => {
2885
- if (val === null || val === void 0) return "-";
2896
+ if (val === null || val === void 0) return "";
2886
2897
  if (typeof val === "object") return JSON.stringify(val);
2887
2898
  return String(val);
2888
2899
  };
2900
+ const tip = vue.reactive({
2901
+ show: false,
2902
+ text: "",
2903
+ top: 0,
2904
+ left: 0,
2905
+ placement: "top"
2906
+ });
2907
+ const hideTip = () => {
2908
+ if (tip.show) tip.show = false;
2909
+ };
2910
+ const onBodyOver = (e) => {
2911
+ var _a, _b;
2912
+ const el = e.target.closest(".f-table__text");
2913
+ if (!el) return hideTip();
2914
+ const colFlag = el.dataset.tooltip;
2915
+ const enabled = colFlag === void 0 ? props.overflowTooltip : colFlag === "1";
2916
+ if (!enabled || el.scrollWidth <= el.clientWidth) return hideTip();
2917
+ const r = el.getBoundingClientRect();
2918
+ const placeTop = r.top > 48;
2919
+ const center = r.left + r.width / 2;
2920
+ tip.text = (_b = (_a = el.textContent) == null ? void 0 : _a.trim()) != null ? _b : "";
2921
+ tip.left = Math.max(
2922
+ TIP_HALF_WIDTH + 8,
2923
+ Math.min(center, window.innerWidth - TIP_HALF_WIDTH - 8)
2924
+ );
2925
+ tip.top = placeTop ? r.top - 8 : r.bottom + 8;
2926
+ tip.placement = placeTop ? "top" : "bottom";
2927
+ tip.show = true;
2928
+ };
2929
+ const onScroll = (e) => {
2930
+ scrollTop.value = e.target.scrollTop;
2931
+ hideTip();
2932
+ };
2889
2933
  let ro = null;
2890
2934
  vue.onMounted(() => {
2891
- if (scrollEl.value) {
2892
- viewportHeight.value = scrollEl.value.clientHeight;
2893
- ro = new ResizeObserver(([entry]) => {
2894
- if (entry)
2895
- viewportHeight.value = entry.contentRect.height;
2896
- });
2897
- ro.observe(scrollEl.value);
2898
- }
2935
+ if (!scrollEl.value) return;
2936
+ viewportHeight.value = scrollEl.value.clientHeight;
2937
+ ro = new ResizeObserver(([entry]) => {
2938
+ if (entry) viewportHeight.value = entry.contentRect.height;
2939
+ });
2940
+ ro.observe(scrollEl.value);
2899
2941
  });
2900
2942
  vue.onBeforeUnmount(() => {
2901
2943
  ro == null ? void 0 : ro.disconnect();
@@ -2903,22 +2945,22 @@ var __async = (__this, __arguments, generator) => {
2903
2945
  vue.watch(() => props.data, () => {
2904
2946
  if (scrollEl.value) scrollEl.value.scrollTop = 0;
2905
2947
  scrollTop.value = 0;
2948
+ hideTip();
2906
2949
  });
2907
2950
  return (_ctx, _cache) => {
2908
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$e, [
2909
- _ctx.loading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$c, [
2910
- _cache[0] || (_cache[0] = vue.createElementVNode("span", { class: "spinner" }, null, -1)),
2911
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.loadingText), 1)
2912
- ])) : vue.createCommentVNode("", true),
2951
+ return vue.openBlock(), vue.createElementBlock("div", {
2952
+ class: "f-table",
2953
+ style: vue.normalizeStyle(vue.unref(rootStyle))
2954
+ }, [
2913
2955
  vue.createElementVNode("div", {
2914
2956
  class: "f-table__scroll",
2915
2957
  ref_key: "scrollEl",
2916
2958
  ref: scrollEl,
2917
- onScroll
2959
+ onScrollPassive: onScroll
2918
2960
  }, [
2919
- vue.createElementVNode("table", _hoisted_3$c, [
2961
+ vue.createElementVNode("table", _hoisted_1$e, [
2920
2962
  vue.createElementVNode("colgroup", null, [
2921
- _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("col", _hoisted_4$9)) : vue.createCommentVNode("", true),
2963
+ _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("col", _hoisted_2$c)) : vue.createCommentVNode("", true),
2922
2964
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.columns, (col) => {
2923
2965
  var _a, _b;
2924
2966
  return vue.openBlock(), vue.createElementBlock("col", {
@@ -2930,16 +2972,16 @@ var __async = (__this, __arguments, generator) => {
2930
2972
  }, null, 4);
2931
2973
  }), 128))
2932
2974
  ]),
2933
- vue.createElementVNode("thead", _hoisted_5$6, [
2975
+ vue.createElementVNode("thead", _hoisted_3$c, [
2934
2976
  vue.createElementVNode("tr", null, [
2935
- _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("th", _hoisted_6$5, "#")) : vue.createCommentVNode("", true),
2977
+ _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("th", _hoisted_4$9, "#")) : vue.createCommentVNode("", true),
2936
2978
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.columns, (col) => {
2937
2979
  return vue.openBlock(), vue.createElementBlock("th", {
2938
2980
  key: col.key,
2939
2981
  class: vue.normalizeClass(["f-table__th", col.thClass])
2940
2982
  }, [
2941
2983
  vue.renderSlot(_ctx.$slots, `header-${col.key}`, { column: col }, () => [
2942
- vue.createElementVNode("div", _hoisted_7$2, [
2984
+ vue.createElementVNode("div", _hoisted_5$6, [
2943
2985
  vue.createElementVNode("span", null, vue.toDisplayString(col.label), 1)
2944
2986
  ])
2945
2987
  ], true)
@@ -2947,23 +2989,29 @@ var __async = (__this, __arguments, generator) => {
2947
2989
  }), 128))
2948
2990
  ])
2949
2991
  ]),
2950
- vue.createElementVNode("tbody", _hoisted_8$1, [
2951
- vue.unref(offsetTop) > 0 ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_9, [
2992
+ vue.createElementVNode("tbody", {
2993
+ class: "f-table__body",
2994
+ onMouseover: onBodyOver,
2995
+ onMouseleave: hideTip
2996
+ }, [
2997
+ vue.unref(offsetTop) > 0 ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_6$5, [
2952
2998
  vue.createElementVNode("td", {
2953
2999
  colspan: vue.unref(colSpan),
2954
3000
  style: vue.normalizeStyle({ height: vue.unref(offsetTop) + "px" })
2955
- }, null, 12, _hoisted_10)
3001
+ }, null, 12, _hoisted_7$2)
2956
3002
  ])) : vue.createCommentVNode("", true),
2957
3003
  vue.unref(visibleRows).length > 0 ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(vue.unref(visibleRows), ({ row, index }) => {
2958
3004
  return vue.openBlock(), vue.createElementBlock("tr", {
2959
- key: index,
2960
- class: "f-table__row"
3005
+ key: getKey(row, index),
3006
+ class: "f-table__row",
3007
+ style: vue.normalizeStyle({ height: _ctx.rowHeight + "px" })
2961
3008
  }, [
2962
- _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("td", _hoisted_11, vue.toDisplayString(index + 1), 1)) : vue.createCommentVNode("", true),
3009
+ _ctx.showIndex ? (vue.openBlock(), vue.createElementBlock("td", _hoisted_8$1, vue.toDisplayString(index + 1), 1)) : vue.createCommentVNode("", true),
2963
3010
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.columns, (col) => {
2964
3011
  return vue.openBlock(), vue.createElementBlock("td", {
2965
3012
  key: col.key,
2966
- class: vue.normalizeClass(["f-table__td", col.tdClass])
3013
+ class: vue.normalizeClass(["f-table__td", col.tdClass]),
3014
+ style: vue.normalizeStyle(col.width ? { maxWidth: col.width } : void 0)
2967
3015
  }, [
2968
3016
  _ctx.$slots[`cell-${col.key}`] ? vue.renderSlot(_ctx.$slots, `cell-${col.key}`, {
2969
3017
  key: 0,
@@ -2977,19 +3025,15 @@ var __async = (__this, __arguments, generator) => {
2977
3025
  value: row[col.key],
2978
3026
  index,
2979
3027
  col
2980
- }, void 0, true) : (vue.openBlock(), vue.createBlock(FTooltip, {
3028
+ }, void 0, true) : (vue.openBlock(), vue.createElementBlock("span", {
2981
3029
  key: 2,
2982
- content: formatCell(row[col.key])
2983
- }, {
2984
- default: vue.withCtx(() => [
2985
- vue.createTextVNode(vue.toDisplayString(formatCell(row[col.key])), 1)
2986
- ]),
2987
- _: 2
2988
- }, 1032, ["content"]))
2989
- ], 2);
3030
+ class: "f-table__text",
3031
+ "data-tooltip": col.tooltip === void 0 ? void 0 : col.tooltip ? "1" : "0"
3032
+ }, vue.toDisplayString(formatCell(row[col.key])), 9, _hoisted_9))
3033
+ ], 6);
2990
3034
  }), 128))
2991
- ]);
2992
- }), 128)) : !_ctx.loading ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_12, [
3035
+ ], 4);
3036
+ }), 128)) : (vue.openBlock(), vue.createElementBlock("tr", _hoisted_10, [
2993
3037
  vue.createElementVNode("td", {
2994
3038
  colspan: vue.unref(colSpan),
2995
3039
  class: "f-table__empty"
@@ -2997,22 +3041,29 @@ var __async = (__this, __arguments, generator) => {
2997
3041
  vue.renderSlot(_ctx.$slots, "empty", {}, () => [
2998
3042
  vue.createTextVNode(vue.toDisplayString(_ctx.emptyText), 1)
2999
3043
  ], true)
3000
- ], 8, _hoisted_13)
3001
- ])) : vue.createCommentVNode("", true),
3002
- vue.unref(offsetBottom) > 0 ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_14, [
3044
+ ], 8, _hoisted_11)
3045
+ ])),
3046
+ vue.unref(offsetBottom) > 0 ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_12, [
3003
3047
  vue.createElementVNode("td", {
3004
3048
  colspan: vue.unref(colSpan),
3005
3049
  style: vue.normalizeStyle({ height: vue.unref(offsetBottom) + "px" })
3006
- }, null, 12, _hoisted_15)
3050
+ }, null, 12, _hoisted_13)
3007
3051
  ])) : vue.createCommentVNode("", true)
3008
- ])
3052
+ ], 32)
3009
3053
  ])
3010
- ], 544)
3011
- ]);
3054
+ ], 544),
3055
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3056
+ vue.unref(tip).show ? (vue.openBlock(), vue.createElementBlock("div", {
3057
+ key: 0,
3058
+ class: vue.normalizeClass(["f-table__tip", `is-${vue.unref(tip).placement}`]),
3059
+ style: vue.normalizeStyle({ top: vue.unref(tip).top + "px", left: vue.unref(tip).left + "px" })
3060
+ }, vue.toDisplayString(vue.unref(tip).text), 7)) : vue.createCommentVNode("", true)
3061
+ ]))
3062
+ ], 4);
3012
3063
  };
3013
3064
  }
3014
3065
  });
3015
- const FTable = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-ce2c2d93"]]);
3066
+ const FTable = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-5ae2ec2c"]]);
3016
3067
  const _hoisted_1$d = { class: "f-upload" };
3017
3068
  const _hoisted_2$b = ["accept", "multiple"];
3018
3069
  const _hoisted_3$b = { class: "f-upload__zone" };
@@ -11,7 +11,7 @@ declare var __VLS_2: `header-${string}`, __VLS_3: {
11
11
  value: unknown;
12
12
  index: number;
13
13
  col: import("../../types/index").FTableColumn;
14
- }, __VLS_14: {};
14
+ }, __VLS_11: {};
15
15
  type __VLS_Slots = {} & {
16
16
  [K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
17
17
  } & {
@@ -19,15 +19,14 @@ type __VLS_Slots = {} & {
19
19
  } & {
20
20
  cell?: (props: typeof __VLS_9) => any;
21
21
  } & {
22
- empty?: (props: typeof __VLS_14) => any;
22
+ empty?: (props: typeof __VLS_11) => any;
23
23
  };
24
24
  declare const __VLS_component: import("vue").DefineComponent<FTableProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FTableProps> & Readonly<{}>, {
25
- loading: boolean;
26
25
  rowHeight: number;
27
26
  overscan: number;
28
27
  showIndex: boolean;
29
- loadingText: string;
30
28
  emptyText: string;
29
+ overflowTooltip: boolean;
31
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
31
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
33
32
  export default _default;
@@ -5,6 +5,7 @@ interface FTableColumn {
5
5
  minWidth?: string;
6
6
  thClass?: string | Record<string, boolean>;
7
7
  tdClass?: string | Record<string, boolean>;
8
+ tooltip?: boolean;
8
9
  }
9
10
  interface FTableProps {
10
11
  data: Record<string, unknown>[];
@@ -12,8 +13,12 @@ interface FTableProps {
12
13
  rowHeight?: number;
13
14
  overscan?: number;
14
15
  showIndex?: boolean;
15
- loading?: boolean;
16
- loadingText?: string;
17
16
  emptyText?: string;
17
+ /** 行唯一键字段,不传则按下标 */
18
+ rowKey?: string;
19
+ /** 表格高度,如 400 / '60vh';不传则由外层容器决定 */
20
+ height?: number | string;
21
+ /** 默认文本单元格被截断时,是否显示 tooltip(列上的 tooltip 可单独覆盖) */
22
+ overflowTooltip?: boolean;
18
23
  }
19
24
  export type { FTableColumn, FTableProps };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fantasia-ui",
3
3
  "private": false,
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "type": "module",
6
6
  "main": "dist/fantasia-ui.umd.js",
7
7
  "module": "dist/fantasia-ui.es.js",