@hoci/core 0.8.1 → 0.10.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,1690 +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 input = event.target;
835
- const newFiles = Array.from(input.files ?? []);
836
- if (newFiles.length) {
837
- if (props.multiple) {
838
- files.value.push(...newFiles);
839
- } else {
840
- files.value = newFiles.slice(newFiles.length - 1);
841
- }
842
- }
843
- input.value = "";
844
- const value = toModelValue(files.value);
845
- emit("update:modelValue", value);
846
- emit("change", value);
847
- });
848
- return {
849
- fileInputRef,
850
- files,
851
- openFileInput
852
- };
853
- }
854
- });
855
-
856
- const iconProps = shared.defineHookProps({
857
- src: {
858
- type: String,
859
- required: true
860
- },
861
- size: {
862
- type: [Number, String]
863
- },
864
- width: {
865
- type: [Number, String]
866
- },
867
- height: {
868
- type: [Number, String]
869
- },
870
- color: {
871
- type: String,
872
- default: "currentColor"
873
- },
874
- mask: {
875
- type: [Boolean, String],
876
- default: () => "auto"
877
- }
878
- });
879
- const isSvg = (src) => src.endsWith(".svg") || src.startsWith("data:image/svg+xml");
880
- const useIcon = shared.defineHookComponent({
881
- props: iconProps,
882
- setup(props, context) {
883
- const sharedConfig = shared.useSharedConfig("icon");
884
- const sizeStyle = vue.computed(() => {
885
- const s = props.size ?? sharedConfig.size;
886
- const unit = tslx.createUnitFormat(sharedConfig.sizeUnit ?? "px");
887
- const size = s ? unit(s) : void 0;
888
- const w = props.width ?? size;
889
- const h = props.height ?? size;
890
- const width = w ? unit(w) : void 0;
891
- const height = h ? unit(h) : void 0;
892
- return {
893
- width,
894
- height
895
- };
896
- });
897
- const dynamicStyle = vue.computed(() => {
898
- const mask = props.mask === "auto" ? isSvg(props.src) : props.mask;
899
- if (!mask) {
900
- return {
901
- "background-image": "var(--icon-url)",
902
- "background-size": "100% 100%"
903
- };
904
- }
905
- return {
906
- "mask": "var(--icon-url) no-repeat",
907
- "mask-size": "100% 100%",
908
- "-webkit-mask": "var(--icon-url) no-repeat",
909
- "-webkit-mask-size": "100% 100%",
910
- "background-color": props.color
911
- };
912
- });
913
- const staticStyle = vue.computed(() => {
914
- return {
915
- "--icon-url": `url("${props.src}")`
916
- };
917
- });
918
- const style = vue.computed(() => {
919
- return {
920
- ...staticStyle.value,
921
- ...dynamicStyle.value,
922
- ...sizeStyle.value,
923
- ...context.attrs.style ?? {}
924
- };
925
- });
926
- return {
927
- style
928
- };
929
- }
930
- });
931
-
932
- const selectionProps = shared.defineHookProps({
933
- modelValue: {
934
- type: shared.valuePropType,
935
- default: () => null
936
- },
937
- /**
938
- * 选中时的 class
939
- */
940
- activeClass: {
941
- type: shared.classPropType,
942
- default: "active"
943
- },
944
- /**
945
- * 每个选项的 class
946
- */
947
- itemClass: {
948
- type: shared.classPropType,
949
- default: ""
950
- },
951
- disabledClass: {
952
- type: shared.classPropType,
953
- default: "disabled"
954
- },
955
- unactiveClass: {
956
- type: shared.classPropType,
957
- default: ""
958
- },
959
- label: {
960
- type: shared.labelPropType
961
- },
962
- /**
963
- * 多选模式
964
- */
965
- multiple: {
966
- type: [Boolean, Number, Array],
967
- default: () => false
968
- },
969
- /**
970
- * 可清除
971
- */
972
- clearable: {
973
- type: Boolean
974
- },
975
- defaultValue: {
976
- type: shared.valuePropType,
977
- default: () => null
978
- },
979
- activateEvent: {
980
- type: String
981
- }
982
- });
983
- const selectionEmits = shared.defineHookEmits([
984
- "update:modelValue",
985
- "change",
986
- "load",
987
- "unload",
988
- "reject"
989
- ]);
990
- const HiSelectionContextSymbol = Symbol("[hi-selection]context");
991
- function useSelectionContext() {
992
- const sharedConfig = shared.useSharedConfig();
993
- return vue.inject(HiSelectionContextSymbol, {
994
- isActive: () => false,
995
- activate: () => {
996
- },
997
- changeActive: () => {
998
- },
999
- reject: () => {
1000
- },
1001
- activeClass: "active",
1002
- unactiveClass: "unactive",
1003
- disabledClass: "disabled",
1004
- itemClass: "",
1005
- activateEvent: sharedConfig.activateEvent,
1006
- label: null,
1007
- multiple: false,
1008
- limit: [0, Number.POSITIVE_INFINITY]
1009
- });
1010
- }
1011
- const useSelectionList = shared.defineHookComponent({
1012
- props: selectionProps,
1013
- emits: selectionEmits,
1014
- setup(props, { emit, slots }) {
1015
- const options = vue.reactive([]);
1016
- function toArray(value) {
1017
- if (!isDefined(value)) {
1018
- return [];
1019
- }
1020
- if (props.multiple && Array.isArray(value)) {
1021
- return value.filter((v) => v != null || v !== void 0);
1022
- }
1023
- return [value];
1024
- }
1025
- const actives = vue.reactive([
1026
- ...toArray(props.modelValue ?? props.defaultValue)
1027
- ]);
1028
- const currentValue = vue.computed({
1029
- get() {
1030
- return props.multiple ? actives : actives[0];
1031
- },
1032
- set(val) {
1033
- actives.splice(0, actives.length, ...toArray(val));
1034
- }
1035
- });
1036
- const modelValue = vue.computed({
1037
- get() {
1038
- return props.modelValue ?? props.defaultValue;
1039
- },
1040
- set(val) {
1041
- emit("update:modelValue", val);
1042
- }
1043
- });
1044
- syncRef(currentValue, modelValue, { immediate: true, deep: true });
1045
- const emitChange = () => emit("change", currentValue.value);
1046
- function isActive(value) {
1047
- return actives.includes(value);
1048
- }
1049
- const multipleActive = vue.computed(() => !!props.multiple);
1050
- const multipleLimit = vue.computed(() => {
1051
- if (Array.isArray(props.multiple)) {
1052
- if (props.multiple[1] === void 0) {
1053
- return [props.multiple[0], Number.POSITIVE_INFINITY];
1054
- }
1055
- return props.multiple;
1056
- }
1057
- return [0, Number.POSITIVE_INFINITY];
1058
- });
1059
- function activate(value) {
1060
- const [min, max] = multipleLimit.value;
1061
- if (isActive(value)) {
1062
- if (multipleActive.value && actives.length > min || props.clearable) {
1063
- actives.splice(actives.indexOf(value), 1);
1064
- emitChange();
1065
- }
1066
- } else {
1067
- if (props.multiple) {
1068
- if (actives.length < max) {
1069
- actives.push(value);
1070
- emitChange();
1071
- }
1072
- } else {
1073
- actives.splice(0, actives.length, value);
1074
- emitChange();
1075
- }
1076
- }
1077
- }
1078
- function reject(value) {
1079
- emit("reject", value);
1080
- }
1081
- const init = (option) => {
1082
- function remove() {
1083
- const index = options.findIndex((e) => e.id === option.id);
1084
- if (index > -1) {
1085
- options.splice(index, 1);
1086
- emit("unload", option);
1087
- }
1088
- }
1089
- for (let i = 0; i < options.length; i++) {
1090
- if (options[i].value === option.value) {
1091
- options.splice(i, 1);
1092
- i--;
1093
- }
1094
- }
1095
- options.push(option);
1096
- emit("load", option);
1097
- return remove;
1098
- };
1099
- const sharedConfig = shared.useSharedConfig();
1100
- vue.provide(HiSelectionContextSymbol, shared.toReactive({
1101
- activeClass: vue.computed(() => tslx.cls(props.activeClass)),
1102
- unactiveClass: vue.computed(() => tslx.cls(props.unactiveClass)),
1103
- disabledClass: vue.computed(() => tslx.cls(props.disabledClass)),
1104
- itemClass: vue.computed(() => tslx.cls(props.itemClass)),
1105
- label: vue.computed(() => props.label),
1106
- multiple: multipleActive,
1107
- limit: multipleLimit,
1108
- clearable: vue.computed(() => props.clearable),
1109
- defaultValue: vue.computed(() => props.defaultValue),
1110
- activateEvent: vue.computed(() => props.activateEvent ?? sharedConfig.activateEvent),
1111
- active: currentValue,
1112
- activate,
1113
- changeActive: activate,
1114
- isActive,
1115
- reject,
1116
- init
1117
- }));
1118
- const renderItem = () => {
1119
- const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
1120
- return props.multiple ? children : shared.getFirstChilld(children);
1121
- };
1122
- const slotData = {
1123
- isActive,
1124
- changeActive: activate,
1125
- renderItem
1126
- };
1127
- const render = () => {
1128
- return vue.renderSlot(slots, "default", slotData);
1129
- };
1130
- return {
1131
- options,
1132
- actives,
1133
- isActive,
1134
- changeActive: activate,
1135
- renderItem,
1136
- render
1137
- };
1138
- }
1139
- });
1140
-
1141
- const itemProps = shared.defineHookProps({
1142
- value: {
1143
- type: shared.valuePropType,
1144
- default() {
1145
- return Math.random().toString(16).slice(2);
1146
- }
1147
- },
1148
- label: {
1149
- type: [Function, String]
1150
- },
1151
- keepAlive: {
1152
- type: Boolean,
1153
- default: () => true
1154
- },
1155
- activateEvent: {
1156
- type: String
1157
- },
1158
- disabled: {
1159
- type: Boolean,
1160
- default: false
1161
- }
1162
- });
1163
- const itemEmits = shared.defineHookEmits(["reject"]);
1164
- const useSelectionItem = shared.defineHookComponent({
1165
- props: itemProps,
1166
- emits: itemEmits,
1167
- setup(props, { slots, emit }) {
1168
- const context = useSelectionContext();
1169
- const activate = () => {
1170
- if (props.disabled) {
1171
- emit("reject", props.value);
1172
- context.reject(props.value);
1173
- return;
1174
- }
1175
- context.activate(props.value);
1176
- };
1177
- const label = vue.computed(() => {
1178
- let label2 = props.label ?? context.label;
1179
- if (label2 && typeof label2 === "function") {
1180
- label2 = label2(props.value);
1181
- }
1182
- return Array.isArray(label2) ? label2 : [label2];
1183
- });
1184
- function render() {
1185
- return slots.default?.({
1186
- active: context.isActive(props.value),
1187
- activate
1188
- }) ?? label.value.filter(Boolean);
1189
- }
1190
- let remove = () => {
1191
- };
1192
- const init = context.init;
1193
- if (init) {
1194
- vue.watch(
1195
- () => props.value,
1196
- (value) => {
1197
- remove();
1198
- remove = init({
1199
- id: Math.random().toString(16).slice(2),
1200
- label: typeof props.label === "string" ? props.label : void 0,
1201
- value,
1202
- render
1203
- });
1204
- },
1205
- { immediate: true }
1206
- );
1207
- tryOnScopeDispose(remove);
1208
- }
1209
- const isActive = vue.computed(() => context.isActive(props.value));
1210
- const isDisabled = vue.computed(() => props.disabled);
1211
- const className = vue.computed(() => {
1212
- const array = [context.itemClass];
1213
- if (!isDisabled.value) {
1214
- array.push(context.isActive(props.value) ? context.activeClass : context.unactiveClass);
1215
- } else {
1216
- array.push(context.disabledClass);
1217
- }
1218
- return tslx.cls(array);
1219
- });
1220
- const activateEvent = vue.computed(() => props.activateEvent ?? context.activateEvent);
1221
- return {
1222
- activate,
1223
- render,
1224
- isActive,
1225
- isDisabled,
1226
- className,
1227
- activateEvent,
1228
- label
1229
- };
1230
- }
1231
- });
1232
-
1233
- const popoverProps = shared.defineHookProps({
1234
- popupClass: {
1235
- type: String
1236
- },
1237
- placement: {
1238
- type: String,
1239
- default: () => "auto"
1240
- },
1241
- triggerEvent: {
1242
- type: String,
1243
- default: () => "hover"
1244
- },
1245
- offset: {
1246
- type: Number,
1247
- default: () => 8
1248
- },
1249
- lazy: {
1250
- type: Boolean,
1251
- default: () => false
1252
- },
1253
- visible: {
1254
- type: Boolean,
1255
- default: () => false
1256
- },
1257
- disabled: {
1258
- type: Boolean,
1259
- default: () => false
1260
- },
1261
- teleport: {
1262
- type: [String, Object, Boolean],
1263
- default: () => true
1264
- }
1265
- });
1266
- const popoverEmits = shared.defineHookEmits(["update:visible", "change"]);
1267
- const usePopover = shared.defineHookComponent({
1268
- props: popoverProps,
1269
- emits: popoverEmits,
1270
- setup(props, context) {
1271
- const visible = useVModel(props, "visible", context.emit, {
1272
- passive: true
1273
- });
1274
- const triggerRef = shared.elementRef();
1275
- const popupRef = shared.elementRef();
1276
- const validate = (event) => {
1277
- const events2 = Array.isArray(event) ? event : [event];
1278
- return !props.disabled && events2.includes(props.triggerEvent);
1279
- };
1280
- let timer;
1281
- const toggle = (_value) => {
1282
- const value = _value ?? !visible.value;
1283
- visible.value = value;
1284
- context.emit("change", value);
1285
- };
1286
- function onMouseover() {
1287
- if (!validate("hover")) {
1288
- return;
1289
- }
1290
- timer = setTimeout(
1291
- () => {
1292
- toggle(true);
1293
- },
1294
- props.lazy ? 800 : 100
1295
- );
1296
- }
1297
- function onMouseout() {
1298
- if (!validate("hover")) {
1299
- return;
1300
- }
1301
- clearTimeout(timer);
1302
- toggle(false);
1303
- }
1304
- const onClick = (e) => {
1305
- if (!validate("click")) {
1306
- return;
1307
- }
1308
- e.preventDefault();
1309
- e.stopPropagation();
1310
- toggle();
1311
- };
1312
- onClickOutside(triggerRef, () => {
1313
- if (!validate(["click", "contextmenu", "touch", "dblclick", "mousedown"])) {
1314
- return;
1315
- }
1316
- toggle(false);
1317
- }, {
1318
- ignore: [popupRef]
1319
- });
1320
- const onContextmenu = (e) => {
1321
- if (!validate("contextmenu")) {
1322
- return;
1323
- }
1324
- e.preventDefault();
1325
- e.stopPropagation();
1326
- toggle();
1327
- };
1328
- const onFocusin = () => {
1329
- if (!validate("focus")) {
1330
- return;
1331
- }
1332
- toggle(true);
1333
- };
1334
- const onFocusout = () => {
1335
- if (!validate("focus")) {
1336
- return;
1337
- }
1338
- toggle(false);
1339
- };
1340
- const onTouchend = () => {
1341
- if (!validate("touch")) {
1342
- return;
1343
- }
1344
- toggle(true);
1345
- };
1346
- const onDblclick = () => {
1347
- if (!validate("dblclick")) {
1348
- return;
1349
- }
1350
- toggle(true);
1351
- };
1352
- const onMousedown = () => {
1353
- if (!validate("mousedown")) {
1354
- return;
1355
- }
1356
- toggle(true);
1357
- };
1358
- const onMouseup = () => {
1359
- if (!validate("mousedown")) {
1360
- return;
1361
- }
1362
- toggle(false);
1363
- };
1364
- const events = {
1365
- onMouseover,
1366
- onMouseout,
1367
- onMousedown,
1368
- onMouseup,
1369
- onContextmenu,
1370
- onClick,
1371
- onDblclick,
1372
- onFocusin,
1373
- onFocusout,
1374
- onTouchend
1375
- };
1376
- const dropdownPosition = vue.reactive({ x: 0, y: 0 });
1377
- const popupClass = vue.computed(() => {
1378
- return props.popupClass;
1379
- });
1380
- function resize() {
1381
- const trigger = triggerRef.value;
1382
- const popup = popupRef.value;
1383
- if (!!trigger && !!popup && visible.value) {
1384
- const { width, height, left, top } = trigger.getBoundingClientRect();
1385
- const { clientWidth: pWidth, clientHeight: pHeight } = popup;
1386
- let x = 0;
1387
- let y = 0;
1388
- const offset = props.offset;
1389
- switch (props.placement) {
1390
- case "auto":
1391
- case "bottom":
1392
- x = left - (pWidth - width) / 2;
1393
- y = top + height + offset;
1394
- break;
1395
- case "bottom-left":
1396
- x = left;
1397
- y = top + height + offset;
1398
- break;
1399
- case "bottom-right":
1400
- x = left + width - pWidth;
1401
- y = top + height + offset;
1402
- break;
1403
- case "top":
1404
- x = left - (pWidth - width) / 2;
1405
- y = top - pHeight - offset;
1406
- break;
1407
- case "top-left":
1408
- x = left;
1409
- y = top - pHeight - offset;
1410
- break;
1411
- case "top-right":
1412
- x = left + width - pWidth;
1413
- y = top - pHeight - offset;
1414
- break;
1415
- case "left":
1416
- x = left - pWidth - offset;
1417
- y = top - (pHeight - height) / 2;
1418
- break;
1419
- case "left-top":
1420
- x = left - pWidth - offset;
1421
- y = top;
1422
- break;
1423
- case "left-bottom":
1424
- x = left - pWidth - offset;
1425
- y = top + height - pHeight;
1426
- break;
1427
- case "right":
1428
- x = left + width + offset;
1429
- y = top - (pHeight - height) / 2;
1430
- break;
1431
- case "right-top":
1432
- x = left + width + offset;
1433
- y = top;
1434
- break;
1435
- case "right-bottom":
1436
- x = left + width + offset;
1437
- y = top + height - pHeight;
1438
- break;
1439
- }
1440
- dropdownPosition.x = x;
1441
- dropdownPosition.y = y;
1442
- }
1443
- }
1444
- vue.watch(visible, () => {
1445
- vue.nextTick(resize);
1446
- });
1447
- const popupStyle = vue.computed(() => {
1448
- return {
1449
- left: tslx.px(dropdownPosition.x),
1450
- top: tslx.px(dropdownPosition.y),
1451
- visibility: visible.value ? "visible" : "hidden",
1452
- position: "fixed"
1453
- };
1454
- });
1455
- return {
1456
- events,
1457
- dropdownPosition,
1458
- triggerRef,
1459
- popupRef,
1460
- popupClass,
1461
- popupStyle
1462
- };
1463
- }
1464
- });
1465
-
1466
- const switchProps = shared.defineHookProps({
1467
- modelValue: {
1468
- type: Boolean,
1469
- default: () => false
1470
- },
1471
- class: {
1472
- type: shared.classPropType
1473
- },
1474
- activeClass: {
1475
- type: shared.classPropType
1476
- },
1477
- unactiveClass: {
1478
- type: shared.classPropType
1479
- },
1480
- activateEvent: {
1481
- type: String
1482
- },
1483
- disabled: {
1484
- type: Boolean,
1485
- default: () => false
1486
- },
1487
- disabledClass: {
1488
- type: shared.classPropType
1489
- }
1490
- });
1491
- const switchEmits = shared.defineHookEmits(["update:modelValue", "change", "reject"]);
1492
- const useSwitch = shared.defineHookComponent({
1493
- props: switchProps,
1494
- emits: switchEmits,
1495
- setup(props, context) {
1496
- const modelValue = useVModel(props, "modelValue", context.emit, {
1497
- passive: true,
1498
- defaultValue: false
1499
- });
1500
- const toggle = function(value) {
1501
- if (props.disabled) {
1502
- context.emit("reject", value);
1503
- return;
1504
- }
1505
- const oldValue = modelValue.value;
1506
- const newValue = typeof value === "boolean" ? value : !oldValue;
1507
- if (newValue !== oldValue) {
1508
- modelValue.value = newValue;
1509
- context.emit("change", newValue);
1510
- }
1511
- };
1512
- const isDisabled = vue.computed(() => props.disabled);
1513
- const className = vue.computed(() => {
1514
- return tslx.cls([
1515
- props.class,
1516
- modelValue.value ? props.activeClass : props.unactiveClass,
1517
- isDisabled.value ? props.disabledClass : ""
1518
- ]);
1519
- });
1520
- const sharedConfig = shared.useSharedConfig();
1521
- const activateEvent = vue.computed(() => props.activateEvent ?? sharedConfig.activateEvent);
1522
- return {
1523
- toggle,
1524
- modelValue,
1525
- className,
1526
- isDisabled,
1527
- activateEvent
1528
- };
1529
- }
1530
- });
1531
-
1532
- const virtualListProps = shared.defineHookProps({
1533
- options: {
1534
- type: Object,
1535
- default: () => ({})
1536
- },
1537
- count: {
1538
- type: Number,
1539
- default: () => 0
1540
- },
1541
- estimateSize: {
1542
- type: [Function, Number],
1543
- default: () => 50
1544
- },
1545
- horizontal: {
1546
- type: Boolean,
1547
- default: () => false
1548
- }
1549
- });
1550
- const virtualListEmits = shared.defineHookEmits({
1551
- scrollEnd: () => true,
1552
- scrollStart: () => true,
1553
- scroll: (_) => true
1554
- });
1555
- const useVirtualList = shared.defineHookComponent({
1556
- props: virtualListProps,
1557
- emits: virtualListEmits,
1558
- setup(props, context) {
1559
- const { emit } = context;
1560
- const scrollElementRef = shared.elementRef();
1561
- const propsEstimateSize = props.estimateSize;
1562
- const estimateSize = typeof propsEstimateSize === "function" ? propsEstimateSize : () => propsEstimateSize;
1563
- const options = vue.computed(() => {
1564
- const opts = { ...props.options || {} };
1565
- return {
1566
- ...opts,
1567
- count: props.count,
1568
- estimateSize,
1569
- horizontal: props.horizontal,
1570
- getScrollElement: () => scrollElementRef.value,
1571
- observeElementRect: virtualCore.observeElementRect,
1572
- observeElementOffset: virtualCore.observeElementOffset,
1573
- scrollToFn: virtualCore.elementScroll
1574
- };
1575
- });
1576
- const virtualizer = new virtualCore.Virtualizer(options.value);
1577
- const state = vue.shallowRef(virtualizer);
1578
- const virtualItems = vue.computed(() => state.value.getVirtualItems());
1579
- const virtualIndexes = vue.computed(() => state.value.getVirtualIndexes());
1580
- const totalSize = vue.computed(() => state.value.getTotalSize());
1581
- vue.watch(
1582
- virtualIndexes,
1583
- (indexes) => {
1584
- if (indexes.length === 0) {
1585
- return;
1586
- }
1587
- if (indexes[indexes.length - 1] === props.count - 1) {
1588
- emit("scrollEnd");
1589
- } else if (indexes[0] === 0) {
1590
- emit("scrollStart");
1591
- }
1592
- emit("scroll", indexes);
1593
- },
1594
- { immediate: true }
1595
- );
1596
- vue.watch(
1597
- options,
1598
- (opts) => {
1599
- virtualizer.setOptions({
1600
- ...opts,
1601
- onChange: (instance, sync) => {
1602
- opts.onChange?.(instance, sync);
1603
- vue.triggerRef(state);
1604
- }
1605
- });
1606
- virtualizer._willUpdate();
1607
- vue.triggerRef(state);
1608
- },
1609
- { immediate: true }
1610
- );
1611
- vue.watch(
1612
- scrollElementRef,
1613
- (el) => {
1614
- if (el) {
1615
- virtualizer._willUpdate();
1616
- vue.triggerRef(state);
1617
- }
1618
- },
1619
- { immediate: true }
1620
- );
1621
- tryOnScopeDispose(virtualizer._didMount());
1622
- const measureElement = (el) => {
1623
- virtualizer.measureElement(el);
1624
- };
1625
- const scrollToIndex = (index, options2 = {
1626
- behavior: "smooth"
1627
- }) => {
1628
- virtualizer.scrollToIndex(index, options2);
1629
- };
1630
- const scrollToStart = (options2 = {
1631
- behavior: "smooth"
1632
- }) => {
1633
- scrollToIndex(0, options2);
1634
- };
1635
- const scrollToEnd = (options2 = {
1636
- behavior: "smooth"
1637
- }) => {
1638
- scrollToIndex(props.count - 1, options2);
1639
- };
1640
- return {
1641
- virtualizer,
1642
- virtualItems,
1643
- virtualIndexes,
1644
- totalSize,
1645
- scrollElementRef,
1646
- measureElement,
1647
- scrollToIndex,
1648
- scrollToStart,
1649
- scrollToEnd
1650
- };
1651
- }
1652
- });
1653
-
1654
- exports.AFFIX_TARGET_KEY = AFFIX_TARGET_KEY;
1655
- exports.affixEmits = affixEmits;
1656
- exports.affixProps = affixProps;
1657
- exports.configProviderProps = configProviderProps;
1658
- exports.fileUploadEmits = fileUploadEmits;
1659
- exports.fileUploadProps = fileUploadProps;
1660
- exports.iconProps = iconProps;
1661
- exports.itemEmits = itemEmits;
1662
- exports.itemProps = itemProps;
1663
- exports.popoverEmits = popoverEmits;
1664
- exports.popoverProps = popoverProps;
1665
- exports.provideAffixTarget = provideAffixTarget;
1666
- exports.selectionEmits = selectionEmits;
1667
- exports.selectionProps = selectionProps;
1668
- exports.switchEmits = switchEmits;
1669
- exports.switchProps = switchProps;
1670
- exports.useAffix = useAffix;
1671
- exports.useFileUpload = useFileUpload;
1672
- exports.useIcon = useIcon;
1673
- exports.usePopover = usePopover;
1674
- exports.useSelectionContext = useSelectionContext;
1675
- exports.useSelectionItem = useSelectionItem;
1676
- exports.useSelectionList = useSelectionList;
1677
- exports.useSwitch = useSwitch;
1678
- exports.useVirtualList = useVirtualList;
1679
- exports.virtualListEmits = virtualListEmits;
1680
- exports.virtualListProps = virtualListProps;
1681
- Object.prototype.hasOwnProperty.call(shared, '__proto__') &&
1682
- !Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
1683
- Object.defineProperty(exports, '__proto__', {
1684
- enumerable: true,
1685
- value: shared['__proto__']
1686
- });
1687
-
1688
- Object.keys(shared).forEach(function (k) {
1689
- if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = shared[k];
1690
- });