ratchet_design 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/app/assets/images/ratchet/favicon.ico +0 -0
- data/app/assets/javascripts/ratchet/_svg.js +55 -0
- data/app/assets/javascripts/ratchet/base/form.js +220 -0
- data/app/assets/javascripts/ratchet/base/mobilemenu.js +62 -0
- data/app/assets/javascripts/ratchet/base/validation.js +230 -0
- data/app/assets/javascripts/ratchet/core.js +92 -0
- data/app/assets/javascripts/ratchet/enhancement/_collapse.js +96 -0
- data/app/assets/javascripts/ratchet/enhancement/_lightbox.js +93 -0
- data/app/assets/javascripts/ratchet/enhancement/_swap.js +120 -0
- data/app/assets/javascripts/ratchet/enhancement/_switcheroo.js +28 -0
- data/app/assets/javascripts/ratchet/enhancement/_textcounter.js +92 -0
- data/app/assets/javascripts/ratchet/enhancement/loader.js +77 -0
- data/app/assets/javascripts/ratchet/enhancement/notice.js +70 -0
- data/app/assets/javascripts/ratchet/enhancement/sticky.js +128 -0
- data/app/assets/javascripts/ratchet/enhancement/waypoints.js +328 -0
- data/app/assets/javascripts/ratchet/shim/classlist.js +234 -0
- data/app/assets/javascripts/ratchet/shim/object.assign.js +30 -0
- data/app/assets/javascripts/ratchet/utility/compile_data.js +32 -0
- data/app/assets/javascripts/ratchet/utility/from_top.js +14 -0
- data/app/assets/javascripts/ratchet/utility/full_stop.js +55 -0
- data/app/assets/javascripts/ratchet/utility/get_closest.js +20 -0
- data/app/assets/javascripts/ratchet/utility/get_next.js +17 -0
- data/app/assets/javascripts/ratchet/utility/load_font.js +72 -0
- data/app/assets/javascripts/ratchet/utility/load_script.js +34 -0
- data/app/assets/javascripts/ratchet/utility/matches.js +15 -0
- data/app/assets/javascripts/ratchet/utility/scroll_to.js +74 -0
- data/app/assets/javascripts/ratchet/utility/throttle.js +25 -0
- data/app/assets/javascripts/ratchet/utility/timeout.js +45 -0
- data/app/assets/javascripts/ratchet/utility/unhover.js +56 -0
- data/app/assets/javascripts/ratchet/utility/word_count.js +15 -0
- data/app/assets/stylesheets/ratchet/_core.scss +20 -0
- data/app/assets/stylesheets/ratchet/base/_button.scss +101 -0
- data/app/assets/stylesheets/ratchet/base/_document.scss +306 -0
- data/app/assets/stylesheets/ratchet/base/_form.scss +614 -0
- data/app/assets/stylesheets/ratchet/base/_list.scss +114 -0
- data/app/assets/stylesheets/ratchet/base/_media.scss +41 -0
- data/app/assets/stylesheets/ratchet/base/_table.scss +81 -0
- data/app/assets/stylesheets/ratchet/base/_text.scss +411 -0
- data/app/assets/stylesheets/ratchet/enhancement/_contrast-section.scss +22 -0
- data/app/assets/stylesheets/ratchet/enhancement/_feature.scss +49 -0
- data/app/assets/stylesheets/ratchet/enhancement/_hero.scss +44 -0
- data/app/assets/stylesheets/ratchet/enhancement/_loader.scss +109 -0
- data/app/assets/stylesheets/ratchet/enhancement/_notice.scss +74 -0
- data/app/assets/stylesheets/ratchet/enhancement/_signup.scss +206 -0
- data/app/assets/stylesheets/ratchet/enhancement/_sticky-sidebar.scss +36 -0
- data/app/assets/stylesheets/ratchet/fonts-woff.css +55 -0
- data/app/assets/stylesheets/ratchet/fonts-woff2.css +55 -0
- data/app/assets/stylesheets/ratchet/utility/_global.scss +255 -0
- data/app/assets/stylesheets/ratchet/utility/_grid.scss +102 -0
- data/app/assets/svgs/ratchet/facebook.svg +1 -0
- data/app/assets/svgs/ratchet/github.svg +1 -0
- data/app/assets/svgs/ratchet/google-plus.svg +1 -0
- data/app/assets/svgs/ratchet/ibm.svg +1 -0
- data/app/assets/svgs/ratchet/inbox.svg +1 -0
- data/app/assets/svgs/ratchet/linkedin.svg +1 -0
- data/app/assets/svgs/ratchet/ratchet.svg +1 -0
- data/app/assets/svgs/ratchet/search.svg +1 -0
- data/app/assets/svgs/ratchet/subscribe.svg +1 -0
- data/app/assets/svgs/ratchet/twitter.svg +1 -0
- data/app/assets/svgs/ratchet/y-combinator.svg +1 -0
- data/app/helpers/ratchet/application_helper.rb +51 -0
- data/app/views/layouts/ratchet/default.html.slim +61 -0
- data/app/views/shared/ratchet/_footer.html.slim +2 -0
- data/app/views/shared/ratchet/_header.html.slim +17 -0
- data/app/views/shared/ratchet/_icons.html.slim +89 -0
- data/lib/ratchet_design.rb +12 -0
- data/lib/ratchet_design/version.rb +3 -0
- data/public/assets/ratchet/core-0.1.0.js +103 -0
- data/public/assets/ratchet/core-0.1.0.js.gz +0 -0
- data/public/assets/ratchet/core-0.1.0.map.json +1 -0
- data/public/assets/ratchet/fonts-woff-0.1.0.css +55 -0
- data/public/assets/ratchet/fonts-woff-0.1.0.css.gz +0 -0
- data/public/assets/ratchet/fonts-woff2-0.1.0.css +55 -0
- data/public/assets/ratchet/fonts-woff2-0.1.0.css.gz +0 -0
- 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
|
+
|
Binary file
|
@@ -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;
|