@will-ui/vue 1.0.1 → 1.0.2

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 (92) hide show
  1. package/dist/components/btn/Btn.d.ts +4 -7
  2. package/dist/components/btn/Btn.js +1 -0
  3. package/dist/components/btn/Btn.js.map +1 -1
  4. package/dist/components/cascade/Cascade.d.ts +1 -1
  5. package/dist/components/choose/Choose.d.ts +4 -2
  6. package/dist/components/choose2/Choose2.d.ts +1 -1
  7. package/dist/components/confirm/index.d.ts +3 -4
  8. package/dist/components/confirm/index.js.map +1 -1
  9. package/dist/components/copy/Copy.d.ts +8 -8
  10. package/dist/components/copy/Copy.js +3 -2
  11. package/dist/components/copy/Copy.js.map +1 -1
  12. package/dist/components/cornerEars/CornerEars.d.ts +4 -7
  13. package/dist/components/cornerEars/CornerEars.js +1 -0
  14. package/dist/components/cornerEars/CornerEars.js.map +1 -1
  15. package/dist/components/date/DatePanel.d.ts +4 -0
  16. package/dist/components/date/DatePanel.js +2 -2
  17. package/dist/components/date/DatePanel.js.map +1 -1
  18. package/dist/components/date/DatePicker.d.ts +1 -1
  19. package/dist/components/date/DatePicker.js +4 -4
  20. package/dist/components/date/DatePicker.js.map +1 -1
  21. package/dist/components/date/Days.d.ts +2 -4
  22. package/dist/components/date/Days.js +1 -3
  23. package/dist/components/date/Days.js.map +1 -1
  24. package/dist/components/date/Months.d.ts +2 -4
  25. package/dist/components/date/Months.js +1 -3
  26. package/dist/components/date/Months.js.map +1 -1
  27. package/dist/components/date/QuickDate.d.ts +2 -12
  28. package/dist/components/date/QuickDate.js +1 -1
  29. package/dist/components/date/QuickDate.js.map +1 -1
  30. package/dist/components/date/Years.d.ts +3 -6
  31. package/dist/components/date/Years.js +1 -8
  32. package/dist/components/date/Years.js.map +1 -1
  33. package/dist/components/form/_use/formRules.d.ts +1 -1
  34. package/dist/components/form/_use/formRules.js.map +1 -1
  35. package/dist/components/formItem/FormItem.js.map +1 -1
  36. package/dist/components/image/Image.d.ts +5 -7
  37. package/dist/components/image/Image.js +3 -2
  38. package/dist/components/image/Image.js.map +1 -1
  39. package/dist/components/index.js +9 -9
  40. package/dist/components/modal/Modal.d.ts +1 -1
  41. package/dist/components/modal/Modal.js +29 -24
  42. package/dist/components/modal/Modal.js.map +1 -1
  43. package/dist/components/notice/src/_util/index.d.ts +1 -1
  44. package/dist/components/notice/src/_util/index.js.map +1 -1
  45. package/dist/components/number/Number copy.d.ts +1 -1
  46. package/dist/components/number/Number.d.ts +1 -1
  47. package/dist/components/pagination/src/Pagination.d.ts +6 -4
  48. package/dist/components/picture/Picture.d.ts +5 -7
  49. package/dist/components/picture/Picture.js +6 -5
  50. package/dist/components/picture/Picture.js.map +1 -1
  51. package/dist/components/picture/PictureViewport.js +22 -32
  52. package/dist/components/picture/PictureViewport.js.map +1 -1
  53. package/dist/components/progress/Progress.d.ts +1 -1
  54. package/dist/components/scrollbar/Scrollbar.js +61 -78
  55. package/dist/components/scrollbar/Scrollbar.js.map +1 -1
  56. package/dist/components/sheet/Sheet.d.ts +3 -1
  57. package/dist/components/sheet/_cell.js +16 -27
  58. package/dist/components/sheet/_cell.js.map +1 -1
  59. package/dist/components/slider/Slider.d.ts +2 -2
  60. package/dist/components/slider/Slider.js +24 -41
  61. package/dist/components/slider/Slider.js.map +1 -1
  62. package/dist/components/tab/Tab.d.ts +3 -3
  63. package/dist/components/tab/Tab.js +6 -0
  64. package/dist/components/tab/Tab.js.map +1 -1
  65. package/dist/components/textarea/Textarea.d.ts +5 -13
  66. package/dist/components/textarea/Textarea.js +3 -2
  67. package/dist/components/textarea/Textarea.js.map +1 -1
  68. package/dist/components/time/Dial.js.map +1 -1
  69. package/dist/components/time/Dial.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/time/TimePicker.d.ts +14 -2
  71. package/dist/components/tree-choose/TreeChoose.d.ts +1 -1
  72. package/dist/components/tree-choose/TreeChoose.js.map +1 -1
  73. package/dist/components/virtual/Virtual.d.ts +5 -5
  74. package/dist/components/virtual/Virtual.js +6 -0
  75. package/dist/components/virtual/Virtual.js.map +1 -1
  76. package/dist/index.d.ts +20 -15
  77. package/dist/index.js +6 -5
  78. package/dist/use/index.d.ts +2 -0
  79. package/dist/use/useChildComponentsCollector.d.ts +5 -0
  80. package/dist/use/useChildComponentsCollector.js.map +1 -1
  81. package/dist/use/usePercentDrag.d.ts +1 -1
  82. package/dist/use/usePercentDrag.js +19 -29
  83. package/dist/use/usePercentDrag.js.map +1 -1
  84. package/dist/use/usePointerDrag.d.ts +50 -0
  85. package/dist/use/usePointerDrag.js +143 -0
  86. package/dist/use/usePointerDrag.js.map +1 -0
  87. package/dist/use/useUII18n.d.ts +10 -0
  88. package/dist/use/useUII18n.js.map +1 -1
  89. package/dist/use/useUpload.js +1 -1
  90. package/dist/use/useUpload.js.map +1 -1
  91. package/package.json +79 -88
  92. package/dist/use/useDrag.d.ts +0 -17
@@ -157,8 +157,8 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
157
157
  direction: DragDirection;
158
158
  modelValue: number;
159
159
  disabled: boolean;
160
- readonly: boolean;
161
160
  step: number;
161
+ readonly: boolean;
162
162
  showTooltip: boolean;
163
163
  hasInput: boolean;
164
164
  inputWidth: string;
@@ -803,10 +803,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
803
803
  color: string;
804
804
  cssVars: CssVars;
805
805
  disabled: boolean;
806
+ step: number;
806
807
  readonly: boolean;
807
808
  hasBtn: boolean;
808
809
  allowDecimal: boolean;
809
- step: number;
810
810
  }, {}, {
811
811
  Write: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
812
812
  modelValue: {
@@ -2,8 +2,9 @@ import { effectiveSizeVar, propColorToCssVars, propSizeToCssVars, toCssVarsStyle
2
2
  import useFormItem from "../../use/useFormItem.js";
3
3
  import Tooltip_default from "../tooltip/Tooltip.js";
4
4
  import { useUII18n } from "../../use/useUII18n.js";
5
+ import usePointerDrag from "../../use/usePointerDrag.js";
5
6
  import Number_default from "../number/Number.js";
6
- import { computed, createVNode, defineComponent, mergeProps, onBeforeUnmount, reactive, ref, watch } from "vue";
7
+ import { computed, createVNode, defineComponent, mergeProps, reactive, ref, watch } from "vue";
7
8
  //#region components/slider/Slider.tsx
8
9
  var MULTIPLES = 1e4;
9
10
  function toBig(n) {
@@ -127,7 +128,6 @@ var Slider_default = /* @__PURE__ */ defineComponent({
127
128
  const { formItem, useDisabled } = useFormItem();
128
129
  const disabled = useDisabled(computed(() => props.disabled));
129
130
  const meta = computed(() => stepMeta(props.min, props.max, props.step));
130
- const dragging = ref(false);
131
131
  const focused = ref(false);
132
132
  const hoverTip = ref(false);
133
133
  const showInvalidTip = ref(false);
@@ -139,7 +139,6 @@ var Slider_default = /* @__PURE__ */ defineComponent({
139
139
  const currentYValue = ref(props.modelValue);
140
140
  const rod = ref();
141
141
  const root = ref();
142
- let pointerId = null;
143
142
  const inactive = computed(() => disabled.value || props.readonly);
144
143
  const axis = computed(() => {
145
144
  const { x, y } = props.direction;
@@ -281,43 +280,28 @@ var Slider_default = /* @__PURE__ */ defineComponent({
281
280
  if (x) applyIndex(percentToIndex(px, total), "x");
282
281
  else if (y) applyIndex(percentToIndex(py, total), "y");
283
282
  }
284
- function endDrag(e) {
285
- if (!dragging.value) return;
286
- dragging.value = false;
287
- const el = root.value;
288
- if (el && pointerId != null) try {
289
- if (el.hasPointerCapture(pointerId)) el.releasePointerCapture(pointerId);
290
- } catch {}
291
- pointerId = null;
292
- document.body.style.userSelect = "";
293
- document.body.style.cursor = "";
294
- if (e) e.preventDefault();
295
- }
296
- function handlePointerDown(e) {
297
- if (inactive.value) return;
298
- if (e.pointerType === "mouse" && e.button !== 0) return;
299
- e.preventDefault();
300
- const el = root.value;
301
- if (!el) return;
302
- pointerId = e.pointerId;
303
- try {
304
- el.setPointerCapture(e.pointerId);
305
- } catch {}
306
- dragging.value = true;
307
- showInvalidTip.value = false;
308
- document.body.style.userSelect = "none";
309
- document.body.style.cursor = "grabbing";
310
- applyPointer(e);
311
- }
312
- function handlePointerMove(e) {
313
- if (!dragging.value || e.pointerId !== pointerId) return;
314
- e.preventDefault();
315
- applyPointer(e);
316
- }
317
- function handlePointerUp(e) {
318
- if (e.pointerId !== pointerId) return;
319
- endDrag(e);
320
- }
283
+ const { dragging, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp } = usePointerDrag({
284
+ events: "pointer",
285
+ bind: "capture",
286
+ cursor: "grabbing",
287
+ lockUserSelect: true,
288
+ disabled: () => inactive.value,
289
+ onStart: (e) => {
290
+ const pe = e;
291
+ if (pe.pointerType === "mouse" && pe.button !== 0) return false;
292
+ e.preventDefault();
293
+ if (!root.value) return false;
294
+ showInvalidTip.value = false;
295
+ applyPointer(pe);
296
+ },
297
+ onMove: (e) => {
298
+ e.preventDefault();
299
+ applyPointer(e);
300
+ },
301
+ onEnd: (e) => {
302
+ if (e) e.preventDefault();
303
+ }
304
+ });
321
305
  function nudge(delta) {
322
306
  if (inactive.value) return;
323
307
  const m = meta.value;
@@ -377,7 +361,6 @@ var Slider_default = /* @__PURE__ */ defineComponent({
377
361
  setByValue(props.modelValue, snapped === props.modelValue);
378
362
  });
379
363
  setByValue(props.modelValue);
380
- onBeforeUnmount(() => endDrag());
381
364
  return () => {
382
365
  const { x, y } = axis.value;
383
366
  const rodPosition = {};
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","names":["computed","mergeProps","ref","reactive","watch","onBeforeUnmount","defineComponent","createVNode","_createVNode","_mergeProps","Tooltip","Num","useUII18n","useFormItem","propSizeToCssVars","propColorToCssVars","effectiveSizeVar","toCssVarsStyle","MULTIPLES","toBig","n","Math","round","stepMeta","min","max","step","minB","maxB","lo","hi","stepB","fullCount","floor","lastFull","extraMax","total","indexToBig","i","m","iClamped","bigToIndex","vB","lastFullI","snappedB","abs","percentToIndex","p","name","components","props","modelValue","type","Number","default","showTooltip","Boolean","tip","Function","direction","Object","x","y","fill","hasInput","inputWidth","String","invalidateTip","undefined","disabled","readonly","size","color","cssVars","emits","input","value","percent","v","setup","emit","t","formItem","useDisabled","meta","dragging","focused","hoverTip","showInvalidTip","pos","left","top","currentXValue","currentYValue","rod","root","pointerId","inactive","axis","both","one","displayValue","lastEmitted","tipContent","rootTokenStyle","tooltipLayerStyle","sliderClass","tooltipOptions","placement","adjustPosition","manual","realTime","show","layerStyle","offset","arrowOffset","emitIfOneAxis","validate","applyIndex","which","silent","next","changed","setByValue","pointerPercent","e","el","knob","px","py","rect","getBoundingClientRect","rodW","offsetWidth","rodH","offsetHeight","ux","width","uy","height","clientX","clientY","applyPointer","ix","iy","endDrag","hasPointerCapture","releasePointerCapture","document","body","style","userSelect","cursor","preventDefault","handlePointerDown","pointerType","button","setPointerCapture","handlePointerMove","handlePointerUp","nudge","delta","handleKeydown","page","key","validateInputValue","snapped","rodPosition","progressSize","sliderRod","trigger","onMouseenter","onMouseleave","main","class","onFocus","onBlur","onKeydown","target","blur","parseFloat","isNaN"],"sources":["../../../components/slider/Slider.tsx"],"sourcesContent":["import {\r\n computed,\r\n mergeProps,\r\n ref,\r\n reactive,\r\n watch,\r\n onBeforeUnmount,\r\n defineComponent,\r\n} from 'vue'\r\nimport type { PropType } from 'vue'\r\nimport type {\r\n DragDirection,\r\n PlacementType,\r\n AdjustmentPosition,\r\n} from '../../config/types'\r\nimport Tooltip from '../tooltip/index'\r\nimport Num from '../number/index'\r\nimport { useUII18n } from '../../use/useUII18n'\r\nimport useFormItem from '../../use/useFormItem'\r\nimport {\r\n propSizeToCssVars,\r\n propColorToCssVars,\r\n effectiveSizeVar,\r\n toCssVarsStyle,\r\n type CssVars,\r\n} from '../../util'\r\n\r\nconst MULTIPLES = 10000\r\n\r\nfunction toBig(n: number) {\r\n return Math.round(n * MULTIPLES)\r\n}\r\n\r\nfunction stepMeta(min: number, max: number, step: number) {\r\n const minB = toBig(min)\r\n const maxB = toBig(max)\r\n const lo = Math.min(minB, maxB)\r\n const hi = Math.max(minB, maxB)\r\n const stepB = step > 0 ? Math.max(1, toBig(step)) : Math.max(1, hi - lo)\r\n const fullCount = Math.floor((hi - lo) / stepB) + 1\r\n const lastFull = lo + (fullCount - 1) * stepB\r\n const extraMax = lastFull !== hi\r\n return {\r\n lo,\r\n hi,\r\n stepB,\r\n fullCount,\r\n extraMax,\r\n total: extraMax ? fullCount + 1 : fullCount,\r\n }\r\n}\r\n\r\nfunction indexToBig(i: number, m: ReturnType<typeof stepMeta>) {\r\n const iClamped = Math.max(0, Math.min(m.total - 1, i))\r\n if (m.extraMax && iClamped === m.total - 1) return m.hi\r\n return m.lo + iClamped * m.stepB\r\n}\r\n\r\nfunction bigToIndex(vB: number, m: ReturnType<typeof stepMeta>) {\r\n const lastFullI = m.fullCount - 1\r\n const i = Math.max(0, Math.min(lastFullI, Math.round((vB - m.lo) / m.stepB)))\r\n const snappedB = m.lo + i * m.stepB\r\n if (m.extraMax && Math.abs(vB - m.hi) <= Math.abs(vB - snappedB)) {\r\n return m.total - 1\r\n }\r\n return i\r\n}\r\n\r\nfunction percentToIndex(p: number, total: number) {\r\n if (total <= 1) return 0\r\n return Math.round(Math.min(1, Math.max(0, p)) * (total - 1))\r\n}\r\n\r\nexport default defineComponent({\r\n name: 'Slider',\r\n components: {\r\n Tooltip,\r\n Num,\r\n },\r\n props: {\r\n modelValue: { type: Number, default: 0 },\r\n step: { type: Number, default: 2 },\r\n min: { type: Number, default: 0 },\r\n max: { type: Number, default: 30 },\r\n showTooltip: { type: Boolean, default: true },\r\n tip: { type: Function as PropType<(pos: { x: number; y: number }) => any> },\r\n direction: {\r\n type: Object as PropType<DragDirection>,\r\n default: () => ({\r\n x: true,\r\n y: false,\r\n }),\r\n },\r\n fill: { type: Boolean, default: true },\r\n hasInput: Boolean,\r\n inputWidth: {\r\n type: String,\r\n default: '3.5em',\r\n },\r\n invalidateTip: {\r\n type: String,\r\n default: undefined,\r\n },\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n readonly: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /** 实例尺度(px)→ --w-prop-slider-size;并桥接内部 Tooltip */\r\n size: { type: Number, default: undefined },\r\n /** 品牌主色 → `--w-prop-slider-color` */\r\n color: { type: String, default: undefined },\r\n /** 实例 CSS 变量 */\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n emits: {\r\n input: (value: number, percent?: number) => {\r\n return (\r\n typeof value === 'number' &&\r\n (percent === undefined || typeof percent === 'number')\r\n )\r\n },\r\n 'update:modelValue': (v: number) => {\r\n return typeof v === 'number'\r\n },\r\n },\r\n setup(props, { emit }) {\r\n const { t } = useUII18n()\r\n const { formItem, useDisabled } = useFormItem()\r\n const disabled = useDisabled(computed(() => props.disabled))\r\n\r\n const meta = computed(() => stepMeta(props.min, props.max, props.step))\r\n\r\n const dragging = ref(false)\r\n const focused = ref(false)\r\n const hoverTip = ref(false)\r\n const showInvalidTip = ref(false)\r\n const pos = reactive({ left: 0, top: 0 })\r\n const currentXValue = ref(props.modelValue)\r\n const currentYValue = ref(props.modelValue)\r\n const rod = ref<HTMLElement>()\r\n const root = ref<HTMLElement>()\r\n let pointerId: number | null = null\r\n\r\n const inactive = computed(() => disabled.value || props.readonly)\r\n const axis = computed(() => {\r\n const { x, y } = props.direction\r\n return {\r\n x: !!x,\r\n y: !!y,\r\n both: !!x && !!y,\r\n one: !!(x && !y) || !!(!x && y),\r\n }\r\n })\r\n\r\n const displayValue = computed(() =>\r\n axis.value.y && !axis.value.x ? currentYValue.value : currentXValue.value,\r\n )\r\n let lastEmitted = props.modelValue\r\n\r\n const tipContent = computed(() => {\r\n if (!props.showTooltip) return\r\n const { x, y } = axis.value\r\n if (props.tip) {\r\n return props.tip({ x: currentXValue.value, y: currentYValue.value })\r\n }\r\n if (x && y) return `${currentXValue.value},${currentYValue.value}`\r\n if (x) return currentXValue.value\r\n if (y) return currentYValue.value\r\n })\r\n\r\n const rootTokenStyle = computed(() =>\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('slider', props.size),\r\n ...propColorToCssVars('slider', props.color),\r\n ...props.cssVars,\r\n }),\r\n )\r\n\r\n const tooltipLayerStyle = computed(() =>\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('slider', props.size),\r\n ...propColorToCssVars('slider', props.color),\r\n '--w-prop-tooltip-size': effectiveSizeVar('slider'),\r\n ...props.cssVars,\r\n }),\r\n )\r\n\r\n const sliderClass = computed(() => {\r\n const { x, y } = axis.value\r\n return [\r\n 'w-slider',\r\n x && y ? 'w-slider-xy' : x ? 'w-slider-x' : y ? 'w-slider-y' : '',\r\n {\r\n 'w-slider-disabled': disabled.value,\r\n 'w-slider-readonly': props.readonly,\r\n 'w-slider-dragging': dragging.value,\r\n },\r\n ]\r\n })\r\n\r\n const tooltipOptions = computed(() => {\r\n const { x } = axis.value\r\n return {\r\n placement: (x ? 'top' : 'left') as PlacementType,\r\n adjustPosition: (x ? 'top' : 'left') as AdjustmentPosition,\r\n manual: true,\r\n realTime: true,\r\n show:\r\n (dragging.value || hoverTip.value || focused.value) &&\r\n props.showTooltip,\r\n layerStyle: tooltipLayerStyle.value,\r\n\r\n offset: { x: x ? 0 : -2, y: x ? -2 : 0 },\r\n arrowOffset: { x: x ? -3 : 0, y: x ? 0 : -3 },\r\n }\r\n })\r\n\r\n function emitIfOneAxis() {\r\n if (!axis.value.one) return\r\n const v = displayValue.value\r\n if (v === lastEmitted) return\r\n lastEmitted = v\r\n const percent = axis.value.x ? pos.left : pos.top\r\n emit('update:modelValue', v)\r\n emit('input', v, percent)\r\n formItem?.validate('change')\r\n }\r\n\r\n function applyIndex(i: number, which: 'x' | 'y' | 'both', silent = false) {\r\n const m = meta.value\r\n const next = indexToBig(i, m) / MULTIPLES\r\n const p =\r\n m.total <= 1 ? 0 : Math.max(0, Math.min(m.total - 1, i)) / (m.total - 1)\r\n let changed = false\r\n if (which === 'x' || which === 'both') {\r\n if (pos.left !== p) {\r\n pos.left = p\r\n changed = true\r\n }\r\n if (currentXValue.value !== next) {\r\n currentXValue.value = next\r\n changed = true\r\n }\r\n }\r\n if (which === 'y' || which === 'both') {\r\n if (pos.top !== p) {\r\n pos.top = p\r\n changed = true\r\n }\r\n if (currentYValue.value !== next) {\r\n currentYValue.value = next\r\n changed = true\r\n }\r\n }\r\n if (!silent && changed) emitIfOneAxis()\r\n }\r\n\r\n function setByValue(v: number, silent = true) {\r\n const i = bigToIndex(toBig(v), meta.value)\r\n const { x, y } = axis.value\r\n applyIndex(i, y && !x ? 'y' : 'x', silent)\r\n }\r\n\r\n function pointerPercent(e: PointerEvent) {\r\n const el = root.value\r\n const knob = rod.value\r\n if (!el) return { px: 0, py: 0 }\r\n const rect = el.getBoundingClientRect()\r\n const rodW = knob?.offsetWidth ?? 0\r\n const rodH = knob?.offsetHeight ?? 0\r\n const ux = Math.max(1, rect.width - rodW)\r\n const uy = Math.max(1, rect.height - rodH)\r\n return {\r\n px: (e.clientX - rect.left - rodW / 2) / ux,\r\n py: (e.clientY - rect.top - rodH / 2) / uy,\r\n }\r\n }\r\n\r\n function applyPointer(e: PointerEvent) {\r\n const { px, py } = pointerPercent(e)\r\n const total = meta.value.total\r\n const { x, y } = axis.value\r\n if (x && y) {\r\n const ix = percentToIndex(px, total)\r\n const iy = percentToIndex(py, total)\r\n const m = meta.value\r\n pos.left = total <= 1 ? 0 : ix / (total - 1)\r\n pos.top = total <= 1 ? 0 : iy / (total - 1)\r\n currentXValue.value = indexToBig(ix, m) / MULTIPLES\r\n currentYValue.value = indexToBig(iy, m) / MULTIPLES\r\n return\r\n }\r\n if (x) applyIndex(percentToIndex(px, total), 'x')\r\n else if (y) applyIndex(percentToIndex(py, total), 'y')\r\n }\r\n\r\n function endDrag(e?: PointerEvent) {\r\n if (!dragging.value) return\r\n dragging.value = false\r\n const el = root.value\r\n if (el && pointerId != null) {\r\n try {\r\n if (el.hasPointerCapture(pointerId))\r\n el.releasePointerCapture(pointerId)\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n pointerId = null\r\n document.body.style.userSelect = ''\r\n document.body.style.cursor = ''\r\n if (e) e.preventDefault()\r\n }\r\n\r\n function handlePointerDown(e: PointerEvent) {\r\n if (inactive.value) return\r\n if (e.pointerType === 'mouse' && e.button !== 0) return\r\n e.preventDefault()\r\n const el = root.value\r\n if (!el) return\r\n pointerId = e.pointerId\r\n try {\r\n el.setPointerCapture(e.pointerId)\r\n } catch {\r\n /* ignore */\r\n }\r\n dragging.value = true\r\n showInvalidTip.value = false\r\n document.body.style.userSelect = 'none'\r\n document.body.style.cursor = 'grabbing'\r\n applyPointer(e)\r\n }\r\n\r\n function handlePointerMove(e: PointerEvent) {\r\n if (!dragging.value || e.pointerId !== pointerId) return\r\n e.preventDefault()\r\n applyPointer(e)\r\n }\r\n\r\n function handlePointerUp(e: PointerEvent) {\r\n if (e.pointerId !== pointerId) return\r\n endDrag(e)\r\n }\r\n\r\n function nudge(delta: number) {\r\n if (inactive.value) return\r\n const m = meta.value\r\n const { x, y } = axis.value\r\n if (x && !y) {\r\n applyIndex(bigToIndex(toBig(currentXValue.value), m) + delta, 'x')\r\n } else if (y && !x) {\r\n applyIndex(bigToIndex(toBig(currentYValue.value), m) + delta, 'y')\r\n }\r\n }\r\n\r\n function handleKeydown(e: KeyboardEvent) {\r\n if (inactive.value || axis.value.both) return\r\n const m = meta.value\r\n const page = Math.max(1, Math.round((m.total - 1) / 10))\r\n switch (e.key) {\r\n case 'ArrowLeft':\r\n case 'ArrowDown':\r\n e.preventDefault()\r\n nudge(-1)\r\n break\r\n case 'ArrowRight':\r\n case 'ArrowUp':\r\n e.preventDefault()\r\n nudge(1)\r\n break\r\n case 'PageDown':\r\n e.preventDefault()\r\n nudge(-page)\r\n break\r\n case 'PageUp':\r\n e.preventDefault()\r\n nudge(page)\r\n break\r\n case 'Home':\r\n e.preventDefault()\r\n applyIndex(0, axis.value.x ? 'x' : 'y')\r\n break\r\n case 'End':\r\n e.preventDefault()\r\n applyIndex(m.total - 1, axis.value.x ? 'x' : 'y')\r\n break\r\n }\r\n }\r\n\r\n function validateInputValue(v: number): boolean {\r\n const m = meta.value\r\n return indexToBig(bigToIndex(toBig(v), m), m) === toBig(v)\r\n }\r\n\r\n watch(\r\n () => props.modelValue,\r\n (v) => {\r\n if (dragging.value || axis.value.both) return\r\n if (v === displayValue.value) return\r\n lastEmitted = v\r\n setByValue(v, true)\r\n },\r\n )\r\n\r\n watch(\r\n () => [props.min, props.max, props.step] as const,\r\n () => {\r\n if (dragging.value) return\r\n const snapped =\r\n indexToBig(\r\n bigToIndex(toBig(props.modelValue), meta.value),\r\n meta.value,\r\n ) / MULTIPLES\r\n setByValue(props.modelValue, snapped === props.modelValue)\r\n },\r\n )\r\n\r\n setByValue(props.modelValue)\r\n\r\n onBeforeUnmount(() => endDrag())\r\n\r\n return () => {\r\n const { x, y } = axis.value\r\n const rodPosition: Record<string, string> = {}\r\n const progressSize: { width?: string; height?: string } = {}\r\n if (x) {\r\n rodPosition['--__pos-x'] = String(pos.left)\r\n progressSize.width = `${pos.left * 100}%`\r\n }\r\n if (y) {\r\n rodPosition['--__pos-y'] = String(pos.top)\r\n progressSize.height = `${pos.top * 100}%`\r\n }\r\n\r\n const sliderRod = (\r\n <div class=\"w-slider-rod\" ref={rod} style={rodPosition}>\r\n <Tooltip {...tooltipOptions.value}>\r\n {{\r\n trigger: () => (\r\n <div\r\n class={[\r\n 'w-slider-for-tip',\r\n { 'rod-in-dragging': dragging.value },\r\n ]}\r\n onDragstart={(e: DragEvent) => e.preventDefault()}\r\n onMouseenter={() => (hoverTip.value = true)}\r\n onMouseleave={() => (hoverTip.value = false)}\r\n />\r\n ),\r\n default: () => tipContent.value,\r\n }}\r\n </Tooltip>\r\n </div>\r\n )\r\n\r\n const main = (\r\n <div\r\n {...mergeProps(\r\n {\r\n class: sliderClass.value,\r\n style: rootTokenStyle.value,\r\n },\r\n { ref: root },\r\n )}\r\n role={axis.value.both ? undefined : 'slider'}\r\n tabindex={disabled.value ? -1 : 0}\r\n aria-valuemin={props.min}\r\n aria-valuemax={props.max}\r\n aria-valuenow={displayValue.value}\r\n aria-orientation={\r\n axis.value.both ? undefined : x ? 'horizontal' : 'vertical'\r\n }\r\n aria-disabled={disabled.value || undefined}\r\n aria-readonly={props.readonly || undefined}\r\n onPointerdown={handlePointerDown}\r\n onPointermove={handlePointerMove}\r\n onPointerup={handlePointerUp}\r\n onPointercancel={handlePointerUp}\r\n onKeydown={handleKeydown}\r\n onFocus={() => (focused.value = true)}\r\n onBlur={() => (focused.value = false)}>\r\n {props.fill ? (\r\n <div class=\"w-slider-progress\" style={progressSize} />\r\n ) : null}\r\n {sliderRod}\r\n </div>\r\n )\r\n\r\n if (props.hasInput && !axis.value.both) {\r\n return (\r\n <div class=\"w-slider-has-input\">\r\n {main}\r\n <Tooltip\r\n real-time\r\n manual\r\n placement=\"top\"\r\n adjustPosition=\"bottom\"\r\n show={showInvalidTip.value}\r\n layerStyle={tooltipLayerStyle.value}>\r\n {{\r\n trigger: () => (\r\n <Num\r\n hasBtn={false}\r\n width={props.inputWidth}\r\n min={Math.min(props.min, props.max)}\r\n max={Math.max(props.min, props.max)}\r\n step={props.step}\r\n modelValue={props.modelValue}\r\n disabled={disabled.value}\r\n readonly={props.readonly}\r\n {...({\r\n onKeydown: (e: KeyboardEvent) => {\r\n if (inactive.value) return\r\n if (e.key === 'Enter') {\r\n ;(e.target as HTMLInputElement).blur()\r\n }\r\n },\r\n onBlur: (e: FocusEvent) => {\r\n if (inactive.value) return\r\n const target = e.target as HTMLInputElement\r\n const v = parseFloat(target.value)\r\n if (isNaN(v)) return\r\n if (validateInputValue(v)) {\r\n showInvalidTip.value = false\r\n setByValue(v, false)\r\n } else {\r\n showInvalidTip.value = true\r\n }\r\n },\r\n } as Record<string, unknown>)}\r\n />\r\n ),\r\n default: () => props.invalidateTip || t('slider.invalid'),\r\n }}\r\n </Tooltip>\r\n </div>\r\n )\r\n }\r\n\r\n return main\r\n }\r\n },\r\n})\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"Slider.js","names":["computed","mergeProps","ref","reactive","watch","defineComponent","createVNode","_createVNode","_mergeProps","Tooltip","Num","useUII18n","useFormItem","usePointerDrag","propSizeToCssVars","propColorToCssVars","effectiveSizeVar","toCssVarsStyle","MULTIPLES","toBig","n","Math","round","stepMeta","min","max","step","minB","maxB","lo","hi","stepB","fullCount","floor","lastFull","extraMax","total","indexToBig","i","m","iClamped","bigToIndex","vB","lastFullI","snappedB","abs","percentToIndex","p","name","components","props","modelValue","type","Number","default","showTooltip","Boolean","tip","Function","direction","Object","x","y","fill","hasInput","inputWidth","String","invalidateTip","undefined","disabled","readonly","size","color","cssVars","emits","input","value","percent","v","setup","emit","t","formItem","useDisabled","meta","focused","hoverTip","showInvalidTip","pos","left","top","currentXValue","currentYValue","rod","root","inactive","axis","both","one","displayValue","lastEmitted","tipContent","rootTokenStyle","tooltipLayerStyle","sliderClass","dragging","tooltipOptions","placement","adjustPosition","manual","realTime","show","layerStyle","offset","arrowOffset","emitIfOneAxis","validate","applyIndex","which","silent","next","changed","setByValue","pointerPercent","e","el","knob","px","py","rect","getBoundingClientRect","rodW","offsetWidth","rodH","offsetHeight","ux","width","uy","height","clientX","clientY","applyPointer","ix","iy","onPointerDown","handlePointerDown","onPointerMove","handlePointerMove","onPointerUp","handlePointerUp","events","bind","cursor","lockUserSelect","onStart","pe","pointerType","button","preventDefault","onMove","onEnd","nudge","delta","handleKeydown","page","key","validateInputValue","snapped","rodPosition","progressSize","sliderRod","trigger","onMouseenter","onMouseleave","main","class","style","onFocus","onBlur","onKeydown","target","blur","parseFloat","isNaN"],"sources":["../../../components/slider/Slider.tsx"],"sourcesContent":["import {\r\n computed,\r\n mergeProps,\r\n ref,\r\n reactive,\r\n watch,\r\n defineComponent,\r\n} from 'vue'\r\nimport type { PropType } from 'vue'\r\nimport type {\r\n DragDirection,\r\n PlacementType,\r\n AdjustmentPosition,\r\n} from '../../config/types'\r\nimport Tooltip from '../tooltip/index'\r\nimport Num from '../number/index'\r\nimport { useUII18n } from '../../use/useUII18n'\r\nimport useFormItem from '../../use/useFormItem'\r\nimport usePointerDrag from '../../use/usePointerDrag'\r\nimport {\r\n propSizeToCssVars,\r\n propColorToCssVars,\r\n effectiveSizeVar,\r\n toCssVarsStyle,\r\n type CssVars,\r\n} from '../../util'\r\n\r\nconst MULTIPLES = 10000\r\n\r\nfunction toBig(n: number) {\r\n return Math.round(n * MULTIPLES)\r\n}\r\n\r\nfunction stepMeta(min: number, max: number, step: number) {\r\n const minB = toBig(min)\r\n const maxB = toBig(max)\r\n const lo = Math.min(minB, maxB)\r\n const hi = Math.max(minB, maxB)\r\n const stepB = step > 0 ? Math.max(1, toBig(step)) : Math.max(1, hi - lo)\r\n const fullCount = Math.floor((hi - lo) / stepB) + 1\r\n const lastFull = lo + (fullCount - 1) * stepB\r\n const extraMax = lastFull !== hi\r\n return {\r\n lo,\r\n hi,\r\n stepB,\r\n fullCount,\r\n extraMax,\r\n total: extraMax ? fullCount + 1 : fullCount,\r\n }\r\n}\r\n\r\nfunction indexToBig(i: number, m: ReturnType<typeof stepMeta>) {\r\n const iClamped = Math.max(0, Math.min(m.total - 1, i))\r\n if (m.extraMax && iClamped === m.total - 1) return m.hi\r\n return m.lo + iClamped * m.stepB\r\n}\r\n\r\nfunction bigToIndex(vB: number, m: ReturnType<typeof stepMeta>) {\r\n const lastFullI = m.fullCount - 1\r\n const i = Math.max(0, Math.min(lastFullI, Math.round((vB - m.lo) / m.stepB)))\r\n const snappedB = m.lo + i * m.stepB\r\n if (m.extraMax && Math.abs(vB - m.hi) <= Math.abs(vB - snappedB)) {\r\n return m.total - 1\r\n }\r\n return i\r\n}\r\n\r\nfunction percentToIndex(p: number, total: number) {\r\n if (total <= 1) return 0\r\n return Math.round(Math.min(1, Math.max(0, p)) * (total - 1))\r\n}\r\n\r\nexport default defineComponent({\r\n name: 'Slider',\r\n components: {\r\n Tooltip,\r\n Num,\r\n },\r\n props: {\r\n modelValue: { type: Number, default: 0 },\r\n step: { type: Number, default: 2 },\r\n min: { type: Number, default: 0 },\r\n max: { type: Number, default: 30 },\r\n showTooltip: { type: Boolean, default: true },\r\n tip: { type: Function as PropType<(pos: { x: number; y: number }) => any> },\r\n direction: {\r\n type: Object as PropType<DragDirection>,\r\n default: () => ({\r\n x: true,\r\n y: false,\r\n }),\r\n },\r\n fill: { type: Boolean, default: true },\r\n hasInput: Boolean,\r\n inputWidth: {\r\n type: String,\r\n default: '3.5em',\r\n },\r\n invalidateTip: {\r\n type: String,\r\n default: undefined,\r\n },\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n readonly: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /** 实例尺度(px)→ --w-prop-slider-size;并桥接内部 Tooltip */\r\n size: { type: Number, default: undefined },\r\n /** 品牌主色 → `--w-prop-slider-color` */\r\n color: { type: String, default: undefined },\r\n /** 实例 CSS 变量 */\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n emits: {\r\n input: (value: number, percent?: number) => {\r\n return (\r\n typeof value === 'number' &&\r\n (percent === undefined || typeof percent === 'number')\r\n )\r\n },\r\n 'update:modelValue': (v: number) => {\r\n return typeof v === 'number'\r\n },\r\n },\r\n setup(props, { emit }) {\r\n const { t } = useUII18n()\r\n const { formItem, useDisabled } = useFormItem()\r\n const disabled = useDisabled(computed(() => props.disabled))\r\n\r\n const meta = computed(() => stepMeta(props.min, props.max, props.step))\r\n\r\n const focused = ref(false)\r\n const hoverTip = ref(false)\r\n const showInvalidTip = ref(false)\r\n const pos = reactive({ left: 0, top: 0 })\r\n const currentXValue = ref(props.modelValue)\r\n const currentYValue = ref(props.modelValue)\r\n const rod = ref<HTMLElement>()\r\n const root = ref<HTMLElement>()\r\n\r\n const inactive = computed(() => disabled.value || props.readonly)\r\n const axis = computed(() => {\r\n const { x, y } = props.direction\r\n return {\r\n x: !!x,\r\n y: !!y,\r\n both: !!x && !!y,\r\n one: !!(x && !y) || !!(!x && y),\r\n }\r\n })\r\n\r\n const displayValue = computed(() =>\r\n axis.value.y && !axis.value.x ? currentYValue.value : currentXValue.value,\r\n )\r\n let lastEmitted = props.modelValue\r\n\r\n const tipContent = computed(() => {\r\n if (!props.showTooltip) return\r\n const { x, y } = axis.value\r\n if (props.tip) {\r\n return props.tip({ x: currentXValue.value, y: currentYValue.value })\r\n }\r\n if (x && y) return `${currentXValue.value},${currentYValue.value}`\r\n if (x) return currentXValue.value\r\n if (y) return currentYValue.value\r\n })\r\n\r\n const rootTokenStyle = computed(() =>\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('slider', props.size),\r\n ...propColorToCssVars('slider', props.color),\r\n ...props.cssVars,\r\n }),\r\n )\r\n\r\n const tooltipLayerStyle = computed(() =>\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('slider', props.size),\r\n ...propColorToCssVars('slider', props.color),\r\n '--w-prop-tooltip-size': effectiveSizeVar('slider'),\r\n ...props.cssVars,\r\n }),\r\n )\r\n\r\n const sliderClass = computed(() => {\r\n const { x, y } = axis.value\r\n return [\r\n 'w-slider',\r\n x && y ? 'w-slider-xy' : x ? 'w-slider-x' : y ? 'w-slider-y' : '',\r\n {\r\n 'w-slider-disabled': disabled.value,\r\n 'w-slider-readonly': props.readonly,\r\n 'w-slider-dragging': dragging.value,\r\n },\r\n ]\r\n })\r\n\r\n const tooltipOptions = computed(() => {\r\n const { x } = axis.value\r\n return {\r\n placement: (x ? 'top' : 'left') as PlacementType,\r\n adjustPosition: (x ? 'top' : 'left') as AdjustmentPosition,\r\n manual: true,\r\n realTime: true,\r\n show:\r\n (dragging.value || hoverTip.value || focused.value) &&\r\n props.showTooltip,\r\n layerStyle: tooltipLayerStyle.value,\r\n\r\n offset: { x: x ? 0 : -2, y: x ? -2 : 0 },\r\n arrowOffset: { x: x ? -3 : 0, y: x ? 0 : -3 },\r\n }\r\n })\r\n\r\n function emitIfOneAxis() {\r\n if (!axis.value.one) return\r\n const v = displayValue.value\r\n if (v === lastEmitted) return\r\n lastEmitted = v\r\n const percent = axis.value.x ? pos.left : pos.top\r\n emit('update:modelValue', v)\r\n emit('input', v, percent)\r\n formItem?.validate('change')\r\n }\r\n\r\n function applyIndex(i: number, which: 'x' | 'y' | 'both', silent = false) {\r\n const m = meta.value\r\n const next = indexToBig(i, m) / MULTIPLES\r\n const p =\r\n m.total <= 1 ? 0 : Math.max(0, Math.min(m.total - 1, i)) / (m.total - 1)\r\n let changed = false\r\n if (which === 'x' || which === 'both') {\r\n if (pos.left !== p) {\r\n pos.left = p\r\n changed = true\r\n }\r\n if (currentXValue.value !== next) {\r\n currentXValue.value = next\r\n changed = true\r\n }\r\n }\r\n if (which === 'y' || which === 'both') {\r\n if (pos.top !== p) {\r\n pos.top = p\r\n changed = true\r\n }\r\n if (currentYValue.value !== next) {\r\n currentYValue.value = next\r\n changed = true\r\n }\r\n }\r\n if (!silent && changed) emitIfOneAxis()\r\n }\r\n\r\n function setByValue(v: number, silent = true) {\r\n const i = bigToIndex(toBig(v), meta.value)\r\n const { x, y } = axis.value\r\n applyIndex(i, y && !x ? 'y' : 'x', silent)\r\n }\r\n\r\n function pointerPercent(e: PointerEvent) {\r\n const el = root.value\r\n const knob = rod.value\r\n if (!el) return { px: 0, py: 0 }\r\n const rect = el.getBoundingClientRect()\r\n const rodW = knob?.offsetWidth ?? 0\r\n const rodH = knob?.offsetHeight ?? 0\r\n const ux = Math.max(1, rect.width - rodW)\r\n const uy = Math.max(1, rect.height - rodH)\r\n return {\r\n px: (e.clientX - rect.left - rodW / 2) / ux,\r\n py: (e.clientY - rect.top - rodH / 2) / uy,\r\n }\r\n }\r\n\r\n function applyPointer(e: PointerEvent) {\r\n const { px, py } = pointerPercent(e)\r\n const total = meta.value.total\r\n const { x, y } = axis.value\r\n if (x && y) {\r\n const ix = percentToIndex(px, total)\r\n const iy = percentToIndex(py, total)\r\n const m = meta.value\r\n pos.left = total <= 1 ? 0 : ix / (total - 1)\r\n pos.top = total <= 1 ? 0 : iy / (total - 1)\r\n currentXValue.value = indexToBig(ix, m) / MULTIPLES\r\n currentYValue.value = indexToBig(iy, m) / MULTIPLES\r\n return\r\n }\r\n if (x) applyIndex(percentToIndex(px, total), 'x')\r\n else if (y) applyIndex(percentToIndex(py, total), 'y')\r\n }\r\n\r\n const {\r\n dragging,\r\n onPointerDown: handlePointerDown,\r\n onPointerMove: handlePointerMove,\r\n onPointerUp: handlePointerUp,\r\n } = usePointerDrag({\r\n events: 'pointer',\r\n bind: 'capture',\r\n cursor: 'grabbing',\r\n lockUserSelect: true,\r\n disabled: () => inactive.value,\r\n onStart: (e) => {\r\n const pe = e as PointerEvent\r\n if (pe.pointerType === 'mouse' && pe.button !== 0) return false\r\n e.preventDefault()\r\n if (!root.value) return false\r\n showInvalidTip.value = false\r\n applyPointer(pe)\r\n },\r\n onMove: (e) => {\r\n e.preventDefault()\r\n applyPointer(e as PointerEvent)\r\n },\r\n onEnd: (e) => {\r\n if (e) e.preventDefault()\r\n },\r\n })\r\n\r\n function nudge(delta: number) {\r\n if (inactive.value) return\r\n const m = meta.value\r\n const { x, y } = axis.value\r\n if (x && !y) {\r\n applyIndex(bigToIndex(toBig(currentXValue.value), m) + delta, 'x')\r\n } else if (y && !x) {\r\n applyIndex(bigToIndex(toBig(currentYValue.value), m) + delta, 'y')\r\n }\r\n }\r\n\r\n function handleKeydown(e: KeyboardEvent) {\r\n if (inactive.value || axis.value.both) return\r\n const m = meta.value\r\n const page = Math.max(1, Math.round((m.total - 1) / 10))\r\n switch (e.key) {\r\n case 'ArrowLeft':\r\n case 'ArrowDown':\r\n e.preventDefault()\r\n nudge(-1)\r\n break\r\n case 'ArrowRight':\r\n case 'ArrowUp':\r\n e.preventDefault()\r\n nudge(1)\r\n break\r\n case 'PageDown':\r\n e.preventDefault()\r\n nudge(-page)\r\n break\r\n case 'PageUp':\r\n e.preventDefault()\r\n nudge(page)\r\n break\r\n case 'Home':\r\n e.preventDefault()\r\n applyIndex(0, axis.value.x ? 'x' : 'y')\r\n break\r\n case 'End':\r\n e.preventDefault()\r\n applyIndex(m.total - 1, axis.value.x ? 'x' : 'y')\r\n break\r\n }\r\n }\r\n\r\n function validateInputValue(v: number): boolean {\r\n const m = meta.value\r\n return indexToBig(bigToIndex(toBig(v), m), m) === toBig(v)\r\n }\r\n\r\n watch(\r\n () => props.modelValue,\r\n (v) => {\r\n if (dragging.value || axis.value.both) return\r\n if (v === displayValue.value) return\r\n lastEmitted = v\r\n setByValue(v, true)\r\n },\r\n )\r\n\r\n watch(\r\n () => [props.min, props.max, props.step] as const,\r\n () => {\r\n if (dragging.value) return\r\n const snapped =\r\n indexToBig(\r\n bigToIndex(toBig(props.modelValue), meta.value),\r\n meta.value,\r\n ) / MULTIPLES\r\n setByValue(props.modelValue, snapped === props.modelValue)\r\n },\r\n )\r\n\r\n setByValue(props.modelValue)\r\n\r\n return () => {\r\n const { x, y } = axis.value\r\n const rodPosition: Record<string, string> = {}\r\n const progressSize: { width?: string; height?: string } = {}\r\n if (x) {\r\n rodPosition['--__pos-x'] = String(pos.left)\r\n progressSize.width = `${pos.left * 100}%`\r\n }\r\n if (y) {\r\n rodPosition['--__pos-y'] = String(pos.top)\r\n progressSize.height = `${pos.top * 100}%`\r\n }\r\n\r\n const sliderRod = (\r\n <div class=\"w-slider-rod\" ref={rod} style={rodPosition}>\r\n <Tooltip {...tooltipOptions.value}>\r\n {{\r\n trigger: () => (\r\n <div\r\n class={[\r\n 'w-slider-for-tip',\r\n { 'rod-in-dragging': dragging.value },\r\n ]}\r\n onDragstart={(e: DragEvent) => e.preventDefault()}\r\n onMouseenter={() => (hoverTip.value = true)}\r\n onMouseleave={() => (hoverTip.value = false)}\r\n />\r\n ),\r\n default: () => tipContent.value,\r\n }}\r\n </Tooltip>\r\n </div>\r\n )\r\n\r\n const main = (\r\n <div\r\n {...mergeProps(\r\n {\r\n class: sliderClass.value,\r\n style: rootTokenStyle.value,\r\n },\r\n { ref: root },\r\n )}\r\n role={axis.value.both ? undefined : 'slider'}\r\n tabindex={disabled.value ? -1 : 0}\r\n aria-valuemin={props.min}\r\n aria-valuemax={props.max}\r\n aria-valuenow={displayValue.value}\r\n aria-orientation={\r\n axis.value.both ? undefined : x ? 'horizontal' : 'vertical'\r\n }\r\n aria-disabled={disabled.value || undefined}\r\n aria-readonly={props.readonly || undefined}\r\n onPointerdown={handlePointerDown}\r\n onPointermove={handlePointerMove}\r\n onPointerup={handlePointerUp}\r\n onPointercancel={handlePointerUp}\r\n onKeydown={handleKeydown}\r\n onFocus={() => (focused.value = true)}\r\n onBlur={() => (focused.value = false)}>\r\n {props.fill ? (\r\n <div class=\"w-slider-progress\" style={progressSize} />\r\n ) : null}\r\n {sliderRod}\r\n </div>\r\n )\r\n\r\n if (props.hasInput && !axis.value.both) {\r\n return (\r\n <div class=\"w-slider-has-input\">\r\n {main}\r\n <Tooltip\r\n real-time\r\n manual\r\n placement=\"top\"\r\n adjustPosition=\"bottom\"\r\n show={showInvalidTip.value}\r\n layerStyle={tooltipLayerStyle.value}>\r\n {{\r\n trigger: () => (\r\n <Num\r\n hasBtn={false}\r\n width={props.inputWidth}\r\n min={Math.min(props.min, props.max)}\r\n max={Math.max(props.min, props.max)}\r\n step={props.step}\r\n modelValue={props.modelValue}\r\n disabled={disabled.value}\r\n readonly={props.readonly}\r\n {...({\r\n onKeydown: (e: KeyboardEvent) => {\r\n if (inactive.value) return\r\n if (e.key === 'Enter') {\r\n ;(e.target as HTMLInputElement).blur()\r\n }\r\n },\r\n onBlur: (e: FocusEvent) => {\r\n if (inactive.value) return\r\n const target = e.target as HTMLInputElement\r\n const v = parseFloat(target.value)\r\n if (isNaN(v)) return\r\n if (validateInputValue(v)) {\r\n showInvalidTip.value = false\r\n setByValue(v, false)\r\n } else {\r\n showInvalidTip.value = true\r\n }\r\n },\r\n } as Record<string, unknown>)}\r\n />\r\n ),\r\n default: () => props.invalidateTip || t('slider.invalid'),\r\n }}\r\n </Tooltip>\r\n </div>\r\n )\r\n }\r\n\r\n return main\r\n }\r\n },\r\n})\r\n"],"mappings":"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"}
@@ -99,15 +99,15 @@ export type TabExpose = {
99
99
  };
100
100
  /**
101
101
  * Vue JSX 通过 `$props` 取属性(不支持 `<Tab<T>>`)。
102
+ * 勿再 `export type TabComponent = typeof Tab`,否则 hover 只显示别名。
102
103
  * `<Tab data={list} v-slots={{ content: ({ item, value }) => ... }} />`
103
104
  * 会从 list 元素类型推断 item / value。
104
105
  */
105
- export type TabComponent = {
106
+ declare const Tab: {
106
107
  new <T = any>(): TabExpose & {
107
108
  $props: TabJSXProps<T>;
108
109
  };
109
110
  };
110
- declare const Tab: TabComponent;
111
111
  /** 实例类型;一般写 `InstanceType<typeof Tab>` 即可 */
112
- export type TabInstance = InstanceType<TabComponent>;
112
+ export type TabInstance = InstanceType<typeof Tab>;
113
113
  export default Tab;
@@ -1,6 +1,12 @@
1
1
  import { propColorToCssVars, propSizeToCssVars, toCssVarsStyle } from "../../util/cssVars.js";
2
2
  import { computed, createVNode, defineComponent, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
3
3
  //#region components/tab/Tab.tsx
4
+ /**
5
+ * Vue JSX 通过 `$props` 取属性(不支持 `<Tab<T>>`)。
6
+ * 勿再 `export type TabComponent = typeof Tab`,否则 hover 只显示别名。
7
+ * `<Tab data={list} v-slots={{ content: ({ item, value }) => ... }} />`
8
+ * 会从 list 元素类型推断 item / value。
9
+ */
4
10
  var Tab = /* @__PURE__ */ defineComponent({
5
11
  name: "Tab",
6
12
  props: {
@@ -1 +1 @@
1
- {"version":3,"file":"Tab.js","names":["defineComponent","reactive","ref","computed","watch","nextTick","onMounted","onBeforeUnmount","createVNode","_createVNode","propColorToCssVars","propSizeToCssVars","toCssVarsStyle","TabImpl","name","props","modelValue","type","String","Number","Boolean","Object","default","undefined","index","data","Array","required","itemClass","activeItemClass","lineStyle","Function","direction","showLine","lineWidth","lineHeight","closable","labelField","valueField","color","size","cssVars","emits","value","change","item","click","close","slots","setup","emit","expose","rootRef","lineRef","items","currentIndex","linePos","left","top","width","height","processedData","isArray","map","_index","label","entries","key","dataLength","length","currentItem","currentValue","isVertical","computedLineStyle","parseFloat","x","y","transform","containerClass","clampIndex","Math","min","max","findIndexByValue","findIndex","findEnabledIndex","from","step","len","i","n","disabled","resolveIndexFromProps","byValue","syncActive","options","next","changed","emitChange","getItemLabel","getItemClass","filter","createSlotOptions","isActive","handleClick","handleClose","event","stopPropagation","handleKeydown","vertical","preventDefault","focus","list","active","deep","rafId","measureLine","root","activeItem","rootRect","getBoundingClientRect","itemRect","scheduleUpdate","requestAnimationFrame","flush","resizeObserver","ResizeObserver","observe","disconnect","cancelAnimationFrame","setIndex","setValue","tokenStyle","content","slotOptions","itemClosable","el","onClick","e","panelScope","Tab"],"sources":["../../../components/tab/Tab.tsx"],"sourcesContent":["import {\r\n defineComponent,\r\n reactive,\r\n ref,\r\n computed,\r\n watch,\r\n nextTick,\r\n onMounted,\r\n onBeforeUnmount,\r\n} from 'vue'\r\nimport type { PropType, SlotsType } from 'vue'\r\nimport { propColorToCssVars, propSizeToCssVars, toCssVarsStyle, type CssVars } from '../../util'\r\n\r\n// ==================== 类型定义 ====================\r\n\r\n/**\r\n * 标签项基础字段(勿加 [key: string]: any,否则会冲掉 label/value 提示)\r\n * 业务扩展字段通过 data 元素类型 T 自动带上\r\n */\r\nexport interface TabItem {\r\n label?: string\r\n value?: any\r\n disabled?: boolean\r\n closable?: boolean\r\n}\r\n\r\n/**\r\n * 标签数据源:对象数组 / 纯字符串数组 / 键值对对象\r\n */\r\nexport type TabData<T = TabItem> =\r\n | T[]\r\n | string[]\r\n | number[]\r\n | Record<string, any>\r\n\r\n/** 字符串/数字项在组件内会被规范化成 { label, value } */\r\nexport type NormalizedTabItem<T> = T extends string | number\r\n ? { label: T; value: T; disabled?: boolean; closable?: boolean }\r\n : T\r\n\r\ntype TabItemValue<T> =\r\n NormalizedTabItem<T> extends { value?: infer V } ? V : any\r\n\r\ntype TabItemLabel<T> =\r\n NormalizedTabItem<T> extends { label?: infer L } ? L : any\r\n\r\n/**\r\n * 插槽作用域;T 由 data 元素类型推断,一般不用手写\r\n */\r\nexport interface TabSlotScope<T = TabItem> {\r\n index: number\r\n item: NormalizedTabItem<T>\r\n value: TabItemValue<T>\r\n label: TabItemLabel<T>\r\n isActive: boolean\r\n}\r\n\r\n/**\r\n * 线条位置类型\r\n */\r\nexport interface LinePosition {\r\n left: number\r\n top: number\r\n width: number\r\n height: number\r\n}\r\n\r\n/**\r\n * 标签方向\r\n */\r\nexport type TabDirection = 'horizontal' | 'vertical'\r\n\r\n/**\r\n * 标签类型\r\n */\r\nexport type TabType = 'default' | 'card' | 'border-card'\r\n\r\nexport type TabSlots<T = any> = {\r\n default?: (scope: TabSlotScope<T>) => any\r\n close?: (scope: TabSlotScope<T>) => any\r\n /** 当前激活标签对应的内容区 */\r\n content?: (scope: TabSlotScope<T>) => any\r\n}\r\n\r\nexport interface TabProps<T = any> {\r\n modelValue?: any\r\n index?: number\r\n data?: TabData<T>\r\n itemClass?:\r\n | string\r\n | Record<string, boolean>\r\n | (string | Record<string, boolean>)[]\r\n activeItemClass?:\r\n | string\r\n | Record<string, boolean>\r\n | (string | Record<string, boolean>)[]\r\n lineStyle?: (pos: LinePosition) => Record<string, string | number>\r\n direction?: TabDirection\r\n type?: TabType\r\n showLine?: boolean\r\n lineWidth?: number | string\r\n lineHeight?: number | string\r\n closable?: boolean\r\n labelField?: string\r\n valueField?: string\r\n /** 品牌主色 → `--w-prop-tab-color` */\r\n color?: string\r\n /** 实例尺度(px)→ `--w-prop-tab-size` */\r\n size?: number\r\n /** 实例 CSS 变量 */\r\n cssVars?: CssVars\r\n}\r\n\r\n/** Vue TSX:$props 含 v-slots,才能从 data 推断插槽 T */\r\nexport type TabJSXProps<T = any> = TabProps<T> & {\r\n 'v-slots'?: TabSlots<T>\r\n vSlots?: TabSlots<T>\r\n class?: unknown\r\n style?: unknown\r\n 'onUpdate:modelValue'?: (value: any) => void\r\n 'onUpdate:index'?: (index: number) => void\r\n onChange?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n onClick?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n onClose?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n}\r\n\r\nexport type TabExpose = {\r\n setIndex: (index: number) => void\r\n setValue: (value: any) => void\r\n}\r\n\r\n/**\r\n * Vue JSX 通过 `$props` 取属性(不支持 `<Tab<T>>`)。\r\n * `<Tab data={list} v-slots={{ content: ({ item, value }) => ... }} />`\r\n * 会从 list 元素类型推断 item / value。\r\n */\r\nexport type TabComponent = {\r\n new <T = any>(): TabExpose & {\r\n $props: TabJSXProps<T>\r\n }\r\n}\r\n\r\n// ==================== 组件定义 ====================\r\n\r\nconst TabImpl = defineComponent({\r\n name: 'Tab',\r\n\r\n props: {\r\n /**\r\n * 当前激活标签的值(v-model)\r\n * 与 index 二选一即可;同时传入时以 modelValue 为准\r\n */\r\n modelValue: {\r\n type: [String, Number, Boolean, Object] as PropType<any>,\r\n default: undefined,\r\n },\r\n\r\n /**\r\n * 当前激活标签索引(v-model:index)\r\n * @default 0\r\n */\r\n index: {\r\n type: Number,\r\n default: 0,\r\n },\r\n\r\n /**\r\n * 标签数据源\r\n * 支持格式:\r\n * - 对象数组: [{ label: '标签名', value: '值' }]\r\n * - 纯字符串数组: ['标签1', '标签2']\r\n * - 键值对对象: { '标签1': '值1', '标签2': '值2' }\r\n */\r\n data: {\r\n type: [Array, Object] as PropType<TabData>,\r\n required: true,\r\n },\r\n\r\n /**\r\n * 自定义标签项 CSS 类名\r\n */\r\n itemClass: {\r\n type: [String, Object, Array] as PropType<\r\n string | Record<string, boolean> | (string | Record<string, boolean>)[]\r\n >,\r\n },\r\n\r\n /**\r\n * 激活态额外 CSS 类名\r\n */\r\n activeItemClass: {\r\n type: [String, Object, Array] as PropType<\r\n string | Record<string, boolean> | (string | Record<string, boolean>)[]\r\n >,\r\n },\r\n\r\n /**\r\n * 自定义指示线条样式\r\n */\r\n lineStyle: {\r\n type: Function as PropType<\r\n (pos: LinePosition) => Record<string, string | number>\r\n >,\r\n },\r\n\r\n /**\r\n * 标签方向\r\n * @default 'horizontal'\r\n */\r\n direction: {\r\n type: String as PropType<TabDirection>,\r\n default: 'horizontal',\r\n },\r\n\r\n /**\r\n * 标签类型\r\n * @default 'default'\r\n */\r\n type: {\r\n type: String as PropType<TabType>,\r\n default: 'default',\r\n },\r\n\r\n /**\r\n * 是否显示激活线条\r\n * @default true\r\n */\r\n showLine: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n\r\n /**\r\n * 线条宽度,默认与标签内容宽度一致(水平方向)\r\n */\r\n lineWidth: {\r\n type: [Number, String] as PropType<number | string>,\r\n },\r\n\r\n /**\r\n * 线条高度,默认与标签内容高度一致(垂直方向)\r\n * @default 2\r\n */\r\n lineHeight: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: 2,\r\n },\r\n\r\n /**\r\n * 是否可关闭\r\n * @default false\r\n */\r\n closable: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n\r\n /**\r\n * 数据中标签文字的字段名\r\n * @default 'label'\r\n */\r\n labelField: {\r\n type: String,\r\n default: 'label',\r\n },\r\n\r\n /**\r\n * 数据中值的字段名\r\n * @default 'value'\r\n */\r\n valueField: {\r\n type: String,\r\n default: 'value',\r\n },\r\n\r\n /** 品牌主色 → `--w-prop-tab-color` */\r\n color: { type: String, default: undefined },\r\n /** 实例尺度(px)→ `--w-prop-tab-size` */\r\n size: { type: Number, default: undefined },\r\n /** 实例 CSS 变量 */\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n\r\n emits: {\r\n /**\r\n * 值变化事件(用于 v-model)\r\n */\r\n 'update:modelValue': (value: any) => true,\r\n\r\n /**\r\n * 索引变化事件(用于 v-model:index)\r\n */\r\n 'update:index': (index: number) => true,\r\n\r\n /**\r\n * 切换标签时触发\r\n */\r\n change: (value: any, index: number, item: any) => true,\r\n\r\n /**\r\n * 点击标签时触发(无论是否切换)\r\n */\r\n click: (value: any, index: number, item: any) => true,\r\n\r\n /**\r\n * 关闭标签时触发\r\n */\r\n close: (value: any, index: number, item: any) => true,\r\n },\r\n\r\n slots: Object as SlotsType<TabSlots>,\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const rootRef = ref<HTMLElement>()\r\n const lineRef = ref<HTMLElement>()\r\n const items = ref<(HTMLElement | null)[]>([])\r\n const currentIndex = ref(0)\r\n\r\n const linePos = reactive<LinePosition>({\r\n left: 0,\r\n top: 0,\r\n width: 0,\r\n height: 0,\r\n })\r\n\r\n const processedData = computed(() => {\r\n const { data, labelField, valueField } = props\r\n\r\n if (Array.isArray(data)) {\r\n return data.map((item, index) => {\r\n if (typeof item === 'string' || typeof item === 'number') {\r\n return {\r\n [labelField]: item,\r\n [valueField]: item,\r\n _index: index,\r\n }\r\n }\r\n return {\r\n ...item,\r\n [labelField]: item[labelField] ?? item.label ?? String(index),\r\n [valueField]:\r\n item[valueField] !== undefined\r\n ? item[valueField]\r\n : item.value !== undefined\r\n ? item.value\r\n : index,\r\n _index: index,\r\n }\r\n })\r\n }\r\n\r\n return Object.entries(data || {}).map(([key, value], index) => ({\r\n [labelField]: key,\r\n [valueField]: value,\r\n _index: index,\r\n }))\r\n })\r\n\r\n const dataLength = computed(() => processedData.value.length)\r\n\r\n const currentItem = computed(\r\n () => processedData.value[currentIndex.value] as TabItem | undefined,\r\n )\r\n\r\n const currentValue = computed(() => {\r\n const item = currentItem.value\r\n return item?.[props.valueField]\r\n })\r\n\r\n const isVertical = computed(() => props.direction === 'vertical')\r\n\r\n const computedLineStyle = computed(() => {\r\n const { lineStyle, lineWidth, lineHeight } = props\r\n\r\n if (lineStyle) {\r\n return lineStyle(linePos)\r\n }\r\n\r\n // 使用 transform: translate3d 进行位移,避免 left/top 过渡引发重排\r\n if (isVertical.value) {\r\n let height = linePos.height\r\n if (lineHeight !== undefined) {\r\n height =\r\n typeof lineHeight === 'number'\r\n ? lineHeight\r\n : parseFloat(String(lineHeight))\r\n }\r\n const width =\r\n lineWidth !== undefined\r\n ? typeof lineWidth === 'number'\r\n ? lineWidth\r\n : parseFloat(String(lineWidth))\r\n : 2\r\n\r\n const x = linePos.left + linePos.width - width\r\n const y =\r\n lineHeight !== undefined\r\n ? linePos.top + (linePos.height - height) / 2\r\n : linePos.top\r\n\r\n return {\r\n transform: `translate3d(${x}px, ${y}px, 0)`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n }\r\n }\r\n\r\n let width = linePos.width\r\n if (lineWidth !== undefined) {\r\n width =\r\n typeof lineWidth === 'number'\r\n ? lineWidth\r\n : parseFloat(String(lineWidth))\r\n }\r\n const height =\r\n typeof lineHeight === 'number'\r\n ? lineHeight\r\n : parseFloat(String(lineHeight))\r\n\r\n const x =\r\n lineWidth !== undefined\r\n ? linePos.left + (linePos.width - width) / 2\r\n : linePos.left\r\n const y = linePos.top + linePos.height - height\r\n\r\n return {\r\n transform: `translate3d(${x}px, ${y}px, 0)`,\r\n width: `${width}px`,\r\n height:\r\n typeof lineHeight === 'number'\r\n ? `${lineHeight}px`\r\n : String(lineHeight),\r\n }\r\n })\r\n\r\n const containerClass = computed(() => [\r\n 'w-tab',\r\n `w-tab--${props.direction}`,\r\n `w-tab--${props.type}`,\r\n {\r\n 'w-tab--no-line': !props.showLine,\r\n 'w-tab--closable': props.closable,\r\n },\r\n ])\r\n\r\n function clampIndex(index: number) {\r\n if (dataLength.value <= 0) return 0\r\n return Math.min(Math.max(index, 0), dataLength.value - 1)\r\n }\r\n\r\n function findIndexByValue(value: any) {\r\n return processedData.value.findIndex(\r\n (item) => item[props.valueField] === value,\r\n )\r\n }\r\n\r\n function findEnabledIndex(from: number, step: 1 | -1) {\r\n const len = dataLength.value\r\n if (len <= 0) return -1\r\n let i = from\r\n for (let n = 0; n < len; n++) {\r\n i = (i + step + len) % len\r\n if (!processedData.value[i]?.disabled) return i\r\n }\r\n return -1\r\n }\r\n\r\n function resolveIndexFromProps() {\r\n if (props.modelValue !== undefined) {\r\n const byValue = findIndexByValue(props.modelValue)\r\n if (byValue !== -1) return byValue\r\n }\r\n return clampIndex(props.index ?? 0)\r\n }\r\n\r\n function syncActive(index: number, options?: { emitChange?: boolean }) {\r\n const next = clampIndex(index)\r\n const item = processedData.value[next]\r\n if (!item || item.disabled) return\r\n\r\n const value = item[props.valueField]\r\n const changed = currentIndex.value !== next\r\n currentIndex.value = next\r\n\r\n emit('update:index', next)\r\n emit('update:modelValue', value)\r\n if (changed && options?.emitChange !== false) {\r\n emit('change', value, next, item)\r\n }\r\n }\r\n\r\n function getItemLabel(index: number) {\r\n return processedData.value[index]?.[props.labelField]\r\n }\r\n\r\n function getItemClass(index: number, item: any) {\r\n return [\r\n 'w-tab-item',\r\n props.itemClass,\r\n {\r\n 'w-tab-item-active': currentIndex.value === index,\r\n 'w-tab-item-disabled': item.disabled,\r\n },\r\n currentIndex.value === index && props.activeItemClass,\r\n ].filter(Boolean)\r\n }\r\n\r\n function createSlotOptions(index: number, item: any): TabSlotScope {\r\n return {\r\n index,\r\n item,\r\n value: item?.[props.valueField],\r\n label: item?.[props.labelField],\r\n isActive: currentIndex.value === index,\r\n }\r\n }\r\n\r\n function handleClick(index: number, item: any) {\r\n const value = item[props.valueField]\r\n emit('click', value, index, item)\r\n if (item.disabled) return\r\n if (currentIndex.value !== index) {\r\n syncActive(index)\r\n }\r\n }\r\n\r\n function handleClose(index: number, item: any, event: Event) {\r\n event.stopPropagation()\r\n emit('close', item[props.valueField], index, item)\r\n }\r\n\r\n function handleKeydown(event: KeyboardEvent) {\r\n const { key } = event\r\n const vertical = isVertical.value\r\n let next = -1\r\n\r\n if (\r\n (vertical && key === 'ArrowDown') ||\r\n (!vertical && key === 'ArrowRight')\r\n ) {\r\n next = findEnabledIndex(currentIndex.value, 1)\r\n } else if (\r\n (vertical && key === 'ArrowUp') ||\r\n (!vertical && key === 'ArrowLeft')\r\n ) {\r\n next = findEnabledIndex(currentIndex.value, -1)\r\n } else if (key === 'Home') {\r\n next = findEnabledIndex(-1, 1)\r\n } else if (key === 'End') {\r\n next = findEnabledIndex(dataLength.value, -1)\r\n } else {\r\n return\r\n }\r\n\r\n if (next === -1) return\r\n event.preventDefault()\r\n syncActive(next)\r\n nextTick(() => items.value[next]?.focus())\r\n }\r\n\r\n // 外部 modelValue / index 同步\r\n watch(\r\n () => props.modelValue,\r\n (value) => {\r\n if (value === undefined) return\r\n const i = findIndexByValue(value)\r\n if (i !== -1 && i !== currentIndex.value) {\r\n currentIndex.value = i\r\n }\r\n },\r\n )\r\n\r\n watch(\r\n () => props.index,\r\n (index) => {\r\n // 仅在未使用 v-model 时跟随 index,避免与 modelValue 抢控制权\r\n if (props.modelValue !== undefined) return\r\n const next = clampIndex(index)\r\n if (next !== currentIndex.value) {\r\n currentIndex.value = next\r\n }\r\n },\r\n )\r\n\r\n // 数据变化:校正越界 / 已被删除的选中项\r\n watch(\r\n processedData,\r\n (list) => {\r\n if (!list.length) {\r\n currentIndex.value = 0\r\n return\r\n }\r\n\r\n if (props.modelValue !== undefined) {\r\n const byValue = findIndexByValue(props.modelValue)\r\n if (byValue !== -1) {\r\n if (byValue !== currentIndex.value) currentIndex.value = byValue\r\n return\r\n }\r\n // 当前值已被移除:落到邻近可用项,并回写 v-model\r\n const next = clampIndex(currentIndex.value)\r\n const item = list[next]\r\n currentIndex.value = next\r\n if (item) {\r\n emit('update:index', next)\r\n emit('update:modelValue', item[props.valueField])\r\n }\r\n return\r\n }\r\n\r\n if (currentIndex.value >= list.length) {\r\n const next = clampIndex(list.length - 1)\r\n const item = list[next]\r\n currentIndex.value = next\r\n if (item) {\r\n emit('update:index', next)\r\n emit('update:modelValue', item[props.valueField])\r\n }\r\n return\r\n }\r\n\r\n const active = list[currentIndex.value]\r\n if (active?.disabled) {\r\n const next = findEnabledIndex(currentIndex.value - 1, 1)\r\n if (next !== -1) {\r\n syncActive(next, { emitChange: false })\r\n }\r\n }\r\n },\r\n { deep: true },\r\n )\r\n\r\n // 初始化选中项\r\n currentIndex.value = resolveIndexFromProps()\r\n\r\n // 使用 rAF 调度测量,避免在响应式同步阶段连续读 rect 触发强制重排\r\n let rafId: number | null = null\r\n\r\n function measureLine() {\r\n const root = rootRef.value\r\n if (!root || !items.value?.length) return\r\n\r\n const activeItem = items.value[currentIndex.value]\r\n if (!activeItem) {\r\n linePos.width = 0\r\n linePos.height = 0\r\n return\r\n }\r\n\r\n // 一次性读取 root 与 item 的 rect,相减得到相对坐标;\r\n // 比 getOffset 遍历 offsetParent 更快且语义更准确\r\n const rootRect = root.getBoundingClientRect()\r\n const itemRect = activeItem.getBoundingClientRect()\r\n\r\n linePos.left = itemRect.left - rootRect.left\r\n linePos.top = itemRect.top - rootRect.top\r\n linePos.width = itemRect.width\r\n linePos.height = itemRect.height\r\n }\r\n\r\n function scheduleUpdate() {\r\n if (rafId != null) return\r\n if (typeof requestAnimationFrame === 'undefined') {\r\n measureLine()\r\n return\r\n }\r\n rafId = requestAnimationFrame(() => {\r\n rafId = null\r\n measureLine()\r\n })\r\n }\r\n\r\n // currentIndex / direction / 数据变化后重新测量\r\n watch(\r\n [currentIndex, () => props.direction, processedData],\r\n () => {\r\n scheduleUpdate()\r\n },\r\n { flush: 'post' },\r\n )\r\n\r\n // 监听容器尺寸变化(窗口缩放、字体延迟加载等)\r\n let resizeObserver: ResizeObserver | null = null\r\n onMounted(() => {\r\n scheduleUpdate()\r\n if (typeof ResizeObserver !== 'undefined' && rootRef.value) {\r\n resizeObserver = new ResizeObserver(() => scheduleUpdate())\r\n resizeObserver.observe(rootRef.value)\r\n }\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n resizeObserver?.disconnect()\r\n resizeObserver = null\r\n if (rafId != null) {\r\n cancelAnimationFrame(rafId)\r\n rafId = null\r\n }\r\n })\r\n\r\n expose({\r\n currentIndex,\r\n currentItem,\r\n currentValue,\r\n processedData,\r\n setIndex: (index: number) => {\r\n if (index >= 0 && index < dataLength.value) {\r\n handleClick(index, processedData.value[index])\r\n }\r\n },\r\n setValue: (value: any) => {\r\n const index = findIndexByValue(value)\r\n if (index !== -1) {\r\n handleClick(index, processedData.value[index])\r\n }\r\n },\r\n })\r\n\r\n return () => {\r\n const tokenStyle = toCssVarsStyle({\r\n ...propSizeToCssVars('tab', props.size),\r\n ...propColorToCssVars('tab', props.color),\r\n ...props.cssVars,\r\n })\r\n\r\n const list = (\r\n <ul\r\n class={containerClass.value}\r\n style={slots.content ? undefined : tokenStyle}\r\n ref={rootRef}\r\n role=\"tablist\"\r\n aria-orientation={props.direction}\r\n onKeydown={handleKeydown}>\r\n {props.showLine && props.type === 'default' && (\r\n <li\r\n class=\"w-tab-line\"\r\n ref={lineRef}\r\n style={computedLineStyle.value}\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n\r\n {processedData.value.map((item, index) => {\r\n const slotOptions = createSlotOptions(index, item)\r\n const label = getItemLabel(index)\r\n const isActive = currentIndex.value === index\r\n const itemClosable =\r\n !item.disabled &&\r\n (item.closable === true ||\r\n (props.closable && item.closable !== false))\r\n\r\n return (\r\n <li\r\n key={item[props.valueField] ?? index}\r\n ref={(el: HTMLElement | null) => {\r\n items.value[index] = el\r\n if (index === 0 && items.value.length > dataLength.value) {\r\n items.value.length = dataLength.value\r\n }\r\n }}\r\n class={getItemClass(index, item)}\r\n role=\"tab\"\r\n tabindex={isActive ? 0 : -1}\r\n aria-selected={isActive}\r\n aria-disabled={!!item.disabled}\r\n onClick={() => handleClick(index, item)}>\r\n {slots.default ? (\r\n slots.default(slotOptions)\r\n ) : (\r\n <span class=\"w-tab-item-label\">{label}</span>\r\n )}\r\n\r\n {itemClosable && (\r\n <span\r\n class=\"w-tab-item-close\"\r\n role=\"button\"\r\n tabindex={-1}\r\n aria-label=\"close\"\r\n onClick={(e) => handleClose(index, item, e)}>\r\n {slots.close ? slots.close(slotOptions) : '×'}\r\n </span>\r\n )}\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n\r\n if (!slots.content) {\r\n return list\r\n }\r\n\r\n const active = currentItem.value\r\n const panelScope = createSlotOptions(\r\n currentIndex.value,\r\n active || { [props.labelField]: '', [props.valueField]: undefined },\r\n )\r\n\r\n return (\r\n <div\r\n class={[\r\n 'w-tab-wrapper',\r\n `w-tab-wrapper--${props.direction}`,\r\n `w-tab-wrapper--${props.type}`,\r\n ]}\r\n style={tokenStyle}>\r\n {list}\r\n <div class=\"w-tab-panel\" role=\"tabpanel\">\r\n {slots.content(panelScope)}\r\n </div>\r\n </div>\r\n )\r\n }\r\n },\r\n})\r\n\r\nconst Tab = TabImpl as unknown as TabComponent\r\n\r\n/** 实例类型;一般写 `InstanceType<typeof Tab>` 即可 */\r\nexport type TabInstance = InstanceType<TabComponent>\r\n\r\nexport default Tab\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"Tab.js","names":["defineComponent","reactive","ref","computed","watch","nextTick","onMounted","onBeforeUnmount","createVNode","_createVNode","propColorToCssVars","propSizeToCssVars","toCssVarsStyle","TabImpl","name","props","modelValue","type","String","Number","Boolean","Object","default","undefined","index","data","Array","required","itemClass","activeItemClass","lineStyle","Function","direction","showLine","lineWidth","lineHeight","closable","labelField","valueField","color","size","cssVars","emits","value","change","item","click","close","slots","setup","emit","expose","rootRef","lineRef","items","currentIndex","linePos","left","top","width","height","processedData","isArray","map","_index","label","entries","key","dataLength","length","currentItem","currentValue","isVertical","computedLineStyle","parseFloat","x","y","transform","containerClass","clampIndex","Math","min","max","findIndexByValue","findIndex","findEnabledIndex","from","step","len","i","n","disabled","resolveIndexFromProps","byValue","syncActive","options","next","changed","emitChange","getItemLabel","getItemClass","filter","createSlotOptions","isActive","handleClick","handleClose","event","stopPropagation","handleKeydown","vertical","preventDefault","focus","list","active","deep","rafId","measureLine","root","activeItem","rootRect","getBoundingClientRect","itemRect","scheduleUpdate","requestAnimationFrame","flush","resizeObserver","ResizeObserver","observe","disconnect","cancelAnimationFrame","setIndex","setValue","tokenStyle","content","slotOptions","itemClosable","el","onClick","e","panelScope","Tab"],"sources":["../../../components/tab/Tab.tsx"],"sourcesContent":["import {\r\n defineComponent,\r\n reactive,\r\n ref,\r\n computed,\r\n watch,\r\n nextTick,\r\n onMounted,\r\n onBeforeUnmount,\r\n} from 'vue'\r\nimport type { PropType, SlotsType } from 'vue'\r\nimport { propColorToCssVars, propSizeToCssVars, toCssVarsStyle, type CssVars } from '../../util'\r\n\r\n// ==================== 类型定义 ====================\r\n\r\n/**\r\n * 标签项基础字段(勿加 [key: string]: any,否则会冲掉 label/value 提示)\r\n * 业务扩展字段通过 data 元素类型 T 自动带上\r\n */\r\nexport interface TabItem {\r\n label?: string\r\n value?: any\r\n disabled?: boolean\r\n closable?: boolean\r\n}\r\n\r\n/**\r\n * 标签数据源:对象数组 / 纯字符串数组 / 键值对对象\r\n */\r\nexport type TabData<T = TabItem> =\r\n | T[]\r\n | string[]\r\n | number[]\r\n | Record<string, any>\r\n\r\n/** 字符串/数字项在组件内会被规范化成 { label, value } */\r\nexport type NormalizedTabItem<T> = T extends string | number\r\n ? { label: T; value: T; disabled?: boolean; closable?: boolean }\r\n : T\r\n\r\ntype TabItemValue<T> =\r\n NormalizedTabItem<T> extends { value?: infer V } ? V : any\r\n\r\ntype TabItemLabel<T> =\r\n NormalizedTabItem<T> extends { label?: infer L } ? L : any\r\n\r\n/**\r\n * 插槽作用域;T 由 data 元素类型推断,一般不用手写\r\n */\r\nexport interface TabSlotScope<T = TabItem> {\r\n index: number\r\n item: NormalizedTabItem<T>\r\n value: TabItemValue<T>\r\n label: TabItemLabel<T>\r\n isActive: boolean\r\n}\r\n\r\n/**\r\n * 线条位置类型\r\n */\r\nexport interface LinePosition {\r\n left: number\r\n top: number\r\n width: number\r\n height: number\r\n}\r\n\r\n/**\r\n * 标签方向\r\n */\r\nexport type TabDirection = 'horizontal' | 'vertical'\r\n\r\n/**\r\n * 标签类型\r\n */\r\nexport type TabType = 'default' | 'card' | 'border-card'\r\n\r\nexport type TabSlots<T = any> = {\r\n default?: (scope: TabSlotScope<T>) => any\r\n close?: (scope: TabSlotScope<T>) => any\r\n /** 当前激活标签对应的内容区 */\r\n content?: (scope: TabSlotScope<T>) => any\r\n}\r\n\r\nexport interface TabProps<T = any> {\r\n modelValue?: any\r\n index?: number\r\n data?: TabData<T>\r\n itemClass?:\r\n | string\r\n | Record<string, boolean>\r\n | (string | Record<string, boolean>)[]\r\n activeItemClass?:\r\n | string\r\n | Record<string, boolean>\r\n | (string | Record<string, boolean>)[]\r\n lineStyle?: (pos: LinePosition) => Record<string, string | number>\r\n direction?: TabDirection\r\n type?: TabType\r\n showLine?: boolean\r\n lineWidth?: number | string\r\n lineHeight?: number | string\r\n closable?: boolean\r\n labelField?: string\r\n valueField?: string\r\n /** 品牌主色 → `--w-prop-tab-color` */\r\n color?: string\r\n /** 实例尺度(px)→ `--w-prop-tab-size` */\r\n size?: number\r\n /** 实例 CSS 变量 */\r\n cssVars?: CssVars\r\n}\r\n\r\n/** Vue TSX:$props 含 v-slots,才能从 data 推断插槽 T */\r\nexport type TabJSXProps<T = any> = TabProps<T> & {\r\n 'v-slots'?: TabSlots<T>\r\n vSlots?: TabSlots<T>\r\n class?: unknown\r\n style?: unknown\r\n 'onUpdate:modelValue'?: (value: any) => void\r\n 'onUpdate:index'?: (index: number) => void\r\n onChange?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n onClick?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n onClose?: (value: any, index: number, item: NormalizedTabItem<T>) => void\r\n}\r\n\r\nexport type TabExpose = {\r\n setIndex: (index: number) => void\r\n setValue: (value: any) => void\r\n}\r\n\r\n// ==================== 组件定义 ====================\r\n\r\nconst TabImpl = defineComponent({\r\n name: 'Tab',\r\n\r\n props: {\r\n /**\r\n * 当前激活标签的值(v-model)\r\n * 与 index 二选一即可;同时传入时以 modelValue 为准\r\n */\r\n modelValue: {\r\n type: [String, Number, Boolean, Object] as PropType<any>,\r\n default: undefined,\r\n },\r\n\r\n /**\r\n * 当前激活标签索引(v-model:index)\r\n * @default 0\r\n */\r\n index: {\r\n type: Number,\r\n default: 0,\r\n },\r\n\r\n /**\r\n * 标签数据源\r\n * 支持格式:\r\n * - 对象数组: [{ label: '标签名', value: '值' }]\r\n * - 纯字符串数组: ['标签1', '标签2']\r\n * - 键值对对象: { '标签1': '值1', '标签2': '值2' }\r\n */\r\n data: {\r\n type: [Array, Object] as PropType<TabData>,\r\n required: true,\r\n },\r\n\r\n /**\r\n * 自定义标签项 CSS 类名\r\n */\r\n itemClass: {\r\n type: [String, Object, Array] as PropType<\r\n string | Record<string, boolean> | (string | Record<string, boolean>)[]\r\n >,\r\n },\r\n\r\n /**\r\n * 激活态额外 CSS 类名\r\n */\r\n activeItemClass: {\r\n type: [String, Object, Array] as PropType<\r\n string | Record<string, boolean> | (string | Record<string, boolean>)[]\r\n >,\r\n },\r\n\r\n /**\r\n * 自定义指示线条样式\r\n */\r\n lineStyle: {\r\n type: Function as PropType<\r\n (pos: LinePosition) => Record<string, string | number>\r\n >,\r\n },\r\n\r\n /**\r\n * 标签方向\r\n * @default 'horizontal'\r\n */\r\n direction: {\r\n type: String as PropType<TabDirection>,\r\n default: 'horizontal',\r\n },\r\n\r\n /**\r\n * 标签类型\r\n * @default 'default'\r\n */\r\n type: {\r\n type: String as PropType<TabType>,\r\n default: 'default',\r\n },\r\n\r\n /**\r\n * 是否显示激活线条\r\n * @default true\r\n */\r\n showLine: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n\r\n /**\r\n * 线条宽度,默认与标签内容宽度一致(水平方向)\r\n */\r\n lineWidth: {\r\n type: [Number, String] as PropType<number | string>,\r\n },\r\n\r\n /**\r\n * 线条高度,默认与标签内容高度一致(垂直方向)\r\n * @default 2\r\n */\r\n lineHeight: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: 2,\r\n },\r\n\r\n /**\r\n * 是否可关闭\r\n * @default false\r\n */\r\n closable: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n\r\n /**\r\n * 数据中标签文字的字段名\r\n * @default 'label'\r\n */\r\n labelField: {\r\n type: String,\r\n default: 'label',\r\n },\r\n\r\n /**\r\n * 数据中值的字段名\r\n * @default 'value'\r\n */\r\n valueField: {\r\n type: String,\r\n default: 'value',\r\n },\r\n\r\n /** 品牌主色 → `--w-prop-tab-color` */\r\n color: { type: String, default: undefined },\r\n /** 实例尺度(px)→ `--w-prop-tab-size` */\r\n size: { type: Number, default: undefined },\r\n /** 实例 CSS 变量 */\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n\r\n emits: {\r\n /**\r\n * 值变化事件(用于 v-model)\r\n */\r\n 'update:modelValue': (value: any) => true,\r\n\r\n /**\r\n * 索引变化事件(用于 v-model:index)\r\n */\r\n 'update:index': (index: number) => true,\r\n\r\n /**\r\n * 切换标签时触发\r\n */\r\n change: (value: any, index: number, item: any) => true,\r\n\r\n /**\r\n * 点击标签时触发(无论是否切换)\r\n */\r\n click: (value: any, index: number, item: any) => true,\r\n\r\n /**\r\n * 关闭标签时触发\r\n */\r\n close: (value: any, index: number, item: any) => true,\r\n },\r\n\r\n slots: Object as SlotsType<TabSlots>,\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const rootRef = ref<HTMLElement>()\r\n const lineRef = ref<HTMLElement>()\r\n const items = ref<(HTMLElement | null)[]>([])\r\n const currentIndex = ref(0)\r\n\r\n const linePos = reactive<LinePosition>({\r\n left: 0,\r\n top: 0,\r\n width: 0,\r\n height: 0,\r\n })\r\n\r\n const processedData = computed(() => {\r\n const { data, labelField, valueField } = props\r\n\r\n if (Array.isArray(data)) {\r\n return data.map((item, index) => {\r\n if (typeof item === 'string' || typeof item === 'number') {\r\n return {\r\n [labelField]: item,\r\n [valueField]: item,\r\n _index: index,\r\n }\r\n }\r\n return {\r\n ...item,\r\n [labelField]: item[labelField] ?? item.label ?? String(index),\r\n [valueField]:\r\n item[valueField] !== undefined\r\n ? item[valueField]\r\n : item.value !== undefined\r\n ? item.value\r\n : index,\r\n _index: index,\r\n }\r\n })\r\n }\r\n\r\n return Object.entries(data || {}).map(([key, value], index) => ({\r\n [labelField]: key,\r\n [valueField]: value,\r\n _index: index,\r\n }))\r\n })\r\n\r\n const dataLength = computed(() => processedData.value.length)\r\n\r\n const currentItem = computed(\r\n () => processedData.value[currentIndex.value] as TabItem | undefined,\r\n )\r\n\r\n const currentValue = computed(() => {\r\n const item = currentItem.value\r\n return item?.[props.valueField]\r\n })\r\n\r\n const isVertical = computed(() => props.direction === 'vertical')\r\n\r\n const computedLineStyle = computed(() => {\r\n const { lineStyle, lineWidth, lineHeight } = props\r\n\r\n if (lineStyle) {\r\n return lineStyle(linePos)\r\n }\r\n\r\n // 使用 transform: translate3d 进行位移,避免 left/top 过渡引发重排\r\n if (isVertical.value) {\r\n let height = linePos.height\r\n if (lineHeight !== undefined) {\r\n height =\r\n typeof lineHeight === 'number'\r\n ? lineHeight\r\n : parseFloat(String(lineHeight))\r\n }\r\n const width =\r\n lineWidth !== undefined\r\n ? typeof lineWidth === 'number'\r\n ? lineWidth\r\n : parseFloat(String(lineWidth))\r\n : 2\r\n\r\n const x = linePos.left + linePos.width - width\r\n const y =\r\n lineHeight !== undefined\r\n ? linePos.top + (linePos.height - height) / 2\r\n : linePos.top\r\n\r\n return {\r\n transform: `translate3d(${x}px, ${y}px, 0)`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n }\r\n }\r\n\r\n let width = linePos.width\r\n if (lineWidth !== undefined) {\r\n width =\r\n typeof lineWidth === 'number'\r\n ? lineWidth\r\n : parseFloat(String(lineWidth))\r\n }\r\n const height =\r\n typeof lineHeight === 'number'\r\n ? lineHeight\r\n : parseFloat(String(lineHeight))\r\n\r\n const x =\r\n lineWidth !== undefined\r\n ? linePos.left + (linePos.width - width) / 2\r\n : linePos.left\r\n const y = linePos.top + linePos.height - height\r\n\r\n return {\r\n transform: `translate3d(${x}px, ${y}px, 0)`,\r\n width: `${width}px`,\r\n height:\r\n typeof lineHeight === 'number'\r\n ? `${lineHeight}px`\r\n : String(lineHeight),\r\n }\r\n })\r\n\r\n const containerClass = computed(() => [\r\n 'w-tab',\r\n `w-tab--${props.direction}`,\r\n `w-tab--${props.type}`,\r\n {\r\n 'w-tab--no-line': !props.showLine,\r\n 'w-tab--closable': props.closable,\r\n },\r\n ])\r\n\r\n function clampIndex(index: number) {\r\n if (dataLength.value <= 0) return 0\r\n return Math.min(Math.max(index, 0), dataLength.value - 1)\r\n }\r\n\r\n function findIndexByValue(value: any) {\r\n return processedData.value.findIndex(\r\n (item) => item[props.valueField] === value,\r\n )\r\n }\r\n\r\n function findEnabledIndex(from: number, step: 1 | -1) {\r\n const len = dataLength.value\r\n if (len <= 0) return -1\r\n let i = from\r\n for (let n = 0; n < len; n++) {\r\n i = (i + step + len) % len\r\n if (!processedData.value[i]?.disabled) return i\r\n }\r\n return -1\r\n }\r\n\r\n function resolveIndexFromProps() {\r\n if (props.modelValue !== undefined) {\r\n const byValue = findIndexByValue(props.modelValue)\r\n if (byValue !== -1) return byValue\r\n }\r\n return clampIndex(props.index ?? 0)\r\n }\r\n\r\n function syncActive(index: number, options?: { emitChange?: boolean }) {\r\n const next = clampIndex(index)\r\n const item = processedData.value[next]\r\n if (!item || item.disabled) return\r\n\r\n const value = item[props.valueField]\r\n const changed = currentIndex.value !== next\r\n currentIndex.value = next\r\n\r\n emit('update:index', next)\r\n emit('update:modelValue', value)\r\n if (changed && options?.emitChange !== false) {\r\n emit('change', value, next, item)\r\n }\r\n }\r\n\r\n function getItemLabel(index: number) {\r\n return processedData.value[index]?.[props.labelField]\r\n }\r\n\r\n function getItemClass(index: number, item: any) {\r\n return [\r\n 'w-tab-item',\r\n props.itemClass,\r\n {\r\n 'w-tab-item-active': currentIndex.value === index,\r\n 'w-tab-item-disabled': item.disabled,\r\n },\r\n currentIndex.value === index && props.activeItemClass,\r\n ].filter(Boolean)\r\n }\r\n\r\n function createSlotOptions(index: number, item: any): TabSlotScope {\r\n return {\r\n index,\r\n item,\r\n value: item?.[props.valueField],\r\n label: item?.[props.labelField],\r\n isActive: currentIndex.value === index,\r\n }\r\n }\r\n\r\n function handleClick(index: number, item: any) {\r\n const value = item[props.valueField]\r\n emit('click', value, index, item)\r\n if (item.disabled) return\r\n if (currentIndex.value !== index) {\r\n syncActive(index)\r\n }\r\n }\r\n\r\n function handleClose(index: number, item: any, event: Event) {\r\n event.stopPropagation()\r\n emit('close', item[props.valueField], index, item)\r\n }\r\n\r\n function handleKeydown(event: KeyboardEvent) {\r\n const { key } = event\r\n const vertical = isVertical.value\r\n let next = -1\r\n\r\n if (\r\n (vertical && key === 'ArrowDown') ||\r\n (!vertical && key === 'ArrowRight')\r\n ) {\r\n next = findEnabledIndex(currentIndex.value, 1)\r\n } else if (\r\n (vertical && key === 'ArrowUp') ||\r\n (!vertical && key === 'ArrowLeft')\r\n ) {\r\n next = findEnabledIndex(currentIndex.value, -1)\r\n } else if (key === 'Home') {\r\n next = findEnabledIndex(-1, 1)\r\n } else if (key === 'End') {\r\n next = findEnabledIndex(dataLength.value, -1)\r\n } else {\r\n return\r\n }\r\n\r\n if (next === -1) return\r\n event.preventDefault()\r\n syncActive(next)\r\n nextTick(() => items.value[next]?.focus())\r\n }\r\n\r\n // 外部 modelValue / index 同步\r\n watch(\r\n () => props.modelValue,\r\n (value) => {\r\n if (value === undefined) return\r\n const i = findIndexByValue(value)\r\n if (i !== -1 && i !== currentIndex.value) {\r\n currentIndex.value = i\r\n }\r\n },\r\n )\r\n\r\n watch(\r\n () => props.index,\r\n (index) => {\r\n // 仅在未使用 v-model 时跟随 index,避免与 modelValue 抢控制权\r\n if (props.modelValue !== undefined) return\r\n const next = clampIndex(index)\r\n if (next !== currentIndex.value) {\r\n currentIndex.value = next\r\n }\r\n },\r\n )\r\n\r\n // 数据变化:校正越界 / 已被删除的选中项\r\n watch(\r\n processedData,\r\n (list) => {\r\n if (!list.length) {\r\n currentIndex.value = 0\r\n return\r\n }\r\n\r\n if (props.modelValue !== undefined) {\r\n const byValue = findIndexByValue(props.modelValue)\r\n if (byValue !== -1) {\r\n if (byValue !== currentIndex.value) currentIndex.value = byValue\r\n return\r\n }\r\n // 当前值已被移除:落到邻近可用项,并回写 v-model\r\n const next = clampIndex(currentIndex.value)\r\n const item = list[next]\r\n currentIndex.value = next\r\n if (item) {\r\n emit('update:index', next)\r\n emit('update:modelValue', item[props.valueField])\r\n }\r\n return\r\n }\r\n\r\n if (currentIndex.value >= list.length) {\r\n const next = clampIndex(list.length - 1)\r\n const item = list[next]\r\n currentIndex.value = next\r\n if (item) {\r\n emit('update:index', next)\r\n emit('update:modelValue', item[props.valueField])\r\n }\r\n return\r\n }\r\n\r\n const active = list[currentIndex.value]\r\n if (active?.disabled) {\r\n const next = findEnabledIndex(currentIndex.value - 1, 1)\r\n if (next !== -1) {\r\n syncActive(next, { emitChange: false })\r\n }\r\n }\r\n },\r\n { deep: true },\r\n )\r\n\r\n // 初始化选中项\r\n currentIndex.value = resolveIndexFromProps()\r\n\r\n // 使用 rAF 调度测量,避免在响应式同步阶段连续读 rect 触发强制重排\r\n let rafId: number | null = null\r\n\r\n function measureLine() {\r\n const root = rootRef.value\r\n if (!root || !items.value?.length) return\r\n\r\n const activeItem = items.value[currentIndex.value]\r\n if (!activeItem) {\r\n linePos.width = 0\r\n linePos.height = 0\r\n return\r\n }\r\n\r\n // 一次性读取 root 与 item 的 rect,相减得到相对坐标;\r\n // 比 getOffset 遍历 offsetParent 更快且语义更准确\r\n const rootRect = root.getBoundingClientRect()\r\n const itemRect = activeItem.getBoundingClientRect()\r\n\r\n linePos.left = itemRect.left - rootRect.left\r\n linePos.top = itemRect.top - rootRect.top\r\n linePos.width = itemRect.width\r\n linePos.height = itemRect.height\r\n }\r\n\r\n function scheduleUpdate() {\r\n if (rafId != null) return\r\n if (typeof requestAnimationFrame === 'undefined') {\r\n measureLine()\r\n return\r\n }\r\n rafId = requestAnimationFrame(() => {\r\n rafId = null\r\n measureLine()\r\n })\r\n }\r\n\r\n // currentIndex / direction / 数据变化后重新测量\r\n watch(\r\n [currentIndex, () => props.direction, processedData],\r\n () => {\r\n scheduleUpdate()\r\n },\r\n { flush: 'post' },\r\n )\r\n\r\n // 监听容器尺寸变化(窗口缩放、字体延迟加载等)\r\n let resizeObserver: ResizeObserver | null = null\r\n onMounted(() => {\r\n scheduleUpdate()\r\n if (typeof ResizeObserver !== 'undefined' && rootRef.value) {\r\n resizeObserver = new ResizeObserver(() => scheduleUpdate())\r\n resizeObserver.observe(rootRef.value)\r\n }\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n resizeObserver?.disconnect()\r\n resizeObserver = null\r\n if (rafId != null) {\r\n cancelAnimationFrame(rafId)\r\n rafId = null\r\n }\r\n })\r\n\r\n expose({\r\n currentIndex,\r\n currentItem,\r\n currentValue,\r\n processedData,\r\n setIndex: (index: number) => {\r\n if (index >= 0 && index < dataLength.value) {\r\n handleClick(index, processedData.value[index])\r\n }\r\n },\r\n setValue: (value: any) => {\r\n const index = findIndexByValue(value)\r\n if (index !== -1) {\r\n handleClick(index, processedData.value[index])\r\n }\r\n },\r\n })\r\n\r\n return () => {\r\n const tokenStyle = toCssVarsStyle({\r\n ...propSizeToCssVars('tab', props.size),\r\n ...propColorToCssVars('tab', props.color),\r\n ...props.cssVars,\r\n })\r\n\r\n const list = (\r\n <ul\r\n class={containerClass.value}\r\n style={slots.content ? undefined : tokenStyle}\r\n ref={rootRef}\r\n role=\"tablist\"\r\n aria-orientation={props.direction}\r\n onKeydown={handleKeydown}>\r\n {props.showLine && props.type === 'default' && (\r\n <li\r\n class=\"w-tab-line\"\r\n ref={lineRef}\r\n style={computedLineStyle.value}\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n\r\n {processedData.value.map((item, index) => {\r\n const slotOptions = createSlotOptions(index, item)\r\n const label = getItemLabel(index)\r\n const isActive = currentIndex.value === index\r\n const itemClosable =\r\n !item.disabled &&\r\n (item.closable === true ||\r\n (props.closable && item.closable !== false))\r\n\r\n return (\r\n <li\r\n key={item[props.valueField] ?? index}\r\n ref={(el: HTMLElement | null) => {\r\n items.value[index] = el\r\n if (index === 0 && items.value.length > dataLength.value) {\r\n items.value.length = dataLength.value\r\n }\r\n }}\r\n class={getItemClass(index, item)}\r\n role=\"tab\"\r\n tabindex={isActive ? 0 : -1}\r\n aria-selected={isActive}\r\n aria-disabled={!!item.disabled}\r\n onClick={() => handleClick(index, item)}>\r\n {slots.default ? (\r\n slots.default(slotOptions)\r\n ) : (\r\n <span class=\"w-tab-item-label\">{label}</span>\r\n )}\r\n\r\n {itemClosable && (\r\n <span\r\n class=\"w-tab-item-close\"\r\n role=\"button\"\r\n tabindex={-1}\r\n aria-label=\"close\"\r\n onClick={(e) => handleClose(index, item, e)}>\r\n {slots.close ? slots.close(slotOptions) : '×'}\r\n </span>\r\n )}\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n\r\n if (!slots.content) {\r\n return list\r\n }\r\n\r\n const active = currentItem.value\r\n const panelScope = createSlotOptions(\r\n currentIndex.value,\r\n active || { [props.labelField]: '', [props.valueField]: undefined },\r\n )\r\n\r\n return (\r\n <div\r\n class={[\r\n 'w-tab-wrapper',\r\n `w-tab-wrapper--${props.direction}`,\r\n `w-tab-wrapper--${props.type}`,\r\n ]}\r\n style={tokenStyle}>\r\n {list}\r\n <div class=\"w-tab-panel\" role=\"tabpanel\">\r\n {slots.content(panelScope)}\r\n </div>\r\n </div>\r\n )\r\n }\r\n },\r\n})\r\n\r\n/**\r\n * Vue JSX 通过 `$props` 取属性(不支持 `<Tab<T>>`)。\r\n * 勿再 `export type TabComponent = typeof Tab`,否则 hover 只显示别名。\r\n * `<Tab data={list} v-slots={{ content: ({ item, value }) => ... }} />`\r\n * 会从 list 元素类型推断 item / value。\r\n */\r\nconst Tab = TabImpl as unknown as {\r\n new <T = any>(): TabExpose & {\r\n $props: TabJSXProps<T>\r\n }\r\n}\r\n\r\n/** 实例类型;一般写 `InstanceType<typeof Tab>` 即可 */\r\nexport type TabInstance = InstanceType<typeof Tab>\r\n\r\nexport default Tab\r\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { DefineComponent } from 'vue';
1
2
  import { CssVars } from '../../util';
2
3
  export type { TextareaGlobalConfig } from './config';
3
4
  export { TEXTAREA_FALLBACK } from './config';
@@ -22,16 +23,7 @@ export type TextareaExpose = {
22
23
  select: () => void;
23
24
  textarea: HTMLTextAreaElement | undefined;
24
25
  };
25
- export type TextareaComponent = {
26
- new (): {
27
- $props: TextareaJSXProps;
28
- $emit: {
29
- (e: 'update:modelValue', value: string): void;
30
- (e: 'input', value: string): void;
31
- (e: 'change', value: string): void;
32
- (e: 'save', value: string): void;
33
- };
34
- } & TextareaExpose;
35
- };
36
- declare const _default: TextareaComponent;
37
- export default _default;
26
+ /** 断言为 DefineComponent,hover / 补全直接看到 TextareaJSXProps(勿再包 XxxComponent 别名) */
27
+ declare const Textarea: DefineComponent<TextareaJSXProps, TextareaExpose>;
28
+ export type TextareaInstance = InstanceType<typeof Textarea>;
29
+ export default Textarea;
@@ -8,7 +8,8 @@ function ghostText(value) {
8
8
  if (!value) return "\xA0";
9
9
  return value.endsWith("\n") ? `${value}\u00A0` : value;
10
10
  }
11
- var TextareaImpl = /* @__PURE__ */ defineComponent({
11
+ /** 断言为 DefineComponent,hover / 补全直接看到 TextareaJSXProps(勿再包 XxxComponent 别名) */
12
+ var Textarea = /* @__PURE__ */ defineComponent({
12
13
  name: "Textarea",
13
14
  inheritAttrs: false,
14
15
  props: {
@@ -188,6 +189,6 @@ var TextareaImpl = /* @__PURE__ */ defineComponent({
188
189
  }
189
190
  });
190
191
  //#endregion
191
- export { TextareaImpl as default };
192
+ export { Textarea as default };
192
193
 
193
194
  //# sourceMappingURL=Textarea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Textarea.js","names":["computed","defineComponent","mergeProps","nextTick","onBeforeUnmount","onMounted","ref","watch","createVNode","_createVNode","_mergeProps","propColorToCssVars","propSizeToCssVars","toCssVarsStyle","useComponentConfig","useFormItem","TEXTAREA_FALLBACK","ghostText","value","endsWith","TextareaImpl","name","inheritAttrs","props","modelValue","type","String","default","size","Number","undefined","color","placeholder","maxlength","disabled","Boolean","readonly","block","saveDelay","validateEvent","cssVars","Object","emits","input","change","save","setup","attrs","emit","expose","cfg","formItem","useDisabled","fieldRef","inner","composing","saveTimer","v","next","clearSaveTimer","clearTimeout","scheduleSave","ms","Math","max","setTimeout","syncScrollTop","scrollTop","commit","opts","length","slice","onInput","e","target","onCompositionStart","onCompositionEnd","onChange","val","validate","onBlur","onKeydownEnter","onWindowResize","window","addEventListener","removeEventListener","api","focus","blur","select","textarea","class","klass","style","attrStyle","rest","rootProps","key"],"sources":["../../../components/textarea/Textarea.tsx"],"sourcesContent":["import {\r\n computed,\r\n defineComponent,\r\n mergeProps,\r\n nextTick,\r\n onBeforeUnmount,\r\n onMounted,\r\n ref,\r\n watch,\r\n type PropType,\r\n} from 'vue'\r\nimport {\r\n propColorToCssVars,\r\n propSizeToCssVars,\r\n toCssVarsStyle,\r\n type CssVars,\r\n} from '../../util'\r\nimport useComponentConfig from '../../use/useComponentConfig'\r\nimport useFormItem from '../../use/useFormItem'\r\nimport { TEXTAREA_FALLBACK } from './config'\r\n\r\nexport type { TextareaGlobalConfig } from './config'\r\nexport { TEXTAREA_FALLBACK } from './config'\r\n\r\nexport type TextareaProps = {\r\n modelValue?: string\r\n size?: number\r\n color?: string\r\n placeholder?: string\r\n maxlength?: number\r\n disabled?: boolean\r\n readonly?: boolean\r\n block?: boolean\r\n /** 停输后触发 save 的防抖毫秒;默认 3000 */\r\n saveDelay?: number\r\n validateEvent?: boolean\r\n cssVars?: CssVars\r\n}\r\n\r\nexport type TextareaJSXProps = TextareaProps &\r\n Omit<\r\n JSX.IntrinsicElements['div'],\r\n keyof TextareaProps | 'ref' | 'onInput' | 'onChange'\r\n >\r\n\r\nexport type TextareaExpose = {\r\n focus: () => void\r\n blur: () => void\r\n select: () => void\r\n textarea: HTMLTextAreaElement | undefined\r\n}\r\n\r\nexport type TextareaComponent = {\r\n new (): {\r\n $props: TextareaJSXProps\r\n $emit: {\r\n (e: 'update:modelValue', value: string): void\r\n (e: 'input', value: string): void\r\n (e: 'change', value: string): void\r\n (e: 'save', value: string): void\r\n }\r\n } & TextareaExpose\r\n}\r\n\r\nfunction ghostText(value: string): string {\r\n if (!value) return '\\u00A0'\r\n return value.endsWith('\\n') ? `${value}\\u00A0` : value\r\n}\r\n\r\nconst TextareaImpl = defineComponent({\r\n name: 'Textarea',\r\n inheritAttrs: false,\r\n props: {\r\n modelValue: { type: String, default: '' },\r\n size: { type: Number, default: undefined },\r\n color: { type: String, default: undefined },\r\n placeholder: { type: String, default: undefined },\r\n maxlength: { type: Number, default: undefined },\r\n disabled: { type: Boolean, default: undefined },\r\n readonly: { type: Boolean, default: undefined },\r\n block: { type: Boolean, default: undefined },\r\n saveDelay: { type: Number, default: undefined },\r\n validateEvent: { type: Boolean, default: undefined },\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n emits: {\r\n 'update:modelValue': (value: string) => typeof value === 'string',\r\n input: (value: string) => typeof value === 'string',\r\n change: (value: string) => typeof value === 'string',\r\n save: (value: string) => typeof value === 'string',\r\n },\r\n setup(props, { attrs, emit, expose }) {\r\n const cfg = useComponentConfig('Textarea', props, TEXTAREA_FALLBACK)\r\n const { formItem, useDisabled } = useFormItem()\r\n const disabled = useDisabled(computed(() => cfg.value.disabled))\r\n\r\n const fieldRef = ref<HTMLTextAreaElement>()\r\n const inner = ref(props.modelValue ?? '')\r\n const composing = ref(false)\r\n let saveTimer: ReturnType<typeof setTimeout> | undefined\r\n\r\n watch(\r\n () => props.modelValue,\r\n (v) => {\r\n const next = v ?? ''\r\n if (next !== inner.value) inner.value = next\r\n },\r\n )\r\n\r\n function clearSaveTimer() {\r\n if (saveTimer !== undefined) {\r\n clearTimeout(saveTimer)\r\n saveTimer = undefined\r\n }\r\n }\r\n\r\n function scheduleSave(value: string) {\r\n clearSaveTimer()\r\n const ms = Math.max(0, cfg.value.saveDelay ?? TEXTAREA_FALLBACK.saveDelay)\r\n saveTimer = setTimeout(() => {\r\n saveTimer = undefined\r\n emit('save', value)\r\n }, ms)\r\n }\r\n\r\n function syncScrollTop() {\r\n nextTick(() => {\r\n if (fieldRef.value) fieldRef.value.scrollTop = 0\r\n })\r\n }\r\n\r\n function commit(value: string, opts?: { save?: boolean }) {\r\n let next = value\r\n const max = cfg.value.maxlength\r\n if (max != null && next.length > max) {\r\n next = next.slice(0, max)\r\n if (fieldRef.value) fieldRef.value.value = next\r\n }\r\n inner.value = next\r\n emit('update:modelValue', next)\r\n emit('input', next)\r\n if (opts?.save !== false) scheduleSave(next)\r\n syncScrollTop()\r\n }\r\n\r\n function onInput(e: Event) {\r\n // 组字过程也要同步,避免父级重渲染冲掉输入;结束前不触发 save\r\n commit((e.target as HTMLTextAreaElement).value, {\r\n save: !composing.value,\r\n })\r\n }\r\n\r\n function onCompositionStart() {\r\n composing.value = true\r\n }\r\n\r\n function onCompositionEnd(e: CompositionEvent) {\r\n composing.value = false\r\n commit((e.target as HTMLTextAreaElement).value)\r\n }\r\n\r\n function onChange(e: Event) {\r\n const val = (e.target as HTMLTextAreaElement).value\r\n if (cfg.value.validateEvent !== false) {\r\n formItem?.validate('change')\r\n }\r\n emit('change', val)\r\n }\r\n\r\n function onBlur() {\r\n if (cfg.value.validateEvent !== false) {\r\n formItem?.validate('blur')\r\n }\r\n }\r\n\r\n function onKeydownEnter() {\r\n syncScrollTop()\r\n }\r\n\r\n function onWindowResize() {\r\n syncScrollTop()\r\n }\r\n\r\n onMounted(() => {\r\n window.addEventListener('resize', onWindowResize)\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n window.removeEventListener('resize', onWindowResize)\r\n clearSaveTimer()\r\n })\r\n\r\n const api: TextareaExpose = {\r\n focus: () => fieldRef.value?.focus(),\r\n blur: () => fieldRef.value?.blur(),\r\n select: () => fieldRef.value?.select(),\r\n get textarea() {\r\n return fieldRef.value\r\n },\r\n }\r\n expose(api)\r\n\r\n return () => {\r\n const { class: klass, style: attrStyle, ...rest } = attrs\r\n const rootProps = mergeProps(\r\n {\r\n class: [\r\n 'w-textarea',\r\n {\r\n 'w-textarea--block': cfg.value.block,\r\n 'w-textarea--disabled': disabled.value,\r\n },\r\n klass,\r\n ],\r\n style: [\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('textarea', cfg.value.size),\r\n ...propColorToCssVars('textarea', cfg.value.color),\r\n ...props.cssVars,\r\n }),\r\n attrStyle as any,\r\n ],\r\n },\r\n {},\r\n )\r\n\r\n return (\r\n <div {...rootProps}>\r\n <div class=\"w-textarea-ghost\" aria-hidden=\"true\">\r\n {ghostText(inner.value)}\r\n </div>\r\n <textarea\r\n {...rest}\r\n ref={fieldRef}\r\n class=\"w-textarea-field\"\r\n value={inner.value}\r\n placeholder={cfg.value.placeholder}\r\n maxlength={cfg.value.maxlength}\r\n disabled={disabled.value || undefined}\r\n readonly={cfg.value.readonly || undefined}\r\n rows={1}\r\n onInput={onInput}\r\n onChange={onChange}\r\n onBlur={onBlur}\r\n onCompositionstart={onCompositionStart}\r\n onCompositionend={onCompositionEnd}\r\n onKeydown={(e: KeyboardEvent) => {\r\n if (e.key === 'Enter') onKeydownEnter()\r\n }}\r\n />\r\n </div>\r\n )\r\n }\r\n },\r\n})\r\n\r\nexport default TextareaImpl as unknown as TextareaComponent\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"Textarea.js","names":["computed","defineComponent","mergeProps","nextTick","onBeforeUnmount","onMounted","ref","watch","createVNode","_createVNode","_mergeProps","propColorToCssVars","propSizeToCssVars","toCssVarsStyle","useComponentConfig","useFormItem","TEXTAREA_FALLBACK","ghostText","value","endsWith","TextareaImpl","name","inheritAttrs","props","modelValue","type","String","default","size","Number","undefined","color","placeholder","maxlength","disabled","Boolean","readonly","block","saveDelay","validateEvent","cssVars","Object","emits","input","change","save","setup","attrs","emit","expose","cfg","formItem","useDisabled","fieldRef","inner","composing","saveTimer","v","next","clearSaveTimer","clearTimeout","scheduleSave","ms","Math","max","setTimeout","syncScrollTop","scrollTop","commit","opts","length","slice","onInput","e","target","onCompositionStart","onCompositionEnd","onChange","val","validate","onBlur","onKeydownEnter","onWindowResize","window","addEventListener","removeEventListener","api","focus","blur","select","textarea","class","klass","style","attrStyle","rest","rootProps","key","Textarea"],"sources":["../../../components/textarea/Textarea.tsx"],"sourcesContent":["import {\r\n computed,\r\n defineComponent,\r\n mergeProps,\r\n nextTick,\r\n onBeforeUnmount,\r\n onMounted,\r\n ref,\r\n watch,\r\n type DefineComponent,\r\n type PropType,\r\n} from 'vue'\r\nimport {\r\n propColorToCssVars,\r\n propSizeToCssVars,\r\n toCssVarsStyle,\r\n type CssVars,\r\n} from '../../util'\r\nimport useComponentConfig from '../../use/useComponentConfig'\r\nimport useFormItem from '../../use/useFormItem'\r\nimport { TEXTAREA_FALLBACK } from './config'\r\n\r\nexport type { TextareaGlobalConfig } from './config'\r\nexport { TEXTAREA_FALLBACK } from './config'\r\n\r\nexport type TextareaProps = {\r\n modelValue?: string\r\n size?: number\r\n color?: string\r\n placeholder?: string\r\n maxlength?: number\r\n disabled?: boolean\r\n readonly?: boolean\r\n block?: boolean\r\n /** 停输后触发 save 的防抖毫秒;默认 3000 */\r\n saveDelay?: number\r\n validateEvent?: boolean\r\n cssVars?: CssVars\r\n}\r\n\r\nexport type TextareaJSXProps = TextareaProps &\r\n Omit<\r\n JSX.IntrinsicElements['div'],\r\n keyof TextareaProps | 'ref' | 'onInput' | 'onChange'\r\n >\r\n\r\nexport type TextareaExpose = {\r\n focus: () => void\r\n blur: () => void\r\n select: () => void\r\n textarea: HTMLTextAreaElement | undefined\r\n}\r\n\r\nfunction ghostText(value: string): string {\r\n if (!value) return '\\u00A0'\r\n return value.endsWith('\\n') ? `${value}\\u00A0` : value\r\n}\r\n\r\nconst TextareaImpl = defineComponent({\r\n name: 'Textarea',\r\n inheritAttrs: false,\r\n props: {\r\n modelValue: { type: String, default: '' },\r\n size: { type: Number, default: undefined },\r\n color: { type: String, default: undefined },\r\n placeholder: { type: String, default: undefined },\r\n maxlength: { type: Number, default: undefined },\r\n disabled: { type: Boolean, default: undefined },\r\n readonly: { type: Boolean, default: undefined },\r\n block: { type: Boolean, default: undefined },\r\n saveDelay: { type: Number, default: undefined },\r\n validateEvent: { type: Boolean, default: undefined },\r\n cssVars: { type: Object as PropType<CssVars>, default: undefined },\r\n },\r\n emits: {\r\n 'update:modelValue': (value: string) => typeof value === 'string',\r\n input: (value: string) => typeof value === 'string',\r\n change: (value: string) => typeof value === 'string',\r\n save: (value: string) => typeof value === 'string',\r\n },\r\n setup(props, { attrs, emit, expose }) {\r\n const cfg = useComponentConfig('Textarea', props, TEXTAREA_FALLBACK)\r\n const { formItem, useDisabled } = useFormItem()\r\n const disabled = useDisabled(computed(() => cfg.value.disabled))\r\n\r\n const fieldRef = ref<HTMLTextAreaElement>()\r\n const inner = ref(props.modelValue ?? '')\r\n const composing = ref(false)\r\n let saveTimer: ReturnType<typeof setTimeout> | undefined\r\n\r\n watch(\r\n () => props.modelValue,\r\n (v) => {\r\n const next = v ?? ''\r\n if (next !== inner.value) inner.value = next\r\n },\r\n )\r\n\r\n function clearSaveTimer() {\r\n if (saveTimer !== undefined) {\r\n clearTimeout(saveTimer)\r\n saveTimer = undefined\r\n }\r\n }\r\n\r\n function scheduleSave(value: string) {\r\n clearSaveTimer()\r\n const ms = Math.max(0, cfg.value.saveDelay ?? TEXTAREA_FALLBACK.saveDelay)\r\n saveTimer = setTimeout(() => {\r\n saveTimer = undefined\r\n emit('save', value)\r\n }, ms)\r\n }\r\n\r\n function syncScrollTop() {\r\n nextTick(() => {\r\n if (fieldRef.value) fieldRef.value.scrollTop = 0\r\n })\r\n }\r\n\r\n function commit(value: string, opts?: { save?: boolean }) {\r\n let next = value\r\n const max = cfg.value.maxlength\r\n if (max != null && next.length > max) {\r\n next = next.slice(0, max)\r\n if (fieldRef.value) fieldRef.value.value = next\r\n }\r\n inner.value = next\r\n emit('update:modelValue', next)\r\n emit('input', next)\r\n if (opts?.save !== false) scheduleSave(next)\r\n syncScrollTop()\r\n }\r\n\r\n function onInput(e: Event) {\r\n // 组字过程也要同步,避免父级重渲染冲掉输入;结束前不触发 save\r\n commit((e.target as HTMLTextAreaElement).value, {\r\n save: !composing.value,\r\n })\r\n }\r\n\r\n function onCompositionStart() {\r\n composing.value = true\r\n }\r\n\r\n function onCompositionEnd(e: CompositionEvent) {\r\n composing.value = false\r\n commit((e.target as HTMLTextAreaElement).value)\r\n }\r\n\r\n function onChange(e: Event) {\r\n const val = (e.target as HTMLTextAreaElement).value\r\n if (cfg.value.validateEvent !== false) {\r\n formItem?.validate('change')\r\n }\r\n emit('change', val)\r\n }\r\n\r\n function onBlur() {\r\n if (cfg.value.validateEvent !== false) {\r\n formItem?.validate('blur')\r\n }\r\n }\r\n\r\n function onKeydownEnter() {\r\n syncScrollTop()\r\n }\r\n\r\n function onWindowResize() {\r\n syncScrollTop()\r\n }\r\n\r\n onMounted(() => {\r\n window.addEventListener('resize', onWindowResize)\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n window.removeEventListener('resize', onWindowResize)\r\n clearSaveTimer()\r\n })\r\n\r\n const api: TextareaExpose = {\r\n focus: () => fieldRef.value?.focus(),\r\n blur: () => fieldRef.value?.blur(),\r\n select: () => fieldRef.value?.select(),\r\n get textarea() {\r\n return fieldRef.value\r\n },\r\n }\r\n expose(api)\r\n\r\n return () => {\r\n const { class: klass, style: attrStyle, ...rest } = attrs\r\n const rootProps = mergeProps(\r\n {\r\n class: [\r\n 'w-textarea',\r\n {\r\n 'w-textarea--block': cfg.value.block,\r\n 'w-textarea--disabled': disabled.value,\r\n },\r\n klass,\r\n ],\r\n style: [\r\n toCssVarsStyle({\r\n ...propSizeToCssVars('textarea', cfg.value.size),\r\n ...propColorToCssVars('textarea', cfg.value.color),\r\n ...props.cssVars,\r\n }),\r\n attrStyle as any,\r\n ],\r\n },\r\n {},\r\n )\r\n\r\n return (\r\n <div {...rootProps}>\r\n <div class=\"w-textarea-ghost\" aria-hidden=\"true\">\r\n {ghostText(inner.value)}\r\n </div>\r\n <textarea\r\n {...rest}\r\n ref={fieldRef}\r\n class=\"w-textarea-field\"\r\n value={inner.value}\r\n placeholder={cfg.value.placeholder}\r\n maxlength={cfg.value.maxlength}\r\n disabled={disabled.value || undefined}\r\n readonly={cfg.value.readonly || undefined}\r\n rows={1}\r\n onInput={onInput}\r\n onChange={onChange}\r\n onBlur={onBlur}\r\n onCompositionstart={onCompositionStart}\r\n onCompositionend={onCompositionEnd}\r\n onKeydown={(e: KeyboardEvent) => {\r\n if (e.key === 'Enter') onKeydownEnter()\r\n }}\r\n />\r\n </div>\r\n )\r\n }\r\n },\r\n})\r\n\r\n/** 断言为 DefineComponent,hover / 补全直接看到 TextareaJSXProps(勿再包 XxxComponent 别名) */\r\nconst Textarea = TextareaImpl as unknown as DefineComponent<\r\n TextareaJSXProps,\r\n TextareaExpose\r\n>\r\n\r\nexport type TextareaInstance = InstanceType<typeof Textarea>\r\n\r\nexport default Textarea\r\n"],"mappings":"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"}