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

@attorn/electron-theme

v2.0.2

Published

A package for theming electron projects with the ability to create, change, install and uninstall themes

Downloads

6

Readme

Getting started

The @attorm/electron-theme is created to theming electron projects. With this package you have the ability to create, install, uninstall and change themes and immediately apply them into your UI.

Because in Attorn Studio, we wanted our users to be able to customize their interface, we decided to create this package.

You can also use it in your electron projects by reading these documents and understanding how @attorm/electron-theme works.

Installation

Using yarn (strongly recommended):

yarn add @attorn/electron-theme

Or using npm:

npm i @attorn/electron-theme

HOW TO USE

We have a special workflow in this package that you can imagine a life cycle about. The following explanations make this clear:

  1. When your app is ready to be displayed, you will read the installed themes from storage (ipcMain).
  2. Identify the theme selected in the user settings and create a css root from it (ipcMain).
  3. You pass the css root to the renderer and the renderer adds it to the stylesheet (ipcRenderer)..

These are the things that happen every time you application is opened. But then you have some helpers that can do the followings:

  • [x] Install new themes in user storage.
  • [x] Remove user-installed themes.
  • [x] Get a list of installed themes (regardless of whether they were installed by the user or you created them by default for your project)
  • [x] Make a new selection from the list of themes.

Now that you have dived into it and realized its workflow, it is time to read the following examples so that you can use this package.

We assume that you are building your application with react. But please think outside the box. You can modify these examples in your renderer method and use this package no matter what you are using in the renderer (including Simple JavaScript, React, Angular, Vue or etc). So let's dive into react examples.

1. Initialize default themes

First you need some default themes. Something like this:

import { AttornElectronTheme } from  '@attorn/electron-theme';

const defaultDark: AttornElectronTheme.Themes = {
   name: 'default-dark',
   theme: { background: 'black', color: 'white'}
}
const defaultLight: AttornElectronTheme.Themes = {
   name: 'default-light',
   theme: { background: 'light', color: 'black'}
}

export const themes = [defaultDark, defaultLight];

Second in your main (where you make an instance of electron BrowserWindow class), add a new listener called before-ready-to-show or anything else you want. Then use sender inside it to send css root to renderer. We will make get-css-root listener in renderer in next step.

import { ipcMain } from  'electron';
import { initializeTheme } from  '@attorn/electron-theme';
import { themes } from '../path-to-your-themes';

ipcMain.on('before-ready-to-show', ({ sender }) => {
   const { allThemes, activeTheme, root } = initializeTheme(themes);
   // in here we have two extra results (allThemes and activeTheme). we do not use theme in these examples but you can use theme if you want.
   sender.send('get-css-root', root);
})

Then in your entry point of your renderer, do something like this:

import { FC, useEffect, useState } from 'react';
import { ipcRenderer } from  'electron';
import { addThemeToStylesheet } from  '@attorn/electron-theme';

export const AppEntryPoint: FC = (): JSX.Element => {
   const [didMount, setDidMount] =  useState<boolean>(false);
   
   ipcRenderer.on('get-css-root', (_, root) => {
      setDidMount(true);
      addThemeToStylesheet(root);
   });
   
   useEffect(() =>  ipcRenderer.send('before-ready-to-show'), []);
   
   return didMount ? <p>My App</p> : <>loading...</>;
}

That's all for the first steps. You now have multiple default themes.

2. Changing them

In order to change themes, you will need another listener in your main. Then use sender inside it to send outcomes to renderer. We will make gchange-theme-result listener in renderer in next step.

import { ipcMain } from  'electron';
import { changeTheme } from  '@attorn/electron-theme';

ipcMain.on('change-theme', ({ sender }, themeName: string) => {
   const outcomes = changeTheme(themeName)
   // the outcome is something like this:
   // { result: true, root: string }
   // if outcomes.result is "false", that means there is no installed themes here called "themeName"
   sender.send('change-theme-result', outcomes);
})

Well, create a component like this somewhere in your renderer. In this component you need some buttons (the number of themes installed) to change theme.

import { FC } from 'react';
import { ipcRenderer } from 'electron';

export const ThemeChanger: FC = (): JSX.Element => {
   const changeTo = (name: string) => ipcRenderer.send('change-theme', name);
   ipcRenderer.on('change-theme-result', (_, msg) => console.log(msg))

   return (<>
      <button onClick={() => changeTo('default-dark')}>Default Dark</button>
      <button onClick={() => changeTo('default-light')}>Default Light</button>
   </>)
}

And yes, that's all you need to do for change themes.

3. Install and uninstall themes

If you, like Attorn Studio, think that your users should be able to customize your app to a great extent, you need to introduce new themes or, like apps like VSCode, Atom or Attorn Studio, have an online system, which allows users to create their own themes and make them available to the public. In this example you will see how you can implement this process using this package.

First you need two new listeners. One for install (install-theme) and another for uninstall (uninstall-theme). You can also combine these two listeners together by passing a flag to specify if user wants to install or uninstall theme. But anyway, here is the example you can follow:

import { ipcMain } from  'electron';
import { installTheme, uninstallTheme, AttornElectronTheme } from  '@attorn/electron-theme';

ipcMain.on('install-theme', (_, { name, theme }: AttornElectronTheme.Themes) => {
   installTheme({ name, theme });
});
ipcMain.on('uninstall-theme', (_, theme: AttornElectronTheme.Themes) => {
   uninstallTheme(theme.name);
});

And in your renderer you can have something like this:

import { FC } from 'react';
import { ipcRenderer } from  'electron';
import { AttornElectronTheme } from '@attorn/electron-theme';

export const ThemeWorker: FC = ():  JSX.Element => {
   // suppose you got this object from a server
   const mockThemes: AttornElectronTheme.Themes[] = [
      { name: 'theme-0', theme: { background: 'red', color: 'black' } },
      { name: 'theme-1', theme: { background: 'black', color: 'red' } },
   ]

   const install = (theme: AttornElectronTheme.Themes) => ipcRenderer.send('install-theme', theme);
   const uninstall = (theme: AttornElectronTheme.Themes) => ipcRenderer.send('uninstall-theme', theme);

   return (<>
      <button onClick={() => install(mockThemes[0])}>install theme-0</button>
      <button onClick={() => install(mockThemes[1])}>install theme-1</button>

      <button onClick={() => uninstall(mockThemes[0])}>uninstall theme-0</button>
      <button onClick={() => uninstall(mockThemes[1])}>uninstall theme-1</button>
   </>)
}

License

The @attorn/electron-storage is MIT licensed