mirror of https://github.com/vizality/vizality
rename StickyWrapper component to StickyElement and update its code
parent
15db3f769a
commit
c4f7792a5e
@ -0,0 +1,44 @@
|
||||
import React, { memo, useEffect, useRef, useState } from 'react';
|
||||
import { joinClassNames } from '@vizality/util/dom';
|
||||
|
||||
export default memo(({ sticky, onStickyChange, className, wrapperClassName, children, ...other }) => {
|
||||
const [ _sticky, setSticky ] = useState(sticky);
|
||||
const headerRef = useRef(null);
|
||||
|
||||
const handleStickyChange = element => {
|
||||
setSticky(element.isIntersecting < 1);
|
||||
if (onStickyChange && typeof onStickyChange === 'function') {
|
||||
onStickyChange(element.isIntersecting < 1);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const header = headerRef?.current;
|
||||
const observer = new IntersectionObserver(
|
||||
([ element ]) => handleStickyChange(element),
|
||||
{ threshold: [ 1 ] }
|
||||
);
|
||||
|
||||
if (header) {
|
||||
observer.observe(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the observer
|
||||
*/
|
||||
return (() => observer.unobserve(header));
|
||||
}, [ headerRef ]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={headerRef}
|
||||
className={joinClassNames('vz-sticky-element-wrapper', wrapperClassName)}
|
||||
vz-stuck={Boolean(_sticky) && ''}
|
||||
{...other}
|
||||
>
|
||||
<div className={joinClassNames('vz-sticky-element', className)}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
@ -1,40 +0,0 @@
|
||||
import React, { memo, useEffect, useRef } from 'react';
|
||||
|
||||
import { excludeProperties } from '@vizality/util/object';
|
||||
import { joinClassNames } from '@vizality/util/dom';
|
||||
|
||||
export default memo(props => {
|
||||
const { className, wrapperClassName, children, handleStickyChange } = props;
|
||||
const sticky = useRef(null);
|
||||
|
||||
const _handleStickyChange = (state, element) => {
|
||||
handleStickyChange(state, element);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(([ entry ]) => {
|
||||
if (entry.intersectionRatio < 1) {
|
||||
entry.target.setAttribute('vz-stuck', '');
|
||||
_handleStickyChange('stuck', entry.target);
|
||||
} else {
|
||||
entry.target.removeAttribute('vz-stuck');
|
||||
_handleStickyChange('unstuck', entry.target);
|
||||
}
|
||||
}, { threshold: [ 1 ] });
|
||||
|
||||
observer.observe(sticky.current);
|
||||
return () => observer.unobserve(sticky.current);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={sticky}
|
||||
className={joinClassNames('vz-sticky-wrapper', wrapperClassName)}
|
||||
{...excludeProperties(props, 'children', 'className', 'wrapperClassName')}
|
||||
>
|
||||
<div className={joinClassNames('vz-sticky', className)}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
@ -0,0 +1,28 @@
|
||||
@use '@vizality' as vz;
|
||||
|
||||
.vz-sticky-element {
|
||||
display: flex;
|
||||
padding: 12px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
&-wrapper {
|
||||
@include vz.size(100%);
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
border-radius: 8px;
|
||||
background: var(--background-secondary-alt);
|
||||
z-index: 1;
|
||||
box-shadow: var(--elevation-low);
|
||||
flex: 0;
|
||||
&[vz-stuck] {
|
||||
background: var(--background-primary);
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
.topPill-30KHOu .selected-3s45Ha.item-PXvHYJ {
|
||||
background: var(--brand-experiment);
|
||||
&:hover {
|
||||
background: var(--brand-experiment);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue