Code Monkey home page Code Monkey logo

ep's Introduction

Build Status

alt tag

enhance your HTML5 <progress> bars with minimal effort!

alt tag

The <progress> element doesn't always play nice.

It doesn't have a consistent appearance across the popular browsers. In addition, different browsers impose different limitations on the <progress> element.

Because of this, it's often overlooked in favor of styled <div> combos.

ep tackles this;

  • Cross browser reset and styling to pull <progress> element in line with modern slim-style bars
  • CSS helpers that provide classes and attributes to deal with things like positioning, growth style, simulation etc.
  • Optional JS helper for better control and interaction with <progress> elements. For example; being able to hook into network request status and display this to the end user.
  • Plays nice wherever the <progress> element is supported!
  const myEp = new Ep(document.querySelector('progress'));
  const makeRequest = () => {
    myEp.simulate();
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        myEp.complete();
      }
    };
    xhttp.open('GET', '/index.html', true);
    xhttp.send();
  };
  (myEp._VALUE) ? myEp.set(0, makeRequest) : makeRequest();

Index

Browser support

Chrome Firefox Safari Opera Edge IE(10+)
πŸ˜„ πŸ˜„ πŸ˜„ πŸ˜„ πŸ˜„ πŸ˜„

Caveats

  • iOS Safari doesn't like indeterminate <progress> elements. Get round this by not setting your <progress> element to be indeterminate but instead using the helper class ep--indeterminate which will mock the indeterminate state.
  • In IE, ensure that the max attribute is set when using specific values. If no max is set, the value won't go higher than 1 😒

Usage

You have various options with how to use ep;

  • Use the stylesheet by adding ep.css to your app.
  • Include the optional JS helper ep.js for some more control.
  • Integrate the ep styles with your own SASS by importing the parts you need.

Install

You can grab a copy of ep through bower or npm;

  bower install ep

  npm install @jh3y/ep

Just using the stylesheet

If you're just using the stylesheet, you just need to include it. No alterations need to be made to your current <progress> elements unless you want to make use of some of the helper classes and attributes.

  <progress value="75" max="100"></progress>

  <progress class="ep--fixed ep--top" value="75" max="100"></progress>

  <progress data-simulate="true" value="75" max="100"></progress>

Need to change the color of a <progress> element or something else? Override the rule. For example, change the color to purple;

  progress {
    background: purple;
  }

  progress::-moz-progress-bar {
    background: purple;
  }

  progress::-webkit-progress-bar {
    background: purple;
  }

  progress::-webkit-progress-value {
    background: purple;
  }

There is also a SASS mixin included to as a shorthand to do this;

@import '~ep/mixins';
.progress {
  @include color-bar(purple);
}

Including the optional JS helper

If you choose to use the optional JS helper. You'll have access to the Ep constructor class. Refer to the JS API for further info.

  const el   = document.querySleect
  const myEp = new Ep()

Integrating with your own SASS files

Say you want to pick and choose pieces of ep. Simple. This is actually the easiest way to override eps configuration variables. ep makes use of the !default flag in sass to make this possible. For example; let's say we only want the core styles but we don't want any opacity and we want the primary color to be be purple.

  $ep-fg: purple;
  $ep-opacity: 1;
  @import '~ep/core'

CSS Helpers API

Without the use of JS, ep provides some CSS helpers in the form of attributes and classes you can apply to <progress> elements to define behaviors.

Aesthetic helpers

Aesthetic helpers come in the form of classes;

  • ep--top - position absolute top
  • ep--bottom - position absolute bottom
  • ep--fixed - position fixed
  • ep--spread - change style of <progress> bar to spread
  • ep--indeterminate - show indeterminate state

Behavioural helpers

Behavioural helpers come in the form of attributes that must be applied to your <progress> elements;

  • data-complete - complete progress(set to 100 and hide, more control with JS helper)
  • data-simulate - slowly simulate progress in steps up to 99%over 30 seconds(request timeout), can be configured/overrode
  • data-mock="value" - mock progress for given number of seconds
  • data-staggered-mock="value" - mock progress but with staggered style
  • data-timer="value" - use progress element as timer for given seconds
  • data-pause - pauses any animation in place such as timer, mock etc.

NOTE:: The mock, staggered-mock, timer and simulate behaviors have duration defaults set in the source. For example; the max duration is set at 4. This is to keep the size down. But these can easily be altered by building your own version of ep or adding rules for the durations you require. For example; I want the simulation to only take 10s and a timer that will take 15s.

progress[data-simulate] {
  animation-duration: 10s;
  animation-timing-function: steps(28);
}

progress[data-timer="15"] {
  animation-duration: 15s;
}

Sass variables

ep leverages the !default flag in Sass so it's easier to override ep configuration variables. Simply set any of the following variables before importing ep.

  • $ep-ns: ep - set the class helper prefix
  • $ep-height: 6px - set the height of <progress> elements
  • $ep-fg: #3498db - set the primary color of <progress> elements
  • $ep-indeterminate-fg: $ep-fg - set the primary color when in indeterminate state
  • $ep-opacity: .6 - set the opacity of <progress> elements
  • $ep-transition: .25s - set the duration for <progress> elements to transition value
  • $ep-timeout-threshold: 30 - the time it takes for simulation to complete in seconds
  • $ep-simulate-max: 99 - at which value should simulation stop
  • $ep-mocks-min: 1 - minimum mocking duration in seconds
  • $ep-mocks-max: 4 - maximum mocking duration in seconds
  • $ep-staggered-mocks-min: 1 - minimum staggered mock duration in seconds
  • $ep-staggered-mocks-max: 4 - maximum staggered mock duration in seconds
  • $ep-timers-min: 1 - minimum timer duration in seconds
  • $ep-timers-max: 4 - maximum timer duration in seconds
$ep-fg: #e74c3c3;
$ep-opacity: .8;
// import with default variables override
@import '~ep/core';

Sass mixin

ep also has a mixin available for coloring progress elements. Simply pass a color to color-bar. You may use this without even importing the ep reset if you just want to color some progress elements.

@import '~ep/mixins';

.my-progress-element { @include color-bar(#7bff7b); }

Javascript helper/API

ep also provides an optional Javascript helper/api. This can be used for convenience and also gives a little more control and power when interacting with <progress> elements. It doesn't create any extra elements, but you must pass a HTMLProgressElement into the constructor.

const bar = document.querySelector('progress');
const myEp = new Ep(bar);

It's main purpose is that it saves you the burden of having to set/remove attributes/classes. But it also provides some nice to haves such as being able to hook into when progress is complete or set.

The source is quite heavily documented and written with babel so be sure to check that out here.

As for the methods available(? denotes an optional parameter);

  • set({number} val, ? {function} cb) - Sets <progress> value with optional callback.
  • setSpread(? {bool} spread) - Set whether <progress> element should be spred style. By default will set to false.
  • setIndeterminate(? {bool} indeterminate) - Set whether <progress> element is using indeterminate helper class. By default, will remove helper class.
  • togglePause - Toggles pause attribute for play/pause animation.
  • setPosition(? {Array string} positions) - Takes an optional array of positions that will be applied to the element. For example, ['top', 'fixed'] will set ep--top ep--fixed class to the <progress> element. If no positions are declared, all currently applied will be wiped.
  • increase(? {number} value, ? {function} cb) - Increase progress value by optional increment with an optional callback. By default, increment is 5.
  • decrease(? {number} value, ? {function} cb) - Decrease progress value by optional decrement with an optional callback. By default, decrement is 5.
  • reset - Resets <progress> value to 0.
  • mock(? {number} duration, ? {bool} staggered, ? {function} cb) - Mocks progress with a mocking animation. Optional duration in seconds. Optional staggered attribute defines which mock style use. Optional callback can be invoked when mock is complete. By default, duration is 4.
  • time(? {number} duration, ? {function} cb) - Timing mock for using element as timer. Optional duration in seconds. Optional callback can be invoked when timer is complete. By default, duration is 4.
  • simulate(? {number} step, ? {number} increment, ? {number} max) - Simulation on the Javascript side is an example where we have more control than we do with CSS. Set a simulation by declaring a step duration in ms, an increment and a max value for the simulation to reach. The default simulation will increment by 5 every second until the <progress> element has a value of 99.
  • complete(? {function} cb) - Complete a progress bar by setting value to 100 and then resetting it. Provide optional callback for when complete.

Hooking into network requests

Yep. You can easily integrate ep to communicate network request status to the end user. The most basic example being something like the following;

  const myEp = new Ep(document.querySelector('progress'));
  const makeRequest = () => {
    myEp.simulate();
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        myEp.complete();
      }
    };
    xhttp.open('GET', '/index.html', true);
    xhttp.send();
  }
  (myEp._VALUE) ? myEp.set(0, makeRequest) : makeRequest();

We start with a simple progress element. Reset it to make sure it starts at 0 and start a simulation. When we get the OK from our network request, set our element to complete πŸŽ‰

What happened to progrecss?

For some time, I'd intended to revisit progre(c)ss with some ideas I had. When I finally got round to it, I went back over the issues and something struck me. Someone had pointed out why not use the <progress> element?

I'd previously struck this off because I liked being able to add :pseudo element progress bars to any element with relative ease where the :pseudo elements were available.

However, using :pseudo elements to display progress isn't ideal and not very semantic.

It makes more sense to create something that can be integrated without big changes.

progre(c)ss is still available under the release tab if you really want it but realistically the code for progre(c)ss is as simple as;

.progrecss {
  &:before {
    color: green;
    content: '';
    height: 6px;
    left: 0;
    opacity: .8;
    position: absolute;
    top: 0;
  }
  @for $percent from 1 through 100 {
    &[data-progrecss-value='#{$percent}'] {
      &:before {
        width: $percent * 1%;
      }
    }
  }
}

Development

ep is developed using webpack, webpack-dev-server, babel and sass.

It uses a self-documented Makefile for development.

See available tasks

  make

Setup

  make setup

Start developing

  make develop

Contributing

Don't hesitate to post and issue, PR or suggestion. Alternatively, get in touch via email or by tweeting me @_jh3y! πŸ˜„

License

MIT


Made real by @jh3y 2017 😎

ep's People

Contributors

jh3y avatar pducks32 avatar unixzii avatar ybur-yug avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ep's Issues

Broken code samples in demo when changing value

Issue summary

When changing the value in the demo for a mock, staggered-mock or timer by deleting the value and then entering a new value, the entire code block becomes mangled.

Expected behavior

Value in code should updated to number value in input if necessary.

Steps to reproduce

Delete value in a number input, then input a number on demo.

@jh3y

Please include dist...

Having to go into the ep folder after downloading it, and manually npm installing, and running make dist is a pain in the ass...

Not to mention, building needs additional configuration, as the Class EP element can't be converted to javascript properly out of the box (not using webpack, just bower / npm / node).

I had to make another .babelrc file with the following contents:

{
	"presets": ["es2015"]
}

in order to get make dist-script to work.

So please, for the love of god, for those who aren't using your exact development environment, or don't have any knowledge of debugging this kind of thing... please either include dist files of the latest build, or at the very least also include a .babelrc file so that make works without a webpack compiler.

Demo layout on small height screen

Issue summary

If I'm viewing the demo on desktop with the window at a small height. The intro and description for ep get cut.

Expected behavior

I should be able to scroll and see the rest of the content.

Browser used

Any.

Steps to reproduce

View the demo and resize the window to be a small height on desktop.

@jh3y

Fix demo value update

Issue summary

If I set a value on either the spread style bar or standard style bar in the demo by first deleting the input value and then changing it, the value in the code sample won't update again

Expected behavior

No matter what I do with the input, the code sample should update if I input a valid number

Steps to reproduce

Delete the input value then input some valid value

@jh3y

Implement tests for optional JS helper

Issue summary

There are currently no tests in place for the optional JS helper.

Expected behavior

It would be ideal to have tests in place that ensure attributes/classes are applied/removed when necessary using particular methods. Also, the ability to test that callbacks are being properly applied.

Requirements

  • Create testing bundle config for webpack.
  • Use mocha and chai along with js-dom for testing.

@jh3y

give an example of AJAX extensions and prefiltering in docs.

I'm not 100% sure without having a look around but I am pretty sure you can write a prefilter for AJAX requests which means you can make a custom update progress function be run everytime an AJAX request is made.

Thomas Davis does something similar in backbone for cross domain requests in one of his examples.

I'll look into it unless anyone has an idea of it.

@jh3y

Title of demo page error

In the title of the demo page, there's no r, like there should be in progre(c)ss, so it says proge(c)ss. A quick look at the heading on the page tells me that there is an r in it.

Stop timer at certain percentage

Could you add a method that stop a timer at certain percentage? It might be helpful when someone will be creating an online test/survey β€”for exampleβ€” and want the users to hurry up, then, as soon as they press a button, the timer will stop. Or maybe, like my case, if someone wants to show how much of something remains for the next step and timer is just perfect.

What are the browser requirements?

I love the idea, thanks for writing it ;)

I'm just curious - I didn't see on the website anywhere - What browsers does this require/work with?

Restructure src folder to be more intuitive

Issue summary

src folder structure is not intuitive. For example; style source living within src/script/entries. Instead, have things like script, style under relative entries.

Will require paths across src file imports and webpack config updates.

@jh3y

add a small js helper

It seems that a very small js helper could be added as an optional extra for mocking progress meters.

Something as simple as being able to provide (where progrecss is a variable instance of a progrecss);

  progrecss.start();

And

  progrecss.stop();

Can't see this being particularly hard to be honest.

@jh3y

basic mocking attribute

From feedback on HN it seems that the ability to be able to mock progre(c)ss easily out of the box would be appreciated.

This can be easily done with keyframes but I'd like to be able to do it with simply doing something like

     <div class="progrecss" data-progrecss="0" data-progrecss-mocking="32"></div>

This would create a progrecss bar that completes it's journey in 32 seconds from render.

This shouldn't be too much effort but I think a maximum of say 120 seconds should be put in unless people want to add their own after that's fine.

Could also add a class like staggered which would stagger the progrecss til completion time.

@jh3y

Staggered mock doesn't honour lower animation durations

Issue summary

On the demo, if I change the duration to <4, then the simulation doesn't show.

Expected behavior

I should see the simulation with the new animation duration specified from the input.

Steps to reproduce

Lower the value specified for duration in the demo.

@jh3y

Fixed position bottom styling makes bar invisible

Issue summary

When the bar is fixed-bottom in the demo, it disappears.

Expected behavior

Should see it fixed to the bottom of the page.

Browser used

Any.

Steps to reproduce

Check the demo, and change the positional demo to fixed-bottom.

Resolution

Instead of setting to bottom: 0, the bar position should be set to bottom: 6px or whatever the height of the bar is.

@jh3y

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.