Skip to content

Commit

Permalink
feat(core): TUI_DARK_MODE add new token (#8657)
Browse files Browse the repository at this point in the history
Co-authored-by: taiga-family-bot <[email protected]>
  • Loading branch information
waterplea and taiga-family-bot authored Aug 26, 2024
1 parent a5f4afa commit f409942
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 23 deletions.
4 changes: 2 additions & 2 deletions projects/addon-doc/components/demo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {AbstractControl} from '@angular/forms';
import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
import type {Params, UrlTree} from '@angular/router';
import {UrlSerializer} from '@angular/router';
import {TuiDocThemeDarkService} from '@taiga-ui/addon-doc/services';
import {TUI_DOC_DEMO_TEXTS, TUI_DOC_URL_STATE_HANDLER} from '@taiga-ui/addon-doc/tokens';
import type {TuiDemoParams} from '@taiga-ui/addon-doc/types';
import {tuiCleanObject, tuiCoerceValueIsTrue} from '@taiga-ui/addon-doc/utils';
Expand All @@ -24,6 +23,7 @@ import {tuiPure, tuiPx} from '@taiga-ui/cdk/utils/miscellaneous';
import {TuiButton} from '@taiga-ui/core/components/button';
import {TuiExpand} from '@taiga-ui/core/components/expand';
import {TuiGroup} from '@taiga-ui/core/directives/group';
import {TUI_DARK_MODE} from '@taiga-ui/core/tokens';
import {TuiDataListWrapper} from '@taiga-ui/kit/components/data-list-wrapper';
import {TuiSwitch} from '@taiga-ui/kit/components/switch';
import {TuiChevron} from '@taiga-ui/kit/directives/chevron';
Expand Down Expand Up @@ -80,7 +80,7 @@ export class TuiDocDemo implements OnInit {
protected readonly template: TemplateRef<Record<string, unknown>> | null = null;

protected dark = tuiCoerceValueIsTrue(
this.params.darkMode ?? inject(TuiDocThemeDarkService).value,
this.params.darkMode ?? inject(TUI_DARK_MODE)(),
);

protected testForm?: FormGroup;
Expand Down
16 changes: 4 additions & 12 deletions projects/addon-doc/components/main/main.component.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
import {AsyncPipe} from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
inject,
ViewEncapsulation,
} from '@angular/core';
import {RouterOutlet} from '@angular/router';
import {TuiDocThemeDarkService} from '@taiga-ui/addon-doc/services';
import {TUI_DOC_ICONS} from '@taiga-ui/addon-doc/tokens';
import {TuiButton} from '@taiga-ui/core/components/button';
import {TuiRoot} from '@taiga-ui/core/components/root';
import {TUI_DARK_MODE} from '@taiga-ui/core/tokens';

import {TuiDocHeader} from '../internal/header';
import {TuiDocNavigation} from '../navigation/navigation.component';

@Component({
standalone: true,
selector: 'tui-doc-main',
imports: [
TuiRoot,
AsyncPipe,
RouterOutlet,
TuiButton,
TuiDocHeader,
TuiDocNavigation,
],
imports: [TuiRoot, RouterOutlet, TuiButton, TuiDocHeader, TuiDocNavigation],
templateUrl: './main.template.html',
styleUrls: ['./main.style.less'],
encapsulation: ViewEncapsulation.None,
Expand All @@ -35,9 +27,9 @@ import {TuiDocNavigation} from '../navigation/navigation.component';
export class TuiDocMain {
private readonly icons = inject(TUI_DOC_ICONS);

protected readonly dark$ = inject(TuiDocThemeDarkService);
protected readonly darkMode = inject(TUI_DARK_MODE);

protected get icon(): string {
return this.dark$.value ? this.icons.light : this.icons.dark;
return this.darkMode() ? this.icons.light : this.icons.dark;
}
}
4 changes: 2 additions & 2 deletions projects/addon-doc/components/main/main.template.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<tui-root [attr.tuiTheme]="(dark$ | async) ? 'dark' : null">
<tui-root [attr.tuiTheme]="darkMode() ? 'dark' : null">
<div class="tui-doc-page">
<tui-doc-navigation class="tui-doc-navigation">
<ng-content select="tuiDocNavigation" />
Expand All @@ -17,7 +17,7 @@
class="tui-doc-dark-mode-switch"
[iconStart]="icon"
[style.border-radius.%]="100"
(click)="dark$.toggle()"
(click)="darkMode.set(!darkMode())"
></button>
</header>
<ng-container ngProjectAs="tuiOverContent">
Expand Down
19 changes: 17 additions & 2 deletions projects/addon-doc/services/theme-dark.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import {inject, Injectable} from '@angular/core';
import {WA_LOCAL_STORAGE, WA_WINDOW} from '@ng-web-apis/common';
import {tuiCreateToken} from '@taiga-ui/cdk/utils/miscellaneous';
import {TUI_DARK_MODE_DEFAULT_KEY, TUI_DARK_MODE_KEY} from '@taiga-ui/core/tokens';
import {BehaviorSubject} from 'rxjs';

export const TUI_DARK_THEME_DEFAULT_KEY = 'tuiDark';
export const TUI_DARK_THEME_KEY = tuiCreateToken(TUI_DARK_THEME_DEFAULT_KEY);
/**
* @deprecated use {@link TUI_DARK_THEME} instead
*/
export const TUI_DARK_THEME_DEFAULT_KEY = TUI_DARK_MODE_DEFAULT_KEY;

/**
* @deprecated use {@link TUI_DARK_THEME} instead
*/
export const TUI_DARK_THEME_KEY = TUI_DARK_MODE_KEY;

/**
* @deprecated use {@link TUI_DARK_THEME} instead
*/
export const TUI_DARK_THEME = tuiCreateToken(false);

/**
* @deprecated use {@link TUI_DARK_THEME} instead
*/
@Injectable({
providedIn: 'root',
})
Expand Down
3 changes: 3 additions & 0 deletions projects/core/services/dark-theme.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import {inject, Injectable} from '@angular/core';
import {WA_WINDOW} from '@ng-web-apis/common';
import {fromEvent, map, Observable, shareReplay, startWith} from 'rxjs';

/**
* @deprecated use {@link TUI_DARK_MODE} instead
*/
@Injectable({
providedIn: 'root',
})
Expand Down
49 changes: 49 additions & 0 deletions projects/core/tokens/dark-mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {effect, inject, InjectionToken, signal, type WritableSignal} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {WA_LOCAL_STORAGE, WA_WINDOW} from '@ng-web-apis/common';
import {tuiCreateToken} from '@taiga-ui/cdk/utils/miscellaneous';
import {filter, fromEvent} from 'rxjs';

export const TUI_DARK_MODE_DEFAULT_KEY = 'tuiDark';
export const TUI_DARK_MODE_KEY = tuiCreateToken(TUI_DARK_MODE_DEFAULT_KEY);
export const TUI_DARK_MODE = new InjectionToken<
WritableSignal<boolean> & {reset(): void}
>('', {
factory: () => {
let automatic = true;

const storage = inject(WA_LOCAL_STORAGE);
const key = inject(TUI_DARK_MODE_KEY);
const saved = storage.getItem(key);
const media = inject(WA_WINDOW).matchMedia('(prefers-color-scheme: dark)');
const result = signal(Boolean((saved && JSON.parse(saved)) ?? media.matches));

fromEvent(media, 'change')
.pipe(
filter(() => !storage.getItem(key)),
takeUntilDestroyed(),
)
.subscribe(() => {
automatic = true;
result.set(media.matches);
});

effect(() => {
const value = String(result());

if (automatic) {
automatic = false;
} else {
storage.setItem(key, value);
}
});

return Object.assign(result, {
reset: () => {
storage.removeItem(key);
automatic = true;
result.set(media.matches);
},
});
},
});
1 change: 1 addition & 0 deletions projects/core/tokens/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './animations-speed';
export * from './assets-path';
export * from './common-icons';
export * from './dark-mode';
export * from './date-format';
export * from './day-type-handler';
export * from './first-day-of-week';
Expand Down
17 changes: 17 additions & 0 deletions projects/demo/src/modules/directives/theme/examples/2/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Dark mode enabled: {{ darkMode() }}
<p>
<button
tuiButton
(click)="darkMode.set(!darkMode())"
>
Toggle
</button>
<button
tuiButton
(click)="darkMode.reset()"
>
Reset
</button>
</p>
<p>Add to Root to enable:</p>
<code>&lt;tui-root [attr.tuiTheme]="darkMode() ? 'dark' : null'"&gt;</code>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
p {
display: flex;
gap: 1rem;
}

code {
white-space: nowrap !important;
}
26 changes: 26 additions & 0 deletions projects/demo/src/modules/directives/theme/examples/2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Component, inject} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';
import {WA_LOCAL_STORAGE, WA_WINDOW} from '@ng-web-apis/common';
import {TUI_DARK_MODE, TUI_DARK_MODE_KEY, TuiButton} from '@taiga-ui/core';

@Component({
standalone: true,
imports: [TuiButton],
templateUrl: './index.html',
styleUrls: ['./index.less'],
encapsulation,
changeDetection,
})
export default class Example {
private readonly key = inject(TUI_DARK_MODE_KEY);
private readonly storage = inject(WA_LOCAL_STORAGE);
private readonly media = inject(WA_WINDOW).matchMedia('(prefers-color-scheme: dark)');

protected readonly darkMode = inject(TUI_DARK_MODE);

protected reset(): void {
this.darkMode.set(this.media.matches);
this.storage.removeItem(this.key);
}
}
9 changes: 5 additions & 4 deletions projects/demo/src/modules/directives/theme/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
are included. Importing is not required.

<tui-doc-example
id="themes"
heading="Themes"
[component]="1 | tuiComponent"
[content]="1 | tuiExample"
*ngFor="let example of examples; let index = index"
[component]="index + 1 | tuiComponent"
[content]="index + 1 | tuiExample"
[heading]="example"
[id]="example | tuiKebab"
/>
</ng-template>
</tui-doc-page>
4 changes: 3 additions & 1 deletion projects/demo/src/modules/directives/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ import {TuiDemo} from '@demo/utils';
templateUrl: './index.html',
changeDetection,
})
export default class Page {}
export default class Page {
protected readonly examples = ['Themes', 'Toggling'];
}

0 comments on commit f409942

Please sign in to comment.