feat(mode-switch): New layout designed for small form factors
Summary: feat(mode-switch): almost working Remove SheetStore in favor of bigger WorkspaceStore Back button for mode switching Test Plan: Tests WIP Reviewers: evan Reviewed By: evan Differential Revision: https://review.inboxapp.com/D1292
|
@ -7,7 +7,6 @@
|
|||
overflow: auto;
|
||||
|
||||
background-color: @source-list-bg;
|
||||
box-shadow: inset -1px -2px 5px rgba(0, 0, 0, 0.22);
|
||||
-webkit-user-select: none;
|
||||
|
||||
.item {
|
||||
|
@ -27,6 +26,7 @@
|
|||
.item-tag {
|
||||
.unread {
|
||||
float: right;
|
||||
font-weight: @font-weight-medium;
|
||||
color: @source-list-active-bg;
|
||||
background: @source-list-bg;
|
||||
}
|
||||
|
|
|
@ -9,17 +9,33 @@ module.exports =
|
|||
activate: (@state={}) ->
|
||||
# Register Message List Actions we provide globally
|
||||
ComponentRegistry.register
|
||||
name: 'MessageToolbarItems'
|
||||
role: 'MessageList:Toolbar'
|
||||
name: 'MessageListSplit'
|
||||
role: 'Root:Right'
|
||||
mode: 'split'
|
||||
view: MessageList
|
||||
|
||||
ComponentRegistry.register
|
||||
name: 'MessageToolbarItemsSplit'
|
||||
role: 'Root:Right:Toolbar'
|
||||
mode: 'split'
|
||||
view: MessageToolbarItems
|
||||
|
||||
ComponentRegistry.register
|
||||
name: 'MessageList'
|
||||
role: 'Root:Right'
|
||||
role: 'Thread:Center'
|
||||
mode: 'list'
|
||||
view: MessageList
|
||||
|
||||
ComponentRegistry.register
|
||||
name: 'MessageToolbarItems'
|
||||
role: 'Thread:Center:Toolbar'
|
||||
mode: 'list'
|
||||
view: MessageToolbarItems
|
||||
|
||||
|
||||
deactivate: ->
|
||||
ComponentRegistry.unregister 'MessageToolbarItems'
|
||||
ComponentRegistry.unregister 'MessageListSplit'
|
||||
ComponentRegistry.unregister 'MessageList'
|
||||
|
||||
serialize: -> @state
|
||||
|
|
|
@ -62,7 +62,7 @@ ArchiveButton = React.createClass
|
|||
|
||||
module.exports = React.createClass
|
||||
getInitialState: ->
|
||||
threadIsSelected: false
|
||||
threadIsSelected: ThreadStore.selectedId()?
|
||||
|
||||
render: ->
|
||||
classes = React.addons.classSet
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
text-align: center;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
transition: opacity .25s ease-in-out;
|
||||
|
||||
.message-toolbar-items-inner {
|
||||
margin: auto;
|
||||
|
@ -22,7 +21,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// .message-toolbar-items also fades in and out when you select / deselect
|
||||
.message-toolbar-items.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
9
internal_packages/mode-switch/lib/main.coffee
Normal file
|
@ -0,0 +1,9 @@
|
|||
{ComponentRegistry} = require 'inbox-exports'
|
||||
ModeSwitch = require './mode-switch'
|
||||
|
||||
module.exports =
|
||||
activate: (state) ->
|
||||
ComponentRegistry.register
|
||||
name: 'ModeSwitch'
|
||||
view: ModeSwitch
|
||||
role: 'Root:Toolbar'
|
62
internal_packages/mode-switch/lib/mode-switch.cjsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
{ComponentRegistry,
|
||||
WorkspaceStore,
|
||||
Actions} = require "inbox-exports"
|
||||
{RetinaImg} = require 'ui-components'
|
||||
React = require "react"
|
||||
_ = require "underscore-plus"
|
||||
|
||||
module.exports =
|
||||
ModeSwitch = React.createClass
|
||||
displayName: 'ModeSwitch'
|
||||
|
||||
getInitialState: ->
|
||||
mode: WorkspaceStore.selectedLayoutMode()
|
||||
|
||||
componentDidMount: ->
|
||||
@unsubscribe = WorkspaceStore.listen(@_onStateChanged, @)
|
||||
|
||||
componentWillUnmount: ->
|
||||
@unsubscribe?()
|
||||
|
||||
render: ->
|
||||
knobX = if @state.mode is 'list' then 25 else 41
|
||||
|
||||
# Currently ModeSwitch is an opaque control that is not intended
|
||||
# to be styled, hence the fixed margins and positions. If we
|
||||
# turn this into a standard component one day, change!
|
||||
<div className="mode-switch"
|
||||
style={order:51, marginTop:14, marginRight:20}
|
||||
onClick={@_onToggleMode}>
|
||||
<RetinaImg
|
||||
data-mode={'list'}
|
||||
name="toolbar-icon-listmode.png"
|
||||
active={@state.mode is 'list'}
|
||||
onClick={@_onSetMode}
|
||||
style={paddingRight:12} />
|
||||
<RetinaImg
|
||||
name="modeslider-bg.png"/>
|
||||
<RetinaImg
|
||||
name="modeslider-knob.png"
|
||||
className="handle"
|
||||
style={top:4, left: knobX}/>
|
||||
<RetinaImg
|
||||
data-mode={'split'}
|
||||
name="toolbar-icon-splitpanes.png"
|
||||
active={@state.mode is 'split'}
|
||||
onClick={@_onSetMode}
|
||||
style={paddingLeft:12} />
|
||||
</div>
|
||||
|
||||
_onStateChanged: ->
|
||||
@setState
|
||||
mode: WorkspaceStore.selectedLayoutMode()
|
||||
|
||||
_onToggleMode: ->
|
||||
if @state.mode is 'list'
|
||||
Actions.selectLayoutMode('split')
|
||||
else
|
||||
Actions.selectLayoutMode('list')
|
||||
|
||||
_onSetMode: (event) ->
|
||||
Actions.selectLayoutMode(event.target.dataset.mode)
|
||||
event.stopPropagation()
|
8
internal_packages/mode-switch/package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "mode-switch",
|
||||
"version": "0.0.1",
|
||||
"description": "Mode switch",
|
||||
"main": "./lib/main",
|
||||
"license": "Proprietary",
|
||||
"private": true
|
||||
}
|
10
internal_packages/mode-switch/stylesheets/mode-switch.less
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
.mode-switch {
|
||||
z-index: 1000;
|
||||
position: relative;
|
||||
|
||||
.handle {
|
||||
position:absolute;
|
||||
transition: left .2s ease-out;
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
}
|
||||
|
||||
.participants {
|
||||
font-size: @font-size-large;
|
||||
font-size: @font-size-base;
|
||||
font-weight: @font-weight-semi-bold;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
@ -43,7 +43,6 @@
|
|||
height: 99%;
|
||||
width: 5px;
|
||||
top: 0;
|
||||
left: 1px;
|
||||
background: @unread-color;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,12 @@
|
|||
'a' : 'application:reply-all' # Gmail
|
||||
'f' : 'application:forward' # Gmail
|
||||
|
||||
# Default cross-platform core behaviors
|
||||
'escape': 'application:pop-sheet'
|
||||
|
||||
# Default cross-platform core behaviors
|
||||
'left': 'core:move-left'
|
||||
'right': 'core:move-right'
|
||||
'enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'shift-up': 'core:select-up'
|
||||
'shift-down': 'core:select-down'
|
||||
'shift-left': 'core:select-left'
|
||||
|
|
|
@ -582,6 +582,9 @@ class Atom extends Model
|
|||
'atom-workspace:logout': =>
|
||||
@logout() if @isLoggedIn()
|
||||
|
||||
# Make sure we can't be made so small that the interface looks like crap
|
||||
@getCurrentWindow().setMinimumSize(875, 500)
|
||||
|
||||
ipc.on 'onboarding-complete', =>
|
||||
maximize = dimensions?.maximized and process.platform isnt 'darwin'
|
||||
@displayWindow({maximize})
|
||||
|
|
|
@ -22,7 +22,10 @@ Mixin =
|
|||
|
||||
componentDidMount: ->
|
||||
@_componentUnlistener = ComponentRegistry.listen =>
|
||||
@setState(getViewsByName(@components))
|
||||
if @isMounted() is false
|
||||
console.log('WARNING: ComponentRegistry firing on unmounted component.')
|
||||
return
|
||||
@setState getViewsByName(@components)
|
||||
|
||||
componentWillUnmount: ->
|
||||
@_componentUnlistener()
|
||||
|
@ -33,7 +36,7 @@ class Component
|
|||
# Don't shit the bed if the user forgets `new`
|
||||
return new Component(attributes) unless @ instanceof Component
|
||||
|
||||
['name', 'model', 'view', 'role'].map (key) =>
|
||||
['name', 'model', 'view', 'role', 'mode'].map (key) =>
|
||||
@[key] = attributes[key] if attributes[key]
|
||||
|
||||
unless @name?
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
_ = require 'underscore-plus'
|
||||
React = require 'react'
|
||||
{Utils} = require "inbox-exports"
|
||||
|
||||
StylesImpactedByZoom = [
|
||||
'top',
|
||||
'left',
|
||||
'right',
|
||||
'bottom',
|
||||
'paddingTop',
|
||||
'paddingLeft',
|
||||
'paddingRight',
|
||||
'paddingBottom',
|
||||
'marginTop',
|
||||
'marginBottom',
|
||||
'marginLeft',
|
||||
'marginRight'
|
||||
]
|
||||
|
||||
module.exports =
|
||||
RetinaImg = React.createClass
|
||||
displayName: 'RetinaImg'
|
||||
propTypes:
|
||||
name: React.PropTypes.string
|
||||
style: React.PropTypes.object
|
||||
className: React.PropTypes.string
|
||||
|
||||
# Optional additional properties which adjust the provided
|
||||
# name. Makes it easy to write parent components when images
|
||||
|
@ -23,7 +38,13 @@ RetinaImg = React.createClass
|
|||
style = @props.style ? {}
|
||||
style.zoom = if pathIsRetina then 0.5 else 1
|
||||
|
||||
<img className={@props.className ? ''} src={path} style={style} />
|
||||
for key, val of style
|
||||
val = "#{val}"
|
||||
if key in StylesImpactedByZoom and val.indexOf('%') is -1
|
||||
style[key] = val.replace('px','') / style.zoom
|
||||
|
||||
otherProps = _.omit(@props, _.keys(@constructor.propTypes))
|
||||
<img src={path} style={style} {...otherProps} />
|
||||
|
||||
_pathFor: (name) ->
|
||||
[basename, ext] = name.split('.')
|
||||
|
|
|
@ -59,6 +59,7 @@ windowActions = [
|
|||
"selectThreadId",
|
||||
"selectTagId",
|
||||
"selectView",
|
||||
"selectLayoutMode",
|
||||
|
||||
# Actions for composer
|
||||
"composeReply",
|
||||
|
@ -102,7 +103,8 @@ windowActions = [
|
|||
"abortDownload",
|
||||
"fileDownloaded",
|
||||
|
||||
"popSheet"
|
||||
"popSheet",
|
||||
"pushSheet"
|
||||
]
|
||||
|
||||
allActions = [].concat(windowActions).concat(globalActions).concat(mainWindowActions)
|
||||
|
|
|
@ -5,10 +5,20 @@ Actions = require '../actions'
|
|||
WorkspaceStore = Reflux.createStore
|
||||
init: ->
|
||||
@_resetInstanceVars()
|
||||
|
||||
@listenTo Actions.selectView, @_onSelectView
|
||||
@listenTo Actions.selectLayoutMode, @_onSelectLayoutMode
|
||||
|
||||
@listenTo Actions.popSheet, @popSheet
|
||||
@listenTo Actions.searchQueryCommitted, @popToRootSheet
|
||||
@listenTo Actions.selectThreadId, @pushThreadSheet
|
||||
atom.commands.add 'body',
|
||||
'application:pop-sheet': => @popSheet()
|
||||
|
||||
_resetInstanceVars: ->
|
||||
@_sheetStack = ["Root"]
|
||||
@_view = 'threads'
|
||||
@_layoutMode = 'list'
|
||||
|
||||
# Inbound Events
|
||||
|
||||
|
@ -16,9 +26,43 @@ WorkspaceStore = Reflux.createStore
|
|||
@_view = view
|
||||
@trigger(@)
|
||||
|
||||
_onSelectLayoutMode: (mode) ->
|
||||
@_layoutMode = mode
|
||||
@trigger(@)
|
||||
|
||||
# Accessing Data
|
||||
|
||||
selectedView: ->
|
||||
@_view
|
||||
|
||||
selectedLayoutMode: ->
|
||||
@_layoutMode
|
||||
|
||||
sheet: ->
|
||||
@_sheetStack[@_sheetStack.length - 1]
|
||||
|
||||
sheetStack: ->
|
||||
@_sheetStack
|
||||
|
||||
# Managing Sheets
|
||||
|
||||
pushSheet: (type) ->
|
||||
@_sheetStack.push(type)
|
||||
@trigger()
|
||||
|
||||
pushThreadSheet: (threadId) ->
|
||||
if @selectedLayoutMode() is 'list' and threadId and @sheet() isnt "Thread"
|
||||
@pushSheet("Thread")
|
||||
|
||||
popSheet: ->
|
||||
if @_sheetStack.length > 1
|
||||
@_sheetStack.pop()
|
||||
@trigger()
|
||||
|
||||
popToRootSheet: ->
|
||||
if @_sheetStack.length > 1
|
||||
@_sheetStack = ["Root"]
|
||||
@trigger()
|
||||
|
||||
|
||||
module.exports = WorkspaceStore
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
React = require 'react'
|
||||
SheetStore = require './sheet-store'
|
||||
Sheet = require './sheet'
|
||||
{Actions,ComponentRegistry} = require "inbox-exports"
|
||||
Flexbox = require './components/flexbox.cjsx'
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
|
||||
{Actions,
|
||||
ComponentRegistry,
|
||||
WorkspaceStore} = require "inbox-exports"
|
||||
|
||||
ToolbarSpacer = React.createClass
|
||||
className: 'ToolbarSpacer'
|
||||
|
@ -21,15 +22,23 @@ Toolbar = React.createClass
|
|||
type: React.PropTypes.string
|
||||
|
||||
getInitialState: ->
|
||||
@_getComponentRegistryState()
|
||||
@_getStateFromStores()
|
||||
|
||||
componentDidMount: ->
|
||||
@unlistener = ComponentRegistry.listen (event) =>
|
||||
@setState(@_getComponentRegistryState())
|
||||
@unlisteners = []
|
||||
@unlisteners.push WorkspaceStore.listen (event) =>
|
||||
@setState(@_getStateFromStores())
|
||||
@unlisteners.push ComponentRegistry.listen (event) =>
|
||||
@setState(@_getStateFromStores())
|
||||
window.addEventListener "resize", (event) =>
|
||||
@recomputeLayout()
|
||||
|
||||
componentWillUnmount: ->
|
||||
@unlistener() if @unlistener
|
||||
|
||||
componentWillReceiveProps: (props) ->
|
||||
@setState(@_getStateFromStores(props))
|
||||
|
||||
componentDidUpdate: ->
|
||||
# Wait for other components that are dirty (the actual columns in the sheet)
|
||||
# to update as well.
|
||||
|
@ -43,34 +52,34 @@ Toolbar = React.createClass
|
|||
# Column toolbars contain items with roles attaching them to items
|
||||
# in the sheet. Ex: MessageList:Toolbar items appear in the column
|
||||
# toolbar for the column containing <MessageList/>.
|
||||
columnToolbars = @state.itemsForViews.map ({column, name, items}) =>
|
||||
<div style={position: 'absolute', top:0}
|
||||
columnToolbars = @state.itemsForColumns.map ({column, name, items}) =>
|
||||
<div style={position: 'absolute', top:0, display:'none'}
|
||||
data-owner-name={name}
|
||||
data-column={column}
|
||||
key={column}>
|
||||
{@_flexboxForItems(items)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ReactCSSTransitionGroup transitionName="sheet-toolbar">
|
||||
{mainToolbar}
|
||||
{columnToolbars}
|
||||
</div>
|
||||
</ReactCSSTransitionGroup>
|
||||
|
||||
_flexboxForItems: (items) ->
|
||||
components = items.map ({view, name}) =>
|
||||
<view key={name} {...@props} />
|
||||
|
||||
<Flexbox direction="row">
|
||||
<ReactCSSTransitionGroup component={Flexbox} direction="row" transitionName="sheet-toolbar">
|
||||
{components}
|
||||
<ToolbarSpacer key="spacer-50" order={-50}/>
|
||||
<ToolbarSpacer key="spacer+50" order={50} />
|
||||
</Flexbox>
|
||||
</ReactCSSTransitionGroup>
|
||||
|
||||
recomputeLayout: ->
|
||||
return unless @isMounted()
|
||||
|
||||
# Find our item containers that are tied to specific columns
|
||||
columnToolbarEls = this.getDOMNode().querySelectorAll('[data-column]')
|
||||
columnToolbarEls = @getDOMNode().querySelectorAll('[data-column]')
|
||||
|
||||
# Find the top sheet in the stack
|
||||
sheet = document.querySelector("[name='Sheet']:last-child")
|
||||
|
@ -81,22 +90,33 @@ Toolbar = React.createClass
|
|||
column = columnToolbarEl.dataset.column
|
||||
columnEl = sheet.querySelector("[data-column='#{column}']")
|
||||
continue unless columnEl
|
||||
|
||||
columnToolbarEl.style.display = 'inherit'
|
||||
columnToolbarEl.style.left = "#{columnEl.offsetLeft}px"
|
||||
columnToolbarEl.style.width = "#{columnEl.offsetWidth}px"
|
||||
|
||||
_getComponentRegistryState: ->
|
||||
items = []
|
||||
items.push(ComponentRegistry.findAllByRole("Global:Toolbar")...)
|
||||
items.push(ComponentRegistry.findAllByRole("#{@props.type}:Toolbar")...)
|
||||
_getStateFromStores: (props) ->
|
||||
props ?= @props
|
||||
state =
|
||||
mode: WorkspaceStore.selectedLayoutMode()
|
||||
items: []
|
||||
itemsForColumns: []
|
||||
|
||||
itemsForViews = []
|
||||
for column in ['Left', 'Right', 'Center']
|
||||
for {view, name} in ComponentRegistry.findAllByRole("#{@props.type}:#{column}")
|
||||
itemsForView = ComponentRegistry.findAllByRole("#{name}:Toolbar")
|
||||
if itemsForView.length > 0
|
||||
itemsForViews.push({column, name, items: itemsForView})
|
||||
for role in ["Global:Toolbar", "#{props.type}:Toolbar"]
|
||||
for entry in ComponentRegistry.findAllByRole(role)
|
||||
continue if entry.mode? and entry.mode != state.mode
|
||||
state.items.push(entry)
|
||||
|
||||
for column in ["Left", "Center", "Right"]
|
||||
role = "#{props.type}:#{column}:Toolbar"
|
||||
items = []
|
||||
for entry in ComponentRegistry.findAllByRole(role)
|
||||
continue if entry.mode? and entry.mode != state.mode
|
||||
items.push(entry)
|
||||
if items.length > 0
|
||||
state.itemsForColumns.push({column, name, items})
|
||||
|
||||
{items, itemsForViews}
|
||||
state
|
||||
|
||||
|
||||
FlexboxForRoles = React.createClass
|
||||
|
@ -128,6 +148,7 @@ FlexboxForRoles = React.createClass
|
|||
items = items.concat(ComponentRegistry.findAllByRole(role))
|
||||
{items}
|
||||
|
||||
|
||||
module.exports =
|
||||
SheetContainer = React.createClass
|
||||
className: 'SheetContainer'
|
||||
|
@ -136,7 +157,7 @@ SheetContainer = React.createClass
|
|||
@_getStateFromStores()
|
||||
|
||||
componentDidMount: ->
|
||||
@unsubscribe = SheetStore.listen @_onStoreChange
|
||||
@unsubscribe = WorkspaceStore.listen @_onStoreChange
|
||||
|
||||
# It's important that every React class explicitly stops listening to
|
||||
# atom events before it unmounts. Thank you event-kit
|
||||
|
@ -146,7 +167,6 @@ SheetContainer = React.createClass
|
|||
|
||||
render: ->
|
||||
topSheetType = @state.stack[@state.stack.length - 1]
|
||||
|
||||
<Flexbox direction="column">
|
||||
<div name="Toolbar" style={order:0} className="sheet-toolbar">
|
||||
<Toolbar ref="toolbar" type={topSheetType}/>
|
||||
|
@ -180,5 +200,5 @@ SheetContainer = React.createClass
|
|||
@setState @_getStateFromStores()
|
||||
|
||||
_getStateFromStores: ->
|
||||
stack: SheetStore.stack()
|
||||
stack: WorkspaceStore.sheetStack()
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
React = require "react"
|
||||
Reflux = require 'reflux'
|
||||
Actions = require './flux/actions'
|
||||
|
||||
SheetStore = Reflux.createStore
|
||||
init: ->
|
||||
@_stack = ["Root"]
|
||||
@listenTo Actions.popSheet, @popSheet
|
||||
|
||||
# Exposed Data
|
||||
|
||||
pushSheet: (type) ->
|
||||
@_stack.push(type)
|
||||
@trigger()
|
||||
|
||||
popSheet: ->
|
||||
@_stack.pop()
|
||||
@trigger()
|
||||
|
||||
topSheetType: ->
|
||||
@_stack[@_stack.length - 1]
|
||||
|
||||
stack: ->
|
||||
@_stack
|
||||
|
||||
module.exports = SheetStore
|
|
@ -1,6 +1,7 @@
|
|||
React = require 'react'
|
||||
_ = require 'underscore-plus'
|
||||
{Actions,ComponentRegistry} = require "inbox-exports"
|
||||
{Actions,ComponentRegistry, WorkspaceStore} = require "inbox-exports"
|
||||
RetinaImg = require './components/retina-img.cjsx'
|
||||
Flexbox = require './components/flexbox.cjsx'
|
||||
ResizableRegion = require './components/resizable-region.cjsx'
|
||||
|
||||
|
@ -18,14 +19,17 @@ Sheet = React.createClass
|
|||
columns: ['Left', 'Center', 'Right']
|
||||
|
||||
getInitialState: ->
|
||||
@_getComponentRegistryState()
|
||||
@_getStateFromStores()
|
||||
|
||||
componentDidMount: ->
|
||||
@unlistener = ComponentRegistry.listen (event) =>
|
||||
@setState(@_getComponentRegistryState())
|
||||
@unlisteners ?= []
|
||||
@unlisteners.push ComponentRegistry.listen (event) =>
|
||||
@setState(@_getStateFromStores())
|
||||
@unlisteners.push WorkspaceStore.listen (event) =>
|
||||
@setState(@_getStateFromStores())
|
||||
|
||||
componentWillUnmount: ->
|
||||
@unlistener() if @unlistener
|
||||
unlisten() for unlisten in @unlisteners
|
||||
|
||||
render: ->
|
||||
style =
|
||||
|
@ -33,6 +37,13 @@ Sheet = React.createClass
|
|||
backgroundColor:'white'
|
||||
width:'100%'
|
||||
height:'100%'
|
||||
zIndex: 1
|
||||
|
||||
# Note - setting the z-index of the sheet is important, even though it's
|
||||
# always 1. Assigning a z-index creates a "stacking context" in the browser,
|
||||
# so z-indexes inside the sheet are relative to each other, but something in
|
||||
# one sheet cannot be on top of something in another sheet.
|
||||
# http://philipwalton.com/articles/what-no-one-told-you-about-z-index/
|
||||
|
||||
<div name={"Sheet"}
|
||||
style={style}
|
||||
|
@ -45,8 +56,9 @@ Sheet = React.createClass
|
|||
|
||||
_backButtonComponent: ->
|
||||
return [] if @props.depth is 0
|
||||
<div onClick={@_pop} key="back">
|
||||
Back
|
||||
<div className="sheet-edge" onClick={@_pop} key="back">
|
||||
<div className="gradient"></div>
|
||||
<div className="x"><RetinaImg name="sheet-back.png"/></div>
|
||||
</div>
|
||||
|
||||
_columnFlexboxComponents: ->
|
||||
|
@ -83,10 +95,17 @@ Sheet = React.createClass
|
|||
{components}
|
||||
</Flexbox>
|
||||
|
||||
_getComponentRegistryState: ->
|
||||
_getStateFromStores: ->
|
||||
state = {}
|
||||
state.mode = WorkspaceStore.selectedLayoutMode()
|
||||
|
||||
for column in @props.columns
|
||||
state["#{column}"] = ComponentRegistry.findAllByRole("#{@props.type}:#{column}")
|
||||
views = []
|
||||
for entry in ComponentRegistry.findAllByRole("#{@props.type}:#{column}")
|
||||
continue if entry.mode? and entry.mode != state.mode
|
||||
views.push(entry)
|
||||
state["#{column}"] = views
|
||||
|
||||
state
|
||||
|
||||
_pop: ->
|
||||
|
|
BIN
static/images/sheets/sheet-back@2x.png
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
static/images/splitpane/modeslider-bg@1x.png
Normal file
After Width: | Height: | Size: 377 B |
BIN
static/images/splitpane/modeslider-bg@2x.png
Normal file
After Width: | Height: | Size: 693 B |
BIN
static/images/splitpane/modeslider-knob@1x.png
Normal file
After Width: | Height: | Size: 465 B |
BIN
static/images/splitpane/modeslider-knob@2x.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
static/images/splitpane/toolbar-icon-listmode-active@1x.png
Normal file
After Width: | Height: | Size: 279 B |
BIN
static/images/splitpane/toolbar-icon-listmode-active@2x.png
Normal file
After Width: | Height: | Size: 499 B |
BIN
static/images/splitpane/toolbar-icon-listmode@1x.png
Normal file
After Width: | Height: | Size: 356 B |
BIN
static/images/splitpane/toolbar-icon-listmode@2x.png
Normal file
After Width: | Height: | Size: 565 B |
BIN
static/images/splitpane/toolbar-icon-splitpanes-active@1x.png
Normal file
After Width: | Height: | Size: 353 B |
BIN
static/images/splitpane/toolbar-icon-splitpanes-active@2x.png
Normal file
After Width: | Height: | Size: 495 B |
BIN
static/images/splitpane/toolbar-icon-splitpanes@1x.png
Normal file
After Width: | Height: | Size: 279 B |
BIN
static/images/splitpane/toolbar-icon-splitpanes@2x.png
Normal file
After Width: | Height: | Size: 610 B |
|
@ -75,6 +75,48 @@ atom-workspace {
|
|||
}
|
||||
}
|
||||
|
||||
.sheet-toolbar-enter {
|
||||
opacity:0;
|
||||
transition: opacity .20s ease-out;
|
||||
}
|
||||
|
||||
.sheet-toolbar-enter.sheet-toolbar-enter-active {
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.sheet-toolbar-leave {
|
||||
opacity:1;
|
||||
transition: opacity .20s ease-in;
|
||||
}
|
||||
|
||||
.sheet-toolbar-leave.sheet-toolbar-leave-active {
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
.sheet-edge {
|
||||
height:100%;
|
||||
z-index: @zindex-popover;
|
||||
position: absolute;
|
||||
|
||||
.x {
|
||||
position: absolute;
|
||||
top: @spacing-standard * 1.5;
|
||||
left: @spacing-standard * 1.5;
|
||||
}
|
||||
.gradient {
|
||||
width:9px;
|
||||
height:100%;
|
||||
background-color: #f4f4f4;
|
||||
background-image: -webkit-gradient(linear, left center, right center, from(rgb(244, 244, 244)), to(rgb(209, 209, 209)));
|
||||
background-image: -webkit-linear-gradient(left, rgb(244, 244, 244), rgb(209, 209, 209));
|
||||
background-image: -moz-linear-gradient(left, rgb(244, 244, 244), rgb(209, 209, 209));
|
||||
background-image: -o-linear-gradient(left, rgb(244, 244, 244), rgb(209, 209, 209));
|
||||
background-image: -ms-linear-gradient(left, rgb(244, 244, 244), rgb(209, 209, 209));
|
||||
background-image: linear-gradient(left, rgb(244, 244, 244), rgb(209, 209, 209));
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,StartColorStr='#f4f4f4', EndColorStr='#d1d1d1');
|
||||
}
|
||||
}
|
||||
|
||||
.flexbox-handle-horizontal {
|
||||
width: 6px;
|
||||
top: 0;
|
||||
|
|