@hoci/components 0.5.7 → 0.5.9
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 +157 -27
- package/dist/index.d.cts +6 -14
- package/dist/index.d.mts +6 -14
- package/dist/index.d.ts +6 -14
- package/dist/index.mjs +161 -32
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const vue = require('vue');
|
|
4
4
|
const core = require('@hoci/core');
|
|
5
|
-
const tslx = require('tslx');
|
|
6
|
-
const shared = require('@hoci/shared');
|
|
7
5
|
const core$1 = require('@vueuse/core');
|
|
6
|
+
const shared = require('@hoci/shared');
|
|
7
|
+
const tslx = require('tslx');
|
|
8
8
|
|
|
9
9
|
const HiAffix = vue.defineComponent({
|
|
10
10
|
name: "HiAffix",
|
|
@@ -17,14 +17,149 @@ const HiAffix = vue.defineComponent({
|
|
|
17
17
|
},
|
|
18
18
|
setup(props, context) {
|
|
19
19
|
const { className, wrapperRef, isFixed, placeholderStyle, fixedStyle } = core.useAffix(props, context);
|
|
20
|
-
return () => vue.h(
|
|
21
|
-
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
return () => vue.h(props.as, { ref: wrapperRef }, [
|
|
21
|
+
isFixed.value && vue.h("div", { style: placeholderStyle.value }),
|
|
22
|
+
vue.h("div", { class: className.value, style: fixedStyle.value }, vue.renderSlot(context.slots, "default"))
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const affixProps = shared.defineHookProps(
|
|
28
|
+
{
|
|
29
|
+
fixedClass: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: ""
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* @zh 距离窗口顶部达到指定偏移量后触发
|
|
35
|
+
* @en Triggered when the specified offset is reached from the top of the window
|
|
36
|
+
*/
|
|
37
|
+
offset: {
|
|
38
|
+
type: Number,
|
|
39
|
+
default: 0
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* @zh 固定的相对方向
|
|
43
|
+
*/
|
|
44
|
+
position: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: "top"
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* @zh 滚动容器,默认是 `window`
|
|
50
|
+
* @en Scroll container, default is `window`
|
|
51
|
+
*/
|
|
52
|
+
target: {
|
|
53
|
+
type: [String, Object, Function]
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* @zh z-index 值
|
|
57
|
+
* @en Z index value
|
|
58
|
+
*/
|
|
59
|
+
zIndex: {
|
|
60
|
+
type: Number,
|
|
61
|
+
default: 998
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
shared.defineHookEmits(["scroll", "change"]);
|
|
66
|
+
const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
|
|
67
|
+
function getTargetRect(target) {
|
|
68
|
+
return shared.isWindow(target) ? {
|
|
69
|
+
top: 0,
|
|
70
|
+
bottom: window.innerHeight
|
|
71
|
+
} : target.getBoundingClientRect();
|
|
72
|
+
}
|
|
73
|
+
shared.defineHookComponent({
|
|
74
|
+
props: affixProps,
|
|
75
|
+
setup(props, { emit }) {
|
|
76
|
+
const wrapperRef = vue.ref(null);
|
|
77
|
+
const wrapperRect = shared.toReactive(core$1.useElementBounding(wrapperRef));
|
|
78
|
+
const parentRef = vue.inject(AFFIX_TARGET_KEY, void 0);
|
|
79
|
+
const targetRef = shared.useElement(props.target, parentRef);
|
|
80
|
+
const isFixed = vue.ref(false);
|
|
81
|
+
const placeholderStyle = vue.ref({});
|
|
82
|
+
const fixedStyle = vue.ref({});
|
|
83
|
+
const className = vue.computed(() => {
|
|
84
|
+
return isFixed.value ? props.fixedClass : "";
|
|
85
|
+
});
|
|
86
|
+
const wrapperVisible = core$1.useElementVisibility(wrapperRef);
|
|
87
|
+
const containerRef = vue.computed(() => {
|
|
88
|
+
if (!wrapperVisible.value) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return targetRef.value ?? window;
|
|
92
|
+
});
|
|
93
|
+
const updatePosition = shared.throttleByRaf(async () => {
|
|
94
|
+
if (!wrapperRef.value || !containerRef.value) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const area = wrapperRect.width * wrapperRect.height;
|
|
98
|
+
if (area === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const newPlaceholderStyles = {
|
|
102
|
+
width: tslx.px(wrapperRect.width),
|
|
103
|
+
height: tslx.px(wrapperRect.height)
|
|
104
|
+
};
|
|
105
|
+
const targetRect = getTargetRect(containerRef.value);
|
|
106
|
+
let newIsFixed = false;
|
|
107
|
+
let newFixedStyles = {};
|
|
108
|
+
const offset = props.offset;
|
|
109
|
+
if (props.position === "top") {
|
|
110
|
+
newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
|
|
111
|
+
newFixedStyles = newIsFixed ? {
|
|
112
|
+
position: "fixed",
|
|
113
|
+
zIndex: props.zIndex,
|
|
114
|
+
top: tslx.px(targetRect.top + offset)
|
|
115
|
+
} : {};
|
|
116
|
+
} else {
|
|
117
|
+
newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
|
|
118
|
+
newFixedStyles = newIsFixed ? {
|
|
119
|
+
position: "fixed",
|
|
120
|
+
bottom: tslx.px(window.innerHeight - targetRect.bottom + offset)
|
|
121
|
+
} : {};
|
|
122
|
+
}
|
|
123
|
+
if (newIsFixed !== isFixed.value) {
|
|
124
|
+
isFixed.value = newIsFixed;
|
|
125
|
+
emit("change", newIsFixed);
|
|
126
|
+
}
|
|
127
|
+
placeholderStyle.value = newPlaceholderStyles;
|
|
128
|
+
fixedStyle.value = {
|
|
129
|
+
...newFixedStyles,
|
|
130
|
+
...newIsFixed ? newPlaceholderStyles : {}
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
core$1.useEventListener(containerRef, "scroll", () => {
|
|
134
|
+
emit("scroll");
|
|
135
|
+
updatePosition();
|
|
136
|
+
});
|
|
137
|
+
core$1.useEventListener(containerRef, "resize", updatePosition);
|
|
138
|
+
vue.watchPostEffect(updatePosition);
|
|
139
|
+
return {
|
|
140
|
+
className,
|
|
141
|
+
wrapperRef,
|
|
142
|
+
containerRef,
|
|
143
|
+
isFixed,
|
|
144
|
+
placeholderStyle,
|
|
145
|
+
fixedStyle,
|
|
146
|
+
updatePosition
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
function provideAffixTarget(target) {
|
|
151
|
+
vue.provide(AFFIX_TARGET_KEY, target);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const HiAffixTarget = vue.defineComponent({
|
|
155
|
+
name: "HiAffixTarget",
|
|
156
|
+
setup(_, context) {
|
|
157
|
+
const targetRef = vue.ref(null);
|
|
158
|
+
provideAffixTarget(targetRef);
|
|
159
|
+
return () => vue.h("div", {
|
|
160
|
+
ref: targetRef,
|
|
161
|
+
...context.attrs
|
|
162
|
+
}, vue.renderSlot(context.slots, "default"));
|
|
28
163
|
}
|
|
29
164
|
});
|
|
30
165
|
|
|
@@ -366,7 +501,7 @@ const HiTabs = vue.defineComponent({
|
|
|
366
501
|
let component = selection.renderItem();
|
|
367
502
|
if (props.keepAlive) {
|
|
368
503
|
component = vue.h(vue.KeepAlive, {
|
|
369
|
-
...typeof props.keepAlive
|
|
504
|
+
...typeof props.keepAlive === "object" ? props.keepAlive : {}
|
|
370
505
|
}, component);
|
|
371
506
|
}
|
|
372
507
|
if (context.slots.content) {
|
|
@@ -402,9 +537,6 @@ const itemProps = shared.defineHookProps({
|
|
|
402
537
|
type: Boolean,
|
|
403
538
|
default: () => true
|
|
404
539
|
},
|
|
405
|
-
key: {
|
|
406
|
-
type: [String, Number, Symbol]
|
|
407
|
-
},
|
|
408
540
|
activateEvent: {
|
|
409
541
|
type: String
|
|
410
542
|
},
|
|
@@ -429,7 +561,7 @@ const useSelectionItem = shared.defineHookComponent({
|
|
|
429
561
|
};
|
|
430
562
|
const label = vue.computed(() => {
|
|
431
563
|
let label2 = props.label ?? context.label;
|
|
432
|
-
if (label2 && typeof label2
|
|
564
|
+
if (label2 && typeof label2 === "function") {
|
|
433
565
|
label2 = label2(props.value);
|
|
434
566
|
}
|
|
435
567
|
return Array.isArray(label2) ? label2 : [label2];
|
|
@@ -450,7 +582,7 @@ const useSelectionItem = shared.defineHookComponent({
|
|
|
450
582
|
remove();
|
|
451
583
|
remove = init({
|
|
452
584
|
id: Math.random().toString(16).slice(2),
|
|
453
|
-
label: typeof props.label
|
|
585
|
+
label: typeof props.label === "string" ? props.label : void 0,
|
|
454
586
|
value,
|
|
455
587
|
render
|
|
456
588
|
});
|
|
@@ -491,15 +623,11 @@ const HiTabPane = vue.defineComponent({
|
|
|
491
623
|
setup(props, context) {
|
|
492
624
|
const { className, activateEvent, activate, isDisabled, label } = useSelectionItem(props, context);
|
|
493
625
|
return () => {
|
|
494
|
-
return vue.h(
|
|
495
|
-
|
|
496
|
-
{
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
disabled: isDisabled.value
|
|
500
|
-
},
|
|
501
|
-
label.value
|
|
502
|
-
);
|
|
626
|
+
return vue.h("div", {
|
|
627
|
+
class: className.value,
|
|
628
|
+
[`on${tslx.capitalize(activateEvent.value)}`]: activate,
|
|
629
|
+
disabled: isDisabled.value
|
|
630
|
+
}, label.value);
|
|
503
631
|
};
|
|
504
632
|
}
|
|
505
633
|
});
|
|
@@ -549,6 +677,7 @@ const HiPopover = vue.defineComponent({
|
|
|
549
677
|
const components = {
|
|
550
678
|
__proto__: null,
|
|
551
679
|
HiAffix: HiAffix,
|
|
680
|
+
HiAffixTarget: HiAffixTarget,
|
|
552
681
|
HiConfigProvider: HiConfigProvider,
|
|
553
682
|
HiIcon: HiIcon,
|
|
554
683
|
HiItem: HiItem,
|
|
@@ -559,13 +688,14 @@ const components = {
|
|
|
559
688
|
HiTabs: HiTabs
|
|
560
689
|
};
|
|
561
690
|
|
|
562
|
-
|
|
691
|
+
function install(app) {
|
|
563
692
|
for (const key in components) {
|
|
564
693
|
app.component(key, components[key]);
|
|
565
694
|
}
|
|
566
|
-
}
|
|
695
|
+
}
|
|
567
696
|
|
|
568
697
|
exports.HiAffix = HiAffix;
|
|
698
|
+
exports.HiAffixTarget = HiAffixTarget;
|
|
569
699
|
exports.HiConfigProvider = HiConfigProvider;
|
|
570
700
|
exports.HiIcon = HiIcon;
|
|
571
701
|
exports.HiItem = HiItem;
|
package/dist/index.d.cts
CHANGED
|
@@ -62,6 +62,10 @@ declare const HiAffix: vue.DefineComponent<{
|
|
|
62
62
|
as: string;
|
|
63
63
|
}, {}>;
|
|
64
64
|
|
|
65
|
+
declare const HiAffixTarget: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{}>>, {}, {}>;
|
|
68
|
+
|
|
65
69
|
declare const HiSelection: vue.DefineComponent<{
|
|
66
70
|
as: {
|
|
67
71
|
type: StringConstructor;
|
|
@@ -182,9 +186,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
182
186
|
type: BooleanConstructor;
|
|
183
187
|
default: () => true;
|
|
184
188
|
};
|
|
185
|
-
key: {
|
|
186
|
-
type: vue.PropType<string | number | symbol>;
|
|
187
|
-
};
|
|
188
189
|
activateEvent: {
|
|
189
190
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
190
191
|
};
|
|
@@ -210,9 +211,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
210
211
|
type: BooleanConstructor;
|
|
211
212
|
default: () => true;
|
|
212
213
|
};
|
|
213
|
-
key: {
|
|
214
|
-
type: vue.PropType<string | number | symbol>;
|
|
215
|
-
};
|
|
216
214
|
activateEvent: {
|
|
217
215
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
218
216
|
};
|
|
@@ -536,9 +534,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
536
534
|
type: BooleanConstructor;
|
|
537
535
|
default: () => true;
|
|
538
536
|
};
|
|
539
|
-
key: {
|
|
540
|
-
type: vue.PropType<string | number | symbol>;
|
|
541
|
-
};
|
|
542
537
|
activateEvent: {
|
|
543
538
|
type: vue.PropType<ActivateEvent>;
|
|
544
539
|
};
|
|
@@ -560,9 +555,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
560
555
|
type: BooleanConstructor;
|
|
561
556
|
default: () => true;
|
|
562
557
|
};
|
|
563
|
-
key: {
|
|
564
|
-
type: vue.PropType<string | number | symbol>;
|
|
565
|
-
};
|
|
566
558
|
activateEvent: {
|
|
567
559
|
type: vue.PropType<ActivateEvent>;
|
|
568
560
|
};
|
|
@@ -666,6 +658,6 @@ declare const HiPopover: vue.DefineComponent<{
|
|
|
666
658
|
as: string;
|
|
667
659
|
}, {}>;
|
|
668
660
|
|
|
669
|
-
declare
|
|
661
|
+
declare function install(app: App): void;
|
|
670
662
|
|
|
671
|
-
export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
|
663
|
+
export { HiAffix, HiAffixTarget, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
package/dist/index.d.mts
CHANGED
|
@@ -62,6 +62,10 @@ declare const HiAffix: vue.DefineComponent<{
|
|
|
62
62
|
as: string;
|
|
63
63
|
}, {}>;
|
|
64
64
|
|
|
65
|
+
declare const HiAffixTarget: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{}>>, {}, {}>;
|
|
68
|
+
|
|
65
69
|
declare const HiSelection: vue.DefineComponent<{
|
|
66
70
|
as: {
|
|
67
71
|
type: StringConstructor;
|
|
@@ -182,9 +186,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
182
186
|
type: BooleanConstructor;
|
|
183
187
|
default: () => true;
|
|
184
188
|
};
|
|
185
|
-
key: {
|
|
186
|
-
type: vue.PropType<string | number | symbol>;
|
|
187
|
-
};
|
|
188
189
|
activateEvent: {
|
|
189
190
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
190
191
|
};
|
|
@@ -210,9 +211,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
210
211
|
type: BooleanConstructor;
|
|
211
212
|
default: () => true;
|
|
212
213
|
};
|
|
213
|
-
key: {
|
|
214
|
-
type: vue.PropType<string | number | symbol>;
|
|
215
|
-
};
|
|
216
214
|
activateEvent: {
|
|
217
215
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
218
216
|
};
|
|
@@ -536,9 +534,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
536
534
|
type: BooleanConstructor;
|
|
537
535
|
default: () => true;
|
|
538
536
|
};
|
|
539
|
-
key: {
|
|
540
|
-
type: vue.PropType<string | number | symbol>;
|
|
541
|
-
};
|
|
542
537
|
activateEvent: {
|
|
543
538
|
type: vue.PropType<ActivateEvent>;
|
|
544
539
|
};
|
|
@@ -560,9 +555,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
560
555
|
type: BooleanConstructor;
|
|
561
556
|
default: () => true;
|
|
562
557
|
};
|
|
563
|
-
key: {
|
|
564
|
-
type: vue.PropType<string | number | symbol>;
|
|
565
|
-
};
|
|
566
558
|
activateEvent: {
|
|
567
559
|
type: vue.PropType<ActivateEvent>;
|
|
568
560
|
};
|
|
@@ -666,6 +658,6 @@ declare const HiPopover: vue.DefineComponent<{
|
|
|
666
658
|
as: string;
|
|
667
659
|
}, {}>;
|
|
668
660
|
|
|
669
|
-
declare
|
|
661
|
+
declare function install(app: App): void;
|
|
670
662
|
|
|
671
|
-
export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
|
663
|
+
export { HiAffix, HiAffixTarget, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,10 @@ declare const HiAffix: vue.DefineComponent<{
|
|
|
62
62
|
as: string;
|
|
63
63
|
}, {}>;
|
|
64
64
|
|
|
65
|
+
declare const HiAffixTarget: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{}>>, {}, {}>;
|
|
68
|
+
|
|
65
69
|
declare const HiSelection: vue.DefineComponent<{
|
|
66
70
|
as: {
|
|
67
71
|
type: StringConstructor;
|
|
@@ -182,9 +186,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
182
186
|
type: BooleanConstructor;
|
|
183
187
|
default: () => true;
|
|
184
188
|
};
|
|
185
|
-
key: {
|
|
186
|
-
type: vue.PropType<string | number | symbol>;
|
|
187
|
-
};
|
|
188
189
|
activateEvent: {
|
|
189
190
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
190
191
|
};
|
|
@@ -210,9 +211,6 @@ declare const HiItem: vue.DefineComponent<{
|
|
|
210
211
|
type: BooleanConstructor;
|
|
211
212
|
default: () => true;
|
|
212
213
|
};
|
|
213
|
-
key: {
|
|
214
|
-
type: vue.PropType<string | number | symbol>;
|
|
215
|
-
};
|
|
216
214
|
activateEvent: {
|
|
217
215
|
type: vue.PropType<_hoci_core.ActivateEvent>;
|
|
218
216
|
};
|
|
@@ -536,9 +534,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
536
534
|
type: BooleanConstructor;
|
|
537
535
|
default: () => true;
|
|
538
536
|
};
|
|
539
|
-
key: {
|
|
540
|
-
type: vue.PropType<string | number | symbol>;
|
|
541
|
-
};
|
|
542
537
|
activateEvent: {
|
|
543
538
|
type: vue.PropType<ActivateEvent>;
|
|
544
539
|
};
|
|
@@ -560,9 +555,6 @@ declare const HiTabPane: vue.DefineComponent<{
|
|
|
560
555
|
type: BooleanConstructor;
|
|
561
556
|
default: () => true;
|
|
562
557
|
};
|
|
563
|
-
key: {
|
|
564
|
-
type: vue.PropType<string | number | symbol>;
|
|
565
|
-
};
|
|
566
558
|
activateEvent: {
|
|
567
559
|
type: vue.PropType<ActivateEvent>;
|
|
568
560
|
};
|
|
@@ -666,6 +658,6 @@ declare const HiPopover: vue.DefineComponent<{
|
|
|
666
658
|
as: string;
|
|
667
659
|
}, {}>;
|
|
668
660
|
|
|
669
|
-
declare
|
|
661
|
+
declare function install(app: App): void;
|
|
670
662
|
|
|
671
|
-
export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
|
663
|
+
export { HiAffix, HiAffixTarget, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { defineComponent, h, renderSlot,
|
|
2
|
-
import { affixProps, useAffix, selectionProps as selectionProps$1, selectionEmits as selectionEmits$1, useSelectionList as useSelectionList$1, itemProps as itemProps$1, itemEmits as itemEmits$1, useSelectionItem as useSelectionItem$1, iconProps, useIcon, switchProps, switchEmits, useSwitch, configProviderProps, provideSharedConfig, popoverProps, popoverEmits, usePopover } from '@hoci/core';
|
|
3
|
-
import {
|
|
4
|
-
import { defineHookProps,
|
|
5
|
-
import {
|
|
1
|
+
import { defineComponent, h, renderSlot, ref, inject, computed, watchPostEffect, provide, reactive, KeepAlive, watch, Teleport } from 'vue';
|
|
2
|
+
import { affixProps as affixProps$1, useAffix, selectionProps as selectionProps$1, selectionEmits as selectionEmits$1, useSelectionList as useSelectionList$1, itemProps as itemProps$1, itemEmits as itemEmits$1, useSelectionItem as useSelectionItem$1, iconProps, useIcon, switchProps, switchEmits, useSwitch, configProviderProps, provideSharedConfig, popoverProps, popoverEmits, usePopover } from '@hoci/core';
|
|
3
|
+
import { useElementBounding, useElementVisibility, useEventListener, syncRef, isDefined, tryOnScopeDispose } from '@vueuse/core';
|
|
4
|
+
import { defineHookProps, defineHookEmits, defineHookComponent, toReactive, useElement, throttleByRaf, isWindow, valuePropType, classPropType, labelPropType, useSharedConfig, getFirstChilld } from '@hoci/shared';
|
|
5
|
+
import { px, capitalize, cls } from 'tslx';
|
|
6
6
|
|
|
7
7
|
const HiAffix = defineComponent({
|
|
8
8
|
name: "HiAffix",
|
|
9
9
|
props: {
|
|
10
|
-
...affixProps,
|
|
10
|
+
...affixProps$1,
|
|
11
11
|
as: {
|
|
12
12
|
type: String,
|
|
13
13
|
default: "div"
|
|
@@ -15,14 +15,149 @@ const HiAffix = defineComponent({
|
|
|
15
15
|
},
|
|
16
16
|
setup(props, context) {
|
|
17
17
|
const { className, wrapperRef, isFixed, placeholderStyle, fixedStyle } = useAffix(props, context);
|
|
18
|
-
return () => h(
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
return () => h(props.as, { ref: wrapperRef }, [
|
|
19
|
+
isFixed.value && h("div", { style: placeholderStyle.value }),
|
|
20
|
+
h("div", { class: className.value, style: fixedStyle.value }, renderSlot(context.slots, "default"))
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const affixProps = defineHookProps(
|
|
26
|
+
{
|
|
27
|
+
fixedClass: {
|
|
28
|
+
type: String,
|
|
29
|
+
default: ""
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* @zh 距离窗口顶部达到指定偏移量后触发
|
|
33
|
+
* @en Triggered when the specified offset is reached from the top of the window
|
|
34
|
+
*/
|
|
35
|
+
offset: {
|
|
36
|
+
type: Number,
|
|
37
|
+
default: 0
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* @zh 固定的相对方向
|
|
41
|
+
*/
|
|
42
|
+
position: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: "top"
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* @zh 滚动容器,默认是 `window`
|
|
48
|
+
* @en Scroll container, default is `window`
|
|
49
|
+
*/
|
|
50
|
+
target: {
|
|
51
|
+
type: [String, Object, Function]
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* @zh z-index 值
|
|
55
|
+
* @en Z index value
|
|
56
|
+
*/
|
|
57
|
+
zIndex: {
|
|
58
|
+
type: Number,
|
|
59
|
+
default: 998
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
defineHookEmits(["scroll", "change"]);
|
|
64
|
+
const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
|
|
65
|
+
function getTargetRect(target) {
|
|
66
|
+
return isWindow(target) ? {
|
|
67
|
+
top: 0,
|
|
68
|
+
bottom: window.innerHeight
|
|
69
|
+
} : target.getBoundingClientRect();
|
|
70
|
+
}
|
|
71
|
+
defineHookComponent({
|
|
72
|
+
props: affixProps,
|
|
73
|
+
setup(props, { emit }) {
|
|
74
|
+
const wrapperRef = ref(null);
|
|
75
|
+
const wrapperRect = toReactive(useElementBounding(wrapperRef));
|
|
76
|
+
const parentRef = inject(AFFIX_TARGET_KEY, void 0);
|
|
77
|
+
const targetRef = useElement(props.target, parentRef);
|
|
78
|
+
const isFixed = ref(false);
|
|
79
|
+
const placeholderStyle = ref({});
|
|
80
|
+
const fixedStyle = ref({});
|
|
81
|
+
const className = computed(() => {
|
|
82
|
+
return isFixed.value ? props.fixedClass : "";
|
|
83
|
+
});
|
|
84
|
+
const wrapperVisible = useElementVisibility(wrapperRef);
|
|
85
|
+
const containerRef = computed(() => {
|
|
86
|
+
if (!wrapperVisible.value) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return targetRef.value ?? window;
|
|
90
|
+
});
|
|
91
|
+
const updatePosition = throttleByRaf(async () => {
|
|
92
|
+
if (!wrapperRef.value || !containerRef.value) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const area = wrapperRect.width * wrapperRect.height;
|
|
96
|
+
if (area === 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const newPlaceholderStyles = {
|
|
100
|
+
width: px(wrapperRect.width),
|
|
101
|
+
height: px(wrapperRect.height)
|
|
102
|
+
};
|
|
103
|
+
const targetRect = getTargetRect(containerRef.value);
|
|
104
|
+
let newIsFixed = false;
|
|
105
|
+
let newFixedStyles = {};
|
|
106
|
+
const offset = props.offset;
|
|
107
|
+
if (props.position === "top") {
|
|
108
|
+
newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
|
|
109
|
+
newFixedStyles = newIsFixed ? {
|
|
110
|
+
position: "fixed",
|
|
111
|
+
zIndex: props.zIndex,
|
|
112
|
+
top: px(targetRect.top + offset)
|
|
113
|
+
} : {};
|
|
114
|
+
} else {
|
|
115
|
+
newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
|
|
116
|
+
newFixedStyles = newIsFixed ? {
|
|
117
|
+
position: "fixed",
|
|
118
|
+
bottom: px(window.innerHeight - targetRect.bottom + offset)
|
|
119
|
+
} : {};
|
|
120
|
+
}
|
|
121
|
+
if (newIsFixed !== isFixed.value) {
|
|
122
|
+
isFixed.value = newIsFixed;
|
|
123
|
+
emit("change", newIsFixed);
|
|
124
|
+
}
|
|
125
|
+
placeholderStyle.value = newPlaceholderStyles;
|
|
126
|
+
fixedStyle.value = {
|
|
127
|
+
...newFixedStyles,
|
|
128
|
+
...newIsFixed ? newPlaceholderStyles : {}
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
useEventListener(containerRef, "scroll", () => {
|
|
132
|
+
emit("scroll");
|
|
133
|
+
updatePosition();
|
|
134
|
+
});
|
|
135
|
+
useEventListener(containerRef, "resize", updatePosition);
|
|
136
|
+
watchPostEffect(updatePosition);
|
|
137
|
+
return {
|
|
138
|
+
className,
|
|
139
|
+
wrapperRef,
|
|
140
|
+
containerRef,
|
|
141
|
+
isFixed,
|
|
142
|
+
placeholderStyle,
|
|
143
|
+
fixedStyle,
|
|
144
|
+
updatePosition
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
function provideAffixTarget(target) {
|
|
149
|
+
provide(AFFIX_TARGET_KEY, target);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const HiAffixTarget = defineComponent({
|
|
153
|
+
name: "HiAffixTarget",
|
|
154
|
+
setup(_, context) {
|
|
155
|
+
const targetRef = ref(null);
|
|
156
|
+
provideAffixTarget(targetRef);
|
|
157
|
+
return () => h("div", {
|
|
158
|
+
ref: targetRef,
|
|
159
|
+
...context.attrs
|
|
160
|
+
}, renderSlot(context.slots, "default"));
|
|
26
161
|
}
|
|
27
162
|
});
|
|
28
163
|
|
|
@@ -364,7 +499,7 @@ const HiTabs = defineComponent({
|
|
|
364
499
|
let component = selection.renderItem();
|
|
365
500
|
if (props.keepAlive) {
|
|
366
501
|
component = h(KeepAlive, {
|
|
367
|
-
...typeof props.keepAlive
|
|
502
|
+
...typeof props.keepAlive === "object" ? props.keepAlive : {}
|
|
368
503
|
}, component);
|
|
369
504
|
}
|
|
370
505
|
if (context.slots.content) {
|
|
@@ -400,9 +535,6 @@ const itemProps = defineHookProps({
|
|
|
400
535
|
type: Boolean,
|
|
401
536
|
default: () => true
|
|
402
537
|
},
|
|
403
|
-
key: {
|
|
404
|
-
type: [String, Number, Symbol]
|
|
405
|
-
},
|
|
406
538
|
activateEvent: {
|
|
407
539
|
type: String
|
|
408
540
|
},
|
|
@@ -427,7 +559,7 @@ const useSelectionItem = defineHookComponent({
|
|
|
427
559
|
};
|
|
428
560
|
const label = computed(() => {
|
|
429
561
|
let label2 = props.label ?? context.label;
|
|
430
|
-
if (label2 && typeof label2
|
|
562
|
+
if (label2 && typeof label2 === "function") {
|
|
431
563
|
label2 = label2(props.value);
|
|
432
564
|
}
|
|
433
565
|
return Array.isArray(label2) ? label2 : [label2];
|
|
@@ -448,7 +580,7 @@ const useSelectionItem = defineHookComponent({
|
|
|
448
580
|
remove();
|
|
449
581
|
remove = init({
|
|
450
582
|
id: Math.random().toString(16).slice(2),
|
|
451
|
-
label: typeof props.label
|
|
583
|
+
label: typeof props.label === "string" ? props.label : void 0,
|
|
452
584
|
value,
|
|
453
585
|
render
|
|
454
586
|
});
|
|
@@ -489,15 +621,11 @@ const HiTabPane = defineComponent({
|
|
|
489
621
|
setup(props, context) {
|
|
490
622
|
const { className, activateEvent, activate, isDisabled, label } = useSelectionItem(props, context);
|
|
491
623
|
return () => {
|
|
492
|
-
return h(
|
|
493
|
-
|
|
494
|
-
{
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
disabled: isDisabled.value
|
|
498
|
-
},
|
|
499
|
-
label.value
|
|
500
|
-
);
|
|
624
|
+
return h("div", {
|
|
625
|
+
class: className.value,
|
|
626
|
+
[`on${capitalize(activateEvent.value)}`]: activate,
|
|
627
|
+
disabled: isDisabled.value
|
|
628
|
+
}, label.value);
|
|
501
629
|
};
|
|
502
630
|
}
|
|
503
631
|
});
|
|
@@ -547,6 +675,7 @@ const HiPopover = defineComponent({
|
|
|
547
675
|
const components = {
|
|
548
676
|
__proto__: null,
|
|
549
677
|
HiAffix: HiAffix,
|
|
678
|
+
HiAffixTarget: HiAffixTarget,
|
|
550
679
|
HiConfigProvider: HiConfigProvider,
|
|
551
680
|
HiIcon: HiIcon,
|
|
552
681
|
HiItem: HiItem,
|
|
@@ -557,10 +686,10 @@ const components = {
|
|
|
557
686
|
HiTabs: HiTabs
|
|
558
687
|
};
|
|
559
688
|
|
|
560
|
-
|
|
689
|
+
function install(app) {
|
|
561
690
|
for (const key in components) {
|
|
562
691
|
app.component(key, components[key]);
|
|
563
692
|
}
|
|
564
|
-
}
|
|
693
|
+
}
|
|
565
694
|
|
|
566
|
-
export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
|
695
|
+
export { HiAffix, HiAffixTarget, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoci/components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Chizuki <chizukicn@outlook.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
18
|
},
|
|
19
19
|
"./*": "./dist/*"
|
|
20
20
|
},
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"maybe-types": "^0.2.0",
|
|
33
33
|
"tslx": "^0.1.1",
|
|
34
|
-
"@hoci/core": "0.5.
|
|
35
|
-
"@hoci/shared": "0.5.
|
|
34
|
+
"@hoci/core": "0.5.9",
|
|
35
|
+
"@hoci/shared": "0.5.9"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "unbuild",
|