tungsten 0.1.17 → 0.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/tungsten/{_form_helpers.js → _form-helpers.js} +0 -0
  3. data/app/assets/javascripts/tungsten/enhancements/flash-messages.js +14 -0
  4. data/app/assets/javascripts/tungsten/enhancements/notify.js +89 -0
  5. data/app/assets/javascripts/tungsten/tungsten.js +5 -2
  6. data/app/assets/stylesheets/tungsten/components/_index.scss +2 -0
  7. data/app/assets/stylesheets/tungsten/components/_notices.scss +31 -0
  8. data/app/assets/stylesheets/tungsten/components/_notifications.scss +136 -0
  9. data/app/assets/stylesheets/tungsten/components/_tooltip.scss +22 -8
  10. data/app/assets/stylesheets/tungsten/core/_animations.scss +48 -0
  11. data/app/assets/stylesheets/tungsten/core/_globals.scss +15 -14
  12. data/app/assets/stylesheets/tungsten/core/_layout.scss +9 -1
  13. data/app/helpers/tungsten/notice_helper.rb +25 -0
  14. data/app/views/shared/tungsten/_flash-messages.html.slim +3 -3
  15. data/lib/tungsten/version.rb +1 -1
  16. data/public/{code-0.1.17.js → code-0.1.18.js} +1 -1
  17. data/public/{code-0.1.17.js.gz → code-0.1.18.js.gz} +0 -0
  18. data/public/{code-0.1.17.map.json → code-0.1.18.map.json} +0 -0
  19. data/public/{tungsten-0.1.17.css → tungsten-0.1.18.css} +256 -14
  20. data/public/tungsten-0.1.18.css.gz +0 -0
  21. data/public/{tungsten-0.1.17.js → tungsten-0.1.18.js} +43 -39
  22. data/public/tungsten-0.1.18.js.gz +0 -0
  23. data/public/tungsten-0.1.18.map.json +1 -0
  24. metadata +16 -12
  25. data/app/assets/javascripts/tungsten/enhancements/form-flash.js +0 -0
  26. data/public/tungsten-0.1.17.css.gz +0 -0
  27. data/public/tungsten-0.1.17.js.gz +0 -0
  28. data/public/tungsten-0.1.17.map.json +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 329f8efbe917b13ad6a9dd0905d7afb167be3d82
4
- data.tar.gz: 7dc93e12d1a22c612d3ea79742ce99787b72f2f6
3
+ metadata.gz: 84a6187cac138f3e21e0ed94b80a54d8df98a2ef
4
+ data.tar.gz: 4012d13ac481790f836cb2e5f6f2af887c02703d
5
5
  SHA512:
6
- metadata.gz: fb1c49ab62f7a3ea7a4f1f354b602b3791c62cdcccbab9d9a478d7dd7ce0f240be9bb7cc6f16a73b6af27d2cf21055dea93f4251725bf65aae54484abe05e6b1
7
- data.tar.gz: ae18d0137dac13386f774285e05adb9cbcf2986af0e4263dddfd84ee3fb1515ef113c7840a5ac5d9b650870d695f210e4156327f6edfb7b41cee3a7b581af701
6
+ metadata.gz: 8b8a2135aad4ad4491e7ecccaf8782fd0d3a5c0524468f68371a8792d7fb9dda111e99121a69ea1ecdee5ac53d71d90a7857c4864e6db17532540a78398f4ddf
7
+ data.tar.gz: 52ad761a7308f1944cfbe46a4d9e6cf39913299655e7cb996979d5f76260d7ec0914e99092e6cbbd68ba4d0951c61b1cb1de111ac2354db9367d138025f21b51
@@ -0,0 +1,14 @@
1
+ var Event = require('compose-event')
2
+ var Notify = require('./notify')
3
+
4
+ // If a page has an element .form-flash, trigger a notification
5
+ //
6
+ Event.change(function(){
7
+ var flash = document.querySelector('.flash-message')
8
+ if (flash) {
9
+ flash.classList.add('hidden')
10
+ var type = flash.dataset.type || 'error'
11
+ Notify(type, flash.textContent.trim())
12
+ }
13
+ })
14
+
@@ -0,0 +1,89 @@
1
+ var Event = require( 'compose-event' )
2
+
3
+ var defaultsByType = {
4
+ normal: { dismissAfter: 2500 },
5
+ success: { dismissAfter: 2500 },
6
+ }
7
+
8
+
9
+ var timeout,
10
+ messageEl,
11
+ template = '\
12
+ <div class="notification">\
13
+ <div class="notification-content">\
14
+ <div class="notification-message" role="alert"></div>\
15
+ <button class="notification-close" href="#" role="button" aria-label="close message">\
16
+ <span class="close-icon" aria-hidden="true"></span>\
17
+ </button>\
18
+ </div>\
19
+ </div>\
20
+ '
21
+
22
+ function notify (type, message) {
23
+ if ( !message ) {
24
+ message = type
25
+ type = null
26
+ }
27
+
28
+ return show( type, message )
29
+ }
30
+
31
+ function show ( type, message ) {
32
+ if ( messageEl ) return dismiss( function(){ show( type, message ) })
33
+
34
+ document.body.insertAdjacentHTML( 'beforeend', template )
35
+ messageEl = document.body.lastChild
36
+
37
+ messageEl.querySelector( '.notification-message' ).innerHTML = message
38
+
39
+ if ( type ) {
40
+
41
+ messageEl.classList.add( type )
42
+ var defaults = defaultsByType[ type ]
43
+
44
+ if ( defaults && defaults.dismissAfter ){
45
+ timeout = Event.delay( dismiss, defaults.dismissAfter )
46
+ }
47
+ }
48
+
49
+ messageEl = document.body.lastChild
50
+
51
+ Event.keyOne( 'esc', dismiss )
52
+ Event.one( messageEl, 'click', '.notification-close', dismiss )
53
+
54
+ return {
55
+ dismiss: dismiss
56
+ }
57
+ }
58
+
59
+ function dismiss ( callback ) {
60
+
61
+ var cb
62
+
63
+ if ( typeof callback == 'function' ) {
64
+ cb = function() { remove(); callback() }
65
+ } else {
66
+ cb = remove;
67
+ }
68
+
69
+ var timeout = Event.delay( cb, 500 )
70
+
71
+ Event.one( messageEl, 'animationstart', function() {
72
+ clearTimeout( timeout )
73
+
74
+ Event.afterAnimation( messageEl, cb )
75
+ })
76
+
77
+ messageEl.classList.add( 'dismiss' )
78
+ }
79
+
80
+ function remove () {
81
+ messageEl = document.querySelector('body > .notification')
82
+
83
+ if (messageEl) {
84
+ messageEl.parentNode.removeChild( messageEl )
85
+ }
86
+ messageEl = null
87
+ }
88
+
89
+ module.exports = notify
@@ -4,18 +4,21 @@ var toolbox = require( 'compose-toolbox' )
4
4
  var ajax = require( 'superagent' )
5
5
  var event = toolbox.event
6
6
  var clipboard = require( './enhancements/clipboard' )
7
+ var notify = require( './enhancements/notify' )
7
8
 
8
9
  event.scroll.disablePointer() // disable pointer events on scroll for performance (to avoid extra repaints)
9
10
  clipboard();
10
11
 
11
12
  require( 'compose-slider' ) // Our slider (range input) component
12
13
  require( './_icons' ) // Import svg icons (from Esvg)
13
- require( './_form_helpers' )
14
+ require( './_form-helpers' )
15
+ require( './enhancements/flash-messages' )
14
16
 
15
17
  // Public API object
16
18
  window.Tungsten = module.exports = toolbox.merge( {
17
19
  ajax : ajax,
18
20
  form : formUp,
19
21
  toggler : toggler,
20
- clipboard : clipboard
22
+ clipboard : clipboard,
23
+ notify : notify
21
24
  }, toolbox )
@@ -3,3 +3,5 @@
3
3
  @import 'badges';
4
4
  @import 'cards';
5
5
  @import 'tooltip';
6
+ @import 'notices';
7
+ @import 'notifications';
@@ -0,0 +1,31 @@
1
+ @mixin notice-colors ($text, $bg, $border) {
2
+ color: $text;
3
+ background: linear-gradient( top, lighten($bg, 2), darken($bg, 2));
4
+ border: 1px solid $border;
5
+ }
6
+ .notice {
7
+ border-radius: $radius;
8
+ box-shadow: 0 3px 5px rgba($gray-11, .15);
9
+ padding: $card-padding;
10
+ @include block-margin;
11
+
12
+ .notice-title, p {
13
+ margin: {
14
+ top: 10px;
15
+ bottom: 10px;
16
+ }
17
+ &:first-child {
18
+ margin-top: 0;
19
+ }
20
+ }
21
+
22
+ @include notice-colors(currentColor, #fff, $gray-05);
23
+
24
+ &.warning {
25
+ @include notice-colors(#80602A, #fff4ad, #E2C66D);
26
+ }
27
+ &.error {
28
+ @include notice-colors(#FFF, #F37B78, #AB5857);
29
+ text-shadow: rgba(#000, .2) 0 1px 1px;
30
+ }
31
+ }
@@ -0,0 +1,136 @@
1
+ $status-text: #fff;
2
+ $status-text-shadow: rgba(#000, .2) 0 1px 1px;
3
+
4
+ @mixin notification-style($color) {
5
+ .notification-content {
6
+ background: $color;
7
+ }
8
+ .notification-content:before {
9
+ background-color: darken($color, 10);
10
+ }
11
+ }
12
+
13
+ .flash-message {
14
+ display: none;
15
+ }
16
+
17
+ .notification {
18
+ position: fixed; top: 0; left: 10px; right: 10px;
19
+ height: 1px;
20
+ z-index: 1000;
21
+ overflow: visible;
22
+ transform: translate3d(0,0,0);
23
+
24
+ &:after {
25
+ content: "";
26
+ position: absolute;
27
+ top: 0; left: 0; right: 0;
28
+ height: 56px;
29
+ z-index: -1;
30
+ }
31
+
32
+ &-content {
33
+ width: 100%;
34
+ font-size: 1.2em;
35
+ margin: 0 auto;
36
+ position: relative;
37
+ animation: slide-down .4s $timing;
38
+ color: $status-text;
39
+ text-shadow: $status-text-shadow;
40
+ box-shadow: 0 3px 10px rgba($gray-11, .3);
41
+ border-bottom-left-radius: 5px;
42
+ border-bottom-right-radius: 5px;
43
+ display: flex;
44
+ align-items: middle;
45
+
46
+ &:before {
47
+ filter: brightness(1);
48
+ border-bottom-left-radius: 5px;
49
+ width: 45px;
50
+ content: "";
51
+ vertical-align: middle;
52
+ text-align: center;
53
+ padding-top: .4em;
54
+ content: url('data:image/svg+xml;utf-8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 32 32"%3E%3Cpath fill="#fff" d="M16 8.5a.5.5 0 0 1 0 1c-5.327 0-10 2.804-10 6a.5.5 0 0 1-1 0c0-3.794 5.037-7 11-7zm0-5c-8.837 0-16 5.373-16 12 0 4.127 2.78 7.766 7.008 9.926 0 .027-.008.045-.008.074 0 1.793-1.34 3.723-1.928 4.736h.002a.906.906 0 0 0 .832 1.264c.094 0 .26-.025.255-.014 3.13-.512 6.07-3.383 6.76-4.215 1 .15 2.03.23 3.09.23 8.84 0 16-5.37 16-12s-7.16-12-16-12zm0 22c-.917 0-1.858-.07-2.796-.207a1.998 1.998 0 0 0-1.836.71c-.428.52-1.646 1.683-3.085 2.538.39-.89.695-1.89.716-2.93v-.18c0-.75-.42-1.44-1.09-1.78C4.21 21.75 2 18.71 2 15.5c0-5.514 6.28-10 14-10 7.718 0 14 4.486 14 10s-6.28 10-14 10z"/%3E%3C/svg%3E');
55
+ }
56
+ }
57
+
58
+ &-message {
59
+ flex-grow: 1;
60
+ padding: 8px 15px;
61
+ a {
62
+ color: #fef0bd;
63
+ &:hover, &:focus {
64
+ color: inherit;
65
+ }
66
+ }
67
+ }
68
+
69
+ &-close {
70
+ flex-shrink: 1;
71
+ text-align: center;
72
+ text-decoration: none;
73
+ padding: 16px 12px;
74
+ color: #fff;
75
+ cursor: pointer;
76
+ opacity: .7;
77
+ background: none;
78
+ border: none;
79
+ animation: half-spin .5s ease-out;
80
+
81
+ .close-icon {
82
+ display: block;
83
+ transition: all .3s cubic-bezier(0.190, 1.000, 0.220, 1.000);
84
+ cursor: pointer;
85
+
86
+ &:before,&:after {
87
+ content: "";
88
+ width: 18px;
89
+ height: 4px;
90
+ background-color: #fff;
91
+ display: block;
92
+ cursor: pointer;
93
+ position: relative;
94
+ }
95
+ &:before {
96
+ top: 2px;
97
+ transform: rotate(-45deg);
98
+ }
99
+ &:after {
100
+ top: -2px;
101
+ transform: rotate(45deg);
102
+ }
103
+ }
104
+
105
+ &:focus, &:hover {
106
+ opacity: 1;
107
+ outline: none;
108
+ }
109
+ }
110
+
111
+ &.dismiss {
112
+ .notification-content {
113
+ animation: slide-up .2s .3s ease-out;
114
+ }
115
+ .close-icon {
116
+ animation: half-spin .5s ease-in reverse;
117
+ }
118
+ }
119
+
120
+ & {
121
+ @include notification-style($gray-09);
122
+ }
123
+
124
+ &.error {
125
+ @include notification-style($red-01);
126
+ }
127
+
128
+ &.action {
129
+ @include notification-style($blue-02);
130
+ }
131
+
132
+ &.success {
133
+ @include notification-style($green-02);
134
+ }
135
+
136
+ }
@@ -7,13 +7,16 @@
7
7
  transform: translate3d(-50%, 0, 0);
8
8
  z-index: 100000;
9
9
  pointer-events: none;
10
+ animation: fade-in .1s ease-in;
11
+ animation-fill-mode: forwards;
12
+ animation-delay: .4s;
13
+ display: none;
10
14
  }
11
15
  &:after {
12
16
  -webkit-font-smoothing: subpixel-antialiased;
17
+ content: attr(aria-label);
13
18
  top: calc(100% + 6px);
14
- transform: translateX(-50%);
15
- background: rgba(#000, 0.8);
16
- display: inline-block;
19
+ background-color: rgba(#000, 0.8);
17
20
  color: #fff;
18
21
  white-space: nowrap;
19
22
  font-size: 11px;
@@ -23,16 +26,27 @@
23
26
  }
24
27
  &:before {
25
28
  top: 100%;
29
+ content: "";
26
30
  @include triangle(up, rgba(#000, 0.8), 6px);
27
31
  }
28
32
 
29
33
  &:hover, &:focus {
30
- &:after { content: attr(aria-label); }
31
- &:before { content: ""; }
34
+ &:after { display: inline-block; }
35
+ &:before { display: inline-block; }
36
+ }
37
+
38
+ &.copied {
39
+ &:after { content: "Copied!"; }
32
40
  &:before, &:after {
33
- animation: fade-in .1s ease-in;
34
- animation-fill-mode: forwards;
35
- animation-delay: .4s;
41
+ animation-delay: 0s;
42
+ }
43
+ &:after {
44
+ background-color: rgba($green-02, .8);
45
+ }
46
+ &:before {
47
+ @include triangle(up, rgba($green-02, .8), 6px);
36
48
  }
37
49
  }
50
+
38
51
  }
52
+
@@ -2,3 +2,51 @@
2
2
  0% { opacity: 0; }
3
3
  100% { opacity: 1; }
4
4
  }
5
+
6
+ @keyframes fade-out {
7
+ 0% { opacity: 1; }
8
+ 100% { opacity: 0; }
9
+ }
10
+
11
+ @keyframes slide-down {
12
+ 0% {
13
+ transform: translateY(-100%)
14
+ } 100% {
15
+ transform: translateY(0)
16
+ }
17
+ }
18
+
19
+ @keyframes slide-up {
20
+ 0% {
21
+ transform: translateY(0)
22
+ } 100% {
23
+ transform: translateY(-100%)
24
+ }
25
+ }
26
+
27
+ @keyframes spin {
28
+ 0% {
29
+ transform: rotate(0deg);
30
+ }
31
+ 100% {
32
+ transform: rotate(360deg);
33
+ }
34
+ }
35
+
36
+ @keyframes half-spin {
37
+ 0% {
38
+ transform: rotate(-180deg);
39
+ }
40
+ 100% {
41
+ transform: rotate(0deg);
42
+ }
43
+ }
44
+
45
+ @keyframes zoom-in {
46
+ 0% {
47
+ transform: scale(.8, .8);
48
+ }
49
+ 100% {
50
+ transform: scale(1,1);
51
+ }
52
+ }
@@ -162,6 +162,21 @@ $header-height: 84px;
162
162
  }
163
163
  }
164
164
 
165
+ // Between widths media query mixin
166
+ @mixin between($small-width, $large-width) {
167
+ $large-width: $large-width - 1;
168
+ @media (max-width: $large-width) and (min-width: $small-width) {
169
+ @content;
170
+ }
171
+ }
172
+
173
+ // HDPI screens media query mixin
174
+ @mixin hdpi {
175
+ @media (min-device-pixel-ratio: 1.3), (min-resolution: 120dpi), (min-resolution: 1.3dppx) {
176
+ @content;
177
+ }
178
+ }
179
+
165
180
  @mixin triangle($direction, $color, $size) {
166
181
  @if $direction == left {
167
182
  border-bottom: $size solid transparent;
@@ -188,17 +203,3 @@ $header-height: 84px;
188
203
  width: 0;
189
204
  }
190
205
 
191
- // Between widths media query mixin
192
- @mixin between($small-width, $large-width) {
193
- $large-width: $large-width - 1;
194
- @media (max-width: $large-width) and (min-width: $small-width) {
195
- @content;
196
- }
197
- }
198
-
199
- // HDPI screens media query mixin
200
- @mixin hdpi {
201
- @media (min-device-pixel-ratio: 1.3), (min-resolution: 120dpi), (min-resolution: 1.3dppx) {
202
- @content;
203
- }
204
- }