ratchet_design 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +41 -0
  4. data/app/assets/images/ratchet/favicon.ico +0 -0
  5. data/app/assets/javascripts/ratchet/_svg.js +55 -0
  6. data/app/assets/javascripts/ratchet/base/form.js +220 -0
  7. data/app/assets/javascripts/ratchet/base/mobilemenu.js +62 -0
  8. data/app/assets/javascripts/ratchet/base/validation.js +230 -0
  9. data/app/assets/javascripts/ratchet/core.js +92 -0
  10. data/app/assets/javascripts/ratchet/enhancement/_collapse.js +96 -0
  11. data/app/assets/javascripts/ratchet/enhancement/_lightbox.js +93 -0
  12. data/app/assets/javascripts/ratchet/enhancement/_swap.js +120 -0
  13. data/app/assets/javascripts/ratchet/enhancement/_switcheroo.js +28 -0
  14. data/app/assets/javascripts/ratchet/enhancement/_textcounter.js +92 -0
  15. data/app/assets/javascripts/ratchet/enhancement/loader.js +77 -0
  16. data/app/assets/javascripts/ratchet/enhancement/notice.js +70 -0
  17. data/app/assets/javascripts/ratchet/enhancement/sticky.js +128 -0
  18. data/app/assets/javascripts/ratchet/enhancement/waypoints.js +328 -0
  19. data/app/assets/javascripts/ratchet/shim/classlist.js +234 -0
  20. data/app/assets/javascripts/ratchet/shim/object.assign.js +30 -0
  21. data/app/assets/javascripts/ratchet/utility/compile_data.js +32 -0
  22. data/app/assets/javascripts/ratchet/utility/from_top.js +14 -0
  23. data/app/assets/javascripts/ratchet/utility/full_stop.js +55 -0
  24. data/app/assets/javascripts/ratchet/utility/get_closest.js +20 -0
  25. data/app/assets/javascripts/ratchet/utility/get_next.js +17 -0
  26. data/app/assets/javascripts/ratchet/utility/load_font.js +72 -0
  27. data/app/assets/javascripts/ratchet/utility/load_script.js +34 -0
  28. data/app/assets/javascripts/ratchet/utility/matches.js +15 -0
  29. data/app/assets/javascripts/ratchet/utility/scroll_to.js +74 -0
  30. data/app/assets/javascripts/ratchet/utility/throttle.js +25 -0
  31. data/app/assets/javascripts/ratchet/utility/timeout.js +45 -0
  32. data/app/assets/javascripts/ratchet/utility/unhover.js +56 -0
  33. data/app/assets/javascripts/ratchet/utility/word_count.js +15 -0
  34. data/app/assets/stylesheets/ratchet/_core.scss +20 -0
  35. data/app/assets/stylesheets/ratchet/base/_button.scss +101 -0
  36. data/app/assets/stylesheets/ratchet/base/_document.scss +306 -0
  37. data/app/assets/stylesheets/ratchet/base/_form.scss +614 -0
  38. data/app/assets/stylesheets/ratchet/base/_list.scss +114 -0
  39. data/app/assets/stylesheets/ratchet/base/_media.scss +41 -0
  40. data/app/assets/stylesheets/ratchet/base/_table.scss +81 -0
  41. data/app/assets/stylesheets/ratchet/base/_text.scss +411 -0
  42. data/app/assets/stylesheets/ratchet/enhancement/_contrast-section.scss +22 -0
  43. data/app/assets/stylesheets/ratchet/enhancement/_feature.scss +49 -0
  44. data/app/assets/stylesheets/ratchet/enhancement/_hero.scss +44 -0
  45. data/app/assets/stylesheets/ratchet/enhancement/_loader.scss +109 -0
  46. data/app/assets/stylesheets/ratchet/enhancement/_notice.scss +74 -0
  47. data/app/assets/stylesheets/ratchet/enhancement/_signup.scss +206 -0
  48. data/app/assets/stylesheets/ratchet/enhancement/_sticky-sidebar.scss +36 -0
  49. data/app/assets/stylesheets/ratchet/fonts-woff.css +55 -0
  50. data/app/assets/stylesheets/ratchet/fonts-woff2.css +55 -0
  51. data/app/assets/stylesheets/ratchet/utility/_global.scss +255 -0
  52. data/app/assets/stylesheets/ratchet/utility/_grid.scss +102 -0
  53. data/app/assets/svgs/ratchet/facebook.svg +1 -0
  54. data/app/assets/svgs/ratchet/github.svg +1 -0
  55. data/app/assets/svgs/ratchet/google-plus.svg +1 -0
  56. data/app/assets/svgs/ratchet/ibm.svg +1 -0
  57. data/app/assets/svgs/ratchet/inbox.svg +1 -0
  58. data/app/assets/svgs/ratchet/linkedin.svg +1 -0
  59. data/app/assets/svgs/ratchet/ratchet.svg +1 -0
  60. data/app/assets/svgs/ratchet/search.svg +1 -0
  61. data/app/assets/svgs/ratchet/subscribe.svg +1 -0
  62. data/app/assets/svgs/ratchet/twitter.svg +1 -0
  63. data/app/assets/svgs/ratchet/y-combinator.svg +1 -0
  64. data/app/helpers/ratchet/application_helper.rb +51 -0
  65. data/app/views/layouts/ratchet/default.html.slim +61 -0
  66. data/app/views/shared/ratchet/_footer.html.slim +2 -0
  67. data/app/views/shared/ratchet/_header.html.slim +17 -0
  68. data/app/views/shared/ratchet/_icons.html.slim +89 -0
  69. data/lib/ratchet_design.rb +12 -0
  70. data/lib/ratchet_design/version.rb +3 -0
  71. data/public/assets/ratchet/core-0.1.0.js +103 -0
  72. data/public/assets/ratchet/core-0.1.0.js.gz +0 -0
  73. data/public/assets/ratchet/core-0.1.0.map.json +1 -0
  74. data/public/assets/ratchet/fonts-woff-0.1.0.css +55 -0
  75. data/public/assets/ratchet/fonts-woff-0.1.0.css.gz +0 -0
  76. data/public/assets/ratchet/fonts-woff2-0.1.0.css +55 -0
  77. data/public/assets/ratchet/fonts-woff2-0.1.0.css.gz +0 -0
  78. metadata +177 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 89650100df2404d22f67c7f009684726963eb6d7
4
+ data.tar.gz: ea6180540d9a955e87377e2585b79d88ddcf3ad2
5
+ SHA512:
6
+ metadata.gz: 139f8966dc358cb3e6b245039979db3f4ecc12dab5cb9a8278a5fe3c87bec82a5f9a8459636e1be57a18677cb8435228a4cf83570aeb9bf0e70fefc5c52b2b5d
7
+ data.tar.gz: dba992c64cc3f07799c2a5dabb3bf413321c4d8efc928a06b1cb76e9b7cb1a249a31014e6cfe967ace0f9078772d9b64bd210776a9cf3fc7320f1156dcfacfb4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Brandon Mathis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # RatchetDesign
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ratchet_design`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ratchet_design'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ratchet_design
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ratchet_design. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
@@ -0,0 +1,55 @@
1
+ var esvg = {
2
+ embed: function(){
3
+ if (!document.querySelector('#esvg-symbols')) {
4
+ document.querySelector('body').insertAdjacentHTML('afterbegin', '<svg id="esvg-symbols" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><symbol id="icon-facebook" viewBox="0 0 38 38" width="38" height="38"><path d="M21.4 12.8h2.1V9.4h-2.7c-2.9 0-4.2 1.3-4.2 3.7v2.6h-2V19h2v9.6h3.9v-9.7h2.7l.3-3.2h-3v-1.8c0-.8.2-1.1.9-1.1z"/></symbol><symbol id="icon-github" viewBox="0 0 38 38" width="38" height="38"><path d="M23 35.9v-4.5c0-1.6-.5-2.5-1.1-3 3.6-.4 7.5-1.8 7.5-8.1 0-1.8-.6-3.3-1.7-4.4.2-.4.7-2.1-.2-4.3 0 0-1.4-.4-4.5 1.6-1.3-.3-2.7-.5-4.2-.5-1.4 0-2.8.2-4.2.5-3.1-2.1-4.5-1.6-4.5-1.6-.9 2.3-.3 3.9-.2 4.3-1 1.1-1.7 2.6-1.7 4.4 0 6.3 3.8 7.7 7.4 8.1-.4.4-.9 1.1-1 2.2-1 .4-3.3 1.1-4.8-1.4 0 0-.9-1.6-2.5-1.7 0 0-1.6 0-.1 1 0 0 1 .5 1.8 2.4 0 0 1 2.9 5.5 1.9v3c0 .4-.3 1-1 .8 1.6.5 3.4.9 5.2.9 1.8 0 3.5-.3 5.2-.9-.6.3-.9-.2-.9-.7z"/></symbol><symbol id="icon-google-plus" viewBox="0 0 38 38" width="38" height="38"><path d="M10.6 24c0 2 2.3 3.2 5.1 3.2 3.9 0 5.4-2.1 5.4-3.7 0-1.4-.5-2.3-2-3.4-1.6-1.1-1.9-1.8-.5-2.9.8-.6 1.4-1.5 1.4-2.6 0-1.2-.5-2.2-1.4-2.7h1.3l1.1-1.1h-4.8c-3 0-4.5 1.8-4.5 3.8s1.4 3.6 4.1 3.6c-.4.9-.3 1.6.4 2.2-4.6 0-5.6 2-5.6 3.6zm3-9.5c-.3-1.7.6-3 1.9-3s2.4 1.4 2.6 3.1c.2 1.7-.5 2.8-1.7 2.8-1.3 0-2.6-1.2-2.8-2.9zm2.4 6.3c2.2.1 3.4 1.4 3.4 2.8 0 1.5-1.2 2.6-3.7 2.6-1.9 0-3.3-1.2-3.3-2.7 0-1.4 1.6-2.7 3.6-2.7zM25.2 10.9h-1.1v2.2h-2.2v1.1h2.2v2.2h1.1v-2.2h2.2v-1.1h-2.2"/></symbol><symbol id="icon-ibm" viewBox="0 0 75 30" width="75" height="30"><path d="M0 0v2h14.6V0H0zm16.7 0v2h20.8s-2.1-2-4.9-2H16.7zm24.8 0v2h12.6l-.8-2H41.5zm21.7 0l-.8 2h12.5V0H63.2zM0 4v2h14.6V4H0zm16.7 0v2h23.2s-.3-1.6-.8-2H16.7zm24.8 0v2h14l-.7-2H41.5zm20.2 0L61 6h13.9V4H61.7zM4.2 8v2.1h6.3V8H4.2zm16.7 0v2.1h6.3V8h-6.3zm12.4 0v2.1h6.3S40 9 40 8h-6.7zm12.5 0v2.1H57L56.2 8H45.8zm14.5 0l-.8 2.1h11.3V8H60.3zM4.2 12v2h6.3v-2H4.2zm16.7 0v2H37s1.4-1.1 1.8-2H20.9zm24.9 0v2h6.3v-1.1l.4 1.1H64l.4-1.1V14h6.3v-2H58.9l-.6 1.7-.6-1.7H45.8zM4.2 16v2h6.3v-2H4.2zm16.7 0v2h17.9c-.4-1-1.8-2-1.8-2H20.9zm24.9 0v2h6.3v-2h-6.3zm7.4 0l.8 2h8.7l.7-2H53.2zm11.3 0v2h6.3v-2h-6.3zM4.2 20v2h6.3v-2H4.2zm16.7 0v2h6.3v-2h-6.3zm12.4 0v2H40c0-1-.4-2-.4-2h-6.3zm12.5 0v2h6.3v-2h-6.3zm8.9 0l.8 2h5.8l.8-2h-7.4zm9.8 0v2h6.3v-2h-6.3zM.1 23.9V26h14.6v-2.1H.1zm16.6 0V26h22.5c.5-.5.8-2.1.8-2.1H16.7zm25 0V26h10.4v-2.1H41.7zm14.4 0l.8 2.1h2.9l.7-2.1h-4.4zm8.4 0V26H75v-2.1H64.5zM.1 28v2h14.6v-2H.1zm16.6 0v2h15.9c2.8 0 4.9-2 4.9-2H16.7zm25 0v2h10.4v-2H41.7zm15.8 0l.7 2h.1l.8-2h-1.6zm7 0v2H75v-2H64.5z"/></symbol><symbol id="icon-inbox" viewBox="0 0 76 54" width="76" height="54"><path d="M74 7S38.66 31 38 31C37.34 31 2 7 2 7V2.63h72V7zm0 6.24v38.33H2V13.24s34.59 22.9 36 22.9c1.41 0 36-22.9 36-22.9z"/></symbol><symbol id="icon-linkedin" viewBox="0 0 38 38" width="38" height="38"><path d="M11.6 15.5H15v10.8h-3.4z"/><ellipse cx="13.3" cy="12.1" rx="2" ry="2"/><path d="M27.5 26.4v-6.9c0-2.9-1.6-4.3-3.9-4.3S20.3 17 20.3 17v-1.5h-3.2v10.8h3.2v-5.7c0-1.5.7-2.4 2-2.4 1.2 0 1.8.9 1.8 2.4v5.7h3.4z"/></symbol><symbol id="icon-ratchet" viewBox="0 0 600 120" width="600" height="120"><path d="M502.1 2.5H397v39h-20v-39h-37v101.8l-16.8-30.2c-4.5 7.4-12.6 12.4-21.9 12.4-14.2 0-25.7-11.5-25.7-25.7s11.5-25.7 25.7-25.7c8.2 0 15.5 3.8 20.2 9.8l.6-1 18-31.7c-3.1-2.2-6.7-4.2-11-6-3.7-1.6-8-3-13.1-4.3C311 .6 305.2 0 298.7 0c-8.2 0-16 1.4-23.3 4.2C268 7 261.6 11 256.2 16.3c-4.3 4.2-8 9-10.9 14.5 2.2-5.5 5.8-12.5 11.5-18.1 3.8-3.8 8.2-7.2 12.9-9.2H113.5L82.8 83.6l13.7 32.9h9.6l2.9-8h36.4l2.9 8H222v-77h19.5c-2.1 6.3-3.2 13.1-3.2 20.5 0 8.9 1.5 17.1 4.6 24.4 3.1 7.4 7.4 13.7 12.9 18.9 5.5 5.3 12 9.3 19.5 12.3 7.5 2.9 15.8 4.4 24.7 4.4 6.6 0 12.5-.7 17.7-2.1 5.1-1.4 9.3-2.9 13-4.5 3.6-1.7 7.3-3.5 9.3-5.6v9.6h37v-43h20v43h32l5.8-107.9.6 107.9H503v-37h-32v-7h19v-28h-19v-6h31V3.2l6.3 36.3H532v78h38v-78h23.7l6.3-37h-97.9zm-379 71l4.2-10.9 4.2 10.9h-8.4zm19.3-66.4l18.4 32.4H184v76.1L142.4 7.1zM92 43.5c0-22.9-18.5-41-41.4-41H0v114h37V87.6l16.7 28.9h42.9L74.2 77.1C84.9 69.7 92 57.6 92 43.5zm-50.1 13H37v-21h4.9c5.4 0 9.7 4.7 9.8 10.5-.1 5.1-4.5 10.5-9.8 10.5zm251.9 17.2l-7.6-13.2 7.6-13.1h15l7.5 13.1-7.5 13.2h-15z"/></symbol><symbol id="icon-search" viewBox="0 0 38 38" width="38" height="38"><path d="M26.7 25.1L23 21.3c.7-1.1 1.2-2.4 1.2-3.8-.1-3.6-3-6.5-6.7-6.5-3.6 0-6.6 2.9-6.6 6.6s3 6.6 6.6 6.6c1.4 0 2.7-.5 3.8-1.2l3.7 3.7c.2.2.5.3.9.3.3 0 .6-.1.9-.3.3-.4.3-1.2-.1-1.6m-9.1-2.6c-2.7 0-4.9-2.2-4.9-4.9s2.2-4.9 4.9-4.9 4.9 2.2 4.9 4.9-2.2 4.9-4.9 4.9"/></symbol><symbol id="icon-subscribe" viewBox="0 0 38 38" width="38" height="38"><path d="M21.6 26.9c0-5.8-4.7-10.5-10.5-10.5v3.2c4 0 7.3 3.3 7.3 7.3h3.2zm-6.2-2.2c0-1.2-1-2.2-2.2-2.2-1.2 0-2.2 1-2.2 2.2s1 2.2 2.2 2.2c1.2 0 2.2-.9 2.2-2.2zM27 27c0-8.8-7.1-16-15.9-16v3.2c3.4 0 6.6 1.3 9 3.7s3.7 5.6 3.7 9l3.2.1z"/></symbol><symbol id="icon-twitter" viewBox="0 0 38 38" width="38" height="38"><path d="M27 12.4c-.7.4-1.4.6-2.2.8-.6-.7-1.5-1.1-2.5-1.1-2.3 0-3.9 2.1-3.4 4.3-2.9-.1-5.5-1.5-7.2-3.6-.9 1.5-.4 3.6 1.1 4.6-.6 0-1.1-.1-1.6-.4 0 1.7 1.1 3.2 2.8 3.5-.5.2-1.1.2-1.6.1.4 1.4 1.7 2.4 3.2 2.4-1.5 1.1-3.4 1.6-5.2 1.4 1.5 1 3.3 1.6 5.3 1.6 6.5 0 10.1-5.4 9.9-10.3.7-.5 1.3-1.1 1.9-1.9-.6.2-1.3.4-2 .5.7-.4 1.3-1.2 1.5-1.9z"/></symbol><symbol id="icon-y-combinator" viewBox="0 0 38 38" width="38" height="38"><path d="M22.4 10.9h3.8l-5.3 10v6h-3.3v-6l-5.5-10H16l3.3 7 3.1-7z"/></symbol></svg>')
5
+ }
6
+ },
7
+ icon: function(name, classnames) {
8
+ var svgName = this.iconName(name)
9
+ var element = document.querySelector('#'+svgName)
10
+
11
+ if (element) {
12
+ return '<svg class="svg-icon '+svgName+' '+(classnames || '')+'" '+this.dimensions(element)+'><use xlink:href="#'+svgName+'"/></svg>'
13
+ } else {
14
+ console.error('File not found: "'+name+'.svg" at app/assets/svgs/ratchet/')
15
+ }
16
+ },
17
+ iconName: function(name) {
18
+ var before = true
19
+ if (before) {
20
+ return "icon-"+this.dasherize(name)
21
+ } else {
22
+ return name+"-icon"
23
+ }
24
+ },
25
+ dimensions: function(el) {
26
+ return 'viewBox="'+el.getAttribute('viewBox')+'" width="'+el.getAttribute('width')+'" height="'+el.getAttribute('height')+'"'
27
+ },
28
+ dasherize: function(input) {
29
+ return input.replace(/[W,_]/g, '-').replace(/-{2,}/g, '-')
30
+ },
31
+ load: function(){
32
+ // If DOM is already ready, embed SVGs
33
+ if (document.readyState == 'interactive') { this.embed() }
34
+
35
+ // Handle Turbolinks (or other things that fire page change events)
36
+ document.addEventListener("page:change", function(event) { this.embed() }.bind(this))
37
+
38
+ // Handle standard DOM ready events
39
+ document.addEventListener("DOMContentLoaded", function(event) { this.embed() }.bind(this))
40
+ },
41
+ aliases: {},
42
+ alias: function(name) {
43
+ var aliased = this.aliases[name]
44
+ if (typeof(aliased) != "undefined") {
45
+ return aliased
46
+ } else {
47
+ return name
48
+ }
49
+ }
50
+ }
51
+
52
+ esvg.load()
53
+
54
+ // Work with module exports:
55
+ if(typeof(module) != 'undefined') { module.exports = esvg }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Form 0.0.1
3
+ * Compose forms module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Dependencies
9
+ var evt = require( 'compose-event' );
10
+
11
+ // Public API function
12
+ var form = function( element, settings ) {
13
+
14
+ // Overridable defaults
15
+ var defaults = {};
16
+
17
+ // Parameter variables
18
+ var selector = document.querySelector( element ) || document.querySelector( 'form' );
19
+
20
+ // Only run if selector exists
21
+ if ( !selector ) return false;
22
+
23
+ // Scoped variables
24
+ var options = Object.assign( {}, defaults, settings ),
25
+ rangeEls = document.querySelectorAll( 'input[type=range]' ),
26
+ tickEls = document.querySelectorAll( 'input[type=checkbox], input[type=radio]' ),
27
+ docBody = document.body;
28
+
29
+ // Prevent non-numeric characters in number fields
30
+ docBody.addEventListener( 'keypress', keyHandler, false );
31
+
32
+ // Run delegated `on input` listener
33
+ docBody.addEventListener( 'input', rangeHandler, true );
34
+
35
+ // Loop over any range inputs that are present
36
+ for ( var rangeIndex = 0; rangeIndex < rangeEls.length; rangeIndex++ ) {
37
+
38
+ // And run their handler function explicitly at runtime
39
+ rangeHandler( rangeEls[ rangeIndex ] );
40
+
41
+ }
42
+
43
+ // Loop over any checkbox/radio inputs that are present
44
+ for ( var tickIndex = 0; tickIndex < tickEls.length; tickIndex++ ) {
45
+
46
+ // And run their handler function explicitly at runtime
47
+ tickHandler( tickEls[ tickIndex ] );
48
+
49
+ }
50
+
51
+ // Checkbox/radio input hander function
52
+ function tickHandler( elem ) {
53
+
54
+ // Find element’s parent node
55
+ var labelParent = elem.parentNode;
56
+
57
+ // If parent is a label
58
+ if ( labelParent.tagName === 'LABEL' ) {
59
+
60
+ // Simply add the `tick-label` classname
61
+ labelParent.classList.add( 'tick-label' );
62
+
63
+ // Otherwise
64
+ } else {
65
+
66
+ // Wrap the element properly
67
+ elem.insertAdjacentHTML( 'beforebegin', '<label class="tick-label"></label>' );
68
+ elem.previousSibling.insertAdjacentElement( 'afterbegin', elem );
69
+
70
+ }
71
+
72
+ // And add empty span to label
73
+ elem.insertAdjacentHTML( 'afterend', '<span></span>' );
74
+
75
+ }
76
+
77
+ // Keydown handler function
78
+ function keyHandler( event ) {
79
+
80
+ // Only run on number inputs
81
+ if ( event.target.type !== 'number' ) {
82
+ return false;
83
+ }
84
+
85
+ // If user enters non-numeric characters
86
+ if ( event.which < 48 || event.which > 57 ) {
87
+
88
+ // Supress them
89
+ event.preventDefault();
90
+
91
+ }
92
+
93
+ }
94
+
95
+ // Range input hander function
96
+ function rangeHandler( event ) {
97
+
98
+ // Define target element
99
+ var element = ( event.target ) ? event.target : event;
100
+
101
+ // Only run on range inputs
102
+ if ( element.type !== 'range' ) {
103
+ return false;
104
+ }
105
+
106
+ // Calculate percentage value
107
+ var percValue = ( element.max ) ? element.value / element.max * 100 : element.value / 100 * 100;
108
+
109
+ // Style bar accordingly
110
+ element.style.backgroundImage = 'linear-gradient(90deg, #009DDC ' + percValue + '%, #D1D1D1 ' + percValue + '%)';
111
+
112
+ }
113
+
114
+ // Rangetouch 0.0.9 - https://github.com/selz/rangetouch
115
+ function rangeTouch( size ) {
116
+
117
+ // Bail if not a touch device
118
+ if ( !( 'ontouchstart' in document.documentElement ) ) {
119
+ return;
120
+ }
121
+
122
+ // Scoped variables
123
+ var rangeInputs = document.querySelectorAll( '[type=range]' ),
124
+ thumbSize = size || 20;
125
+
126
+ // Set touchAction to prevent delays
127
+ for ( var i = rangeInputs.length - 1; i >= 0; i-- ) {
128
+ rangeInputs[ i ].style.touchAction = 'manipulation';
129
+ rangeInputs[ i ].style.webkitUserSelect = 'none';
130
+ }
131
+
132
+ // Listen for events
133
+ docBody.addEventListener( 'touchstart', setValue, false );
134
+ docBody.addEventListener( 'touchmove', setValue, false );
135
+ docBody.addEventListener( 'touchend', setValue, false );
136
+
137
+ // Get the number of decimal places
138
+ function getDecimalPlaces( value ) {
139
+ var match = ( '' + value ).match( /( ?:\.( \d+ ) )?( ?:[eE]( [+-]?\d+ ) )?$/ );
140
+ if ( !match ) {
141
+ return 0;
142
+ }
143
+ return Math.max( 0, ( match[ 1 ] ? match[ 1 ].length : 0 ) - ( match[ 2 ] ? +match[ 2 ] : 0 ) );
144
+ }
145
+
146
+ // Round to the nearest step
147
+ function roundToStep( number, step ) {
148
+ if ( step < 1 ) {
149
+ var places = getDecimalPlaces( parseInt( step ) );
150
+ return parseFloat( number.toFixed( places ) );
151
+ }
152
+ return ( Math.round( number / step ) * step );
153
+ }
154
+
155
+ // Get the value based on touch position
156
+ function getValue( event ) {
157
+
158
+ // Scoped variables
159
+ var input = event.target,
160
+ touch = event.changedTouches[ 0 ],
161
+ min = parseFloat( input.getAttribute( 'min' ) ) || 0,
162
+ max = parseFloat( input.getAttribute( 'max' ) ) || 100,
163
+ step = parseFloat( input.getAttribute( 'step' ) ) || 1,
164
+ delta = max - min;
165
+
166
+ // Calculate percentage
167
+ var percent,
168
+ clientRect = input.getBoundingClientRect(),
169
+ thumbWidth = ( ( ( 100 / clientRect.width ) * ( thumbSize / 2 ) ) / 100 );
170
+
171
+ // Determine left percentage
172
+ percent = ( ( 100 / clientRect.width ) * ( touch.clientX - clientRect.left ) );
173
+
174
+ // Don't allow outside bounds
175
+ if ( percent < 0 ) {
176
+ percent = 0;
177
+ } else if ( percent > 100 ) {
178
+ percent = 100;
179
+ }
180
+
181
+ // Factor in the thumb offset
182
+ if ( percent < 50 ) {
183
+ percent -= ( ( 100 - ( percent * 2 ) ) * thumbWidth );
184
+ } else if ( percent > 50 ) {
185
+ percent += ( ( ( percent - 50 ) * 2 ) * thumbWidth );
186
+ }
187
+
188
+ // Find the closest step to the mouse position
189
+ return min + roundToStep( delta * ( percent / 100 ), step );
190
+
191
+ }
192
+
193
+ // Update range value based on position
194
+ function setValue( event ) {
195
+
196
+ // Bail if not a range slider
197
+ if ( event.target.type !== 'range' ) {
198
+ return;
199
+ }
200
+
201
+ // Prevent text highlight on iOS
202
+ event.preventDefault();
203
+
204
+ // Set value
205
+ event.target.value = getValue( event );
206
+
207
+ // Trigger input event
208
+ evt.fire( event.target, ( event.type === 'touchend' ? 'change' : 'input' ) );
209
+
210
+ }
211
+
212
+ }
213
+
214
+ // Initialize RangeTouch
215
+ rangeTouch();
216
+
217
+ };
218
+
219
+ // Public API
220
+ module.exports = form;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Mobile Menu 0.0.2
3
+ * Compose mobile menu module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT (http://www.opensource.org/licenses/mit-license.php/)
6
+ **/
7
+
8
+ // Public API function
9
+ var mobileMenu = function( element, settings ) {
10
+
11
+ // Overridable defaults
12
+ var defaults = {
13
+ initWidth : '700px',
14
+ openClass : 'menu-open'
15
+ };
16
+
17
+ // Scoped variables
18
+ var options = Object.assign( {}, defaults, settings ),
19
+ selector = document.querySelector( element ),
20
+ widthQuery = window.matchMedia( '(max-width: ' + options.initWidth + ')' );
21
+
22
+ // Attach listeners
23
+ if ( selector ) {
24
+
25
+ // Call listener function explicitly at run time
26
+ queryHandler( widthQuery );
27
+
28
+ // Attach listener function to listen in on state changes
29
+ widthQuery.addListener( queryHandler );
30
+
31
+ }
32
+
33
+ // Click handler function
34
+ function clickHandler( event ) {
35
+
36
+ event.preventDefault();
37
+
38
+ document.body.classList.toggle( options.openClass );
39
+
40
+ }
41
+
42
+ // Media query handler function
43
+ function queryHandler( condition ) {
44
+
45
+ // If media query matches
46
+ if ( condition.matches ) {
47
+
48
+ // Click function listener
49
+ selector.addEventListener( 'click', clickHandler, false );
50
+
51
+ } else {
52
+
53
+ // Remove click listener
54
+ selector.removeEventListener( 'click', clickHandler, false );
55
+
56
+ }
57
+ }
58
+
59
+ };
60
+
61
+ // Public API
62
+ module.exports = mobileMenu;
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Validation 0.0.6
3
+ * Compose form validation module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Dependencies
9
+ var matches = require( '../utility/matches' ),
10
+ getClosest = require( '../utility/get_closest' ),
11
+ wordCount = require( '../utility/word_count' );
12
+
13
+ // Public API function
14
+ var validation = function( element, settings ) {
15
+
16
+ // Overridable defaults
17
+ var defaults = {};
18
+
19
+ // Parameter variables
20
+ var selector = document.querySelector( element ) || document.querySelector( '[required]' );
21
+
22
+ // Only run if selector exists & validation is supported
23
+ if ( !selector || typeof document.createElement( 'input' ).checkValidity !== 'function' ) return false;
24
+
25
+ // Scoped variables
26
+ var options = Object.assign( {}, defaults, settings ),
27
+ docBody = document.body;
28
+
29
+ // Suppress default message bubbles
30
+ docBody.addEventListener( 'invalid', function( event ) {
31
+ event.preventDefault();
32
+ }, true );
33
+
34
+ // Run delegated `on blur` validation checks
35
+ docBody.addEventListener( 'blur', blurHandler, true );
36
+
37
+ // Run delegated `on submit` validation checks
38
+ docBody.addEventListener( 'click', submissionHandler, false );
39
+
40
+ // Blur validation handler
41
+ function blurHandler( event ) {
42
+
43
+ // Only run on non-submit inputs
44
+ if ( !matches( event.target, 'input:not([type=submit]), textarea' ) ) return false;
45
+
46
+ // Scoped variables
47
+ var element = event.target,
48
+ minWords = element.dataset.minWords,
49
+ indicator = getClosest( element, 'label' ) || element,
50
+ validity;
51
+
52
+ // Remove pre-existing validation message
53
+ messageHandler( 'hide', element );
54
+
55
+ // If element has `data-min-words` attribute
56
+ if ( minWords ) {
57
+
58
+ // And it has a value that is less than the set minimum
59
+ if ( element.value && wordCount( element.value ) < minWords ) {
60
+
61
+ // Set a custom error message
62
+ element.setCustomValidity( 'Please write at least ' + minWords + ' words.' );
63
+
64
+ // Otherwise
65
+ } else {
66
+
67
+ // Default to normal error messaging
68
+ element.setCustomValidity( '' );
69
+
70
+ }
71
+
72
+ }
73
+
74
+ // Check validity
75
+ validity = element.checkValidity();
76
+
77
+ // If the element has a value but is invalid
78
+ if ( element.value && !validity ) {
79
+
80
+ // Set invalid state
81
+ indicator.classList.remove( 'valid' );
82
+ indicator.classList.add( 'invalid' );
83
+
84
+ // If the element has a value and is valid
85
+ } else if ( element.value && validity ) {
86
+
87
+ // Set valid state
88
+ indicator.classList.remove( 'invalid' );
89
+ indicator.classList.add( 'valid' );
90
+
91
+ // If the element has no value
92
+ } else if ( !element.value ) {
93
+
94
+ // Set neutral state
95
+ indicator.classList.remove( 'valid' );
96
+ indicator.classList.remove( 'invalid' );
97
+
98
+ }
99
+
100
+ }
101
+
102
+ // Submission validation handler function
103
+ function submissionHandler( event ) {
104
+
105
+ // Only run on submission
106
+ if ( !matches( event.target, 'input[type=submit], button:not([type=button])' ) ) return;
107
+
108
+ // Scoped variables
109
+ var invalidForm = getClosest( event.target, 'form' ),
110
+ invalidElem = invalidForm.querySelector( 'input:invalid, textarea:invalid' ),
111
+ indicator;
112
+
113
+ // If invalid element found
114
+ if ( invalidElem ) {
115
+
116
+ // Set indicator to parent label if it exists
117
+ indicator = getClosest( invalidElem, 'label' ) || invalidElem;
118
+
119
+ // If credit card field is invalid
120
+ if ( matches( invalidElem, '[data-stripe=number]' ) ) {
121
+
122
+ // Strip it of non-number characters
123
+ invalidElem.value = invalidElem.value.replace( /[^0-9 -]/g, '' );
124
+
125
+ // Evaluate form validity again
126
+ invalidElem = invalidForm.querySelector( 'input:invalid, textarea:invalid' );
127
+
128
+ // And return if valid
129
+ if ( !invalidElem ) return;
130
+
131
+ }
132
+
133
+ // Prevent default behavior
134
+ event.preventDefault();
135
+
136
+ // If invalid is not hidden
137
+ if ( invalidElem.style.display !== 'none' ) {
138
+
139
+ // Focus it
140
+ invalidElem.focus();
141
+
142
+ // Otherwise
143
+ } else {
144
+
145
+ // Focus its immediate sibling (mostly used for upload buttons)
146
+ invalidElem.nextSibling.focus();
147
+
148
+ }
149
+
150
+ // Toggle classes
151
+ indicator.classList.remove( 'valid' );
152
+ indicator.classList.add( 'invalid' );
153
+
154
+ // Show validation message
155
+ messageHandler( 'show', invalidElem );
156
+
157
+ // Prevent Safari submission
158
+ return false;
159
+
160
+ }
161
+
162
+ }
163
+
164
+ // Validation message handler function
165
+ function messageHandler( action, element ) {
166
+
167
+ // Scoped variables
168
+ var parentForm = getClosest( element, 'form' ),
169
+ oldMessage = parentForm.querySelector( '.validation-message' ),
170
+ newMessage = element.validationMessage,
171
+
172
+ // Hide old message
173
+ hideMessage = function() {
174
+ oldMessage.parentNode.removeChild( oldMessage );
175
+ },
176
+
177
+ // Show new message
178
+ showMessage = function() {
179
+
180
+ // Find the element's parent label
181
+ var labelParent = getClosest( element, 'label' );
182
+
183
+ // If it doesn't exist, abort
184
+ if ( !labelParent ) return false;
185
+
186
+ // Otherwise, create and append the validation message
187
+ labelParent.insertAdjacentHTML( 'beforeend', '<aside class="validation-message"><p>' + newMessage + '</p></aside>' );
188
+
189
+ };
190
+
191
+ // If a `data-message` attribute exists, use it in message
192
+ if ( element.dataset.message ) newMessage = element.dataset.message;
193
+
194
+ // If hide action is passed hide old message
195
+ if ( oldMessage && action === 'hide' ) hideMessage();
196
+
197
+ // If show action is passed and no old message exists
198
+ if ( action === 'show' && !oldMessage ) {
199
+
200
+ // Show new message
201
+ showMessage();
202
+
203
+ // If show action is passed and old message exists
204
+ } else if ( action === 'show' && oldMessage ) {
205
+
206
+ // Make sure old message is not on currently invalid element
207
+ if ( oldMessage.parentNode !== element.parentNode ) {
208
+
209
+ // Hide old message
210
+ hideMessage();
211
+
212
+ // And show new message
213
+ showMessage();
214
+
215
+ // Otherwise
216
+ } else {
217
+
218
+ // Update message text on currently invalid element
219
+ oldMessage.childNodes[ 0 ].textContent = newMessage;
220
+
221
+ }
222
+
223
+ }
224
+
225
+ }
226
+
227
+ };
228
+
229
+ // Public API
230
+ module.exports = validation;