@@ -2,21 +2,15 @@ import React, { useState } from 'react';
22import {
33 Select ,
44 SelectGroup ,
5- SelectList ,
6- SelectOption ,
75 MenuToggle ,
86 MenuSearch ,
97 MenuSearchInput ,
108 ToggleGroup ,
119 ToggleGroupItem ,
1210 Icon ,
1311 Divider ,
14- Spinner ,
15- Label ,
16- Popover ,
17- Button
12+ Spinner
1813} from '@patternfly/react-core' ;
19- import { HelpIcon , ExternalLinkAltIcon } from '@patternfly/react-icons' ;
2014import { useTheme , THEME_TYPES } from '../../hooks/useTheme' ;
2115
2216const SunIcon = (
@@ -50,6 +44,14 @@ const DesktopIcon = (
5044 </ svg >
5145) ;
5246
47+ const ThemeVariantGroupLabel = ( ) => {
48+ return (
49+ < div className = "pf-v6-c-menu__group-title" id = "theme-selector-variant-title" >
50+ Theme
51+ </ div >
52+ ) ;
53+ } ;
54+
5355const ColorSchemeGroupLabel = ( ) => {
5456 return (
5557 < div className = "pf-v6-c-menu__group-title" id = "theme-selector-color-scheme-title" >
@@ -58,60 +60,34 @@ const ColorSchemeGroupLabel = () => {
5860 ) ;
5961} ;
6062
61- const HighContrastGroupLabel = ( ) => {
62- const [ isPopoverOpen , setIsPopoverOpen ] = useState ( false ) ;
63-
63+ const ContrastModeGroupLabel = ( ) => {
6464 return (
65- < div className = "pf-v6-c-menu__group-title" >
66- High contrast{ ' ' }
67- < Popover
68- onClick = { ( e ) => e . stopPropagation ( ) }
69- headerContent = { 'Under development' }
70- headerComponent = "h1"
71- bodyContent = {
72- 'We are still working to add high contrast support across all PatternFly components and extensions. This beta allows you to preview our progress.'
73- }
74- footerContent = {
75- < Button
76- icon = { < ExternalLinkAltIcon /> }
77- component = "a"
78- isInline
79- variant = "link"
80- href = "/design-foundations/theming"
81- target = "_blank"
82- >
83- Learn more
84- </ Button >
85- }
86- aria-label = "More info about high contrast"
87- appendTo = { ( ) => document . body }
88- >
89- < Button variant = "plain" hasNoPadding icon = { < HelpIcon /> } aria-label = "High contrast help" />
90- </ Popover > { ' ' }
91-
92- < Label color = "blue" isCompact >
93- Beta
94- </ Label >
65+ < div className = "pf-v6-c-menu__group-title" id = "theme-selector-contrast-title" >
66+ Contrast mode
9567 </ div >
9668 ) ;
9769} ;
9870
9971export const ThemeSelector = ( { id } ) => {
72+ const { mode : themeVariant , setMode : setThemeVariant , modes : themeVariantModes } = useTheme ( THEME_TYPES . THEME_VARIANT ) ;
10073 const { mode : themeMode , setMode : setThemeMode , modes : colorModes } = useTheme ( THEME_TYPES . COLOR ) ;
10174 const {
102- mode : highContrastMode ,
103- setMode : setHighContrastMode ,
104- modes : highContrastModes
105- } = useTheme ( THEME_TYPES . HIGH_CONTRAST ) ;
75+ mode : contrastMode ,
76+ setMode : setContrastMode ,
77+ modes : contrastModes
78+ } = useTheme ( THEME_TYPES . CONTRAST ) ;
10679 const [ isThemeSelectOpen , setIsThemeSelectOpen ] = useState ( false ) ;
10780
108- const handleThemeChange = ( _event , selectedMode ) => {
109- setThemeMode ( selectedMode ) ;
110- setIsThemeSelectOpen ( false ) ;
81+ const handleThemeVariantChange = ( evt ) => {
82+ setThemeVariant ( evt . currentTarget . id ) ;
11183 } ;
11284
113- const handleHighContrastThemeSelection = ( evt ) => {
114- setHighContrastMode ( evt . currentTarget . id ) ;
85+ const handleThemeChange = ( evt ) => {
86+ setThemeMode ( evt . currentTarget . id ) ;
87+ } ;
88+
89+ const handleContrastModeChange = ( evt ) => {
90+ setContrastMode ( evt . currentTarget . id ) ;
11591 } ;
11692
11793 const getThemeDisplayText = ( mode ) => {
@@ -126,6 +102,9 @@ export const ThemeSelector = ({ id }) => {
126102 } ;
127103
128104 const getThemeIcon = ( mode ) => {
105+ if ( ! colorModes ) {
106+ return < Spinner size = "sm" /> ;
107+ }
129108 switch ( mode ) {
130109 case colorModes . LIGHT :
131110 return SunIcon ;
@@ -134,16 +113,14 @@ export const ThemeSelector = ({ id }) => {
134113 case colorModes . SYSTEM :
135114 return DesktopIcon ;
136115 default :
137- return < Spinner size = "sm" /> ;
116+ return DesktopIcon ; // Default to system icon
138117 }
139118 } ;
140119
141120 return (
142121 < Select
143122 id = { id }
144123 isOpen = { isThemeSelectOpen }
145- selected = { themeMode }
146- onSelect = { handleThemeChange }
147124 onOpenChange = { ( isOpen ) => setIsThemeSelectOpen ( isOpen ) }
148125 toggle = { ( toggleRef ) => (
149126 < MenuToggle
@@ -162,50 +139,86 @@ export const ThemeSelector = ({ id }) => {
162139 preventOverflow : true
163140 } }
164141 >
142+ < SelectGroup label = { ThemeVariantGroupLabel } >
143+ < MenuSearch >
144+ < MenuSearchInput >
145+ < ToggleGroup aria-labelledby = "theme-selector-variant-title" >
146+ < ToggleGroupItem
147+ text = "Default"
148+ buttonId = { themeVariantModes . DEFAULT }
149+ isSelected = { themeVariant === themeVariantModes . DEFAULT }
150+ onChange = { handleThemeVariantChange }
151+ />
152+ < ToggleGroupItem
153+ text = "Unified"
154+ buttonId = { themeVariantModes . UNIFIED }
155+ isSelected = { themeVariant === themeVariantModes . UNIFIED }
156+ onChange = { handleThemeVariantChange }
157+ />
158+ </ ToggleGroup >
159+ </ MenuSearchInput >
160+ </ MenuSearch >
161+ </ SelectGroup >
162+ < Divider />
165163 < SelectGroup label = { ColorSchemeGroupLabel } >
166- < SelectList aria-labelledby = "theme-selector-color-scheme-title" >
167- < SelectOption value = { colorModes . SYSTEM } icon = { DesktopIcon } description = "Follow system preference" >
168- System
169- </ SelectOption >
170- < SelectOption value = { colorModes . LIGHT } icon = { SunIcon } description = "Always use light mode" >
171- Light
172- </ SelectOption >
173- < SelectOption value = { colorModes . DARK } icon = { MoonIcon } description = "Always use dark mode" >
174- Dark
175- </ SelectOption >
176- </ SelectList >
164+ < MenuSearch >
165+ < MenuSearchInput >
166+ < ToggleGroup aria-labelledby = "theme-selector-color-scheme-title" >
167+ < ToggleGroupItem
168+ text = "System"
169+ buttonId = { colorModes . SYSTEM }
170+ isSelected = { themeMode === colorModes . SYSTEM }
171+ onChange = { handleThemeChange }
172+ />
173+ < ToggleGroupItem
174+ text = "Light"
175+ buttonId = { colorModes . LIGHT }
176+ isSelected = { themeMode === colorModes . LIGHT }
177+ onChange = { handleThemeChange }
178+ />
179+ < ToggleGroupItem
180+ text = "Dark"
181+ buttonId = { colorModes . DARK }
182+ isSelected = { themeMode === colorModes . DARK }
183+ onChange = { handleThemeChange }
184+ />
185+ </ ToggleGroup >
186+ </ MenuSearchInput >
187+ </ MenuSearch >
188+ </ SelectGroup >
189+ < Divider />
190+ < SelectGroup label = { ContrastModeGroupLabel } >
191+ < MenuSearch >
192+ < MenuSearchInput >
193+ < ToggleGroup aria-labelledby = "theme-selector-contrast-title" >
194+ < ToggleGroupItem
195+ text = "System"
196+ buttonId = { contrastModes . SYSTEM }
197+ isSelected = { contrastMode === contrastModes . SYSTEM }
198+ onChange = { handleContrastModeChange }
199+ />
200+ < ToggleGroupItem
201+ text = "Default"
202+ buttonId = { contrastModes . DEFAULT }
203+ isSelected = { contrastMode === contrastModes . DEFAULT }
204+ onChange = { handleContrastModeChange }
205+ />
206+ < ToggleGroupItem
207+ text = "High contrast"
208+ buttonId = { contrastModes . HIGH_CONTRAST }
209+ isSelected = { contrastMode === contrastModes . HIGH_CONTRAST }
210+ onChange = { handleContrastModeChange }
211+ />
212+ < ToggleGroupItem
213+ text = "Glass"
214+ buttonId = { contrastModes . GLASS }
215+ isSelected = { contrastMode === contrastModes . GLASS }
216+ onChange = { handleContrastModeChange }
217+ />
218+ </ ToggleGroup >
219+ </ MenuSearchInput >
220+ </ MenuSearch >
177221 </ SelectGroup >
178- { process . env . hasHighContrastSwitcher && (
179- < >
180- < Divider />
181- < SelectGroup label = { HighContrastGroupLabel } >
182- < MenuSearch >
183- < MenuSearchInput >
184- < ToggleGroup aria-label = "High contrast theme switcher" >
185- < ToggleGroupItem
186- text = "System"
187- buttonId = { highContrastModes . SYSTEM }
188- isSelected = { highContrastMode === highContrastModes . SYSTEM }
189- onChange = { handleHighContrastThemeSelection }
190- />
191- < ToggleGroupItem
192- text = "On"
193- buttonId = { highContrastModes . ON }
194- isSelected = { highContrastMode === highContrastModes . ON }
195- onChange = { handleHighContrastThemeSelection }
196- />
197- < ToggleGroupItem
198- text = "Off"
199- buttonId = { highContrastModes . OFF }
200- isSelected = { highContrastMode === highContrastModes . OFF }
201- onChange = { handleHighContrastThemeSelection }
202- />
203- </ ToggleGroup >
204- </ MenuSearchInput >
205- </ MenuSearch >
206- </ SelectGroup >
207- </ >
208- ) }
209222 </ Select >
210223 ) ;
211224} ;
0 commit comments