@holyer-lib/ui 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui.umd.js CHANGED
@@ -16,7 +16,319 @@
16
16
  return css;
17
17
  }
18
18
 
19
- function __$styleInject(css) {
19
+ function __$styleInject$2(css) {
20
+ if (!css) return;
21
+
22
+ if (typeof window == 'undefined') return;
23
+ var style = document.createElement('style');
24
+ style.setAttribute('media', 'screen');
25
+
26
+ style.innerHTML = css;
27
+ document.head.appendChild(style);
28
+ return css;
29
+ }
30
+
31
+ __$styleInject$2(".hi-expand-text {\n display: flex;\n width: 100%;\n line-height: 1.5;\n}\n.hi-expand-text--content {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n text-overflow: ellipsis;\n word-break: break-word;\n -webkit-line-clamp: var(--hi-expand-text-line-clamp);\n line-clamp: var(--hi-expand-text-line-clamp);\n}\n.hi-expand-text--content.hi-expand-text--content__show-toggle::before {\n content: '';\n float: right;\n height: 100%;\n margin-bottom: calc(-1em * 1.5);\n}\n.hi-expand-text--content__expanded {\n display: block;\n overflow: visible;\n -webkit-line-clamp: unset;\n line-clamp: unset;\n}\n.hi-expand-text--toggle {\n color: var(--td-brand-color);\n float: right;\n clear: both;\n cursor: pointer;\n}\n");
32
+
33
+ //
34
+
35
+ var script$2 = {
36
+ name: 'HiExpandText',
37
+ props: {
38
+ content: {
39
+ type: String,
40
+ default: ''
41
+ },
42
+
43
+ /**
44
+ * [0]: 展开时显示的文本,[1]: 收起时显示的文本
45
+ */
46
+ label: {
47
+ type: Array,
48
+ default: () => ['展开', '收起'],
49
+ validator: arr => {
50
+ return arr.length === 2 && arr.every(s => typeof s === 'string');
51
+ }
52
+ },
53
+
54
+ lineClamp: {
55
+ type: Number,
56
+ default: 2
57
+ }
58
+ },
59
+ data() {
60
+ return {
61
+ showToggle: false,
62
+ isExpanded: false,
63
+ resizeTimer: null,
64
+ resizeObserver: null
65
+ };
66
+ },
67
+ computed: {
68
+ expandText() {
69
+ return this.isExpanded ? this.label[1] : this.label[0];
70
+ },
71
+
72
+ textClass() {
73
+ return {
74
+ 'hi-expand-text--content': true,
75
+ 'hi-expand-text--content__show-toggle': this.showToggle,
76
+ 'hi-expand-text--content__expanded': this.isExpanded
77
+ };
78
+ }
79
+ },
80
+
81
+ watch: {
82
+ content() {
83
+ this.$nextTick(this.checkEllipsis);
84
+ }
85
+ },
86
+ mounted() {
87
+ this.checkEllipsis();
88
+ window.addEventListener('resize', this.handleResize);
89
+ if (window.ResizeObserver && this.$el) {
90
+ this.resizeObserver = new ResizeObserver(() => {
91
+ this.handleResize();
92
+ });
93
+ this.resizeObserver.observe(this.$el);
94
+ }
95
+ },
96
+ beforeDestroy() {
97
+ window.removeEventListener('resize', this.handleResize);
98
+ if (this.resizeObserver) this.resizeObserver.disconnect();
99
+ if (this.resizeTimer) clearTimeout(this.resizeTimer);
100
+ },
101
+
102
+ methods: {
103
+ handleResize() {
104
+ if (this.resizeTimer) clearTimeout(this.resizeTimer);
105
+ this.resizeTimer = setTimeout(() => {
106
+ this.checkEllipsis();
107
+ }, 100);
108
+ },
109
+
110
+ /**
111
+ * @Description 检查是否存在溢出情况,兼容展开和收起两种状态
112
+ * @Author holyer
113
+ * @Date 2026/02/08 17:01:51
114
+ */
115
+ checkEllipsis() {
116
+ const textEl = this.$refs.textRef;
117
+ if (!textEl || !textEl.offsetParent) {
118
+ this.showToggle = false;
119
+ return;
120
+ }
121
+
122
+ if (this.isExpanded) {
123
+ // 展开状态下:模拟收起状态,检测是否需要 toggle
124
+ this.showToggle = this.wouldOverflowIfCollapsed(textEl);
125
+ } else {
126
+ // 收起状态下:直接检测是否溢出
127
+ this.showToggle = textEl.scrollHeight - textEl.clientHeight > 2;
128
+ }
129
+ },
130
+
131
+ /**
132
+ * 模拟收起状态,检测内容是否会溢出
133
+ */
134
+ wouldOverflowIfCollapsed(el) {
135
+ // 1. 保存原始状态
136
+ const originalDisplay = el.style.display;
137
+ const originalWebkitLineClamp = el.style.webkitLineClamp;
138
+ const originalClassList = el.className;
139
+
140
+ try {
141
+ // 2. 临时应用“收起”样式,移除 --expanded 和 --show-toggle
142
+ el.className = 'hi-expand-text--content';
143
+ el.style.display = '-webkit-box';
144
+ el.style.webkitBoxOrient = 'vertical';
145
+ el.style.overflow = 'hidden';
146
+ el.style.webkitLineClamp = this.lineClamp;
147
+
148
+ // 3. 强制 reflow(触发 layout)
149
+ const { scrollHeight, clientHeight } = el;
150
+
151
+ // 4. 判断是否溢出
152
+ return scrollHeight - clientHeight > 2;
153
+ } finally {
154
+ // 5. 恢复原始状态(确保无副作用)
155
+ el.className = originalClassList;
156
+ el.style.display = originalDisplay;
157
+ el.style.webkitLineClamp = originalWebkitLineClamp;
158
+ }
159
+ },
160
+
161
+ handleToggle() {
162
+ this.isExpanded = !this.isExpanded;
163
+ this.$emit('toggle', this.isExpanded);
164
+ },
165
+
166
+ // 供外部手动更新
167
+ update() {
168
+ this.$nextTick(this.checkEllipsis);
169
+ }
170
+ }
171
+ };
172
+
173
+ function normalizeComponent$2(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
174
+ if (typeof shadowMode !== 'boolean') {
175
+ createInjectorSSR = createInjector;
176
+ createInjector = shadowMode;
177
+ shadowMode = false;
178
+ }
179
+ // Vue.extend constructor export interop.
180
+ const options = typeof script === 'function' ? script.options : script;
181
+ // render functions
182
+ if (template && template.render) {
183
+ options.render = template.render;
184
+ options.staticRenderFns = template.staticRenderFns;
185
+ options._compiled = true;
186
+ // functional template
187
+ if (isFunctionalTemplate) {
188
+ options.functional = true;
189
+ }
190
+ }
191
+ // scopedId
192
+ if (scopeId) {
193
+ options._scopeId = scopeId;
194
+ }
195
+ let hook;
196
+ if (moduleIdentifier) {
197
+ // server build
198
+ hook = function (context) {
199
+ // 2.3 injection
200
+ context =
201
+ context || // cached call
202
+ (this.$vnode && this.$vnode.ssrContext) || // stateful
203
+ (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
204
+ // 2.2 with runInNewContext: true
205
+ if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
206
+ context = __VUE_SSR_CONTEXT__;
207
+ }
208
+ // inject component styles
209
+ if (style) {
210
+ style.call(this, createInjectorSSR(context));
211
+ }
212
+ // register component module identifier for async chunk inference
213
+ if (context && context._registeredComponents) {
214
+ context._registeredComponents.add(moduleIdentifier);
215
+ }
216
+ };
217
+ // used by ssr in case component is cached and beforeCreate
218
+ // never gets called
219
+ options._ssrRegister = hook;
220
+ }
221
+ else if (style) {
222
+ hook = shadowMode
223
+ ? function (context) {
224
+ style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
225
+ }
226
+ : function (context) {
227
+ style.call(this, createInjector(context));
228
+ };
229
+ }
230
+ if (hook) {
231
+ if (options.functional) {
232
+ // register for functional component in vue file
233
+ const originalRender = options.render;
234
+ options.render = function renderWithStyleInjection(h, context) {
235
+ hook.call(context);
236
+ return originalRender(h, context);
237
+ };
238
+ }
239
+ else {
240
+ // inject component registration as beforeCreate hook
241
+ const existing = options.beforeCreate;
242
+ options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
243
+ }
244
+ }
245
+ return script;
246
+ }
247
+
248
+ /* script */
249
+ const __vue_script__$2 = script$2;
250
+
251
+ /* template */
252
+ var __vue_render__$2 = function () {
253
+ var _vm = this;
254
+ var _h = _vm.$createElement;
255
+ var _c = _vm._self._c || _h;
256
+ return _c(
257
+ "div",
258
+ {
259
+ staticClass: "hi-expand-text",
260
+ style: { "--hi-expand-text-line-clamp": _vm.lineClamp },
261
+ },
262
+ [
263
+ _c(
264
+ "div",
265
+ { ref: "textRef", class: _vm.textClass },
266
+ [
267
+ _vm.showToggle
268
+ ? _c(
269
+ "div",
270
+ {
271
+ staticClass: "hi-expand-text--toggle",
272
+ on: { click: _vm.handleToggle },
273
+ },
274
+ [
275
+ _vm._t("toggleText", function () {
276
+ return [_vm._v(_vm._s(_vm.expandText))]
277
+ }),
278
+ ],
279
+ 2
280
+ )
281
+ : _vm._e(),
282
+ _vm._v(" "),
283
+ _vm._t("default", function () {
284
+ return [_vm._v(_vm._s(_vm.content))]
285
+ }),
286
+ ],
287
+ 2
288
+ ),
289
+ ]
290
+ )
291
+ };
292
+ var __vue_staticRenderFns__$2 = [];
293
+ __vue_render__$2._withStripped = true;
294
+
295
+ /* style */
296
+ const __vue_inject_styles__$2 = undefined;
297
+ /* scoped */
298
+ const __vue_scope_id__$2 = undefined;
299
+ /* module identifier */
300
+ const __vue_module_identifier__$2 = undefined;
301
+ /* functional template */
302
+ const __vue_is_functional_template__$2 = false;
303
+ /* style inject */
304
+
305
+ /* style inject SSR */
306
+
307
+ /* style inject shadow dom */
308
+
309
+
310
+
311
+ const __vue_component__$2 = /*#__PURE__*/normalizeComponent$2(
312
+ { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
313
+ __vue_inject_styles__$2,
314
+ __vue_script__$2,
315
+ __vue_scope_id__$2,
316
+ __vue_is_functional_template__$2,
317
+ __vue_module_identifier__$2,
318
+ false,
319
+ undefined,
320
+ undefined,
321
+ undefined
322
+ );
323
+
324
+ __vue_component__$2.name = 'HiExpandText';
325
+
326
+ // 添加 install
327
+ __vue_component__$2.install = Vue => {
328
+ Vue.component(__vue_component__$2.name, __vue_component__$2);
329
+ };
330
+
331
+ function __$styleInject$1(css) {
20
332
  if (!css) return;
21
333
 
22
334
  if (typeof window == 'undefined') return;
@@ -28,7 +340,7 @@
28
340
  return css;
29
341
  }
30
342
 
31
- __$styleInject(".hi-title {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.hi-title--small {\n gap: 2px;\n}\n.hi-title--large {\n gap: 6px;\n}\n.hi-title__header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n.hi-title__prefix {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n}\n.hi-title__bar {\n width: 4px;\n background-color: var(--td-brand-color);\n flex-shrink: 0;\n}\n.hi-title__icon {\n flex-shrink: 0;\n line-height: 1;\n}\n.hi-title__text {\n margin: 0;\n font-weight: 600;\n color: var(--td-text-color-primary);\n}\n.hi-title__description {\n margin: 0;\n font-size: 12px;\n color: var(--td-text-color-secondary);\n}\n");
343
+ __$styleInject$1(".hi-title {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.hi-title--small {\n gap: 2px;\n}\n.hi-title--large {\n gap: 6px;\n}\n.hi-title__header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n.hi-title__prefix {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n}\n.hi-title__bar {\n width: 4px;\n background-color: var(--td-brand-color);\n flex-shrink: 0;\n}\n.hi-title__icon {\n flex-shrink: 0;\n line-height: 1;\n}\n.hi-title__text {\n margin: 0;\n font-weight: 600;\n color: var(--td-text-color-primary);\n}\n.hi-title__description {\n margin: 0;\n font-size: 12px;\n color: var(--td-text-color-secondary);\n}\n");
32
344
 
33
345
  //
34
346
  const TITILE_SIZE_MAP = {
@@ -36,7 +348,7 @@
36
348
  medium: '16px',
37
349
  large: '18px'
38
350
  };
39
- var script = {
351
+ var script$1 = {
40
352
  name: 'HiTitle',
41
353
  inheritAttrs: false,
42
354
  props: {
@@ -115,7 +427,7 @@
115
427
  }
116
428
  };
117
429
 
118
- function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
430
+ function normalizeComponent$1(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
119
431
  if (typeof shadowMode !== 'boolean') {
120
432
  createInjectorSSR = createInjector;
121
433
  createInjector = shadowMode;
@@ -191,10 +503,10 @@
191
503
  }
192
504
 
193
505
  /* script */
194
- const __vue_script__ = script;
506
+ const __vue_script__$1 = script$1;
195
507
 
196
508
  /* template */
197
- var __vue_render__ = function () {
509
+ var __vue_render__$1 = function () {
198
510
  var _vm = this;
199
511
  var _h = _vm.$createElement;
200
512
  var _c = _vm._self._c || _h;
@@ -260,6 +572,435 @@
260
572
  ]
261
573
  )
262
574
  };
575
+ var __vue_staticRenderFns__$1 = [];
576
+ __vue_render__$1._withStripped = true;
577
+
578
+ /* style */
579
+ const __vue_inject_styles__$1 = undefined;
580
+ /* scoped */
581
+ const __vue_scope_id__$1 = undefined;
582
+ /* module identifier */
583
+ const __vue_module_identifier__$1 = undefined;
584
+ /* functional template */
585
+ const __vue_is_functional_template__$1 = false;
586
+ /* style inject */
587
+
588
+ /* style inject SSR */
589
+
590
+ /* style inject shadow dom */
591
+
592
+
593
+
594
+ const __vue_component__$1 = /*#__PURE__*/normalizeComponent$1(
595
+ { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
596
+ __vue_inject_styles__$1,
597
+ __vue_script__$1,
598
+ __vue_scope_id__$1,
599
+ __vue_is_functional_template__$1,
600
+ __vue_module_identifier__$1,
601
+ false,
602
+ undefined,
603
+ undefined,
604
+ undefined
605
+ );
606
+
607
+ // 显式设置 name(避免 .vue 丢失)
608
+ __vue_component__$1.name = 'HiTitle';
609
+
610
+ // 添加 install
611
+ __vue_component__$1.install = Vue => {
612
+ Vue.component(__vue_component__$1.name, __vue_component__$1);
613
+ };
614
+
615
+ function __$styleInject(css) {
616
+ if (!css) return;
617
+
618
+ if (typeof window == 'undefined') return;
619
+ var style = document.createElement('style');
620
+ style.setAttribute('media', 'screen');
621
+
622
+ style.innerHTML = css;
623
+ document.head.appendChild(style);
624
+ return css;
625
+ }
626
+
627
+ __$styleInject(".hi-virtual-list {\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n will-change: scroll-position;\n}\n.hi-virtual-list--placeholder {\n pointer-events: none;\n}\n.hi-virtual-list--item-wrapper {\n box-sizing: border-box;\n}\n");
628
+
629
+ /**
630
+ * 类型判断工具
631
+ */
632
+
633
+ /**
634
+ * 将数值或字符串转换为合法的 CSS 长度值(用于 style 绑定)
635
+ * - 若为 number,自动追加 'px' 单位
636
+ * - 若为 string,原样返回(假定用户已提供合法 CSS 长度值)
637
+ * @param {number|string} value - 输入值(如 100, '100%', '50vh', 'auto')
638
+ * @returns {string} 合法的 CSS 长度字符串 默认值为 0
639
+ * @example
640
+ * formatSize(100) // '100px'
641
+ * formatSize('100%') // '100%'
642
+ * formatSize('50vh') // '50vh'
643
+ * formatSize(null) // 0
644
+ * formatSize(undefined) // 0
645
+ */
646
+ function formatSize(value) {
647
+ if (typeof value === 'number') {
648
+ return `${value}px`;
649
+ }
650
+ if (typeof value === 'string') {
651
+ if (value.trim() === '') {
652
+ return 0;
653
+ }
654
+ return value;
655
+ }
656
+ return 0;
657
+ }
658
+
659
+ //
660
+
661
+ var script = {
662
+ name: 'HiVirtualList',
663
+ props: {
664
+ items: {
665
+ type: Array,
666
+ required: true,
667
+ default: () => []
668
+ },
669
+ itemHeight: {
670
+ type: Number,
671
+ required: true,
672
+ validator(value) {
673
+ if (value <= 0) {
674
+ // eslint-disable-next-line no-console
675
+ console.error('[HiVirtualList] itemHeight must be a positive number.');
676
+ return false;
677
+ }
678
+ return true;
679
+ }
680
+ },
681
+ height: {
682
+ type: [Number, String],
683
+ required: true
684
+ },
685
+ buffer: {
686
+ type: Number,
687
+ default: 50
688
+ },
689
+ nodeKey: {
690
+ type: String,
691
+ default: undefined
692
+ }
693
+ },
694
+ data() {
695
+ return {
696
+ scrollTop: 0,
697
+ clientHeight: 0,
698
+ resizeObserver: null,
699
+ resizeTimer: null
700
+ };
701
+ },
702
+ computed: {
703
+ styles() {
704
+ return {
705
+ height: formatSize(this.height)
706
+ };
707
+ },
708
+ renderItemHeight() {
709
+ return formatSize(this.itemHeight);
710
+ },
711
+ total() {
712
+ return this.items.length;
713
+ },
714
+ visibleCount() {
715
+ if (!this.clientHeight || !this.itemHeight) return 20;
716
+ return Math.ceil(this.clientHeight / this.itemHeight) + this.buffer * 2;
717
+ },
718
+ startIndex() {
719
+ return Math.max(0, Math.floor(this.scrollTop / this.itemHeight));
720
+ },
721
+ endIndex() {
722
+ return Math.min(this.total, this.startIndex + this.visibleCount);
723
+ },
724
+ visibleItems() {
725
+ return this.items.slice(this.startIndex, this.endIndex);
726
+ },
727
+ topPlaceholderHeight() {
728
+ return formatSize(this.startIndex * this.itemHeight);
729
+ },
730
+ bottomPlaceholderHeight() {
731
+ return formatSize((this.total - this.endIndex) * this.itemHeight);
732
+ }
733
+ },
734
+ mounted() {
735
+ this.updateClientHeight();
736
+ this.setupResizeListener();
737
+ },
738
+ beforeDestroy() {
739
+ this.cleanupResizeListener();
740
+ },
741
+ methods: {
742
+ /**
743
+ * 判断是否应使用 nodeKey 字段
744
+ */
745
+ _shouldUseNodeKey() {
746
+ return this.nodeKey && typeof this.nodeKey === 'string' && this.nodeKey.trim() !== '';
747
+ },
748
+
749
+ /**
750
+ * 获取 item 的唯一 key(用于 v-for)
751
+ */
752
+ getNodeKey(item, index) {
753
+ if (this._shouldUseNodeKey() && item != null && typeof item === 'object') {
754
+ const key = item[this.nodeKey];
755
+ if (key != null) {
756
+ return key;
757
+ }
758
+ }
759
+ return index;
760
+ },
761
+
762
+ updateClientHeight() {
763
+ if (this.$refs.rootRef) {
764
+ this.clientHeight = this.$refs.rootRef.clientHeight;
765
+ }
766
+ },
767
+
768
+ setupResizeListener() {
769
+ if (typeof ResizeObserver !== 'undefined') {
770
+ this.resizeObserver = new ResizeObserver(() => {
771
+ this.updateClientHeight();
772
+ });
773
+ this.resizeObserver.observe(this.$refs.rootRef);
774
+ } else {
775
+ window.addEventListener('resize', this.handleWindowResize);
776
+ }
777
+ },
778
+
779
+ cleanupResizeListener() {
780
+ if (this.resizeObserver) {
781
+ this.resizeObserver.disconnect();
782
+ this.resizeObserver = null;
783
+ }
784
+ if (this.resizeTimer) {
785
+ clearTimeout(this.resizeTimer);
786
+ this.resizeTimer = null;
787
+ }
788
+ window.removeEventListener('resize', this.handleWindowResize);
789
+ },
790
+
791
+ handleWindowResize() {
792
+ if (this.resizeTimer) {
793
+ clearTimeout(this.resizeTimer);
794
+ }
795
+ this.resizeTimer = setTimeout(() => {
796
+ this.updateClientHeight();
797
+ }, 100);
798
+ },
799
+
800
+ handleScroll(e) {
801
+ this.scrollTop = e.target.scrollTop;
802
+ this.$emit('scroll', e);
803
+
804
+ const { scrollHeight, clientHeight, scrollTop } = e.target;
805
+ if (scrollTop === 0) this.$emit('reach-top');
806
+ if (scrollHeight - clientHeight - scrollTop < 100) this.$emit('reach-bottom');
807
+ this.$emit('visible-change', { startIndex: this.startIndex, endIndex: this.endIndex });
808
+ },
809
+
810
+ refresh() {
811
+ this.updateClientHeight();
812
+ },
813
+
814
+ /**
815
+ * 内部滚动方法(仅设置 DOM scrollTop,状态由 handleScroll 同步)
816
+ */
817
+ _setScrollTop(scrollTop) {
818
+ if (this.$refs.rootRef) {
819
+ this.$refs.rootRef.scrollTop = scrollTop;
820
+ }
821
+ },
822
+
823
+ /**
824
+ * 滚动到指定目标
825
+ * - 若启用了有效的 nodeKey,则 target 视为 keyValue
826
+ * - 否则,target 必须是 number(index)
827
+ */
828
+ scrollTo(target) {
829
+ if (target == null) {
830
+ // eslint-disable-next-line no-console
831
+ console.warn('[HiVirtualList] scrollTo: target cannot be null or undefined');
832
+ return;
833
+ }
834
+
835
+ let index = -1;
836
+
837
+ // 使用 getNodeKey 生成的 key 进行匹配(严格对齐)
838
+ if (this._shouldUseNodeKey()) {
839
+ index = this.items.findIndex((item, i) => {
840
+ return this.getNodeKey(item, i) === target;
841
+ });
842
+ } else {
843
+ // 降级到 index 模式
844
+ if (typeof target === 'number' && target >= 0 && target < this.total) {
845
+ index = target;
846
+ } else {
847
+ // eslint-disable-next-line no-console
848
+ console.warn(
849
+ '[HiVirtualList] scrollTo: when nodeKey is not provided, target must be a valid index (number).'
850
+ );
851
+ return;
852
+ }
853
+ }
854
+
855
+ if (index < 0 || index >= this.total) {
856
+ if (this._shouldUseNodeKey()) {
857
+ // eslint-disable-next-line no-console
858
+ console.warn(`[HiVirtualList] scrollTo: item with key "${target}" not found`);
859
+ } else {
860
+ // eslint-disable-next-line no-console
861
+ console.warn(`[HiVirtualList] scrollTo: index ${target} is out of range [0, ${this.total})`);
862
+ }
863
+ return;
864
+ }
865
+
866
+ this._setScrollTop(index * this.itemHeight);
867
+ },
868
+
869
+ scrollToTop() {
870
+ this._setScrollTop(0);
871
+ },
872
+
873
+ scrollToBottom() {
874
+ this._setScrollTop(this.total * this.itemHeight);
875
+ },
876
+
877
+ getVisibleRange() {
878
+ return {
879
+ startIndex: this.startIndex,
880
+ endIndex: this.endIndex
881
+ };
882
+ }
883
+ }
884
+ };
885
+
886
+ function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
887
+ if (typeof shadowMode !== 'boolean') {
888
+ createInjectorSSR = createInjector;
889
+ createInjector = shadowMode;
890
+ shadowMode = false;
891
+ }
892
+ // Vue.extend constructor export interop.
893
+ const options = typeof script === 'function' ? script.options : script;
894
+ // render functions
895
+ if (template && template.render) {
896
+ options.render = template.render;
897
+ options.staticRenderFns = template.staticRenderFns;
898
+ options._compiled = true;
899
+ // functional template
900
+ if (isFunctionalTemplate) {
901
+ options.functional = true;
902
+ }
903
+ }
904
+ // scopedId
905
+ if (scopeId) {
906
+ options._scopeId = scopeId;
907
+ }
908
+ let hook;
909
+ if (moduleIdentifier) {
910
+ // server build
911
+ hook = function (context) {
912
+ // 2.3 injection
913
+ context =
914
+ context || // cached call
915
+ (this.$vnode && this.$vnode.ssrContext) || // stateful
916
+ (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
917
+ // 2.2 with runInNewContext: true
918
+ if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
919
+ context = __VUE_SSR_CONTEXT__;
920
+ }
921
+ // inject component styles
922
+ if (style) {
923
+ style.call(this, createInjectorSSR(context));
924
+ }
925
+ // register component module identifier for async chunk inference
926
+ if (context && context._registeredComponents) {
927
+ context._registeredComponents.add(moduleIdentifier);
928
+ }
929
+ };
930
+ // used by ssr in case component is cached and beforeCreate
931
+ // never gets called
932
+ options._ssrRegister = hook;
933
+ }
934
+ else if (style) {
935
+ hook = shadowMode
936
+ ? function (context) {
937
+ style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
938
+ }
939
+ : function (context) {
940
+ style.call(this, createInjector(context));
941
+ };
942
+ }
943
+ if (hook) {
944
+ if (options.functional) {
945
+ // register for functional component in vue file
946
+ const originalRender = options.render;
947
+ options.render = function renderWithStyleInjection(h, context) {
948
+ hook.call(context);
949
+ return originalRender(h, context);
950
+ };
951
+ }
952
+ else {
953
+ // inject component registration as beforeCreate hook
954
+ const existing = options.beforeCreate;
955
+ options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
956
+ }
957
+ }
958
+ return script;
959
+ }
960
+
961
+ /* script */
962
+ const __vue_script__ = script;
963
+
964
+ /* template */
965
+ var __vue_render__ = function () {
966
+ var _vm = this;
967
+ var _h = _vm.$createElement;
968
+ var _c = _vm._self._c || _h;
969
+ return _c(
970
+ "div",
971
+ {
972
+ ref: "rootRef",
973
+ staticClass: "hi-virtual-list",
974
+ style: _vm.styles,
975
+ on: { scroll: _vm.handleScroll },
976
+ },
977
+ [
978
+ _c("div", {
979
+ staticClass: "hi-virtual-list--placeholder",
980
+ style: { height: _vm.topPlaceholderHeight },
981
+ }),
982
+ _vm._v(" "),
983
+ _vm._l(_vm.visibleItems, function (item, i) {
984
+ return _c(
985
+ "div",
986
+ {
987
+ key: _vm.getNodeKey(item, _vm.startIndex + i),
988
+ staticClass: "hi-virtual-list--item-wrapper",
989
+ style: { height: _vm.renderItemHeight },
990
+ },
991
+ [_vm._t("default", null, { item: item, index: _vm.startIndex + i })],
992
+ 2
993
+ )
994
+ }),
995
+ _vm._v(" "),
996
+ _c("div", {
997
+ staticClass: "hi-virtual-list--placeholder",
998
+ style: { height: _vm.bottomPlaceholderHeight },
999
+ }),
1000
+ ],
1001
+ 2
1002
+ )
1003
+ };
263
1004
  var __vue_staticRenderFns__ = [];
264
1005
  __vue_render__._withStripped = true;
265
1006
 
@@ -293,14 +1034,19 @@
293
1034
  );
294
1035
 
295
1036
  // 显式设置 name(避免 .vue 丢失)
296
- __vue_component__.name = 'HiTitle';
1037
+ __vue_component__.name = 'HiVirtualList';
297
1038
 
298
1039
  // 添加 install
299
1040
  __vue_component__.install = Vue => {
300
1041
  Vue.component(__vue_component__.name, __vue_component__);
301
1042
  };
302
1043
 
303
- const components = [__vue_component__];
1044
+ // eslint-disable-next-line prettier/prettier
1045
+ const components = [
1046
+ __vue_component__$2,
1047
+ __vue_component__$1,
1048
+ __vue_component__
1049
+ ];
304
1050
 
305
1051
  const install = function (Vue) {
306
1052
  components.forEach(component => {
@@ -308,7 +1054,12 @@
308
1054
  });
309
1055
  };
310
1056
 
311
- var index = { install, HiTitle: __vue_component__ };
1057
+ var index = {
1058
+ install,
1059
+ HiExpandText: __vue_component__$2,
1060
+ HiTitle: __vue_component__$1,
1061
+ HiVirtualList: __vue_component__
1062
+ };
312
1063
 
313
1064
  return index;
314
1065