Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: move system-theme-extractor to i-static-page/modules/theme #1116

Merged
merged 20 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ _Note: Gaps between patch versions are faulty, broken or test releases._

* Added support for different cookie stores: `core/cookies`, `core/kv-storage/engines/cookie`

#### :house: Internal

* Moved `system-theme-extractor` from `core` to `components/super/i-static-page/modules/theme`

## v4.0.0-beta.57 (2024-02-13)

#### :bug: Bug Fix
Expand Down Expand Up @@ -70,6 +74,7 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
#### :house: Internal

* Create a `mono` template in `i-block` for dynamic mono components. It disables vnode attribute hoisting.
>>>>>>> v4

## v4.0.0-beta.54 (2024-02-06)

Expand Down
8 changes: 5 additions & 3 deletions src/components/super/i-static-page/i-static-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { setLocale, locale } from 'core/i18n';

import type { AppliedRoute, InitialRoute } from 'core/router';
import * as cookie from 'core/kv-storage/engines/cookie';
import { webEngineFactory } from 'core/system-theme-extractor/engines/web';
import { SystemThemeExtractorWeb } from 'components/super/i-static-page/modules/theme';

import {

Expand Down Expand Up @@ -103,8 +103,10 @@ export default abstract class iStaticPage extends iPage {
*/
@system<iStaticPage>((o) => themeManagerFactory(
o,
cookie.syncLocalStorage,
webEngineFactory(o)
{
themeStorageEngine: cookie.syncLocalStorage,
systemThemeExtractor: new SystemThemeExtractorWeb(o)
}
))

readonly theme: CanUndef<ThemeManager>;
Expand Down
42 changes: 37 additions & 5 deletions src/components/super/i-static-page/modules/theme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,24 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, {

## Accessors

## current
### availableThemes

A set of available app themes.

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.availableThemes);
}
}
```

## Methods

### get

Current theme value.

Expand All @@ -103,22 +120,37 @@ import iBlock, { component, prop, field } from 'components/super/i-block/i-block
@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.current);
console.log(this.r.theme.get());
}
}
```

## availableThemes
### set

A set of available app themes.
Sets a new value for the current theme.

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
changeTheme(value: 'dark' | 'light') {
this.r.theme.set(value);
}
}
```

### useSystem

Sets the actual system theme and activates the system theme change listener.

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.availableThemes);
this.r.theme.useSystem();
}
}
```
16 changes: 8 additions & 8 deletions src/components/super/i-static-page/modules/theme/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { StorageEngine } from 'core/kv-storage';

import type iBlock from 'components/super/i-block/i-block';
import ThemeManager from 'components/super/i-static-page/modules/theme/theme-manager';
import type { StorageEngine } from 'core/kv-storage';
import type { SystemThemeExtractor } from 'core/system-theme-extractor';

import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';

/**
* Returns an instance of the class for managing interface themes, if that functionality is available
* Returns an instance of the class for managing interface themes if that functionality is available
*
* @param component
* @param store
* @param systemTheme
* @param engines
*/
export default function themeManagerFactory(
component: iBlock,
store: StorageEngine,
systemTheme: SystemThemeExtractor
engines: {themeStorageEngine: StorageEngine; systemThemeExtractor: SystemThemeExtractor}
): CanNull<ThemeManager> {
return Object.isString(THEME) ? new ThemeManager(component, store, systemTheme) : null;
return Object.isString(THEME) ? new ThemeManager(component, engines) : null;
}
4 changes: 3 additions & 1 deletion src/components/super/i-static-page/modules/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* @packageDocumentation
*/

export * from 'components/super/i-static-page/modules/theme/const';
export { default } from 'components/super/i-static-page/modules/theme/factory';

export { default as ThemeManager } from 'components/super/i-static-page/modules/theme/theme-manager';
export * from 'components/super/i-static-page/modules/theme/const';
export { default as SystemThemeExtractorWeb } from 'components/super/i-static-page/modules/theme/system-theme-extractor/engines/web/engine';
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]

## v4.0.0-beta.?? (2024-??-??)

#### :house: Internal

* Moved from `core` to `components/super/i-static-page/modules/theme`

## v4.0.0-beta.52 (2023-01-31)

#### :rocket: New Feature
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# core/system-theme-extractor
# components/super/i-static-page/modules/theme/system-theme-extractor

This module provides an API for obtaining and observing the preferred color scheme of an application.

Expand All @@ -9,12 +9,12 @@ By default, the engine for the web is supported.
The engine needs to be passed to the `themeManager` constructor.

```ts
import { webEngineFactory } from 'core/system-theme-extractor/engines/web';
import { SystemThemeExtractorWeb } from 'components/super/i-static-page/modules/theme';

class iRoot extends iStaticPage {
@system<iStaticPage>((o) => themeManagerFactory(
// ...other required parameters for themeManager
webEngineFactory(o)
new SystemThemeExtractorWeb(o)
))

readonly theme: CanUndef<ThemeManager>;
Expand All @@ -24,16 +24,16 @@ class iRoot extends iStaticPage {
Also, you can implement your own engine.

```ts
// src/core/system-theme-extractor/engines/custom/index.ts
import type { SystemThemeExtractor } from 'core/system-theme-extractor';
// src/components/super/i-static-page/modules/theme/system-theme-extractor/engines/custom/index.ts
import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';

export default class CustomEngine implements SystemThemeExtractor {
// Implement all necessary methods of the interface here.
}
```

The `SystemThemeExtractor` interface specifies that the `getSystemTheme` method
should return a promise-like object so that you can compute the system theme asynchronously.
If synchronous computation is relevant in your case, you can use `SyncPromise`.
The `SystemThemeExtractor` interface specifies that the `getSystemTheme` method should return a Promise object,
allowing for asynchronous computation of the system theme.
If synchronous computation is necessary for your case, you can use `SyncPromise`.

See `components/super/i-static-page/modules/theme` for details
See `components/super/i-static-page/modules/theme` for details.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { EventEmitterLikeP, AsyncOptions } from 'core/async';
import SyncPromise from 'core/promise/sync';

import Friend from 'components/friends/friend';
import type iBlock from 'components/super/i-block/i-block';

import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';

/**
* Represents a `SystemThemeExtractor` implementation tailored for web environments.
* This implementation uses a media query to monitor changes in the preferred color scheme.
*/
export default class WebEngine extends Friend implements SystemThemeExtractor {
/**
* Media query to watch theme changes
*/
protected darkThemeMq: MediaQueryList;

/**
* Event emitter
*/
protected emitter: EventEmitterLikeP;

constructor(component: iBlock) {
super(component);

this.darkThemeMq = globalThis.matchMedia('(prefers-color-scheme: dark)');

type EmitterArgs = [string, (e: Event) => void];

this.emitter = Object.cast((...args: EmitterArgs) => {
this.darkThemeMq.addEventListener(...args);
return (...args: EmitterArgs) => this.darkThemeMq.removeEventListener(...args);
});
}

/** @inheritDoc */
getSystemTheme(): SyncPromise<string> {
return SyncPromise.resolve(this.darkThemeMq.matches ? 'dark' : 'light');
}

/** @inheritDoc */
onThemeChange(cb: (value: string) => void, asyncOptions?: AsyncOptions): void {
const changeHandler = (e: MediaQueryListEvent) => cb(e.matches ? 'dark' : 'light');
this.ctx.async.on(this.emitter, 'change', changeHandler, asyncOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

export * from 'core/system-theme-extractor/interface';
export * from 'components/super/i-static-page/modules/theme/system-theme-extractor/interface';
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { AsyncOptions } from 'core/async/modules/base/interface';

/**
* An API for retrieving and monitoring the system's visual appearance
*/
export interface SystemThemeExtractor {
/**
* Retrieves the current system visual appearance theme
*/
getSystemTheme(): Promise<string>;

/**
* Initializes an event listener for changes in the system's visual appearance theme
*
* @param cb - a callback function to be invoked when the theme changes.
* It receives the color scheme identifier as a string parameter,
* by which the project's theme can be selected.
*
* @param [asyncOptions]
*/
onThemeChange(cb: (value: string) => void, asyncOptions?: AsyncOptions): void;
}
Loading
Loading