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;
}

#fields {
    -webkit-transition: -webkit-transform 0.3s ease-in-out;
}

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

#master-wrapper {
    top: 20px;
    position: relative;
    height: 166px;
    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": "Fifth",
    "value": 5},
{
    "name": "Sixth",
    "value": 6},
{
    "name": "Seventh",
    "value": 7},
{
    "name": "Another",
    "value": 55},
{
    "name": "Yet Another",
    "value": 65},
{
    "name": "Last",
    "value": 99}
];

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

var wrapper = document.getElementById("wrapper");
var fields = document.getElementById("fields");

var scrollY = 0;

function doScroll(direction) {
    var liPadding = 10;
    var scrollHeight = wrapper.clientHeight - liPadding;
    //var item = fields.firstElementChild;
    //var scrollHeight = item.offsetHeight * 3;
    var currentPosition = scrollY * scrollHeight;

    if (direction == "down" && 
        currentPosition + scrollHeight < fields.clientHeight) {
            scrollY++;
    }
    
    if (direction == "up" && scrollY > 0) {
            scrollY--;
    }
            
    var scrollPx = scrollY * scrollHeight;
    fields.style.webkitTransform = "translateY(" + -scrollPx + "px)";
}

up = document.getElementById("scrollUp");
up.onmousedown = function() { doScroll("up"); };

down = document.getElementById("scrollDown");
down.onmousedown = function() { doScroll("down"); };

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