1+ import React , { useState , useMemo , useEffect } from "react" ;
2+ import { Collapse , Button , SistentThemeProvider } from "@sistent/sistent" ;
3+ import { SistentLayout } from "../../sistent-layout" ;
4+ import TabButton from "../../../../../reusecore/Button" ;
5+ import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode" ;
6+ import { CodeBlock } from "../button/code-block" ;
7+ import { navigate } from "gatsby" ;
8+ import { useLocation } from "@reach/router" ;
9+
10+ const TABS = [ "Overview" , "Guidance" , "Code" ] ;
11+
12+ const collapseExamples = [
13+ {
14+ title : "Basic Collapse" ,
15+ description : "A simple collapsible section that can be toggled with a button click." ,
16+ element : ( { isDark } ) => {
17+ const [ expanded , setExpanded ] = useState ( false ) ;
18+ return (
19+ < >
20+ < Button
21+ variant = "contained"
22+ onClick = { ( ) => setExpanded ( ! expanded ) }
23+ style = { { marginBottom : '1rem' } }
24+ >
25+ { expanded ? 'Collapse' : 'Expand' }
26+ </ Button >
27+ < Collapse in = { expanded } >
28+ < div style = { {
29+ padding : '1rem' ,
30+ border : '1px solid #ddd' ,
31+ borderRadius : '4px' ,
32+ backgroundColor : isDark ? '#333' : '#f5f5f5'
33+ } } >
34+ This content will be collapsed/expanded with a smooth animation.
35+ </ div >
36+ </ Collapse >
37+ </ >
38+ ) ;
39+ } ,
40+ code : `import { Collapse, Button } from "@sistent/sistent";
41+ import { useState } from "react";
42+
43+ function BasicCollapse() {
44+ const [expanded, setExpanded] = useState(false);
45+
46+ return (
47+ <>
48+ <Button onClick={() => setExpanded(!expanded)}>
49+ {expanded ? 'Collapse' : 'Expand'}
50+ </Button>
51+ <Collapse in={expanded}>
52+ <div style={{ padding: '1rem', border: '1px solid #ddd' }}>
53+ Content to be collapsed/expanded
54+ </div>
55+ </Collapse>
56+ </>
57+ );
58+ }` ,
59+ id : "basic-collapse"
60+ } ,
61+ {
62+ title : "Default Expanded" ,
63+ description : "A collapsible section that starts expanded by default." ,
64+ element : ( { isDark } ) => {
65+ const [ expanded , setExpanded ] = useState ( true ) ;
66+ return (
67+ < >
68+ < Button
69+ variant = "outlined"
70+ onClick = { ( ) => setExpanded ( ! expanded ) }
71+ style = { { marginBottom : '1rem' } }
72+ >
73+ { expanded ? 'Collapse' : 'Expand' }
74+ </ Button >
75+ < Collapse in = { expanded } >
76+ < div style = { {
77+ padding : '1rem' ,
78+ border : '1px solid #ddd' ,
79+ borderRadius : '4px' ,
80+ backgroundColor : isDark ? '#333' : '#f5f5f5'
81+ } } >
82+ This content is expanded by default. Click the button to collapse it.
83+ </ div >
84+ </ Collapse >
85+ </ >
86+ ) ;
87+ } ,
88+ code : `function DefaultExpanded() {
89+ const [expanded, setExpanded] = useState(true);
90+
91+ return (
92+ <>
93+ <Button onClick={() => setExpanded(!expanded)}>
94+ {expanded ? 'Collapse' : 'Expand'}
95+ </Button>
96+ <Collapse in={expanded}>
97+ <div>Content that's expanded by default</div>
98+ </Collapse>
99+ </>
100+ );
101+ }` ,
102+ id : "default-expanded"
103+ } ,
104+ {
105+ title : "Unmount on Exit" ,
106+ description : "Unmounts the content when collapsed for better performance with large content." ,
107+ element : ( { isDark } ) => {
108+ const [ expanded , setExpanded ] = useState ( false ) ;
109+ return (
110+ < >
111+ < Button
112+ variant = "text"
113+ onClick = { ( ) => setExpanded ( ! expanded ) }
114+ style = { { marginBottom : '1rem' } }
115+ >
116+ { expanded ? 'Collapse (unmounts content)' : 'Expand (mounts content)' }
117+ </ Button >
118+ < Collapse in = { expanded } unmountOnExit >
119+ < div style = { {
120+ padding : '1rem' ,
121+ border : '1px solid #ddd' ,
122+ borderRadius : '4px' ,
123+ backgroundColor : isDark ? '#333' : '#f5f5f5'
124+ } } >
125+ This content will be unmounted when collapsed (check the React DevTools).
126+ </ div >
127+ </ Collapse >
128+ </ >
129+ ) ;
130+ } ,
131+ code : `function UnmountOnExit() {
132+ const [expanded, setExpanded] = useState(false);
133+
134+ return (
135+ <>
136+ <Button onClick={() => setExpanded(!expanded)}>
137+ {expanded ? 'Collapse' : 'Expand'}
138+ </Button>
139+ <Collapse in={expanded} unmountOnExit>
140+ <div>Content that unmounts when collapsed</div>
141+ </Collapse>
142+ </>
143+ );
144+ }` ,
145+ id : "unmount-on-exit"
146+ } ,
147+ {
148+ title : "Custom Transition" ,
149+ description : "Customize the transition duration and easing function." ,
150+ element : ( { isDark } ) => {
151+ const [ expanded , setExpanded ] = useState ( false ) ;
152+ return (
153+ < >
154+ < Button
155+ variant = "contained"
156+ onClick = { ( ) => setExpanded ( ! expanded ) }
157+ style = { { marginBottom : '1rem' } }
158+ >
159+ { expanded ? 'Fast Collapse' : 'Slow Expand' }
160+ </ Button >
161+ < Collapse
162+ in = { expanded }
163+ timeout = { expanded ? 1000 : 300 } // Slower when expanding, faster when collapsing
164+ easing = { expanded ? "cubic-bezier(0.4, 0, 0.2, 1)" : "ease-out" }
165+ >
166+ < div style = { {
167+ padding : '1rem' ,
168+ border : '1px solid #ddd' ,
169+ borderRadius : '4px' ,
170+ backgroundColor : isDark ? '#333' : '#f5f5f5'
171+ } } >
172+ Notice the different animation speeds when expanding vs collapsing.
173+ </ div >
174+ </ Collapse >
175+ </ >
176+ ) ;
177+ } ,
178+ code : `function CustomTransition() {
179+ const [expanded, setExpanded] = useState(false);
180+
181+ return (
182+ <>
183+ <Button onClick={() => setExpanded(!expanded)}>
184+ {expanded ? 'Fast Collapse' : 'Slow Expand'}
185+ </Button>
186+ <Collapse
187+ in={expanded}
188+ timeout={expanded ? 1000 : 300}
189+ easing={expanded ? "cubic-bezier(0.4, 0, 0.2, 1)" : "ease-out"}
190+ >
191+ <div>Custom transition content</div>
192+ </Collapse>
193+ </>
194+ );
195+ }` ,
196+ id : "custom-transition"
197+ }
198+ ] ;
199+
200+ const CollapseComponent = ( ) => {
201+ const { isDark } = useStyledDarkMode ( ) ;
202+ const location = useLocation ( ) ;
203+
204+ // Determine active tab from URL
205+ const activeTab = useMemo ( ( ) => {
206+ const path = location . pathname ;
207+ if ( path . endsWith ( '/code' ) ) return 'Code' ;
208+ if ( path . endsWith ( '/guidance' ) ) return 'Guidance' ;
209+ return 'Overview' ;
210+ } , [ location . pathname ] ) ;
211+
212+ // Handle tab change
213+ const handleTabChange = ( tab ) => {
214+ const basePath = "/projects/sistent/components/collapse" ;
215+ const newPath = tab === 'Overview' ? basePath : `${ basePath } /${ tab . toLowerCase ( ) } ` ;
216+ if ( location . pathname !== newPath ) {
217+ navigate ( newPath ) ;
218+ }
219+ } ;
220+
221+ return (
222+ < SistentLayout title = "Collapse" >
223+ < section className = "content" style = { { padding : '2rem 0' } } >
224+ < a id = "Layout" style = { { display : 'block' , marginBottom : '1.5rem' } } >
225+ < h2 style = { { marginBottom : '0.5rem' } } > Collapse</ h2 >
226+ </ a >
227+ < p style = { { fontSize : '1.1rem' , lineHeight : '1.7' , marginBottom : '2.5rem' } } >
228+ The Collapse component provides a smooth, animated way to show and hide content.
229+ Below are various examples demonstrating its capabilities and usage patterns.
230+ </ p >
231+
232+ < div className = "filterBtns" style = { { marginBottom : '2.5rem' } } >
233+ { TABS . map ( ( tab ) => (
234+ < TabButton
235+ key = { tab }
236+ title = { tab }
237+ className = { activeTab === tab ? "active" : "" }
238+ onClick = { ( ) => handleTabChange ( tab ) }
239+ />
240+ ) ) }
241+ </ div >
242+
243+ < div className = "main-content" style = { { display : 'flex' , flexDirection : 'column' , gap : '3.5rem' } } >
244+ { collapseExamples . map ( ( example ) => (
245+ < div key = { example . id } className = "example-container" style = { {
246+ marginBottom : '2.5rem' ,
247+ padding : '1.5rem' ,
248+ backgroundColor : isDark ? '#1e1e1e' : '#f9f9f9' ,
249+ borderRadius : '8px' ,
250+ boxShadow : '0 2px 8px rgba(0,0,0,0.1)'
251+ } } >
252+ < h3 style = { {
253+ fontSize : '1.5rem' ,
254+ marginBottom : '1rem' ,
255+ color : isDark ? '#fff' : '#333'
256+ } } >
257+ { example . title }
258+ </ h3 >
259+ < p style = { {
260+ fontSize : '1.05rem' ,
261+ lineHeight : '1.6' ,
262+ marginBottom : '1.5rem' ,
263+ color : isDark ? '#e0e0e0' : '#555'
264+ } } >
265+ { example . description }
266+ </ p >
267+ < div className = "example-preview" style = { {
268+ padding : '1.5rem' ,
269+ border : `1px solid ${ isDark ? '#444' : '#e0e0e0' } ` ,
270+ borderRadius : '6px' ,
271+ marginBottom : '1.5rem' ,
272+ backgroundColor : isDark ? '#2a2a2a' : '#fff' ,
273+ boxShadow : isDark ? '0 2px 4px rgba(0,0,0,0.2)' : '0 1px 3px rgba(0,0,0,0.05)'
274+ } } >
275+ < SistentThemeProvider initialMode = { isDark ? "dark" : "light" } >
276+ { example . element ( { isDark } ) }
277+ </ SistentThemeProvider >
278+ </ div >
279+ < div className = "code-block-container" style = { {
280+ marginTop : '1.5rem' ,
281+ borderRadius : '6px' ,
282+ overflow : 'hidden' ,
283+ boxShadow : '0 2px 8px rgba(0,0,0,0.1)'
284+ } } >
285+ < CodeBlock name = { `collapse-${ example . id } ` } code = { example . code } />
286+ </ div >
287+ </ div >
288+ ) ) }
289+ </ div >
290+ </ section >
291+ </ SistentLayout >
292+ ) ;
293+ } ;
294+
295+ export default CollapseComponent ;
0 commit comments