Skip to content

Commit b72f94f

Browse files
committed
enhance theme selector
1 parent 259780e commit b72f94f

File tree

3 files changed

+292
-133
lines changed

3 files changed

+292
-133
lines changed

packages/documentation-framework/components/themeSelector/themeSelector.js

Lines changed: 107 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,15 @@ import React, { useState } from 'react';
22
import {
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';
2014
import { useTheme, THEME_TYPES } from '../../hooks/useTheme';
2115

2216
const 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+
5355
const 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-
&nbsp;
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

9971
export 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

Comments
 (0)