npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@6c65726f79/custom-titlebar

v0.9.1

Published

Poorly coded titlebar for Electron, NW.js and PWAs

Downloads

172

Readme

custom-titlebar

Poorly coded titlebar for Electron, NW.js and PWAs.

NPM npm npm bundle size npm

Preview 1

Light/Dark skin

Preview 3

Control button styles

Preview 2

Condensed menu

Preview 4

Progressive web app

About

It's a library for Electron, NW.js and PWAs, it can be used on a basic website but it's useless ¯\(ツ)

Main features

  • Compatible with any version of Electron 🎉
  • Works with Electron, NW.js and probably others 🤷‍♂️
  • Fully compatible with Progressive Web Apps and Window Controls Overlay 🔥
  • Works without any dependencies, so it won't break in the next major release of Electron 👀
  • Very small footprint (< 30 kB) 👣
  • Options and methods very similar to custom-electron-titlebar 📖

Demo

You can see a demo of this library in a PWA here: https://6c65726f79.github.io/custom-titlebar/

Notes:

  • Check the list of compatible browsers.
  • If the install button doesn't appear, try reloading and reopening the tab several times.
  • You may need to manually enable Window Controls Overlay until Chrome 98 is released: chrome://flags/#enable-desktop-pwas-window-controls-overlay

Inpiration

This package is highly inspired by custom-electron-titlebar.

Motivations

I needed a custom titlebar for Electron 14 to replace the unmaintained custom-electron-titlebar, but I couldn't find any interesting ones, so I made it myself.

Not yet implemented

  • ~~MenuItem role, icon, radio~~ Done!
  • ~~Icons theme~~ Done!
  • Submenu scrollbar
  • Keyboard controls

Q&A

Can I use this package without @electron/remote?

Absolutely! Check out the advanced examples to see how it's done.

How to fix Content Security Policy errors?

Simply add style-src 'unsafe-inline' in the Content-Security-Policy meta tag.

How long before this package becomes unmaintained too?

This package doesn't rely on the Electron or NW.js API so it doesn't need as much maintenance as other packages. Even if I stop maintaining it and the API change dramatically, you could modify your code to match the new API. So theoretically this package can't become obsolete.

Install

npm i @6c65726f79/custom-titlebar

Usage

Node.js

JavaScript

const Titlebar = require('@6c65726f79/custom-titlebar');

new Titlebar({
  backgroundColor: '#000'
});

TypeScript

import Titlebar from '@6c65726f79/custom-titlebar';

new Titlebar({
  backgroundColor: '#000'
});

Browser

<script src="https://cdn.jsdelivr.net/npm/@6c65726f79/custom-titlebar/lib/index.js"></script>

<script>
  new Titlebar({
    backgroundColor: '#000'
  });
</script>

Examples

See the Wiki for more advanced examples.

Electron

main.js

const { initialize, enable } = require('@electron/remote/main');
const { app, BrowserWindow } = require('electron');
const path = require('path');

initialize();

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false,
    webPreferences: {
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  })

  enable(win.webContents);
  
  win.loadFile('index.html');
}

app.whenReady().then(() => {
  createWindow();
})

preload.js

const { Menu, getCurrentWindow } = require('@electron/remote');
const Titlebar = require('@6c65726f79/custom-titlebar');
const { platform } = require('process');

const currentWindow = getCurrentWindow();
let titlebar;

currentWindow.webContents.once('dom-ready', () => {
  titlebar = new Titlebar({
    menu: Menu.getApplicationMenu(),
    backgroundColor: '#37474f',
    platform: platform,
    browserWindow: currentWindow, /* Only needed if you use MenuItem roles */
    onMinimize: () => currentWindow.minimize(),
    onMaximize: () => currentWindow.isMaximized() ? currentWindow.unmaximize() : currentWindow.maximize(),
    onClose: () => currentWindow.close(),
    isMaximized: () => currentWindow.isMaximized()
  });
});

NW.js

package.json

{
  "name": "helloworld",
  "main": "index.html",
  "window": {
    "frame": false,
    "toolbar": false
  },
  "dependencies": {
    "@6c65726f79/custom-titlebar": "latest"
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Hello World!</title>
    <script src="./node_modules/@6c65726f79/custom-titlebar/lib/index.js"></script> 
  </head>
  <body>
    <h1>Hello World!</h1>
    <script>
      const gui = require('nw.gui');
      const { platform } = require('process');
      const win = gui.Window.get();
      let maximized = false;

      win.onMaximized.addListener(() => { maximized=true; });
      win.onRestore.addListener(() => { maximized=false; });

      const titlebar = new Titlebar({
        backgroundColor: '#37474f',
        platform: platform,
        onMinimize: () => win.minimize(),
        onMaximize: () => maximized ? win.restore() : win.maximize(),
        onClose: () => win.close(),
        isMaximized: () => maximized
      });
    </script>
  </body>
</html>

Progressive Web App

manifest.webmanifest

{
  "background_color": "#2975ff",
  "description": "Progressive Web Application with a custom titlebar",
  "display": "standalone",
  "display_override": ["window-controls-overlay"],
  "icons": [],
  "name": "Progressive Web Application",
  "short_name": "custom-titlebar",
  "start_url": "./",
  "theme_color": "#2975ff"
}

index.html

<html>
    <head>
        <title>Titlebar</title>
        <script src="https://cdn.jsdelivr.net/npm/@6c65726f79/custom-titlebar/lib/index.js"></script>
        <link rel="manifest" href="manifest.webmanifest">
    </head>
    <body>
        <div id="app" style="padding:8px;">
            This is a web page
        </div>
        <script>
          let titlebar;
          const menu = [
            {
              label: 'File',
              submenu: [
                {
                    label: 'Checkbox',
                    type: 'checkbox',
                    id: 'checkbox'
                },
                {
                    label: 'Checked state',
                    click: () => {
                        alert(titlebar.getMenuItemById('checkbox')?.checked ? 'Checked' : 'Unchecked');
                    }
                }
              ]
            }
          ];
          
          function createTitlebar() {
            titlebar = new Titlebar({
              backgroundUnfocusEffect: false,
              windowControlsOverlay: true,
              backgroundColor:"#2975ff",
              menu
            });
          }

          window.addEventListener('load', () => {
            // Use the titlebar only in standalone mode
            if (navigator.standalone || window.matchMedia('(display-mode: standalone)').matches) {
              createTitlebar();
            }

            window.matchMedia('(display-mode: standalone)').onchange = (e) => {
              e.matches ? createTitlebar() : titlebar.dispose();
            }
          });
        </script>
    </body>
</html>

Options

All parameters are optional.

| Parameter | Type | Description | Default | | ------------------------ | ---------- | ---------------------------------------------------------------------------------- | ---------------- | | backgroundColor | string | The background color of the titlebar. The value must be a valid CSS color. | "#FFFFFF" | | backgroundUnfocusEffect | boolean | Enables or disables the unfocus effect on the background of the titlebar. | true | | browserWindow | object | The current BrowserWindow. (Electron only) | undefined | | condensed | boolean | Force the menu bar to be condensed. | false | | closeable | boolean | Enables or disables the close button. | true | | drag | boolean | Define whether or not you can drag the window. | true | | hideControlsOnDarwin | boolean | Set this option to true if you're using titleBarStyle: 'hidden' on macOS. (Electron only) | false | | hideMenuOnDarwin | boolean | Hide the menu bar when the platform is darwin. | true | | height | number | The height of the titlebar. | 30 | | icon | string | The icon of the titlebar. | undefined | | isMaximized | function | A function that return true or false if the window is maximized or not. | undefined | | maximizable | boolean | Enables or disables the maximize button. | true | | menu | object | List of MenuItem to show in the menu bar. (Electron or NW.js) | undefined | | menuItemClickHandler | function | A function that takes a commandId as parameter to handle menu item clicks. | undefined | | minimizable | boolean | Enables or disables the minimize button. | true | | onClose | function | The function to call when the close button is clicked. | undefined | | onMaximize | function | The function to call when the maximize/restore button is clicked. | undefined | | onMinimize | function | The function to call when the minimize button is clicked. | undefined | | overflow | string | The overflow of the container. (auto, visible, hidden) | "auto" | | platform | string | Style of the control buttons. (win, darwin) | "win" | | title | string | Window title. | document.title | | titleHorizontalAlignment | string | Set horizontal alignment of the window title. (left, center, right) | "center" | | unfocusEffect | boolean | Enables or disables the unfocus effect on the text and background of the titlebar. | true | | windowControlsOverlay | boolean | Set this option to true if you're using Window Controls Overlay. | false |

Methods

getMenuItemById

Returns the MenuItem with the specified id.

const titlebar = new Titlebar({
  menu: [{label: 'Item 1', id: 'item1'}]
});

const menuItem = titlebar.getMenuItemById('item1');

console.log(menuItem.label); // Item 1

updateOptions

This method updates all parameters that are specified.

titlebar.updateOptions({
  menu: Menu.getApplicationMenu(),
  condensed: 'true',
  titleHorizontalAlignment: 'left'
});

updateTitle

This method update the title of the titlebar. If you change the content of the title tag, you should call this method to update the title.

document.title = 'My new title';
titlebar.updateTitle();

// Or you can do as follows and avoid writing document.title
titlebar.updateTitle('New Title');

updateMenu

Deprecated: This method will be removed in v1.0.0, use updateOptions instead.

This method updates or creates the menu. You can use an array of MenuItem from Electron/NW.js, or directly Menu.getApplicationMenu() in Electron.

// With a menu template
const menu = [
  {
    label: 'Item 1',
    submenu: [
      {
        label: 'Subitem 1',
        click: () => console.log('Clicked on subitem 1')
      },
      {
        type: 'separator'
      },
      {
        label: 'Subitem 2',
        click: () => console.log('Clicked on subitem 2')
      },
    ]
  },
  {
    label: 'Item 2',
    submenu: [
      {
        label: 'Subitem checkbox',
        type: 'checkbox',
        checked: true
      },
      {
        type: 'separator'
      },
      {
        label: 'Subitem with submenu',
        submenu: [
          {
            label: 'Submenu item 1',
            accelerator: 'Ctrl+T'
          }
        ]
      }
    ]
  }
];
titlebar.updateMenu(menu);

// Or with getApplicationMenu in Electron
titlebar.updateMenu(Menu.getApplicationMenu());

// Disable menu
titlebar.updateMenu();

dispose

This method removes the titlebar completely and all recorded events.

titlebar.dispose();

CSS Classes

The following CSS classes exist and can be used to customize the titlebar.

| Class name | Description | | ------------------------------ | ---------------------------------------------- | | custom-titlebar | Style of the titlebar. | | custom-titlebar-appicon | Style of the icon. | | custom-titlebar-container | Style of the container under the titlebar. | | custom-titlebar-controls | Style of the window controls. | | custom-titlebar-menu-item | Style of the main menu items. | | custom-titlebar-separator | Style of the separators. | | custom-titlebar-submenu | Style of the submenus. | | custom-titlebar-submenu-item | Style of the submenu items. |


Made with love and fun from France ❤