Skip to content

Commit

Permalink
chore(theme): added theme provider
Browse files Browse the repository at this point in the history
  • Loading branch information
pimenovoleg committed Jun 21, 2024
1 parent f303a50 commit 27a4770
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 145 deletions.
Empty file.
61 changes: 0 additions & 61 deletions packages/components/checkbox/src/checkbox.ts

This file was deleted.

49 changes: 0 additions & 49 deletions packages/components/checkbox/src/style.css

This file was deleted.

32 changes: 0 additions & 32 deletions packages/components/checkbox/stories/checkbox.stories.ts

This file was deleted.

6 changes: 4 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"peerDependencies": {
"@angular/common": "^17.3.0",
"@angular/core": "^17.3.0",
"@radix-ng/primitives": "^0.2.0"
"@radix-ng/primitives": "workspace:*"
},
"devDependencies": {
"@radix-ng/primitives": "workspace:*"
},
"devDependencies": {},
"dependencies": {
"tslib": "^2.3.0"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/components/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './src/theme.directive';
export * from './src/theme.service';
File renamed without changes.
92 changes: 92 additions & 0 deletions packages/components/theme/src/theme.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
Directive,
effect,
ElementRef,
inject,
OnChanges,
OnInit,
Renderer2,
signal
} from '@angular/core';

import { ThemeService } from './theme.service';

@Directive({
selector: '[rdxAppTheme]',
standalone: true
})
export class RdxThemeDirective implements OnInit, OnChanges {
private readonly themeService = inject(ThemeService);
private readonly elementRef = inject(ElementRef);
private readonly renderer = inject(Renderer2);

appearance = signal<string>('default');
accentColor = signal<string>('default');
grayColor = signal<string>('default');
panelBackground = signal<string>('default');
radius = signal<string>('default');
scaling = signal<string>('default');

isRoot = signal<boolean>(false);

ngOnInit() {
this.applyTheme();
effect(() => this.updateClasses());
}

ngOnChanges() {
this.applyTheme();
}

private applyTheme() {
this.themeService.setAppearance(this.appearance());
this.themeService.setAccentColor(this.accentColor());
this.themeService.setGrayColor(this.grayColor());
this.themeService.setPanelBackground(this.panelBackground());
this.themeService.setRadius(this.radius());
this.themeService.setScaling(this.scaling());
}

private updateClasses() {
const context = this.themeService.contextSignal();

const themeClasses = {
'theme-light': context.appearance === 'light',
'theme-dark': context.appearance === 'dark',
'theme-accent-blue': context.accentColor === 'blue',
'theme-gray-auto': context.grayColor === 'auto'
// Add more classes as necessary
};

for (const [key, value] of Object.entries(themeClasses)) {
if (value) {
this.renderer.addClass(this.elementRef.nativeElement, key);
} else {
this.renderer.removeClass(this.elementRef.nativeElement, key);
}
}
}

private updateAttributes() {
const context = this.themeService.contextSignal();

this.renderer.setAttribute(
this.elementRef.nativeElement,
'data-is-root-theme',
this.isRoot() ? 'true' : 'false'
);
this.renderer.setAttribute(
this.elementRef.nativeElement,
'data-accent-color',
context.accentColor
);
this.renderer.setAttribute(
this.elementRef.nativeElement,
'data-gray-color',
context.grayColor
);

this.renderer.setAttribute(this.elementRef.nativeElement, 'data-radius', context.radius);
this.renderer.setAttribute(this.elementRef.nativeElement, 'data-scaling', context.scaling);
}
}
52 changes: 52 additions & 0 deletions packages/components/theme/src/theme.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Injectable, signal, WritableSignal } from '@angular/core';

interface ThemeContextValue {
appearance: string;
accentColor: string;
grayColor: string;
panelBackground: string;
radius: string;
scaling: string;
}

@Injectable({
providedIn: 'root'
})
export class ThemeService {
private context = signal<ThemeContextValue>({
appearance: 'default',
accentColor: 'default',
grayColor: 'default',
panelBackground: 'default',
radius: 'default',
scaling: 'default'
});

get contextSignal(): WritableSignal<ThemeContextValue> {
return this.context;
}

setAppearance(appearance: string) {
this.context.update((current) => ({ ...current, appearance }));
}

setAccentColor(accentColor: string) {
this.context.update((current) => ({ ...current, accentColor }));
}

setGrayColor(grayColor: string) {
this.context.update((current) => ({ ...current, grayColor }));
}

setPanelBackground(panelBackground: string) {
this.context.update((current) => ({ ...current, panelBackground }));
}

setRadius(radius: string) {
this.context.update((current) => ({ ...current, radius }));
}

setScaling(scaling: string) {
this.context.update((current) => ({ ...current, scaling }));
}
}
25 changes: 25 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
packages:
- "apps/docs/**"

- "packages/components/**"
- "packages/primitives/**"
- "!**/dist/**"
1 change: 1 addition & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
"@radix-ng/components/theme": ["packages/components/theme/index.ts"],
"@radix-ng/primitives/checkbox": ["packages/primitives/checkbox/index.ts"],
"@radix-ng/primitives/label": ["packages/primitives/label/index.ts"],
"@radix-ng/primitives/radio": ["packages/primitives/radio/index.ts"],
Expand Down

0 comments on commit 27a4770

Please sign in to comment.