Skip to content

Commit fbae716

Browse files
committed
feat(CCollapse): add horizontal collapse
1 parent 4af14e0 commit fbae716

File tree

5 files changed

+85
-8
lines changed

5 files changed

+85
-8
lines changed

packages/coreui-react/src/components/collapse/CCollapse.tsx

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export interface CCollapseProps extends HTMLAttributes<HTMLDivElement> {
1010
* A string of all className you want applied to the base component.
1111
*/
1212
className?: string
13+
/**
14+
* Set horizontal collapsing to transition the width instead of height.
15+
*/
16+
horizontal?: boolean
1317
/**
1418
* Callback fired when the component requests to be hidden.
1519
*/
@@ -25,8 +29,9 @@ export interface CCollapseProps extends HTMLAttributes<HTMLDivElement> {
2529
}
2630

2731
export const CCollapse = forwardRef<HTMLDivElement, CCollapseProps>(
28-
({ children, className, onHide, onShow, visible, ...rest }, ref) => {
32+
({ children, className, horizontal, onHide, onShow, visible, ...rest }, ref) => {
2933
const [height, setHeight] = useState<number>()
34+
const [width, setWidth] = useState<number>()
3035
const collapseRef = useRef<HTMLDivElement>(null)
3136
const forkedRef = useForkedRef(ref, collapseRef)
3237

@@ -42,27 +47,53 @@ export const CCollapse = forwardRef<HTMLDivElement, CCollapseProps>(
4247

4348
const onEntering = () => {
4449
onShow && onShow()
50+
51+
if (horizontal) {
52+
collapseRef.current && setWidth(collapseRef.current.scrollWidth)
53+
return
54+
}
4555
collapseRef.current && setHeight(collapseRef.current.scrollHeight)
4656
}
4757

4858
const onEntered = () => {
59+
if (horizontal) {
60+
setWidth(0)
61+
return
62+
}
4963
setHeight(0)
5064
}
5165

5266
const onExit = () => {
67+
if (horizontal) {
68+
collapseRef.current && setWidth(collapseRef.current.scrollWidth)
69+
return
70+
}
5371
collapseRef.current && setHeight(collapseRef.current.scrollHeight)
5472
}
5573

5674
const onExiting = () => {
5775
onHide && onHide()
76+
if (horizontal) {
77+
setWidth(0)
78+
return
79+
}
5880
setHeight(0)
5981
}
6082

6183
const onExited = () => {
84+
if (horizontal) {
85+
setWidth(0)
86+
return
87+
}
6288
setHeight(0)
6389
}
6490

65-
const _className = classNames(className)
91+
const _className = classNames(
92+
{
93+
'collapse-horizontal': horizontal,
94+
},
95+
className,
96+
)
6697

6798
return (
6899
<CSSTransition
@@ -77,10 +108,11 @@ export const CCollapse = forwardRef<HTMLDivElement, CCollapseProps>(
77108
{(state) => {
78109
const transitionClass = getTransitionClass(state)
79110
const currentHeight = height === 0 ? null : { height }
111+
const currentWidth = width === 0 ? null : { width }
80112
return (
81113
<div
82114
className={classNames(_className, transitionClass)}
83-
style={{ ...currentHeight }}
115+
style={{ ...currentHeight, ...currentWidth }}
84116
{...rest}
85117
ref={forkedRef}
86118
>
@@ -96,6 +128,7 @@ export const CCollapse = forwardRef<HTMLDivElement, CCollapseProps>(
96128
CCollapse.propTypes = {
97129
children: PropTypes.node,
98130
className: PropTypes.string,
131+
horizontal: PropTypes.bool,
99132
onHide: PropTypes.func,
100133
onShow: PropTypes.func,
101134
visible: PropTypes.bool,

packages/coreui-react/src/components/offcanvas/__tests__/COffcanvas.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ test('COffcanvas customize and event on click backdrop', async () => {
5151
expect(container.firstChild).toHaveClass('show')
5252
expect(container.firstChild).toHaveTextContent('Test')
5353
expect(onHide).toHaveBeenCalledTimes(0)
54-
const backdrop = document.querySelector('.modal-backdrop')
54+
const backdrop = document.querySelector('.offcanvas-backdrop')
5555
if (backdrop !== null) {
5656
fireEvent.click(backdrop)
5757
}

packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ exports[`COffcanvas customize and event on click backdrop 1`] = `
1111
Test
1212
</div>
1313
<div
14-
class="modal-backdrop fade show"
14+
class="offcanvas-backdrop fade show"
1515
/>
1616
</div>
1717
`;
@@ -27,7 +27,7 @@ exports[`COffcanvas customize and event on keypress 1`] = `
2727
Test
2828
</div>
2929
<div
30-
class="modal-backdrop fade show"
30+
class="offcanvas-backdrop fade show"
3131
/>
3232
</div>
3333
`;

packages/docs/content/4.0/components/collapse.mdx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,50 @@ return (
7878
)
7979
```
8080

81+
## Horizontal
82+
83+
The collapse plugin also supports horizontal collapsing. Add the `horizontal` property to transition the `width` instead of `height` and set a `width` on the immediate child element.
84+
85+
export const HorizontalExample = () => {
86+
const [visible, setVisible] = useState(false)
87+
return (
88+
<>
89+
<CButton className="mb-3" onClick={() => setVisible(!visible)} aria-expanded={visible} aria-controls="collapseWidthExample">Button</CButton>
90+
<div style={{ minHeight: '120px'}}>
91+
<CCollapse id="collapseWidthExample" horizontal visible={visible}>
92+
<CCard style={{width: '300px'}}>
93+
<CCardBody>
94+
This is some placeholder content for a horizontal collapse. It's hidden by default and shown when triggered.
95+
</CCardBody>
96+
</CCard>
97+
</CCollapse>
98+
</div>
99+
</>
100+
)
101+
}
102+
103+
<Example>
104+
<HorizontalExample />
105+
</Example>
106+
107+
```jsx
108+
const [visible, setVisible] = useState(false)
109+
return (
110+
<>
111+
<CButton className="mb-3" onClick={() => setVisible(!visible)} aria-expanded={visible} aria-controls="collapseWidthExample">Button</CButton>
112+
<div style={{ minHeight: '120px'}}>
113+
<CCollapse id="collapseWidthExample" horizontal visible={visible}>
114+
<CCard style={{width: '300px'}}>
115+
<CCardBody>
116+
This is some placeholder content for a horizontal collapse. It's hidden by default and shown when triggered.
117+
</CCardBody>
118+
</CCard>
119+
</CCollapse>
120+
</div>
121+
</>
122+
)
123+
```
124+
81125
## Multiple targets
82126
83127
A `<CButton>` can show and hide multiple elements.

packages/docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"scripts": {
1717
"api": "rimraf \"content/$npm_package_config_version_short/api/*\" & node build/api.js",
1818
"build": "gatsby build",
19-
"develop": "gatsby develop",
19+
"develop": "export NODE_OPTIONS=--openssl-legacy-provider; gatsby develop",
2020
"dist": "run-s api build",
2121
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
2222
"start": "gatsby develop",
@@ -34,7 +34,7 @@
3434
"@coreui/react-chartjs": "^2.0.0",
3535
"@mdx-js/mdx": "^1.6.22",
3636
"@mdx-js/react": "^1.6.22",
37-
"gatsby": "^3.14.3",
37+
"gatsby": "^3.14.6",
3838
"gatsby-plugin-google-gtag": "^3.14.0",
3939
"gatsby-plugin-image": "^1.14.1",
4040
"gatsby-plugin-manifest": "^3.14.0",

0 commit comments

Comments
 (0)