forked from nylas/nylas-mail
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsheet.cjsx
135 lines (114 loc) · 4.9 KB
/
sheet.cjsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
React = require 'react'
_ = require 'underscore'
{Actions,ComponentRegistry, WorkspaceStore} = require "nylas-exports"
RetinaImg = require './components/retina-img'
Flexbox = require './components/flexbox'
InjectedComponentSet = require './components/injected-component-set'
ResizableRegion = require './components/resizable-region'
FLEX = 10000
class Sheet extends React.Component
@displayName = 'Sheet'
@propTypes =
data: React.PropTypes.object.isRequired
depth: React.PropTypes.number.isRequired
onColumnSizeChanged: React.PropTypes.func
@childContextTypes:
sheetDepth: React.PropTypes.number
getChildContext: =>
sheetDepth: @props.depth
constructor: (@props) ->
@state = @_getStateFromStores()
componentDidMount: =>
@unlisteners ?= []
@unlisteners.push ComponentRegistry.listen (event) =>
@setState(@_getStateFromStores())
@unlisteners.push WorkspaceStore.listen (event) =>
@setState(@_getStateFromStores())
componentDidUpdate: =>
@props.onColumnSizeChanged(@) if @props.onColumnSizeChanged
minWidth = 0
minWidth += col.minWidth for col in @state.columns
atom.setMinimumWidth(minWidth)
shouldComponentUpdate: (nextProps, nextState) =>
not _.isEqual(nextProps, @props) or not _.isEqual(nextState, @state)
componentWillUnmount: =>
unlisten() for unlisten in @unlisteners
render: =>
style =
position:'absolute'
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}
className={"sheet mode-#{@state.mode}"}
data-id={@props.data.id}>
<Flexbox direction="row">
{@_columnFlexboxElements()}
</Flexbox>
</div>
_columnFlexboxElements: =>
@state.columns.map ({maxWidth, minWidth, handle, location}, idx) =>
if minWidth != maxWidth and maxWidth < FLEX
<ResizableRegion key={"#{@props.data.id}:#{idx}"}
name={"#{@props.data.id}:#{idx}"}
className={"column-#{location.id}"}
style={height:'100%'}
data-column={idx}
onResize={ => @props.onColumnSizeChanged(@) }
minWidth={minWidth}
maxWidth={maxWidth}
handle={handle}>
<InjectedComponentSet direction="column" matching={location: location, mode: @state.mode}/>
</ResizableRegion>
else
style =
height: '100%'
minWidth: minWidth
if maxWidth < FLEX
style.width = maxWidth
else
style.flex = 1
<InjectedComponentSet direction="column"
key={"#{@props.data.id}:#{idx}"}
name={"#{@props.data.id}:#{idx}"}
className={"column-#{location.id}"}
data-column={idx}
style={style}
matching={location: location, mode: @state.mode}/>
_getStateFromStores: =>
state =
mode: WorkspaceStore.layoutMode()
columns: []
widest = -1
widestWidth = -1
if @props.data?.columns[state.mode]?
for location, idx in @props.data.columns[state.mode]
continue if WorkspaceStore.isLocationHidden(location)
entries = ComponentRegistry.findComponentsMatching({location: location, mode: state.mode})
maxWidth = _.reduce entries, ((m,component) -> Math.min(component.containerStyles?.maxWidth ? 10000, m)), 10000
minWidth = _.reduce entries, ((m,component) -> Math.max(component.containerStyles?.minWidth ? 0, m)), 0
col = {maxWidth, minWidth, location}
state.columns.push(col)
if maxWidth > widestWidth
widestWidth = maxWidth
widest = idx
if state.columns.length > 0
# Once we've accumulated all the React components for the columns,
# ensure that at least one column has a huge max-width so that the columns
# expand to fill the window. This may make items in the column unhappy, but
# we pick the column with the highest max-width so the effect is minimal.
state.columns[widest].maxWidth = FLEX
# Assign flexible edges based on whether items are to the left or right
# of the flexible column (which has no edges)
state.columns[i].handle = ResizableRegion.Handle.Right for i in [0..widest-1] by 1
state.columns[i].handle = ResizableRegion.Handle.Left for i in [widest..state.columns.length-1] by 1
state
_pop: =>
Actions.popSheet()
module.exports = Sheet