- _rowHeight: ->
+ _rowHeight: =>
39
- _headers: ->
+ _headers: =>
return [] unless @props.displayHeaders
headerColumns = @props.columns.map (column) ->
@@ -178,7 +176,7 @@ ListTabular = React.createClass
{headerColumns}
- _rows: ->
+ _rows: =>
rowHeight = @_rowHeight()
rows = []
@@ -203,3 +201,5 @@ ListTabular = React.createClass
ListTabular.Item = ListTabularItem
ListTabular.Column = ListColumn
+
+module.exports = ListTabular
\ No newline at end of file
diff --git a/src/components/menu.cjsx b/src/components/menu.cjsx
index b8e52aca4..edd630abc 100644
--- a/src/components/menu.cjsx
+++ b/src/components/menu.cjsx
@@ -1,71 +1,29 @@
React = require 'react/addons'
+classNames = require 'classnames'
_ = require 'underscore-plus'
{Utils} = require 'inbox-exports'
{CompositeDisposable} = require 'event-kit'
###
-The Menu component allows you to display a list of items. Menu takes care of
-several important things, ensuring that your menu is consistent with the rest
-of the Edgehill application and offers a near-native experience:
-
-- Keyboard Interaction with the Up and Down arrow keys, Enter to select
-- Maintaining selection across content changes
-- Highlighted state
-
-Menus are often, but not always, used in conjunction with `Popover` to display
-a floating "popup" menu. See `template-picker.cjsx` for an example.
-
-Populating the Menu
--------------------
-
-When you render a Menu component, you need to provide three important props:
-
-`items`:
- An array of arbitrary objects the menu should display.
-
-`itemContent`:
- A function that returns a MenuItem, string, or React component for the given
- `item`.
-
- If you return a MenuItem, your item is injected into the list directly.
-
- If you return a string or React component, the result is placed within a
- MenuItem, resulting in the following DOM:
- `
{your content}
`.
-
- To create dividers and other special menu items, return an instance of:
-
-
-`itemKey`:
- A function that returns a unique string key for the given `item`. Keys are
- important for efficient React rendering when `items` is changed, and a
- key function is required.
-
-The Menu also exposes "header" and "footer" regions you can fill with arbitrary
-components by providing the `headerComponents` and `footerComponents` props.
-These items are nested within `.header-container`. and `.footer-container`,
-and you can customize their appearance by providing CSS selectors scoped to your
-component's Menu instance:
-
-```
-.template-picker .menu .header-container {
- height: 100px;
-}
-```
-
-Events
-------
-
-`onSelect`:
- Called with the selected item when the user clicks an item in the menu
- or confirms their selection with the Enter key.
-
+Public: `MenuItem` components can be provided to the {Menu} by the `itemContent` function.
+MenuItem's props allow you to display dividers as well as standard items.
###
+class MenuItem extends React.Component
+ @displayName = 'MenuItem'
+ ###
+ Public: React `props` supported by MenuItem:
+
+ - `divider` (optional) Pass a {String} to render the menu item as a section divider.
+ - `key` (optional)
+ - `selected` (optional)
+ ###
+ @propTypes:
+ divider: React.PropTypes.string
+ key: React.PropTypes.string
+ selected: React.PropTypes.bool
-MenuItem = React.createClass
- displayName: 'MenuItem'
- render: ->
+ render: =>
if @props.divider
+###
+Public: React component for a {Menu} item that displays a name and email address.
+###
+class MenuNameEmailItem extends React.Component
+ @displayName: 'MenuNameEmailItem'
-MenuNameEmailItem = React.createClass
- displayName: 'MenuNameEmailItem'
- propTypes:
+ ###
+ Public: React `props` supported by MenuNameEmailItem:
+
+ - `name` (optional) The {String} name to be displayed.
+ - `email` (optional) The {String} email address to be displayed.
+ ###
+ @propTypes:
name: React.PropTypes.string
email: React.PropTypes.string
- render: ->
+ render: =>
if @props.name?.length > 0 and @props.name isnt @props.email
{@props.name}
@@ -89,26 +56,88 @@ MenuNameEmailItem = React.createClass
else
{@props.email}
+###
+Public: React component for multi-section Menus with key binding
-Menu = React.createClass
+The Menu component allows you to display a list of items. Menu takes care of
+several important things, ensuring that your menu is consistent with the rest
+of the Edgehill application and offers a near-native experience:
- propTypes:
+- Keyboard Interaction with the Up and Down arrow keys, Enter to select
+- Maintaining selection across content changes
+- Highlighted state
+
+Menus are often, but not always, used in conjunction with {Popover} to display
+a floating "popup" menu. See `template-picker.cjsx` for an example.
+
+The Menu also exposes "header" and "footer" regions you can fill with arbitrary
+components by providing the `headerComponents` and `footerComponents` props.
+These items are nested within `.header-container`. and `.footer-container`,
+and you can customize their appearance by providing CSS selectors scoped to your
+component's Menu instance:
+
+```css
+.template-picker .menu .header-container {
+ height: 100px;
+}
+```
+###
+
+class Menu extends React.Component
+ @displayName: 'Menu'
+
+ ###
+ Public: React `props` supported by Menu:
+
+ - `className` (optional) The {String} class name applied to the Menu
+
+ - `itemContent` A {Function} that returns a {MenuItem}, {String}, or
+ React component for the given `item`.
+
+ If you return a {MenuItem}, your item is injected into the list directly.
+
+ If you return a string or React component, the result is placed within a
+ {MenuItem}, resulting in the following DOM:
+ `
{your content}
`.
+
+ To create dividers and other special menu items, return an instance of:
+
+
+ - `itemKey` A {Function} that returns a unique string key for the given `item`.
+ Keys are important for efficient React rendering when `items` is changed, and a
+ key function is required.
+
+ - `items` An {Array} of arbitrary objects the menu should display.
+
+ - `onSelect` A {Function} called with the selected item when the user clicks
+ an item in the menu or confirms their selection with the Enter key.
+
+ ###
+ @propTypes:
className: React.PropTypes.string,
footerComponents: React.PropTypes.arrayOf(React.PropTypes.element),
headerComponents: React.PropTypes.arrayOf(React.PropTypes.element),
itemContent: React.PropTypes.func.isRequired,
itemKey: React.PropTypes.func.isRequired,
+
items: React.PropTypes.array.isRequired
onSelect: React.PropTypes.func.isRequired,
- getInitialState: ->
- selectedIndex: -1
+ constructor: (@props) ->
+ @state =
+ selectedIndex: -1
- getSelectedItem: ->
+ # Public: Takes an argument and does some stuff.
+ #
+ # a - A {String}
+ #
+ # Returns {Boolean}.
+ #
+ getSelectedItem: =>
@props.items[@state.selectedIndex]
- componentDidMount: ->
+ componentDidMount: =>
@subscriptions = new CompositeDisposable()
@subscriptions.add atom.commands.add '.menu', {
'menu:move-up': => @_onShiftSelectedIndex(-1)
@@ -116,7 +145,7 @@ Menu = React.createClass
'menu:enter': => @_onEnter()
}
- componentWillReceiveProps: (newProps) ->
+ componentWillReceiveProps: (newProps) =>
# Attempt to preserve selection across props.items changes by
# finding an item in the new list with a key matching the old
# selected item's key
@@ -131,15 +160,15 @@ Menu = React.createClass
@setState
selectedIndex: newSelectionIndex
- componentDidUpdate: ->
- item = @getDOMNode().querySelector(".selected")
- container = @getDOMNode().querySelector(".content-container")
+ componentDidUpdate: =>
+ item = React.findDOMNode(@).querySelector(".selected")
+ container = React.findDOMNode(@).querySelector(".content-container")
Utils.scrollNodeToVisibleInContainer(item, container)
- componentWillUnmount: ->
+ componentWillUnmount: =>
@subscriptions?.dispose()
- render: ->
+ render: =>
hc = @props.headerComponents ? []
if hc.length is 0 then hc =
fc = @props.footerComponents ? []
@@ -154,9 +183,9 @@ Menu = React.createClass
- _contentContainer: ->
+ _contentContainer: =>
items = @props.items.map(@_itemComponentForItem) ? []
- contentClass = React.addons.classSet
+ contentClass = classNames
'content-container': true
'empty': items.length is 0
@@ -164,9 +193,9 @@ Menu = React.createClass
{items}
- _itemComponentForItem: (item, i) ->
+ _itemComponentForItem: (item, i) =>
content = @props.itemContent(item)
- return content if content.type is MenuItem.type
+ return content if content instanceof MenuItem
onMouseDown = (event) =>
event.preventDefault()
@@ -177,7 +206,7 @@ Menu = React.createClass
content={content}
selected={@state.selectedIndex is i} />
- _onShiftSelectedIndex: (delta) ->
+ _onShiftSelectedIndex: (delta) =>
return if @props.items.length is 0
index = @state.selectedIndex + delta
index = Math.max(0, Math.min(@props.items.length-1, index))
@@ -192,7 +221,7 @@ Menu = React.createClass
isDivider = itemContent.props?.divider
@_onShiftSelectedIndex(delta) if isDivider
- _onEnter: ->
+ _onEnter: =>
item = @props.items[@state.selectedIndex]
@props.onSelect(item) if item?
@@ -200,4 +229,4 @@ Menu = React.createClass
Menu.Item = MenuItem
Menu.NameEmailItem = MenuNameEmailItem
-module.exports = Menu
+module.exports = Menu
\ No newline at end of file
diff --git a/src/components/multiselect-action-bar.cjsx b/src/components/multiselect-action-bar.cjsx
index b00a14692..7220efd24 100644
--- a/src/components/multiselect-action-bar.cjsx
+++ b/src/components/multiselect-action-bar.cjsx
@@ -1,10 +1,11 @@
React = require "react/addons"
+classNames = require 'classnames'
_ = require 'underscore-plus'
{Actions,
AddRemoveTagsTask,
WorkspaceStore} = require "inbox-exports"
-RegisteredRegion = require './registered-region'
+InjectedComponentSet = require './injected-component-set'
RetinaImg = require './retina-img'
module.exports =
@@ -61,7 +62,7 @@ MultiselectActionBar = React.createClass
_renderActions: ->
return unless @state.view
-
_label: ->
@@ -73,7 +74,7 @@ MultiselectActionBar = React.createClass
""
_classSet: ->
- React.addons.classSet
+ classNames
"selection-bar": true
"enabled": @state.count > 0
diff --git a/src/components/multiselect-list.cjsx b/src/components/multiselect-list.cjsx
index 9654ff58e..74a20074b 100644
--- a/src/components/multiselect-list.cjsx
+++ b/src/components/multiselect-list.cjsx
@@ -1,5 +1,6 @@
_ = require 'underscore-plus'
React = require 'react'
+classNames = require 'classnames'
ListTabular = require './list-tabular'
Spinner = require './spinner'
{Actions,
@@ -9,11 +10,10 @@ Spinner = require './spinner'
NamespaceStore} = require 'inbox-exports'
EventEmitter = require('events').EventEmitter
-module.exports =
-MultiselectList = React.createClass
- displayName: 'MultiselectList'
+class MultiselectList extends React.Component
+ @displayName = 'MultiselectList'
- propTypes:
+ @propTypes =
className: React.PropTypes.string.isRequired
collection: React.PropTypes.string.isRequired
commands: React.PropTypes.object.isRequired
@@ -21,36 +21,36 @@ MultiselectList = React.createClass
dataStore: React.PropTypes.object.isRequired
itemPropsProvider: React.PropTypes.func.isRequired
- getInitialState: ->
- @_getStateFromStores()
+ constructor: (@props) ->
+ @state = @_getStateFromStores()
- componentDidMount: ->
+ componentDidMount: =>
@setupForProps(@props)
- componentWillReceiveProps: (newProps) ->
+ componentWillReceiveProps: (newProps) =>
return if _.isEqual(@props, newProps)
@teardownForProps()
@setupForProps(newProps)
@setState(@_getStateFromStores(newProps))
- componentDidUpdate: (prevProps, prevState) ->
+ componentDidUpdate: (prevProps, prevState) =>
if prevState.focusedId isnt @state.focusedId or
prevState.keyboardCursorId isnt @state.keyboardCursorId
- item = @getDOMNode().querySelector(".focused")
- item ?= @getDOMNode().querySelector(".keyboard-cursor")
- list = @refs.list.getDOMNode()
+ item = React.findDOMNode(@).querySelector(".focused")
+ item ?= React.findDOMNode(@).querySelector(".keyboard-cursor")
+ list = React.findDOMNode(@refs.list)
Utils.scrollNodeToVisibleInContainer(item, list)
- componentWillUnmount: ->
+ componentWillUnmount: =>
@teardownForProps()
- teardownForProps: ->
+ teardownForProps: =>
return unless @unsubscribers
unsubscribe() for unsubscribe in @unsubscribers
@command_unsubscriber.dispose()
- setupForProps: (props) ->
+ setupForProps: (props) =>
commands = _.extend {},
'core:focus-item': => @_onEnter()
'core:select-item': => @_onSelect()
@@ -66,8 +66,8 @@ MultiselectList = React.createClass
checkmarkColumn = new ListTabular.Column
name: ""
- resolver: (thread) ->
- toggle = (event) ->
+ resolver: (thread) =>
+ toggle = (event) =>
props.dataStore.view().selection.toggle(thread)
event.stopPropagation()
@@ -79,7 +79,7 @@ MultiselectList = React.createClass
@unsubscribers.push FocusedContentStore.listen @_onChange
@command_unsubscriber = atom.commands.add('body', commands)
- render: ->
+ render: =>
# IMPORTANT: DO NOT pass inline functions as props. _.isEqual thinks these
# are "different", and will re-render everything. Instead, declare them with ?=,
# pass a reference. (Alternatively, ignore these in children's shouldComponentUpdate.)
@@ -93,7 +93,7 @@ MultiselectList = React.createClass
@itemPropsProvider ?= (item) =>
props = @props.itemPropsProvider(item)
props.className ?= ''
- props.className += " " + React.addons.classSet
+ props.className += " " + classNames
'selected': item.id in @state.selectedIds
'focused': @state.showFocus and item.id is @state.focusedId
'keyboard-cursor': @state.showKeyboardCursor and item.id is @state.keyboardCursorId
@@ -115,7 +115,7 @@ MultiselectList = React.createClass
- _onClickItem: (item, event) ->
+ _onClickItem: (item, event) =>
if event.metaKey
@state.dataView.selection.toggle(item)
if @state.showKeyboardCursor
@@ -127,13 +127,13 @@ MultiselectList = React.createClass
else
Actions.focusInCollection({collection: @props.collection, item: item})
- _onEnter: ->
+ _onEnter: =>
return unless @state.showKeyboardCursor
item = @state.dataView.getById(@state.keyboardCursorId)
if item
Actions.focusInCollection({collection: @props.collection, item: item})
- _onSelect: ->
+ _onSelect: =>
if @state.showKeyboardCursor and @_visible()
id = @state.keyboardCursorId
else
@@ -142,7 +142,7 @@ MultiselectList = React.createClass
return unless id
@state.dataView.selection.toggle(@state.dataView.getById(id))
- _onShift: (delta, options = {}) ->
+ _onShift: (delta, options = {}) =>
if @state.showKeyboardCursor and @_visible()
id = @state.keyboardCursorId
action = Actions.focusKeyboardInCollection
@@ -160,7 +160,7 @@ MultiselectList = React.createClass
if options.select
@state.dataView.selection.walk({current, next})
- _visible: ->
+ _visible: =>
if WorkspaceStore.layoutMode() is "list"
WorkspaceStore.topSheet().root
else
@@ -170,12 +170,11 @@ MultiselectList = React.createClass
# Since they're on the same event listner, and the event listeners are
# unordered, we need a way to push thread list updates later back in the
# queue.
- _onChange: -> _.delay =>
- return unless @isMounted()
+ _onChange: => _.delay =>
@setState(@_getStateFromStores())
, 1
- _getStateFromStores: (props) ->
+ _getStateFromStores: (props) =>
props ?= @props
view = props.dataStore?.view()
@@ -188,3 +187,6 @@ MultiselectList = React.createClass
keyboardCursorId: FocusedContentStore.keyboardCursorId(props.collection)
showFocus: !FocusedContentStore.keyboardCursorEnabled()
showKeyboardCursor: FocusedContentStore.keyboardCursorEnabled()
+
+
+module.exports = MultiselectList
\ No newline at end of file
diff --git a/src/components/popover.cjsx b/src/components/popover.cjsx
index 3bd8988a3..b199dbb4b 100644
--- a/src/components/popover.cjsx
+++ b/src/components/popover.cjsx
@@ -3,8 +3,8 @@ _ = require 'underscore-plus'
{CompositeDisposable} = require 'event-kit'
###
-The Popover component makes it easy to display a sheet or popup menu when the user
-clicks the React element provided as `buttonComponent`. In Edgehill, the Popover
+Public: The Popover component makes it easy to display a sheet or popup menu when the
+user clicks the React element provided as `buttonComponent`. In Edgehill, the Popover
component is used to create rich dropdown menus, detail popups, etc. with consistent
look and feel and behavior.
@@ -24,54 +24,54 @@ The Popover component handles:
- Automatically focusing the item with the lowest tabIndex inside the popover
-Input Focus
------------
+## Input Focus
+
If your Popover contains an input, like a search bar, give it a tabIndex and
Popover will automatically focus it when the popover is opened.
-Advanced Use
-------------
+## Advanced Use
+
If you don't want to use the Popover in conjunction with a triggering button,
you can manually call `open()` and `close()` to display it. A typical scenario
looks like this:
-```
-render: ->
+```coffeescript
+render: =>
Popover Contents
-showMyPopover: ->
+showMyPopover: =>
@refs.myPopover.open()
```
-
###
-module.exports =
-Popover = React.createClass
- propTypes:
- buttonComponent: React.PropTypes.element,
+class Popover extends React.Component
- getInitialState: ->
- showing: false
+ @propTypes =
+ buttonComponent: React.PropTypes.element
- componentDidMount: ->
+ constructor: (@props) ->
+ @state =
+ showing: false
+
+ componentDidMount: =>
@subscriptions = new CompositeDisposable()
@subscriptions.add atom.commands.add '.popover-container', {
'popover:close': => @close()
}
- componentWillUnmount: ->
+ componentWillUnmount: =>
@subscriptions?.dispose()
- open: ->
+ open: =>
@setState
showing: true
- close: ->
+ close: =>
@setState
showing: false
- render: ->
+ render: =>
wrappedButtonComponent = []
if @props.buttonComponent
wrappedButtonComponent =
{@props.buttonComponent}
@@ -88,21 +88,22 @@ Popover = React.createClass
{popoverComponent}
- _onClick: ->
+ _onClick: =>
showing = !@state.showing
@setState({showing})
if showing
setTimeout =>
# Automatically focus the element inside us with the lowest tab index
- node = @refs.popover.getDOMNode()
+ node = @refs.popover.findDOMNode()
matches = _.sortBy node.querySelectorAll("[tabIndex]"), (a,b) -> a.tabIndex < b.tabIndex
matches[0].focus() if matches[0]
- _onBlur: (event) ->
+ _onBlur: (event) =>
target = event.nativeEvent.relatedTarget
- if target? and @refs.container.getDOMNode().contains(target)
+ if target? and @refs.container.findDOMNode().contains(target)
return
@setState
showing:false
+module.exports = Popover
\ No newline at end of file
diff --git a/src/components/resizable-region.cjsx b/src/components/resizable-region.cjsx
index f296b98e2..4c723073a 100644
--- a/src/components/resizable-region.cjsx
+++ b/src/components/resizable-region.cjsx
@@ -27,11 +27,10 @@ ResizableHandle =
'width': Math.min(props.maxWidth ? 10000, Math.max(props.minWidth ? 0, event.pageX - state.bcr.left))
-module.exports =
-ResizableRegion = React.createClass
- displayName: 'ResizableRegion'
+class ResizableRegion extends React.Component
+ @displayName = 'ResizableRegion'
- propTypes:
+ @propTypes =
handle: React.PropTypes.object.isRequired
onResize: React.PropTypes.func
@@ -43,13 +42,12 @@ ResizableRegion = React.createClass
minHeight: React.PropTypes.number
maxHeight: React.PropTypes.number
- getDefaultProps: ->
- handle: ResizableHandle.Right
+ constructor: (@props = {}) ->
+ @props.handle ?= ResizableHandle.Right
+ @state =
+ dragging: false
- getInitialState: ->
- dragging: false
-
- render: ->
+ render: =>
if @props.handle.axis is 'horizontal'
containerStyle =
'minWidth': @props.minWidth
@@ -85,7 +83,7 @@ ResizableRegion = React.createClass
- componentDidUpdate: (lastProps, lastState) ->
+ componentDidUpdate: (lastProps, lastState) =>
if lastState.dragging and not @state.dragging
document.removeEventListener('mousemove', @_mouseMove)
document.removeEventListener('mouseup', @_mouseUp)
@@ -93,19 +91,19 @@ ResizableRegion = React.createClass
document.addEventListener('mousemove', @_mouseMove)
document.addEventListener('mouseup', @_mouseUp)
- componentWillReceiveProps: (nextProps) ->
+ componentWillReceiveProps: (nextProps) =>
if nextProps.handle.axis is 'vertical' and nextProps.initialHeight != @props.initialHeight
@setState(height: nextProps.initialHeight)
if nextProps.handle.axis is 'horizontal' and nextProps.initialWidth != @props.initialWidth
@setState(width: nextProps.initialWidth)
- componentWillUnmount: ->
+ componentWillUnmount: =>
PriorityUICoordinator.endPriorityTask(@_taskId) if @_taskId
@_taskId = null
- _mouseDown: (event) ->
+ _mouseDown: (event) =>
return if event.button != 0
- bcr = @getDOMNode().getBoundingClientRect()
+ bcr = React.findDOMNode(@).getBoundingClientRect()
@setState
dragging: true
bcr: bcr
@@ -115,7 +113,7 @@ ResizableRegion = React.createClass
PriorityUICoordinator.endPriorityTask(@_taskId) if @_taskId
@_taskId = PriorityUICoordinator.beginPriorityTask()
- _mouseUp: (event) ->
+ _mouseUp: (event) =>
return if event.button != 0
@setState
dragging: false
@@ -126,7 +124,7 @@ ResizableRegion = React.createClass
PriorityUICoordinator.endPriorityTask(@_taskId)
@_taskId = null
- _mouseMove: (event) ->
+ _mouseMove: (event) =>
return if !@state.dragging
@setState @props.handle.transform(@state, @props, event)
@props.onResize(@state.height ? @state.width) if @props.onResize
@@ -134,3 +132,5 @@ ResizableRegion = React.createClass
event.preventDefault()
ResizableRegion.Handle = ResizableHandle
+
+module.exports = ResizableRegion
\ No newline at end of file
diff --git a/src/components/spinner.cjsx b/src/components/spinner.cjsx
index 3839b2ab9..bdabae9ea 100644
--- a/src/components/spinner.cjsx
+++ b/src/components/spinner.cjsx
@@ -1,17 +1,18 @@
React = require 'react'
_ = require 'underscore-plus'
+classNames = require 'classnames'
-module.exports =
-Spinner = React.createClass
- propTypes:
+class Spinner extends React.Component
+ @propTypes =
visible: React.PropTypes.bool
style: React.PropTypes.object
- getInitialState: ->
- hidden: true
- paused: true
+ constructor: (@props) ->
+ @state =
+ hidden: true
+ paused: true
- componentDidMount: ->
+ componentDidMount: =>
# The spinner always starts hidden. After it's mounted, it unhides itself
# if it's set to visible. This is a bit strange, but ensures that the CSS
# transition from .spinner.hidden => .spinner always happens, along with
@@ -19,7 +20,7 @@ Spinner = React.createClass
if @props.visible and @state.hidden
@showAfterDelay()
- componentWillReceiveProps: (nextProps) ->
+ componentWillReceiveProps: (nextProps) =>
hidden = if nextProps.visible? then !nextProps.visible else false
if @state.hidden is false and hidden is true
@@ -28,21 +29,19 @@ Spinner = React.createClass
else if @state.hidden is true and hidden is false
@showAfterDelay()
- pauseAfterDelay: ->
+ pauseAfterDelay: =>
_.delay =>
- return unless @isMounted()
return if @props.visible
@setState({paused: true})
,250
- showAfterDelay: ->
+ showAfterDelay: =>
_.delay =>
- return unless @isMounted()
return if @props.visible isnt true
@setState({paused: false, hidden: false})
, 300
- render: ->
+ render: =>
if @props.withCover
@_renderDotsWithCover()
else
@@ -51,7 +50,7 @@ Spinner = React.createClass
# This displays an extra div that's a partially transparent white cover.
# If you don't want to make your own background for the loading state,
# this is a convenient default.
- _renderDotsWithCover: ->
+ _renderDotsWithCover: =>
coverClasses = React.addons.classSet
"spinner-cover": true
"hidden": @state.hidden
@@ -70,8 +69,8 @@ Spinner = React.createClass
{@_renderSpinnerDots()}
- _renderSpinnerDots: ->
- spinnerClass = React.addons.classSet
+ _renderSpinnerDots: =>
+ spinnerClass = classNames
'spinner': true
'hidden': @state.hidden
'paused': @state.paused
@@ -81,7 +80,7 @@ Spinner = React.createClass
'left': '50%'
'top': '50%'
'zIndex': @props.zIndex+1 ? 1001
- 'transform':'translate(-50%,-50%);'
+ 'transform':'translate(-50%,-50%)'
otherProps = _.omit(@props, _.keys(@constructor.propTypes))
@@ -90,3 +89,5 @@ Spinner = React.createClass
+
+module.exports = Spinner
diff --git a/src/components/timeout-transition-group.cjsx b/src/components/timeout-transition-group.cjsx
index dd86e11b0..a6c5671e3 100644
--- a/src/components/timeout-transition-group.cjsx
+++ b/src/components/timeout-transition-group.cjsx
@@ -29,21 +29,21 @@ TICK = 17
endEvents = ['webkitTransitionEnd', 'webkitAnimationEnd']
-animationSupported = -> true
+animationSupported = => true
###*
# Functions for element class management to replace dependency on jQuery
# addClass, removeClass and hasClass
###
-addClass = (element, className) ->
+addClass = (element, className) =>
if element.classList
element.classList.add className
else if !hasClass(element, className)
element.className = element.className + ' ' + className
element
-removeClass = (element, className) ->
+removeClass = (element, className) =>
if hasClass(className)
if element.classList
element.classList.remove className
@@ -51,15 +51,17 @@ removeClass = (element, className) ->
element.className = (' ' + element.className + ' ').replace(' ' + className + ' ', ' ').trim()
element
-hasClass = (element, className) ->
+hasClass = (element, className) =>
if element.classList
element.classList.contains className
else
(' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1
-TimeoutTransitionGroupChild = React.createClass(
- transition: (animationType, finishCallback) ->
- node = @getDOMNode()
+
+class TimeoutTransitionGroupChild extends React.Component
+
+ transition: (animationType, finishCallback) =>
+ node = React.findDOMNode(@)
className = @props.name + '-' + animationType
activeClassName = className + '-active'
@@ -104,29 +106,28 @@ TimeoutTransitionGroupChild = React.createClass(
@queueClass activeClassName
return
- queueClass: (className) ->
+ queueClass: (className) =>
@classNameQueue.push className
if !@timeout
@timeout = setTimeout(@flushClassNameQueue, TICK)
return
- flushClassNameQueue: ->
- if @isMounted()
- @classNameQueue.forEach ((name) ->
- addClass(@getDOMNode(), name)
- return
- ).bind(this)
+ flushClassNameQueue: =>
+ @classNameQueue.forEach ((name) =>
+ addClass(React.findDOMNode(@), name)
+ return
+ ).bind(this)
@classNameQueue.length = 0
@timeout = null
return
- componentWillMount: ->
+ componentWillMount: =>
@classNameQueue = []
@animationTimeout = null
@animationTaskId = null
return
- componentWillUnmount: ->
+ componentWillUnmount: =>
if @timeout
clearTimeout(@timeout)
if @animationTimeout
@@ -137,37 +138,36 @@ TimeoutTransitionGroupChild = React.createClass(
@animationTaskId = null
return
- componentWillEnter: (done) ->
+ componentWillEnter: (done) =>
if @props.enter
@transition 'enter', done
else
done()
return
- componentWillLeave: (done) ->
+ componentWillLeave: (done) =>
if @props.leave
@transition 'leave', done
else
done()
return
- render: ->
+ render: =>
React.Children.only @props.children
-)
-TimeoutTransitionGroup = React.createClass(
- propTypes:
+class TimeoutTransitionGroup extends React.Component
+ @propTypes =
enterTimeout: React.PropTypes.number.isRequired
leaveTimeout: React.PropTypes.number.isRequired
transitionName: React.PropTypes.string.isRequired
transitionEnter: React.PropTypes.bool
transitionLeave: React.PropTypes.bool
- getDefaultProps: ->
+ @defaultProps =
transitionEnter: true
transitionLeave: true
- _wrapChild: (child) ->
+ _wrapChild: (child) =>
- render: ->
+ render: =>
-)
-module.exports = TimeoutTransitionGroup
-# ---
-# generated by js2coffee 2.0.1
\ No newline at end of file
+module.exports = TimeoutTransitionGroup
\ No newline at end of file
diff --git a/src/components/tokenizing-text-field.cjsx b/src/components/tokenizing-text-field.cjsx
index 6703bbefb..39d6874e0 100644
--- a/src/components/tokenizing-text-field.cjsx
+++ b/src/components/tokenizing-text-field.cjsx
@@ -1,4 +1,5 @@
React = require 'react/addons'
+classNames = require 'classnames'
_ = require 'underscore-plus'
{CompositeDisposable} = require 'event-kit'
{Contact, ContactStore} = require 'inbox-exports'
@@ -25,7 +26,7 @@ Token = React.createClass
})
render: ->
- classes = React.addons.classSet
+ classes = classNames
"token": true
"dragging": @getDragState('token').isDragging
"selected": @props.selected
@@ -196,7 +197,7 @@ TokenizingTextField = React.createClass
render: ->
{Menu} = require 'ui-components'
- classes = React.addons.classSet _.extend (@props.menuClassSet ? {}),
+ classes = classNames _.extend (@props.menuClassSet ? {}),
"tokenizing-field": true
"focused": @state.focus
"native-key-bindings": true
diff --git a/src/custom-event-mixin.coffee b/src/custom-event-mixin.coffee
deleted file mode 100644
index 1a3bb4d88..000000000
--- a/src/custom-event-mixin.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports =
-CustomEventMixin =
- componentWillMount: ->
- @customEventListeners = {}
-
- componentWillUnmount: ->
- for name, listeners in @customEventListeners
- for listener in listeners
- @getDOMNode().removeEventListener(name, listener)
-
- addCustomEventListeners: (customEventListeners) ->
- for name, listener of customEventListeners
- @customEventListeners[name] ?= []
- @customEventListeners[name].push(listener)
- @getDOMNode().addEventListener(name, listener)
diff --git a/src/flux/action-bridge.coffee b/src/flux/action-bridge.coffee
index 463a2cd4a..864cacbff 100644
--- a/src/flux/action-bridge.coffee
+++ b/src/flux/action-bridge.coffee
@@ -14,7 +14,8 @@ TargetWindows =
Message =
DATABASE_STORE_TRIGGER: 'db-store-trigger'
-###
+# Public: ActionBridge
+#
# The ActionBridge has two responsibilities:
# 1. When you're in a secondary window, the ActionBridge observes all Root actions. When a
# Root action is fired, it converts it's payload to JSON, tunnels it to the main window
@@ -26,7 +27,7 @@ Message =
# into all of the windows of the application. This is important, because the DatabaseStore
# in all secondary windows is a read-replica. Only the DatabaseStore in the main window
# of the application consumes persistModel actions and writes changes to the database.
-###
+
class ActionBridge
@Role: Role
@Message: Message
diff --git a/src/flux/models/file.coffee b/src/flux/models/file.coffee
index bf357b2fd..e901ba1d6 100644
--- a/src/flux/models/file.coffee
+++ b/src/flux/models/file.coffee
@@ -3,8 +3,6 @@ Actions = require '../actions'
Attributes = require '../attributes'
_ = require 'underscore-plus'
-module.exports =
-
##
# Files are small objects that wrap attachments and other files available via the API.
#
@@ -34,3 +32,6 @@ class File extends Model
'contentId': Attributes.String
modelKey: 'contentId'
jsonKey: 'content_id'
+
+
+module.exports = File
\ No newline at end of file
diff --git a/src/flux/models/query.coffee b/src/flux/models/query.coffee
index 9e2e45ab8..1bf0ca6fe 100644
--- a/src/flux/models/query.coffee
+++ b/src/flux/models/query.coffee
@@ -1,11 +1,8 @@
{Matcher, NullPlaceholder, AttributeJoinedData} = require '../attributes'
_ = require 'underscore-plus'
-###
-# ModelQuery exposes an ActiveRecord-style syntax for building database queries.
+# Database: ModelQuery exposes an ActiveRecord-style syntax for building database queries.
#
-# @namespace Application
-###
class ModelQuery
##
diff --git a/src/flux/models/thread.coffee b/src/flux/models/thread.coffee
index a475f99d5..b2237c69f 100644
--- a/src/flux/models/thread.coffee
+++ b/src/flux/models/thread.coffee
@@ -9,10 +9,8 @@ Attributes = require '../attributes'
Function::getter = (prop, get) ->
Object.defineProperty @prototype, prop, {get, configurable: yes}
-module.exports =
-##
-# @class Thread
-# @namespace Models
+#
+# Public: Thread
#
class Thread extends Model
@@ -120,3 +118,6 @@ class Thread extends Model
AddRemoveTagsTask = require '../tasks/add-remove-tags'
task = new AddRemoveTagsTask(@id, tagIdsToAdd, tagIdsToRemove)
Actions.queueTask(task)
+
+
+module.exports = Thread
\ No newline at end of file
diff --git a/src/flux/stores/draft-store.coffee b/src/flux/stores/draft-store.coffee
index 7a7211aaf..3f436e63d 100644
--- a/src/flux/stores/draft-store.coffee
+++ b/src/flux/stores/draft-store.coffee
@@ -66,7 +66,9 @@ DraftStore = Reflux.createStore
# Returns a promise
sessionForLocalId: (localId) ->
- throw new Error("sessionForLocalId requires a localId") unless localId
+ if not localId
+ console.log((new Error).stack)
+ throw new Error("sessionForLocalId requires a localId")
@_draftSessions[localId] ?= new DraftStoreProxy(localId)
@_draftSessions[localId]
diff --git a/src/flux/stores/search-view.coffee b/src/flux/stores/search-view.coffee
index 81d82e182..f7d75b0f5 100644
--- a/src/flux/stores/search-view.coffee
+++ b/src/flux/stores/search-view.coffee
@@ -3,7 +3,7 @@ Utils = require '../models/utils'
DatabaseStore = require './database-store'
ModelView = require './model-view'
-module.exports =
+# Public: Class here!
class SearchView extends ModelView
constructor: (@_query, @_namespaceId) ->
@@ -13,6 +13,11 @@ class SearchView extends ModelView
_.defer => @retrievePage(0)
@
+ # Public: Takes an argument and does some stuff.
+ #
+ # a - A {String}
+ #
+ # Returns {Boolean}.
query: ->
@_query
@@ -30,6 +35,11 @@ class SearchView extends ModelView
# to retrieve pages.
{start: start, end: end + 100}
+ # Public: It's my song turn it up.
+ #
+ # a - A {String}
+ #
+ # Returns {Boolean}.
count: ->
@_queryResultTotal
@@ -72,3 +82,6 @@ class SearchView extends ModelView
@_emitter.emit('trigger')
console.log("Search view fetched #{idx} in #{Date.now() - start} msec.")
+
+
+module.exports = SearchView
diff --git a/src/sheet-container.cjsx b/src/sheet-container.cjsx
index a1b88ee36..a577b715b 100644
--- a/src/sheet-container.cjsx
+++ b/src/sheet-container.cjsx
@@ -9,26 +9,27 @@ _ = require 'underscore-plus'
ComponentRegistry,
WorkspaceStore} = require "inbox-exports"
-ToolbarSpacer = React.createClass
- className: 'ToolbarSpacer'
- propTypes:
+class ToolbarSpacer extends React.Component
+ @displayName = 'ToolbarSpacer'
+ @propTypes =
order: React.PropTypes.number
- render: ->
+
+ render: =>
-ToolbarBack = React.createClass
- className: 'ToolbarBack'
- render: ->
+class ToolbarBack extends React.Component
+ @displayName = 'ToolbarBack'
+ render: =>