JSFiddle - React, Tailwind, and code Playground

by speakman

HTML

<div id="master-wrapper">
    <div id="wrapper">
        <ul id="fields"></ul>
    </div>
    <div id="scrollUp"></div>
    <div id="scrollDown"></div>
</div>

CSS

* {
    -webkit-user-select: none;
}

li {
    margin: 10px;
    padding: 10px;
    border: 1px solid silver;
    border-radius: 7px;
    font-family: sans-serif;
    font-size: 13pt;
}

li:hover {
    background-color: #E0E0E0;
    cursor: pointer;
}

#wrapper {
    overflow-y: hidden;
    height: 100%;
}

#master-wrapper {
    top: 100px;
    position: relative;
    height: 200px;
    border: 1px solid black;
    border-radius: 7px;
    background-image: -webkit-gradient(
        linear, left top, left bottom,
        color-stop(0.9, rgba(255,255,255,0)),
        color-stop(1, rgba(255,255,255,255))
        );
}

#scrollUp, #scrollDown {
    position: absolute;
    right: 0px;
    cursor: pointer;
    width: 64px;
    height: 64px;
    display: none;
}

#scrollUp {
    background-image: url("http://b.dryicons.com/images/icon_sets/coquette_part_5_icons_set/png/64x64/green_arrow_up.png");
    top: 10px;
}

#scrollDown {
    background-image: url("http://b.dryicons.com/images/icon_sets/coquette_part_5_icons_set/png/64x64/green_arrow_down.png");
    bottom: 10px;
}

JavaScript

choices = [
    {
    "name": "First",
    "value": 1},
{
    "name": "Second",
    "value": 2},
{
    "name": "Third",
    "value": 3},
{
    "name": "Forth",
    "value": 4},
{
    "name": "Another",
    "value": 55},
{
    "name": "Last",
    "value": 99}
];

el = document.getElementById("fields");
choices.forEach(function(c) {
    choice = document.createElement("li");
    choice.innerHTML = c["name"];
    choice.onclick = function() {
        this.scrollIntoView(false);
        alert("Got " + c["value"].toString());
    };
    el.appendChild(choice);
});

wrapper = document.getElementById("wrapper");

var scrollTimer = null;
function startScroll(delta) {
    var lastVisit = new Date().getTime();
    scrollTimer = setInterval(function() {
        oldTop = wrapper.scrollTop;
        
        now = new Date().getTime();
        msDelta = now - lastVisit;
        lastVisit = now;
        
        wrapper.scrollTop += msDelta * 0.5 * delta;
        
        if (wrapper.scrollTop == oldTop) {
            clearInterval(scrollTimer);
        }
    }, 1);
}

function stopScroll() {
    clearInterval(scrollTimer);
}

up = document.getElementById("scrollUp");
up.onmousedown = function() { startScroll(-1); };
up.onmouseout = function() { stopScroll(); };
up.onmouseup = function() { stopScroll(); };

down = document.getElementById("scrollDown");
down.onmousedown = function() { startScroll(+1); };
down.onmouseout = function() { stopScroll(); };
down.onmouseup = function() { stopScroll(); };

if (wrapper.clientHeight < wrapper.scrollHeight) {
    wrapper.style.width = (wrapper.clientWidth - 50) + "px";
    up.style.display = "block";
    down.style.display = "block";
}