Skip to content

Commit 9a254db

Browse files
committed
feat: add CElementCover component
1 parent 4c25748 commit 9a254db

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/CElementCover.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useEffect, createRef, useState } from 'react'
2+
import PropTypes from 'prop-types'
3+
import classNames from 'classnames'
4+
import { mapToCssModules } from './Shared/helper.js'
5+
import CSpinner from './CSpinner'
6+
7+
//component - CoreUI / CElementCover
8+
const CElementCover = props => {
9+
10+
const {
11+
className,
12+
cssModule,
13+
children,
14+
//
15+
innerRef,
16+
boundaries,
17+
opacity,
18+
...attributes
19+
} = props
20+
21+
const [customBoundaries, setCustomBoundaries] = useState({})
22+
const ref = createRef(null)
23+
innerRef && innerRef(ref)
24+
25+
const getCustomBoundaries = () => {
26+
if (!ref || !ref.current || !boundaries) {
27+
return {}
28+
}
29+
const parent = ref.current.parentElement
30+
const parentCoords = parent.getBoundingClientRect()
31+
const customBoundaries = {}
32+
boundaries.forEach(({sides, query}) => {
33+
const element = parent.querySelector(query)
34+
if (!element || !sides) {
35+
return
36+
}
37+
const coords = element.getBoundingClientRect()
38+
sides.forEach(side => {
39+
const sideMargin = Math.abs(coords[side] - parentCoords[side])
40+
customBoundaries[side] = sideMargin + 'px'
41+
})
42+
})
43+
return customBoundaries
44+
}
45+
46+
useEffect(() => {
47+
setCustomBoundaries(getCustomBoundaries())
48+
}, [JSON.stringify(getCustomBoundaries())])
49+
50+
//render
51+
const classes = mapToCssModules(classNames(className), cssModule)
52+
53+
const containerCoords = {
54+
top: 0,
55+
left: 0,
56+
right: 0,
57+
bottom: 0,
58+
...customBoundaries
59+
}
60+
61+
const coverStyles = {
62+
...containerCoords,
63+
position: 'absolute',
64+
backgroundColor: `rgb(255,255,255,${opacity})`
65+
}
66+
67+
return (
68+
<div
69+
className={classes}
70+
style={coverStyles}
71+
{...attributes}
72+
ref={ref}
73+
>
74+
{ children ||
75+
<div style={{
76+
position: 'absolute',
77+
top: '50%',
78+
left: '50%',
79+
transform: 'translateX(-50%) translateY(-50%)'
80+
}}>
81+
<CSpinner grow size="lg" color="primary"/>
82+
</div>
83+
}
84+
</div>
85+
)
86+
}
87+
88+
CElementCover.propTypes = {
89+
children: PropTypes.node,
90+
className: PropTypes.string,
91+
cssModule: PropTypes.object,
92+
//
93+
innerRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func, PropTypes.string]),
94+
boundaries: PropTypes.array,
95+
opacity: PropTypes.number
96+
};
97+
98+
CElementCover.defaultProps = {
99+
opacity: 0.4
100+
};
101+
102+
export default CElementCover

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export {default as CCardTitle} from './CCardTitle';
1818
export {default as CCardSubtitle} from './CCardSubtitle';
1919
export {default as CCardText} from './CCardText';
2020
export {default as CCreateElement} from './CCreateElement';
21+
export {default as CElementCover} from './CElementCover';
2122
export {default as CRow} from './CRow';
2223
export {default as CCol} from './CCol';
2324
export {default as CContainer} from './CContainer';

0 commit comments

Comments
 (0)