quilt_ui 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/assets/javascripts/quilt.js +1 -0
- data/assets/stylesheets/quilt/components/badge.scss +47 -0
- data/assets/stylesheets/quilt/components.scss +1 -0
- data/assets/stylesheets/quilt/foundation/colors.scss +122 -0
- data/assets/stylesheets/quilt/foundation/defaults.scss +22 -0
- data/assets/stylesheets/quilt/foundation/spacing.scss +35 -0
- data/assets/stylesheets/quilt/foundation/typography.scss +181 -0
- data/assets/stylesheets/quilt/foundation/utilities/lengths.scss +29 -0
- data/assets/stylesheets/quilt/foundation/utilities/maps.scss +32 -0
- data/assets/stylesheets/quilt/foundation/utilities.scss +2 -0
- data/assets/stylesheets/quilt/foundation.scss +5 -0
- data/assets/stylesheets/quilt/global/typography.scss +23 -0
- data/assets/stylesheets/quilt/global.scss +1 -0
- data/assets/stylesheets/quilt.scss +3 -0
- data/helpers/components/badge.rb +26 -0
- data/helpers/components/component.rb +117 -0
- data/lib/quilt/engine.rb +12 -0
- data/lib/quilt/version.rb +3 -0
- data/lib/quilt_ui.rb +13 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: acf0c64722b0b47bca95af230be7aa97dc0d8277
|
4
|
+
data.tar.gz: b3a04c11c71083140c744ee1ab470536730ee402
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2c9f085e2fa763f27751cc557d4f5ec5c2dcafb977e73c81ae54dc7fd7d7f9f61809b21f80ad1b8f961faa564246bcc00fbea64d1f0ab91ecd516e46498dc934
|
7
|
+
data.tar.gz: 2f0d653f6886066c7eee34fde72ef2c8191b2616375fb078650c2dc4a90ddfef1f959dff13c2f8d972bf7216a61c81a17c37f59718eabd665efd307bd4067947
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Quilt=t():e.Quilt=t()}(this,function(){return function(e){function t(r){if(o[r])return o[r].exports;var n=o[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var o={};return t.m=e,t.c=o,t.p="",t(0)}([function(e,t,o){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t.default=e,t}Object.defineProperty(t,"__esModule",{value:!0}),t.Utilities=t.Components=void 0;var n=o(1),i=r(n),u=o(3),s=r(u);t.Components=i,t.Utilities=s},function(e,t){"use strict"},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.Desktop={matches:!0},t.Mobile={matches:!1}},function(e,t,o){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t.default=e,t}Object.defineProperty(t,"__esModule",{value:!0}),t.Breakpoints=void 0;var n=o(2),i=r(n);t.Breakpoints=i}])});
|
@@ -0,0 +1,47 @@
|
|
1
|
+
.badge {
|
2
|
+
@include meta-text;
|
3
|
+
border-radius: default(border-radius);
|
4
|
+
background-color: color(background);
|
5
|
+
padding: spacing(tiny) spacing(tight);
|
6
|
+
vertical-align: middle;
|
7
|
+
white-space: nowrap;
|
8
|
+
display: inline-block;
|
9
|
+
|
10
|
+
+ .badge {
|
11
|
+
margin-left: spacing(tight);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
.badge--success {
|
16
|
+
background-color: color(background, success);
|
17
|
+
}
|
18
|
+
|
19
|
+
.badge--info {
|
20
|
+
background-color: color(background, info);
|
21
|
+
}
|
22
|
+
|
23
|
+
.badge--subdued {
|
24
|
+
background-color: color(background, subdued);
|
25
|
+
}
|
26
|
+
|
27
|
+
.badge--attention {
|
28
|
+
background-color: color(background, attention);
|
29
|
+
}
|
30
|
+
|
31
|
+
.badge--warning {
|
32
|
+
background-color: color(background, warning);
|
33
|
+
}
|
34
|
+
|
35
|
+
.badge--critical {
|
36
|
+
background-color: color(background, critical);
|
37
|
+
}
|
38
|
+
|
39
|
+
.badge--complete {
|
40
|
+
background-color: color(background, subdued);
|
41
|
+
}
|
42
|
+
|
43
|
+
.badge--inline {
|
44
|
+
font-size: type-size(label);
|
45
|
+
line-height: type-line-height(label);
|
46
|
+
margin-left: spacing(tiny);
|
47
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
@import 'components/badge';
|
@@ -0,0 +1,122 @@
|
|
1
|
+
// scss-lint:disable ColorVariable, ColorKeyword
|
2
|
+
$color-palette-data: (
|
3
|
+
white: #fff,
|
4
|
+
black: #000,
|
5
|
+
|
6
|
+
slate-lightest: #95a7b7,
|
7
|
+
slate-lighter: #798c9c,
|
8
|
+
slate-light: #454e57,
|
9
|
+
slate: #31373d,
|
10
|
+
slate-dark: #272c30,
|
11
|
+
slate-darker: #212529,
|
12
|
+
|
13
|
+
sky-lighter: #fafbfc,
|
14
|
+
sky-light: #f5f6f7,
|
15
|
+
sky: #ebeef0,
|
16
|
+
sky-dark: #d3dbe2,
|
17
|
+
sky-darker: #c3cfd8,
|
18
|
+
|
19
|
+
blue-lightest: #eff9fd,
|
20
|
+
blue-lighter: #cae9f7,
|
21
|
+
blue-light: #4fb0e8,
|
22
|
+
blue: #479ccf,
|
23
|
+
blue-dark: #4293c2,
|
24
|
+
blue-darker: #3e89b5,
|
25
|
+
|
26
|
+
green-lightest: #f8ffec,
|
27
|
+
green-lighter: #e5fabc,
|
28
|
+
green-light: #b2d86a,
|
29
|
+
green: #96bf48,
|
30
|
+
green-dark: #7ba232,
|
31
|
+
green-darker: #4d6110,
|
32
|
+
|
33
|
+
yellow-lightest: #fffbe9,
|
34
|
+
yellow-lighter: #fff7b2,
|
35
|
+
yellow-light: #ffe477,
|
36
|
+
yellow: #ffd117,
|
37
|
+
yellow-dark: #d4a002,
|
38
|
+
yellow-darker: #6f4f0c,
|
39
|
+
|
40
|
+
orange-lightest: #fff9ec,
|
41
|
+
orange-lighter: #ffebcc,
|
42
|
+
orange-light: #fec97d,
|
43
|
+
orange: #ff9517,
|
44
|
+
orange-dark: #e06b0c,
|
45
|
+
orange-darker: #7f3a07,
|
46
|
+
|
47
|
+
red-lightest: #fef6f5,
|
48
|
+
red-lighter: #ffd9d6,
|
49
|
+
red-light: #ff9797,
|
50
|
+
red: #ff5d5d,
|
51
|
+
red-dark: #d83e3e,
|
52
|
+
red-darker: #852929,
|
53
|
+
|
54
|
+
purple-lightest: #faf1fe,
|
55
|
+
purple-lighter: #eccdff,
|
56
|
+
purple-light: #d098ff,
|
57
|
+
purple: #b762ff,
|
58
|
+
purple-dark: #763eaf,
|
59
|
+
purple-darker: #4a1f72,
|
60
|
+
|
61
|
+
teal-lightest: #eafdf7,
|
62
|
+
teal-lighter: #c3f9e4,
|
63
|
+
teal-light: #78ecbc,
|
64
|
+
teal: #29bc94,
|
65
|
+
teal-dark: #15966d,
|
66
|
+
teal-darker: #186148,
|
67
|
+
|
68
|
+
shade: rgba(#000, 0.1),
|
69
|
+
|
70
|
+
ink-black: rgba(#000, 0.9),
|
71
|
+
ink-charcoal: rgba(#000, 0.6),
|
72
|
+
ink-slate: rgba(#000, 0.45)
|
73
|
+
);
|
74
|
+
|
75
|
+
$color-keys-data: (
|
76
|
+
text: (
|
77
|
+
primary: ink-black,
|
78
|
+
secondary: ink-charcoal,
|
79
|
+
hint: ink-slate,
|
80
|
+
link: blue,
|
81
|
+
error: red-dark,
|
82
|
+
success: green-dark
|
83
|
+
),
|
84
|
+
|
85
|
+
background: (
|
86
|
+
primary: sky-dark,
|
87
|
+
subdued: sky,
|
88
|
+
success: green-light,
|
89
|
+
info: blue-lighter,
|
90
|
+
attention: yellow-light,
|
91
|
+
warning: orange-light,
|
92
|
+
error: red-light,
|
93
|
+
critical: red-light
|
94
|
+
),
|
95
|
+
|
96
|
+
border: (
|
97
|
+
primary: sky
|
98
|
+
),
|
99
|
+
|
100
|
+
shadow: (
|
101
|
+
primary: shade
|
102
|
+
)
|
103
|
+
);
|
104
|
+
// scss-lint:enable ColorVariable, ColorKeyword
|
105
|
+
|
106
|
+
//*
|
107
|
+
// Returns the color value for a given color name and group.
|
108
|
+
//
|
109
|
+
// @param {String} $group - The key for the color group.
|
110
|
+
// @param {String} $color - The key for the color name. Defaults to primary.
|
111
|
+
// @return {Color} The color value.
|
112
|
+
|
113
|
+
@function color($group, $color: primary) {
|
114
|
+
$color-palette-key: map-get(map-get($color-keys-data, $group), $color);
|
115
|
+
$fetched-color: map-get($color-palette-data, $color-palette-key);
|
116
|
+
|
117
|
+
@if type-of($fetched-color) == color {
|
118
|
+
@return $fetched-color;
|
119
|
+
} @else {
|
120
|
+
@error "Color `#{$group} - #{$color}` not found. Available colors: #{available-names($color-keys-data)}";
|
121
|
+
}
|
122
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$defaults-data: (
|
2
|
+
border-radius: 3px,
|
3
|
+
box-shadow: 0 2px 4px color(shadow),
|
4
|
+
border-width: 1px,
|
5
|
+
border: 1px solid color(border)
|
6
|
+
);
|
7
|
+
|
8
|
+
//*
|
9
|
+
// Returns the default value for the passed property
|
10
|
+
//
|
11
|
+
// @param {String} $property - The property to retrieve
|
12
|
+
// @return {Mixed} The default value for that property
|
13
|
+
|
14
|
+
@function default($property) {
|
15
|
+
$fetched-value: map-get($defaults-data, $property);
|
16
|
+
|
17
|
+
@if $fetched-value != null {
|
18
|
+
@return $fetched-value;
|
19
|
+
} @else {
|
20
|
+
@error "Default property `#{$property}` not found. Available properties: #{available-names($defaults-data)}";
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
$unit: 4px;
|
2
|
+
|
3
|
+
$spacing-data: (
|
4
|
+
base: rem($unit * 4),
|
5
|
+
tiny: rem($unit),
|
6
|
+
tight: rem($unit * 2),
|
7
|
+
loose: rem($unit * 6)
|
8
|
+
);
|
9
|
+
|
10
|
+
//*
|
11
|
+
// Returns the spacing value for a given variant.
|
12
|
+
//
|
13
|
+
// @param {String} $variant - The key for the given variant.
|
14
|
+
// @return {Number} The spacing for the variant.
|
15
|
+
|
16
|
+
@function spacing($variant: base) {
|
17
|
+
$fetched-value: map-get($spacing-data, $variant);
|
18
|
+
|
19
|
+
@if type-of($fetched-value) == number {
|
20
|
+
@return $fetched-value;
|
21
|
+
} @else {
|
22
|
+
@error "Spacing variant `#{$variant}` not found. Available variants: #{available-names($spacing-data)}";
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
//*
|
27
|
+
// Adds spacing between all direct children.
|
28
|
+
//
|
29
|
+
// @param {String} $variant - The key for the given variant.
|
30
|
+
|
31
|
+
@mixin vertical-rhythm($variant: base) {
|
32
|
+
> *:not(.hide) + * {
|
33
|
+
margin-top: spacing($variant);
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,181 @@
|
|
1
|
+
$type-sizes-data: (
|
2
|
+
x-small: rem(12px),
|
3
|
+
small: rem(14px),
|
4
|
+
medium: rem(16px),
|
5
|
+
large: rem(20px),
|
6
|
+
x-large: rem(32px)
|
7
|
+
);
|
8
|
+
|
9
|
+
$type-size-keys-data: (
|
10
|
+
meta: small,
|
11
|
+
body: medium,
|
12
|
+
section-title: medium,
|
13
|
+
page-title: large,
|
14
|
+
display-title: x-large,
|
15
|
+
label: x-small
|
16
|
+
);
|
17
|
+
|
18
|
+
//*
|
19
|
+
// Returns the font size value for a given typography style.
|
20
|
+
//
|
21
|
+
// @param {String} $style - The key for the style.
|
22
|
+
// @return {Number} The font size value.
|
23
|
+
|
24
|
+
@function type-size($style) {
|
25
|
+
$size-key: map-get($type-size-keys-data, $style);
|
26
|
+
$fetched-value: map-get($type-sizes-data, $size-key);
|
27
|
+
|
28
|
+
@if type-of($fetched-value) == number {
|
29
|
+
@return $fetched-value;
|
30
|
+
} @else {
|
31
|
+
@error "Type style `#{$style}` not found. Available styles: #{available-names($type-size-keys-data)}";
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
$type-line-heights-data: (
|
38
|
+
x-small: rem(14px),
|
39
|
+
small: rem(20px),
|
40
|
+
medium: rem(24px),
|
41
|
+
large: rem(48px)
|
42
|
+
);
|
43
|
+
|
44
|
+
$type-line-height-keys-data: (
|
45
|
+
meta: small,
|
46
|
+
body: medium,
|
47
|
+
section-title: small,
|
48
|
+
page-title: small,
|
49
|
+
display-title: large,
|
50
|
+
label: x-small
|
51
|
+
);
|
52
|
+
|
53
|
+
//*
|
54
|
+
// Returns the line height value for a given typography style.
|
55
|
+
//
|
56
|
+
// @param {String} $style - The key for the style.
|
57
|
+
// @return {Number} The line-height value.
|
58
|
+
|
59
|
+
@function type-line-height($style) {
|
60
|
+
$line-height-key: map-get($type-line-height-keys-data, $style);
|
61
|
+
$fetched-value: map-get($type-line-heights-data, $line-height-key);
|
62
|
+
|
63
|
+
@if type-of($fetched-value) == number {
|
64
|
+
@return $fetched-value;
|
65
|
+
} @else {
|
66
|
+
@error "Type style `#{$style}` not found. Available styles: #{available-names($type-line-height-keys-data)}";
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
$type-weights-data: (
|
73
|
+
bold: 600,
|
74
|
+
medium: 500,
|
75
|
+
regular: 400,
|
76
|
+
light: 300
|
77
|
+
);
|
78
|
+
|
79
|
+
$type-weight-keys-data: (
|
80
|
+
meta: regular,
|
81
|
+
emphasized: bold,
|
82
|
+
body: regular,
|
83
|
+
section-title: medium,
|
84
|
+
page-title: regular,
|
85
|
+
display-title: light
|
86
|
+
);
|
87
|
+
|
88
|
+
//*
|
89
|
+
// Returns the font weight value for a given typography style.
|
90
|
+
//
|
91
|
+
// @param {String} $style - The key for the variant.
|
92
|
+
// @return {Number} The font-weight value.
|
93
|
+
|
94
|
+
@function type-weight($style) {
|
95
|
+
$weight-key: map-get($type-weight-keys-data, $style);
|
96
|
+
$fetched-value: map-get($type-weights-data, $weight-key);
|
97
|
+
|
98
|
+
@if type-of($fetched-value) == number {
|
99
|
+
@return $fetched-value;
|
100
|
+
} @else {
|
101
|
+
@error "Type style `#{$style}` not found. Available styles: #{available-names($type-weight-keys-data)}";
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
$type-family-data: (
|
108
|
+
sans-serif: ("Helvetica Neue", Helvetica, Arial, sans-serif),
|
109
|
+
monospace: (Monaco, Consolas, "Lucida Console", monospace)
|
110
|
+
);
|
111
|
+
|
112
|
+
$type-family-keys-data: (
|
113
|
+
base: sans-serif,
|
114
|
+
code: monospace
|
115
|
+
);
|
116
|
+
|
117
|
+
//*
|
118
|
+
// Returns the font family for a given typography style.
|
119
|
+
//
|
120
|
+
// @param {String} $style - The key for the variant.
|
121
|
+
// @return {List} The font family list.
|
122
|
+
|
123
|
+
@function type-family($style) {
|
124
|
+
$family-key: map-get($type-family-keys-data, $style);
|
125
|
+
$fetched-value: map-get($type-family-data, $family-key);
|
126
|
+
|
127
|
+
@if $fetched-value != null {
|
128
|
+
@return $fetched-value;
|
129
|
+
} @else {
|
130
|
+
@error "Type family `#{$style}` not found. Available families: #{available-names($type-family-keys-data)}";
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
@mixin emphasized-text {
|
137
|
+
font-weight: type-weight(emphasized);
|
138
|
+
}
|
139
|
+
|
140
|
+
@mixin meta-text {
|
141
|
+
font-size: type-size(meta);
|
142
|
+
line-height: type-line-height(meta);
|
143
|
+
font-weight: type-weight(meta);
|
144
|
+
color: color(text, secondary);
|
145
|
+
}
|
146
|
+
|
147
|
+
@mixin body-text {
|
148
|
+
font-size: type-size(body);
|
149
|
+
line-height: type-line-height(body);
|
150
|
+
font-weight: type-weight(body);
|
151
|
+
color: color(text, primary);
|
152
|
+
}
|
153
|
+
|
154
|
+
@mixin section-title {
|
155
|
+
font-size: type-size(section-title);
|
156
|
+
line-height: type-line-height(section-title);
|
157
|
+
font-weight: type-weight(section-title);
|
158
|
+
color: color(text, primary);
|
159
|
+
}
|
160
|
+
|
161
|
+
@mixin page-title {
|
162
|
+
font-size: type-size(page-title);
|
163
|
+
line-height: type-line-height(page-title);
|
164
|
+
font-weight: type-weight(page-title);
|
165
|
+
color: color(text, primary);
|
166
|
+
}
|
167
|
+
|
168
|
+
@mixin display-title {
|
169
|
+
font-size: type-size(display-title);
|
170
|
+
line-height: type-line-height(display-title);
|
171
|
+
font-weight: type-weight(display-title);
|
172
|
+
color: color(text, primary);
|
173
|
+
}
|
174
|
+
|
175
|
+
@mixin error-text {
|
176
|
+
color: color(text, error);
|
177
|
+
}
|
178
|
+
|
179
|
+
@mixin succes-text {
|
180
|
+
color: color(text, success);
|
181
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
$base-size: 10px;
|
2
|
+
|
3
|
+
//*
|
4
|
+
// Returns the value in rem for a given pixel value.
|
5
|
+
//
|
6
|
+
// @param {Number} $value - The pixel value to be converted.
|
7
|
+
// @return {Number} The converted value in rem.
|
8
|
+
|
9
|
+
@function rem($value) {
|
10
|
+
@if unit($value) != 'px' {
|
11
|
+
@error 'Value must be in px.';
|
12
|
+
}
|
13
|
+
|
14
|
+
@return $value / $base-size * 1rem;
|
15
|
+
}
|
16
|
+
|
17
|
+
//*
|
18
|
+
// Returns the value in pixels for a given rem value.
|
19
|
+
//
|
20
|
+
// @param {Number} $value - The rem value to be converted.
|
21
|
+
// @return {Number} The converted value in pixels.
|
22
|
+
|
23
|
+
@function px($value) {
|
24
|
+
@if unit($value) != 'rem' {
|
25
|
+
@error 'Value must be in rem.';
|
26
|
+
}
|
27
|
+
|
28
|
+
@return ($value / 1rem) * $base-size;
|
29
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
//*
|
2
|
+
// Returns the list of available names in a given map.
|
3
|
+
//
|
4
|
+
// @param {Map} $map - The map of data to list the names from.
|
5
|
+
// @param {Number} $map - The level of depth to get names from.
|
6
|
+
// @return {String} The list of names in the map.
|
7
|
+
|
8
|
+
@function available-names($map, $level: 1) {
|
9
|
+
@if type-of($map) != 'map' { @return null; }
|
10
|
+
|
11
|
+
$output: '';
|
12
|
+
$newline: '\A ';
|
13
|
+
|
14
|
+
@if $level == 1 {
|
15
|
+
@each $key, $value in $map {
|
16
|
+
$output: $output + '#{$newline}- #{$key} #{available-names($value, $level + 1)}';
|
17
|
+
}
|
18
|
+
} @else {
|
19
|
+
$output: '(';
|
20
|
+
$i: 1;
|
21
|
+
|
22
|
+
@each $key, $value in $map {
|
23
|
+
$sep: if($i < length($map), ', ', '');
|
24
|
+
$output: $output + '#{$key}#{$sep}#{available-names($value, $level + 1)}';
|
25
|
+
$i: $i + 1;
|
26
|
+
}
|
27
|
+
|
28
|
+
$output: $output + ')';
|
29
|
+
}
|
30
|
+
|
31
|
+
@return $output;
|
32
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.type-container {
|
2
|
+
@include vertical-rhythm;
|
3
|
+
}
|
4
|
+
|
5
|
+
.body-text {
|
6
|
+
@include body-text;
|
7
|
+
}
|
8
|
+
|
9
|
+
.meta-text {
|
10
|
+
@include meta-text;
|
11
|
+
}
|
12
|
+
|
13
|
+
.section-title {
|
14
|
+
@include section-title;
|
15
|
+
}
|
16
|
+
|
17
|
+
.page-title {
|
18
|
+
@include page-title;
|
19
|
+
}
|
20
|
+
|
21
|
+
.display-title {
|
22
|
+
@include display-title;
|
23
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
@import 'global/typography';
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative './component.rb'
|
2
|
+
|
3
|
+
module Quilt
|
4
|
+
module UIHelper
|
5
|
+
def ui_badge(content_or_args = nil, **args, &block)
|
6
|
+
if content_or_args.is_a?(Hash)
|
7
|
+
args = content_or_args
|
8
|
+
else
|
9
|
+
content = content_or_args
|
10
|
+
args ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
Badge.new(self, **args).render(content, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
class Badge < Component
|
17
|
+
base_css_class 'badge'
|
18
|
+
variant :inline, accepts: [true, false]
|
19
|
+
variant :status, converts: :to_s, accepts: %w(subdued info success attention warning critical complete)
|
20
|
+
|
21
|
+
def render(content, &block)
|
22
|
+
ui_content_tag(:span, content, options, class: variant_classes, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'smart_properties'
|
2
|
+
|
3
|
+
module Quilt
|
4
|
+
module UIHelper
|
5
|
+
class Component < SimpleDelegator
|
6
|
+
# rubocop:disable Alias
|
7
|
+
alias view_context __getobj__
|
8
|
+
# rubocop:enable Alias
|
9
|
+
|
10
|
+
include SmartProperties
|
11
|
+
|
12
|
+
def self.fallback
|
13
|
+
Fallback.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.with_airbag
|
17
|
+
Airbag.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.variants
|
21
|
+
parent_variants = defined?(super) ? super : {}
|
22
|
+
(parent_variants || {}).merge(@variants || {})
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.variant(name, accepts: [true, false], **options)
|
26
|
+
@variants ||= {}
|
27
|
+
@variants[name] = Variant.new(name.to_s.dasherize, Set.new(accepts))
|
28
|
+
property name, accepts: accepts, **options
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.base_css_class(class_name)
|
32
|
+
define_method(:base_css_class) { class_name }
|
33
|
+
end
|
34
|
+
|
35
|
+
property :options, accepts: Hash, default: {}, required: true
|
36
|
+
|
37
|
+
def initialize(view_context, **args)
|
38
|
+
class_properties = self.class.properties.keys
|
39
|
+
valid_args = args.slice(*class_properties)
|
40
|
+
options = args.except(*class_properties)
|
41
|
+
|
42
|
+
super(view_context, options: options, **valid_args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def base_css_class
|
46
|
+
raise NotImplementedError, 'You need to define a base_css_class method for your component'
|
47
|
+
end
|
48
|
+
|
49
|
+
def render
|
50
|
+
raise NotImplementedError, 'You must implement a render method'
|
51
|
+
end
|
52
|
+
|
53
|
+
def variant_classes(*additional_classes)
|
54
|
+
classes = self.class.variants.reduce([base_css_class]) do |matched_classes, (variant_name, variant)|
|
55
|
+
if self[variant_name]
|
56
|
+
matched_classes << "#{base_css_class}--#{variant.boolean? ? variant.name : self[variant_name]}"
|
57
|
+
else
|
58
|
+
matched_classes
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
[classes, additional_classes].flatten.compact
|
63
|
+
end
|
64
|
+
|
65
|
+
def ui_content_tag(name, *content_or_additional_options, **base_options, &block)
|
66
|
+
additional_options = content_or_additional_options.last.is_a?(Hash) ? content_or_additional_options.pop : {}
|
67
|
+
|
68
|
+
content = if block_given?
|
69
|
+
capture(&block)
|
70
|
+
else
|
71
|
+
Array(content_or_additional_options).compact.inject(''.html_safe, :<<)
|
72
|
+
end
|
73
|
+
|
74
|
+
options = base_options.merge(additional_options) do |key, base_value, additional_value|
|
75
|
+
case key
|
76
|
+
when :class
|
77
|
+
Array(base_value) + Array(additional_value)
|
78
|
+
else
|
79
|
+
additional_value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
content.blank? ? ''.html_safe : content_tag(name, options) { content }
|
84
|
+
end
|
85
|
+
|
86
|
+
class Variant < Struct.new(:name, :values)
|
87
|
+
BOOLEAN = Set.new([true, false]).freeze
|
88
|
+
|
89
|
+
def boolean?
|
90
|
+
values == BOOLEAN
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Airbag < SimpleDelegator
|
95
|
+
# rubocop:disable Alias
|
96
|
+
alias component_class __getobj__
|
97
|
+
# rubocop:enable Alias
|
98
|
+
|
99
|
+
def new(*args, **attrs, &block)
|
100
|
+
component_class.new(*args, **attrs, &block)
|
101
|
+
rescue SmartProperties::AssignmentError => error
|
102
|
+
raise if Rails.env.development? || Rails.env.test?
|
103
|
+
Bugsnag.notify(FallbackWarning.new(error))
|
104
|
+
component_class.fallback(*args, **attrs, &block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class Fallback
|
109
|
+
def render(*)
|
110
|
+
''.html_safe
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class FallbackWarning < RuntimeError; end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/quilt/engine.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Quilt.helpers.each { |helper| require helper }
|
2
|
+
|
3
|
+
module Quilt
|
4
|
+
class Engine < Rails::Engine
|
5
|
+
config.assets.paths << File.expand_path('../../../assets/stylesheets', __FILE__)
|
6
|
+
config.assets.paths << File.expand_path('../../../assets/javascripts', __FILE__)
|
7
|
+
|
8
|
+
ActiveSupport.on_load :action_view do
|
9
|
+
include Quilt::UIHelper
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/quilt_ui.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'quilt/version'
|
2
|
+
|
3
|
+
module Quilt
|
4
|
+
def self.root
|
5
|
+
@root ||= Pathname.new(File.dirname(File.expand_path('..', __FILE__)))
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.helpers
|
9
|
+
Dir.glob(root + 'helpers/**/*.rb')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'quilt/engine' if defined?(Rails)
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: quilt_ui
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Sauve
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: smart_properties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.0.0
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- chris.sauve@shopify.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- assets/javascripts/quilt.js
|
49
|
+
- assets/stylesheets/quilt.scss
|
50
|
+
- assets/stylesheets/quilt/components.scss
|
51
|
+
- assets/stylesheets/quilt/components/badge.scss
|
52
|
+
- assets/stylesheets/quilt/foundation.scss
|
53
|
+
- assets/stylesheets/quilt/foundation/colors.scss
|
54
|
+
- assets/stylesheets/quilt/foundation/defaults.scss
|
55
|
+
- assets/stylesheets/quilt/foundation/spacing.scss
|
56
|
+
- assets/stylesheets/quilt/foundation/typography.scss
|
57
|
+
- assets/stylesheets/quilt/foundation/utilities.scss
|
58
|
+
- assets/stylesheets/quilt/foundation/utilities/lengths.scss
|
59
|
+
- assets/stylesheets/quilt/foundation/utilities/maps.scss
|
60
|
+
- assets/stylesheets/quilt/global.scss
|
61
|
+
- assets/stylesheets/quilt/global/typography.scss
|
62
|
+
- helpers/components/badge.rb
|
63
|
+
- helpers/components/component.rb
|
64
|
+
- lib/quilt/engine.rb
|
65
|
+
- lib/quilt/version.rb
|
66
|
+
- lib/quilt_ui.rb
|
67
|
+
homepage:
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.5.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: All of Shopify’s core assets.
|
91
|
+
test_files: []
|