@hoci/components 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs DELETED
@@ -1,2238 +0,0 @@
1
- 'use strict';
2
-
3
- const shared = require('@hoci/shared');
4
- const vue = require('vue');
5
- const tslx = require('tslx');
6
- const core = require('@hoci/core');
7
-
8
- function tryOnScopeDispose(fn) {
9
- if (vue.getCurrentScope()) {
10
- vue.onScopeDispose(fn);
11
- return true;
12
- }
13
- return false;
14
- }
15
-
16
- function isDefined(v) {
17
- return vue.unref(v) != null;
18
- }
19
-
20
- const isClient = typeof window !== "undefined" && typeof document !== "undefined";
21
- typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
22
- const notNullish = (val) => val != null;
23
- const toString = Object.prototype.toString;
24
- const isObject = (val) => toString.call(val) === "[object Object]";
25
- const noop = () => {
26
- };
27
-
28
- function createFilterWrapper(filter, fn) {
29
- function wrapper(...args) {
30
- return new Promise((resolve, reject) => {
31
- Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
32
- });
33
- }
34
- return wrapper;
35
- }
36
- const bypassFilter = (invoke) => {
37
- return invoke();
38
- };
39
- function pausableFilter(extendFilter = bypassFilter, options = {}) {
40
- const {
41
- initialState = "active"
42
- } = options;
43
- const isActive = toRef(initialState === "active");
44
- function pause() {
45
- isActive.value = false;
46
- }
47
- function resume() {
48
- isActive.value = true;
49
- }
50
- const eventFilter = (...args) => {
51
- if (isActive.value)
52
- extendFilter(...args);
53
- };
54
- return { isActive: vue.readonly(isActive), pause, resume, eventFilter };
55
- }
56
- function getLifeCycleTarget(target) {
57
- return vue.getCurrentInstance();
58
- }
59
- function toArray(value) {
60
- return Array.isArray(value) ? value : [value];
61
- }
62
-
63
- function toRef(...args) {
64
- if (args.length !== 1)
65
- return vue.toRef(...args);
66
- const r = args[0];
67
- return typeof r === "function" ? vue.readonly(vue.customRef(() => ({ get: r, set: noop }))) : vue.ref(r);
68
- }
69
-
70
- function watchWithFilter(source, cb, options = {}) {
71
- const {
72
- eventFilter = bypassFilter,
73
- ...watchOptions
74
- } = options;
75
- return vue.watch(
76
- source,
77
- createFilterWrapper(
78
- eventFilter,
79
- cb
80
- ),
81
- watchOptions
82
- );
83
- }
84
-
85
- function watchPausable(source, cb, options = {}) {
86
- const {
87
- eventFilter: filter,
88
- initialState = "active",
89
- ...watchOptions
90
- } = options;
91
- const { eventFilter, pause, resume, isActive } = pausableFilter(filter, { initialState });
92
- const stop = watchWithFilter(
93
- source,
94
- cb,
95
- {
96
- ...watchOptions,
97
- eventFilter
98
- }
99
- );
100
- return { stop, pause, resume, isActive };
101
- }
102
-
103
- function syncRef(left, right, ...[options]) {
104
- const {
105
- flush = "sync",
106
- deep = false,
107
- immediate = true,
108
- direction = "both",
109
- transform = {}
110
- } = options || {};
111
- const watchers = [];
112
- const transformLTR = "ltr" in transform && transform.ltr || ((v) => v);
113
- const transformRTL = "rtl" in transform && transform.rtl || ((v) => v);
114
- if (direction === "both" || direction === "ltr") {
115
- watchers.push(watchPausable(
116
- left,
117
- (newValue) => {
118
- watchers.forEach((w) => w.pause());
119
- right.value = transformLTR(newValue);
120
- watchers.forEach((w) => w.resume());
121
- },
122
- { flush, deep, immediate }
123
- ));
124
- }
125
- if (direction === "both" || direction === "rtl") {
126
- watchers.push(watchPausable(
127
- right,
128
- (newValue) => {
129
- watchers.forEach((w) => w.pause());
130
- left.value = transformRTL(newValue);
131
- watchers.forEach((w) => w.resume());
132
- },
133
- { flush, deep, immediate }
134
- ));
135
- }
136
- const stop = () => {
137
- watchers.forEach((w) => w.stop());
138
- };
139
- return stop;
140
- }
141
-
142
- function tryOnMounted(fn, sync = true, target) {
143
- const instance = getLifeCycleTarget();
144
- if (instance)
145
- vue.onMounted(fn, target);
146
- else if (sync)
147
- fn();
148
- else
149
- vue.nextTick(fn);
150
- }
151
-
152
- function watchImmediate(source, cb, options) {
153
- return vue.watch(
154
- source,
155
- cb,
156
- {
157
- ...options,
158
- immediate: true
159
- }
160
- );
161
- }
162
-
163
- function watchOnce(source, cb, options) {
164
- const stop = vue.watch(source, (...args) => {
165
- vue.nextTick(() => stop());
166
- return cb(...args);
167
- }, options);
168
- return stop;
169
- }
170
-
171
- const defaultWindow = isClient ? window : void 0;
172
-
173
- function unrefElement(elRef) {
174
- var _a;
175
- const plain = vue.toValue(elRef);
176
- return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
177
- }
178
-
179
- function useEventListener(...args) {
180
- const cleanups = [];
181
- const cleanup = () => {
182
- cleanups.forEach((fn) => fn());
183
- cleanups.length = 0;
184
- };
185
- const register = (el, event, listener, options) => {
186
- el.addEventListener(event, listener, options);
187
- return () => el.removeEventListener(event, listener, options);
188
- };
189
- const firstParamTargets = vue.computed(() => {
190
- const test = toArray(vue.toValue(args[0])).filter((e) => e != null);
191
- return test.every((e) => typeof e !== "string") ? test : void 0;
192
- });
193
- const stopWatch = watchImmediate(
194
- () => {
195
- var _a, _b;
196
- return [
197
- (_b = (_a = firstParamTargets.value) == null ? void 0 : _a.map((e) => unrefElement(e))) != null ? _b : [defaultWindow].filter((e) => e != null),
198
- toArray(vue.toValue(firstParamTargets.value ? args[1] : args[0])),
199
- toArray(vue.unref(firstParamTargets.value ? args[2] : args[1])),
200
- // @ts-expect-error - TypeScript gets the correct types, but somehow still complains
201
- vue.toValue(firstParamTargets.value ? args[3] : args[2])
202
- ];
203
- },
204
- ([raw_targets, raw_events, raw_listeners, raw_options]) => {
205
- cleanup();
206
- if (!(raw_targets == null ? void 0 : raw_targets.length) || !(raw_events == null ? void 0 : raw_events.length) || !(raw_listeners == null ? void 0 : raw_listeners.length))
207
- return;
208
- const optionsClone = isObject(raw_options) ? { ...raw_options } : raw_options;
209
- cleanups.push(
210
- ...raw_targets.flatMap(
211
- (el) => raw_events.flatMap(
212
- (event) => raw_listeners.map((listener) => register(el, event, listener, optionsClone))
213
- )
214
- )
215
- );
216
- },
217
- { flush: "post" }
218
- );
219
- const stop = () => {
220
- stopWatch();
221
- cleanup();
222
- };
223
- tryOnScopeDispose(cleanup);
224
- return stop;
225
- }
226
-
227
- function useMounted() {
228
- const isMounted = vue.shallowRef(false);
229
- const instance = vue.getCurrentInstance();
230
- if (instance) {
231
- vue.onMounted(() => {
232
- isMounted.value = true;
233
- }, instance);
234
- }
235
- return isMounted;
236
- }
237
-
238
- function useSupported(callback) {
239
- const isMounted = useMounted();
240
- return vue.computed(() => {
241
- isMounted.value;
242
- return Boolean(callback());
243
- });
244
- }
245
-
246
- function useMutationObserver(target, callback, options = {}) {
247
- const { window = defaultWindow, ...mutationOptions } = options;
248
- let observer;
249
- const isSupported = useSupported(() => window && "MutationObserver" in window);
250
- const cleanup = () => {
251
- if (observer) {
252
- observer.disconnect();
253
- observer = void 0;
254
- }
255
- };
256
- const targets = vue.computed(() => {
257
- const value = vue.toValue(target);
258
- const items = toArray(value).map(unrefElement).filter(notNullish);
259
- return new Set(items);
260
- });
261
- const stopWatch = vue.watch(
262
- () => targets.value,
263
- (targets2) => {
264
- cleanup();
265
- if (isSupported.value && targets2.size) {
266
- observer = new MutationObserver(callback);
267
- targets2.forEach((el) => observer.observe(el, mutationOptions));
268
- }
269
- },
270
- { immediate: true, flush: "post" }
271
- );
272
- const takeRecords = () => {
273
- return observer == null ? void 0 : observer.takeRecords();
274
- };
275
- const stop = () => {
276
- stopWatch();
277
- cleanup();
278
- };
279
- tryOnScopeDispose(stop);
280
- return {
281
- isSupported,
282
- stop,
283
- takeRecords
284
- };
285
- }
286
-
287
- function useResizeObserver(target, callback, options = {}) {
288
- const { window = defaultWindow, ...observerOptions } = options;
289
- let observer;
290
- const isSupported = useSupported(() => window && "ResizeObserver" in window);
291
- const cleanup = () => {
292
- if (observer) {
293
- observer.disconnect();
294
- observer = void 0;
295
- }
296
- };
297
- const targets = vue.computed(() => {
298
- const _targets = vue.toValue(target);
299
- return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)];
300
- });
301
- const stopWatch = vue.watch(
302
- targets,
303
- (els) => {
304
- cleanup();
305
- if (isSupported.value && window) {
306
- observer = new ResizeObserver(callback);
307
- for (const _el of els) {
308
- if (_el)
309
- observer.observe(_el, observerOptions);
310
- }
311
- }
312
- },
313
- { immediate: true, flush: "post" }
314
- );
315
- const stop = () => {
316
- cleanup();
317
- stopWatch();
318
- };
319
- tryOnScopeDispose(stop);
320
- return {
321
- isSupported,
322
- stop
323
- };
324
- }
325
-
326
- function useElementBounding(target, options = {}) {
327
- const {
328
- reset = true,
329
- windowResize = true,
330
- windowScroll = true,
331
- immediate = true,
332
- updateTiming = "sync"
333
- } = options;
334
- const height = vue.shallowRef(0);
335
- const bottom = vue.shallowRef(0);
336
- const left = vue.shallowRef(0);
337
- const right = vue.shallowRef(0);
338
- const top = vue.shallowRef(0);
339
- const width = vue.shallowRef(0);
340
- const x = vue.shallowRef(0);
341
- const y = vue.shallowRef(0);
342
- function recalculate() {
343
- const el = unrefElement(target);
344
- if (!el) {
345
- if (reset) {
346
- height.value = 0;
347
- bottom.value = 0;
348
- left.value = 0;
349
- right.value = 0;
350
- top.value = 0;
351
- width.value = 0;
352
- x.value = 0;
353
- y.value = 0;
354
- }
355
- return;
356
- }
357
- const rect = el.getBoundingClientRect();
358
- height.value = rect.height;
359
- bottom.value = rect.bottom;
360
- left.value = rect.left;
361
- right.value = rect.right;
362
- top.value = rect.top;
363
- width.value = rect.width;
364
- x.value = rect.x;
365
- y.value = rect.y;
366
- }
367
- function update() {
368
- if (updateTiming === "sync")
369
- recalculate();
370
- else if (updateTiming === "next-frame")
371
- requestAnimationFrame(() => recalculate());
372
- }
373
- useResizeObserver(target, update);
374
- vue.watch(() => unrefElement(target), (ele) => !ele && update());
375
- useMutationObserver(target, update, {
376
- attributeFilter: ["style", "class"]
377
- });
378
- if (windowScroll)
379
- useEventListener("scroll", update, { capture: true, passive: true });
380
- if (windowResize)
381
- useEventListener("resize", update, { passive: true });
382
- tryOnMounted(() => {
383
- if (immediate)
384
- update();
385
- });
386
- return {
387
- height,
388
- bottom,
389
- left,
390
- right,
391
- top,
392
- width,
393
- x,
394
- y,
395
- update
396
- };
397
- }
398
-
399
- function useIntersectionObserver(target, callback, options = {}) {
400
- const {
401
- root,
402
- rootMargin = "0px",
403
- threshold = 0,
404
- window = defaultWindow,
405
- immediate = true
406
- } = options;
407
- const isSupported = useSupported(() => window && "IntersectionObserver" in window);
408
- const targets = vue.computed(() => {
409
- const _target = vue.toValue(target);
410
- return toArray(_target).map(unrefElement).filter(notNullish);
411
- });
412
- let cleanup = noop;
413
- const isActive = vue.shallowRef(immediate);
414
- const stopWatch = isSupported.value ? vue.watch(
415
- () => [targets.value, unrefElement(root), isActive.value],
416
- ([targets2, root2]) => {
417
- cleanup();
418
- if (!isActive.value)
419
- return;
420
- if (!targets2.length)
421
- return;
422
- const observer = new IntersectionObserver(
423
- callback,
424
- {
425
- root: unrefElement(root2),
426
- rootMargin,
427
- threshold
428
- }
429
- );
430
- targets2.forEach((el) => el && observer.observe(el));
431
- cleanup = () => {
432
- observer.disconnect();
433
- cleanup = noop;
434
- };
435
- },
436
- { immediate, flush: "post" }
437
- ) : noop;
438
- const stop = () => {
439
- cleanup();
440
- stopWatch();
441
- isActive.value = false;
442
- };
443
- tryOnScopeDispose(stop);
444
- return {
445
- isSupported,
446
- isActive,
447
- pause() {
448
- cleanup();
449
- isActive.value = false;
450
- },
451
- resume() {
452
- isActive.value = true;
453
- },
454
- stop
455
- };
456
- }
457
-
458
- function useElementVisibility(element, options = {}) {
459
- const {
460
- window = defaultWindow,
461
- scrollTarget,
462
- threshold = 0,
463
- rootMargin,
464
- once = false
465
- } = options;
466
- const elementIsVisible = vue.shallowRef(false);
467
- const { stop } = useIntersectionObserver(
468
- element,
469
- (intersectionObserverEntries) => {
470
- let isIntersecting = elementIsVisible.value;
471
- let latestTime = 0;
472
- for (const entry of intersectionObserverEntries) {
473
- if (entry.time >= latestTime) {
474
- latestTime = entry.time;
475
- isIntersecting = entry.isIntersecting;
476
- }
477
- }
478
- elementIsVisible.value = isIntersecting;
479
- if (once) {
480
- watchOnce(elementIsVisible, () => {
481
- stop();
482
- });
483
- }
484
- },
485
- {
486
- root: scrollTarget,
487
- window,
488
- threshold,
489
- rootMargin: vue.toValue(rootMargin)
490
- }
491
- );
492
- return elementIsVisible;
493
- }
494
-
495
- const affixProps = shared.defineHookProps(
496
- {
497
- fixedClass: {
498
- type: String,
499
- default: ""
500
- },
501
- /**
502
- * @zh 距离窗口顶部达到指定偏移量后触发
503
- * @en Triggered when the specified offset is reached from the top of the window
504
- */
505
- offset: {
506
- type: Number,
507
- default: 0
508
- },
509
- /**
510
- * @zh 固定的相对方向
511
- */
512
- position: {
513
- type: String,
514
- default: "top"
515
- },
516
- /**
517
- * @zh 滚动容器,默认是 `window`
518
- * @en Scroll container, default is `window`
519
- */
520
- target: {
521
- type: [String, Object, Function]
522
- },
523
- /**
524
- * @zh z-index 值
525
- * @en Z index value
526
- */
527
- zIndex: {
528
- type: Number,
529
- default: 998
530
- }
531
- }
532
- );
533
- shared.defineHookEmits(["scroll", "change"]);
534
- const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
535
- function getTargetRect(target) {
536
- return shared.isWindow(target) ? {
537
- top: 0,
538
- bottom: window.innerHeight
539
- } : target.getBoundingClientRect();
540
- }
541
- shared.defineHookComponent({
542
- props: affixProps,
543
- setup(props, { emit }) {
544
- const wrapperRef = shared.elementRef();
545
- const wrapperRect = shared.toReactive(useElementBounding(wrapperRef));
546
- const parentRef = vue.inject(AFFIX_TARGET_KEY, void 0);
547
- const targetRef = shared.useElement(props.target, parentRef);
548
- const isFixed = vue.ref(false);
549
- const placeholderStyle = vue.ref({});
550
- const fixedStyle = vue.ref({});
551
- const className = vue.computed(() => {
552
- return isFixed.value ? props.fixedClass : "";
553
- });
554
- const wrapperVisible = useElementVisibility(wrapperRef);
555
- const containerRef = vue.computed(() => {
556
- if (!wrapperVisible.value) {
557
- return null;
558
- }
559
- return targetRef.value ?? window;
560
- });
561
- const updatePosition = shared.throttleByRaf(async () => {
562
- if (!wrapperRef.value || !containerRef.value) {
563
- return;
564
- }
565
- const area = wrapperRect.width * wrapperRect.height;
566
- if (area === 0) {
567
- return;
568
- }
569
- const newPlaceholderStyles = {
570
- width: tslx.px(wrapperRect.width),
571
- height: tslx.px(wrapperRect.height)
572
- };
573
- const targetRect = getTargetRect(containerRef.value);
574
- let newIsFixed = false;
575
- let newFixedStyles = {};
576
- const offset = props.offset;
577
- if (props.position === "top") {
578
- newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
579
- newFixedStyles = newIsFixed ? {
580
- position: "fixed",
581
- zIndex: props.zIndex,
582
- top: tslx.px(targetRect.top + offset)
583
- } : {};
584
- } else {
585
- newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
586
- newFixedStyles = newIsFixed ? {
587
- position: "fixed",
588
- bottom: tslx.px(window.innerHeight - targetRect.bottom + offset)
589
- } : {};
590
- }
591
- if (newIsFixed !== isFixed.value) {
592
- isFixed.value = newIsFixed;
593
- emit("change", newIsFixed);
594
- }
595
- placeholderStyle.value = newPlaceholderStyles;
596
- fixedStyle.value = {
597
- ...newFixedStyles,
598
- ...newIsFixed ? newPlaceholderStyles : {}
599
- };
600
- });
601
- useEventListener(containerRef, "scroll", () => {
602
- emit("scroll");
603
- updatePosition();
604
- });
605
- useEventListener(containerRef, "resize", updatePosition);
606
- vue.watchPostEffect(updatePosition);
607
- return {
608
- className,
609
- wrapperRef,
610
- containerRef,
611
- isFixed,
612
- placeholderStyle,
613
- fixedStyle,
614
- updatePosition
615
- };
616
- }
617
- });
618
- function provideAffixTarget(target) {
619
- vue.provide(AFFIX_TARGET_KEY, target);
620
- }
621
-
622
- const HiAffixTarget = vue.defineComponent({
623
- name: "HiAffixTarget",
624
- setup(_, context) {
625
- const targetRef = shared.elementRef();
626
- provideAffixTarget(targetRef);
627
- return () => vue.h("div", {
628
- ref: targetRef,
629
- ...context.attrs
630
- }, vue.renderSlot(context.slots, "default"));
631
- }
632
- });
633
-
634
- const HiAffix = vue.defineComponent({
635
- name: "HiAffix",
636
- props: {
637
- ...core.affixProps,
638
- as: {
639
- type: String,
640
- default: "div"
641
- }
642
- },
643
- setup(props, context) {
644
- const { className, wrapperRef, isFixed, placeholderStyle, fixedStyle } = core.useAffix(props, context);
645
- return () => vue.h(props.as, { ref: wrapperRef }, [
646
- isFixed.value && vue.h("div", { style: placeholderStyle.value }),
647
- vue.h("div", { class: className.value, style: fixedStyle.value }, vue.renderSlot(context.slots, "default"))
648
- ]);
649
- }
650
- });
651
-
652
- const HiConfigProvider = vue.defineComponent({
653
- props: {
654
- ...core.configProviderProps,
655
- as: {
656
- type: String
657
- }
658
- },
659
- setup(props, context) {
660
- core.provideSharedConfig(props);
661
- return () => {
662
- const content = vue.renderSlot(context.slots, "default", void 0);
663
- if (props.as) {
664
- return vue.h(props.as, content);
665
- }
666
- return content;
667
- };
668
- }
669
- });
670
-
671
- const HiFileUpload = vue.defineComponent({
672
- name: "HiFileUpload",
673
- props: {
674
- ...core.fileUploadProps,
675
- accept: {
676
- type: String,
677
- default: "*/*"
678
- },
679
- as: {
680
- type: String,
681
- default: "div"
682
- }
683
- },
684
- emits: core.fileUploadEmits,
685
- setup(props, context) {
686
- const { slots } = context;
687
- const { fileInputRef, files, openFileInput } = core.useFileUpload(props, context);
688
- return () => {
689
- return vue.h(props.as, {
690
- onClick: openFileInput
691
- }, [
692
- vue.h("input", {
693
- ref: fileInputRef,
694
- type: "file",
695
- accept: props.accept,
696
- multiple: props.multiple,
697
- style: { display: "none" }
698
- }),
699
- vue.renderSlot(slots, "default", {
700
- files: files.value
701
- })
702
- ]);
703
- };
704
- }
705
- });
706
-
707
- const HiIcon = vue.defineComponent({
708
- props: {
709
- ...core.iconProps,
710
- as: {
711
- type: String,
712
- default: "div"
713
- }
714
- },
715
- setup(props, context) {
716
- const { style } = core.useIcon(props, context);
717
- return () => {
718
- return vue.h(props.as, {
719
- style: style.value
720
- });
721
- };
722
- }
723
- });
724
-
725
- const HiItem = vue.defineComponent({
726
- name: "HiItem",
727
- props: {
728
- ...core.itemProps,
729
- as: {
730
- type: String,
731
- default: "div"
732
- }
733
- },
734
- emits: core.itemEmits,
735
- setup(props, context) {
736
- const { render, activate, className, isDisabled, activateEvent } = core.useSelectionItem(
737
- props,
738
- context
739
- );
740
- return () => vue.h(
741
- props.as,
742
- {
743
- class: className.value,
744
- [`on${tslx.capitalize(activateEvent.value)}`]: activate,
745
- disabled: isDisabled.value
746
- },
747
- render()
748
- );
749
- }
750
- });
751
-
752
- const HiPopover = vue.defineComponent({
753
- name: "HiPopover",
754
- props: {
755
- ...core.popoverProps,
756
- as: {
757
- type: String,
758
- default: "div"
759
- }
760
- },
761
- emits: core.popoverEmits,
762
- setup(props, context) {
763
- const { triggerRef, popupClass, events, popupRef, popupStyle } = core.usePopover(props, context);
764
- return () => {
765
- let content = vue.h(
766
- "div",
767
- {
768
- class: popupClass.value,
769
- style: popupStyle.value,
770
- ref: popupRef
771
- },
772
- vue.renderSlot(context.slots, "popup")
773
- );
774
- if (props.teleport) {
775
- content = vue.h(
776
- vue.Teleport,
777
- {
778
- to: props.teleport === true ? "body" : props.teleport
779
- },
780
- content
781
- );
782
- }
783
- return vue.h(props.as, {
784
- ref: triggerRef,
785
- ...events
786
- }, [
787
- vue.renderSlot(context.slots, "default"),
788
- content
789
- ]);
790
- };
791
- }
792
- });
793
-
794
- const HiSelection = vue.defineComponent({
795
- name: "HiSelection",
796
- props: {
797
- ...core.selectionProps,
798
- as: {
799
- type: String,
800
- default: "div"
801
- }
802
- },
803
- emits: core.selectionEmits,
804
- setup(props, context) {
805
- const { render } = core.useSelectionList(props, context);
806
- return () => vue.h(props.as, {}, render());
807
- }
808
- });
809
-
810
- const HiSwitch = vue.defineComponent({
811
- name: "HiSwitch",
812
- props: {
813
- ...core.switchProps,
814
- as: {
815
- type: String,
816
- default: "div"
817
- }
818
- },
819
- emits: core.switchEmits,
820
- setup(props, context) {
821
- const { slots } = context;
822
- const { className, toggle, modelValue, isDisabled, activateEvent } = core.useSwitch(props, context);
823
- return () => {
824
- return vue.h(
825
- props.as,
826
- {
827
- class: className.value,
828
- [`on${tslx.capitalize(activateEvent.value)}`]: toggle
829
- },
830
- vue.renderSlot(slots, "default", {
831
- active: modelValue.value,
832
- isDisabled: isDisabled.value
833
- })
834
- );
835
- };
836
- }
837
- });
838
-
839
- const selectionProps = shared.defineHookProps({
840
- modelValue: {
841
- type: shared.valuePropType,
842
- default: () => null
843
- },
844
- /**
845
- * 选中时的 class
846
- */
847
- activeClass: {
848
- type: shared.classPropType,
849
- default: "active"
850
- },
851
- /**
852
- * 每个选项的 class
853
- */
854
- itemClass: {
855
- type: shared.classPropType,
856
- default: ""
857
- },
858
- disabledClass: {
859
- type: shared.classPropType,
860
- default: "disabled"
861
- },
862
- unactiveClass: {
863
- type: shared.classPropType,
864
- default: ""
865
- },
866
- label: {
867
- type: shared.labelPropType
868
- },
869
- /**
870
- * 多选模式
871
- */
872
- multiple: {
873
- type: [Boolean, Number, Array],
874
- default: () => false
875
- },
876
- /**
877
- * 可清除
878
- */
879
- clearable: {
880
- type: Boolean
881
- },
882
- defaultValue: {
883
- type: shared.valuePropType,
884
- default: () => null
885
- },
886
- activateEvent: {
887
- type: String
888
- }
889
- });
890
- const selectionEmits = shared.defineHookEmits([
891
- "update:modelValue",
892
- "change",
893
- "load",
894
- "unload",
895
- "reject"
896
- ]);
897
- const HiSelectionContextSymbol = Symbol("[hi-selection]context");
898
- function useSelectionContext() {
899
- const sharedConfig = shared.useSharedConfig();
900
- return vue.inject(HiSelectionContextSymbol, {
901
- isActive: () => false,
902
- activate: () => {
903
- },
904
- changeActive: () => {
905
- },
906
- reject: () => {
907
- },
908
- activeClass: "active",
909
- unactiveClass: "unactive",
910
- disabledClass: "disabled",
911
- itemClass: "",
912
- activateEvent: sharedConfig.activateEvent,
913
- label: null,
914
- multiple: false,
915
- limit: [0, Number.POSITIVE_INFINITY]
916
- });
917
- }
918
- const useSelectionList = shared.defineHookComponent({
919
- props: selectionProps,
920
- emits: selectionEmits,
921
- setup(props, { emit, slots }) {
922
- const options = vue.reactive([]);
923
- function toArray(value) {
924
- if (!isDefined(value)) {
925
- return [];
926
- }
927
- if (props.multiple && Array.isArray(value)) {
928
- return value.filter((v) => v != null || v !== void 0);
929
- }
930
- return [value];
931
- }
932
- const actives = vue.reactive([
933
- ...toArray(props.modelValue ?? props.defaultValue)
934
- ]);
935
- const currentValue = vue.computed({
936
- get() {
937
- return props.multiple ? actives : actives[0];
938
- },
939
- set(val) {
940
- actives.splice(0, actives.length, ...toArray(val));
941
- }
942
- });
943
- const modelValue = vue.computed({
944
- get() {
945
- return props.modelValue ?? props.defaultValue;
946
- },
947
- set(val) {
948
- emit("update:modelValue", val);
949
- }
950
- });
951
- syncRef(currentValue, modelValue, { immediate: true, deep: true });
952
- const emitChange = () => emit("change", currentValue.value);
953
- function isActive(value) {
954
- return actives.includes(value);
955
- }
956
- const multipleActive = vue.computed(() => !!props.multiple);
957
- const multipleLimit = vue.computed(() => {
958
- if (Array.isArray(props.multiple)) {
959
- if (props.multiple[1] === void 0) {
960
- return [props.multiple[0], Number.POSITIVE_INFINITY];
961
- }
962
- return props.multiple;
963
- }
964
- return [0, Number.POSITIVE_INFINITY];
965
- });
966
- function activate(value) {
967
- const [min, max] = multipleLimit.value;
968
- if (isActive(value)) {
969
- if (multipleActive.value && actives.length > min || props.clearable) {
970
- actives.splice(actives.indexOf(value), 1);
971
- emitChange();
972
- }
973
- } else {
974
- if (props.multiple) {
975
- if (actives.length < max) {
976
- actives.push(value);
977
- emitChange();
978
- }
979
- } else {
980
- actives.splice(0, actives.length, value);
981
- emitChange();
982
- }
983
- }
984
- }
985
- function reject(value) {
986
- emit("reject", value);
987
- }
988
- const init = (option) => {
989
- function remove() {
990
- const index = options.findIndex((e) => e.id === option.id);
991
- if (index > -1) {
992
- options.splice(index, 1);
993
- emit("unload", option);
994
- }
995
- }
996
- for (let i = 0; i < options.length; i++) {
997
- if (options[i].value === option.value) {
998
- options.splice(i, 1);
999
- i--;
1000
- }
1001
- }
1002
- options.push(option);
1003
- emit("load", option);
1004
- return remove;
1005
- };
1006
- const sharedConfig = shared.useSharedConfig();
1007
- vue.provide(HiSelectionContextSymbol, shared.toReactive({
1008
- activeClass: vue.computed(() => tslx.cls(props.activeClass)),
1009
- unactiveClass: vue.computed(() => tslx.cls(props.unactiveClass)),
1010
- disabledClass: vue.computed(() => tslx.cls(props.disabledClass)),
1011
- itemClass: vue.computed(() => tslx.cls(props.itemClass)),
1012
- label: vue.computed(() => props.label),
1013
- multiple: multipleActive,
1014
- limit: multipleLimit,
1015
- clearable: vue.computed(() => props.clearable),
1016
- defaultValue: vue.computed(() => props.defaultValue),
1017
- activateEvent: vue.computed(() => props.activateEvent ?? sharedConfig.activateEvent),
1018
- active: currentValue,
1019
- activate,
1020
- changeActive: activate,
1021
- isActive,
1022
- reject,
1023
- init
1024
- }));
1025
- const renderItem = () => {
1026
- const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
1027
- return props.multiple ? children : shared.getFirstChilld(children);
1028
- };
1029
- const slotData = {
1030
- isActive,
1031
- changeActive: activate,
1032
- renderItem
1033
- };
1034
- const render = () => {
1035
- return vue.renderSlot(slots, "default", slotData);
1036
- };
1037
- return {
1038
- options,
1039
- actives,
1040
- isActive,
1041
- changeActive: activate,
1042
- renderItem,
1043
- render
1044
- };
1045
- }
1046
- });
1047
-
1048
- const itemProps = shared.defineHookProps({
1049
- value: {
1050
- type: shared.valuePropType,
1051
- default() {
1052
- return Math.random().toString(16).slice(2);
1053
- }
1054
- },
1055
- label: {
1056
- type: [Function, String]
1057
- },
1058
- keepAlive: {
1059
- type: Boolean,
1060
- default: () => true
1061
- },
1062
- activateEvent: {
1063
- type: String
1064
- },
1065
- disabled: {
1066
- type: Boolean,
1067
- default: false
1068
- }
1069
- });
1070
- const itemEmits = shared.defineHookEmits(["reject"]);
1071
- const useSelectionItem = shared.defineHookComponent({
1072
- props: itemProps,
1073
- emits: itemEmits,
1074
- setup(props, { slots, emit }) {
1075
- const context = useSelectionContext();
1076
- const activate = () => {
1077
- if (props.disabled) {
1078
- emit("reject", props.value);
1079
- context.reject(props.value);
1080
- return;
1081
- }
1082
- context.activate(props.value);
1083
- };
1084
- const label = vue.computed(() => {
1085
- let label2 = props.label ?? context.label;
1086
- if (label2 && typeof label2 === "function") {
1087
- label2 = label2(props.value);
1088
- }
1089
- return Array.isArray(label2) ? label2 : [label2];
1090
- });
1091
- function render() {
1092
- return slots.default?.({
1093
- active: context.isActive(props.value),
1094
- activate
1095
- }) ?? label.value.filter(Boolean);
1096
- }
1097
- let remove = () => {
1098
- };
1099
- const init = context.init;
1100
- if (init) {
1101
- vue.watch(
1102
- () => props.value,
1103
- (value) => {
1104
- remove();
1105
- remove = init({
1106
- id: Math.random().toString(16).slice(2),
1107
- label: typeof props.label === "string" ? props.label : void 0,
1108
- value,
1109
- render
1110
- });
1111
- },
1112
- { immediate: true }
1113
- );
1114
- tryOnScopeDispose(remove);
1115
- }
1116
- const isActive = vue.computed(() => context.isActive(props.value));
1117
- const isDisabled = vue.computed(() => props.disabled);
1118
- const className = vue.computed(() => {
1119
- const array = [context.itemClass];
1120
- if (!isDisabled.value) {
1121
- array.push(context.isActive(props.value) ? context.activeClass : context.unactiveClass);
1122
- } else {
1123
- array.push(context.disabledClass);
1124
- }
1125
- return tslx.cls(array);
1126
- });
1127
- const activateEvent = vue.computed(() => props.activateEvent ?? context.activateEvent);
1128
- return {
1129
- activate,
1130
- render,
1131
- isActive,
1132
- isDisabled,
1133
- className,
1134
- activateEvent,
1135
- label
1136
- };
1137
- }
1138
- });
1139
-
1140
- const HiTabPane = vue.defineComponent({
1141
- name: "HiTabPane",
1142
- props: {
1143
- ...itemProps
1144
- },
1145
- emits: itemEmits,
1146
- inheritAttrs: true,
1147
- setup(props, context) {
1148
- const { className, activateEvent, activate, isDisabled, label } = useSelectionItem(props, context);
1149
- return () => {
1150
- return vue.h("div", {
1151
- class: className.value,
1152
- [`on${tslx.capitalize(activateEvent.value)}`]: activate,
1153
- disabled: isDisabled.value
1154
- }, label.value);
1155
- };
1156
- }
1157
- });
1158
-
1159
- const HiTabs = vue.defineComponent({
1160
- name: "HiTabs",
1161
- props: {
1162
- ...selectionProps,
1163
- headerClass: {
1164
- type: shared.classPropType
1165
- },
1166
- as: {
1167
- type: String,
1168
- default: "div"
1169
- },
1170
- headerAs: {
1171
- type: String,
1172
- default: "div"
1173
- },
1174
- contentAs: {
1175
- type: String,
1176
- default: "div"
1177
- },
1178
- contentClass: {
1179
- type: shared.classPropType
1180
- },
1181
- keepAlive: {
1182
- type: [Boolean, Object],
1183
- default: false
1184
- }
1185
- },
1186
- inheritAttrs: true,
1187
- setup(props, context) {
1188
- const selection = useSelectionList(props, context);
1189
- return () => {
1190
- let component = selection.renderItem();
1191
- if (props.keepAlive) {
1192
- component = vue.h(vue.KeepAlive, {
1193
- ...typeof props.keepAlive === "object" ? props.keepAlive : {}
1194
- }, component);
1195
- }
1196
- if (context.slots.content) {
1197
- component = context.slots.content({
1198
- component
1199
- });
1200
- } else {
1201
- component = vue.h(props.contentAs, {
1202
- class: props.contentClass
1203
- }, component);
1204
- }
1205
- return vue.h(props.as, [
1206
- vue.h(props.headerAs, {
1207
- class: props.headerClass
1208
- }, vue.renderSlot(context.slots, "default")),
1209
- component
1210
- ]);
1211
- };
1212
- }
1213
- });
1214
-
1215
- function memo(getDeps, fn, opts) {
1216
- let deps = opts.initialDeps ?? [];
1217
- let result;
1218
- function memoizedFunction() {
1219
- var _a, _b, _c, _d;
1220
- let depTime;
1221
- if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
1222
- const newDeps = getDeps();
1223
- const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
1224
- if (!depsChanged) {
1225
- return result;
1226
- }
1227
- deps = newDeps;
1228
- let resultTime;
1229
- if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();
1230
- result = fn(...newDeps);
1231
- if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {
1232
- const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
1233
- const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
1234
- const resultFpsPercentage = resultEndTime / 16;
1235
- const pad = (str, num) => {
1236
- str = String(str);
1237
- while (str.length < num) {
1238
- str = " " + str;
1239
- }
1240
- return str;
1241
- };
1242
- console.info(
1243
- `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,
1244
- `
1245
- font-size: .6rem;
1246
- font-weight: bold;
1247
- color: hsl(${Math.max(
1248
- 0,
1249
- Math.min(120 - 120 * resultFpsPercentage, 120)
1250
- )}deg 100% 31%);`,
1251
- opts == null ? void 0 : opts.key
1252
- );
1253
- }
1254
- (_d = opts == null ? void 0 : opts.onChange) == null ? void 0 : _d.call(opts, result);
1255
- return result;
1256
- }
1257
- memoizedFunction.updateDeps = (newDeps) => {
1258
- deps = newDeps;
1259
- };
1260
- return memoizedFunction;
1261
- }
1262
- function notUndefined(value, msg) {
1263
- if (value === void 0) {
1264
- throw new Error(`Unexpected undefined${""}`);
1265
- } else {
1266
- return value;
1267
- }
1268
- }
1269
- const approxEqual = (a, b) => Math.abs(a - b) <= 1;
1270
- const debounce = (targetWindow, fn, ms) => {
1271
- let timeoutId;
1272
- return function(...args) {
1273
- targetWindow.clearTimeout(timeoutId);
1274
- timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);
1275
- };
1276
- };
1277
-
1278
- const getRect = (element) => {
1279
- const { offsetWidth, offsetHeight } = element;
1280
- return { width: offsetWidth, height: offsetHeight };
1281
- };
1282
- const defaultKeyExtractor = (index) => index;
1283
- const defaultRangeExtractor = (range) => {
1284
- const start = Math.max(range.startIndex - range.overscan, 0);
1285
- const end = Math.min(range.endIndex + range.overscan, range.count - 1);
1286
- const arr = [];
1287
- for (let i = start; i <= end; i++) {
1288
- arr.push(i);
1289
- }
1290
- return arr;
1291
- };
1292
- const observeElementRect = (instance, cb) => {
1293
- const element = instance.scrollElement;
1294
- if (!element) {
1295
- return;
1296
- }
1297
- const targetWindow = instance.targetWindow;
1298
- if (!targetWindow) {
1299
- return;
1300
- }
1301
- const handler = (rect) => {
1302
- const { width, height } = rect;
1303
- cb({ width: Math.round(width), height: Math.round(height) });
1304
- };
1305
- handler(getRect(element));
1306
- if (!targetWindow.ResizeObserver) {
1307
- return () => {
1308
- };
1309
- }
1310
- const observer = new targetWindow.ResizeObserver((entries) => {
1311
- const run = () => {
1312
- const entry = entries[0];
1313
- if (entry == null ? void 0 : entry.borderBoxSize) {
1314
- const box = entry.borderBoxSize[0];
1315
- if (box) {
1316
- handler({ width: box.inlineSize, height: box.blockSize });
1317
- return;
1318
- }
1319
- }
1320
- handler(getRect(element));
1321
- };
1322
- instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
1323
- });
1324
- observer.observe(element, { box: "border-box" });
1325
- return () => {
1326
- observer.unobserve(element);
1327
- };
1328
- };
1329
- const addEventListenerOptions = {
1330
- passive: true
1331
- };
1332
- const supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
1333
- const observeElementOffset = (instance, cb) => {
1334
- const element = instance.scrollElement;
1335
- if (!element) {
1336
- return;
1337
- }
1338
- const targetWindow = instance.targetWindow;
1339
- if (!targetWindow) {
1340
- return;
1341
- }
1342
- let offset = 0;
1343
- const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
1344
- targetWindow,
1345
- () => {
1346
- cb(offset, false);
1347
- },
1348
- instance.options.isScrollingResetDelay
1349
- );
1350
- const createHandler = (isScrolling) => () => {
1351
- const { horizontal, isRtl } = instance.options;
1352
- offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
1353
- fallback();
1354
- cb(offset, isScrolling);
1355
- };
1356
- const handler = createHandler(true);
1357
- const endHandler = createHandler(false);
1358
- endHandler();
1359
- element.addEventListener("scroll", handler, addEventListenerOptions);
1360
- const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
1361
- if (registerScrollendEvent) {
1362
- element.addEventListener("scrollend", endHandler, addEventListenerOptions);
1363
- }
1364
- return () => {
1365
- element.removeEventListener("scroll", handler);
1366
- if (registerScrollendEvent) {
1367
- element.removeEventListener("scrollend", endHandler);
1368
- }
1369
- };
1370
- };
1371
- const measureElement = (element, entry, instance) => {
1372
- if (entry == null ? void 0 : entry.borderBoxSize) {
1373
- const box = entry.borderBoxSize[0];
1374
- if (box) {
1375
- const size = Math.round(
1376
- box[instance.options.horizontal ? "inlineSize" : "blockSize"]
1377
- );
1378
- return size;
1379
- }
1380
- }
1381
- return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
1382
- };
1383
- const elementScroll = (offset, {
1384
- adjustments = 0,
1385
- behavior
1386
- }, instance) => {
1387
- var _a, _b;
1388
- const toOffset = offset + adjustments;
1389
- (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {
1390
- [instance.options.horizontal ? "left" : "top"]: toOffset,
1391
- behavior
1392
- });
1393
- };
1394
- class Virtualizer {
1395
- constructor(opts) {
1396
- this.unsubs = [];
1397
- this.scrollElement = null;
1398
- this.targetWindow = null;
1399
- this.isScrolling = false;
1400
- this.scrollToIndexTimeoutId = null;
1401
- this.measurementsCache = [];
1402
- this.itemSizeCache = /* @__PURE__ */ new Map();
1403
- this.pendingMeasuredCacheIndexes = [];
1404
- this.scrollRect = null;
1405
- this.scrollOffset = null;
1406
- this.scrollDirection = null;
1407
- this.scrollAdjustments = 0;
1408
- this.elementsCache = /* @__PURE__ */ new Map();
1409
- this.observer = /* @__PURE__ */ (() => {
1410
- let _ro = null;
1411
- const get = () => {
1412
- if (_ro) {
1413
- return _ro;
1414
- }
1415
- if (!this.targetWindow || !this.targetWindow.ResizeObserver) {
1416
- return null;
1417
- }
1418
- return _ro = new this.targetWindow.ResizeObserver((entries) => {
1419
- entries.forEach((entry) => {
1420
- const run = () => {
1421
- this._measureElement(entry.target, entry);
1422
- };
1423
- this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
1424
- });
1425
- });
1426
- };
1427
- return {
1428
- disconnect: () => {
1429
- var _a;
1430
- (_a = get()) == null ? void 0 : _a.disconnect();
1431
- _ro = null;
1432
- },
1433
- observe: (target) => {
1434
- var _a;
1435
- return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
1436
- },
1437
- unobserve: (target) => {
1438
- var _a;
1439
- return (_a = get()) == null ? void 0 : _a.unobserve(target);
1440
- }
1441
- };
1442
- })();
1443
- this.range = null;
1444
- this.setOptions = (opts2) => {
1445
- Object.entries(opts2).forEach(([key, value]) => {
1446
- if (typeof value === "undefined") delete opts2[key];
1447
- });
1448
- this.options = {
1449
- debug: false,
1450
- initialOffset: 0,
1451
- overscan: 1,
1452
- paddingStart: 0,
1453
- paddingEnd: 0,
1454
- scrollPaddingStart: 0,
1455
- scrollPaddingEnd: 0,
1456
- horizontal: false,
1457
- getItemKey: defaultKeyExtractor,
1458
- rangeExtractor: defaultRangeExtractor,
1459
- onChange: () => {
1460
- },
1461
- measureElement,
1462
- initialRect: { width: 0, height: 0 },
1463
- scrollMargin: 0,
1464
- gap: 0,
1465
- indexAttribute: "data-index",
1466
- initialMeasurementsCache: [],
1467
- lanes: 1,
1468
- isScrollingResetDelay: 150,
1469
- enabled: true,
1470
- isRtl: false,
1471
- useScrollendEvent: false,
1472
- useAnimationFrameWithResizeObserver: false,
1473
- ...opts2
1474
- };
1475
- };
1476
- this.notify = (sync) => {
1477
- var _a, _b;
1478
- (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);
1479
- };
1480
- this.maybeNotify = memo(
1481
- () => {
1482
- this.calculateRange();
1483
- return [
1484
- this.isScrolling,
1485
- this.range ? this.range.startIndex : null,
1486
- this.range ? this.range.endIndex : null
1487
- ];
1488
- },
1489
- (isScrolling) => {
1490
- this.notify(isScrolling);
1491
- },
1492
- {
1493
- key: process.env.NODE_ENV !== "production" && "maybeNotify",
1494
- debug: () => this.options.debug,
1495
- initialDeps: [
1496
- this.isScrolling,
1497
- this.range ? this.range.startIndex : null,
1498
- this.range ? this.range.endIndex : null
1499
- ]
1500
- }
1501
- );
1502
- this.cleanup = () => {
1503
- this.unsubs.filter(Boolean).forEach((d) => d());
1504
- this.unsubs = [];
1505
- this.observer.disconnect();
1506
- this.scrollElement = null;
1507
- this.targetWindow = null;
1508
- };
1509
- this._didMount = () => {
1510
- return () => {
1511
- this.cleanup();
1512
- };
1513
- };
1514
- this._willUpdate = () => {
1515
- var _a;
1516
- const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
1517
- if (this.scrollElement !== scrollElement) {
1518
- this.cleanup();
1519
- if (!scrollElement) {
1520
- this.maybeNotify();
1521
- return;
1522
- }
1523
- this.scrollElement = scrollElement;
1524
- if (this.scrollElement && "ownerDocument" in this.scrollElement) {
1525
- this.targetWindow = this.scrollElement.ownerDocument.defaultView;
1526
- } else {
1527
- this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
1528
- }
1529
- this.elementsCache.forEach((cached) => {
1530
- this.observer.observe(cached);
1531
- });
1532
- this._scrollToOffset(this.getScrollOffset(), {
1533
- adjustments: void 0,
1534
- behavior: void 0
1535
- });
1536
- this.unsubs.push(
1537
- this.options.observeElementRect(this, (rect) => {
1538
- this.scrollRect = rect;
1539
- this.maybeNotify();
1540
- })
1541
- );
1542
- this.unsubs.push(
1543
- this.options.observeElementOffset(this, (offset, isScrolling) => {
1544
- this.scrollAdjustments = 0;
1545
- this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
1546
- this.scrollOffset = offset;
1547
- this.isScrolling = isScrolling;
1548
- this.maybeNotify();
1549
- })
1550
- );
1551
- }
1552
- };
1553
- this.getSize = () => {
1554
- if (!this.options.enabled) {
1555
- this.scrollRect = null;
1556
- return 0;
1557
- }
1558
- this.scrollRect = this.scrollRect ?? this.options.initialRect;
1559
- return this.scrollRect[this.options.horizontal ? "width" : "height"];
1560
- };
1561
- this.getScrollOffset = () => {
1562
- if (!this.options.enabled) {
1563
- this.scrollOffset = null;
1564
- return 0;
1565
- }
1566
- this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === "function" ? this.options.initialOffset() : this.options.initialOffset);
1567
- return this.scrollOffset;
1568
- };
1569
- this.getFurthestMeasurement = (measurements, index) => {
1570
- const furthestMeasurementsFound = /* @__PURE__ */ new Map();
1571
- const furthestMeasurements = /* @__PURE__ */ new Map();
1572
- for (let m = index - 1; m >= 0; m--) {
1573
- const measurement = measurements[m];
1574
- if (furthestMeasurementsFound.has(measurement.lane)) {
1575
- continue;
1576
- }
1577
- const previousFurthestMeasurement = furthestMeasurements.get(
1578
- measurement.lane
1579
- );
1580
- if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {
1581
- furthestMeasurements.set(measurement.lane, measurement);
1582
- } else if (measurement.end < previousFurthestMeasurement.end) {
1583
- furthestMeasurementsFound.set(measurement.lane, true);
1584
- }
1585
- if (furthestMeasurementsFound.size === this.options.lanes) {
1586
- break;
1587
- }
1588
- }
1589
- return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {
1590
- if (a.end === b.end) {
1591
- return a.index - b.index;
1592
- }
1593
- return a.end - b.end;
1594
- })[0] : void 0;
1595
- };
1596
- this.getMeasurementOptions = memo(
1597
- () => [
1598
- this.options.count,
1599
- this.options.paddingStart,
1600
- this.options.scrollMargin,
1601
- this.options.getItemKey,
1602
- this.options.enabled
1603
- ],
1604
- (count, paddingStart, scrollMargin, getItemKey, enabled) => {
1605
- this.pendingMeasuredCacheIndexes = [];
1606
- return {
1607
- count,
1608
- paddingStart,
1609
- scrollMargin,
1610
- getItemKey,
1611
- enabled
1612
- };
1613
- },
1614
- {
1615
- key: false
1616
- }
1617
- );
1618
- this.getMeasurements = memo(
1619
- () => [this.getMeasurementOptions(), this.itemSizeCache],
1620
- ({ count, paddingStart, scrollMargin, getItemKey, enabled }, itemSizeCache) => {
1621
- if (!enabled) {
1622
- this.measurementsCache = [];
1623
- this.itemSizeCache.clear();
1624
- return [];
1625
- }
1626
- if (this.measurementsCache.length === 0) {
1627
- this.measurementsCache = this.options.initialMeasurementsCache;
1628
- this.measurementsCache.forEach((item) => {
1629
- this.itemSizeCache.set(item.key, item.size);
1630
- });
1631
- }
1632
- const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
1633
- this.pendingMeasuredCacheIndexes = [];
1634
- const measurements = this.measurementsCache.slice(0, min);
1635
- for (let i = min; i < count; i++) {
1636
- const key = getItemKey(i);
1637
- const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);
1638
- const start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;
1639
- const measuredSize = itemSizeCache.get(key);
1640
- const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
1641
- const end = start + size;
1642
- const lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;
1643
- measurements[i] = {
1644
- index: i,
1645
- start,
1646
- size,
1647
- end,
1648
- key,
1649
- lane
1650
- };
1651
- }
1652
- this.measurementsCache = measurements;
1653
- return measurements;
1654
- },
1655
- {
1656
- key: process.env.NODE_ENV !== "production" && "getMeasurements",
1657
- debug: () => this.options.debug
1658
- }
1659
- );
1660
- this.calculateRange = memo(
1661
- () => [
1662
- this.getMeasurements(),
1663
- this.getSize(),
1664
- this.getScrollOffset(),
1665
- this.options.lanes
1666
- ],
1667
- (measurements, outerSize, scrollOffset, lanes) => {
1668
- return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
1669
- measurements,
1670
- outerSize,
1671
- scrollOffset,
1672
- lanes
1673
- }) : null;
1674
- },
1675
- {
1676
- key: process.env.NODE_ENV !== "production" && "calculateRange",
1677
- debug: () => this.options.debug
1678
- }
1679
- );
1680
- this.getVirtualIndexes = memo(
1681
- () => {
1682
- let startIndex = null;
1683
- let endIndex = null;
1684
- const range = this.calculateRange();
1685
- if (range) {
1686
- startIndex = range.startIndex;
1687
- endIndex = range.endIndex;
1688
- }
1689
- this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);
1690
- return [
1691
- this.options.rangeExtractor,
1692
- this.options.overscan,
1693
- this.options.count,
1694
- startIndex,
1695
- endIndex
1696
- ];
1697
- },
1698
- (rangeExtractor, overscan, count, startIndex, endIndex) => {
1699
- return startIndex === null || endIndex === null ? [] : rangeExtractor({
1700
- startIndex,
1701
- endIndex,
1702
- overscan,
1703
- count
1704
- });
1705
- },
1706
- {
1707
- key: process.env.NODE_ENV !== "production" && "getVirtualIndexes",
1708
- debug: () => this.options.debug
1709
- }
1710
- );
1711
- this.indexFromElement = (node) => {
1712
- const attributeName = this.options.indexAttribute;
1713
- const indexStr = node.getAttribute(attributeName);
1714
- if (!indexStr) {
1715
- console.warn(
1716
- `Missing attribute name '${attributeName}={index}' on measured element.`
1717
- );
1718
- return -1;
1719
- }
1720
- return parseInt(indexStr, 10);
1721
- };
1722
- this._measureElement = (node, entry) => {
1723
- const index = this.indexFromElement(node);
1724
- const item = this.measurementsCache[index];
1725
- if (!item) {
1726
- return;
1727
- }
1728
- const key = item.key;
1729
- const prevNode = this.elementsCache.get(key);
1730
- if (prevNode !== node) {
1731
- if (prevNode) {
1732
- this.observer.unobserve(prevNode);
1733
- }
1734
- this.observer.observe(node);
1735
- this.elementsCache.set(key, node);
1736
- }
1737
- if (node.isConnected) {
1738
- this.resizeItem(index, this.options.measureElement(node, entry, this));
1739
- }
1740
- };
1741
- this.resizeItem = (index, size) => {
1742
- const item = this.measurementsCache[index];
1743
- if (!item) {
1744
- return;
1745
- }
1746
- const itemSize = this.itemSizeCache.get(item.key) ?? item.size;
1747
- const delta = size - itemSize;
1748
- if (delta !== 0) {
1749
- if (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments) {
1750
- if (process.env.NODE_ENV !== "production" && this.options.debug) {
1751
- console.info("correction", delta);
1752
- }
1753
- this._scrollToOffset(this.getScrollOffset(), {
1754
- adjustments: this.scrollAdjustments += delta,
1755
- behavior: void 0
1756
- });
1757
- }
1758
- this.pendingMeasuredCacheIndexes.push(item.index);
1759
- this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
1760
- this.notify(false);
1761
- }
1762
- };
1763
- this.measureElement = (node) => {
1764
- if (!node) {
1765
- this.elementsCache.forEach((cached, key) => {
1766
- if (!cached.isConnected) {
1767
- this.observer.unobserve(cached);
1768
- this.elementsCache.delete(key);
1769
- }
1770
- });
1771
- return;
1772
- }
1773
- this._measureElement(node, void 0);
1774
- };
1775
- this.getVirtualItems = memo(
1776
- () => [this.getVirtualIndexes(), this.getMeasurements()],
1777
- (indexes, measurements) => {
1778
- const virtualItems = [];
1779
- for (let k = 0, len = indexes.length; k < len; k++) {
1780
- const i = indexes[k];
1781
- const measurement = measurements[i];
1782
- virtualItems.push(measurement);
1783
- }
1784
- return virtualItems;
1785
- },
1786
- {
1787
- key: process.env.NODE_ENV !== "production" && "getVirtualItems",
1788
- debug: () => this.options.debug
1789
- }
1790
- );
1791
- this.getVirtualItemForOffset = (offset) => {
1792
- const measurements = this.getMeasurements();
1793
- if (measurements.length === 0) {
1794
- return void 0;
1795
- }
1796
- return notUndefined(
1797
- measurements[findNearestBinarySearch(
1798
- 0,
1799
- measurements.length - 1,
1800
- (index) => notUndefined(measurements[index]).start,
1801
- offset
1802
- )]
1803
- );
1804
- };
1805
- this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
1806
- const size = this.getSize();
1807
- const scrollOffset = this.getScrollOffset();
1808
- if (align === "auto") {
1809
- align = toOffset >= scrollOffset + size ? "end" : "start";
1810
- }
1811
- if (align === "center") {
1812
- toOffset += (itemSize - size) / 2;
1813
- } else if (align === "end") {
1814
- toOffset -= size;
1815
- }
1816
- const maxOffset = this.getTotalSize() - size;
1817
- return Math.max(Math.min(maxOffset, toOffset), 0);
1818
- };
1819
- this.getOffsetForIndex = (index, align = "auto") => {
1820
- index = Math.max(0, Math.min(index, this.options.count - 1));
1821
- const item = this.measurementsCache[index];
1822
- if (!item) {
1823
- return void 0;
1824
- }
1825
- const size = this.getSize();
1826
- const scrollOffset = this.getScrollOffset();
1827
- if (align === "auto") {
1828
- if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {
1829
- align = "end";
1830
- } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {
1831
- align = "start";
1832
- } else {
1833
- return [scrollOffset, align];
1834
- }
1835
- }
1836
- const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
1837
- return [
1838
- this.getOffsetForAlignment(toOffset, align, item.size),
1839
- align
1840
- ];
1841
- };
1842
- this.isDynamicMode = () => this.elementsCache.size > 0;
1843
- this.cancelScrollToIndex = () => {
1844
- if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {
1845
- this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId);
1846
- this.scrollToIndexTimeoutId = null;
1847
- }
1848
- };
1849
- this.scrollToOffset = (toOffset, { align = "start", behavior } = {}) => {
1850
- this.cancelScrollToIndex();
1851
- if (behavior === "smooth" && this.isDynamicMode()) {
1852
- console.warn(
1853
- "The `smooth` scroll behavior is not fully supported with dynamic size."
1854
- );
1855
- }
1856
- this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {
1857
- adjustments: void 0,
1858
- behavior
1859
- });
1860
- };
1861
- this.scrollToIndex = (index, { align: initialAlign = "auto", behavior } = {}) => {
1862
- index = Math.max(0, Math.min(index, this.options.count - 1));
1863
- this.cancelScrollToIndex();
1864
- if (behavior === "smooth" && this.isDynamicMode()) {
1865
- console.warn(
1866
- "The `smooth` scroll behavior is not fully supported with dynamic size."
1867
- );
1868
- }
1869
- const offsetAndAlign = this.getOffsetForIndex(index, initialAlign);
1870
- if (!offsetAndAlign) return;
1871
- const [offset, align] = offsetAndAlign;
1872
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
1873
- if (behavior !== "smooth" && this.isDynamicMode() && this.targetWindow) {
1874
- this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {
1875
- this.scrollToIndexTimeoutId = null;
1876
- const elementInDOM = this.elementsCache.has(
1877
- this.options.getItemKey(index)
1878
- );
1879
- if (elementInDOM) {
1880
- const [latestOffset] = notUndefined(
1881
- this.getOffsetForIndex(index, align)
1882
- );
1883
- const currentScrollOffset = this.getScrollOffset();
1884
- if (!approxEqual(latestOffset, currentScrollOffset)) {
1885
- this.scrollToIndex(index, { align, behavior });
1886
- }
1887
- } else {
1888
- this.scrollToIndex(index, { align, behavior });
1889
- }
1890
- });
1891
- }
1892
- };
1893
- this.scrollBy = (delta, { behavior } = {}) => {
1894
- this.cancelScrollToIndex();
1895
- if (behavior === "smooth" && this.isDynamicMode()) {
1896
- console.warn(
1897
- "The `smooth` scroll behavior is not fully supported with dynamic size."
1898
- );
1899
- }
1900
- this._scrollToOffset(this.getScrollOffset() + delta, {
1901
- adjustments: void 0,
1902
- behavior
1903
- });
1904
- };
1905
- this.getTotalSize = () => {
1906
- var _a;
1907
- const measurements = this.getMeasurements();
1908
- let end;
1909
- if (measurements.length === 0) {
1910
- end = this.options.paddingStart;
1911
- } else if (this.options.lanes === 1) {
1912
- end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
1913
- } else {
1914
- const endByLane = Array(this.options.lanes).fill(null);
1915
- let endIndex = measurements.length - 1;
1916
- while (endIndex >= 0 && endByLane.some((val) => val === null)) {
1917
- const item = measurements[endIndex];
1918
- if (endByLane[item.lane] === null) {
1919
- endByLane[item.lane] = item.end;
1920
- }
1921
- endIndex--;
1922
- }
1923
- end = Math.max(...endByLane.filter((val) => val !== null));
1924
- }
1925
- return Math.max(
1926
- end - this.options.scrollMargin + this.options.paddingEnd,
1927
- 0
1928
- );
1929
- };
1930
- this._scrollToOffset = (offset, {
1931
- adjustments,
1932
- behavior
1933
- }) => {
1934
- this.options.scrollToFn(offset, { behavior, adjustments }, this);
1935
- };
1936
- this.measure = () => {
1937
- this.itemSizeCache = /* @__PURE__ */ new Map();
1938
- this.notify(false);
1939
- };
1940
- this.setOptions(opts);
1941
- }
1942
- }
1943
- const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
1944
- while (low <= high) {
1945
- const middle = (low + high) / 2 | 0;
1946
- const currentValue = getCurrentValue(middle);
1947
- if (currentValue < value) {
1948
- low = middle + 1;
1949
- } else if (currentValue > value) {
1950
- high = middle - 1;
1951
- } else {
1952
- return middle;
1953
- }
1954
- }
1955
- if (low > 0) {
1956
- return low - 1;
1957
- } else {
1958
- return 0;
1959
- }
1960
- };
1961
- function calculateRange({
1962
- measurements,
1963
- outerSize,
1964
- scrollOffset,
1965
- lanes
1966
- }) {
1967
- const lastIndex = measurements.length - 1;
1968
- const getOffset = (index) => measurements[index].start;
1969
- if (measurements.length <= lanes) {
1970
- return {
1971
- startIndex: 0,
1972
- endIndex: lastIndex
1973
- };
1974
- }
1975
- let startIndex = findNearestBinarySearch(
1976
- 0,
1977
- lastIndex,
1978
- getOffset,
1979
- scrollOffset
1980
- );
1981
- let endIndex = startIndex;
1982
- if (lanes === 1) {
1983
- while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
1984
- endIndex++;
1985
- }
1986
- } else if (lanes > 1) {
1987
- const endPerLane = Array(lanes).fill(0);
1988
- while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
1989
- const item = measurements[endIndex];
1990
- endPerLane[item.lane] = item.end;
1991
- endIndex++;
1992
- }
1993
- const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
1994
- while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
1995
- const item = measurements[startIndex];
1996
- startPerLane[item.lane] = item.start;
1997
- startIndex--;
1998
- }
1999
- startIndex = Math.max(0, startIndex - startIndex % lanes);
2000
- endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
2001
- }
2002
- return { startIndex, endIndex };
2003
- }
2004
-
2005
- const virtualListProps = shared.defineHookProps({
2006
- options: {
2007
- type: Object,
2008
- default: () => ({})
2009
- },
2010
- count: {
2011
- type: Number,
2012
- default: () => 0
2013
- },
2014
- estimateSize: {
2015
- type: [Function, Number],
2016
- default: () => 50
2017
- },
2018
- horizontal: {
2019
- type: Boolean,
2020
- default: () => false
2021
- }
2022
- });
2023
- const virtualListEmits = shared.defineHookEmits({
2024
- scrollEnd: () => true,
2025
- scrollStart: () => true,
2026
- scroll: (_) => true
2027
- });
2028
- const useVirtualList = shared.defineHookComponent({
2029
- props: virtualListProps,
2030
- emits: virtualListEmits,
2031
- setup(props, context) {
2032
- const { emit } = context;
2033
- const scrollElementRef = shared.elementRef();
2034
- const propsEstimateSize = props.estimateSize;
2035
- const estimateSize = typeof propsEstimateSize === "function" ? propsEstimateSize : () => propsEstimateSize;
2036
- const options = vue.computed(() => {
2037
- const opts = { ...props.options || {} };
2038
- return {
2039
- ...opts,
2040
- count: props.count,
2041
- estimateSize,
2042
- horizontal: props.horizontal,
2043
- getScrollElement: () => scrollElementRef.value,
2044
- observeElementRect,
2045
- observeElementOffset,
2046
- scrollToFn: elementScroll
2047
- };
2048
- });
2049
- const virtualizer = new Virtualizer(options.value);
2050
- const state = vue.shallowRef(virtualizer);
2051
- const virtualItems = vue.computed(() => state.value.getVirtualItems());
2052
- const virtualIndexes = vue.computed(() => state.value.getVirtualIndexes());
2053
- const totalSize = vue.computed(() => state.value.getTotalSize());
2054
- vue.watch(
2055
- virtualIndexes,
2056
- (indexes) => {
2057
- if (indexes.length === 0) {
2058
- return;
2059
- }
2060
- if (indexes[indexes.length - 1] === props.count - 1) {
2061
- emit("scrollEnd");
2062
- } else if (indexes[0] === 0) {
2063
- emit("scrollStart");
2064
- }
2065
- emit("scroll", indexes);
2066
- },
2067
- { immediate: true }
2068
- );
2069
- vue.watch(
2070
- options,
2071
- (opts) => {
2072
- virtualizer.setOptions({
2073
- ...opts,
2074
- onChange: (instance, sync) => {
2075
- opts.onChange?.(instance, sync);
2076
- vue.triggerRef(state);
2077
- }
2078
- });
2079
- virtualizer._willUpdate();
2080
- vue.triggerRef(state);
2081
- },
2082
- { immediate: true }
2083
- );
2084
- vue.watch(
2085
- scrollElementRef,
2086
- (el) => {
2087
- if (el) {
2088
- virtualizer._willUpdate();
2089
- vue.triggerRef(state);
2090
- }
2091
- },
2092
- { immediate: true }
2093
- );
2094
- tryOnScopeDispose(virtualizer._didMount());
2095
- const measureElement = (el) => {
2096
- virtualizer.measureElement(el);
2097
- };
2098
- const scrollToIndex = (index, options2 = {
2099
- behavior: "smooth"
2100
- }) => {
2101
- virtualizer.scrollToIndex(index, options2);
2102
- };
2103
- const scrollToStart = (options2 = {
2104
- behavior: "smooth"
2105
- }) => {
2106
- scrollToIndex(0, options2);
2107
- };
2108
- const scrollToEnd = (options2 = {
2109
- behavior: "smooth"
2110
- }) => {
2111
- scrollToIndex(props.count - 1, options2);
2112
- };
2113
- return {
2114
- virtualizer,
2115
- virtualItems,
2116
- virtualIndexes,
2117
- totalSize,
2118
- scrollElementRef,
2119
- measureElement,
2120
- scrollToIndex,
2121
- scrollToStart,
2122
- scrollToEnd
2123
- };
2124
- }
2125
- });
2126
-
2127
- const HiVirtualList = vue.defineComponent({
2128
- name: "HiVirtualList",
2129
- inheritAttrs: true,
2130
- props: {
2131
- ...virtualListProps,
2132
- as: {
2133
- type: String,
2134
- default: () => "div"
2135
- },
2136
- wrapperAs: {
2137
- type: String,
2138
- default: () => "div"
2139
- },
2140
- wrapperStyle: {
2141
- type: Object,
2142
- default: () => ({})
2143
- },
2144
- wrapperClass: {
2145
- type: shared.classPropType,
2146
- default: () => ""
2147
- }
2148
- },
2149
- emits: virtualListEmits,
2150
- setup(props, context) {
2151
- const { slots, expose } = context;
2152
- const {
2153
- totalSize,
2154
- scrollElementRef,
2155
- virtualItems,
2156
- scrollToIndex,
2157
- scrollToStart,
2158
- scrollToEnd
2159
- } = useVirtualList(props, context);
2160
- expose({
2161
- scrollToIndex,
2162
- scrollToStart,
2163
- scrollToEnd
2164
- });
2165
- const wrapperStyle = vue.computed(() => {
2166
- return {
2167
- position: "relative",
2168
- [props.horizontal ? "width" : "height"]: `${totalSize.value}px`,
2169
- ...props.wrapperStyle
2170
- };
2171
- });
2172
- return () => vue.h(
2173
- props.as,
2174
- {
2175
- ref: scrollElementRef,
2176
- style: {
2177
- [props.horizontal ? "overflowX" : "overflowY"]: "auto"
2178
- }
2179
- },
2180
- [
2181
- vue.h(
2182
- props.wrapperAs,
2183
- {
2184
- style: wrapperStyle.value,
2185
- class: props.wrapperClass
2186
- },
2187
- tslx.each(virtualItems.value, (item) => {
2188
- const slotData = {
2189
- ...item,
2190
- style: {
2191
- position: "absolute",
2192
- [props.horizontal ? "left" : "top"]: `${item.start}px`,
2193
- [props.horizontal ? "width" : "height"]: `${item.size}px`
2194
- }
2195
- };
2196
- return vue.renderSlot(slots, "item", slotData);
2197
- })
2198
- )
2199
- ]
2200
- );
2201
- }
2202
- });
2203
-
2204
- const components = {
2205
- __proto__: null,
2206
- HiAffix: HiAffix,
2207
- HiAffixTarget: HiAffixTarget,
2208
- HiConfigProvider: HiConfigProvider,
2209
- HiFileUpload: HiFileUpload,
2210
- HiIcon: HiIcon,
2211
- HiItem: HiItem,
2212
- HiPopover: HiPopover,
2213
- HiSelection: HiSelection,
2214
- HiSwitch: HiSwitch,
2215
- HiTabPane: HiTabPane,
2216
- HiTabs: HiTabs,
2217
- HiVirtualList: HiVirtualList
2218
- };
2219
-
2220
- function install(app) {
2221
- for (const key in components) {
2222
- app.component(key, components[key]);
2223
- }
2224
- }
2225
-
2226
- exports.HiAffix = HiAffix;
2227
- exports.HiAffixTarget = HiAffixTarget;
2228
- exports.HiConfigProvider = HiConfigProvider;
2229
- exports.HiFileUpload = HiFileUpload;
2230
- exports.HiIcon = HiIcon;
2231
- exports.HiItem = HiItem;
2232
- exports.HiPopover = HiPopover;
2233
- exports.HiSelection = HiSelection;
2234
- exports.HiSwitch = HiSwitch;
2235
- exports.HiTabPane = HiTabPane;
2236
- exports.HiTabs = HiTabs;
2237
- exports.HiVirtualList = HiVirtualList;
2238
- exports.install = install;