JSFiddle - React, Tailwind, and code Playground

by John Kawakami

HTML

<div id="menu"></div>

CSS

.box {
    width: 100px; 
    height: 20px;
    border-bottom: 1px solid silver;
    padding: 6px;
    -moz-user-select: none;
    cursor: default;
}
.lit {
    background-color: #aef;
}
.dim {
    background-color: #fff;
}

JavaScript

menu = {
    'ca': 'California',
    'ar': 'Arkansas',
    'ak': 'Alaska',
    'nv': 'Nevada',
    'co': 'Colorado',
    'pa': 'Pennsylvania'
};
menuState = {
    'ca': false,
    'ar': false,
    'ak': false,
    'nv': false,
    'co': false,
    'pa': false
};
dispatch = d3.dispatch('lit', 'dim');
body = d3.select('#menu');
Object.keys(menu).forEach(function(name) {
	body.append('div')
        .attr('id', name)
        .attr('class','box')
        .html(menu[name])
    	.on('click', clickHandlerMaker(name));
});
dispatch.on('lit', function(target) {
    d3.select('#'+target).classed({'lit':true, 'dim':false});
});
dispatch.on('dim', function(target) {
    d3.select('#'+target).classed({'lit':false, 'dim':true});
});
refreshAll();

function clickHandlerMaker(name) {
	return function() {    
        menuState[name] = ! menuState[name];
        if (menuState[name]) {
            dispatch.lit(name);
        } else {
            dispatch.dim(name);
        }
    };
}
function refreshAll() {
	Object.keys(menu).forEach(function(name) {
        if (menuState[name]) {
            dispatch.lit(name);
        } else {
            dispatch.dim(name);
        }
    });
}