Hey I've uploaded a Button StateMachine plugin to github. I started off writing the state machine into my button entities, but the code became to cluttered so I decided to move the state machine into a separate module/plugin.
Have a look and let me know if it proves useful to you. Would also appreciate feedback on bugs, and/or ways to improve this plugin.

Get the plugin and documentation here: Impact-ButtonStateMachine-Plugin


Below is an example implementation of a game button using the state machine plugin (see github repo for more complete example and docs):

// -------------------------------------------------------------------------------------------------------------
// DemoGamebtn.js
// -------------------------------------------------------------------------------------------------------------
ig.module(
    'game.entities.demogamebtn'
)
.requires(
    'plugins.button-state-machine',
    'impact.entity'
)
.defines(function() {
    EntityDemoGamebtn = ig.Entity.extend({
        size: {x: 16, y: 16},

        btnStateMachine: null,

        // -------------------------------------------------------------------------------------------------------------
        // Button States
        // -------------------------------------------------------------------------------------------------------------
        endClick: function() { this.currentAnim = this.anims.btnNormal; },
        endClickIgnore: function() { this.currentAnim = this.anims.btnNormal; },
        endHover: function() { this.currentAnim = this.anims.btnNormal; },
        startClick: function() { this.currentAnim = this.anims.btnDown; },
        startHover: function() { this.currentAnim = this.anims.btnHover; },

        // -------------------------------------------------------------------------------------------------------------
        // Alpha Hit Detection
        // -------------------------------------------------------------------------------------------------------------
        // hittest - returns true if mouse cursor within bounds, else false
        hittest: function() {
            if ((ig.input.mouse.x > this.pos.x && ig.input.mouse.x < (this.pos.x + this.size.x)) &&
                (ig.input.mouse.y > this.pos.y && ig.input.mouse.y < (this.pos.y + this.size.y)))
            {
                return true;
            }
            return false;                       // hittest failed - mouse outside of entity
        },
        init: function(x, y, settings) {

            this.animSheet = new ig.AnimationSheet('media/btns/' + settings.image , settings.width, settings.height);
            this.addAnim('btnNormal', 1, [0]);
            this.addAnim('btnHover', 2, [1]);
            this.addAnim('btnDown', 3, [2]);
            this.addAnim('btnDisabled', 4, [3]);
            this.currentAnim = this.anims.btnNormal;
            this.size.x = settings.width;
            this.size.y = settings.height;

            // ...
            // ...
            this.btnStateMachine = new ig.ButtonStateMachine();
            this.btnStateMachine.isMouseInside = this.hittest.bind(this);
            this.btnStateMachine.isMouseDown = function() { return ig.input.state('click'); };
            this.btnStateMachine.startClick = this.startClick.bind(this);
            this.btnStateMachine.endClick = this.endClick.bind(this);
            this.btnStateMachine.startHover = this.startHover.bind(this);
            this.btnStateMachine.endHover = this.endHover.bind(this);
            this.btnStateMachine.endClickIgnore = this.endClickIgnore.bind(this);

            this.parent(x, y, settings);
        },
        update: function() {
            this.parent();

            this.btnStateMachine.updateState();
        }
    });
});