1- import React , { useContext , useEffect , useState , useCallback } from 'react' ;
1+ import React , { useContext , useEffect } from 'react' ;
22import { useLocation } from '@reach/router' ;
33import {
44 Button ,
55 CodeBlock ,
66 Flex ,
77 CodeBlockCode ,
88 debounce ,
9- Icon ,
109 Label ,
1110 Switch ,
12- Select ,
13- SelectOption ,
14- SelectList ,
15- MenuToggle ,
1611 Tooltip ,
1712 Stack ,
18- StackItem
13+ StackItem ,
1914} from '@patternfly/react-core' ;
2015import * as reactCoreModule from '@patternfly/react-core' ;
2116import * as reactCoreNextModule from '@patternfly/react-core/next' ;
@@ -24,9 +19,6 @@ import * as reactTableModule from '@patternfly/react-table';
2419import * as reactTableDeprecatedModule from '@patternfly/react-table/deprecated' ;
2520import { css } from '@patternfly/react-styles' ;
2621import { getParameters } from 'codesandbox/lib/api/define' ;
27- const SunIcon = < svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 32 32" className = "pf-v6-svg" fill = "var(--pf-t--global--icon--color--regular)" > < path d = "M16 25c-4.963 0-9-4.038-9-9s4.037-9 9-9 9 4.038 9 9-4.037 9-9 9Zm0-16c-3.86 0-7 3.14-7 7s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7Zm0-4a1 1 0 0 1-1-1V1a1 1 0 1 1 2 0v3a1 1 0 0 1-1 1Zm0 27a1 1 0 0 1-1-1v-3a1 1 0 1 1 2 0v3a1 1 0 0 1-1 1ZM4 17H1a1 1 0 1 1 0-2h3a1 1 0 1 1 0 2Zm27 0h-3a1 1 0 1 1 0-2h3a1 1 0 1 1 0 2ZM5.394 27.606a1 1 0 0 1-.707-1.707l2.12-2.12a1 1 0 1 1 1.415 1.413L6.1 27.313a.997.997 0 0 1-.707.293ZM24.485 8.515a1 1 0 0 1-.707-1.707L25.9 4.686a1 1 0 1 1 1.415 1.415l-2.122 2.12a.997.997 0 0 1-.707.294Zm-16.97 0a.997.997 0 0 1-.707-.293L4.686 6.1a1 1 0 1 1 1.415-1.415l2.12 2.122a1 1 0 0 1-.706 1.707Zm19.091 19.091a.997.997 0 0 1-.707-.293l-2.12-2.12a1 1 0 1 1 1.413-1.415l2.122 2.121a1 1 0 0 1-.707 1.707Z" > </ path > </ svg > ;
28- const MoonIcon = < svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 32 32" className = "pf-v6-svg" fill = "var(--pf-t--global--icon--color--regular)" > < path d = "M16.457 30C8.485 30 2 23.515 2 15.543c0-5.93 3.715-11.345 9.243-13.476a.999.999 0 0 1 1.289 1.3 12.185 12.185 0 0 0-.843 4.487c0 6.869 5.588 12.457 12.457 12.457 1.56 0 3.07-.284 4.487-.844a.998.998 0 0 1 1.3 1.29C27.802 26.285 22.387 30 16.456 30ZM9.992 4.904C6.338 7.134 4 11.177 4 15.544 4 22.412 9.588 28 16.457 28c4.367 0 8.41-2.338 10.639-5.992a14.39 14.39 0 0 1-2.95.302c-7.971 0-14.457-6.485-14.457-14.456 0-1.003.102-1.989.303-2.95Z" > </ path > </ svg > ;
29- const DesktopIcon = < svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 32 32" className = "pf-v6-svg" fill = "var(--pf-t--global--icon--color--regular)" > < path d = "M23.94 16a1 1 0 0 1-.992-.876 6.957 6.957 0 0 0-6.069-6.062 1 1 0 1 1 .242-1.985 8.953 8.953 0 0 1 7.812 7.8A.999.999 0 0 1 23.94 16ZM16 5a1 1 0 0 1-1-1V1a1 1 0 1 1 2 0v3a1 1 0 0 1-1 1Zm0 27a1 1 0 0 1-1-1v-3a1 1 0 1 1 2 0v3a1 1 0 0 1-1 1ZM4 17H1a1 1 0 1 1 0-2h3a1 1 0 1 1 0 2Zm27 0h-3a1 1 0 1 1 0-2h3a1 1 0 1 1 0 2ZM5.394 27.606a1 1 0 0 1-.707-1.707l2.12-2.12a1 1 0 1 1 1.415 1.413L6.1 27.313a.997.997 0 0 1-.707.293ZM24.485 8.515a1 1 0 0 1-.707-1.707L25.9 4.686a1 1 0 1 1 1.415 1.415l-2.122 2.12a.997.997 0 0 1-.707.294Zm-16.97 0a.997.997 0 0 1-.707-.293L4.686 6.1a1 1 0 1 1 1.415-1.415l2.12 2.122a1 1 0 0 1-.706 1.707Zm19.091 19.091a.997.997 0 0 1-.707-.293l-2.12-2.12a1 1 0 1 1 1.413-1.415l2.122 2.121a1 1 0 0 1-.707 1.707ZM16 24.875c-4.894 0-8.875-3.981-8.875-8.875a8.879 8.879 0 0 1 5.227-8.088.876.876 0 0 1 1.153 1.163 6.945 6.945 0 0 0-.63 2.925A7.133 7.133 0 0 0 20 19.125a6.948 6.948 0 0 0 2.925-.63.876.876 0 0 1 1.163 1.154A8.88 8.88 0 0 1 16 24.875Zm-4.785-14.153A7.135 7.135 0 0 0 8.875 16 7.133 7.133 0 0 0 16 23.125a7.13 7.13 0 0 0 5.278-2.34c-.419.06-.845.09-1.278.09-4.894 0-8.875-3.981-8.875-8.875 0-.433.03-.86.09-1.278Z" > </ path > </ svg > ;
3022import { ExampleToolbar } from './exampleToolbar.jsx' ;
3123import { AutoLinkHeader } from '../autoLinkHeader/autoLinkHeader' ;
3224import {
@@ -35,92 +27,15 @@ import {
3527 getReactParams ,
3628 getExampleClassName ,
3729 getExampleId ,
38- liveCodeTypes ,
30+ liveCodeTypes
3931} from '../../helpers' ;
4032import { convertToReactComponent } from '@patternfly/ast-helpers' ;
4133import missingThumbnail from './missing-thumbnail.jpg' ;
4234import { RtlContext } from '../../layouts' ;
43- import { useTheme } from '../../hooks/useTheme ' ;
35+ import { ThemeSelector } from '../themeSelector/themeSelector ' ;
4436
4537const errorComponent = ( err ) => < pre > { err . toString ( ) } </ pre > ;
4638
47- // Full-screen theme selector component using shared theme hook
48- const FullScreenThemeSelector = ( ) => {
49- const { themeMode, setThemeMode, THEME_MODES } = useTheme ( ) ;
50- const [ isThemeSelectOpen , setIsThemeSelectOpen ] = useState ( false ) ;
51-
52- const handleThemeChange = ( _event , selectedMode ) => {
53- setThemeMode ( selectedMode ) ;
54- setIsThemeSelectOpen ( false ) ;
55- } ;
56-
57- const getThemeDisplayText = ( mode ) => {
58- switch ( mode ) {
59- case THEME_MODES . LIGHT :
60- return 'Light' ;
61- case THEME_MODES . DARK :
62- return 'Dark' ;
63- default :
64- return 'System' ;
65- }
66- } ;
67-
68- const getThemeIcon = ( mode ) => {
69- switch ( mode ) {
70- case THEME_MODES . LIGHT :
71- return SunIcon ;
72- case THEME_MODES . DARK :
73- return MoonIcon ;
74- default :
75- return DesktopIcon ;
76- }
77- } ;
78-
79- return (
80- < Select
81- id = "ws-example-theme-select"
82- isOpen = { isThemeSelectOpen }
83- selected = { themeMode }
84- onSelect = { handleThemeChange }
85- onOpenChange = { ( isOpen ) => setIsThemeSelectOpen ( isOpen ) }
86- toggle = { ( toggleRef ) => (
87- < MenuToggle
88- ref = { toggleRef }
89- onClick = { ( ) => setIsThemeSelectOpen ( ! isThemeSelectOpen ) }
90- isExpanded = { isThemeSelectOpen }
91- icon = { < Icon size = "lg" > { getThemeIcon ( themeMode ) } </ Icon > }
92- aria-label = { `Theme selection, current: ${ getThemeDisplayText ( themeMode ) } ` }
93- />
94- ) }
95- shouldFocusToggleOnSelect
96- >
97- < SelectList >
98- < SelectOption
99- value = { THEME_MODES . SYSTEM }
100- icon = { DesktopIcon }
101- description = "Follow system preference"
102- >
103- System
104- </ SelectOption >
105- < SelectOption
106- value = { THEME_MODES . LIGHT }
107- icon = { SunIcon }
108- description = "Always use light mode"
109- >
110- Light
111- </ SelectOption >
112- < SelectOption
113- value = { THEME_MODES . DARK }
114- icon = { MoonIcon }
115- description = "Always use dark mode"
116- >
117- Dark
118- </ SelectOption >
119- </ SelectList >
120- </ Select >
121- ) ;
122- } ;
123-
12439class ErrorBoundary extends React . Component {
12540 constructor ( props ) {
12641 super ( props ) ;
@@ -131,7 +46,7 @@ class ErrorBoundary extends React.Component {
13146 errorInfo . _suppressLogging = true ;
13247 this . setState ( {
13348 error : error ,
134- errorInfo : errorInfo ,
49+ errorInfo : errorInfo
13550 } ) ;
13651 }
13752
@@ -183,15 +98,15 @@ export const Example = ({
18398 // Content that appears between h3 and code block to explain example
18499 children,
185100 // Show dark theme switcher on full page examples
186- hasDarkThemeSwitcher = process . env . hasDarkThemeSwitcher ,
101+ hasThemeSwitcher = process . env . hasThemeSwitcher ,
187102 // Show dark theme switcher on full page examples
188103 hasRTLSwitcher = process . env . hasRTLSwitcher ,
189104 // Map of relative imports matched to their npm package import path (passed to Codesandbox)
190105 relativeImports,
191106 // md file location in node_modules, used to resolve relative import paths in examples
192107 relPath = '' ,
193108 // absolute url to hosted file
194- sourceLink = '' ,
109+ sourceLink = ''
195110} ) => {
196111 if ( isFullscreenPreview ) {
197112 isFullscreen = false ;
@@ -202,9 +117,7 @@ export const Example = ({
202117 useEffect ( ( ) => {
203118 if ( ! isFullscreenPreview ) return ;
204119
205- document . readyState === 'complete'
206- ? addPageLoadedClass ( )
207- : window . addEventListener ( 'load' , addPageLoadedClass ) ;
120+ document . readyState === 'complete' ? addPageLoadedClass ( ) : window . addEventListener ( 'load' , addPageLoadedClass ) ;
208121
209122 return ( ) => window . removeEventListener ( 'load' , addPageLoadedClass ) ;
210123 } , [ ] ) ;
@@ -230,9 +143,7 @@ export const Example = ({
230143 ...reactCoreModule ,
231144 ...reactTableModule ,
232145 ...( source === 'react-next' ? reactCoreNextModule : { } ) ,
233- ...( source === 'react-deprecated'
234- ? { ...reactCoreDeprecatedModule , ...reactTableDeprecatedModule }
235- : { } ) ,
146+ ...( source === 'react-deprecated' ? { ...reactCoreDeprecatedModule , ...reactTableDeprecatedModule } : { } )
236147 } ;
237148
238149 let livePreview = null ;
@@ -248,8 +159,7 @@ export const Example = ({
248159 ) ;
249160 } else {
250161 try {
251- const { code : transformedCode , hasTS } =
252- convertToReactComponent ( editorCode ) ;
162+ const { code : transformedCode , hasTS } = convertToReactComponent ( editorCode ) ;
253163 if ( hasTS ) {
254164 lang = 'ts' ;
255165 } else {
@@ -259,11 +169,7 @@ export const Example = ({
259169 const componentNames = Object . keys ( scope ) ;
260170 const componentValues = Object . values ( scope ) ;
261171
262- const getPreviewComponent = new Function (
263- 'React' ,
264- ...componentNames ,
265- transformedCode
266- ) ;
172+ const getPreviewComponent = new Function ( 'React' , ...componentNames , transformedCode ) ;
267173 const PreviewComponent = getPreviewComponent ( React , ...componentValues ) ;
268174
269175 livePreview = (
@@ -282,13 +188,13 @@ export const Example = ({
282188 return (
283189 < div id = { previewId } className = { css ( className , 'pf-v6-u-h-100' ) } >
284190 { livePreview }
285- { ( hasDarkThemeSwitcher || hasRTLSwitcher ) && (
191+ { ( hasThemeSwitcher || hasRTLSwitcher ) && (
286192 < Flex
287193 direction = { { default : 'column' } }
288194 gap = { { default : 'gapMd' } }
289195 className = "ws-full-page-utils pf-v6-m-dir-ltr"
290196 >
291- { hasDarkThemeSwitcher && < FullScreenThemeSelector /> }
197+ { hasThemeSwitcher && < ThemeSelector id = "ws-example-theme-select" /> }
292198 { hasRTLSwitcher && (
293199 < Switch
294200 id = "ws-example-rtl-switch"
@@ -310,61 +216,49 @@ export const Example = ({
310216 const codeBoxParams = getParameters (
311217 lang === 'html'
312218 ? getStaticParams ( title , editorCode )
313- : getReactParams (
314- title ,
315- editorCode ,
316- scope ,
317- lang ,
318- relativeImports ,
319- relPath ,
320- sourceLink
321- )
219+ : getReactParams ( title , editorCode , scope , lang , relativeImports , relPath , sourceLink )
322220 ) ;
323221 const fullscreenLink =
324- loc . pathname . replace ( / \/ $ / , '' ) +
325- ( loc . pathname . endsWith ( source ) ? '' : `/${ source } ` ) +
326- '/' +
327- slugger ( title ) ;
222+ loc . pathname . replace ( / \/ $ / , '' ) + ( loc . pathname . endsWith ( source ) ? '' : `/${ source } ` ) + '/' + slugger ( title ) ;
328223
329224 const hasMetaText = isBeta || isDemo || isDeprecated || false ;
330- const tooltips = ( < React . Fragment >
331- { isBeta && (
332- < Tooltip content = "This beta component is currently under review and is still open for further evolution." >
333- < Button variant = "plain" hasNoPadding >
334- < Label isCompact color = "blue" >
335- Beta
336- </ Label >
337- </ Button >
338- </ Tooltip >
339- ) }
340- { isDemo && (
341- < Tooltip content = "Demos show how multiple components can be used in a single design." >
342- < Button variant = "plain" hasNoPadding >
343- < Label isCompact color = "purple" >
344- Demo
345- </ Label >
346- </ Button >
347- </ Tooltip >
348- ) }
349- { isDeprecated && (
350- < Tooltip content = "Deprecated components are available for use but are no longer being maintained or enhanced." >
351- < Button variant = "plain" hasNoPadding >
352- < Label isCompact color = "grey" >
353- Deprecated
354- </ Label >
355- </ Button >
356- </ Tooltip >
357- ) }
358- </ React . Fragment > ) ;
359- const metaText = hasMetaText && tooltips
225+ const tooltips = (
226+ < React . Fragment >
227+ { isBeta && (
228+ < Tooltip content = "This beta component is currently under review and is still open for further evolution." >
229+ < Button variant = "plain" hasNoPadding >
230+ < Label isCompact color = "blue" >
231+ Beta
232+ </ Label >
233+ </ Button >
234+ </ Tooltip >
235+ ) }
236+ { isDemo && (
237+ < Tooltip content = "Demos show how multiple components can be used in a single design." >
238+ < Button variant = "plain" hasNoPadding >
239+ < Label isCompact color = "purple" >
240+ Demo
241+ </ Label >
242+ </ Button >
243+ </ Tooltip >
244+ ) }
245+ { isDeprecated && (
246+ < Tooltip content = "Deprecated components are available for use but are no longer being maintained or enhanced." >
247+ < Button variant = "plain" hasNoPadding >
248+ < Label isCompact color = "grey" >
249+ Deprecated
250+ </ Label >
251+ </ Button >
252+ </ Tooltip >
253+ ) }
254+ </ React . Fragment >
255+ ) ;
256+ const metaText = hasMetaText && tooltips ;
360257
361258 return (
362259 < Stack hasGutter >
363260 < StackItem >
364- < AutoLinkHeader
365- metaText = { metaText }
366- headingLevel = "h3"
367- >
261+ < AutoLinkHeader metaText = { metaText } headingLevel = "h3" >
368262 { title }
369263 </ AutoLinkHeader >
370264 { children }
@@ -378,22 +272,11 @@ export const Example = ({
378272 target = "_blank"
379273 aria-label = { `Open fullscreen ${ title } example` }
380274 >
381- < img
382- src = { thumbnail . src }
383- width = { thumbnail . width }
384- height = { thumbnail . height }
385- alt = { `${ title } screenshot` }
386- />
275+ < img src = { thumbnail . src } width = { thumbnail . width } height = { thumbnail . height } alt = { `${ title } screenshot` } />
387276 </ a >
388277 </ div >
389278 ) : (
390- < div
391- id = { previewId }
392- className = { css (
393- className ,
394- isRTL && 'pf-v6-m-dir-rtl'
395- ) }
396- >
279+ < div id = { previewId } className = { css ( className , isRTL && 'pf-v6-m-dir-rtl' ) } >
397280 { livePreview }
398281 </ div >
399282 ) }
0 commit comments