15 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
3 | "organizeImports": {
4 | "enabled": true
5 | },
6 | "linter": {
7 | "enabled": true,
8 | "rules": {
9 | "recommended": true,
10 | "style": {
11 | "noParameterAssign": "warn",
12 | "noNonNullAssertion": "warn",
13 | "useNodejsImportProtocol": "warn"
14 | },
15 | "suspicious": {
16 | "noAssignInExpressions": "warn"
17 | }
18 | }
19 | },
20 | "vcs": {
21 | "enabled": true,
22 | "clientKind": "git",
23 | "useIgnoreFile": true
24 | },
25 | "formatter": {
26 | "enabled": true,
27 | "indentStyle": "space",
28 | "indentWidth": 2
29 | },
30 | "javascript": {
31 | "formatter": {
32 | "quoteStyle": "single",
33 | "jsxQuoteStyle": "double"
34 | }
35 | },
36 | "json": {
37 | "parser": {
38 | "allowComments": true
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/native-menu/main.js:
--------------------------------------------------------------------------------
1 | const { app, Menu, Tray } = require('electron');
2 | const path = require('path');
3 |
4 | const { menubar } = require('../../');
5 |
6 | const iconPath = path.join(__dirname, '..', '..', 'assets', 'IconTemplate.png');
7 |
8 | app.on('ready', () => {
9 | const tray = new Tray(iconPath);
10 | const contextMenu = Menu.buildFromTemplate([
11 | { label: 'Item1', type: 'radio' },
12 | { label: 'Item2', type: 'radio' },
13 | { label: 'Item3', type: 'radio', checked: true },
14 | { label: 'Item4', type: 'radio' },
15 | ]);
16 | tray.setContextMenu(contextMenu);
17 |
18 | const mb = menubar({
19 | tray,
20 | });
21 |
22 | mb.on('ready', () => {
23 | // needed for macos to remove white screen
24 | // ref: https://github.com/max-mapper/menubar/issues/345
25 | tray.removeAllListeners();
26 |
27 | console.log('Menubar app is ready.');
28 | // your app code here
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Before opening issues
2 |
3 | **If you are asking a question**:
4 |
5 | Remember that `menubar` is just a lightweight wrapper around Electron. Most of the time you can probably find the answer to your question already answered in the [Electron Issue Tracker](https://github.com/electron/electron/issues)
6 |
7 | **For bug reports/technical issues**:
8 |
9 | Please provide the following information when opening issues:
10 |
11 | - Which version of menubar are you using?
12 | - What cli arguments are you passing?
13 | - What platform are you running menubar on?
14 | - Is there a stack trace in the error message you're seeing?
15 | - If possible, please provide instructions to reproduce your problem.
16 |
17 | Thanks!
18 |
19 | ## Releases
20 |
21 | - commit your changes
22 | - `npm version `
23 | - `git push && git push --tags` (or `git push` with `git config --global push.followTags true` on latest git)
24 | - `npm publish`
25 |
--------------------------------------------------------------------------------
/docs/modules/_util_getwindowposition_.md:
--------------------------------------------------------------------------------
1 | > **[menubar](../README.md)**
2 |
3 | [Globals](../globals.md) / ["util/getWindowPosition"](_util_getwindowposition_.md) /
4 |
5 | # External module: "util/getWindowPosition"
6 |
7 | ## Index
8 |
9 | ### Functions
10 |
11 | * [getWindowPosition](_util_getwindowposition_.md#getwindowposition)
12 | * [taskbarLocation](_util_getwindowposition_.md#taskbarlocation)
13 |
14 | ## Functions
15 |
16 | ### getWindowPosition
17 |
18 | ▸ **getWindowPosition**(`tray`: `Tray`): *`WindowPosition`*
19 |
20 | *Defined in [util/getWindowPosition.ts:52](https://github.com/adam-lynch/menubar/blob/6b93752/src/util/getWindowPosition.ts#L52)*
21 |
22 | **Parameters:**
23 |
24 | Name | Type | Description |
25 | ------ | ------ | ------ |
26 | `tray` | `Tray` | The Electron Tray instance. |
27 |
28 | **Returns:** *`WindowPosition`*
29 |
30 | ___
31 |
32 | ### taskbarLocation
33 |
34 | ▸ **taskbarLocation**(`tray`: `Tray`): *`TaskbarLocation`*
35 |
36 | *Defined in [util/getWindowPosition.ts:18](https://github.com/adam-lynch/menubar/blob/6b93752/src/util/getWindowPosition.ts#L18)*
37 |
38 | **Parameters:**
39 |
40 | Name | Type | Description |
41 | ------ | ------ | ------ |
42 | `tray` | `Tray` | The Electron Tray instance. |
43 |
44 | **Returns:** *`TaskbarLocation`*
--------------------------------------------------------------------------------
/src/Menubar.spec.ts:
--------------------------------------------------------------------------------
1 | import { BrowserWindow, Tray, app } from 'electron';
2 |
3 | import { Menubar } from './Menubar';
4 |
5 | describe('Menubar', () => {
6 | let mb: Menubar | undefined;
7 |
8 | beforeEach(() => {
9 | mb = new Menubar(app, { preloadWindow: true });
10 | });
11 |
12 | it('should have property `app`', () => {
13 | expect(mb!.app).toBeDefined();
14 | });
15 |
16 | it('should have property `positioner`', () => {
17 | expect(() => mb!.positioner as unknown).toThrow();
18 | return new Promise((resolve) => {
19 | mb!.on('after-create-window', () => {
20 | expect(mb!.positioner).toBeDefined();
21 | resolve();
22 | });
23 | });
24 | });
25 |
26 | it('should have property `tray`', () => {
27 | expect(() => mb!.tray).toThrow();
28 | return new Promise((resolve) => {
29 | mb!.on('ready', () => {
30 | expect(mb!.tray).toBeInstanceOf(Tray);
31 | resolve();
32 | });
33 | });
34 | });
35 |
36 | it('should have property `window`', () => {
37 | expect(mb!.window).toBeUndefined();
38 | return new Promise((resolve) => {
39 | mb!.on('ready', () => {
40 | expect(mb!.window).toBeInstanceOf(BrowserWindow);
41 | resolve();
42 | });
43 | });
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2015-2019, Max Ogden
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "menubar",
3 | "version": "9.5.2",
4 | "author": "Max Ogden",
5 | "bugs": {
6 | "url": "https://github.com/maxogden/menubar/issues"
7 | },
8 | "description": "high level way to create menubar desktop applications with electron",
9 | "files": [
10 | "/assets",
11 | "/lib"
12 | ],
13 | "homepage": "https://github.com/maxogden/menubar",
14 | "keywords": [
15 | "electron",
16 | "shell",
17 | "menubar",
18 | "menu",
19 | "taskbar",
20 | "tray",
21 | "traybar",
22 | "mac",
23 | "linux",
24 | "windows",
25 | "app"
26 | ],
27 | "license": "BSD-2-Clause",
28 | "main": "lib/index.js",
29 | "publishConfig": {
30 | "access": "public"
31 | },
32 | "repository": {
33 | "type": "git",
34 | "url": "https://github.com/maxogden/menubar.git"
35 | },
36 | "scripts": {
37 | "build": "rimraf lib/ && tsc",
38 | "deploy": "yarn build && standard-version",
39 | "docs": "typedoc",
40 | "lint:check": "biome check",
41 | "lint": "biome check --fix",
42 | "test": "jest"
43 | },
44 | "types": "lib/index.d.ts",
45 | "dependencies": {
46 | "electron-positioner": "^4.1.0"
47 | },
48 | "devDependencies": {
49 | "@biomejs/biome": "^1.9.3",
50 | "@types/jest": "^25.2.3",
51 | "electron": "^34.3.0",
52 | "jest": "^26.0.1",
53 | "rimraf": "^3.0.2",
54 | "standard-version": "^8.0.0",
55 | "ts-jest": "^26.0.0",
56 | "typedoc": "^0.17.7",
57 | "typedoc-plugin-markdown": "^2.2.17",
58 | "typedoc-plugin-no-inherit": "^1.1.10",
59 | "typescript": "^4.6.2"
60 | },
61 | "peerDependencies": {
62 | "electron": ">=9.0.0 <35.0.0"
63 | },
64 | "packageManager": "yarn@1.22.22"
65 | }
66 |
--------------------------------------------------------------------------------
/WORKING_PLATFORMS.md:
--------------------------------------------------------------------------------
1 | # Platforms where `menubar` is known to work
2 |
3 | This document is still a work-in-progress. If you have tested `menubar` with a platform that is not listed under here, I would greatly appreciate a PR!
4 |
5 | ## macOS
6 |
7 | | Version | Working Status | Known Issues |
8 | | ----------------- | -------------- | -------------------------------------------------------------------------------------------------------------- |
9 | | 14.15 Sonoma | ✅ Good | |
10 | | 10.14 Mojave | ✅ Good | [#147](https://github.com/maxogden/menubar/issues/147), [#215](https://github.com/maxogden/menubar/issues/215) |
11 | | 10.13 High Sierra | ✅ Good | |
12 |
13 | ## Windows
14 |
15 | | Version | Working Status | Known Issues |
16 | | ---------- | -------------- | ------------ |
17 | | Windows 11 | ✅ Good | |
18 | | Windows 10 | ✅ Good | |
19 | | Windows 8 | ✅ Good | |
20 |
21 | ## Linux
22 |
23 | | Distribution | Desktop Environment | Working Status | Known Issues |
24 | | ------------- | ------------------- | -------------- | ------------------------------------------------------ |
25 | | openSUSE 13.1 | Xfce 4.10.1 | ❌ Bad | [#123](https://github.com/maxogden/menubar/issues/123) |
26 | | Ubuntu 18.04 | Unity | ✅ Good | |
27 | | Ubuntu 14.04 | Unity | ❌ Bad | [#68](https://github.com/maxogden/menubar/issues/68) |
28 |
--------------------------------------------------------------------------------
/src/util/cleanOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @ignore
3 | */
4 |
5 | /** */
6 |
7 | import path from 'path';
8 | import url from 'url';
9 | import { app } from 'electron';
10 |
11 | import type { Options } from '../types';
12 |
13 | const DEFAULT_WINDOW_HEIGHT = 400;
14 | const DEFAULT_WINDOW_WIDTH = 400;
15 |
16 | /**
17 | * Take as input some options, and return a sanitized version of it.
18 | *
19 | * @param opts - The options to clean.
20 | * @ignore
21 | */
22 | export function cleanOptions(opts?: Partial): Options {
23 | const options: Partial = { ...opts };
24 |
25 | if (options.activateWithApp === undefined) {
26 | options.activateWithApp = true;
27 | }
28 | if (!options.dir) {
29 | options.dir = app.getAppPath();
30 | }
31 | if (!path.isAbsolute(options.dir)) {
32 | options.dir = path.resolve(options.dir);
33 | }
34 | // Note: options.index can be `false`
35 | if (options.index === undefined) {
36 | options.index = url.format({
37 | pathname: path.join(options.dir, 'index.html'),
38 | protocol: 'file:',
39 | slashes: true,
40 | });
41 | }
42 | options.loadUrlOptions = options.loadUrlOptions || {};
43 |
44 | options.tooltip = options.tooltip || '';
45 |
46 | // `icon`, `preloadWindow`, `showDockIcon`, `showOnAllWorkspaces`,
47 | // `showOnRightClick` don't need any special treatment
48 |
49 | // Now we take care of `browserWindow`
50 | if (!options.browserWindow) {
51 | options.browserWindow = {};
52 | }
53 |
54 | // Set width/height on options to be usable before the window is created
55 | options.browserWindow.width =
56 | // Note: not using `options.browserWindow.width || DEFAULT_WINDOW_WIDTH` so
57 | // that users can put a 0 width
58 | options.browserWindow.width !== undefined
59 | ? options.browserWindow.width
60 | : DEFAULT_WINDOW_WIDTH;
61 | options.browserWindow.height =
62 | options.browserWindow.height !== undefined
63 | ? options.browserWindow.height
64 | : DEFAULT_WINDOW_HEIGHT;
65 |
66 | return options as Options;
67 | }
68 |
--------------------------------------------------------------------------------
/src/util/cleanOptions.spec.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 |
3 | import { MOCK_APP_GETAPPPATH } from '../__mocks__/electron';
4 | import { cleanOptions } from './cleanOptions';
5 |
6 | const DEFAULT_OPTIONS = {
7 | activateWithApp: true,
8 | browserWindow: {
9 | height: 400,
10 | width: 400,
11 | },
12 | dir: path.resolve(MOCK_APP_GETAPPPATH),
13 | index: `file://${path.join(path.resolve(MOCK_APP_GETAPPPATH), 'index.html')}`,
14 | loadUrlOptions: {},
15 | tooltip: '',
16 | };
17 |
18 | describe('cleanOptions', () => {
19 | it('should handle undefined', () => {
20 | expect(cleanOptions(undefined)).toEqual(DEFAULT_OPTIONS);
21 | });
22 |
23 | it('should handle a dir string with relative path', () => {
24 | expect(cleanOptions({ dir: 'MY_RELATIVE_PATH' })).toEqual({
25 | ...DEFAULT_OPTIONS,
26 | dir: path.resolve('MY_RELATIVE_PATH'),
27 | index: `file://${path.join(
28 | path.resolve('MY_RELATIVE_PATH'),
29 | 'index.html',
30 | )}`,
31 | });
32 | });
33 |
34 | it('should handle a dir string with absolute path', () => {
35 | expect(cleanOptions({ dir: '/home/me/MY_ABSOLUTE_PATH' })).toEqual({
36 | ...DEFAULT_OPTIONS,
37 | dir: '/home/me/MY_ABSOLUTE_PATH',
38 | index: 'file:///home/me/MY_ABSOLUTE_PATH/index.html',
39 | });
40 | });
41 |
42 | it('should handle a false index', () => {
43 | expect(cleanOptions({ index: false })).toEqual({
44 | ...DEFAULT_OPTIONS,
45 | index: false,
46 | });
47 | });
48 |
49 | it('should handle an object with multiple fields', () => {
50 | expect(
51 | cleanOptions({
52 | browserWindow: {
53 | height: 100,
54 | },
55 | index: 'file:///home/abc/index.html',
56 | showDockIcon: true,
57 | windowPosition: 'trayCenter',
58 | }),
59 | ).toEqual({
60 | ...DEFAULT_OPTIONS,
61 | browserWindow: {
62 | ...DEFAULT_OPTIONS.browserWindow,
63 | height: 100,
64 | },
65 | index: 'file:///home/abc/index.html',
66 | showDockIcon: true,
67 | windowPosition: 'trayCenter',
68 | });
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/src/util/getWindowPosition.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Utilities to get taskbar position and consequently menubar's position
3 | */
4 |
5 | /** */
6 |
7 | import { type Rectangle, type Tray, screen as electronScreen } from 'electron';
8 |
9 | const isLinux = process.platform === 'linux';
10 |
11 | const trayToScreenRects = (tray: Tray): [Rectangle, Rectangle] => {
12 | // There may be more than one screen, so we need to figure out on which screen our tray icon lives.
13 | const { workArea, bounds: screenBounds } = electronScreen.getDisplayMatching(
14 | tray.getBounds(),
15 | );
16 |
17 | workArea.x -= screenBounds.x;
18 | workArea.y -= screenBounds.y;
19 |
20 | return [screenBounds, workArea];
21 | };
22 |
23 | type TaskbarLocation = 'top' | 'bottom' | 'left' | 'right';
24 |
25 | /**
26 | * Determine taskbard location: "top", "bottom", "left" or "right".
27 | *
28 | * Only tested on Windows for now, and only used in Windows.
29 | *
30 | * @param tray - The Electron Tray instance.
31 | */
32 | export function taskbarLocation(tray: Tray): TaskbarLocation {
33 | const [screenBounds, workArea] = trayToScreenRects(tray);
34 |
35 | // TASKBAR LEFT
36 | if (workArea.x > 0) {
37 | // Most likely Ubuntu hence assuming the window should be on top
38 | if (isLinux && workArea.y > 0) return 'top';
39 | // The workspace starts more on the right
40 | return 'left';
41 | }
42 |
43 | // TASKBAR TOP
44 | if (workArea.y > 0) {
45 | return 'top';
46 | }
47 |
48 | // TASKBAR RIGHT
49 | // Here both workArea.y and workArea.x are 0 so we can no longer leverage them.
50 | // We can use the workarea and display width though.
51 | // Determine taskbar location
52 | if (workArea.width < screenBounds.width) {
53 | // The taskbar is either on the left or right, but since the LEFT case was handled above,
54 | // we can be sure we're dealing with a right taskbar
55 | return 'right';
56 | }
57 |
58 | // TASKBAR BOTTOM
59 | // Since all the other cases were handled, we can be sure we're dealing with a bottom taskbar
60 | return 'bottom';
61 | }
62 |
63 | type WindowPosition =
64 | | 'trayCenter'
65 | | 'topRight'
66 | | 'trayBottomCenter'
67 | | 'bottomLeft'
68 | | 'bottomRight';
69 |
70 | /**
71 | * Depending on where the taskbar is, determine where the window should be
72 | * positioned.
73 | *
74 | * @param tray - The Electron Tray instance.
75 | */
76 | export function getWindowPosition(tray: Tray): WindowPosition {
77 | switch (process.platform) {
78 | // macOS
79 | // Supports top taskbars
80 | case 'darwin':
81 | return 'trayCenter';
82 | // Linux
83 | // Windows
84 | // Supports top/bottom/left/right taskbar
85 | case 'linux':
86 | case 'win32': {
87 | const traySide = taskbarLocation(tray);
88 |
89 | // Assign position for menubar
90 | if (traySide === 'top') {
91 | return isLinux ? 'topRight' : 'trayCenter';
92 | }
93 | if (traySide === 'bottom') {
94 | return 'bottomRight';
95 | }
96 | if (traySide === 'left') {
97 | return 'bottomLeft';
98 | }
99 | if (traySide === 'right') {
100 | return 'bottomRight';
101 | }
102 | }
103 | }
104 |
105 | // When we really don't know, we just show the menubar on the top-right
106 | return 'topRight';
107 | }
108 |
--------------------------------------------------------------------------------
/docs/interfaces/_types_.options.md:
--------------------------------------------------------------------------------
1 | > **[menubar](../README.md)**
2 |
3 | [Globals](../globals.md) / ["types"](../modules/_types_.md) / [Options](_types_.options.md) /
4 |
5 | # Interface: Options
6 |
7 | ## Hierarchy
8 |
9 | * **Options**
10 |
11 | ## Table of Contents
12 |
13 | ### Properties
14 |
15 | * [browserWindow](_types_.options.md#browserwindow)
16 | * [dir](_types_.options.md#dir)
17 | * [icon](_types_.options.md#optional-icon)
18 | * [index](_types_.options.md#index)
19 | * [loadUrlOptions](_types_.options.md#optional-loadurloptions)
20 | * [preloadWindow](_types_.options.md#optional-preloadwindow)
21 | * [showDockIcon](_types_.options.md#optional-showdockicon)
22 | * [showOnAllWorkspaces](_types_.options.md#optional-showonallworkspaces)
23 | * [showOnRightClick](_types_.options.md#optional-showonrightclick)
24 | * [tooltip](_types_.options.md#tooltip)
25 | * [tray](_types_.options.md#optional-tray)
26 | * [windowPosition](_types_.options.md#optional-windowposition)
27 |
28 | ## Properties
29 |
30 | ### browserWindow
31 |
32 | • **browserWindow**: *`BrowserWindowConstructorOptions`*
33 |
34 | *Defined in [types.ts:23](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L23)*
35 |
36 | ___
37 |
38 | ### dir
39 |
40 | • **dir**: *string*
41 |
42 | *Defined in [types.ts:27](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L27)*
43 |
44 | ___
45 |
46 | ### `Optional` icon
47 |
48 | • **icon**? : *string | `NativeImage`*
49 |
50 | *Defined in [types.ts:34](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L34)*
51 |
52 | ___
53 |
54 | ### index
55 |
56 | • **index**: *string | false*
57 |
58 | *Defined in [types.ts:43](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L43)*
59 |
60 | ___
61 |
62 | ### `Optional` loadUrlOptions
63 |
64 | • **loadUrlOptions**? : *`LoadURLOptions`*
65 |
66 | *Defined in [types.ts:51](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L51)*
67 |
68 | ___
69 |
70 | ### `Optional` preloadWindow
71 |
72 | • **preloadWindow**? : *undefined | false | true*
73 |
74 | *Defined in [types.ts:56](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L56)*
75 |
76 | ___
77 |
78 | ### `Optional` showDockIcon
79 |
80 | • **showDockIcon**? : *undefined | false | true*
81 |
82 | *Defined in [types.ts:61](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L61)*
83 |
84 | ___
85 |
86 | ### `Optional` showOnAllWorkspaces
87 |
88 | • **showOnAllWorkspaces**? : *undefined | false | true*
89 |
90 | *Defined in [types.ts:66](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L66)*
91 |
92 | ___
93 |
94 | ### `Optional` showOnRightClick
95 |
96 | • **showOnRightClick**? : *undefined | false | true*
97 |
98 | *Defined in [types.ts:70](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L70)*
99 |
100 | ___
101 |
102 | ### tooltip
103 |
104 | • **tooltip**: *string*
105 |
106 | *Defined in [types.ts:74](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L74)*
107 |
108 | ___
109 |
110 | ### `Optional` tray
111 |
112 | • **tray**? : *`Tray`*
113 |
114 | *Defined in [types.ts:78](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L78)*
115 |
116 | ___
117 |
118 | ### `Optional` windowPosition
119 |
120 | • **windowPosition**? : *"trayLeft" | "trayBottomLeft" | "trayRight" | "trayBottomRight" | "trayCenter" | "trayBottomCenter" | "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "topCenter" | "bottomCenter" | "leftCenter" | "rightCenter" | "center"*
121 |
122 | *Defined in [types.ts:83](https://github.com/maxogden/menubar/blob/c7d6640/src/types.ts#L83)*
123 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | BrowserWindowConstructorOptions,
3 | LoadURLOptions,
4 | Tray,
5 | } from 'electron';
6 |
7 | /**
8 | * Options for creating a menubar application
9 | */
10 | export interface Options {
11 | /**
12 | * Listen on `app.on('activate')` to open menubar when app is activated.
13 | * @default `true`
14 | */
15 | activateWithApp?: boolean;
16 | /**
17 | * An Electron BrowserWindow instance, or an options object to be passed into
18 | * the BrowserWindow constructor.
19 | * @example
20 | * ```typescript
21 | * const options = { height: 640, width: 480 };
22 | *
23 | * const mb = new Menubar({
24 | * browserWindow: options
25 | * });
26 | * ```
27 | */
28 | browserWindow: BrowserWindowConstructorOptions;
29 | /**
30 | * The app source directory.
31 | */
32 | dir: string;
33 | /**
34 | * The png icon to use for the menubar. A good size to start with is 20x20.
35 | * To support retina, supply a 2x sized image (e.g. 40x40) with @2x added to
36 | * the end of the name, so icon.png and icon@2x.png and Electron will
37 | * automatically use your @2x version on retina screens.
38 | */
39 | icon?: string | Electron.NativeImage;
40 | /**
41 | * The URL to load the menubar's browserWindow with. The url can be a remote
42 | * address (e.g. `http://`) or a path to a local HTML file using the
43 | * `file://` protocol. If false, then menubar won't call `loadURL` on
44 | * start.
45 | * @default `file:// + options.dir + index.html`
46 | * @see https://electronjs.org/docs/api/browser-window#winloadurlurl-options
47 | */
48 | index: string | false;
49 | /**
50 | * The options passed when loading the index URL in the menubar's
51 | * browserWindow. Everything browserWindow.loadURL supports is supported;
52 | * this object is simply passed onto browserWindow.loadURL
53 | * @default `{}`
54 | * @see https://electronjs.org/docs/api/browser-window#winloadurlurl-options
55 | */
56 | loadUrlOptions?: LoadURLOptions;
57 | /**
58 | * Create BrowserWindow instance before it is used -- increasing resource
59 | * usage, but making the click on the menubar load faster.
60 | */
61 | preloadWindow?: boolean;
62 | /**
63 | * Configure the visibility of the application dock icon, macOS only. Calls
64 | * [`app.dock.hide`](https://electronjs.org/docs/api/app#appdockhide-macos).
65 | */
66 | showDockIcon?: boolean;
67 | /**
68 | * Makes the window available on all OS X workspaces. Calls
69 | * [`setVisibleOnAllWorkspaces`](https://electronjs.org/docs/api/browser-window#winsetvisibleonallworkspacesvisible-options).
70 | */
71 | showOnAllWorkspaces?: boolean;
72 | /**
73 | * Show the window on 'right-click' event instead of regular 'click'.
74 | */
75 | showOnRightClick?: boolean;
76 | /**
77 | * Menubar tray icon tooltip text. Calls [`tray.setTooltip`](https://electronjs.org/docs/api/tray#traysettooltiptooltip).
78 | */
79 | tooltip: string;
80 | /**
81 | * An electron Tray instance. If provided, `options.icon` will be ignored.
82 | */
83 | tray?: Tray;
84 | /**
85 | * Sets the window position (x and y will still override this), check
86 | * electron-positioner docs for valid values.
87 | */
88 | windowPosition?:
89 | | 'trayLeft'
90 | | 'trayBottomLeft'
91 | | 'trayRight'
92 | | 'trayBottomRight'
93 | | 'trayCenter'
94 | | 'trayBottomCenter'
95 | | 'topLeft'
96 | | 'topRight'
97 | | 'bottomLeft'
98 | | 'bottomRight'
99 | | 'topCenter'
100 | | 'bottomCenter'
101 | | 'leftCenter'
102 | | 'rightCenter'
103 | | 'center';
104 | }
105 |
--------------------------------------------------------------------------------
/docs/classes/_menubar_.menubar.md:
--------------------------------------------------------------------------------
1 | > **[menubar](../README.md)**
2 |
3 | [Globals](../globals.md) / ["Menubar"](../modules/_menubar_.md) / [Menubar](_menubar_.menubar.md) /
4 |
5 | # Class: Menubar
6 |
7 | ## Hierarchy
8 |
9 | * `EventEmitter`
10 |
11 | * **Menubar**
12 |
13 | ## Index
14 |
15 | ### Constructors
16 |
17 | * [constructor](_menubar_.menubar.md#constructor)
18 |
19 | ### Accessors
20 |
21 | * [app](_menubar_.menubar.md#app)
22 | * [positioner](_menubar_.menubar.md#positioner)
23 | * [tray](_menubar_.menubar.md#tray)
24 | * [window](_menubar_.menubar.md#window)
25 |
26 | ### Methods
27 |
28 | * [getOption](_menubar_.menubar.md#getoption)
29 | * [hideWindow](_menubar_.menubar.md#hidewindow)
30 | * [setOption](_menubar_.menubar.md#setoption)
31 | * [showWindow](_menubar_.menubar.md#showwindow)
32 |
33 | ## Constructors
34 |
35 | ### constructor
36 |
37 | \+ **new Menubar**(`app`: `App`, `options?`: `Partial`): *[Menubar](_menubar_.menubar.md)*
38 |
39 | *Defined in [Menubar.ts:24](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L24)*
40 |
41 | **Parameters:**
42 |
43 | Name | Type |
44 | ------ | ------ |
45 | `app` | `App` |
46 | `options?` | `Partial` |
47 |
48 | **Returns:** *[Menubar](_menubar_.menubar.md)*
49 |
50 | ## Accessors
51 |
52 | ### app
53 |
54 | • **app**:
55 |
56 | *Defined in [Menubar.ts:47](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L47)*
57 |
58 | ___
59 |
60 | ### positioner
61 |
62 | • **positioner**:
63 |
64 | *Defined in [Menubar.ts:56](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L56)*
65 |
66 | ___
67 |
68 | ### tray
69 |
70 | • **tray**:
71 |
72 | *Defined in [Menubar.ts:69](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L69)*
73 |
74 | ___
75 |
76 | ### window
77 |
78 | • **window**:
79 |
80 | *Defined in [Menubar.ts:83](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L83)*
81 |
82 | ## Methods
83 |
84 | ### getOption
85 |
86 | ▸ **getOption**<**K**>(`key`: `K`): *`Options[K]`*
87 |
88 | *Defined in [Menubar.ts:92](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L92)*
89 |
90 | **Type parameters:**
91 |
92 | ▪ **K**: *keyof Options*
93 |
94 | **Parameters:**
95 |
96 | Name | Type | Description |
97 | ------ | ------ | ------ |
98 | `key` | `K` | The option key to retrieve, see [Options](../interfaces/_types_.options.md). |
99 |
100 | **Returns:** *`Options[K]`*
101 |
102 | ___
103 |
104 | ### hideWindow
105 |
106 | ▸ **hideWindow**(): *void*
107 |
108 | *Defined in [Menubar.ts:99](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L99)*
109 |
110 | **Returns:** *void*
111 |
112 | ___
113 |
114 | ### setOption
115 |
116 | ▸ **setOption**<**K**>(`key`: `K`, `value`: `Options[K]`): *void*
117 |
118 | *Defined in [Menubar.ts:115](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L115)*
119 |
120 | **Type parameters:**
121 |
122 | ▪ **K**: *keyof Options*
123 |
124 | **Parameters:**
125 |
126 | Name | Type | Description |
127 | ------ | ------ | ------ |
128 | `key` | `K` | The option key to modify, see [Options](../interfaces/_types_.options.md). |
129 | `value` | `Options[K]` | The value to set. |
130 |
131 | **Returns:** *void*
132 |
133 | ___
134 |
135 | ### showWindow
136 |
137 | ▸ **showWindow**(`trayPos?`: `Electron.Rectangle`): *`Promise`*
138 |
139 | *Defined in [Menubar.ts:124](https://github.com/adam-lynch/menubar/blob/6b93752/src/Menubar.ts#L124)*
140 |
141 | **Parameters:**
142 |
143 | Name | Type | Description |
144 | ------ | ------ | ------ |
145 | `trayPos?` | `Electron.Rectangle` | The bounds to show the window in. |
146 |
147 | **Returns:** *`Promise`*
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | > **[menubar](README.md)**
2 |
3 | [Globals](globals.md) /
4 |
5 | [](https://travis-ci.org/maxogden/menubar)
6 | [](https://www.npmjs.com/package/@maxogden/menubar)
7 | [](https://david-dm.org/maxogden/menubar)
8 | 
9 | 
10 |
11 |
12 |
13 |
➖ Menubar
14 |
High level way to create menubar desktop applications with Electron.
15 |
16 |
17 |
18 | This module provides boilerplate for setting up a menubar application using Electron. All you have to do is point it at your `index.html` and `menubar` will handle the rest.
19 |
20 | ✅ Only one dependency, and one peer-dependency.
21 |
22 | ✅ Works on macOS, Windows and most Linuxes. See [details](./WORKING_PLATFORMS.md).
23 |
24 | ✅ 💥 [**3.6kB minified + gzipped**](https://bundlephobia.com/result?p=menubar) 💥
25 |
26 | | | | |
27 | | :-----------------------------------------------------------: | :--------------------------------------------------------: | :------------------------------------------------------: |
28 | | macOS Mojave 10.14 | Windows 10 | Ubuntu 18.04 |
29 |
30 | ## Installation
31 |
32 | ```bash
33 | yarn add menubar
34 | ```
35 |
36 | ## Usage
37 |
38 | Starting with your own new project, run these commands:
39 |
40 | ```bash
41 | $ yarn add menubar
42 | $ touch myApp.js
43 | $ touch index.html
44 | ```
45 |
46 | Fill `index.html` with some HTML, and `myApp.js` like this:
47 |
48 | ```javascript
49 | const { menubar } = require('menubar');
50 |
51 | const mb = menubar();
52 |
53 | mb.on('ready', () => {
54 | console.log('app is ready');
55 | // your app code here
56 | });
57 | ```
58 |
59 | Then use `electron` to run the app:
60 |
61 | ```bash
62 | $ electron myApp.js
63 | ```
64 |
65 | Alternatively, see [`examples/hello-world`](/examples/hello-world) folder for a simple working example.
66 |
67 | ## `Menubar` Class
68 |
69 | The return value of `menubar()` is a `Menubar` class instance, which has these properties:
70 |
71 | - `app`: the [Electron App](https://electronjs.org/docs/api/app) instance,
72 | - `window`: the [Electron Browser Window](https://electronjs.org/docs/api/browser-window) instance,
73 | - `tray`: the [Electron Tray](https://electronjs.org/docs/api/tray) instance,
74 | - `positioner`: the [Electron Positioner](https://github.com/jenslind/electron-positioner) instance,
75 | - `setOption(option, value)`: change an option after menubar is created,
76 | - `getOption(option)`: get an menubar option,
77 | - `showWindow()`: show the menubar window,
78 | - `hideWindow()`: hide the menubar window
79 |
80 | See the reference [API docs](./docs/classes/_menubar_.menubar.md).
81 |
82 | ## `menubar()` Options
83 |
84 | You can pass an optional options object into the `menubar({ ... })` function:
85 |
86 | - `dir` (default `process.cwd()`) - the app source directory
87 | - `index` (default `file:// + opts.dir + index.html`) - The URL to load the menubar's browserWindow with. The url can be a remote address (e.g. `http://`) or a path to a local HTML file using the `file://` protocol.
88 | - `browserWindow` - BrowserWindow options to be passed to the BrowserWindow constructor, see [Electron docs](https://electronjs.org/docs/api/browser-window#new-browserwindowoptions). Some interesting fields to passed down are:
89 | - `x` (default `undefined`) - the x position of the window
90 | - `y` (default `undefined`) - the y position of the window
91 | - `width` (default 400) - window width
92 | - `height` (default 400) - window height
93 | - `alwaysOnTop` (default false) - if true, the window will not hide on blur
94 | - `icon` (default `opts.dir + IconTemplate.png`) - the png icon to use for the menubar. A good size to start with is 20x20. To support retina, supply a 2x sized image (e.g. 40x40) with `@2x` added to the end of the name, so `icon.png` and `icon@2x.png` and Electron will automatically use your `@2x` version on retina screens.
95 | - `tooltip` (default empty) - menubar tray icon tooltip text
96 | - `tray` (default created on-the-fly) - an electron `Tray` instance. if provided `opts.icon` will be ignored
97 | - `preloadWindow` (default false) - Create [BrowserWindow](https://electronjs.org/docs/api/browser-window#new-browserwindowoptions) instance before it is used -- increasing resource usage, but making the click on the menubar load faster.
98 | - `showOnAllWorkspaces` (default true) - Makes the window available on all OS X workspaces.
99 | - `windowPosition` (default trayCenter and trayBottomCenter on Windows) - Sets the window position (x and y will still override this), check [positioner docs](https://github.com/jenslind/electron-positioner#docs) for valid values.
100 | - `showDockIcon` (default false) - Configure the visibility of the application dock icon.
101 | - `showOnRightClick` (default false) - Show the window on 'right-click' event instead of regular 'click'
102 |
103 | See the reference [API docs](./docs/interfaces/_types_.options.md).
104 |
105 | ## Events
106 |
107 | The `Menubar` class is an event emitter:
108 |
109 | - `ready` - when `menubar`'s tray icon has been created and initialized, i.e. when `menubar` is ready to be used. Note: this is different than Electron app's `ready` event, which happens much earlier in the process
110 | - `create-window` - the line before `new BrowserWindow()` is called
111 | - `after-create-window` - the line after all window init code is done
112 | - `show` - the line before `window.show()` is called
113 | - `after-show` - the line after `window.show()` is called
114 | - `hide` - the line before `window.hide()` is called (on window blur)
115 | - `after-hide` - the line after `window.hide()` is called
116 | - `after-close` - after the `.window` (BrowserWindow) property has been deleted
117 | - `focus-lost` - emitted if always-on-top option is set and the user clicks away
118 |
119 | ## Compatibility with Electron
120 |
121 | | menubar | Electron | Notes |
122 | | -------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------- |
123 | | 7.x.x | 7.x.x |
124 | | 6.x.x | 4.x.x \| 5.x.x \| 6.x.x | Not recommended for [security reasons](https://electronjs.org/docs/tutorial/security#17-use-a-current-version-of-electron) |
125 | | <= 5.x.x | <= 3.x.x | Please, _please_ don't use these old versions |
126 |
127 | ## API Docs
128 |
129 | See the reference [API docs](./docs/globals.md).
130 |
131 | ## Tips
132 |
133 | - Use `mb.on('after-create-window', callback)` to run things after your app has loaded. For example you could run `mb.window.openDevTools()` to open the developer tools for debugging, or load a different URL with `mb.window.loadUrl()`
134 | - Use `mb.on('focus-lost')` if you would like to perform some operation when using the option `browserWindow.alwaysOnTop: true`
135 | - To restore focus of previous window after menubar hide, use `mb.on('after-hide', () => { mb.app.hide() } )` or similar
136 | - To create a native menu, you can use `tray.setContextMenu(contextMenu)`, and pass this custom tray to menubar: `const mb = menubar({ tray });`. See [this example](https://github.com/maxogden/menubar/tree/master/examples/native-menu) for more information.
137 | - To avoid a flash when opening your menubar app, you can disable backgrounding the app using the following: `mb.app.commandLine.appendSwitch('disable-backgrounding-occluded-windows', 'true');`
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | [](https://www.npmjs.com/package/menubar)
3 | 
4 | 
5 | 
6 |
7 |
8 |
9 |
➖ Menubar
10 |
High level way to create menubar desktop applications with Electron.
11 |
12 |
13 |
14 | This module provides boilerplate for setting up a menubar application using Electron. All you have to do is point it at your `index.html` and `menubar` will handle the rest.
15 |
16 | ✅ Only one dependency, and one peer-dependency.
17 |
18 | ✅ Works on macOS, Windows and most Linuxes. See [details](./WORKING_PLATFORMS.md).
19 |
20 | ✅ 💥 [**3.6kB minified + gzipped**](https://bundlephobia.com/result?p=menubar) 💥
21 |
22 | | | | |
23 | | :-----------------------------------------------------------: | :--------------------------------------------------------: | :------------------------------------------------------: |
24 | | macOS Mojave 10.14 | Windows 10 | Ubuntu 18.04 |
25 |
26 | ## Installation
27 |
28 | ```bash
29 | yarn add menubar
30 | ```
31 |
32 | ## Usage
33 |
34 | Starting with your own new project, run these commands:
35 |
36 | ```bash
37 | $ yarn add menubar
38 | $ touch myApp.js
39 | $ touch index.html
40 | ```
41 |
42 | Fill `index.html` with some HTML, and `myApp.js` like this:
43 |
44 | ```javascript
45 | const { menubar } = require('menubar');
46 |
47 | const mb = menubar();
48 |
49 | mb.on('ready', () => {
50 | console.log('app is ready');
51 | // your app code here
52 | });
53 | ```
54 |
55 | Then use `electron` to run the app:
56 |
57 | ```bash
58 | $ electron myApp.js
59 | ```
60 |
61 | Alternatively, see [`examples/hello-world`](/examples/hello-world) folder for a simple working example.
62 |
63 | ## `Menubar` Class
64 |
65 | The return value of `menubar()` is a `Menubar` class instance, which has these properties:
66 |
67 | - `app`: the [Electron App](https://electronjs.org/docs/api/app) instance,
68 | - `window`: the [Electron Browser Window](https://electronjs.org/docs/api/browser-window) instance,
69 | - `tray`: the [Electron Tray](https://electronjs.org/docs/api/tray) instance,
70 | - `positioner`: the [Electron Positioner](https://github.com/jenslind/electron-positioner) instance,
71 | - `setOption(option, value)`: change an option after menubar is created,
72 | - `getOption(option)`: get an menubar option,
73 | - `showWindow()`: show the menubar window,
74 | - `hideWindow()`: hide the menubar window
75 |
76 | See the reference [API docs](./docs/classes/_menubar_.menubar.md).
77 |
78 | ## `menubar()` Options
79 |
80 | You can pass an optional options object into the `menubar({ ... })` function:
81 |
82 | - `dir` (default `process.cwd()`) - the app source directory
83 | - `index` (default `file:// + opts.dir + index.html`) - The URL to load the menubar's browserWindow with. The url can be a remote address (e.g. `http://`) or a path to a local HTML file using the `file://` protocol.
84 | - `browserWindow` - BrowserWindow options to be passed to the BrowserWindow constructor, see [Electron docs](https://electronjs.org/docs/api/browser-window#new-browserwindowoptions). Some interesting fields to passed down are:
85 | - `x` (default `undefined`) - the x position of the window
86 | - `y` (default `undefined`) - the y position of the window
87 | - `width` (default 400) - window width
88 | - `height` (default 400) - window height
89 | - `alwaysOnTop` (default false) - if true, the window will not hide on blur
90 | - `icon` (default `opts.dir + IconTemplate.png`) - the png icon to use for the menubar. A good size to start with is 20x20. To support retina, supply a 2x sized image (e.g. 40x40) with `@2x` added to the end of the name, so `icon.png` and `icon@2x.png` and Electron will automatically use your `@2x` version on retina screens.
91 | - `tooltip` (default empty) - menubar tray icon tooltip text
92 | - `tray` (default created on-the-fly) - an electron `Tray` instance. if provided `opts.icon` will be ignored
93 | - `preloadWindow` (default false) - Create [BrowserWindow](https://electronjs.org/docs/api/browser-window#new-browserwindowoptions) instance before it is used -- increasing resource usage, but making the click on the menubar load faster.
94 | - `loadUrlOptions` - (default undefined) The options passed when loading the index URL in the menubar's browserWindow. Everything browserWindow.loadURL supports is supported; this object is simply passed onto [browserWindow.loadURL](https://electronjs.org/docs/api/browser-window#winloadurlurl-options)
95 | - `showOnAllWorkspaces` (default true) - Makes the window available on all OS X workspaces.
96 | - `windowPosition` (default trayCenter and trayBottomCenter on Windows) - Sets the window position (x and y will still override this), check [positioner docs](https://github.com/jenslind/electron-positioner#docs) for valid values.
97 | - `showDockIcon` (default false) - Configure the visibility of the application dock icon.
98 | - `showOnRightClick` (default false) - Show the window on 'right-click' event instead of regular 'click'
99 |
100 | See the reference [API docs](./docs/interfaces/_types_.options.md).
101 |
102 | ## Events
103 |
104 | The `Menubar` class is an event emitter:
105 |
106 | - `ready` - when `menubar`'s tray icon has been created and initialized, i.e. when `menubar` is ready to be used. Note: this is different than Electron app's `ready` event, which happens much earlier in the process
107 | - `create-window` - the line before `new BrowserWindow()` is called
108 | - `before-load` - after create window, before loadUrl (can be used for `require("@electron/remote/main").enable(webContents)`)
109 | - `after-create-window` - the line after all window init code is done and url was loaded
110 | - `show` - the line before `window.show()` is called
111 | - `after-show` - the line after `window.show()` is called
112 | - `hide` - the line before `window.hide()` is called (on window blur)
113 | - `after-hide` - the line after `window.hide()` is called
114 | - `after-close` - after the `.window` (BrowserWindow) property has been deleted
115 | - `focus-lost` - emitted if always-on-top option is set and the user clicks away
116 |
117 | ## Compatibility with Electron
118 |
119 | | menubar | Electron | Notes |
120 | | -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
121 | | 9.x.x | >= 9.x.x <= 34.x.x | |
122 | | 8.x.x | 8.x.xx | |
123 | | 7.x.x | 7.x.xx | |
124 | | 6.x.x | >= 4.x.x < 7.x.x | Not recommended for [security reasons](https://electronjs.org/docs/tutorial/security#17-use-a-current-version-of-electron) |
125 | | <= 5.x.x | <= 3.x.x | Please, _please_ don't use these old versions |
126 |
127 | ## API Docs
128 |
129 | See the reference [API docs](./docs/globals.md).
130 |
131 | ## Tips
132 |
133 | - Use `mb.on('after-create-window', callback)` to run things after your app has loaded. For example you could run `mb.window.openDevTools()` to open the developer tools for debugging, or load a different URL with `mb.window.loadURL()`
134 | - Use `mb.on('focus-lost')` if you would like to perform some operation when using the option `browserWindow.alwaysOnTop: true`
135 | - To restore focus of previous window after menubar hide, use `mb.on('after-hide', () => { mb.app.hide() } )` or similar
136 | - To create a native menu, you can use `tray.setContextMenu(contextMenu)`, and pass this custom tray to menubar: `const mb = menubar({ tray });`. See [this example](https://github.com/maxogden/menubar/tree/master/examples/native-menu) for more information.
137 | - To avoid a flash when opening your menubar app, you can disable backgrounding the app using the following: `mb.app.commandLine.appendSwitch('disable-backgrounding-occluded-windows', 'true');`
138 |
--------------------------------------------------------------------------------
/src/Menubar.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 | import fs from 'fs';
3 | import path from 'path';
4 | import { BrowserWindow, Tray } from 'electron';
5 | import Positioner from 'electron-positioner';
6 |
7 | import type { Options } from './types';
8 | import { cleanOptions } from './util/cleanOptions';
9 | import { getWindowPosition } from './util/getWindowPosition';
10 |
11 | /**
12 | * The main Menubar class.
13 | *
14 | * @noInheritDoc
15 | */
16 | export class Menubar extends EventEmitter {
17 | private _app: Electron.App;
18 | private _browserWindow?: BrowserWindow;
19 | private _blurTimeout: NodeJS.Timeout | null = null; // track blur events with timeout
20 | private _isVisible: boolean; // track visibility
21 | private _cachedBounds?: Electron.Rectangle; // _cachedBounds are needed for double-clicked event
22 | private _options: Options;
23 | private _positioner: Positioner | undefined;
24 | private _tray?: Tray;
25 |
26 | constructor(app: Electron.App, options?: Partial) {
27 | super();
28 | this._app = app;
29 | this._options = cleanOptions(options);
30 | this._isVisible = false;
31 |
32 | if (app.isReady()) {
33 | // See https://github.com/maxogden/menubar/pull/151
34 | process.nextTick(() =>
35 | this.appReady().catch((err) => console.error('menubar: ', err)),
36 | );
37 | } else {
38 | app.on('ready', () => {
39 | this.appReady().catch((err) => console.error('menubar: ', err));
40 | });
41 | }
42 | }
43 |
44 | /**
45 | * The Electron [App](https://electronjs.org/docs/api/app)
46 | * instance.
47 | */
48 | get app(): Electron.App {
49 | return this._app;
50 | }
51 |
52 | /**
53 | * The [electron-positioner](https://github.com/jenslind/electron-positioner)
54 | * instance.
55 | */
56 | get positioner(): Positioner {
57 | if (!this._positioner) {
58 | throw new Error(
59 | 'Please access `this.positioner` after the `after-create-window` event has fired.',
60 | );
61 | }
62 |
63 | return this._positioner;
64 | }
65 |
66 | /**
67 | * The Electron [Tray](https://electronjs.org/docs/api/tray) instance.
68 | */
69 | get tray(): Tray {
70 | if (!this._tray) {
71 | throw new Error(
72 | 'Please access `this.tray` after the `ready` event has fired.',
73 | );
74 | }
75 |
76 | return this._tray;
77 | }
78 |
79 | /**
80 | * The Electron [BrowserWindow](https://electronjs.org/docs/api/browser-window)
81 | * instance, if it's present.
82 | */
83 | get window(): BrowserWindow | undefined {
84 | return this._browserWindow;
85 | }
86 |
87 | /**
88 | * Retrieve a menubar option.
89 | *
90 | * @param key - The option key to retrieve, see {@link Options}.
91 | */
92 | getOption(key: K): Options[K] {
93 | return this._options[key];
94 | }
95 |
96 | /**
97 | * Hide the menubar window.
98 | */
99 | hideWindow(): void {
100 | if (!this._browserWindow || !this._isVisible) {
101 | return;
102 | }
103 | this.emit('hide');
104 | this._browserWindow.hide();
105 | this.emit('after-hide');
106 | this._isVisible = false;
107 | if (this._blurTimeout) {
108 | clearTimeout(this._blurTimeout);
109 | this._blurTimeout = null;
110 | }
111 | }
112 |
113 | /**
114 | * Change an option after menubar is created.
115 | *
116 | * @param key - The option key to modify, see {@link Options}.
117 | * @param value - The value to set.
118 | */
119 | setOption(key: K, value: Options[K]): void {
120 | this._options[key] = value;
121 | }
122 |
123 | /**
124 | * Show the menubar window.
125 | *
126 | * @param trayPos - The bounds to show the window in.
127 | */
128 | async showWindow(trayPos?: Electron.Rectangle): Promise {
129 | if (!this.tray) {
130 | throw new Error('Tray should have been instantiated by now');
131 | }
132 |
133 | if (!this._browserWindow) {
134 | await this.createWindow();
135 | }
136 |
137 | // Use guard for TypeScript, to avoid ! everywhere
138 | if (!this._browserWindow) {
139 | throw new Error('Window has been initialized just above. qed.');
140 | }
141 |
142 | // 'Windows' taskbar: sync windows position each time before showing
143 | // https://github.com/maxogden/menubar/issues/232
144 | if (['win32', 'linux'].includes(process.platform)) {
145 | // Fill in this._options.windowPosition when taskbar position is available
146 | this._options.windowPosition = getWindowPosition(this.tray);
147 | }
148 |
149 | this.emit('show');
150 |
151 | if (trayPos && trayPos.x !== 0) {
152 | // Cache the bounds
153 | this._cachedBounds = trayPos;
154 | } else if (this._cachedBounds) {
155 | // Cached value will be used if showWindow is called without bounds data
156 | trayPos = this._cachedBounds;
157 | } else if (this.tray.getBounds) {
158 | // Get the current tray bounds
159 | trayPos = this.tray.getBounds();
160 | }
161 |
162 | // Default the window to the right if `trayPos` bounds are undefined or null.
163 | let noBoundsPosition = undefined;
164 | if (
165 | (trayPos === undefined || trayPos.x === 0) &&
166 | this._options.windowPosition &&
167 | this._options.windowPosition.startsWith('tray')
168 | ) {
169 | noBoundsPosition =
170 | process.platform === 'win32' ? 'bottomRight' : 'topRight';
171 | }
172 |
173 | const position = this.positioner.calculate(
174 | this._options.windowPosition || noBoundsPosition,
175 | trayPos,
176 | ) as { x: number; y: number };
177 |
178 | // Not using `||` because x and y can be zero.
179 | const x =
180 | this._options.browserWindow.x !== undefined
181 | ? this._options.browserWindow.x
182 | : position.x;
183 | const y =
184 | this._options.browserWindow.y !== undefined
185 | ? this._options.browserWindow.y
186 | : position.y;
187 |
188 | // `.setPosition` crashed on non-integers
189 | // https://github.com/maxogden/menubar/issues/233
190 | this._browserWindow.setPosition(Math.round(x), Math.round(y));
191 | this._browserWindow.show();
192 | this._isVisible = true;
193 | this.emit('after-show');
194 | return;
195 | }
196 |
197 | private async appReady(): Promise {
198 | if (this.app.dock && !this._options.showDockIcon) {
199 | this.app.dock.hide();
200 | }
201 |
202 | if (this._options.activateWithApp) {
203 | this.app.on('activate', (_event, hasVisibleWindows) => {
204 | if (!hasVisibleWindows) {
205 | this.showWindow().catch(console.error);
206 | }
207 | });
208 | }
209 |
210 | let trayImage =
211 | this._options.icon || path.join(this._options.dir, 'IconTemplate.png');
212 | if (typeof trayImage === 'string' && !fs.existsSync(trayImage)) {
213 | trayImage = path.join(__dirname, '..', 'assets', 'IconTemplate.png'); // Default cat icon
214 | }
215 |
216 | const defaultClickEvent = this._options.showOnRightClick
217 | ? 'right-click'
218 | : 'click';
219 |
220 | this._tray = this._options.tray || new Tray(trayImage);
221 | // Type guards for TS not to complain
222 | if (!this.tray) {
223 | throw new Error('Tray has been initialized above');
224 | }
225 | this.tray.on(
226 | defaultClickEvent as Parameters[0],
227 | this.clicked.bind(this),
228 | );
229 | this.tray.on('double-click', this.clicked.bind(this));
230 | this.tray.setToolTip(this._options.tooltip);
231 |
232 | if (!this._options.windowPosition) {
233 | this._options.windowPosition = getWindowPosition(this.tray);
234 | }
235 |
236 | if (this._options.preloadWindow) {
237 | await this.createWindow();
238 | }
239 |
240 | this.emit('ready');
241 | }
242 |
243 | /**
244 | * Callback on tray icon click or double-click.
245 | *
246 | * @param e
247 | * @param bounds
248 | */
249 | private async clicked(
250 | event?: Electron.KeyboardEvent,
251 | bounds?: Electron.Rectangle,
252 | ): Promise {
253 | if (event && (event.shiftKey || event.ctrlKey || event.metaKey)) {
254 | return this.hideWindow();
255 | }
256 |
257 | // if blur was invoked clear timeout
258 | if (this._blurTimeout) {
259 | clearInterval(this._blurTimeout);
260 | }
261 |
262 | if (this._browserWindow && this._isVisible) {
263 | return this.hideWindow();
264 | }
265 |
266 | this._cachedBounds = bounds || this._cachedBounds;
267 | await this.showWindow(this._cachedBounds);
268 | }
269 |
270 | private async createWindow(): Promise {
271 | this.emit('create-window');
272 |
273 | // We add some default behavior for menubar's browserWindow, to make it
274 | // look like a menubar
275 | const defaults = {
276 | show: false, // Don't show it at first
277 | frame: false, // Remove window frame
278 | };
279 |
280 | this._browserWindow = new BrowserWindow({
281 | ...defaults,
282 | ...this._options.browserWindow,
283 | });
284 |
285 | this._positioner = new Positioner(this._browserWindow);
286 |
287 | this._browserWindow.on('blur', () => {
288 | if (!this._browserWindow) {
289 | return;
290 | }
291 |
292 | // hack to close if icon clicked when open
293 | this._browserWindow.isAlwaysOnTop()
294 | ? this.emit('focus-lost')
295 | : (this._blurTimeout = setTimeout(() => {
296 | this.hideWindow();
297 | }, 100));
298 | });
299 |
300 | if (this._options.showOnAllWorkspaces !== false) {
301 | // https://github.com/electron/electron/issues/37832#issuecomment-1497882944
302 | this._browserWindow.setVisibleOnAllWorkspaces(true, {
303 | skipTransformProcessType: true, // Avoid damaging the original visible state of app.dock
304 | });
305 | }
306 |
307 | this._browserWindow.on('close', this.windowClear.bind(this));
308 |
309 | this.emit('before-load');
310 |
311 | // If the user explicity set options.index to false, we don't loadURL
312 | // https://github.com/maxogden/menubar/issues/255
313 | if (this._options.index !== false) {
314 | await this._browserWindow.loadURL(
315 | this._options.index,
316 | this._options.loadUrlOptions,
317 | );
318 | }
319 | this.emit('after-create-window');
320 | }
321 |
322 | private windowClear(): void {
323 | this._browserWindow = undefined;
324 | this.emit('after-close');
325 | }
326 | }
327 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ### [9.5.2](https://github.com/maxogden/menubar/compare/v9.5.1...v9.5.2) (2025-10-10)
6 |
7 | ### [9.5.1](https://github.com/maxogden/menubar/compare/v9.5.0...v9.5.1) (2024-10-11)
8 |
9 | ## [9.5.0](https://github.com/maxogden/menubar/compare/v9.4.0...v9.5.0) (2024-06-25)
10 |
11 |
12 | ### Features
13 |
14 | * widen electron support ([#473](https://github.com/maxogden/menubar/issues/473)) ([bd3beb2](https://github.com/maxogden/menubar/commit/bd3beb2c2bc9700f4738a4e0f25085aa8a0f5e86))
15 |
16 |
17 | ### Bug Fixes
18 |
19 | * Fix for Broken Native Menubar Example ([#471](https://github.com/maxogden/menubar/issues/471)) ([b000c86](https://github.com/maxogden/menubar/commit/b000c86777cb0cf6fa883fb0256410981e154ce1))
20 | * win32 position ([#479](https://github.com/maxogden/menubar/issues/479)) ([9e5cb86](https://github.com/maxogden/menubar/commit/9e5cb86a276f29efd36d10a07e27fa820343f880))
21 |
22 | ## [9.4.0](https://github.com/maxogden/menubar/compare/v9.3.0...v9.4.0) (2023-11-28)
23 |
24 |
25 | ### Features
26 |
27 | * Update electron to 27 ([#458](https://github.com/maxogden/menubar/issues/458)) ([f3dbac6](https://github.com/maxogden/menubar/commit/f3dbac66582baa322c2c8caa5027f1b8ef480e67))
28 |
29 |
30 | ### Bug Fixes
31 |
32 | * Avoid setVisibleOnAllWorkspaces from destroying the original visible state of app.dock ([#442](https://github.com/maxogden/menubar/issues/442)) ([d8df2ab](https://github.com/maxogden/menubar/commit/d8df2ab4b65564c8ec58dc7156128bfd53fab2c9))
33 |
34 | ## [9.3.0](https://github.com/maxogden/menubar/compare/v9.2.3...v9.3.0) (2023-02-13)
35 |
36 |
37 | ### Features
38 |
39 | * add electron 22 support ([#414](https://github.com/maxogden/menubar/issues/414)) ([a39382f](https://github.com/maxogden/menubar/commit/a39382fe843953395bf99267ee83102def70b06e))
40 |
41 | ### [9.2.3](https://github.com/maxogden/menubar/compare/v9.2.2...v9.2.3) (2022-10-05)
42 |
43 |
44 | ### Features
45 |
46 | * electron 21 support ([#382](https://github.com/maxogden/menubar/issues/382)) ([c9d5b61](https://github.com/maxogden/menubar/commit/c9d5b61da2b55e20e9b2d0f4c0181c57f33a27c3))
47 |
48 | ### [9.2.2](https://github.com/maxogden/menubar/compare/v9.2.1...v9.2.2) (2022-09-05)
49 |
50 |
51 | ### Features
52 |
53 | * Add Electron 20 as a peerDependency ([#379](https://github.com/maxogden/menubar/issues/379)) ([4c027b2](https://github.com/maxogden/menubar/commit/4c027b22499c7c83a4d87b9aa17d5e86f3172b68))
54 |
55 |
56 | ### Bug Fixes
57 |
58 | * arrow example problem ([#342](https://github.com/maxogden/menubar/issues/342)) ([64b80d5](https://github.com/maxogden/menubar/commit/64b80d5f49ebb367b75e21e88af15fdc874cda86))
59 |
60 | ### [9.2.1](https://github.com/maxogden/menubar/compare/v9.2.0...v9.2.1) (2022-07-11)
61 |
62 |
63 | ### Bug Fixes
64 |
65 | * Add support for electron 19 ([#376](https://github.com/maxogden/menubar/issues/376)) ([6d0feb0](https://github.com/maxogden/menubar/commit/6d0feb0e492681200966dde10a63a73cfb503138))
66 |
67 | ## [9.2.0](https://github.com/maxogden/menubar/compare/v9.1.2...v9.2.0) (2022-04-11)
68 |
69 |
70 | ### Features
71 |
72 | * add `before-load` event ([#370](https://github.com/maxogden/menubar/issues/370)) ([3247986](https://github.com/maxogden/menubar/commit/3247986f164d8b2fb2912ab33beb25c9c6d8ece3))
73 |
74 | ### [9.1.2](https://github.com/maxogden/menubar/compare/v9.1.1...v9.1.2) (2022-03-29)
75 |
76 |
77 | ### Bug Fixes
78 |
79 | * Add electron 17 support ([#373](https://github.com/maxogden/menubar/issues/373)) ([fafc29f](https://github.com/maxogden/menubar/commit/fafc29f168e91369ad5d60a61abc0363076c303a))
80 |
81 | ### [9.1.1](https://github.com/maxogden/menubar/compare/v9.1.0...v9.1.1) (2021-12-09)
82 |
83 |
84 | ### Bug Fixes
85 |
86 | * Add electron 16 support ([#364](https://github.com/maxogden/menubar/issues/364)) ([325e151](https://github.com/maxogden/menubar/commit/325e1517cfc407bc0ccc98be776d8d9590d6f119))
87 |
88 | ## [9.1.0](https://github.com/maxogden/menubar/compare/v9.0.6...v9.1.0) (2021-10-27)
89 |
90 |
91 | ### Features
92 |
93 | * add option activateWithApp to allow not activate with this event ([#361](https://github.com/maxogden/menubar/issues/361)) ([8384bf2](https://github.com/maxogden/menubar/commit/8384bf24abe6138aded26fcd7bd6d1d7a325f319))
94 |
95 | ### [9.0.6](https://github.com/maxogden/menubar/compare/v9.0.5...v9.0.6) (2021-10-15)
96 |
97 |
98 | ### Bug Fixes
99 |
100 | * Add support for electron 14 and 15 ([#358](https://github.com/maxogden/menubar/issues/358)) ([8eaba8c](https://github.com/maxogden/menubar/commit/8eaba8cdfcd3ce9427ee3ffd65b3426c62f65048))
101 |
102 | ### [9.0.5](https://github.com/maxogden/menubar/compare/v9.0.4...v9.0.5) (2021-06-28)
103 |
104 |
105 | ### Bug Fixes
106 |
107 | * Add support for Electron 13 ([#347](https://github.com/maxogden/menubar/issues/347)) ([fbf07bd](https://github.com/maxogden/menubar/commit/fbf07bd0bd24b2aac26cdd1db61eb55924f3ee63))
108 | * window position on linux & windows when taskbar is on the left ([#343](https://github.com/maxogden/menubar/issues/343)) ([5d8e0c8](https://github.com/maxogden/menubar/commit/5d8e0c89996f67b58f059ec767a87db104a90292))
109 |
110 | ### [9.0.4](https://github.com/maxogden/menubar/compare/v9.0.3...v9.0.4) (2021-05-03)
111 |
112 |
113 | ### Bug Fixes
114 |
115 | * Add support for Electron 12 ([#332](https://github.com/maxogden/menubar/issues/332)) ([c1f055d](https://github.com/maxogden/menubar/commit/c1f055daed76be2d0f408fda5d4835defcd59dcc))
116 |
117 | ### [9.0.3](https://github.com/maxogden/menubar/compare/v9.0.2...v9.0.3) (2021-02-24)
118 |
119 |
120 | ### Bug Fixes
121 |
122 | * Add support for Electron 10 and 11 ([#321](https://github.com/maxogden/menubar/issues/321)) ([4a89656](https://github.com/maxogden/menubar/commit/4a8965628a0a1a7a14602fef3add7bef436a508f))
123 |
124 | ### [9.0.2](https://github.com/maxogden/menubar/compare/v9.0.1...v9.0.2) (2021-01-20)
125 |
126 |
127 | ### Bug Fixes
128 |
129 | * Improve 'windows' OS detection of taskbar location ([#307](https://github.com/maxogden/menubar/issues/307)) ([4726584](https://github.com/maxogden/menubar/commit/4726584664148a57656c40872836ebba2d030980))
130 |
131 | ### [9.0.1](https://github.com/maxogden/menubar/compare/v9.0.0...v9.0.1) (2020-05-28)
132 |
133 |
134 | ### Bug Fixes
135 |
136 | * calling showWindow() prevents menubar window from closing ([#287](https://github.com/maxogden/menubar/issues/287)) ([53d8f82](https://github.com/maxogden/menubar/commit/53d8f82b604ad5555f59108a97234ebf32e43f80))
137 |
138 | ## [9.0.0](https://github.com/maxogden/menubar/compare/v8.0.2...v9.0.0) (2020-05-27)
139 |
140 |
141 | ### ⚠ BREAKING CHANGES
142 |
143 | * Please use Electron 9 with this menubar version.
144 |
145 | ### Features
146 |
147 | * Support Electron 9 ([#286](https://github.com/maxogden/menubar/issues/286)) ([44cf1b1](https://github.com/maxogden/menubar/commit/44cf1b1e6cce83f9e63a39f1d32fbb664396e7bc))
148 |
149 | ### [8.0.2](https://github.com/maxogden/menubar/compare/v8.0.1...v8.0.2) (2020-04-27)
150 |
151 |
152 | ### Bug Fixes
153 |
154 | * Show window on dock icon click ([#279](https://github.com/maxogden/menubar/issues/279)) ([a8607fa](https://github.com/maxogden/menubar/commit/a8607fa708d229d9124471127482fe461198f1f3))
155 | * update prevent flicker on Windows (fixes [#274](https://github.com/maxogden/menubar/issues/274)) ([#276](https://github.com/maxogden/menubar/issues/276)) ([9592f34](https://github.com/maxogden/menubar/commit/9592f3437ce3660b6464f5b436ed111291eb75d3))
156 |
157 | ### [8.0.1](https://github.com/maxogden/menubar/compare/v8.0.0...v8.0.1) (2020-03-14)
158 |
159 |
160 | ### Bug Fixes
161 |
162 | * **deps:** [Security] bump acorn from 6.1.1 to 6.4.1 ([#272](https://github.com/maxogden/menubar/issues/272)) ([1332b77](https://github.com/maxogden/menubar/commit/1332b774372de69c04e2a098833ae35775c35cad))
163 |
164 | ## [8.0.0](https://github.com/maxogden/menubar/compare/v7.2.0...v8.0.0) (2020-02-10)
165 |
166 |
167 | ### ⚠ BREAKING CHANGES
168 |
169 | * Menubar's recommended peer dependency is `electron@^8.0.0`
170 |
171 | ### Features
172 |
173 | * Support Electron 8 ([#268](https://github.com/maxogden/menubar/issues/268)) ([ad99c5a](https://github.com/maxogden/menubar/commit/ad99c5add02ab6d0d751cf6bda8a2c96c674620f))
174 |
175 | ## [7.2.0](https://github.com/maxogden/menubar/compare/v7.1.0...v7.2.0) (2020-01-16)
176 |
177 |
178 | ### Features
179 |
180 | * Adding a loadUrlOptions option ([#263](https://github.com/maxogden/menubar/issues/263)) ([8e6bd01](https://github.com/maxogden/menubar/commit/8e6bd0154aaee02a5d601bbe37c51c55065c3923))
181 |
182 | ## [7.1.0](https://github.com/maxogden/menubar/compare/v7.0.0...v7.1.0) (2019-11-25)
183 |
184 |
185 | ### Features
186 |
187 | * Allow skipping loadUrl ([#257](https://github.com/maxogden/menubar/issues/257)) ([095486a](https://github.com/maxogden/menubar/commit/095486ab338df26fc4d6a1e7a658cfa9fa4a69b7))
188 |
189 | # [7.0.0](https://github.com/maxogden/menubar/compare/v6.0.8...v7.0.0) (2019-10-23)
190 |
191 |
192 | * feat!: Support Electron 7 (#250) ([b54dce5](https://github.com/maxogden/menubar/commit/b54dce5)), closes [#250](https://github.com/maxogden/menubar/issues/250)
193 |
194 |
195 | ### BREAKING CHANGES
196 |
197 | * - Drop support for Electron 4, 5, and 6.
198 | - Remove deprecated passing string argument to `menubar`, use `dir` field instead
199 | ```diff
200 | - menubar('/home/me/MY_ABSOLUTE_PATH');
201 | + menubar({ dir: '/home/me/MY_ABSOLUTE_PATH' });
202 | ```
203 | - Remove deprecated passing `x`, `y`, `height`, `width`, `alwaysOnTop` fields to `menubar`, pass them instead into the `browserWindow` field
204 | ```diff
205 | - menubar({
206 | - x: 12,
207 | - y: 34,
208 | - height: 500,
209 | - width: 320,
210 | - alwaysOnTop: true
211 | - });
212 | + menubar({
213 | + browserWindow: {
214 | + x: 12,
215 | + y: 34,
216 | + height: 500,
217 | + width: 320,
218 | + alwaysOnTop: true
219 | + }
220 | + });
221 | ```
222 |
223 |
224 |
225 | ## [6.0.8](https://github.com/maxogden/menubar/compare/v6.0.7...v6.0.8) (2019-09-16)
226 |
227 |
228 | ### Bug Fixes
229 |
230 | * Move doc tool to `devDependencies` ([#245](https://github.com/maxogden/menubar/issues/245)) ([2756c7a](https://github.com/maxogden/menubar/commit/2756c7a))
231 |
232 |
233 |
234 | ## [6.0.7](https://github.com/maxogden/menubar/compare/v6.0.6...v6.0.7) (2019-07-31)
235 |
236 |
237 | ### Bug Fixes
238 |
239 | * Support Electron 6 ([#242](https://github.com/maxogden/menubar/issues/242)) ([1fd9bd7](https://github.com/maxogden/menubar/commit/1fd9bd7))
240 |
241 |
242 |
243 | ## [6.0.6](https://github.com/maxogden/menubar/compare/v6.0.5...v6.0.6) (2019-07-02)
244 |
245 |
246 | ### Bug Fixes
247 |
248 | * Fix crash on windows position ([#235](https://github.com/maxogden/menubar/issues/235)) ([cbbe175](https://github.com/maxogden/menubar/commit/cbbe175))
249 |
250 |
251 |
252 | ## [6.0.5](https://github.com/maxogden/menubar/compare/v6.0.4...v6.0.5) (2019-06-11)
253 |
254 |
255 | ### Bug Fixes
256 |
257 | * Remove postinstall, export taskbarLocation ([#226](https://github.com/maxogden/menubar/issues/226)) ([941b3be](https://github.com/maxogden/menubar/commit/941b3be))
258 |
259 |
260 |
261 | ## [6.0.4](https://github.com/maxogden/menubar/compare/v6.0.3...v6.0.4) (2019-06-11)
262 |
263 |
264 | ### Bug Fixes
265 |
266 | * Correct position on Windows & multi-taskbar ([#217](https://github.com/maxogden/menubar/issues/217)) ([4f29fe2](https://github.com/maxogden/menubar/commit/4f29fe2)), closes [#196](https://github.com/maxogden/menubar/issues/196)
267 | * Fix double 'after-hide' event ([#216](https://github.com/maxogden/menubar/issues/216)) ([a4d900e](https://github.com/maxogden/menubar/commit/a4d900e))
268 |
269 |
270 |
271 | ## [6.0.3](https://github.com/maxogden/menubar/compare/v6.0.2...v6.0.3) (2019-06-05)
272 |
273 |
274 | ### Bug Fixes
275 |
276 | * Fix accessing Menubar.window ([#214](https://github.com/maxogden/menubar/issues/214)) ([cd5ef73](https://github.com/maxogden/menubar/commit/cd5ef73))
277 |
278 |
279 |
280 | ## [6.0.2](https://github.com/maxogden/menubar/compare/v6.0.1...v6.0.2) (2019-05-31)
281 |
282 |
283 | ### Bug Fixes
284 |
285 | * Use cat icon if no icon provided ([#205](https://github.com/maxogden/menubar/issues/205)) ([fc02e02](https://github.com/maxogden/menubar/commit/fc02e02))
286 |
287 |
288 |
289 | ## [6.0.1](https://github.com/maxogden/menubar/compare/v6.0.0...v6.0.1) (2019-05-31)
290 |
291 |
292 | ### Bug Fixes
293 |
294 | * Fix changelog links ([#204](https://github.com/maxogden/menubar/issues/204)) ([de96756](https://github.com/maxogden/menubar/commit/de96756))
295 |
296 |
297 |
298 | # [6.0.0](https://github.com/maxogden/menubar/compare/v5.2.3...v6.0.0) (2019-05-31)
299 |
300 |
301 | ### Bug Fixes
302 |
303 | * Update to Electron 5 ([#15](https://github.com/amaurym/g/menubar/issues/15)) ([ce86216](https://github.com/maxogden/menubar/commit/ce86216))
304 | * Window does not show when already app is ready ([#8](https://github.com/amaurym/g/menubar/issues/8)) ([251fb21](https://github.com/maxogden/menubar/commit/251fb21))
305 |
306 |
307 | ### Code Refactoring
308 |
309 | * Convert all codebase to typescript ([#2](https://github.com/amaurym/g/menubar/issues/2)) ([820d41a](https://github.com/maxogden/menubar/commit/820d41a))
310 |
311 |
312 | ### Features
313 |
314 | * Add `browserWindow` field in options, deprecate `height`, `width`, `x`, `y`, `alwaysOnTop` in favor of `browserWindow` ([#18](https://github.com/amaurym/g/menubar/issues/18)) ([0b2d897](https://github.com/maxogden/menubar/commit/0b2d897))
315 | * Support Electron.NativeImage icon argument ([#7](https://github.com/amaurym/g/menubar/issues/7)) ([03d67f3](https://github.com/maxogden/menubar/commit/03d67f3))
316 |
317 |
318 | ### BREAKING CHANGES
319 |
320 | * We're using a named export in Typescript now:
321 | ```diff
322 | - var menubar = require('menubar');
323 | + var { menubar } = require('menubar');
324 | ```
325 |
326 | Alternatively, using ES6/TS syntax:
327 | ```javascript
328 | import { menubar } from 'menubar';
329 | ```
330 |
--------------------------------------------------------------------------------
/examples/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@electron/get@^2.0.0":
6 | version "2.0.3"
7 | resolved "https://registry.yarnpkg.com/@electron/get/-/get-2.0.3.tgz#fba552683d387aebd9f3fcadbcafc8e12ee4f960"
8 | integrity sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==
9 | dependencies:
10 | debug "^4.1.1"
11 | env-paths "^2.2.0"
12 | fs-extra "^8.1.0"
13 | got "^11.8.5"
14 | progress "^2.0.3"
15 | semver "^6.2.0"
16 | sumchecker "^3.0.1"
17 | optionalDependencies:
18 | global-agent "^3.0.0"
19 |
20 | "@sindresorhus/is@^4.0.0":
21 | version "4.6.0"
22 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
23 | integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
24 |
25 | "@szmarczak/http-timer@^4.0.5":
26 | version "4.0.6"
27 | resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
28 | integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
29 | dependencies:
30 | defer-to-connect "^2.0.0"
31 |
32 | "@types/cacheable-request@^6.0.1":
33 | version "6.0.3"
34 | resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
35 | integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==
36 | dependencies:
37 | "@types/http-cache-semantics" "*"
38 | "@types/keyv" "^3.1.4"
39 | "@types/node" "*"
40 | "@types/responselike" "^1.0.0"
41 |
42 | "@types/http-cache-semantics@*":
43 | version "4.0.4"
44 | resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4"
45 | integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==
46 |
47 | "@types/keyv@^3.1.4":
48 | version "3.1.4"
49 | resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
50 | integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
51 | dependencies:
52 | "@types/node" "*"
53 |
54 | "@types/node@*", "@types/node@^20.9.0":
55 | version "20.14.2"
56 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18"
57 | integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==
58 | dependencies:
59 | undici-types "~5.26.4"
60 |
61 | "@types/responselike@^1.0.0":
62 | version "1.0.3"
63 | resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50"
64 | integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==
65 | dependencies:
66 | "@types/node" "*"
67 |
68 | "@types/yauzl@^2.9.1":
69 | version "2.10.3"
70 | resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
71 | integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
72 | dependencies:
73 | "@types/node" "*"
74 |
75 | boolean@^3.0.1:
76 | version "3.2.0"
77 | resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
78 | integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
79 |
80 | buffer-crc32@~0.2.3:
81 | version "0.2.13"
82 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
83 | integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
84 |
85 | cacheable-lookup@^5.0.3:
86 | version "5.0.4"
87 | resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
88 | integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
89 |
90 | cacheable-request@^7.0.2:
91 | version "7.0.4"
92 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817"
93 | integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==
94 | dependencies:
95 | clone-response "^1.0.2"
96 | get-stream "^5.1.0"
97 | http-cache-semantics "^4.0.0"
98 | keyv "^4.0.0"
99 | lowercase-keys "^2.0.0"
100 | normalize-url "^6.0.1"
101 | responselike "^2.0.0"
102 |
103 | clone-response@^1.0.2:
104 | version "1.0.3"
105 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3"
106 | integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==
107 | dependencies:
108 | mimic-response "^1.0.0"
109 |
110 | debug@^4.1.0, debug@^4.1.1:
111 | version "4.3.5"
112 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
113 | integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
114 | dependencies:
115 | ms "2.1.2"
116 |
117 | decompress-response@^6.0.0:
118 | version "6.0.0"
119 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
120 | integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
121 | dependencies:
122 | mimic-response "^3.1.0"
123 |
124 | defer-to-connect@^2.0.0:
125 | version "2.0.1"
126 | resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
127 | integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
128 |
129 | define-data-property@^1.0.1:
130 | version "1.1.4"
131 | resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
132 | integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
133 | dependencies:
134 | es-define-property "^1.0.0"
135 | es-errors "^1.3.0"
136 | gopd "^1.0.1"
137 |
138 | define-properties@^1.2.1:
139 | version "1.2.1"
140 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
141 | integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
142 | dependencies:
143 | define-data-property "^1.0.1"
144 | has-property-descriptors "^1.0.0"
145 | object-keys "^1.1.1"
146 |
147 | detect-node@^2.0.4:
148 | version "2.1.0"
149 | resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
150 | integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
151 |
152 | electron@^34.3.0:
153 | version "34.3.0"
154 | resolved "https://registry.yarnpkg.com/electron/-/electron-34.3.0.tgz#d52a5bd14c72a5811a0c0e233db5c20ad70ba078"
155 | integrity sha512-I238qRnYTAsuwJ/rS7HGaFNY4NNKAcjX8nlj7mnNmj1TK3z4HvNoD1r7Zud81DYDFx8AITuLd76EPrEnnfF9Bg==
156 | dependencies:
157 | "@electron/get" "^2.0.0"
158 | "@types/node" "^20.9.0"
159 | extract-zip "^2.0.1"
160 |
161 | end-of-stream@^1.1.0:
162 | version "1.4.4"
163 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
164 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
165 | dependencies:
166 | once "^1.4.0"
167 |
168 | env-paths@^2.2.0:
169 | version "2.2.1"
170 | resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
171 | integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
172 |
173 | es-define-property@^1.0.0:
174 | version "1.0.0"
175 | resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
176 | integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
177 | dependencies:
178 | get-intrinsic "^1.2.4"
179 |
180 | es-errors@^1.3.0:
181 | version "1.3.0"
182 | resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
183 | integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
184 |
185 | es6-error@^4.1.1:
186 | version "4.1.1"
187 | resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
188 | integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
189 |
190 | escape-string-regexp@^4.0.0:
191 | version "4.0.0"
192 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
193 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
194 |
195 | extract-zip@^2.0.1:
196 | version "2.0.1"
197 | resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
198 | integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
199 | dependencies:
200 | debug "^4.1.1"
201 | get-stream "^5.1.0"
202 | yauzl "^2.10.0"
203 | optionalDependencies:
204 | "@types/yauzl" "^2.9.1"
205 |
206 | fd-slicer@~1.1.0:
207 | version "1.1.0"
208 | resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
209 | integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
210 | dependencies:
211 | pend "~1.2.0"
212 |
213 | fs-extra@^8.1.0:
214 | version "8.1.0"
215 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
216 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
217 | dependencies:
218 | graceful-fs "^4.2.0"
219 | jsonfile "^4.0.0"
220 | universalify "^0.1.0"
221 |
222 | function-bind@^1.1.2:
223 | version "1.1.2"
224 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
225 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
226 |
227 | get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
228 | version "1.2.4"
229 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
230 | integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
231 | dependencies:
232 | es-errors "^1.3.0"
233 | function-bind "^1.1.2"
234 | has-proto "^1.0.1"
235 | has-symbols "^1.0.3"
236 | hasown "^2.0.0"
237 |
238 | get-stream@^5.1.0:
239 | version "5.2.0"
240 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
241 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
242 | dependencies:
243 | pump "^3.0.0"
244 |
245 | global-agent@^3.0.0:
246 | version "3.0.0"
247 | resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
248 | integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
249 | dependencies:
250 | boolean "^3.0.1"
251 | es6-error "^4.1.1"
252 | matcher "^3.0.0"
253 | roarr "^2.15.3"
254 | semver "^7.3.2"
255 | serialize-error "^7.0.1"
256 |
257 | globalthis@^1.0.1:
258 | version "1.0.4"
259 | resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
260 | integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
261 | dependencies:
262 | define-properties "^1.2.1"
263 | gopd "^1.0.1"
264 |
265 | gopd@^1.0.1:
266 | version "1.0.1"
267 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
268 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
269 | dependencies:
270 | get-intrinsic "^1.1.3"
271 |
272 | got@^11.8.5:
273 | version "11.8.6"
274 | resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
275 | integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==
276 | dependencies:
277 | "@sindresorhus/is" "^4.0.0"
278 | "@szmarczak/http-timer" "^4.0.5"
279 | "@types/cacheable-request" "^6.0.1"
280 | "@types/responselike" "^1.0.0"
281 | cacheable-lookup "^5.0.3"
282 | cacheable-request "^7.0.2"
283 | decompress-response "^6.0.0"
284 | http2-wrapper "^1.0.0-beta.5.2"
285 | lowercase-keys "^2.0.0"
286 | p-cancelable "^2.0.0"
287 | responselike "^2.0.0"
288 |
289 | graceful-fs@^4.1.6, graceful-fs@^4.2.0:
290 | version "4.2.11"
291 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
292 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
293 |
294 | has-property-descriptors@^1.0.0:
295 | version "1.0.2"
296 | resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
297 | integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
298 | dependencies:
299 | es-define-property "^1.0.0"
300 |
301 | has-proto@^1.0.1:
302 | version "1.0.3"
303 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
304 | integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
305 |
306 | has-symbols@^1.0.3:
307 | version "1.0.3"
308 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
309 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
310 |
311 | hasown@^2.0.0:
312 | version "2.0.2"
313 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
314 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
315 | dependencies:
316 | function-bind "^1.1.2"
317 |
318 | http-cache-semantics@^4.0.0:
319 | version "4.1.1"
320 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
321 | integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
322 |
323 | http2-wrapper@^1.0.0-beta.5.2:
324 | version "1.0.3"
325 | resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
326 | integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
327 | dependencies:
328 | quick-lru "^5.1.1"
329 | resolve-alpn "^1.0.0"
330 |
331 | json-buffer@3.0.1:
332 | version "3.0.1"
333 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
334 | integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
335 |
336 | json-stringify-safe@^5.0.1:
337 | version "5.0.1"
338 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
339 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
340 |
341 | jsonfile@^4.0.0:
342 | version "4.0.0"
343 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
344 | integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
345 | optionalDependencies:
346 | graceful-fs "^4.1.6"
347 |
348 | keyv@^4.0.0:
349 | version "4.5.4"
350 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
351 | integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
352 | dependencies:
353 | json-buffer "3.0.1"
354 |
355 | lowercase-keys@^2.0.0:
356 | version "2.0.0"
357 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
358 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
359 |
360 | matcher@^3.0.0:
361 | version "3.0.0"
362 | resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
363 | integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
364 | dependencies:
365 | escape-string-regexp "^4.0.0"
366 |
367 | mimic-response@^1.0.0:
368 | version "1.0.1"
369 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
370 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
371 |
372 | mimic-response@^3.1.0:
373 | version "3.1.0"
374 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
375 | integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
376 |
377 | ms@2.1.2:
378 | version "2.1.2"
379 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
380 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
381 |
382 | normalize-url@^6.0.1:
383 | version "6.1.0"
384 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
385 | integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
386 |
387 | object-keys@^1.1.1:
388 | version "1.1.1"
389 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
390 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
391 |
392 | once@^1.3.1, once@^1.4.0:
393 | version "1.4.0"
394 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
395 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
396 | dependencies:
397 | wrappy "1"
398 |
399 | p-cancelable@^2.0.0:
400 | version "2.1.1"
401 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
402 | integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
403 |
404 | pend@~1.2.0:
405 | version "1.2.0"
406 | resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
407 | integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
408 |
409 | progress@^2.0.3:
410 | version "2.0.3"
411 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
412 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
413 |
414 | pump@^3.0.0:
415 | version "3.0.0"
416 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
417 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
418 | dependencies:
419 | end-of-stream "^1.1.0"
420 | once "^1.3.1"
421 |
422 | quick-lru@^5.1.1:
423 | version "5.1.1"
424 | resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
425 | integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
426 |
427 | resolve-alpn@^1.0.0:
428 | version "1.2.1"
429 | resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
430 | integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
431 |
432 | responselike@^2.0.0:
433 | version "2.0.1"
434 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
435 | integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==
436 | dependencies:
437 | lowercase-keys "^2.0.0"
438 |
439 | roarr@^2.15.3:
440 | version "2.15.4"
441 | resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
442 | integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
443 | dependencies:
444 | boolean "^3.0.1"
445 | detect-node "^2.0.4"
446 | globalthis "^1.0.1"
447 | json-stringify-safe "^5.0.1"
448 | semver-compare "^1.0.0"
449 | sprintf-js "^1.1.2"
450 |
451 | semver-compare@^1.0.0:
452 | version "1.0.0"
453 | resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
454 | integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
455 |
456 | semver@^6.2.0:
457 | version "6.3.1"
458 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
459 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
460 |
461 | semver@^7.3.2:
462 | version "7.6.2"
463 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13"
464 | integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==
465 |
466 | serialize-error@^7.0.1:
467 | version "7.0.1"
468 | resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
469 | integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
470 | dependencies:
471 | type-fest "^0.13.1"
472 |
473 | sprintf-js@^1.1.2:
474 | version "1.1.3"
475 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
476 | integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
477 |
478 | sumchecker@^3.0.1:
479 | version "3.0.1"
480 | resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
481 | integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
482 | dependencies:
483 | debug "^4.1.0"
484 |
485 | type-fest@^0.13.1:
486 | version "0.13.1"
487 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
488 | integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
489 |
490 | undici-types@~5.26.4:
491 | version "5.26.5"
492 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
493 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
494 |
495 | universalify@^0.1.0:
496 | version "0.1.2"
497 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
498 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
499 |
500 | wrappy@1:
501 | version "1.0.2"
502 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
503 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
504 |
505 | yauzl@^2.10.0:
506 | version "2.10.0"
507 | resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
508 | integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
509 | dependencies:
510 | buffer-crc32 "~0.2.3"
511 | fd-slicer "~1.1.0"
512 |
--------------------------------------------------------------------------------