@hoci/core 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,1688 +0,0 @@
1
- 'use strict';
2
-
3
- const shared = require('@hoci/shared');
4
- const vue = require('vue');
5
- const tslx = require('tslx');
6
- const virtualCore = require('@tanstack/virtual-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 isDef = (val) => typeof val !== "undefined";
23
- const notNullish = (val) => val != null;
24
- const toString = Object.prototype.toString;
25
- const isObject = (val) => toString.call(val) === "[object Object]";
26
- const noop = () => {
27
- };
28
- const isIOS = /* @__PURE__ */ getIsIOS();
29
- function getIsIOS() {
30
- var _a, _b;
31
- return isClient && ((_a = window == null ? void 0 : window.navigator) == null ? void 0 : _a.userAgent) && (/iP(?:ad|hone|od)/.test(window.navigator.userAgent) || ((_b = window == null ? void 0 : window.navigator) == null ? void 0 : _b.maxTouchPoints) > 2 && /iPad|Macintosh/.test(window == null ? void 0 : window.navigator.userAgent));
32
- }
33
-
34
- function createFilterWrapper(filter, fn) {
35
- function wrapper(...args) {
36
- return new Promise((resolve, reject) => {
37
- Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
38
- });
39
- }
40
- return wrapper;
41
- }
42
- const bypassFilter = (invoke) => {
43
- return invoke();
44
- };
45
- function pausableFilter(extendFilter = bypassFilter, options = {}) {
46
- const {
47
- initialState = "active"
48
- } = options;
49
- const isActive = toRef(initialState === "active");
50
- function pause() {
51
- isActive.value = false;
52
- }
53
- function resume() {
54
- isActive.value = true;
55
- }
56
- const eventFilter = (...args) => {
57
- if (isActive.value)
58
- extendFilter(...args);
59
- };
60
- return { isActive: vue.readonly(isActive), pause, resume, eventFilter };
61
- }
62
- function getLifeCycleTarget(target) {
63
- return vue.getCurrentInstance();
64
- }
65
- function toArray(value) {
66
- return Array.isArray(value) ? value : [value];
67
- }
68
-
69
- function toRef(...args) {
70
- if (args.length !== 1)
71
- return vue.toRef(...args);
72
- const r = args[0];
73
- return typeof r === "function" ? vue.readonly(vue.customRef(() => ({ get: r, set: noop }))) : vue.ref(r);
74
- }
75
-
76
- function watchWithFilter(source, cb, options = {}) {
77
- const {
78
- eventFilter = bypassFilter,
79
- ...watchOptions
80
- } = options;
81
- return vue.watch(
82
- source,
83
- createFilterWrapper(
84
- eventFilter,
85
- cb
86
- ),
87
- watchOptions
88
- );
89
- }
90
-
91
- function watchPausable(source, cb, options = {}) {
92
- const {
93
- eventFilter: filter,
94
- initialState = "active",
95
- ...watchOptions
96
- } = options;
97
- const { eventFilter, pause, resume, isActive } = pausableFilter(filter, { initialState });
98
- const stop = watchWithFilter(
99
- source,
100
- cb,
101
- {
102
- ...watchOptions,
103
- eventFilter
104
- }
105
- );
106
- return { stop, pause, resume, isActive };
107
- }
108
-
109
- function syncRef(left, right, ...[options]) {
110
- const {
111
- flush = "sync",
112
- deep = false,
113
- immediate = true,
114
- direction = "both",
115
- transform = {}
116
- } = options || {};
117
- const watchers = [];
118
- const transformLTR = "ltr" in transform && transform.ltr || ((v) => v);
119
- const transformRTL = "rtl" in transform && transform.rtl || ((v) => v);
120
- if (direction === "both" || direction === "ltr") {
121
- watchers.push(watchPausable(
122
- left,
123
- (newValue) => {
124
- watchers.forEach((w) => w.pause());
125
- right.value = transformLTR(newValue);
126
- watchers.forEach((w) => w.resume());
127
- },
128
- { flush, deep, immediate }
129
- ));
130
- }
131
- if (direction === "both" || direction === "rtl") {
132
- watchers.push(watchPausable(
133
- right,
134
- (newValue) => {
135
- watchers.forEach((w) => w.pause());
136
- left.value = transformRTL(newValue);
137
- watchers.forEach((w) => w.resume());
138
- },
139
- { flush, deep, immediate }
140
- ));
141
- }
142
- const stop = () => {
143
- watchers.forEach((w) => w.stop());
144
- };
145
- return stop;
146
- }
147
-
148
- function tryOnMounted(fn, sync = true, target) {
149
- const instance = getLifeCycleTarget();
150
- if (instance)
151
- vue.onMounted(fn, target);
152
- else if (sync)
153
- fn();
154
- else
155
- vue.nextTick(fn);
156
- }
157
-
158
- function watchImmediate(source, cb, options) {
159
- return vue.watch(
160
- source,
161
- cb,
162
- {
163
- ...options,
164
- immediate: true
165
- }
166
- );
167
- }
168
-
169
- function watchOnce(source, cb, options) {
170
- const stop = vue.watch(source, (...args) => {
171
- vue.nextTick(() => stop());
172
- return cb(...args);
173
- }, options);
174
- return stop;
175
- }
176
-
177
- const defaultWindow = isClient ? window : void 0;
178
-
179
- function unrefElement(elRef) {
180
- var _a;
181
- const plain = vue.toValue(elRef);
182
- return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
183
- }
184
-
185
- function useEventListener(...args) {
186
- const cleanups = [];
187
- const cleanup = () => {
188
- cleanups.forEach((fn) => fn());
189
- cleanups.length = 0;
190
- };
191
- const register = (el, event, listener, options) => {
192
- el.addEventListener(event, listener, options);
193
- return () => el.removeEventListener(event, listener, options);
194
- };
195
- const firstParamTargets = vue.computed(() => {
196
- const test = toArray(vue.toValue(args[0])).filter((e) => e != null);
197
- return test.every((e) => typeof e !== "string") ? test : void 0;
198
- });
199
- const stopWatch = watchImmediate(
200
- () => {
201
- var _a, _b;
202
- return [
203
- (_b = (_a = firstParamTargets.value) == null ? void 0 : _a.map((e) => unrefElement(e))) != null ? _b : [defaultWindow].filter((e) => e != null),
204
- toArray(vue.toValue(firstParamTargets.value ? args[1] : args[0])),
205
- toArray(vue.unref(firstParamTargets.value ? args[2] : args[1])),
206
- // @ts-expect-error - TypeScript gets the correct types, but somehow still complains
207
- vue.toValue(firstParamTargets.value ? args[3] : args[2])
208
- ];
209
- },
210
- ([raw_targets, raw_events, raw_listeners, raw_options]) => {
211
- cleanup();
212
- 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))
213
- return;
214
- const optionsClone = isObject(raw_options) ? { ...raw_options } : raw_options;
215
- cleanups.push(
216
- ...raw_targets.flatMap(
217
- (el) => raw_events.flatMap(
218
- (event) => raw_listeners.map((listener) => register(el, event, listener, optionsClone))
219
- )
220
- )
221
- );
222
- },
223
- { flush: "post" }
224
- );
225
- const stop = () => {
226
- stopWatch();
227
- cleanup();
228
- };
229
- tryOnScopeDispose(cleanup);
230
- return stop;
231
- }
232
-
233
- let _iOSWorkaround = false;
234
- function onClickOutside(target, handler, options = {}) {
235
- const { window = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options;
236
- if (!window) {
237
- return controls ? { stop: noop, cancel: noop, trigger: noop } : noop;
238
- }
239
- if (isIOS && !_iOSWorkaround) {
240
- _iOSWorkaround = true;
241
- const listenerOptions = { passive: true };
242
- Array.from(window.document.body.children).forEach((el) => useEventListener(el, "click", noop, listenerOptions));
243
- useEventListener(window.document.documentElement, "click", noop, listenerOptions);
244
- }
245
- let shouldListen = true;
246
- const shouldIgnore = (event) => {
247
- return vue.toValue(ignore).some((target2) => {
248
- if (typeof target2 === "string") {
249
- return Array.from(window.document.querySelectorAll(target2)).some((el) => el === event.target || event.composedPath().includes(el));
250
- } else {
251
- const el = unrefElement(target2);
252
- return el && (event.target === el || event.composedPath().includes(el));
253
- }
254
- });
255
- };
256
- function hasMultipleRoots(target2) {
257
- const vm = vue.toValue(target2);
258
- return vm && vm.$.subTree.shapeFlag === 16;
259
- }
260
- function checkMultipleRoots(target2, event) {
261
- const vm = vue.toValue(target2);
262
- const children = vm.$.subTree && vm.$.subTree.children;
263
- if (children == null || !Array.isArray(children))
264
- return false;
265
- return children.some((child) => child.el === event.target || event.composedPath().includes(child.el));
266
- }
267
- const listener = (event) => {
268
- const el = unrefElement(target);
269
- if (event.target == null)
270
- return;
271
- if (!(el instanceof Element) && hasMultipleRoots(target) && checkMultipleRoots(target, event))
272
- return;
273
- if (!el || el === event.target || event.composedPath().includes(el))
274
- return;
275
- if ("detail" in event && event.detail === 0)
276
- shouldListen = !shouldIgnore(event);
277
- if (!shouldListen) {
278
- shouldListen = true;
279
- return;
280
- }
281
- handler(event);
282
- };
283
- let isProcessingClick = false;
284
- const cleanup = [
285
- useEventListener(window, "click", (event) => {
286
- if (!isProcessingClick) {
287
- isProcessingClick = true;
288
- setTimeout(() => {
289
- isProcessingClick = false;
290
- }, 0);
291
- listener(event);
292
- }
293
- }, { passive: true, capture }),
294
- useEventListener(window, "pointerdown", (e) => {
295
- const el = unrefElement(target);
296
- shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el));
297
- }, { passive: true }),
298
- detectIframe && useEventListener(window, "blur", (event) => {
299
- setTimeout(() => {
300
- var _a;
301
- const el = unrefElement(target);
302
- if (((_a = window.document.activeElement) == null ? void 0 : _a.tagName) === "IFRAME" && !(el == null ? void 0 : el.contains(window.document.activeElement))) {
303
- handler(event);
304
- }
305
- }, 0);
306
- }, { passive: true })
307
- ].filter(Boolean);
308
- const stop = () => cleanup.forEach((fn) => fn());
309
- if (controls) {
310
- return {
311
- stop,
312
- cancel: () => {
313
- shouldListen = false;
314
- },
315
- trigger: (event) => {
316
- shouldListen = true;
317
- listener(event);
318
- shouldListen = false;
319
- }
320
- };
321
- }
322
- return stop;
323
- }
324
-
325
- function useMounted() {
326
- const isMounted = vue.shallowRef(false);
327
- const instance = vue.getCurrentInstance();
328
- if (instance) {
329
- vue.onMounted(() => {
330
- isMounted.value = true;
331
- }, instance);
332
- }
333
- return isMounted;
334
- }
335
-
336
- function useSupported(callback) {
337
- const isMounted = useMounted();
338
- return vue.computed(() => {
339
- isMounted.value;
340
- return Boolean(callback());
341
- });
342
- }
343
-
344
- function useMutationObserver(target, callback, options = {}) {
345
- const { window = defaultWindow, ...mutationOptions } = options;
346
- let observer;
347
- const isSupported = useSupported(() => window && "MutationObserver" in window);
348
- const cleanup = () => {
349
- if (observer) {
350
- observer.disconnect();
351
- observer = void 0;
352
- }
353
- };
354
- const targets = vue.computed(() => {
355
- const value = vue.toValue(target);
356
- const items = toArray(value).map(unrefElement).filter(notNullish);
357
- return new Set(items);
358
- });
359
- const stopWatch = vue.watch(
360
- () => targets.value,
361
- (targets2) => {
362
- cleanup();
363
- if (isSupported.value && targets2.size) {
364
- observer = new MutationObserver(callback);
365
- targets2.forEach((el) => observer.observe(el, mutationOptions));
366
- }
367
- },
368
- { immediate: true, flush: "post" }
369
- );
370
- const takeRecords = () => {
371
- return observer == null ? void 0 : observer.takeRecords();
372
- };
373
- const stop = () => {
374
- stopWatch();
375
- cleanup();
376
- };
377
- tryOnScopeDispose(stop);
378
- return {
379
- isSupported,
380
- stop,
381
- takeRecords
382
- };
383
- }
384
-
385
- function cloneFnJSON(source) {
386
- return JSON.parse(JSON.stringify(source));
387
- }
388
-
389
- function useResizeObserver(target, callback, options = {}) {
390
- const { window = defaultWindow, ...observerOptions } = options;
391
- let observer;
392
- const isSupported = useSupported(() => window && "ResizeObserver" in window);
393
- const cleanup = () => {
394
- if (observer) {
395
- observer.disconnect();
396
- observer = void 0;
397
- }
398
- };
399
- const targets = vue.computed(() => {
400
- const _targets = vue.toValue(target);
401
- return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)];
402
- });
403
- const stopWatch = vue.watch(
404
- targets,
405
- (els) => {
406
- cleanup();
407
- if (isSupported.value && window) {
408
- observer = new ResizeObserver(callback);
409
- for (const _el of els) {
410
- if (_el)
411
- observer.observe(_el, observerOptions);
412
- }
413
- }
414
- },
415
- { immediate: true, flush: "post" }
416
- );
417
- const stop = () => {
418
- cleanup();
419
- stopWatch();
420
- };
421
- tryOnScopeDispose(stop);
422
- return {
423
- isSupported,
424
- stop
425
- };
426
- }
427
-
428
- function useElementBounding(target, options = {}) {
429
- const {
430
- reset = true,
431
- windowResize = true,
432
- windowScroll = true,
433
- immediate = true,
434
- updateTiming = "sync"
435
- } = options;
436
- const height = vue.shallowRef(0);
437
- const bottom = vue.shallowRef(0);
438
- const left = vue.shallowRef(0);
439
- const right = vue.shallowRef(0);
440
- const top = vue.shallowRef(0);
441
- const width = vue.shallowRef(0);
442
- const x = vue.shallowRef(0);
443
- const y = vue.shallowRef(0);
444
- function recalculate() {
445
- const el = unrefElement(target);
446
- if (!el) {
447
- if (reset) {
448
- height.value = 0;
449
- bottom.value = 0;
450
- left.value = 0;
451
- right.value = 0;
452
- top.value = 0;
453
- width.value = 0;
454
- x.value = 0;
455
- y.value = 0;
456
- }
457
- return;
458
- }
459
- const rect = el.getBoundingClientRect();
460
- height.value = rect.height;
461
- bottom.value = rect.bottom;
462
- left.value = rect.left;
463
- right.value = rect.right;
464
- top.value = rect.top;
465
- width.value = rect.width;
466
- x.value = rect.x;
467
- y.value = rect.y;
468
- }
469
- function update() {
470
- if (updateTiming === "sync")
471
- recalculate();
472
- else if (updateTiming === "next-frame")
473
- requestAnimationFrame(() => recalculate());
474
- }
475
- useResizeObserver(target, update);
476
- vue.watch(() => unrefElement(target), (ele) => !ele && update());
477
- useMutationObserver(target, update, {
478
- attributeFilter: ["style", "class"]
479
- });
480
- if (windowScroll)
481
- useEventListener("scroll", update, { capture: true, passive: true });
482
- if (windowResize)
483
- useEventListener("resize", update, { passive: true });
484
- tryOnMounted(() => {
485
- if (immediate)
486
- update();
487
- });
488
- return {
489
- height,
490
- bottom,
491
- left,
492
- right,
493
- top,
494
- width,
495
- x,
496
- y,
497
- update
498
- };
499
- }
500
-
501
- function useIntersectionObserver(target, callback, options = {}) {
502
- const {
503
- root,
504
- rootMargin = "0px",
505
- threshold = 0,
506
- window = defaultWindow,
507
- immediate = true
508
- } = options;
509
- const isSupported = useSupported(() => window && "IntersectionObserver" in window);
510
- const targets = vue.computed(() => {
511
- const _target = vue.toValue(target);
512
- return toArray(_target).map(unrefElement).filter(notNullish);
513
- });
514
- let cleanup = noop;
515
- const isActive = vue.shallowRef(immediate);
516
- const stopWatch = isSupported.value ? vue.watch(
517
- () => [targets.value, unrefElement(root), isActive.value],
518
- ([targets2, root2]) => {
519
- cleanup();
520
- if (!isActive.value)
521
- return;
522
- if (!targets2.length)
523
- return;
524
- const observer = new IntersectionObserver(
525
- callback,
526
- {
527
- root: unrefElement(root2),
528
- rootMargin,
529
- threshold
530
- }
531
- );
532
- targets2.forEach((el) => el && observer.observe(el));
533
- cleanup = () => {
534
- observer.disconnect();
535
- cleanup = noop;
536
- };
537
- },
538
- { immediate, flush: "post" }
539
- ) : noop;
540
- const stop = () => {
541
- cleanup();
542
- stopWatch();
543
- isActive.value = false;
544
- };
545
- tryOnScopeDispose(stop);
546
- return {
547
- isSupported,
548
- isActive,
549
- pause() {
550
- cleanup();
551
- isActive.value = false;
552
- },
553
- resume() {
554
- isActive.value = true;
555
- },
556
- stop
557
- };
558
- }
559
-
560
- function useElementVisibility(element, options = {}) {
561
- const {
562
- window = defaultWindow,
563
- scrollTarget,
564
- threshold = 0,
565
- rootMargin,
566
- once = false
567
- } = options;
568
- const elementIsVisible = vue.shallowRef(false);
569
- const { stop } = useIntersectionObserver(
570
- element,
571
- (intersectionObserverEntries) => {
572
- let isIntersecting = elementIsVisible.value;
573
- let latestTime = 0;
574
- for (const entry of intersectionObserverEntries) {
575
- if (entry.time >= latestTime) {
576
- latestTime = entry.time;
577
- isIntersecting = entry.isIntersecting;
578
- }
579
- }
580
- elementIsVisible.value = isIntersecting;
581
- if (once) {
582
- watchOnce(elementIsVisible, () => {
583
- stop();
584
- });
585
- }
586
- },
587
- {
588
- root: scrollTarget,
589
- window,
590
- threshold,
591
- rootMargin: vue.toValue(rootMargin)
592
- }
593
- );
594
- return elementIsVisible;
595
- }
596
-
597
- function useVModel(props, key, emit, options = {}) {
598
- var _a, _b, _c;
599
- const {
600
- clone = false,
601
- passive = false,
602
- eventName,
603
- deep = false,
604
- defaultValue,
605
- shouldEmit
606
- } = options;
607
- const vm = vue.getCurrentInstance();
608
- const _emit = emit || (vm == null ? void 0 : vm.emit) || ((_a = vm == null ? void 0 : vm.$emit) == null ? void 0 : _a.bind(vm)) || ((_c = (_b = vm == null ? void 0 : vm.proxy) == null ? void 0 : _b.$emit) == null ? void 0 : _c.bind(vm == null ? void 0 : vm.proxy));
609
- let event = eventName;
610
- if (!key) {
611
- key = "modelValue";
612
- }
613
- event = event || `update:${key.toString()}`;
614
- const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val);
615
- const getValue = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
616
- const triggerEmit = (value) => {
617
- if (shouldEmit) {
618
- if (shouldEmit(value))
619
- _emit(event, value);
620
- } else {
621
- _emit(event, value);
622
- }
623
- };
624
- if (passive) {
625
- const initialValue = getValue();
626
- const proxy = vue.ref(initialValue);
627
- let isUpdating = false;
628
- vue.watch(
629
- () => props[key],
630
- (v) => {
631
- if (!isUpdating) {
632
- isUpdating = true;
633
- proxy.value = cloneFn(v);
634
- vue.nextTick(() => isUpdating = false);
635
- }
636
- }
637
- );
638
- vue.watch(
639
- proxy,
640
- (v) => {
641
- if (!isUpdating && (v !== props[key] || deep))
642
- triggerEmit(v);
643
- },
644
- { deep }
645
- );
646
- return proxy;
647
- } else {
648
- return vue.computed({
649
- get() {
650
- return getValue();
651
- },
652
- set(value) {
653
- triggerEmit(value);
654
- }
655
- });
656
- }
657
- }
658
-
659
- const affixProps = shared.defineHookProps(
660
- {
661
- fixedClass: {
662
- type: String,
663
- default: ""
664
- },
665
- /**
666
- * @zh 距离窗口顶部达到指定偏移量后触发
667
- * @en Triggered when the specified offset is reached from the top of the window
668
- */
669
- offset: {
670
- type: Number,
671
- default: 0
672
- },
673
- /**
674
- * @zh 固定的相对方向
675
- */
676
- position: {
677
- type: String,
678
- default: "top"
679
- },
680
- /**
681
- * @zh 滚动容器,默认是 `window`
682
- * @en Scroll container, default is `window`
683
- */
684
- target: {
685
- type: [String, Object, Function]
686
- },
687
- /**
688
- * @zh z-index 值
689
- * @en Z index value
690
- */
691
- zIndex: {
692
- type: Number,
693
- default: 998
694
- }
695
- }
696
- );
697
- const affixEmits = shared.defineHookEmits(["scroll", "change"]);
698
- const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
699
- function getTargetRect(target) {
700
- return shared.isWindow(target) ? {
701
- top: 0,
702
- bottom: window.innerHeight
703
- } : target.getBoundingClientRect();
704
- }
705
- const useAffix = shared.defineHookComponent({
706
- props: affixProps,
707
- setup(props, { emit }) {
708
- const wrapperRef = shared.elementRef();
709
- const wrapperRect = shared.toReactive(useElementBounding(wrapperRef));
710
- const parentRef = vue.inject(AFFIX_TARGET_KEY, void 0);
711
- const targetRef = shared.useElement(props.target, parentRef);
712
- const isFixed = vue.ref(false);
713
- const placeholderStyle = vue.ref({});
714
- const fixedStyle = vue.ref({});
715
- const className = vue.computed(() => {
716
- return isFixed.value ? props.fixedClass : "";
717
- });
718
- const wrapperVisible = useElementVisibility(wrapperRef);
719
- const containerRef = vue.computed(() => {
720
- if (!wrapperVisible.value) {
721
- return null;
722
- }
723
- return targetRef.value ?? window;
724
- });
725
- const updatePosition = shared.throttleByRaf(async () => {
726
- if (!wrapperRef.value || !containerRef.value) {
727
- return;
728
- }
729
- const area = wrapperRect.width * wrapperRect.height;
730
- if (area === 0) {
731
- return;
732
- }
733
- const newPlaceholderStyles = {
734
- width: tslx.px(wrapperRect.width),
735
- height: tslx.px(wrapperRect.height)
736
- };
737
- const targetRect = getTargetRect(containerRef.value);
738
- let newIsFixed = false;
739
- let newFixedStyles = {};
740
- const offset = props.offset;
741
- if (props.position === "top") {
742
- newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
743
- newFixedStyles = newIsFixed ? {
744
- position: "fixed",
745
- zIndex: props.zIndex,
746
- top: tslx.px(targetRect.top + offset)
747
- } : {};
748
- } else {
749
- newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
750
- newFixedStyles = newIsFixed ? {
751
- position: "fixed",
752
- bottom: tslx.px(window.innerHeight - targetRect.bottom + offset)
753
- } : {};
754
- }
755
- if (newIsFixed !== isFixed.value) {
756
- isFixed.value = newIsFixed;
757
- emit("change", newIsFixed);
758
- }
759
- placeholderStyle.value = newPlaceholderStyles;
760
- fixedStyle.value = {
761
- ...newFixedStyles,
762
- ...newIsFixed ? newPlaceholderStyles : {}
763
- };
764
- });
765
- useEventListener(containerRef, "scroll", () => {
766
- emit("scroll");
767
- updatePosition();
768
- });
769
- useEventListener(containerRef, "resize", updatePosition);
770
- vue.watchPostEffect(updatePosition);
771
- return {
772
- className,
773
- wrapperRef,
774
- containerRef,
775
- isFixed,
776
- placeholderStyle,
777
- fixedStyle,
778
- updatePosition
779
- };
780
- }
781
- });
782
- function provideAffixTarget(target) {
783
- vue.provide(AFFIX_TARGET_KEY, target);
784
- }
785
-
786
- const configProviderProps = shared.defineHookProps({
787
- icon: {
788
- type: Object
789
- },
790
- activateEvent: {
791
- type: String
792
- }
793
- });
794
-
795
- const fileUploadProps = shared.defineHookProps({
796
- modelValue: {
797
- type: [File, Array],
798
- default: () => []
799
- },
800
- multiple: {
801
- type: Boolean,
802
- default: false
803
- }
804
- });
805
- const fileUploadEmits = shared.defineHookEmits([
806
- "update:modelValue",
807
- "change"
808
- ]);
809
- const useFileUpload = shared.defineHookComponent({
810
- props: fileUploadProps,
811
- emits: fileUploadEmits,
812
- setup(props, { emit }) {
813
- const fileInputRef = shared.elementRef();
814
- const files = vue.ref([]);
815
- vue.watch(() => shared.toArray(props.modelValue), (value) => {
816
- files.value = value;
817
- }, {
818
- immediate: true,
819
- deep: true
820
- });
821
- const openFileInput = () => {
822
- fileInputRef.value?.click();
823
- };
824
- const toModelValue = (files2) => {
825
- if (props.multiple) {
826
- return files2;
827
- }
828
- if (files2.length) {
829
- return files2[files2.length - 1];
830
- }
831
- return null;
832
- };
833
- useEventListener(fileInputRef, "change", (event) => {
834
- const newFiles = Array.from(event.target.files ?? []);
835
- if (newFiles?.length) {
836
- if (props.multiple) {
837
- files.value.push(...newFiles);
838
- } else {
839
- files.value = newFiles.slice(newFiles.length - 1);
840
- }
841
- }
842
- const value = toModelValue(files.value);
843
- emit("update:modelValue", value);
844
- emit("change", value);
845
- });
846
- return {
847
- fileInputRef,
848
- files,
849
- openFileInput
850
- };
851
- }
852
- });
853
-
854
- const iconProps = shared.defineHookProps({
855
- src: {
856
- type: String,
857
- required: true
858
- },
859
- size: {
860
- type: [Number, String]
861
- },
862
- width: {
863
- type: [Number, String]
864
- },
865
- height: {
866
- type: [Number, String]
867
- },
868
- color: {
869
- type: String,
870
- default: "currentColor"
871
- },
872
- mask: {
873
- type: [Boolean, String],
874
- default: () => "auto"
875
- }
876
- });
877
- const isSvg = (src) => src.endsWith(".svg") || src.startsWith("data:image/svg+xml");
878
- const useIcon = shared.defineHookComponent({
879
- props: iconProps,
880
- setup(props, context) {
881
- const sharedConfig = shared.useSharedConfig("icon");
882
- const sizeStyle = vue.computed(() => {
883
- const s = props.size ?? sharedConfig.size;
884
- const unit = tslx.createUnitFormat(sharedConfig.sizeUnit ?? "px");
885
- const size = s ? unit(s) : void 0;
886
- const w = props.width ?? size;
887
- const h = props.height ?? size;
888
- const width = w ? unit(w) : void 0;
889
- const height = h ? unit(h) : void 0;
890
- return {
891
- width,
892
- height
893
- };
894
- });
895
- const dynamicStyle = vue.computed(() => {
896
- const mask = props.mask === "auto" ? isSvg(props.src) : props.mask;
897
- if (!mask) {
898
- return {
899
- "background-image": "var(--icon-url)",
900
- "background-size": "100% 100%"
901
- };
902
- }
903
- return {
904
- "mask": "var(--icon-url) no-repeat",
905
- "mask-size": "100% 100%",
906
- "-webkit-mask": "var(--icon-url) no-repeat",
907
- "-webkit-mask-size": "100% 100%",
908
- "background-color": props.color
909
- };
910
- });
911
- const staticStyle = vue.computed(() => {
912
- return {
913
- "--icon-url": `url("${props.src}")`
914
- };
915
- });
916
- const style = vue.computed(() => {
917
- return {
918
- ...staticStyle.value,
919
- ...dynamicStyle.value,
920
- ...sizeStyle.value,
921
- ...context.attrs.style ?? {}
922
- };
923
- });
924
- return {
925
- style
926
- };
927
- }
928
- });
929
-
930
- const selectionProps = shared.defineHookProps({
931
- modelValue: {
932
- type: shared.valuePropType,
933
- default: () => null
934
- },
935
- /**
936
- * 选中时的 class
937
- */
938
- activeClass: {
939
- type: shared.classPropType,
940
- default: "active"
941
- },
942
- /**
943
- * 每个选项的 class
944
- */
945
- itemClass: {
946
- type: shared.classPropType,
947
- default: ""
948
- },
949
- disabledClass: {
950
- type: shared.classPropType,
951
- default: "disabled"
952
- },
953
- unactiveClass: {
954
- type: shared.classPropType,
955
- default: ""
956
- },
957
- label: {
958
- type: shared.labelPropType
959
- },
960
- /**
961
- * 多选模式
962
- */
963
- multiple: {
964
- type: [Boolean, Number, Array],
965
- default: () => false
966
- },
967
- /**
968
- * 可清除
969
- */
970
- clearable: {
971
- type: Boolean
972
- },
973
- defaultValue: {
974
- type: shared.valuePropType,
975
- default: () => null
976
- },
977
- activateEvent: {
978
- type: String
979
- }
980
- });
981
- const selectionEmits = shared.defineHookEmits([
982
- "update:modelValue",
983
- "change",
984
- "load",
985
- "unload",
986
- "reject"
987
- ]);
988
- const HiSelectionContextSymbol = Symbol("[hi-selection]context");
989
- function useSelectionContext() {
990
- const sharedConfig = shared.useSharedConfig();
991
- return vue.inject(HiSelectionContextSymbol, {
992
- isActive: () => false,
993
- activate: () => {
994
- },
995
- changeActive: () => {
996
- },
997
- reject: () => {
998
- },
999
- activeClass: "active",
1000
- unactiveClass: "unactive",
1001
- disabledClass: "disabled",
1002
- itemClass: "",
1003
- activateEvent: sharedConfig.activateEvent,
1004
- label: null,
1005
- multiple: false,
1006
- limit: [0, Number.POSITIVE_INFINITY]
1007
- });
1008
- }
1009
- const useSelectionList = shared.defineHookComponent({
1010
- props: selectionProps,
1011
- emits: selectionEmits,
1012
- setup(props, { emit, slots }) {
1013
- const options = vue.reactive([]);
1014
- function toArray(value) {
1015
- if (!isDefined(value)) {
1016
- return [];
1017
- }
1018
- if (props.multiple && Array.isArray(value)) {
1019
- return value.filter((v) => v != null || v !== void 0);
1020
- }
1021
- return [value];
1022
- }
1023
- const actives = vue.reactive([
1024
- ...toArray(props.modelValue ?? props.defaultValue)
1025
- ]);
1026
- const currentValue = vue.computed({
1027
- get() {
1028
- return props.multiple ? actives : actives[0];
1029
- },
1030
- set(val) {
1031
- actives.splice(0, actives.length, ...toArray(val));
1032
- }
1033
- });
1034
- const modelValue = vue.computed({
1035
- get() {
1036
- return props.modelValue ?? props.defaultValue;
1037
- },
1038
- set(val) {
1039
- emit("update:modelValue", val);
1040
- }
1041
- });
1042
- syncRef(currentValue, modelValue, { immediate: true, deep: true });
1043
- const emitChange = () => emit("change", currentValue.value);
1044
- function isActive(value) {
1045
- return actives.includes(value);
1046
- }
1047
- const multipleActive = vue.computed(() => !!props.multiple);
1048
- const multipleLimit = vue.computed(() => {
1049
- if (Array.isArray(props.multiple)) {
1050
- if (props.multiple[1] === void 0) {
1051
- return [props.multiple[0], Number.POSITIVE_INFINITY];
1052
- }
1053
- return props.multiple;
1054
- }
1055
- return [0, Number.POSITIVE_INFINITY];
1056
- });
1057
- function activate(value) {
1058
- const [min, max] = multipleLimit.value;
1059
- if (isActive(value)) {
1060
- if (multipleActive.value && actives.length > min || props.clearable) {
1061
- actives.splice(actives.indexOf(value), 1);
1062
- emitChange();
1063
- }
1064
- } else {
1065
- if (props.multiple) {
1066
- if (actives.length < max) {
1067
- actives.push(value);
1068
- emitChange();
1069
- }
1070
- } else {
1071
- actives.splice(0, actives.length, value);
1072
- emitChange();
1073
- }
1074
- }
1075
- }
1076
- function reject(value) {
1077
- emit("reject", value);
1078
- }
1079
- const init = (option) => {
1080
- function remove() {
1081
- const index = options.findIndex((e) => e.id === option.id);
1082
- if (index > -1) {
1083
- options.splice(index, 1);
1084
- emit("unload", option);
1085
- }
1086
- }
1087
- for (let i = 0; i < options.length; i++) {
1088
- if (options[i].value === option.value) {
1089
- options.splice(i, 1);
1090
- i--;
1091
- }
1092
- }
1093
- options.push(option);
1094
- emit("load", option);
1095
- return remove;
1096
- };
1097
- const sharedConfig = shared.useSharedConfig();
1098
- vue.provide(HiSelectionContextSymbol, shared.toReactive({
1099
- activeClass: vue.computed(() => tslx.cls(props.activeClass)),
1100
- unactiveClass: vue.computed(() => tslx.cls(props.unactiveClass)),
1101
- disabledClass: vue.computed(() => tslx.cls(props.disabledClass)),
1102
- itemClass: vue.computed(() => tslx.cls(props.itemClass)),
1103
- label: vue.computed(() => props.label),
1104
- multiple: multipleActive,
1105
- limit: multipleLimit,
1106
- clearable: vue.computed(() => props.clearable),
1107
- defaultValue: vue.computed(() => props.defaultValue),
1108
- activateEvent: vue.computed(() => props.activateEvent ?? sharedConfig.activateEvent),
1109
- active: currentValue,
1110
- activate,
1111
- changeActive: activate,
1112
- isActive,
1113
- reject,
1114
- init
1115
- }));
1116
- const renderItem = () => {
1117
- const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
1118
- return props.multiple ? children : shared.getFirstChilld(children);
1119
- };
1120
- const slotData = {
1121
- isActive,
1122
- changeActive: activate,
1123
- renderItem
1124
- };
1125
- const render = () => {
1126
- return vue.renderSlot(slots, "default", slotData);
1127
- };
1128
- return {
1129
- options,
1130
- actives,
1131
- isActive,
1132
- changeActive: activate,
1133
- renderItem,
1134
- render
1135
- };
1136
- }
1137
- });
1138
-
1139
- const itemProps = shared.defineHookProps({
1140
- value: {
1141
- type: shared.valuePropType,
1142
- default() {
1143
- return Math.random().toString(16).slice(2);
1144
- }
1145
- },
1146
- label: {
1147
- type: [Function, String]
1148
- },
1149
- keepAlive: {
1150
- type: Boolean,
1151
- default: () => true
1152
- },
1153
- activateEvent: {
1154
- type: String
1155
- },
1156
- disabled: {
1157
- type: Boolean,
1158
- default: false
1159
- }
1160
- });
1161
- const itemEmits = shared.defineHookEmits(["reject"]);
1162
- const useSelectionItem = shared.defineHookComponent({
1163
- props: itemProps,
1164
- emits: itemEmits,
1165
- setup(props, { slots, emit }) {
1166
- const context = useSelectionContext();
1167
- const activate = () => {
1168
- if (props.disabled) {
1169
- emit("reject", props.value);
1170
- context.reject(props.value);
1171
- return;
1172
- }
1173
- context.activate(props.value);
1174
- };
1175
- const label = vue.computed(() => {
1176
- let label2 = props.label ?? context.label;
1177
- if (label2 && typeof label2 === "function") {
1178
- label2 = label2(props.value);
1179
- }
1180
- return Array.isArray(label2) ? label2 : [label2];
1181
- });
1182
- function render() {
1183
- return slots.default?.({
1184
- active: context.isActive(props.value),
1185
- activate
1186
- }) ?? label.value.filter(Boolean);
1187
- }
1188
- let remove = () => {
1189
- };
1190
- const init = context.init;
1191
- if (init) {
1192
- vue.watch(
1193
- () => props.value,
1194
- (value) => {
1195
- remove();
1196
- remove = init({
1197
- id: Math.random().toString(16).slice(2),
1198
- label: typeof props.label === "string" ? props.label : void 0,
1199
- value,
1200
- render
1201
- });
1202
- },
1203
- { immediate: true }
1204
- );
1205
- tryOnScopeDispose(remove);
1206
- }
1207
- const isActive = vue.computed(() => context.isActive(props.value));
1208
- const isDisabled = vue.computed(() => props.disabled);
1209
- const className = vue.computed(() => {
1210
- const array = [context.itemClass];
1211
- if (!isDisabled.value) {
1212
- array.push(context.isActive(props.value) ? context.activeClass : context.unactiveClass);
1213
- } else {
1214
- array.push(context.disabledClass);
1215
- }
1216
- return tslx.cls(array);
1217
- });
1218
- const activateEvent = vue.computed(() => props.activateEvent ?? context.activateEvent);
1219
- return {
1220
- activate,
1221
- render,
1222
- isActive,
1223
- isDisabled,
1224
- className,
1225
- activateEvent,
1226
- label
1227
- };
1228
- }
1229
- });
1230
-
1231
- const popoverProps = shared.defineHookProps({
1232
- popupClass: {
1233
- type: String
1234
- },
1235
- placement: {
1236
- type: String,
1237
- default: () => "auto"
1238
- },
1239
- triggerEvent: {
1240
- type: String,
1241
- default: () => "hover"
1242
- },
1243
- offset: {
1244
- type: Number,
1245
- default: () => 8
1246
- },
1247
- lazy: {
1248
- type: Boolean,
1249
- default: () => false
1250
- },
1251
- visible: {
1252
- type: Boolean,
1253
- default: () => false
1254
- },
1255
- disabled: {
1256
- type: Boolean,
1257
- default: () => false
1258
- },
1259
- teleport: {
1260
- type: [String, Object, Boolean],
1261
- default: () => true
1262
- }
1263
- });
1264
- const popoverEmits = shared.defineHookEmits(["update:visible", "change"]);
1265
- const usePopover = shared.defineHookComponent({
1266
- props: popoverProps,
1267
- emits: popoverEmits,
1268
- setup(props, context) {
1269
- const visible = useVModel(props, "visible", context.emit, {
1270
- passive: true
1271
- });
1272
- const triggerRef = shared.elementRef();
1273
- const popupRef = shared.elementRef();
1274
- const validate = (event) => {
1275
- const events2 = Array.isArray(event) ? event : [event];
1276
- return !props.disabled && events2.includes(props.triggerEvent);
1277
- };
1278
- let timer;
1279
- const toggle = (_value) => {
1280
- const value = _value ?? !visible.value;
1281
- visible.value = value;
1282
- context.emit("change", value);
1283
- };
1284
- function onMouseover() {
1285
- if (!validate("hover")) {
1286
- return;
1287
- }
1288
- timer = setTimeout(
1289
- () => {
1290
- toggle(true);
1291
- },
1292
- props.lazy ? 800 : 100
1293
- );
1294
- }
1295
- function onMouseout() {
1296
- if (!validate("hover")) {
1297
- return;
1298
- }
1299
- clearTimeout(timer);
1300
- toggle(false);
1301
- }
1302
- const onClick = (e) => {
1303
- if (!validate("click")) {
1304
- return;
1305
- }
1306
- e.preventDefault();
1307
- e.stopPropagation();
1308
- toggle();
1309
- };
1310
- onClickOutside(triggerRef, () => {
1311
- if (!validate(["click", "contextmenu", "touch", "dblclick", "mousedown"])) {
1312
- return;
1313
- }
1314
- toggle(false);
1315
- }, {
1316
- ignore: [popupRef]
1317
- });
1318
- const onContextmenu = (e) => {
1319
- if (!validate("contextmenu")) {
1320
- return;
1321
- }
1322
- e.preventDefault();
1323
- e.stopPropagation();
1324
- toggle();
1325
- };
1326
- const onFocusin = () => {
1327
- if (!validate("focus")) {
1328
- return;
1329
- }
1330
- toggle(true);
1331
- };
1332
- const onFocusout = () => {
1333
- if (!validate("focus")) {
1334
- return;
1335
- }
1336
- toggle(false);
1337
- };
1338
- const onTouchend = () => {
1339
- if (!validate("touch")) {
1340
- return;
1341
- }
1342
- toggle(true);
1343
- };
1344
- const onDblclick = () => {
1345
- if (!validate("dblclick")) {
1346
- return;
1347
- }
1348
- toggle(true);
1349
- };
1350
- const onMousedown = () => {
1351
- if (!validate("mousedown")) {
1352
- return;
1353
- }
1354
- toggle(true);
1355
- };
1356
- const onMouseup = () => {
1357
- if (!validate("mousedown")) {
1358
- return;
1359
- }
1360
- toggle(false);
1361
- };
1362
- const events = {
1363
- onMouseover,
1364
- onMouseout,
1365
- onMousedown,
1366
- onMouseup,
1367
- onContextmenu,
1368
- onClick,
1369
- onDblclick,
1370
- onFocusin,
1371
- onFocusout,
1372
- onTouchend
1373
- };
1374
- const dropdownPosition = vue.reactive({ x: 0, y: 0 });
1375
- const popupClass = vue.computed(() => {
1376
- return props.popupClass;
1377
- });
1378
- function resize() {
1379
- const trigger = triggerRef.value;
1380
- const popup = popupRef.value;
1381
- if (!!trigger && !!popup && visible.value) {
1382
- const { width, height, left, top } = trigger.getBoundingClientRect();
1383
- const { clientWidth: pWidth, clientHeight: pHeight } = popup;
1384
- let x = 0;
1385
- let y = 0;
1386
- const offset = props.offset;
1387
- switch (props.placement) {
1388
- case "auto":
1389
- case "bottom":
1390
- x = left - (pWidth - width) / 2;
1391
- y = top + height + offset;
1392
- break;
1393
- case "bottom-left":
1394
- x = left;
1395
- y = top + height + offset;
1396
- break;
1397
- case "bottom-right":
1398
- x = left + width - pWidth;
1399
- y = top + height + offset;
1400
- break;
1401
- case "top":
1402
- x = left - (pWidth - width) / 2;
1403
- y = top - pHeight - offset;
1404
- break;
1405
- case "top-left":
1406
- x = left;
1407
- y = top - pHeight - offset;
1408
- break;
1409
- case "top-right":
1410
- x = left + width - pWidth;
1411
- y = top - pHeight - offset;
1412
- break;
1413
- case "left":
1414
- x = left - pWidth - offset;
1415
- y = top - (pHeight - height) / 2;
1416
- break;
1417
- case "left-top":
1418
- x = left - pWidth - offset;
1419
- y = top;
1420
- break;
1421
- case "left-bottom":
1422
- x = left - pWidth - offset;
1423
- y = top + height - pHeight;
1424
- break;
1425
- case "right":
1426
- x = left + width + offset;
1427
- y = top - (pHeight - height) / 2;
1428
- break;
1429
- case "right-top":
1430
- x = left + width + offset;
1431
- y = top;
1432
- break;
1433
- case "right-bottom":
1434
- x = left + width + offset;
1435
- y = top + height - pHeight;
1436
- break;
1437
- }
1438
- dropdownPosition.x = x;
1439
- dropdownPosition.y = y;
1440
- }
1441
- }
1442
- vue.watch(visible, () => {
1443
- vue.nextTick(resize);
1444
- });
1445
- const popupStyle = vue.computed(() => {
1446
- return {
1447
- left: tslx.px(dropdownPosition.x),
1448
- top: tslx.px(dropdownPosition.y),
1449
- visibility: visible.value ? "visible" : "hidden",
1450
- position: "fixed"
1451
- };
1452
- });
1453
- return {
1454
- events,
1455
- dropdownPosition,
1456
- triggerRef,
1457
- popupRef,
1458
- popupClass,
1459
- popupStyle
1460
- };
1461
- }
1462
- });
1463
-
1464
- const switchProps = shared.defineHookProps({
1465
- modelValue: {
1466
- type: Boolean,
1467
- default: () => false
1468
- },
1469
- class: {
1470
- type: shared.classPropType
1471
- },
1472
- activeClass: {
1473
- type: shared.classPropType
1474
- },
1475
- unactiveClass: {
1476
- type: shared.classPropType
1477
- },
1478
- activateEvent: {
1479
- type: String
1480
- },
1481
- disabled: {
1482
- type: Boolean,
1483
- default: () => false
1484
- },
1485
- disabledClass: {
1486
- type: shared.classPropType
1487
- }
1488
- });
1489
- const switchEmits = shared.defineHookEmits(["update:modelValue", "change", "reject"]);
1490
- const useSwitch = shared.defineHookComponent({
1491
- props: switchProps,
1492
- emits: switchEmits,
1493
- setup(props, context) {
1494
- const modelValue = useVModel(props, "modelValue", context.emit, {
1495
- passive: true,
1496
- defaultValue: false
1497
- });
1498
- const toggle = function(value) {
1499
- if (props.disabled) {
1500
- context.emit("reject", value);
1501
- return;
1502
- }
1503
- const oldValue = modelValue.value;
1504
- const newValue = typeof value === "boolean" ? value : !oldValue;
1505
- if (newValue !== oldValue) {
1506
- modelValue.value = newValue;
1507
- context.emit("change", newValue);
1508
- }
1509
- };
1510
- const isDisabled = vue.computed(() => props.disabled);
1511
- const className = vue.computed(() => {
1512
- return tslx.cls([
1513
- props.class,
1514
- modelValue.value ? props.activeClass : props.unactiveClass,
1515
- isDisabled.value ? props.disabledClass : ""
1516
- ]);
1517
- });
1518
- const sharedConfig = shared.useSharedConfig();
1519
- const activateEvent = vue.computed(() => props.activateEvent ?? sharedConfig.activateEvent);
1520
- return {
1521
- toggle,
1522
- modelValue,
1523
- className,
1524
- isDisabled,
1525
- activateEvent
1526
- };
1527
- }
1528
- });
1529
-
1530
- const virtualListProps = shared.defineHookProps({
1531
- options: {
1532
- type: Object,
1533
- default: () => ({})
1534
- },
1535
- count: {
1536
- type: Number,
1537
- default: () => 0
1538
- },
1539
- estimateSize: {
1540
- type: [Function, Number],
1541
- default: () => 50
1542
- },
1543
- horizontal: {
1544
- type: Boolean,
1545
- default: () => false
1546
- }
1547
- });
1548
- const virtualListEmits = shared.defineHookEmits({
1549
- scrollEnd: () => true,
1550
- scrollStart: () => true,
1551
- scroll: (_) => true
1552
- });
1553
- const useVirtualList = shared.defineHookComponent({
1554
- props: virtualListProps,
1555
- emits: virtualListEmits,
1556
- setup(props, context) {
1557
- const { emit } = context;
1558
- const scrollElementRef = shared.elementRef();
1559
- const propsEstimateSize = props.estimateSize;
1560
- const estimateSize = typeof propsEstimateSize === "function" ? propsEstimateSize : () => propsEstimateSize;
1561
- const options = vue.computed(() => {
1562
- const opts = { ...props.options || {} };
1563
- return {
1564
- ...opts,
1565
- count: props.count,
1566
- estimateSize,
1567
- horizontal: props.horizontal,
1568
- getScrollElement: () => scrollElementRef.value,
1569
- observeElementRect: virtualCore.observeElementRect,
1570
- observeElementOffset: virtualCore.observeElementOffset,
1571
- scrollToFn: virtualCore.elementScroll
1572
- };
1573
- });
1574
- const virtualizer = new virtualCore.Virtualizer(options.value);
1575
- const state = vue.shallowRef(virtualizer);
1576
- const virtualItems = vue.computed(() => state.value.getVirtualItems());
1577
- const virtualIndexes = vue.computed(() => state.value.getVirtualIndexes());
1578
- const totalSize = vue.computed(() => state.value.getTotalSize());
1579
- vue.watch(
1580
- virtualIndexes,
1581
- (indexes) => {
1582
- if (indexes.length === 0) {
1583
- return;
1584
- }
1585
- if (indexes[indexes.length - 1] === props.count - 1) {
1586
- emit("scrollEnd");
1587
- } else if (indexes[0] === 0) {
1588
- emit("scrollStart");
1589
- }
1590
- emit("scroll", indexes);
1591
- },
1592
- { immediate: true }
1593
- );
1594
- vue.watch(
1595
- options,
1596
- (opts) => {
1597
- virtualizer.setOptions({
1598
- ...opts,
1599
- onChange: (instance, sync) => {
1600
- opts.onChange?.(instance, sync);
1601
- vue.triggerRef(state);
1602
- }
1603
- });
1604
- virtualizer._willUpdate();
1605
- vue.triggerRef(state);
1606
- },
1607
- { immediate: true }
1608
- );
1609
- vue.watch(
1610
- scrollElementRef,
1611
- (el) => {
1612
- if (el) {
1613
- virtualizer._willUpdate();
1614
- vue.triggerRef(state);
1615
- }
1616
- },
1617
- { immediate: true }
1618
- );
1619
- tryOnScopeDispose(virtualizer._didMount());
1620
- const measureElement = (el) => {
1621
- virtualizer.measureElement(el);
1622
- };
1623
- const scrollToIndex = (index, options2 = {
1624
- behavior: "smooth"
1625
- }) => {
1626
- virtualizer.scrollToIndex(index, options2);
1627
- };
1628
- const scrollToStart = (options2 = {
1629
- behavior: "smooth"
1630
- }) => {
1631
- scrollToIndex(0, options2);
1632
- };
1633
- const scrollToEnd = (options2 = {
1634
- behavior: "smooth"
1635
- }) => {
1636
- scrollToIndex(props.count - 1, options2);
1637
- };
1638
- return {
1639
- virtualizer,
1640
- virtualItems,
1641
- virtualIndexes,
1642
- totalSize,
1643
- scrollElementRef,
1644
- measureElement,
1645
- scrollToIndex,
1646
- scrollToStart,
1647
- scrollToEnd
1648
- };
1649
- }
1650
- });
1651
-
1652
- exports.AFFIX_TARGET_KEY = AFFIX_TARGET_KEY;
1653
- exports.affixEmits = affixEmits;
1654
- exports.affixProps = affixProps;
1655
- exports.configProviderProps = configProviderProps;
1656
- exports.fileUploadEmits = fileUploadEmits;
1657
- exports.fileUploadProps = fileUploadProps;
1658
- exports.iconProps = iconProps;
1659
- exports.itemEmits = itemEmits;
1660
- exports.itemProps = itemProps;
1661
- exports.popoverEmits = popoverEmits;
1662
- exports.popoverProps = popoverProps;
1663
- exports.provideAffixTarget = provideAffixTarget;
1664
- exports.selectionEmits = selectionEmits;
1665
- exports.selectionProps = selectionProps;
1666
- exports.switchEmits = switchEmits;
1667
- exports.switchProps = switchProps;
1668
- exports.useAffix = useAffix;
1669
- exports.useFileUpload = useFileUpload;
1670
- exports.useIcon = useIcon;
1671
- exports.usePopover = usePopover;
1672
- exports.useSelectionContext = useSelectionContext;
1673
- exports.useSelectionItem = useSelectionItem;
1674
- exports.useSelectionList = useSelectionList;
1675
- exports.useSwitch = useSwitch;
1676
- exports.useVirtualList = useVirtualList;
1677
- exports.virtualListEmits = virtualListEmits;
1678
- exports.virtualListProps = virtualListProps;
1679
- Object.prototype.hasOwnProperty.call(shared, '__proto__') &&
1680
- !Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
1681
- Object.defineProperty(exports, '__proto__', {
1682
- enumerable: true,
1683
- value: shared['__proto__']
1684
- });
1685
-
1686
- Object.keys(shared).forEach(function (k) {
1687
- if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = shared[k];
1688
- });