From bc916a25306bfb9d77dd163bcda21e3a0b127fc7 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Fri, 5 Jun 2015 11:40:44 -0700 Subject: [PATCH] feat(theming): Definitely not hacker mode. I don't know what you're talking about. Summary: Add docs for new RetinaImg modes Test Plan: Not much to test, except that it looks good! Reviewers: evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D1595 --- .../lib/account-sidebar-sheet-item.cjsx | 4 +- .../lib/account-sidebar-tag-item.cjsx | 2 +- .../stylesheets/account-sidebar.less | 5 +- .../composer/lib/compose-button.cjsx | 2 +- .../composer/lib/composer-view.cjsx | 12 +- .../composer/stylesheets/composer.less | 2 + .../message-list/lib/email-frame.cjsx | 114 +----------------- .../message-list/lib/message-item.cjsx | 12 +- .../message-list/lib/message-list.cjsx | 3 +- .../lib/thread-archive-button.cjsx | 2 +- .../message-list/lib/thread-tags-button.cjsx | 4 +- .../stylesheets/message-list.less | 8 +- .../lib/template-picker.cjsx | 4 +- .../mode-switch/lib/mode-switch.cjsx | 8 +- .../mode-switch/lib/mode-toggle.cjsx | 6 +- .../mode-switch/stylesheets/mode-switch.less | 19 ++- .../onboarding/lib/container-view.cjsx | 12 +- .../onboarding/stylesheets/onboarding.less | 10 +- .../search-bar/lib/search-bar.cjsx | 1 + .../lib/sidebar-fullcontact-details.cjsx | 5 +- .../stylesheets/sidebar-fullcontact.less | 6 +- .../thread-list/lib/thread-buttons.cjsx | 8 +- .../thread-list/lib/thread-list.cjsx | 4 +- .../tooltip/stylesheets/tooltip.less | 2 +- .../ui-dark/styles/ui-variables.less | 51 +++++++- menus/darwin.cson | 2 + menus/linux.cson | 2 + menus/win32.cson | 2 + src/browser/application.coffee | 8 ++ src/components/empty-state.cjsx | 8 +- src/components/popover.cjsx | 5 +- src/components/retina-img.cjsx | 59 +++++++-- src/components/tokenizing-text-field.cjsx | 4 +- src/sheet-toolbar.cjsx | 4 +- src/theme-manager.coffee | 1 + static/buttons.less | 10 +- static/components/list-tabular.less | 7 +- static/components/popover.less | 4 +- static/components/tokenizing-text-field.less | 1 + static/email-frame.less | 80 ++++++++++++ static/inputs.less | 1 + static/variables/ui-variables.less | 22 ---- static/workspace.less | 1 + 43 files changed, 314 insertions(+), 213 deletions(-) create mode 100644 static/email-frame.less diff --git a/internal_packages/account-sidebar/lib/account-sidebar-sheet-item.cjsx b/internal_packages/account-sidebar/lib/account-sidebar-sheet-item.cjsx index 04aebecb4..fdc09f65f 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar-sheet-item.cjsx +++ b/internal_packages/account-sidebar/lib/account-sidebar-sheet-item.cjsx @@ -17,10 +17,10 @@ class AccountSidebarSheetItem extends React.Component icon = else if _.isString(@props.item.icon) - icon = + icon = else - icon = + icon =
{icon} diff --git a/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx b/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx index 2d123151d..35bf902f3 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx +++ b/internal_packages/account-sidebar/lib/account-sidebar-tag-item.cjsx @@ -21,7 +21,7 @@ class AccountSidebarTagItem extends React.Component 'selected': @props.select
- + {@props.item.name} {unread}
diff --git a/internal_packages/account-sidebar/stylesheets/account-sidebar.less b/internal_packages/account-sidebar/stylesheets/account-sidebar.less index a6add0b89..7e32e6be4 100644 --- a/internal_packages/account-sidebar/stylesheets/account-sidebar.less +++ b/internal_packages/account-sidebar/stylesheets/account-sidebar.less @@ -22,6 +22,7 @@ .item { color: @text-color-subtle; + img.content-mask { background-color: @text-color-subtle; } font-size: @font-size-small; font-weight: 400; padding: 0 @spacing-standard; @@ -47,9 +48,7 @@ &.selected { background: @source-list-active-bg; color: @source-list-active-color; - img.colorfill { - background: @source-list-active-color; - } + img.content-mask { background-color: @source-list-active-color; } } &:hover { diff --git a/internal_packages/composer/lib/compose-button.cjsx b/internal_packages/composer/lib/compose-button.cjsx index e63d22693..5b7c0a055 100644 --- a/internal_packages/composer/lib/compose-button.cjsx +++ b/internal_packages/composer/lib/compose-button.cjsx @@ -10,7 +10,7 @@ class ComposeButton extends React.Component className="btn btn-toolbar" data-tooltip="Compose new message" onClick={@_onNewCompose}> - + _onNewCompose: => Actions.composeNewBlankDraft() diff --git a/internal_packages/composer/lib/composer-view.cjsx b/internal_packages/composer/lib/composer-view.cjsx index 61e1c296d..506d97afb 100644 --- a/internal_packages/composer/lib/composer-view.cjsx +++ b/internal_packages/composer/lib/composer-view.cjsx @@ -155,7 +155,11 @@ class ComposerView extends React.Component + onClick={@_popoutComposer}> + +
@@ -260,18 +264,18 @@ class ComposerView extends React.Component + onClick={@_destroyDraft}> + onClick={@_attachFile}>
+ onClick={@_sendDraft}> Send diff --git a/internal_packages/composer/stylesheets/composer.less b/internal_packages/composer/stylesheets/composer.less index 475729dd4..41475f8f7 100644 --- a/internal_packages/composer/stylesheets/composer.less +++ b/internal_packages/composer/stylesheets/composer.less @@ -70,6 +70,7 @@ .header-action { color: @text-color-very-subtle; + img.content-mask { background-color: @text-color-very-subtle; } font-size: @font-size-small; padding-left: 1em; &:hover { @@ -93,6 +94,7 @@ } input, textarea, div[contenteditable] { + color: @text-color; position: relative; z-index: 1; display: block; diff --git a/internal_packages/message-list/lib/email-frame.cjsx b/internal_packages/message-list/lib/email-frame.cjsx index eef9dfc11..d51bedee6 100644 --- a/internal_packages/message-list/lib/email-frame.cjsx +++ b/internal_packages/message-list/lib/email-frame.cjsx @@ -3,114 +3,6 @@ _ = require "underscore" {EventedIFrame} = require 'nylas-component-kit' {Utils} = require 'nylas-exports' -EmailFixingStyles = """ - -""" - class EmailFrame extends React.Component @displayName = 'EmailFrame' @@ -140,7 +32,11 @@ class EmailFrame extends React.Component wrapperClass = if @props.showQuotedText then "show-quoted-text" else "" doc = React.findDOMNode(@).contentDocument doc.open() - doc.write(EmailFixingStyles) + + EmailFixingStyles = document.querySelector('[source-path*="email-frame.less"]')?.innerText + EmailFixingStyles = EmailFixingStyles.replace(/.ignore-in-parent-frame/g, '') + if (EmailFixingStyles) + doc.write("") doc.write("
#{@_emailContent()}
") doc.close() diff --git a/internal_packages/message-list/lib/message-item.cjsx b/internal_packages/message-list/lib/message-item.cjsx index 726295c42..d49f7bbfc 100644 --- a/internal_packages/message-list/lib/message-item.cjsx +++ b/internal_packages/message-list/lib/message-item.cjsx @@ -134,20 +134,20 @@ class MessageItem extends React.Component _renderMessageActions: =>
- +
@@ -221,13 +221,13 @@ class MessageItem extends React.Component
@setState detailedHeaders: false}> - +
else
@setState detailedHeaders: true}> - +
# Eventually, _formatBody will run a series of registered body transformers. diff --git a/internal_packages/message-list/lib/message-list.cjsx b/internal_packages/message-list/lib/message-list.cjsx index 192390713..187d4007e 100755 --- a/internal_packages/message-list/lib/message-list.cjsx +++ b/internal_packages/message-list/lib/message-list.cjsx @@ -98,7 +98,8 @@ class MessageList extends React.Component if @_hasReplyArea()
- Write a reply… + + Write a reply…
else return
diff --git a/internal_packages/message-list/lib/thread-archive-button.cjsx b/internal_packages/message-list/lib/thread-archive-button.cjsx index af1528707..b7eccc81d 100644 --- a/internal_packages/message-list/lib/thread-archive-button.cjsx +++ b/internal_packages/message-list/lib/thread-archive-button.cjsx @@ -10,7 +10,7 @@ class ArchiveButton extends React.Component _onArchive: (e) => diff --git a/internal_packages/message-list/lib/thread-tags-button.cjsx b/internal_packages/message-list/lib/thread-tags-button.cjsx index 654365462..bc56a4363 100644 --- a/internal_packages/message-list/lib/thread-tags-button.cjsx +++ b/internal_packages/message-list/lib/thread-tags-button.cjsx @@ -59,8 +59,8 @@ class ThreadTagsButton extends React.Component render: => button = headerComponents = [ diff --git a/internal_packages/message-list/stylesheets/message-list.less b/internal_packages/message-list/stylesheets/message-list.less index 1f77e74e9..46c619fa9 100644 --- a/internal_packages/message-list/stylesheets/message-list.less +++ b/internal_packages/message-list/stylesheets/message-list.less @@ -42,6 +42,7 @@ .message-toolbar-arrow.down { order:101; + margin-right: 0; padding-top:6px; } .message-toolbar-arrow.up { @@ -130,6 +131,7 @@ .collapsed-from { font-weight: @font-weight-semi-bold; + color: @text-color; // min-width: 60px; margin-right: 1em; } @@ -249,10 +251,12 @@ .footer-reply-area-wrap { width: 100%; - color: @text-color-very-subtle; border-top: 1px solid @border-color-divider; background: @background-primary; + color: @text-color-very-subtle; + img.content-mask { background-color:@text-color-very-subtle; } + &:hover { cursor: default; } @@ -371,7 +375,7 @@ .column-MessageListSidebar { background-color: @background-off-primary; overflow: auto; - border-left: 1px solid #ddd; + border-left: 1px solid @border-color-divider; .flexbox-handle-horizontal div { border-right: 0; width: 1px; diff --git a/internal_packages/message-templates/lib/template-picker.cjsx b/internal_packages/message-templates/lib/template-picker.cjsx index 80b02c53a..365ac4842 100644 --- a/internal_packages/message-templates/lib/template-picker.cjsx +++ b/internal_packages/message-templates/lib/template-picker.cjsx @@ -23,8 +23,8 @@ class TemplatePicker extends React.Component render: => button = headerComponents = [ diff --git a/internal_packages/mode-switch/lib/mode-switch.cjsx b/internal_packages/mode-switch/lib/mode-switch.cjsx index 4ae874fdf..496b97b4f 100644 --- a/internal_packages/mode-switch/lib/mode-switch.cjsx +++ b/internal_packages/mode-switch/lib/mode-switch.cjsx @@ -36,6 +36,7 @@ class ModeSwitch extends React.Component @@ -45,14 +46,15 @@ class ModeSwitch extends React.Component name="modeslider-knob.png" className="handle" style={top:4, left: knobX}/> -
- + _onStateChanged: => @setState(@_getStateFromStores()) diff --git a/internal_packages/mode-switch/lib/mode-toggle.cjsx b/internal_packages/mode-switch/lib/mode-toggle.cjsx index 11b0eca12..d851b15e1 100644 --- a/internal_packages/mode-switch/lib/mode-toggle.cjsx +++ b/internal_packages/mode-switch/lib/mode-toggle.cjsx @@ -20,15 +20,15 @@ class ModeToggle extends React.Component render: => return
unless @state.visible -
- + _onStateChanged: => @setState(@_getStateFromStores()) diff --git a/internal_packages/mode-switch/stylesheets/mode-switch.less b/internal_packages/mode-switch/stylesheets/mode-switch.less index 7500ea2e3..1af16f80d 100644 --- a/internal_packages/mode-switch/stylesheets/mode-switch.less +++ b/internal_packages/mode-switch/stylesheets/mode-switch.less @@ -1,19 +1,14 @@ @import 'ui-variables'; -.mode-switch { - z-index: 1000; - position: relative; - - .handle { - position:absolute; - transition: left .2s ease-out; - } -} .mode-toggle { z-index: 1000; position: relative; - - .colorfill { - background-color: @component-active-color; + .content-mask { + background-color: @text-color-subtle; } } +.mode-toggle.mode-split { + .content-mask { + background-color: @component-active-color; + } +} diff --git a/internal_packages/onboarding/lib/container-view.cjsx b/internal_packages/onboarding/lib/container-view.cjsx index fed7fdb19..a5a45e169 100644 --- a/internal_packages/onboarding/lib/container-view.cjsx +++ b/internal_packages/onboarding/lib/container-view.cjsx @@ -69,12 +69,12 @@ class ContainerView extends React.Component if @state.page is 'welcome'
- +

Welcome to Nylas

- +
Enter your email address:
@@ -95,12 +95,12 @@ class ContainerView extends React.Component else if @state.page == 'add-account'
- +
- +

Connect an Account

- +
Link accounts from other services to supercharge your email.
@@ -119,7 +119,7 @@ class ContainerView extends React.Component }) }
- +
diff --git a/internal_packages/onboarding/stylesheets/onboarding.less b/internal_packages/onboarding/stylesheets/onboarding.less index 251b06b10..c7bc4f9f3 100644 --- a/internal_packages/onboarding/stylesheets/onboarding.less +++ b/internal_packages/onboarding/stylesheets/onboarding.less @@ -11,7 +11,7 @@ 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } -} +} @-webkit-keyframes fill { 0% { opacity: 0; border-width: @checkSize / 2; } @@ -22,7 +22,7 @@ .onboarding-container { width:100%; height:100%; - background-color: #f0f0f0; + background-color: @gray-lighter; -webkit-animation: fadein 0.8s; text-align: center; @@ -38,7 +38,7 @@ .logo { padding-top:40px; } - + h2 { margin-top: 27px; margin-bottom: 90px; @@ -135,7 +135,7 @@ bottom: 9%; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.08); } - + &:after { content: ""; position: absolute; @@ -152,7 +152,7 @@ -webkit-animation: fill 0.5s forwards; -webkit-animation-delay: 0.8s; } - + .check-icon { position: absolute; z-index: 3; diff --git a/internal_packages/search-bar/lib/search-bar.cjsx b/internal_packages/search-bar/lib/search-bar.cjsx index fcee4147c..75200ed7d 100644 --- a/internal_packages/search-bar/lib/search-bar.cjsx +++ b/internal_packages/search-bar/lib/search-bar.cjsx @@ -52,6 +52,7 @@ class SearchBar extends React.Component
- +
{@_username(profile)} {@_twitterBio(profile)} diff --git a/internal_packages/sidebar-fullcontact/stylesheets/sidebar-fullcontact.less b/internal_packages/sidebar-fullcontact/stylesheets/sidebar-fullcontact.less index 2624cd162..8e7dc19bd 100644 --- a/internal_packages/sidebar-fullcontact/stylesheets/sidebar-fullcontact.less +++ b/internal_packages/sidebar-fullcontact/stylesheets/sidebar-fullcontact.less @@ -7,6 +7,10 @@ flex-shrink: 0; .full-contact { + color: @text-color; + -webkit-user-select:text; + img.content-mask { background-color: @text-color; } + h1.name { font-size: 20px; font-weight: @font-weight-normal; @@ -41,7 +45,7 @@ .social-profile { margin-top: 0.5em; .social-icon { - padding-top: 6px; + margin-top: 6px; float: left; } .social-link { diff --git a/internal_packages/thread-list/lib/thread-buttons.cjsx b/internal_packages/thread-list/lib/thread-buttons.cjsx index e5dbe29e5..d97081608 100644 --- a/internal_packages/thread-list/lib/thread-buttons.cjsx +++ b/internal_packages/thread-list/lib/thread-buttons.cjsx @@ -16,7 +16,7 @@ class ThreadBulkArchiveButton extends React.Component className="btn btn-toolbar" data-tooltip="Archive" onClick={@_onArchive}> - + _onArchive: => @@ -55,11 +55,12 @@ DownButton = React.createClass render: ->
- +
_classSet: -> classNames + "btn-icon": true "message-toolbar-arrow": true "down": true "disabled": @state.disabled @@ -77,11 +78,12 @@ UpButton = React.createClass render: ->
- +
_classSet: -> classNames + "btn-icon": true "message-toolbar-arrow": true "up": true "disabled": @state.disabled diff --git a/internal_packages/thread-list/lib/thread-list.cjsx b/internal_packages/thread-list/lib/thread-list.cjsx index 815c2e30a..9b89d408a 100644 --- a/internal_packages/thread-list/lib/thread-list.cjsx +++ b/internal_packages/thread-list/lib/thread-list.cjsx @@ -55,7 +55,9 @@ class ThreadList extends React.Component if hasDraft
- +
else diff --git a/internal_packages/tooltip/stylesheets/tooltip.less b/internal_packages/tooltip/stylesheets/tooltip.less index 9c3ccc9e1..cea85fda5 100644 --- a/internal_packages/tooltip/stylesheets/tooltip.less +++ b/internal_packages/tooltip/stylesheets/tooltip.less @@ -18,7 +18,7 @@ background: #fff; box-shadow: 0 10px 20px rgba(0,0,0,0.19), inset 0 0 1px rgba(0,0,0,0.5); border-radius: @border-radius-base; - color: @text-color; + color: #313435; font-weight: @font-weight-normal; text-align: center; diff --git a/internal_packages/ui-dark/styles/ui-variables.less b/internal_packages/ui-dark/styles/ui-variables.less index 7281b9e92..1074e2fd3 100644 --- a/internal_packages/ui-dark/styles/ui-variables.less +++ b/internal_packages/ui-dark/styles/ui-variables.less @@ -1 +1,50 @@ -@background-primary: #ffffff; +@gray-base: #ffffff; +@gray-darker: darken(@gray-base, 13.5%); // #222 +@gray-dark: darken(@gray-base, 20%); // #333 +@gray: darken(@gray-base, 33.5%); // #555 +@gray-light: darken(@gray-base, 46.7%); // #777 +@gray-lighter: darken(@gray-base, 92.5%); // #eee +@white: #0a0b0c; + +@background-off-primary: #333; +@background-secondary: #2D2D2D; +@background-tertiary: #6d7987; + +@background-primary: #313131; +@background-color: darken(#313131, 15%); +@btn-default-bg-color: #404040; +@accent-primary: #5AA8FA; +@accent-primary-dark: #3087E1; + +@text-color: #C2C2C2; +@text-color-subtle: fadeout(@text-color, 20%); +@text-color-very-subtle: fadeout(@text-color, 40%); +@text-color-inverse: white; +@text-color-inverse-subtle: fadeout(@text-color-inverse, 20%); +@text-color-inverse-very-subtle: fadeout(@text-color-inverse, 50%); +@text-color-heading: #FFF; + +@border-primary-bg: lighten(@background-primary, 10%); +@border-secondary-bg: lighten(@background-secondary, 10%); +@border-tertiary-bg: lighten(@background-tertiary, 10%); +@border-color-divider: @border-secondary-bg; + +@input-bg: #242424; +@input-border: @border-color-divider; + +@list-bg: #333; +@list-border: #383838; + +@list-selected-color: @text-color-inverse; + +@toolbar-background-color: @background-secondary; + +.thread-icon:not(.thread-icon-unread) { + -webkit-filter: invert(100%); +} +img.content-dark { + -webkit-filter: invert(100%); +} +img.content-light { + -webkit-filter: invert(100%); +} diff --git a/menus/darwin.cson b/menus/darwin.cson index 5a39bf237..a7cbd6d06 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -52,6 +52,8 @@ { label: 'Developer' submenu: [ + { label: 'Toggle Hacker Theme', command: 'application:toggle-theme' } + { type: 'separator' } { label: 'Open In Dev Mode...', command: 'application:open-dev' } { type: 'separator' } { label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' } diff --git a/menus/linux.cson b/menus/linux.cson index 7516510d4..ce6cf61f4 100644 --- a/menus/linux.cson +++ b/menus/linux.cson @@ -35,6 +35,8 @@ { label: 'Developer' submenu: [ + { label: 'Toggle Hacker Theme', command: 'application:toggle-theme' } + { type: 'separator' } { label: 'Open In &Dev Mode...', command: 'application:open-dev' } { type: 'separator' } { label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' } diff --git a/menus/win32.cson b/menus/win32.cson index e01f0e5dc..debc3ddb6 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -37,6 +37,8 @@ { label: 'Developer' submenu: [ + { label: 'Toggle Hacker Theme', command: 'application:toggle-theme' } + { type: 'separator' } { label: 'Open In &Dev Mode...', command: 'application:open-dev' } { type: 'separator' } { label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' } diff --git a/src/browser/application.coffee b/src/browser/application.coffee index 6b89bb8fe..91cf22584 100644 --- a/src/browser/application.coffee +++ b/src/browser/application.coffee @@ -249,6 +249,14 @@ class Application @windowManager.devMode = true @windowManager.ensurePrimaryWindowOnscreen() + @on 'application:toggle-theme', => + themes = @config.get('core.themes') ? [] + if 'ui-dark' in themes + themes = _.without themes, 'ui-dark' + else + themes.push('ui-dark') + @config.set('core.themes', themes) + if process.platform is 'darwin' @on 'application:about', -> Menu.sendActionToFirstResponder('orderFrontStandardAboutPanel:') @on 'application:bring-all-windows-to-front', -> Menu.sendActionToFirstResponder('arrangeInFront:') diff --git a/src/components/empty-state.cjsx b/src/components/empty-state.cjsx index 7ba9cd2c3..179a83438 100644 --- a/src/components/empty-state.cjsx +++ b/src/components/empty-state.cjsx @@ -53,10 +53,10 @@ class EmptyState extends React.Component {@state.message?.byline}
- - - - + + + +
diff --git a/src/components/popover.cjsx b/src/components/popover.cjsx index 8f702070f..83767430b 100644 --- a/src/components/popover.cjsx +++ b/src/components/popover.cjsx @@ -102,8 +102,9 @@ class Popover extends React.Component pointerStyle = 'position': 'absolute' 'marginLeft': '50%' - 'width': 22.5 - 'height': 11 + 'zoom': 0.5 + 'width': 45 + 'height': 21 'zIndex': 0 if @props.direction is 'up' diff --git a/src/components/retina-img.cjsx b/src/components/retina-img.cjsx index 22389bfc3..4c7b3c612 100644 --- a/src/components/retina-img.cjsx +++ b/src/components/retina-img.cjsx @@ -23,6 +23,12 @@ StylesImpactedByZoom = [ # constant at require-time DEFAULT_RESOURCE_PATH = atom.getLoadSettings().resourcePath +Mode = + ContentPreserve: 'original' + ContentLight: 'light' + ContentDark: 'dark' + ContentIsMask: 'mask' + ### Public: RetinaImg wraps the DOM's standard ` tag and implements a `UIImage` style interface. Rather than specifying an image `src`, RetinaImg allows you to provide @@ -31,45 +37,84 @@ display based on pixel density. Given `image.png`, on a Retina screen, it looks `image@2x.png`, `image.png`, `image@1x.png` in that order. It uses a lookup table and caches image names, so images generally resolve immediately. +RetinaImg also introduces the concept of image `modes`. Specifying an image mode +is important for theming: it describes the content of your image, allowing theme +developers to properly adjust it. The four modes are described below: + +- `ContentPreserve`: Your image contains color or should not be adjusted by any theme. + +- `ContentLight`: Your image is a grayscale image with light colors, intended to be shown + against a dark background. If a theme developer changes the background to be light, they + can safely apply CSS filters to invert or darken this image. This mode adds the + `content-light` CSS class to the image. + +- `ContentDark`: Your image is a grayscale image with dark colors, intended to be shown + against a light background. If a theme developer changes the background to be dark, they + can safely apply CSS filters to invert or brighten this image. This mode adds the + `content-dark` CSS class to the image. + +- `ContentIsMask`: This image provides alpha information only, and color should + be based on the `background-color` of the RetinaImg. This mode adds the + `content-mask` CSS class to the image, and leverages `-webkit-mask-image`. + + Example: Icons displayed within buttons specify ContentIsMask, and their + color is declared via CSS to be the same as the button text color. Changing + `@text-color-subtle` in a theme changes both button text and button icons! + + ```css + .btn-icon { + color: @text-color-subtle; + img.content-mask { background-color:@text-color-subtle; } + } + ``` + Section: Component Kit ### class RetinaImg extends React.Component @displayName: 'RetinaImg' + @Mode: Mode ### Public: React `props` supported by RetinaImg: + - `mode` (required) One of the RetinaImg.Mode constants. See above for details. - `name` (optional) A {String} image name to display. + - `url` (optional) A {String} url of an image to display. + May be an http, https, or `nylas:///` URL. - `fallback` (optional) A {String} image name to use when `name` cannot be found. - `selected` (optional) Appends "-selected" to the end of the image name when when true - `active` (optional) Appends "-active" to the end of the image name when when true - - `colorfill` (optional) Adds -webkit-mask-image and other styles, and the .colorfill CSS - class, so that setting a CSS background color will colorfill the image. - `style` (optional) An {Object} with additional styles to apply to the image. - `resourcePath` (options) Changes the default lookup location used to find the images. ### @propTypes: + mode: React.PropTypes.string.isRequired name: React.PropTypes.string + url: React.PropTypes.string + className: React.PropTypes.string style: React.PropTypes.object fallback: React.PropTypes.string selected: React.PropTypes.bool active: React.PropTypes.bool - colorfill: React.PropTypes.bool resourcePath: React.PropTypes.string render: -> - path = @_pathFor(@props.name) ? @_pathFor(@props.fallback) ? '' + path = @props.url ? @_pathFor(@props.name) ? @_pathFor(@props.fallback) ? '' pathIsRetina = path.indexOf('@2x') > 0 - className = undefined + className = @props.className ? '' style = @props.style ? {} style.WebkitUserDrag = 'none' style.zoom = if pathIsRetina then 0.5 else 1 - if @props.colorfill + if @props.mode is Mode.ContentIsMask style.WebkitMaskImage = "url('#{path}')" style.objectPosition = "10000px" - className = "colorfill" + className += " content-mask" + else if @props.mode is Mode.ContentDark + className += " content-dark" + else if @props.mode is Mode.ContentLight + className += " content-light" for key, val of style val = "#{val}" diff --git a/src/components/tokenizing-text-field.cjsx b/src/components/tokenizing-text-field.cjsx index aa9266192..ccbdd2856 100644 --- a/src/components/tokenizing-text-field.cjsx +++ b/src/components/tokenizing-text-field.cjsx @@ -35,7 +35,9 @@ Token = React.createClass
- + {@props.children}
diff --git a/src/sheet-toolbar.cjsx b/src/sheet-toolbar.cjsx index a70401948..f385f8450 100644 --- a/src/sheet-toolbar.cjsx +++ b/src/sheet-toolbar.cjsx @@ -21,7 +21,7 @@ class ToolbarBack extends React.Component @displayName: 'ToolbarBack' render: =>
- +
_onClick: => @@ -156,4 +156,4 @@ class Toolbar extends React.Component state -module.exports = Toolbar \ No newline at end of file +module.exports = Toolbar diff --git a/src/theme-manager.coffee b/src/theme-manager.coffee index 541485e23..14f5c0051 100644 --- a/src/theme-manager.coffee +++ b/src/theme-manager.coffee @@ -285,6 +285,7 @@ class ThemeManager reloadBaseStylesheets: -> @requireStylesheet('../static/index') + @requireStylesheet('../static/email-frame') if nativeStylesheetPath = fs.resolveOnLoadPath(process.platform, ['css', 'less']) @requireStylesheet(nativeStylesheetPath) diff --git a/static/buttons.less b/static/buttons.less index 5aae9bf58..e7f22bd88 100644 --- a/static/buttons.less +++ b/static/buttons.less @@ -46,10 +46,12 @@ button, html input[type="button"] { color: @btn-default-text-color; background: @btn-default-bg-color; + img.content-mask { background-color:@btn-default-text-color; } &.btn-action { color: @btn-action-text-color; background: @btn-action-bg-color; + img.content-mask { background-color:@btn-action-text-color; } } &.btn-emphasis { @@ -58,7 +60,7 @@ button, html input[type="button"] { color: @btn-emphasis-text-color; font-weight: @font-weight-medium; - img {-webkit-filter: brightness(100);} + img.content-mask { background-color:@btn-emphasis-text-color; } } &.btn-emphasis:active { @@ -69,6 +71,7 @@ button, html input[type="button"] { &.btn-danger, .btn-destructive { color: @btn-danger-text-color; background: @btn-danger-bg-color; + img.content-mask { background-color:@btn-danger-text-color; } } } @@ -88,6 +91,7 @@ button, html input[type="button"] { border: 0; box-shadow: none; color: @text-color-subtle; + img.content-mask { background-color:@text-color-subtle; } margin-right: 10px; outline: none !important; font-size: 20px; @@ -98,6 +102,7 @@ button, html input[type="button"] { &.inverse { color: @text-color-inverse; + img.content-mask { background-color:@text-color-inverse; } &:hover { color: white; @@ -105,16 +110,19 @@ button, html input[type="button"] { &:active { color: @text-color-inverse; + img.content-mask { background-color:@text-color-inverse; } } } &:hover { cursor: default; color: @text-color-link; + img.content-mask { background-color:@text-color-link; } box-shadow: none; } &:active { color: @text-color-link-active; + img.content-mask { background-color:@text-color-link-active; } box-shadow: none; } } diff --git a/static/components/list-tabular.less b/static/components/list-tabular.less index 17ee5d3a8..0e514b779 100644 --- a/static/components/list-tabular.less +++ b/static/components/list-tabular.less @@ -140,6 +140,11 @@ border-radius: 2px; } } + &.focused { + .checkmark .inner { + border:1px solid @accent-primary; + } + } .checkmark { padding: 12px; @@ -149,7 +154,7 @@ .inner { width:14px; height:14px; - border:1px solid @table-border-color; + border:1px solid @list-border; border-radius: 2px; background: transparent; background-size: 12px 9px; diff --git a/static/components/popover.less b/static/components/popover.less index d0690a655..8e777d2db 100644 --- a/static/components/popover.less +++ b/static/components/popover.less @@ -36,7 +36,7 @@ } .popover-pointer { - background: transparent url('images/tooltip/tooltip-bg-pointer@2x.png') no-repeat; - background-size: 22.5px 10.5px; + -webkit-mask-image: url('images/tooltip/tooltip-bg-pointer@2x.png'); + background-color: @background-color; } } diff --git a/static/components/tokenizing-text-field.less b/static/components/tokenizing-text-field.less index 1f602f2b0..41704949f 100644 --- a/static/components/tokenizing-text-field.less +++ b/static/components/tokenizing-text-field.less @@ -31,6 +31,7 @@ .token { display: inline-block; position: relative; + color: @text-color; padding: 0.4em @spacing-half 0.4em @spacing-half; padding-right: 1.5em; margin: 0 5px 5px 0; diff --git a/static/email-frame.less b/static/email-frame.less new file mode 100644 index 000000000..8c83b3d2a --- /dev/null +++ b/static/email-frame.less @@ -0,0 +1,80 @@ +@import 'variables/ui-variables'; +@import 'ui-variables'; + +.ignore-in-parent-frame { + + html, body { + font-family: "FaktPro", "Helvetica", "Lucidia Grande", sans-serif; + font-size: 16px; + line-height: 1.5; + + color: @text-color; + background-color: transparent !important; + border: 0; + margin: 0; + padding: 0; + + -webkit-text-size-adjust: auto; + word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; + } + + strong, b, .bold { + font-weight: 600; + } + + body { + padding: 0; + margin: auto; + max-width: 840px; + overflow: hidden; + -webkit-font-smoothing: antialiased; + } + + pre { + white-space: normal; + } + + a { + color: @text-color-link; + } + + a:hover { + color: @text-color-link-hover; + } + + a:visited { + color: darken(@text-color-link, 10%); + } + a img { + border-bottom: 0; + } + + body.heightDetermined { + overflow-y: hidden; + } + + div,pre { + max-width: 100%; + } + + img { + max-width: 100%; + height: auto; + border: 0; + } + + .gmail_extra, + .gmail_quote, + #divRplyFwdMsg, + blockquote { + display:none; + } + + .show-quoted-text .gmail_extra, + .show-quoted-text .gmail_quote, + .show-quoted-text #divRplyFwdMsg, + .show-quoted-text blockquote { + display:inherit; + } + +} diff --git a/static/inputs.less b/static/inputs.less index 6e4e8df32..74e41c1f2 100644 --- a/static/inputs.less +++ b/static/inputs.less @@ -20,6 +20,7 @@ input[type="url"] { font-size: @font-size-base; line-height: @line-height-computed; font-weight:400; + background: @input-bg; &.input-bordered { border-radius: @border-radius-base; diff --git a/static/variables/ui-variables.less b/static/variables/ui-variables.less index 29965a6e0..453db3edc 100644 --- a/static/variables/ui-variables.less +++ b/static/variables/ui-variables.less @@ -203,28 +203,6 @@ @standard-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.21); @standard-shadow-up: 0 -1px 4px 0 rgba(0, 0, 0, 0.21); - -//============================== Tables ===============================// -// Customizes the `.table` component with basic values, each used across -// all table variations. - -//** Padding for ``s and ``s. -@table-cell-padding: 8px; -//** Padding for cells in `.table-condensed`. -@table-condensed-cell-padding: 5px; - -//** Default background color used for all tables. -@table-bg: transparent; -//** Background color used for `.table-striped`. -@table-bg-accent: #f9f9f9; -//** Background color used for `.table-hover`. -@table-bg-hover: #f5f5f5; -@table-bg-active: @table-bg-hover; - -//** Border color for table and cell borders. -@table-border-color: #ddd; - - //=============================== Buttons ==============================// @btn-shadow: @standard-shadow; diff --git a/static/workspace.less b/static/workspace.less index 093f0dfe6..7fcc1f8ff 100644 --- a/static/workspace.less +++ b/static/workspace.less @@ -153,6 +153,7 @@ body.is-blurred { order:-999; padding-top: 5px; padding-left: @spacing-three-quarters; + img.content-mask { background-color: @text-color-heading; } flex-grow: 0; flex-shrink: 0; }