@adecore/shell 0.26.3 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,4 +2,8 @@ export interface ThemeState {
2
2
  resolved: 'light' | 'dark';
3
3
  followsSystem: boolean;
4
4
  background: string;
5
+ overlay?: {
6
+ color: string;
7
+ symbolColor: string;
8
+ };
5
9
  }
package/dist/theme.d.ts CHANGED
@@ -2,10 +2,7 @@ import type { BrowserWindow, BrowserWindowConstructorOptions, NativeTheme } from
2
2
  import type { ThemeState } from './bridge/theme.ts';
3
3
  export interface TitleBarOverlay {
4
4
  height: number;
5
- colors: Record<ThemeState['resolved'], {
6
- color: string;
7
- symbolColor: string;
8
- }>;
5
+ colors: Record<ThemeState['resolved'], NonNullable<ThemeState['overlay']>>;
9
6
  }
10
7
  export interface ThemeOptions {
11
8
  nativeTheme: Pick<NativeTheme, 'themeSource'>;
package/dist/theme.js CHANGED
@@ -7,12 +7,22 @@
7
7
  export const createTheme = (options) => {
8
8
  const platform = options.platform ?? process.platform;
9
9
  let current = null;
10
- const overlayOf = (resolved) => options.overlay ? { height: options.overlay.height, ...options.overlay.colors[resolved] } : undefined;
10
+ /*
11
+ * The colors a page reports win over the ones per theme, so the controls stay on its ground after it
12
+ * changed and a window opened later starts on it too. Only the two colors are taken from what crossed IPC.
13
+ */
14
+ const overlayOf = (theme) => {
15
+ if (!options.overlay) {
16
+ return undefined;
17
+ }
18
+ const { color, symbolColor } = theme.overlay ?? options.overlay.colors[theme.resolved];
19
+ return { height: options.overlay.height, color, symbolColor };
20
+ };
11
21
  return {
12
22
  apply: (theme) => {
13
23
  current = theme;
14
24
  options.nativeTheme.themeSource = theme.followsSystem ? 'system' : theme.resolved;
15
- const overlay = platform === 'darwin' ? undefined : overlayOf(theme.resolved);
25
+ const overlay = platform === 'darwin' ? undefined : overlayOf(theme);
16
26
  for (const window of options.windows()) {
17
27
  if (window.isDestroyed()) {
18
28
  continue;
@@ -26,8 +36,7 @@ export const createTheme = (options) => {
26
36
  current: () => current,
27
37
  /* The constructor options of a new window: its own chrome and the ground the others have. Dark until a page says otherwise. */
28
38
  windowOptions: () => {
29
- const resolved = current?.resolved ?? 'dark';
30
- const overlay = overlayOf(resolved);
39
+ const overlay = overlayOf(current ?? { resolved: 'dark' });
31
40
  const chrome = platform === 'darwin'
32
41
  ? { titleBarStyle: 'hiddenInset', trafficLightPosition: options.trafficLights ?? { x: 17, y: 17 } }
33
42
  : { titleBarStyle: 'hidden', ...(overlay ? { titleBarOverlay: overlay } : {}) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/shell",
3
- "version": "0.26.3",
3
+ "version": "0.27.0",
4
4
  "description": "The main process of an Electron app: its menu, its updater and the guards around its page.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
@@ -5,4 +5,9 @@ export interface ThemeState {
5
5
  followsSystem: boolean;
6
6
  /* The page's ground, so the window paints it before the page does. */
7
7
  background: string;
8
+ /*
9
+ * The colors of the native window controls off macOS, for a page whose ground is not one fixed color per
10
+ * theme. Without it the shell takes the colors it was given for `resolved`.
11
+ */
12
+ overlay?: { color: string; symbolColor: string };
8
13
  }
package/src/theme.ts CHANGED
@@ -4,7 +4,7 @@ import type { ThemeState } from './bridge/theme.ts';
4
4
  /* The native window controls a page leaves room for off macOS, with their colors per theme. */
5
5
  export interface TitleBarOverlay {
6
6
  height: number;
7
- colors: Record<ThemeState['resolved'], { color: string; symbolColor: string }>;
7
+ colors: Record<ThemeState['resolved'], NonNullable<ThemeState['overlay']>>;
8
8
  }
9
9
 
10
10
  export interface ThemeOptions {
@@ -29,14 +29,23 @@ export const createTheme = (options: ThemeOptions) => {
29
29
  const platform = options.platform ?? process.platform;
30
30
  let current: ThemeState | null = null;
31
31
 
32
- const overlayOf = (resolved: ThemeState['resolved']) =>
33
- options.overlay ? { height: options.overlay.height, ...options.overlay.colors[resolved] } : undefined;
32
+ /*
33
+ * The colors a page reports win over the ones per theme, so the controls stay on its ground after it
34
+ * changed and a window opened later starts on it too. Only the two colors are taken from what crossed IPC.
35
+ */
36
+ const overlayOf = (theme: Pick<ThemeState, 'resolved' | 'overlay'>) => {
37
+ if (!options.overlay) {
38
+ return undefined;
39
+ }
40
+ const { color, symbolColor } = theme.overlay ?? options.overlay.colors[theme.resolved];
41
+ return { height: options.overlay.height, color, symbolColor };
42
+ };
34
43
 
35
44
  return {
36
45
  apply: (theme: ThemeState): void => {
37
46
  current = theme;
38
47
  options.nativeTheme.themeSource = theme.followsSystem ? 'system' : theme.resolved;
39
- const overlay = platform === 'darwin' ? undefined : overlayOf(theme.resolved);
48
+ const overlay = platform === 'darwin' ? undefined : overlayOf(theme);
40
49
  for (const window of options.windows()) {
41
50
  if (window.isDestroyed()) {
42
51
  continue;
@@ -52,8 +61,7 @@ export const createTheme = (options: ThemeOptions) => {
52
61
 
53
62
  /* The constructor options of a new window: its own chrome and the ground the others have. Dark until a page says otherwise. */
54
63
  windowOptions: (): BrowserWindowConstructorOptions => {
55
- const resolved = current?.resolved ?? 'dark';
56
- const overlay = overlayOf(resolved);
64
+ const overlay = overlayOf(current ?? { resolved: 'dark' });
57
65
  const chrome: BrowserWindowConstructorOptions =
58
66
  platform === 'darwin'
59
67
  ? { titleBarStyle: 'hiddenInset', trafficLightPosition: options.trafficLights ?? { x: 17, y: 17 } }