<div id="app" class="card">
  <div class="card__content card__content--loader"> 
    <p>Loading</p> 
  </div>
  <div id="card" class="hide card__content">
     <div class="card__body">
        <div class="card__quote">
          quote
        </div>

        <div class="card__author">
          -- author
        </div>
      </div>
      <div class="card__footer">
        <button id="load_btn" class="btn btn--new">
          More
        </button>
        <a href="#" target="_blank" class="btn btn--tweet">
          Tweet
        </a>
      </div> 
  </div> 
</div>
body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 95vh;
  background: #ddd;
  font-size: 1em;
  color: #212121;
}

.card {
  width: 600px;
  background: white;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

.card__content {
  color: #212121;
  padding: 20px;
}

.card__content--loader {
  height: 95px;
  display: flex;
  align-items: center;
  justify-content: center
}

.card__body {
 padding-bottom: 15px;
}

.card__author {
  padding-top: 10px;
  font-style: italic;
}

.card__footer {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.btn {
  color: #fff;
  cursor: pointer;
  margin-top: 10px;
  margin-left: 10px;
  border-radius: 0.4rem;
  text-decoration: none;
  display: inline-block;
  padding: .3rem .9rem;
}

.btn--new {
  background-color: #2093be;
  border: 0.1rem solid #2093be;
  
}

.btn--tweet {
  background-color: #0074d9;
  border: 0.1rem solid #0074d9;
}

.btn:hover {
  background: #3cb0fd;
  border: 0.1rem solid #3cb0fd;
  text-decoration: none;
}

.hide {
  display: none;
}
import {
  createMachine,
  state,
  invoke,
  transition,
  reduce,
  action,
  interpret
} from 'https://unpkg.com/robot3@0.2.9/machine.js';

function get_quote() {
  const delay = random_number(2, 4) * 1000;

  return new Promise(res => {
    setTimeout(() => res(__quotes()), delay);
  });
}

function update_card({ dom, data }) {
  dom.load_btn.textContent = 'More';
  dom.quote.textContent = data.quote;
  dom.author.textContent = data.author;

  const web_intent = 'https://twitter.com/intent/tweet?text=';
  const tweet = `${data.quote} -- ${data.author}`;
  dom.tweet_btn.setAttribute('href', web_intent + encodeURIComponent(tweet));
}

function hide_loader({ dom }) {
  dom.loader.classList.add('hide');
  dom.card.classList.remove('hide');
}

function show_loading({ dom }) {
  dom.load_btn.textContent = 'Loading...';
}

const context = ev => ({
  data: {},
  dom: {
    quote: document.querySelector('.card__quote'),
    author: document.querySelector('.card__author'),
    loader: document.querySelector('.card__content--loader'),
    load_btn: window.load_btn,
    tweet_btn: document.querySelector('.btn--tweet'),
    card: window.card
  }
});

const load_quote = (...args) =>
  invoke(
    get_quote,
    transition(
      'done',
      'idle',
      reduce((ctx, ev) => ({ ...ctx, data: ev.data })),
      ...args
    ),
    transition('error', 'idle')
  );

const mr_robot = createMachine(
  {
    empty: load_quote(action(update_card), action(hide_loader)),
    idle: state(transition('fetch', 'loading', action(show_loading))),
    loading: load_quote(action(update_card))
  },
  context
);

const service = interpret(mr_robot, () => {});
const fetch_quote = () => service.send('fetch');

window.load_btn.addEventListener('click', fetch_quote);




function random_number(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function __quotes() {
  const data = [
    {
      quote:
        'The more varieties of different kinds of notations are still useful — don’t only read the people who code like you.',
      author: 'Donald Knuth'
    },
    {
      quote:
        'The good news about computers is that they do what you tell them to do. The bad news is that they do what you tell them to do.',
      author: 'Ted Nelson'
    },
    {
      quote:
        'They were saying computers deal with numbers. This was absolutely nonsense. Computers deal with arbitrary information of any kind.',
      author: 'Ted Nelson'
    },
    {
      quote:
        'In my second year in graduate school, I took a computer course and that was like lightening striking.',
      author: 'Ted Nelson'
    },
    {
      quote:
        'Right now you are a prisoner of each application you use. You have only the options that were given you by the developer of that application.',
      author: 'Ted Nelson'
    },
    { quote: 'Making things easy is hard.', author: 'Ted Nelson' },
    {
      quote:
        'The difference between theory and practice is that in theory, there is no difference between theory and practice.',
      author: 'Richard Moore (engineer)'
    },
    {
      quote:
        'You should name a variable using the same care with which you name a first-born child.',
      author: 'Jim Coplien'
    },
    {
      quote:
        'The ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code.',
      author: 'Robert C. Martin'
    },
    {
      quote: "There's nothing more permanent than a temporary hack.",
      author: 'Kyle Simpson'
    },
    {
      quote:
        'As numbers are reduced to the simplest principles, like 0 and 1, a wonderful order is apparent throughout.',
      author: 'Gottfried Wilhelm Leibniz'
    }
  ];

  const index = random_number(0, data.length - 1);
  return data[index];
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.