Add Focusable mixin and FocusContext

Focusable objects have ::focus and ::blur methods and a ::focused
property. Focusable objects can be assigned a ::focusContext, and the
::focused property will only be true for at most one object with the
same context.
This commit is contained in:
Nathan Sobo
2014-01-09 09:53:14 -07:00
parent 1a5e10c1d2
commit 4e99d003ee
3 changed files with 59 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
{Model} = require 'theorist'
Focusable = require '../src/focusable'
FocusContext = require '../src/focus-context'
describe "Focusable mixin", ->
it "ensures that only a single model is focused for a given focus manager", ->
class Item extends Model
Focusable.includeInto(this)
focusContext = new FocusContext
item1 = new Item({focusContext})
item2 = new Item({focusContext})
item3 = new Item({focusContext})
expect(focusContext.focusedObject).toBe null
expect(item1.focused).toBe false
expect(item2.focused).toBe false
expect(item3.focused).toBe false
item1.focus()
expect(focusContext.focusedObject).toBe item1
expect(item1.focused).toBe true
expect(item2.focused).toBe false
expect(item3.focused).toBe false
item2.focus()
expect(focusContext.focusedObject).toBe item2
expect(item1.focused).toBe false
expect(item2.focused).toBe true
expect(item3.focused).toBe false
item2.blur()
expect(focusContext.focusedObject).toBe null
expect(item1.focused).toBe false
expect(item2.focused).toBe false
expect(item3.focused).toBe false

5
src/focus-context.coffee Normal file
View File

@@ -0,0 +1,5 @@
{Model} = require 'theorist'
module.exports =
class FocusContext extends Model
@property 'focusedObject', null

18
src/focusable.coffee Normal file
View File

@@ -0,0 +1,18 @@
Mixin = require 'mixto'
module.exports =
class Focusable extends Mixin
@included: ->
@property 'focusContext'
@behavior 'focused', ->
@$focusContext
.flatMapLatest((context) -> context?.$focusedObject)
.map((focusedObject) => focusedObject is this)
focus: ->
throw new Error("Object must be assigned a focusContext to be focus") unless @focusContext
@focusContext.focusedObject = this
blur: ->
throw new Error("Object must be assigned a focusContext to be blurred") unless @focusContext
@focusContext.focusedObject = null if @focused