feat(Sticky): support sticky to bottom (#7979)
This commit is contained in:
@@ -51,4 +51,22 @@ exports[`should render demo and match snapshot 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="height: 200px;">
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-sticky">
|
||||
<button type="button"
|
||||
class="van-button van-button--primary van-button--normal"
|
||||
style="margin-left: 15px;"
|
||||
>
|
||||
<div class="van-button__content">
|
||||
<span class="van-button__text">
|
||||
Offset Bottom
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -30,11 +30,39 @@ exports[`should allow to using offset-top prop with vw unit 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should sticky inside container when using container prop 1`] = `
|
||||
<div style="height: 20px;">
|
||||
<div style="height: 10px;">
|
||||
exports[`should sticky inside container bottom when using container prop 1`] = `
|
||||
<div style="margin-top: 640px;">
|
||||
<div style="height: 150px;">
|
||||
</div>
|
||||
<div style="height: 44px; width: 88px;">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="transform: translate3d(0, -5px, 0);"
|
||||
style="height: 44px; width: 88px; bottom: 0px;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should sticky inside container bottom when using container prop 2`] = `
|
||||
<div style="margin-top: 640px;">
|
||||
<div style="height: 150px;">
|
||||
</div>
|
||||
<div style="height: 44px; width: 88px;">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="height: 44px; width: 88px; bottom: 0px; transform: translate3d(0, 24px, 0);"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should sticky inside container when using container prop 1`] = `
|
||||
<div style="height: 150px;">
|
||||
<div style="height: 44px; width: 88px;">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="height: 44px; width: 88px; top: 0px;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
@@ -43,26 +71,32 @@ exports[`should sticky inside container when using container prop 1`] = `
|
||||
`;
|
||||
|
||||
exports[`should sticky inside container when using container prop 2`] = `
|
||||
<div style="height: 20px;">
|
||||
<div style="height: 10px;">
|
||||
<div class="van-sticky">
|
||||
<div style="height: 150px;">
|
||||
<div style="height: 44px; width: 88px;">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="height: 44px; width: 88px; top: 0px; transform: translate3d(0, -14px, 0);"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should sticky to top after scrolling 1`] = `
|
||||
exports[`should sticky to bottom after scrolling 1`] = `
|
||||
<div style="height: 10px;">
|
||||
<div class="van-sticky">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="bottom: 10px;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should sticky to top after scrolling 2`] = `
|
||||
exports[`should sticky to top after scrolling 1`] = `
|
||||
<div style="height: 10px;">
|
||||
<div class="van-sticky van-sticky--fixed">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="top: 0px;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
@@ -71,7 +105,7 @@ exports[`should sticky to top after scrolling 2`] = `
|
||||
exports[`should update z-index when using z-index prop 1`] = `
|
||||
<div style="height: 10px;">
|
||||
<div class="van-sticky van-sticky--fixed"
|
||||
style="z-index: 0;"
|
||||
style="top: 0px; z-index: 0;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
|
||||
+162
-14
@@ -1,19 +1,51 @@
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { mount, mockScrollTop } from '../../../test';
|
||||
import { mockScrollTop, mount } from '../../../test';
|
||||
import Sticky from '..';
|
||||
|
||||
Object.defineProperty(window.HTMLElement.prototype, 'clientHeight', {
|
||||
value: 640,
|
||||
});
|
||||
|
||||
test('should sticky to top after scrolling', async () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <Sticky style="height: 10px;">Content</Sticky>;
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: -90,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should sticky to bottom after scrolling', async () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return (
|
||||
<Sticky style="height: 10px;" offsetBottom={10} position="bottom">
|
||||
Content
|
||||
</Sticky>
|
||||
);
|
||||
},
|
||||
});
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: 640,
|
||||
bottom: 650,
|
||||
});
|
||||
|
||||
await mockScrollTop(0);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should update z-index when using z-index prop', async () => {
|
||||
@@ -27,25 +59,41 @@ test('should update z-index when using z-index prop', async () => {
|
||||
},
|
||||
});
|
||||
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: -90,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
await mockScrollTop(0);
|
||||
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should add offset top when using offset-top prop', async () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return (
|
||||
<Sticky style="height: 10px;" offsetTop={10}>
|
||||
<Sticky style="height: 10px;" offsetTop={10} position="top">
|
||||
Content
|
||||
</Sticky>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: -90,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
await mockScrollTop(0);
|
||||
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should allow to using offset-top prop with rem unit', async () => {
|
||||
@@ -63,10 +111,17 @@ test('should allow to using offset-top prop with rem unit', async () => {
|
||||
},
|
||||
});
|
||||
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: -90,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
|
||||
await mockScrollTop(0);
|
||||
mockStickyRect.mockRestore();
|
||||
window.getComputedStyle = originGetComputedStyle;
|
||||
});
|
||||
|
||||
@@ -83,9 +138,17 @@ test('should allow to using offset-top prop with vw unit', async () => {
|
||||
},
|
||||
});
|
||||
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: -90,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
await mockScrollTop(0);
|
||||
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should not trigger scroll event when hidden', () => {
|
||||
@@ -114,8 +177,8 @@ test('should sticky inside container when using container prop', async () => {
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div ref="container" style="height: 20px;">
|
||||
<Sticky ref="sticky" style="height: 10px;" container={this.container}>
|
||||
<div ref="container" style="height: 150px;">
|
||||
<Sticky ref="sticky" style="height: 44px;" container={this.container}>
|
||||
Content
|
||||
</Sticky>
|
||||
</div>
|
||||
@@ -123,12 +186,97 @@ test('should sticky inside container when using container prop', async () => {
|
||||
},
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
await mockScrollTop(15);
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element.firstElementChild, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
height: 44,
|
||||
width: 88,
|
||||
top: -100,
|
||||
bottom: -56,
|
||||
});
|
||||
const mockContainerRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: -100,
|
||||
bottom: 50,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
await mockScrollTop(25);
|
||||
|
||||
mockStickyRect.mockReturnValue({
|
||||
height: 44,
|
||||
width: 88,
|
||||
top: -120,
|
||||
bottom: -76,
|
||||
});
|
||||
mockContainerRect.mockReturnValue({
|
||||
top: -120,
|
||||
bottom: 30,
|
||||
});
|
||||
await mockScrollTop(120);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
await mockScrollTop(0);
|
||||
mockContainerRect.mockRestore();
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should sticky inside container bottom when using container prop', async () => {
|
||||
const wrapper = mount({
|
||||
setup() {
|
||||
const container = ref();
|
||||
return {
|
||||
container,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div ref="container" style="margin-top: 640px">
|
||||
<div style="height: 150px" />
|
||||
<Sticky
|
||||
ref="sticky"
|
||||
style="height: 44px;"
|
||||
container={this.container}
|
||||
position="bottom"
|
||||
>
|
||||
Content
|
||||
</Sticky>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const mockStickyRect = jest
|
||||
.spyOn(wrapper.element.children[1], 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
height: 44,
|
||||
width: 88,
|
||||
top: 690,
|
||||
bottom: 734,
|
||||
});
|
||||
const mockContainerRect = jest
|
||||
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||
.mockReturnValue({
|
||||
top: 540,
|
||||
bottom: 734,
|
||||
});
|
||||
|
||||
await mockScrollTop(100);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
|
||||
mockStickyRect.mockReturnValue({
|
||||
height: 44,
|
||||
width: 88,
|
||||
top: 770,
|
||||
bottom: 814,
|
||||
});
|
||||
mockContainerRect.mockReturnValue({
|
||||
top: 620,
|
||||
bottom: 814,
|
||||
});
|
||||
await mockScrollTop(20);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
mockContainerRect.mockRestore();
|
||||
mockStickyRect.mockRestore();
|
||||
});
|
||||
|
||||
test('should emit scroll event when visibility changed', async () => {
|
||||
|
||||
Reference in New Issue
Block a user