Mailspring/docs/creating-a-theme.md
Ben Gotow 1e8fd46342 fix(drafts): Various improvements and fixes to drafts, draft state management
Summary:
This diff contains a few major changes:

1. Scribe is no longer used for the text editor. It's just a plain contenteditable region. The toolbar items (bold, italic, underline) still work. Scribe was causing React inconcistency issues in the following scenario:
   - View thread with draft, edit draft
   - Move to another thread
   - Move back to thread with draft
   - Move to another thread. Notice that one or more messages from thread with draft are still there.

There may be a way to fix this, but I tried for hours and there are Github Issues open on it's repository asking for React compatibility, so it may be fixed soon. For now contenteditable is working great.

2. Action.saveDraft() is no longer debounced in the DraftStore. Instead, firing that action causes the save to happen immediately, and the DraftStoreProxy has a new "DraftChangeSet" class which is responsbile for batching saves as the user interacts with the ComposerView. There are a couple big wins here:

   - In the future, we may want to be able to call Action.saveDraft() in other situations and it should behave like a normal action. We may also want to expose the DraftStoreProxy as an easy way of backing interactive draft UI.

   - Previously, when you added a contact to To/CC/BCC, this happened:

     <input> -> Action.saveDraft -> (delay!!) -> Database -> DraftStore -> DraftStoreProxy -> View Updates

Increasing the delay to something reasonable like 200msec meant there was 200msec of lag before you saw the new view state.

To fix this, I created a new class called DraftChangeSet which is responsible for accumulating changes as they're made and firing Action.saveDraft. "Adding" a change to the change set also causes the Draft provided by the DraftStoreProxy to change immediately (the changes are a temporary layer on top of the database object). This means no delay while changes are being applied. There's a better explanation in the source!

This diff includes a few minor fixes as well:

1. Draft.state is gone—use Message.object = draft instead
2. String model attributes should never be null
3. Pre-send checks that can cancel draft send
4. Put the entire curl history and task queue into feedback reports
5. Cache localIds for extra speed
6. Move us up to latest React

Test Plan: No new tests - once we lock down this new design I'll write tests for the DraftChangeSet

Reviewers: evan

Reviewed By: evan

Differential Revision: https://review.inboxapp.com/D1125
2015-02-03 16:24:31 -08:00

6.4 KiB

Creating a Theme

Atom's interface is rendered using HTML, and it's styled via Less which is a superset of CSS. Don't worry if you haven't heard of Less before; it's just like CSS, but with a few handy extensions.

Atom supports two types of themes: UI and syntax. UI themes style elements such as the tree view, the tabs, drop-down lists, and the status bar. Syntax themes style the code inside the editor.

Themes can be installed and changed from the settings view which you can open by selecting the Atom > Preferences... menu and navigating to the Install section and the Themes section on the left hand side.

Getting Started

Themes are pretty straightforward but it's still helpful to be familiar with a few things before starting:

  • Less is a superset of CSS, but it has some really handy features like variables. If you aren't familiar with its syntax, take a few minutes to familiarize yourself.
  • You may also want to review the concept of a package.json, too. This file is used to help distribute your theme to Atom users.
  • Your theme's package.json must contain a "theme" key with a value of "ui" or "syntax" for Atom to recognize and load it as a theme.
  • You can find existing themes to install or fork on atom.io.

Creating a Syntax Theme

Let's create your first theme.

To get started, hit cmd-shift-P, and start typing "Generate Syntax Theme" to generate a new theme package. Select "Generate Syntax Theme," and you'll be asked for the path where your theme will be created. Let's call ours motif-syntax. Tip: syntax themes should end with -syntax.

Atom will pop open a new window, showing the motif-syntax theme, with a default set of folders and files created for us. If you open the settings view (cmd-,) and navigate to the Themes section on the left, you'll see the Motif theme listed in the Syntax Theme drop-down. Select it from the menu to activate it, now when you open an editor you should see that your new motif-syntax theme in action.

Open up styles/colors.less to change the various colors variables which have been already been defined. For example, turn @red into #f4c2c1.

Then open styles/base.less and modify the various selectors that have been already been defined. These selectors style different parts of code in the editor such as comments, strings and the line numbers in the gutter.

As an example, let's make the .gutter background-color into @red.

Reload Atom by pressing cmd-alt-ctrl-l to see the changes you made reflected in your Atom window. Pretty neat!

Tip: You can avoid reloading to see changes you make by opening an atom window in dev mode. To open a Dev Mode Atom window run atom --dev . in the terminal, use cmd-shift-o or use the View > Developer > Open in Dev Mode menu. When you edit your theme, changes will instantly be reflected!

Note: It's advised to not specify a font-family in your syntax theme because it will override the Font Family field in Atom's settings. If you still like to recommend a font that goes well with your theme, we recommend you do so in your README.

Creating an Interface Theme

Interface themes must provide a ui-variables.less file which contains all of the variables provided by the core themes.

To create an interface UI theme, do the following:

  1. Fork one of the following repositories:
  1. Clone the forked repository to the local filesystem
  2. Open a terminal in the forked theme's directory
  3. Open your new theme in a Dev Mode Atom window run atom --dev . in the terminal or use the View > Developer > Open in Dev Mode menu
  4. Change the name of the theme in the theme's package.json file
  5. Name your theme end with a -ui. i.e. super-white-ui
  6. Run apm link to symlink your repository to ~/.atom/packages
  7. Reload Atom using cmd-alt-ctrl-L
  8. Enable the theme via UI Theme drop-down in the Themes section of the settings view
  9. Make changes! Since you opened the theme in a Dev Mode window, changes will be instantly reflected in the editor without having to reload.

Development workflow

There are a few of tools to help make theme development faster and easier.

Live Reload

Reloading by hitting cmd-alt-ctrl-L after you make changes to your theme is less than ideal. Atom supports live updating of styles on Dev Mode Atom windows.

To enable a Dev Mode window:

  1. Open your theme directory in a dev window by either going to the View > Developer > Open in Dev Mode menu or by hitting the cmd-shift-o shortcut
  2. Make a change to your theme file and save it. Your change should be immediately applied!

If you'd like to reload all the styles at any time, you can use the shortcut cmd-ctrl-shift-r.

Developer Tools

Atom is based on the Chrome browser, and supports Chrome's Developer Tools. You can open them by selecting the View > Toggle Developer Tools menu, or by using the cmd-alt-i shortcut.

The dev tools allow you to inspect elements and take a look at their CSS properties.

devtools-img

Check out Google's extensive tutorial for a short introduction.

Atom Styleguide

If you are creating an interface theme, you'll want a way to see how your theme changes affect all the components in the system. The styleguide is a page that renders every component Atom supports.

To open the styleguide, open the command palette (cmd-shift-P) and search for styleguide, or use the shortcut cmd-ctrl-shift-g.

styleguide-img