@hoci/components 0.5.7 → 0.5.8

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 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",
@@ -28,6 +28,145 @@ const HiAffix = vue.defineComponent({
28
28
  }
29
29
  });
30
30
 
31
+ const affixProps = shared.defineHookProps(
32
+ {
33
+ fixedClass: {
34
+ type: String,
35
+ default: ""
36
+ },
37
+ /**
38
+ * @zh 距离窗口顶部达到指定偏移量后触发
39
+ * @en Triggered when the specified offset is reached from the top of the window
40
+ */
41
+ offset: {
42
+ type: Number,
43
+ default: 0
44
+ },
45
+ /**
46
+ * @zh 固定的相对方向
47
+ */
48
+ position: {
49
+ type: String,
50
+ default: "top"
51
+ },
52
+ /**
53
+ * @zh 滚动容器,默认是 `window`
54
+ * @en Scroll container, default is `window`
55
+ */
56
+ target: {
57
+ type: [String, Object, Function]
58
+ },
59
+ /**
60
+ * @zh z-index 值
61
+ * @en Z index value
62
+ */
63
+ zIndex: {
64
+ type: Number,
65
+ default: 998
66
+ }
67
+ }
68
+ );
69
+ shared.defineHookEmits(["scroll", "change"]);
70
+ const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
71
+ function getTargetRect(target) {
72
+ return shared.isWindow(target) ? {
73
+ top: 0,
74
+ bottom: window.innerHeight
75
+ } : target.getBoundingClientRect();
76
+ }
77
+ shared.defineHookComponent({
78
+ props: affixProps,
79
+ setup(props, { emit }) {
80
+ const wrapperRef = vue.ref(null);
81
+ const wrapperRect = shared.toReactive(core$1.useElementBounding(wrapperRef));
82
+ const parentRef = vue.inject(AFFIX_TARGET_KEY, void 0);
83
+ const targetRef = shared.useElement(props.target, parentRef);
84
+ const isFixed = vue.ref(false);
85
+ const placeholderStyle = vue.ref({});
86
+ const fixedStyle = vue.ref({});
87
+ const className = vue.computed(() => {
88
+ return isFixed.value ? props.fixedClass : "";
89
+ });
90
+ const wrapperVisible = core$1.useElementVisibility(wrapperRef);
91
+ const containerRef = vue.computed(() => {
92
+ if (!wrapperVisible.value) {
93
+ return null;
94
+ }
95
+ return targetRef.value ?? window;
96
+ });
97
+ const updatePosition = shared.throttleByRaf(async () => {
98
+ if (!wrapperRef.value || !containerRef.value) {
99
+ return;
100
+ }
101
+ const area = wrapperRect.width * wrapperRect.height;
102
+ if (area === 0) {
103
+ return;
104
+ }
105
+ const newPlaceholderStyles = {
106
+ width: tslx.px(wrapperRect.width),
107
+ height: tslx.px(wrapperRect.height)
108
+ };
109
+ const targetRect = getTargetRect(containerRef.value);
110
+ let newIsFixed = false;
111
+ let newFixedStyles = {};
112
+ const offset = props.offset;
113
+ if (props.position === "top") {
114
+ newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
115
+ newFixedStyles = newIsFixed ? {
116
+ position: "fixed",
117
+ zIndex: props.zIndex,
118
+ top: tslx.px(targetRect.top + offset)
119
+ } : {};
120
+ } else {
121
+ newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
122
+ newFixedStyles = newIsFixed ? {
123
+ position: "fixed",
124
+ bottom: tslx.px(window.innerHeight - targetRect.bottom + offset)
125
+ } : {};
126
+ }
127
+ if (newIsFixed !== isFixed.value) {
128
+ isFixed.value = newIsFixed;
129
+ emit("change", newIsFixed);
130
+ }
131
+ placeholderStyle.value = newPlaceholderStyles;
132
+ fixedStyle.value = {
133
+ ...newFixedStyles,
134
+ ...newIsFixed ? newPlaceholderStyles : {}
135
+ };
136
+ });
137
+ core$1.useEventListener(containerRef, "scroll", () => {
138
+ emit("scroll");
139
+ updatePosition();
140
+ });
141
+ core$1.useEventListener(containerRef, "resize", updatePosition);
142
+ vue.watchPostEffect(updatePosition);
143
+ return {
144
+ className,
145
+ wrapperRef,
146
+ containerRef,
147
+ isFixed,
148
+ placeholderStyle,
149
+ fixedStyle,
150
+ updatePosition
151
+ };
152
+ }
153
+ });
154
+ function provideAffixTarget(target) {
155
+ vue.provide(AFFIX_TARGET_KEY, target);
156
+ }
157
+
158
+ const HiAffixTarget = vue.defineComponent({
159
+ name: "HiAffixTarget",
160
+ setup(_, context) {
161
+ const targetRef = vue.ref(null);
162
+ provideAffixTarget(targetRef);
163
+ return () => vue.h("div", {
164
+ ref: targetRef,
165
+ ...context.attrs
166
+ }, vue.renderSlot(context.slots, "default"));
167
+ }
168
+ });
169
+
31
170
  const HiSelection = vue.defineComponent({
32
171
  name: "HiSelection",
33
172
  props: {
@@ -549,6 +688,7 @@ const HiPopover = vue.defineComponent({
549
688
  const components = {
550
689
  __proto__: null,
551
690
  HiAffix: HiAffix,
691
+ HiAffixTarget: HiAffixTarget,
552
692
  HiConfigProvider: HiConfigProvider,
553
693
  HiIcon: HiIcon,
554
694
  HiItem: HiItem,
@@ -566,6 +706,7 @@ const install = (app) => {
566
706
  };
567
707
 
568
708
  exports.HiAffix = HiAffix;
709
+ exports.HiAffixTarget = HiAffixTarget;
569
710
  exports.HiConfigProvider = HiConfigProvider;
570
711
  exports.HiIcon = HiIcon;
571
712
  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;
@@ -668,4 +672,4 @@ declare const HiPopover: vue.DefineComponent<{
668
672
 
669
673
  declare const install: (app: App) => void;
670
674
 
671
- export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
675
+ 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;
@@ -668,4 +672,4 @@ declare const HiPopover: vue.DefineComponent<{
668
672
 
669
673
  declare const install: (app: App) => void;
670
674
 
671
- export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
675
+ 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;
@@ -668,4 +672,4 @@ declare const HiPopover: vue.DefineComponent<{
668
672
 
669
673
  declare const install: (app: App) => void;
670
674
 
671
- export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
675
+ 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, reactive, computed, provide, inject, KeepAlive, watch, Teleport } from 'vue';
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 { capitalize, cls } from 'tslx';
4
- import { defineHookProps, valuePropType, classPropType, labelPropType, defineHookEmits, defineHookComponent, useSharedConfig, toReactive, getFirstChilld } from '@hoci/shared';
5
- import { syncRef, isDefined, tryOnScopeDispose } from '@vueuse/core';
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"
@@ -26,6 +26,145 @@ const HiAffix = defineComponent({
26
26
  }
27
27
  });
28
28
 
29
+ const affixProps = defineHookProps(
30
+ {
31
+ fixedClass: {
32
+ type: String,
33
+ default: ""
34
+ },
35
+ /**
36
+ * @zh 距离窗口顶部达到指定偏移量后触发
37
+ * @en Triggered when the specified offset is reached from the top of the window
38
+ */
39
+ offset: {
40
+ type: Number,
41
+ default: 0
42
+ },
43
+ /**
44
+ * @zh 固定的相对方向
45
+ */
46
+ position: {
47
+ type: String,
48
+ default: "top"
49
+ },
50
+ /**
51
+ * @zh 滚动容器,默认是 `window`
52
+ * @en Scroll container, default is `window`
53
+ */
54
+ target: {
55
+ type: [String, Object, Function]
56
+ },
57
+ /**
58
+ * @zh z-index 值
59
+ * @en Z index value
60
+ */
61
+ zIndex: {
62
+ type: Number,
63
+ default: 998
64
+ }
65
+ }
66
+ );
67
+ defineHookEmits(["scroll", "change"]);
68
+ const AFFIX_TARGET_KEY = Symbol("AFFIX_TARGET_KEY");
69
+ function getTargetRect(target) {
70
+ return isWindow(target) ? {
71
+ top: 0,
72
+ bottom: window.innerHeight
73
+ } : target.getBoundingClientRect();
74
+ }
75
+ defineHookComponent({
76
+ props: affixProps,
77
+ setup(props, { emit }) {
78
+ const wrapperRef = ref(null);
79
+ const wrapperRect = toReactive(useElementBounding(wrapperRef));
80
+ const parentRef = inject(AFFIX_TARGET_KEY, void 0);
81
+ const targetRef = useElement(props.target, parentRef);
82
+ const isFixed = ref(false);
83
+ const placeholderStyle = ref({});
84
+ const fixedStyle = ref({});
85
+ const className = computed(() => {
86
+ return isFixed.value ? props.fixedClass : "";
87
+ });
88
+ const wrapperVisible = useElementVisibility(wrapperRef);
89
+ const containerRef = computed(() => {
90
+ if (!wrapperVisible.value) {
91
+ return null;
92
+ }
93
+ return targetRef.value ?? window;
94
+ });
95
+ const updatePosition = throttleByRaf(async () => {
96
+ if (!wrapperRef.value || !containerRef.value) {
97
+ return;
98
+ }
99
+ const area = wrapperRect.width * wrapperRect.height;
100
+ if (area === 0) {
101
+ return;
102
+ }
103
+ const newPlaceholderStyles = {
104
+ width: px(wrapperRect.width),
105
+ height: px(wrapperRect.height)
106
+ };
107
+ const targetRect = getTargetRect(containerRef.value);
108
+ let newIsFixed = false;
109
+ let newFixedStyles = {};
110
+ const offset = props.offset;
111
+ if (props.position === "top") {
112
+ newIsFixed = wrapperRect.top - targetRect.top < offset && offset >= 0;
113
+ newFixedStyles = newIsFixed ? {
114
+ position: "fixed",
115
+ zIndex: props.zIndex,
116
+ top: px(targetRect.top + offset)
117
+ } : {};
118
+ } else {
119
+ newIsFixed = targetRect.bottom - wrapperRect.bottom < offset;
120
+ newFixedStyles = newIsFixed ? {
121
+ position: "fixed",
122
+ bottom: px(window.innerHeight - targetRect.bottom + offset)
123
+ } : {};
124
+ }
125
+ if (newIsFixed !== isFixed.value) {
126
+ isFixed.value = newIsFixed;
127
+ emit("change", newIsFixed);
128
+ }
129
+ placeholderStyle.value = newPlaceholderStyles;
130
+ fixedStyle.value = {
131
+ ...newFixedStyles,
132
+ ...newIsFixed ? newPlaceholderStyles : {}
133
+ };
134
+ });
135
+ useEventListener(containerRef, "scroll", () => {
136
+ emit("scroll");
137
+ updatePosition();
138
+ });
139
+ useEventListener(containerRef, "resize", updatePosition);
140
+ watchPostEffect(updatePosition);
141
+ return {
142
+ className,
143
+ wrapperRef,
144
+ containerRef,
145
+ isFixed,
146
+ placeholderStyle,
147
+ fixedStyle,
148
+ updatePosition
149
+ };
150
+ }
151
+ });
152
+ function provideAffixTarget(target) {
153
+ provide(AFFIX_TARGET_KEY, target);
154
+ }
155
+
156
+ const HiAffixTarget = defineComponent({
157
+ name: "HiAffixTarget",
158
+ setup(_, context) {
159
+ const targetRef = ref(null);
160
+ provideAffixTarget(targetRef);
161
+ return () => h("div", {
162
+ ref: targetRef,
163
+ ...context.attrs
164
+ }, renderSlot(context.slots, "default"));
165
+ }
166
+ });
167
+
29
168
  const HiSelection = defineComponent({
30
169
  name: "HiSelection",
31
170
  props: {
@@ -547,6 +686,7 @@ const HiPopover = defineComponent({
547
686
  const components = {
548
687
  __proto__: null,
549
688
  HiAffix: HiAffix,
689
+ HiAffixTarget: HiAffixTarget,
550
690
  HiConfigProvider: HiConfigProvider,
551
691
  HiIcon: HiIcon,
552
692
  HiItem: HiItem,
@@ -563,4 +703,4 @@ const install = (app) => {
563
703
  }
564
704
  };
565
705
 
566
- export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
706
+ 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.7",
3
+ "version": "0.5.8",
4
4
  "description": "",
5
5
  "author": "Chizuki <chizukicn@outlook.com>",
6
6
  "license": "MIT",
@@ -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.7",
35
- "@hoci/shared": "0.5.7"
34
+ "@hoci/core": "0.5.8",
35
+ "@hoci/shared": "0.5.8"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "unbuild",