sard-uniapp 1.19.5 → 1.20.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/CHANGELOG.md +22 -0
- package/README.md +1 -1
- package/components/calendar/README.md +20 -20
- package/components/calendar/calendar.vue +1 -1
- package/components/calendar-input/README.md +10 -10
- package/components/calendar-input/calendar-input.vue +2 -2
- package/components/calendar-month/calendar-month.vue +17 -21
- package/components/calendar-popout/calendar-popout.vue +1 -1
- package/components/card/README.md +16 -8
- package/components/card/card.vue +7 -1
- package/components/card/common.d.ts +2 -0
- package/components/card/index.scss +30 -2
- package/components/card/variables.scss +16 -1
- package/components/checkbox/common.d.ts +1 -0
- package/components/checkbox/common.js +1 -0
- package/components/checkbox-input/checkbox-input.vue +9 -0
- package/components/checkbox-popout/README.md +27 -6
- package/components/checkbox-popout/checkbox-popout.vue +113 -47
- package/components/checkbox-popout/common.d.ts +3 -0
- package/components/checkbox-popout/index.scss +16 -0
- package/components/config/index.d.ts +6 -0
- package/components/config/index.js +6 -0
- package/components/datetime-picker/README.md +1 -71
- package/components/datetime-picker/common.d.ts +1 -0
- package/components/datetime-picker/common.js +21 -8
- package/components/datetime-picker/datetime-picker.vue +3 -3
- package/components/datetime-picker-input/README.md +10 -10
- package/components/datetime-picker-input/datetime-picker-input.vue +2 -2
- package/components/datetime-picker-popout/datetime-picker-popout.vue +1 -1
- package/components/datetime-range-picker/datetime-range-picker.vue +12 -10
- package/components/datetime-range-picker-input/README.md +10 -10
- package/components/datetime-range-picker-input/datetime-range-picker-input.vue +2 -2
- package/components/datetime-range-picker-popout/README.md +0 -6
- package/components/datetime-range-picker-popout/datetime-range-picker-popout.vue +11 -8
- package/components/floating-bubble/floating-bubble.vue +3 -3
- package/components/form/README.md +19 -19
- package/components/form/form.vue +1 -1
- package/components/icon/icon.d.ts +1 -1
- package/components/indexes/README.md +4 -0
- package/components/indexes-nav/indexes-nav.vue +2 -2
- package/components/keyboard/common.d.ts +1 -2
- package/components/keyboard/common.js +2 -11
- package/components/keyboard/keyboard.d.ts +2 -2
- package/components/list-item/index.scss +4 -0
- package/components/locale/lang/en-US.d.ts +4 -0
- package/components/locale/lang/en-US.js +4 -0
- package/components/locale/lang/zh-CN.d.ts +4 -0
- package/components/locale/lang/zh-CN.js +4 -0
- package/components/marquee/README.md +8 -2
- package/components/marquee/marquee.vue +9 -1
- package/components/notice-bar/README.md +8 -2
- package/components/notice-bar/notice-bar.vue +14 -8
- package/components/notify/notify.d.ts +1 -1
- package/components/notify-agent/notify-agent.d.ts +1 -1
- package/components/pagination/pagination.vue +2 -2
- package/components/popover/utils.js +4 -4
- package/components/pull-down-refresh/common.d.ts +1 -1
- package/components/radio/common.d.ts +1 -0
- package/components/radio/common.js +1 -0
- package/components/radio-input/radio-input.vue +6 -0
- package/components/radio-popout/README.md +20 -6
- package/components/radio-popout/common.d.ts +2 -0
- package/components/radio-popout/index.scss +4 -0
- package/components/radio-popout/radio-popout.vue +91 -45
- package/components/read-more/README.md +82 -0
- package/components/read-more/common.d.ts +24 -0
- package/components/read-more/common.js +2 -0
- package/components/read-more/index.d.ts +1 -0
- package/components/read-more/index.js +1 -0
- package/components/read-more/index.scss +41 -0
- package/components/read-more/read-more.d.ts +20 -0
- package/components/read-more/read-more.vue +168 -0
- package/components/read-more/variables.scss +12 -0
- package/components/resize-sensor/README.md +55 -0
- package/components/resize-sensor/common.d.ts +19 -0
- package/components/resize-sensor/common.js +2 -0
- package/components/resize-sensor/index.d.ts +1 -0
- package/components/resize-sensor/index.js +1 -0
- package/components/resize-sensor/index.scss +33 -0
- package/components/resize-sensor/resize-sensor.d.ts +16 -0
- package/components/resize-sensor/resize-sensor.vue +152 -0
- package/components/scroll-list/README.md +79 -0
- package/components/scroll-list/common.d.ts +23 -0
- package/components/scroll-list/common.js +1 -0
- package/components/scroll-list/index.d.ts +1 -0
- package/components/scroll-list/index.js +1 -0
- package/components/scroll-list/index.scss +35 -0
- package/components/scroll-list/scroll-list.d.ts +20 -0
- package/components/scroll-list/scroll-list.vue +158 -0
- package/components/scroll-list/variables.scss +11 -0
- package/components/sidebar/README.md +8 -8
- package/components/sidebar/sidebar.vue +1 -1
- package/components/slider/slider.vue +4 -4
- package/components/stepper/stepper.vue +2 -2
- package/components/sticky/README.md +92 -0
- package/components/sticky/common.d.ts +15 -0
- package/components/sticky/common.js +1 -0
- package/components/sticky/index.d.ts +1 -0
- package/components/sticky/index.js +1 -0
- package/components/sticky/index.scss +18 -0
- package/components/sticky/sticky.d.ts +10 -0
- package/components/sticky/sticky.vue +190 -0
- package/components/sticky-box/common.d.ts +19 -0
- package/components/sticky-box/common.js +1 -0
- package/components/sticky-box/index.d.ts +1 -0
- package/components/sticky-box/index.js +1 -0
- package/components/sticky-box/index.scss +19 -0
- package/components/sticky-box/sticky-box.d.ts +10 -0
- package/components/sticky-box/sticky-box.vue +82 -0
- package/components/style/mixins/border.scss +101 -38
- package/components/style/variables-dark.scss +4 -0
- package/components/style/variables.scss +8 -0
- package/components/table/table.vue +2 -1
- package/components/table-fixation/table-fixation.vue +2 -1
- package/components/toast/toast.d.ts +1 -1
- package/components/toast-agent/toast-agent.d.ts +1 -1
- package/components/tree/tree.d.ts +1 -1
- package/components/tree-node/tree-node.vue +2 -2
- package/components/upload/README.md +23 -15
- package/components/upload/common.d.ts +6 -4
- package/components/upload/upload.d.ts +2 -0
- package/components/upload/upload.vue +51 -13
- package/components/upload/utils.d.ts +1 -0
- package/components/upload/utils.js +2 -0
- package/components/upload-preview/index.scss +1 -0
- package/components/upload-preview/upload-preview.d.ts +6 -4
- package/components/upload-preview/upload-preview.vue +17 -24
- package/global.d.ts +5 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/index.scss +2 -0
- package/package.json +4 -2
- package/use/index.d.ts +4 -0
- package/use/index.js +4 -0
- package/use/useIndeterminate.d.ts +10 -0
- package/use/useIndeterminate.js +27 -0
- package/use/useIntersectionObserver.d.ts +16 -0
- package/use/useIntersectionObserver.js +52 -0
- package/use/useSimulatedClick.js +2 -2
- package/use/useSimulatedPress.js +2 -2
- package/use/useSingleTask.d.ts +6 -0
- package/use/useSingleTask.js +40 -0
- package/use/useWindowResize.d.ts +4 -0
- package/use/useWindowResize.js +15 -0
- package/utils/array.d.ts +28 -0
- package/utils/array.js +90 -0
- package/utils/common.d.ts +3 -0
- package/utils/common.js +1 -0
- package/utils/date.d.ts +84 -11
- package/utils/date.js +120 -63
- package/utils/dom.js +2 -0
- package/utils/geometry.d.ts +56 -38
- package/utils/geometry.js +56 -30
- package/utils/index.d.ts +8 -1
- package/utils/index.js +8 -1
- package/utils/is.d.ts +12 -0
- package/utils/is.js +16 -0
- package/utils/number.d.ts +24 -0
- package/utils/number.js +37 -0
- package/utils/object.d.ts +29 -0
- package/utils/object.js +139 -0
- package/utils/persist.d.ts +15 -0
- package/utils/persist.js +89 -0
- package/utils/physics.d.ts +34 -0
- package/utils/physics.js +66 -0
- package/utils/request.d.ts +227 -0
- package/utils/request.js +249 -0
- package/utils/router.d.ts +47 -0
- package/utils/router.js +115 -0
- package/utils/string.d.ts +46 -0
- package/utils/string.js +134 -0
- package/utils/url-query.d.ts +19 -0
- package/utils/url-query.js +95 -0
- package/utils/utils.d.ts +0 -166
- package/utils/utils.js +0 -441
- package/utils/case.d.ts +0 -4
- package/utils/case.js +0 -26
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: 组件
|
|
3
|
+
title: Sticky
|
|
4
|
+
subtitle: 粘性布局
|
|
5
|
+
group: 布局
|
|
6
|
+
version: 1.20+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 介绍
|
|
10
|
+
|
|
11
|
+
粘性布局组件,用于在页面滚动时将元素固定在指定位置。
|
|
12
|
+
|
|
13
|
+
css 的粘性定位有更好的性能和体验,如果能满足需求,则不需要使用 `Sticky` 组件。
|
|
14
|
+
|
|
15
|
+
`Sticky` 组件通常用于需要粘性定位的元素受父元素范围限制的情景,因为 `Sticky` 组件能跳脱父元素的范围限制。
|
|
16
|
+
|
|
17
|
+
@info
|
|
18
|
+
|
|
19
|
+
需在模拟器或移动设备上查看效果,因为 `uni.createIntersectionObserver` 在 pc 端获取的数据是不正确的。
|
|
20
|
+
|
|
21
|
+
@endinfo
|
|
22
|
+
|
|
23
|
+
## 引入
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import Sticky from 'sard-uniapp/components/sticky/sticky.vue'
|
|
27
|
+
import StickyBox from 'sard-uniapp/components/sticky-box/sticky-box.vue'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 代码演示
|
|
31
|
+
|
|
32
|
+
### 吸顶
|
|
33
|
+
|
|
34
|
+
使用 `offset-top` 设置粘性定位元素距离视窗顶部的距离。
|
|
35
|
+
|
|
36
|
+
如果是自定义导航栏,则需要自行加上状态栏和导航栏的高度。
|
|
37
|
+
|
|
38
|
+
黏住视窗状态时使用的是 `fixed` 定位。
|
|
39
|
+
|
|
40
|
+
@code('${DEMO_PATH}/sticky/demo/OffsetTop.vue')
|
|
41
|
+
|
|
42
|
+
### 动态插入
|
|
43
|
+
|
|
44
|
+
即使是动态插入的数据,`Sticky` 组件也能重新计算其位置。
|
|
45
|
+
|
|
46
|
+
@code('${DEMO_PATH}/sticky/demo/Dynamic.vue')
|
|
47
|
+
|
|
48
|
+
### 吸底
|
|
49
|
+
|
|
50
|
+
使用 `offset-bottom` 设置粘性定位元素距离视窗底部的距离。
|
|
51
|
+
|
|
52
|
+
@code('${DEMO_PATH}/sticky/demo/OffsetBottom.vue')
|
|
53
|
+
|
|
54
|
+
### 吸顶和吸底
|
|
55
|
+
|
|
56
|
+
可以同时使用 `offset-top` 和 `offset-bottom` 设置粘性定位元素距离视窗顶部和底部的距离。
|
|
57
|
+
|
|
58
|
+
@code('${DEMO_PATH}/sticky/demo/OffsetTopBottom.vue')
|
|
59
|
+
|
|
60
|
+
### 容器中的吸顶
|
|
61
|
+
|
|
62
|
+
如果要将元素限制在某个范围之内,可以使用 `StickyBox` 组件包裹着 `Sticky` 组件。
|
|
63
|
+
|
|
64
|
+
黏住 `StickyBox` 组件状态时使用的是 `absolute` 定位,因此 `Sticky` 组件不能被其他含有响应其绝对定位于 `StickyBox` 的定位样式的元素包裹。
|
|
65
|
+
|
|
66
|
+
@code('${DEMO_PATH}/sticky/demo/BoxTop.vue')
|
|
67
|
+
|
|
68
|
+
### 容器中的吸底
|
|
69
|
+
|
|
70
|
+
@code('${DEMO_PATH}/sticky/demo/BoxBottom.vue')
|
|
71
|
+
|
|
72
|
+
### 容器中的吸顶和吸底
|
|
73
|
+
|
|
74
|
+
@code('${DEMO_PATH}/sticky/demo/BoxTopBottom.vue')
|
|
75
|
+
|
|
76
|
+
## API
|
|
77
|
+
|
|
78
|
+
### StickyProps
|
|
79
|
+
|
|
80
|
+
| 属性 | 描述 | 类型 | 默认值 |
|
|
81
|
+
| ------------- | ---------------- | ---------- | ------ |
|
|
82
|
+
| root-class | 组件根元素类名 | string | - |
|
|
83
|
+
| root-style | 组件根元素样式 | StyleValue | - |
|
|
84
|
+
| offset-top | 吸顶距离,单位px | number | - |
|
|
85
|
+
| offset-bottom | 吸底距离,单位px | number | - |
|
|
86
|
+
| z-index | 粘性元素的层级 | number | - |
|
|
87
|
+
|
|
88
|
+
### StickySlots
|
|
89
|
+
|
|
90
|
+
| 插槽 | 描述 | 属性 |
|
|
91
|
+
| ------- | -------------- | ---- |
|
|
92
|
+
| default | 自定义默认内容 | - |
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type StyleValue } from 'vue';
|
|
2
|
+
export interface StickyProps {
|
|
3
|
+
rootStyle?: StyleValue;
|
|
4
|
+
rootClass?: string;
|
|
5
|
+
offsetTop?: number;
|
|
6
|
+
offsetBottom?: number;
|
|
7
|
+
zIndex?: number | string;
|
|
8
|
+
}
|
|
9
|
+
export interface StickySlots {
|
|
10
|
+
default?(props: Record<string, never>): any;
|
|
11
|
+
}
|
|
12
|
+
export interface StickyEmits {
|
|
13
|
+
}
|
|
14
|
+
export interface StickyExpose {
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { StickyProps, StickySlots, StickyEmits, StickyExpose, } from './common';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@use '../style/base' as *;
|
|
2
|
+
|
|
3
|
+
@include bem(sticky) {
|
|
4
|
+
@include b() {
|
|
5
|
+
display: block;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
@include e(fixation) {
|
|
9
|
+
position: relative;
|
|
10
|
+
z-index: 1;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@include e(bound) {
|
|
14
|
+
position: absolute;
|
|
15
|
+
min-width: 1px;
|
|
16
|
+
min-height: 1px;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type StickyProps, type StickySlots } from './common';
|
|
2
|
+
declare function __VLS_template(): Readonly<StickySlots> & StickySlots;
|
|
3
|
+
declare const __VLS_component: import("vue").DefineComponent<StickyProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<StickyProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
4
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
5
|
+
export default _default;
|
|
6
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
7
|
+
new (): {
|
|
8
|
+
$slots: S;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view :class="stickyClass" :style="stickyStyle">
|
|
3
|
+
<view :class="observeClass" :style="observeStyle">
|
|
4
|
+
<view :class="fixationClass" :style="fixationStyle">
|
|
5
|
+
<view :class="boundClass" :style="boundStyle">
|
|
6
|
+
<slot></slot>
|
|
7
|
+
<sar-resize-sensor initial :threshold="0" @resize="onResize" />
|
|
8
|
+
</view>
|
|
9
|
+
</view>
|
|
10
|
+
</view>
|
|
11
|
+
</view>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import { defineComponent as _defineComponent } from "vue";
|
|
16
|
+
import {
|
|
17
|
+
computed,
|
|
18
|
+
inject,
|
|
19
|
+
onBeforeMount,
|
|
20
|
+
onUnmounted,
|
|
21
|
+
reactive,
|
|
22
|
+
ref,
|
|
23
|
+
toRef
|
|
24
|
+
} from "vue";
|
|
25
|
+
import {
|
|
26
|
+
classNames,
|
|
27
|
+
stringifyStyle,
|
|
28
|
+
createBem,
|
|
29
|
+
uniqid,
|
|
30
|
+
isNumber
|
|
31
|
+
} from "../../utils";
|
|
32
|
+
import { useIntersectionObserver } from "../../use";
|
|
33
|
+
import SarResizeSensor from "../resize-sensor/resize-sensor.vue";
|
|
34
|
+
import { stickyContextSymbol } from "../sticky-box/common";
|
|
35
|
+
/**
|
|
36
|
+
* @property {string} rootClass 组件根元素类名,默认值:-。
|
|
37
|
+
* @property {StyleValue} rootStyle 组件根元素样式,默认值:-。
|
|
38
|
+
* @property {number} offsetTop 吸顶距离,单位px,默认值:-。
|
|
39
|
+
* @property {number} offsetBottom 吸底距离,单位px,默认值:-。
|
|
40
|
+
* @property {number} zIndex 粘性元素的层级,默认值:-。
|
|
41
|
+
*/
|
|
42
|
+
export default _defineComponent({
|
|
43
|
+
components: {
|
|
44
|
+
SarResizeSensor,
|
|
45
|
+
},
|
|
46
|
+
...{
|
|
47
|
+
options: {
|
|
48
|
+
virtualHost: true,
|
|
49
|
+
styleIsolation: "shared"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
__name: "sticky",
|
|
53
|
+
props: {
|
|
54
|
+
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
55
|
+
rootClass: { type: String, required: false },
|
|
56
|
+
offsetTop: { type: Number, required: false },
|
|
57
|
+
offsetBottom: { type: Number, required: false },
|
|
58
|
+
zIndex: { type: [Number, String], required: false }
|
|
59
|
+
},
|
|
60
|
+
setup(__props, { expose: __expose }) {
|
|
61
|
+
const props = __props;
|
|
62
|
+
const bem = createBem("sticky");
|
|
63
|
+
const observeId = uniqid();
|
|
64
|
+
const positionStyle = reactive({
|
|
65
|
+
position: "relative",
|
|
66
|
+
top: "",
|
|
67
|
+
bottom: ""
|
|
68
|
+
});
|
|
69
|
+
const boundingBox = ref("none");
|
|
70
|
+
const width = ref(null);
|
|
71
|
+
const height = ref(null);
|
|
72
|
+
const context = inject(stickyContextSymbol, null);
|
|
73
|
+
const size = computed(() => {
|
|
74
|
+
return {
|
|
75
|
+
width: width.value !== null ? width.value + "px" : "",
|
|
76
|
+
height: height.value !== null ? height.value + "px" : ""
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
const { recreate } = useIntersectionObserver(
|
|
80
|
+
(res) => {
|
|
81
|
+
const { intersectionRatio, relativeRect, boundingClientRect } = res;
|
|
82
|
+
Object.assign(positionStyle, {
|
|
83
|
+
position: "relative",
|
|
84
|
+
top: "",
|
|
85
|
+
bottom: ""
|
|
86
|
+
});
|
|
87
|
+
if (intersectionRatio < 1) {
|
|
88
|
+
if (isNumber(props.offsetTop) && boundingClientRect.top < relativeRect.top) {
|
|
89
|
+
positionStyle.position = "fixed";
|
|
90
|
+
positionStyle.top = props.offsetTop + "px";
|
|
91
|
+
} else if (isNumber(props.offsetBottom) && boundingClientRect.bottom > relativeRect.bottom) {
|
|
92
|
+
positionStyle.position = "fixed";
|
|
93
|
+
positionStyle.bottom = props.offsetBottom + "px";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
selector: `.${observeId}`,
|
|
99
|
+
thresholds: [1],
|
|
100
|
+
offsetTop: toRef(() => props.offsetTop),
|
|
101
|
+
offsetBottom: toRef(() => props.offsetBottom)
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
let boxRecreate = null;
|
|
105
|
+
if (context) {
|
|
106
|
+
const { recreate: recreate2 } = useIntersectionObserver(
|
|
107
|
+
(res) => {
|
|
108
|
+
const { relativeRect, boundingClientRect } = res;
|
|
109
|
+
if (boundingClientRect.top > relativeRect.bottom) {
|
|
110
|
+
boundingBox.value = "top";
|
|
111
|
+
} else if (boundingClientRect.bottom < relativeRect.top) {
|
|
112
|
+
boundingBox.value = "bottom";
|
|
113
|
+
} else {
|
|
114
|
+
boundingBox.value = "none";
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
selector: `.${context.boxId}`,
|
|
119
|
+
thresholds: [0],
|
|
120
|
+
instance: context.instance,
|
|
121
|
+
offsetTop: toRef(() => (props.offsetTop || 0) + (height.value || 0)),
|
|
122
|
+
offsetBottom: toRef(
|
|
123
|
+
() => (props.offsetBottom || 0) + (height.value || 0)
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
boxRecreate = recreate2;
|
|
128
|
+
}
|
|
129
|
+
const onResize = (res) => {
|
|
130
|
+
width.value = res.width;
|
|
131
|
+
height.value = res.height;
|
|
132
|
+
recreate();
|
|
133
|
+
};
|
|
134
|
+
const onBoxResize = () => {
|
|
135
|
+
boxRecreate?.();
|
|
136
|
+
};
|
|
137
|
+
onBeforeMount(() => {
|
|
138
|
+
context?.onResize(onBoxResize);
|
|
139
|
+
});
|
|
140
|
+
onUnmounted(() => {
|
|
141
|
+
context?.offResize(onBoxResize);
|
|
142
|
+
});
|
|
143
|
+
__expose({});
|
|
144
|
+
const stickyClass = computed(() => {
|
|
145
|
+
return classNames(bem.b(), props.rootClass);
|
|
146
|
+
});
|
|
147
|
+
const stickyStyle = computed(() => {
|
|
148
|
+
return stringifyStyle(size.value, props.rootStyle);
|
|
149
|
+
});
|
|
150
|
+
const observeClass = computed(() => {
|
|
151
|
+
return classNames(bem.e("observe"), observeId);
|
|
152
|
+
});
|
|
153
|
+
const observeStyle = computed(() => {
|
|
154
|
+
return stringifyStyle(size.value);
|
|
155
|
+
});
|
|
156
|
+
const fixationClass = computed(() => {
|
|
157
|
+
return classNames(bem.e("fixation"));
|
|
158
|
+
});
|
|
159
|
+
const fixationStyle = computed(() => {
|
|
160
|
+
return stringifyStyle(
|
|
161
|
+
size.value,
|
|
162
|
+
{
|
|
163
|
+
zIndex: props.zIndex
|
|
164
|
+
},
|
|
165
|
+
boundingBox.value === "none" ? positionStyle : {
|
|
166
|
+
position: "absolute",
|
|
167
|
+
top: boundingBox.value === "top" ? 0 : "",
|
|
168
|
+
bottom: boundingBox.value === "bottom" ? 0 : ""
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
const boundClass = computed(() => {
|
|
173
|
+
return classNames(bem.e("bound"));
|
|
174
|
+
});
|
|
175
|
+
const boundStyle = computed(() => {
|
|
176
|
+
return stringifyStyle();
|
|
177
|
+
});
|
|
178
|
+
const __returned__ = { props, bem, observeId, positionStyle, boundingBox, width, height, context, size, recreate, get boxRecreate() {
|
|
179
|
+
return boxRecreate;
|
|
180
|
+
}, set boxRecreate(v) {
|
|
181
|
+
boxRecreate = v;
|
|
182
|
+
}, onResize, onBoxResize, stickyClass, stickyStyle, observeClass, observeStyle, fixationClass, fixationStyle, boundClass, boundStyle, SarResizeSensor };
|
|
183
|
+
return __returned__;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
</script>
|
|
187
|
+
|
|
188
|
+
<style lang="scss">
|
|
189
|
+
@import './index.scss';
|
|
190
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type NodeRect } from '../../utils';
|
|
2
|
+
import { type ComponentInternalInstance, type InjectionKey, type StyleValue } from 'vue';
|
|
3
|
+
export interface StickyBoxProps {
|
|
4
|
+
rootStyle?: StyleValue;
|
|
5
|
+
rootClass?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface StickyBoxSlots {
|
|
8
|
+
default?(props: Record<string, never>): any;
|
|
9
|
+
}
|
|
10
|
+
export interface StickyBoxEmits {
|
|
11
|
+
}
|
|
12
|
+
export interface StickyBoxExpose {
|
|
13
|
+
}
|
|
14
|
+
export declare const stickyContextSymbol: InjectionKey<{
|
|
15
|
+
boxId: string;
|
|
16
|
+
onResize: (callback: (res: NodeRect) => void) => void;
|
|
17
|
+
offResize: (callback: (res: NodeRect) => void) => void;
|
|
18
|
+
instance: ComponentInternalInstance;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const stickyContextSymbol = Symbol('sticky-context');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { StickyBoxProps, StickyBoxSlots, StickyBoxEmits, StickyBoxExpose, } from './common';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@use '../style/base' as *;
|
|
2
|
+
|
|
3
|
+
@include bem(sticky-box) {
|
|
4
|
+
@include b() {
|
|
5
|
+
position: relative;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@include e(observe) {
|
|
10
|
+
position: absolute;
|
|
11
|
+
top: 0;
|
|
12
|
+
right: 0;
|
|
13
|
+
bottom: 0;
|
|
14
|
+
left: 0;
|
|
15
|
+
z-index: -9999;
|
|
16
|
+
pointer-events: none;
|
|
17
|
+
visibility: hidden;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type StickyBoxProps, type StickyBoxSlots } from './common';
|
|
2
|
+
declare function __VLS_template(): Readonly<StickyBoxSlots> & StickyBoxSlots;
|
|
3
|
+
declare const __VLS_component: import("vue").DefineComponent<StickyBoxProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<StickyBoxProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
4
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
|
5
|
+
export default _default;
|
|
6
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
7
|
+
new (): {
|
|
8
|
+
$slots: S;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view :class="stickyBoxClass" :style="stickyBoxStyle">
|
|
3
|
+
<view :class="observeClass"></view>
|
|
4
|
+
<slot></slot>
|
|
5
|
+
<sar-resize-sensor initial :threshold="0" @resize="handleResize" />
|
|
6
|
+
</view>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { defineComponent as _defineComponent } from "vue";
|
|
11
|
+
import { computed, getCurrentInstance, provide } from "vue";
|
|
12
|
+
import {
|
|
13
|
+
classNames,
|
|
14
|
+
stringifyStyle,
|
|
15
|
+
createBem,
|
|
16
|
+
uniqid
|
|
17
|
+
} from "../../utils";
|
|
18
|
+
import {
|
|
19
|
+
stickyContextSymbol
|
|
20
|
+
} from "./common";
|
|
21
|
+
import SarResizeSensor from "../resize-sensor/resize-sensor.vue";
|
|
22
|
+
export default _defineComponent({
|
|
23
|
+
components: {
|
|
24
|
+
SarResizeSensor,
|
|
25
|
+
},
|
|
26
|
+
...{
|
|
27
|
+
options: {
|
|
28
|
+
virtualHost: true,
|
|
29
|
+
styleIsolation: "shared"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
__name: "sticky-box",
|
|
33
|
+
props: {
|
|
34
|
+
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
35
|
+
rootClass: { type: String, required: false }
|
|
36
|
+
},
|
|
37
|
+
setup(__props, { expose: __expose }) {
|
|
38
|
+
const props = __props;
|
|
39
|
+
const bem = createBem("sticky-box");
|
|
40
|
+
const boxId = uniqid();
|
|
41
|
+
const resizeHandlers = [];
|
|
42
|
+
const onResize = (handler) => {
|
|
43
|
+
const index = resizeHandlers.indexOf(handler);
|
|
44
|
+
if (index === -1) {
|
|
45
|
+
resizeHandlers.push(handler);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const offResize = (handler) => {
|
|
49
|
+
const index = resizeHandlers.indexOf(handler);
|
|
50
|
+
if (index !== -1) {
|
|
51
|
+
resizeHandlers.splice(index, 1);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const handleResize = (res) => {
|
|
55
|
+
resizeHandlers.forEach((handler) => handler(res));
|
|
56
|
+
};
|
|
57
|
+
const instance = getCurrentInstance();
|
|
58
|
+
provide(stickyContextSymbol, {
|
|
59
|
+
boxId,
|
|
60
|
+
onResize,
|
|
61
|
+
offResize,
|
|
62
|
+
instance
|
|
63
|
+
});
|
|
64
|
+
__expose({});
|
|
65
|
+
const stickyBoxClass = computed(() => {
|
|
66
|
+
return classNames(bem.b(), props.rootClass);
|
|
67
|
+
});
|
|
68
|
+
const stickyBoxStyle = computed(() => {
|
|
69
|
+
return stringifyStyle(props.rootStyle);
|
|
70
|
+
});
|
|
71
|
+
const observeClass = computed(() => {
|
|
72
|
+
return classNames(bem.e("observe"), boxId);
|
|
73
|
+
});
|
|
74
|
+
const __returned__ = { props, bem, boxId, resizeHandlers, onResize, offResize, handleResize, instance, stickyBoxClass, stickyBoxStyle, observeClass, SarResizeSensor };
|
|
75
|
+
return __returned__;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<style lang="scss">
|
|
81
|
+
@import './index.scss';
|
|
82
|
+
</style>
|