Skip to content

Commit ce65667

Browse files
committed
WIP
1 parent 40581cc commit ce65667

File tree

6 files changed

+75
-19
lines changed

6 files changed

+75
-19
lines changed

packages/components/src/components/hds/theme-switcher/index.hbs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,21 @@
33
SPDX-License-Identifier: MPL-2.0
44
}}
55

6-
<Hds::Dropdown @enableCollisionDetection={{true}} @matchToggleWidth={{@toggleIsFullWidth}} class="hds-theme-switcher-control" ...attributes as |D|>
7-
<D.ToggleButton @color="secondary" @size={{this.toggleSize}} @isFullWidth={{@toggleIsFullWidth}} @text={{this.toggleContent.label}} @icon={{this.toggleContent.icon}} />
6+
<Hds::Dropdown
7+
@enableCollisionDetection={{true}}
8+
@matchToggleWidth={{@toggleIsFullWidth}}
9+
class="hds-theme-switcher-control"
10+
...attributes
11+
as |D|
12+
>
13+
<D.ToggleButton
14+
@color="secondary"
15+
@size={{this.toggleSize}}
16+
@isFullWidth={{@toggleIsFullWidth}}
17+
@text={{this.toggleContent.label}}
18+
@icon={{this.toggleContent.icon}}
19+
/>
820
{{#each-in this._options as |key data|}}
921
<D.Interactive @icon={{data.icon}} {{on "click" (fn this.setTheme data.theme)}}>{{data.label}}</D.Interactive>
1022
{{/each-in}}
11-
</Hds::Dropdown>
23+
</Hds::Dropdown>

packages/components/src/components/hds/theme-switcher/index.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,53 @@ import { action } from '@ember/object';
99

1010
import type { HdsDropdownSignature } from '../dropdown/index.ts';
1111
import type { HdsDropdownToggleButtonSignature } from '../dropdown/toggle/button.ts';
12+
import type { HdsIconSignature } from '../icon/index.ts';
1213
import type HdsThemingService from '../../../services/hds-theming.ts';
1314
import { type HdsThemes } from '../../../services/hds-theming.ts';
1415

15-
export const OPTIONS = {
16-
none: { theme: undefined, icon: 'minus', label: 'None' },
16+
type ThemeOptionKey = 'system' | 'light' | 'dark'; // | 'none';
17+
18+
interface ThemeOption {
19+
theme: HdsThemes;
20+
icon: HdsIconSignature['Args']['name'];
21+
label: string;
22+
}
23+
24+
export const OPTIONS: Record<ThemeOptionKey, ThemeOption> = {
1725
system: { theme: 'system', icon: 'monitor', label: 'System' },
1826
light: { theme: 'light', icon: 'sun', label: 'Light' },
1927
dark: { theme: 'dark', icon: 'moon', label: 'Dark' },
20-
} as const;
28+
// none: { theme: undefined, icon: 'minus', label: 'None' },
29+
};
2130

2231
export interface HdsThemeSwitcherSignature {
2332
Args: {
2433
toggleSize?: HdsDropdownToggleButtonSignature['Args']['size'];
2534
toggleIsFullWidth?: boolean;
35+
hasSystemOption?: boolean;
36+
// hasNoThemeOption?: boolean;
2637
};
2738
Element: HdsDropdownSignature['Element'];
2839
}
2940

3041
export default class HdsThemeSwitcher extends Component<HdsThemeSwitcherSignature> {
3142
@service declare readonly hdsTheming: HdsThemingService;
3243

33-
_options = OPTIONS;
44+
get _options() {
45+
const options: Partial<typeof OPTIONS> = { ...OPTIONS };
46+
const hasSystemOption = this.args.hasSystemOption ?? true;
47+
// const hasNoThemeOption = this.args.hasNoThemeOption ?? false;
48+
49+
if (!hasSystemOption) {
50+
delete options.system;
51+
}
52+
53+
// if (!hasNoThemeOption) {
54+
// delete options.none;
55+
// }
56+
57+
return options;
58+
}
3459

3560
get toggleSize() {
3661
return this.args.toggleSize ?? 'small';
@@ -52,6 +77,7 @@ export default class HdsThemeSwitcher extends Component<HdsThemeSwitcherSignatur
5277
}
5378

5479
get currentTheme() {
80+
// we get the theme from the global service
5581
return this.hdsTheming.currentTheme;
5682
}
5783

packages/components/src/services/hds-theming.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const HDS_THEMING_CLASS_SELECTOR = 'hds-theme';
88
export const HDS_THEMING_LOCALSTORAGE_KEY = 'hds-current-theming-preferences';
99

1010
export enum HdsThemeValues {
11-
// system settings
11+
// system settings (prefers-color-scheme)
1212
System = 'system',
1313
// user settings for dark/light
1414
Light = 'light',
@@ -33,8 +33,8 @@ type ThemeSelector = 'data' | 'class';
3333

3434
export type HdsThemingServiceOptions = {
3535
themeMap: {
36-
[HdsThemeValues.Light]: HdsModes;
37-
[HdsThemeValues.Dark]: HdsModes;
36+
[HdsThemeValues.Light]: HdsModeValues.CdsG0 | HdsModeValues.CdsG10;
37+
[HdsThemeValues.Dark]: HdsModeValues.CdsG90 | HdsModeValues.CdsG100;
3838
};
3939
themeSelector: ThemeSelector;
4040
};
@@ -44,18 +44,20 @@ export default class HdsThemingService extends Service {
4444
@tracked currentMode: HdsModes = undefined;
4545
@tracked currentThemingServiceOptions: HdsThemingServiceOptions = {
4646
themeMap: {
47-
[HdsThemeValues.Light]: HdsModeValues.Hds, // TODO understand if we want to use `CdsG0` here instead
47+
[HdsThemeValues.Light]: HdsModeValues.CdsG0,
4848
[HdsThemeValues.Dark]: HdsModeValues.CdsG100,
4949
},
5050
themeSelector: 'data',
5151
};
5252

5353
constructor(owner: Owner) {
5454
super(owner);
55+
console.log('HdsThemingService constructor');
5556
this.initializeTheme();
5657
}
5758

5859
initializeTheme() {
60+
console.log('HdsThemingService > initializeTheme');
5961
const storedTheme = localStorage.getItem(
6062
HDS_THEMING_LOCALSTORAGE_KEY
6163
) as HdsThemes;
@@ -76,11 +78,7 @@ export default class HdsThemingService extends Service {
7678
return;
7779
}
7880

79-
if (
80-
theme === undefined ||
81-
theme === HdsThemeValues.System ||
82-
!THEMES.includes(theme)
83-
) {
81+
if (theme === undefined || !THEMES.includes(theme)) {
8482
this.currentTheme = undefined;
8583
this.currentMode = undefined;
8684
if (this.currentThemingServiceOptions.themeSelector === 'data') {
@@ -91,8 +89,11 @@ export default class HdsThemingService extends Service {
9189
localStorage.removeItem(HDS_THEMING_LOCALSTORAGE_KEY);
9290
} else {
9391
this.currentTheme = theme;
94-
// TODO theme may be `system` in which case what happens to
95-
this.currentMode = this.currentThemingServiceOptions.themeMap[theme];
92+
if (theme === HdsThemeValues.System) {
93+
this.currentMode = undefined;
94+
} else {
95+
this.currentMode = this.currentThemingServiceOptions.themeMap[theme];
96+
}
9697
if (this.currentThemingServiceOptions.themeSelector === 'data') {
9798
rootElement.setAttribute(HDS_THEMING_DATA_SELECTOR, this.currentMode);
9899
} else if (this.currentThemingServiceOptions.themeSelector === 'class') {

showcase/app/components/page-foundations/theming/sub-sections/theme-switcher.gts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ const SubSectionThemeSwitcher: TemplateOnlyComponent = <template>
3131
</ShwFlex>
3232

3333
<ShwDivider />
34+
35+
<ShwTextH4 @tag="h3">Options</ShwTextH4>
36+
37+
<ShwFlex @gap="2rem" as |SF|>
38+
<SF.Item @label="System/Light/Dark (default)">
39+
<HdsThemeSwitcher />
40+
</SF.Item>
41+
<SF.Item @label="Only Light/Dark">
42+
<HdsThemeSwitcher @hasSystemOption={{false}} />
43+
</SF.Item>
44+
</ShwFlex>
45+
46+
<ShwDivider />
3447
</template>;
3548

3649
export default SubSectionThemeSwitcher;

showcase/app/components/shw/theme-switcher/index.gts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { service } from '@ember/service';
1010
import { eq } from 'ember-truth-helpers';
1111
// import { tracked } from '@glimmer/tracking';
1212

13-
import type HdsThemingService from '@hashicorp/design-system-components/services/hds-theming.ts';
13+
import type HdsThemingService from '@hashicorp/design-system-components/services/hds-theming';
1414

1515
interface ShwThemeSwitcherSignature {
1616
Element: HTMLDivElement;

showcase/app/controllers/application.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ import { tracked } from '@glimmer/tracking';
1010
import type RouterService from '@ember/routing/router-service';
1111
import type Owner from '@ember/owner';
1212

13+
import type HdsThemingService from '@hashicorp/design-system-components/services/hds-theming';
14+
1315
export default class ApplicationController extends Controller {
1416
@service declare readonly router: RouterService;
17+
@service declare readonly hdsTheming: HdsThemingService;
1518

1619
@tracked isFrameless = false;
1720

1821
constructor(owner: Owner) {
1922
super(owner);
2023
this.router.on('routeDidChange', this.routeDidChange.bind(this));
24+
this.hdsTheming.initializeTheme();
2125
}
2226

2327
routeDidChange() {

0 commit comments

Comments
 (0)