docks_theme_api 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +15 -0
  2. data/.babelrc +4 -0
  3. data/.editorconfig +8 -0
  4. data/.eslintrc +115 -0
  5. data/.gitignore +24 -0
  6. data/.rubocop.yml +20 -0
  7. data/.travis.yml +16 -0
  8. data/Gemfile +4 -0
  9. data/README.md +5 -0
  10. data/Rakefile +3 -0
  11. data/assets/images/icons.svg +63 -0
  12. data/assets/scripts/coffeescript/pattern_library_helpers.coffee +8 -0
  13. data/assets/scripts/javascript/pattern_library_helpers.js +11 -0
  14. data/assets/scripts/pattern_library.js +10380 -0
  15. data/assets/scripts/pattern_library_demo.js +0 -0
  16. data/assets/styles/less/pattern-library-helpers.less +103 -0
  17. data/assets/styles/pattern-library-demo.css +1882 -0
  18. data/assets/styles/pattern-library.css +1882 -0
  19. data/assets/styles/sass/pattern-library-helpers.sass +90 -0
  20. data/assets/styles/scss/pattern-library-helpers.scss +99 -0
  21. data/assets/styles/stylus/pattern-library-helpers.styl +90 -0
  22. data/assets/templates/erb/demo.erb +26 -0
  23. data/assets/templates/erb/layouts/demo.erb +17 -0
  24. data/assets/templates/erb/layouts/pattern.erb +76 -0
  25. data/assets/templates/erb/partials/sidebar.erb +124 -0
  26. data/assets/templates/erb/partials/symbols/class.erb +1 -0
  27. data/assets/templates/erb/partials/symbols/demo.erb +40 -0
  28. data/assets/templates/erb/partials/symbols/factory.erb +70 -0
  29. data/assets/templates/erb/partials/symbols/function.erb +103 -0
  30. data/assets/templates/erb/partials/symbols/mixin.erb +62 -0
  31. data/assets/templates/erb/partials/symbols/variable.erb +59 -0
  32. data/assets/templates/erb/pattern.erb +102 -0
  33. data/assets/templates/haml/demo.haml +14 -0
  34. data/assets/templates/haml/layouts/demo.haml +6 -0
  35. data/assets/templates/haml/layouts/pattern.haml +38 -0
  36. data/assets/templates/haml/partials/sidebar.haml +68 -0
  37. data/assets/templates/haml/partials/symbols/class.haml +1 -0
  38. data/assets/templates/haml/partials/symbols/demo.haml +23 -0
  39. data/assets/templates/haml/partials/symbols/factory.haml +38 -0
  40. data/assets/templates/haml/partials/symbols/function.haml +54 -0
  41. data/assets/templates/haml/partials/symbols/mixin.haml +31 -0
  42. data/assets/templates/haml/partials/symbols/variable.haml +22 -0
  43. data/assets/templates/haml/pattern.haml +54 -0
  44. data/assets/templates/slim/demo.slim +24 -0
  45. data/assets/templates/slim/layouts/demo.slim +5 -0
  46. data/assets/templates/slim/layouts/pattern.slim +48 -0
  47. data/assets/templates/slim/partials/sidebar.slim +112 -0
  48. data/assets/templates/slim/partials/symbols/class.slim +1 -0
  49. data/assets/templates/slim/partials/symbols/demo.slim +30 -0
  50. data/assets/templates/slim/partials/symbols/factory.slim +57 -0
  51. data/assets/templates/slim/partials/symbols/function.slim +81 -0
  52. data/assets/templates/slim/partials/symbols/mixin.slim +45 -0
  53. data/assets/templates/slim/partials/symbols/variable.slim +35 -0
  54. data/assets/templates/slim/pattern.slim +63 -0
  55. data/docks_config.rb +32 -0
  56. data/docks_theme_api.gemspec +37 -0
  57. data/gulpfile.js +88 -0
  58. data/karma.conf.js +6 -0
  59. data/lib/docks_theme_api/components/base_component.rb +99 -0
  60. data/lib/docks_theme_api/components/code_block_component.rb +10 -0
  61. data/lib/docks_theme_api/components/popover_component.rb +15 -0
  62. data/lib/docks_theme_api/components/table_component.rb +34 -0
  63. data/lib/docks_theme_api/components/tablist_component.rb +11 -0
  64. data/lib/docks_theme_api/components.rb +21 -0
  65. data/lib/docks_theme_api/helpers/ui_helper.rb +69 -0
  66. data/lib/docks_theme_api/theme.rb +21 -0
  67. data/lib/docks_theme_api.rb +1 -0
  68. data/package.json +60 -0
  69. data/source/behaviors/filterable/filterable.coffee +353 -0
  70. data/source/behaviors/filterable/filterable.js +0 -0
  71. data/source/behaviors/filterable/filterable.scss +34 -0
  72. data/source/behaviors/filterable/package.json +3 -0
  73. data/source/behaviors/index.js +0 -0
  74. data/source/components/avatar/avatar.erb +20 -0
  75. data/source/components/avatar/avatar.js +142 -0
  76. data/source/components/avatar/avatar.scss +200 -0
  77. data/source/components/avatar/avatar_container.erb +13 -0
  78. data/source/components/avatar/package.json +3 -0
  79. data/source/components/avatar/spec/avatar_spec.js +81 -0
  80. data/source/components/badge/badge.scss +158 -0
  81. data/source/components/button/button.scss +213 -0
  82. data/source/components/card/card.scss +32 -0
  83. data/source/components/code_block/code-block.scss +353 -0
  84. data/source/components/code_block/code_block.erb +95 -0
  85. data/source/components/code_block/code_block.js +444 -0
  86. data/source/components/code_block/package.json +3 -0
  87. data/source/components/code_block/spec/code_block_spec.js +10 -0
  88. data/source/components/demo/demo.js +244 -0
  89. data/source/components/demo/demo.scss +90 -0
  90. data/source/components/demo/package.json +3 -0
  91. data/source/components/exploded/exploded.erb +25 -0
  92. data/source/components/exploded/exploded.js +694 -0
  93. data/source/components/exploded/exploded.scss +166 -0
  94. data/source/components/exploded/package.json +3 -0
  95. data/source/components/field/field.js +24 -0
  96. data/source/components/field/field.scss +101 -0
  97. data/source/components/field/package.json +3 -0
  98. data/source/components/header/header.scss +33 -0
  99. data/source/components/iframe/iframe.erb +12 -0
  100. data/source/components/iframe/iframe.js +381 -0
  101. data/source/components/iframe/package.json +3 -0
  102. data/source/components/index.js +37 -0
  103. data/source/components/inline_group/inline-group.scss +14 -0
  104. data/source/components/internal_link/internal_link.js +49 -0
  105. data/source/components/internal_link/package.json +3 -0
  106. data/source/components/list/list.scss +230 -0
  107. data/source/components/modal/modal.coffee +84 -0
  108. data/source/components/modal/modal.erb +19 -0
  109. data/source/components/modal/modal.js +0 -0
  110. data/source/components/modal/modal.scss +57 -0
  111. data/source/components/modal/package.json +3 -0
  112. data/source/components/notice/notice.scss +48 -0
  113. data/source/components/popover/package.json +3 -0
  114. data/source/components/popover/popover.coffee +562 -0
  115. data/source/components/popover/popover.erb +21 -0
  116. data/source/components/popover/popover.js +0 -0
  117. data/source/components/popover/popover.scss +139 -0
  118. data/source/components/range/range.scss +78 -0
  119. data/source/components/resizable/package.json +3 -0
  120. data/source/components/resizable/resizable.erb +30 -0
  121. data/source/components/resizable/resizable.js +250 -0
  122. data/source/components/resizable/resizable.scss +245 -0
  123. data/source/components/resizable/size_buttons.js +249 -0
  124. data/source/components/scroll_container/package.json +3 -0
  125. data/source/components/scroll_container/scroll-container.scss +4 -0
  126. data/source/components/scroll_container/scroll_container.js +24 -0
  127. data/source/components/section/section.scss +99 -0
  128. data/source/components/select/package.json +3 -0
  129. data/source/components/select/select.erb +21 -0
  130. data/source/components/select/select.js +35 -0
  131. data/source/components/select/select.scss +163 -0
  132. data/source/components/table/package.json +3 -0
  133. data/source/components/table/table.erb +16 -0
  134. data/source/components/table/table.js +351 -0
  135. data/source/components/table/table.scss +236 -0
  136. data/source/components/tablist/package.json +3 -0
  137. data/source/components/tablist/tablist.erb +13 -0
  138. data/source/components/tablist/tablist.js +246 -0
  139. data/source/components/tablist/tablist.scss +191 -0
  140. data/source/components/tablist/tablist_panel.erb +14 -0
  141. data/source/components/tablist/tablist_tab.erb +20 -0
  142. data/source/components/toggle/package.json +3 -0
  143. data/source/components/toggle/toggle.erb +11 -0
  144. data/source/components/toggle/toggle.js +211 -0
  145. data/source/components/toggle/toggle_container.erb +30 -0
  146. data/source/components/vertical_spacer/vertical-spacer.scss +3 -0
  147. data/source/components/vertical_stack/vertical-stack.scss +19 -0
  148. data/source/components/xray/package.json +3 -0
  149. data/source/components/xray/xray.erb +50 -0
  150. data/source/components/xray/xray.js +123 -0
  151. data/source/components/xray/xray.scss +79 -0
  152. data/source/foundation/app/app.js +15 -0
  153. data/source/foundation/app/package.json +3 -0
  154. data/source/pattern-library-demo.scss +13 -0
  155. data/source/pattern-library.scss +13 -0
  156. data/source/pattern_library.js +8 -0
  157. data/source/pattern_library_demo.js +8 -0
  158. data/source/structures/index.js +11 -0
  159. data/source/structures/sidebar/package.json +3 -0
  160. data/source/structures/sidebar/sidebar.js +69 -0
  161. data/source/structures/sidebar/sidebar.scss +79 -0
  162. data/source/utilities/builder/builder.js +138 -0
  163. data/source/utilities/builder/package.json +3 -0
  164. data/source/utilities/client/client.js +7 -0
  165. data/source/utilities/client/package.json +3 -0
  166. data/source/utilities/colors/colors.scss +112 -0
  167. data/source/utilities/defaults/defaults.scss +38 -0
  168. data/source/utilities/dom_cache/dom_cache.js +24 -0
  169. data/source/utilities/dom_cache/package.json +3 -0
  170. data/source/utilities/events/events.js +25 -0
  171. data/source/utilities/events/package.json +3 -0
  172. data/source/utilities/font_sizes/font-sizes.scss +85 -0
  173. data/source/utilities/foundation/a11y.scss +10 -0
  174. data/source/utilities/foundation/base.scss +29 -0
  175. data/source/utilities/foundation/icon.scss +114 -0
  176. data/source/utilities/foundation/layout.scss +67 -0
  177. data/source/utilities/foundation/page.scss +39 -0
  178. data/source/utilities/foundation/type.scss +208 -0
  179. data/source/utilities/functions/functions.scss +127 -0
  180. data/source/utilities/keycodes/keycodes.js +23 -0
  181. data/source/utilities/keycodes/package.json +3 -0
  182. data/source/utilities/markup/markup.js +90 -0
  183. data/source/utilities/markup/package.json +3 -0
  184. data/source/utilities/media/media.scss +172 -0
  185. data/source/utilities/mixins/mixins.scss +89 -0
  186. data/source/utilities/naming_convention/naming_convention.js +3 -0
  187. data/source/utilities/naming_convention/package.json +3 -0
  188. data/source/utilities/numbers/numbers.js +14 -0
  189. data/source/utilities/numbers/package.json +3 -0
  190. data/source/utilities/painting/package.json +3 -0
  191. data/source/utilities/painting/painting.js +7 -0
  192. data/source/utilities/pattern/package.json +3 -0
  193. data/source/utilities/pattern/pattern.js +50 -0
  194. data/source/utilities/query_string/package.json +3 -0
  195. data/source/utilities/query_string/query_string.js +24 -0
  196. data/source/utilities/template/package.json +3 -0
  197. data/source/utilities/template/template.js +10 -0
  198. data/source/utilities/text_range/package.json +3 -0
  199. data/source/utilities/text_range/text_range.js +30 -0
  200. data/source/utilities/ui_events/package.json +3 -0
  201. data/source/utilities/ui_events/ui_events.js +85 -0
  202. data/source/utilities/variables/variables.scss +18 -0
  203. data/source/utilities/z_indexes/z-indexes.scss +88 -0
  204. data/source/vendor/array_includes.js +28 -0
  205. data/source/vendor/highlight.js +1142 -0
  206. data/source/vendor/index.js +1 -0
  207. data/source/vendor/matrix.js +399 -0
  208. data/source/vendor/query_string.js +66 -0
  209. data/spec/assets/.eslintrc +9 -0
  210. data/spec/assets/spec_fixture.js +33 -0
  211. data/spec/assets/spec_helper.js +19 -0
  212. data/spec/lib/components/base_component_spec.rb +156 -0
  213. data/spec/lib/components_spec.rb +30 -0
  214. data/spec/lib/helpers/ui_helper_spec.rb +62 -0
  215. data/spec/lib/theme_spec.rb +25 -0
  216. data/spec/spec_helper.rb +15 -0
  217. data/tasks/gulp/.eslintrc +6 -0
  218. data/tasks/gulp/browser_sync.js +8 -0
  219. data/tasks/gulp/code_quality/scripts.js +10 -0
  220. data/tasks/gulp/config/index.js +116 -0
  221. data/tasks/gulp/minify/scripts.js +13 -0
  222. data/tasks/gulp/minify/styles.js +13 -0
  223. data/tasks/gulp/pattern_library/index.js +5 -0
  224. data/tasks/gulp/pattern_library/scripts.js +10 -0
  225. data/tasks/gulp/pattern_library/styles.js +10 -0
  226. data/tasks/gulp/scripts.js +8 -0
  227. data/tasks/gulp/spec/scripts.js +11 -0
  228. data/tasks/gulp/styles.js +17 -0
  229. data/tasks/gulp/utilities/babel/relative_require.js +22 -0
  230. data/tasks/gulp/utilities/babel/spec_helper.js +20 -0
  231. data/tasks/gulp/utilities/browserify_bundler.js +22 -0
  232. data/tasks/gulp/utilities/handle_errors.js +13 -0
  233. data/tasks/gulp/watch.js +9 -0
  234. data/tasks/rake/rspec.rake +7 -0
  235. data/tasks/rake/rubocop.rake +8 -0
  236. data/tasks/rake/templates.rake +50 -0
  237. metadata +470 -0
@@ -0,0 +1,245 @@
1
+ // ___ ___ ___ ___ ___
2
+ // / /\ / /\ / /\ ___ / /\ / /\
3
+ // / /::\ / /:/_ / /:/_ / /\ / /::| / /:/_
4
+ // / /:/\:\ / /:/ /\ / /:/ /\ / /:/ / /:/:| / /:/ /\
5
+ // / /:/~/:/ / /:/ /:/_ / /:/ /::\ /__/::\ / /:/|:|__ / /:/ /:/_
6
+ // /__/:/ /:/___/__/:/ /:/ /\/__/:/ /:/\:\\__\/\:\__ /__/:/ |:| /\/__/:/ /:/ /\
7
+ // \ \:\/:::::/\ \:\/:/ /:/\ \:\/:/~/:/ \ \:\/\\__\/ |:|/:/\ \:\/:/ /:/
8
+ // \ \::/~~~~ \ \::/ /:/ \ \::/ /:/ \__\::/ | |:/:/ \ \::/ /:/
9
+ // \ \:\ \ \:\/:/ \__\/ /:/ /__/:/ | |::/ \ \:\/:/
10
+ // \ \:\ \ \::/ /__/:/ \__\/ | |:/ \ \::/
11
+ // \__\/ \__\/ \__\/ |__|/ \__\/
12
+
13
+ //*
14
+ // @pattern Resizable
15
+ //
16
+ // A container that can be resized by dragging on a handle
17
+ // (`.resizable__handle`) with a contained iframe that shows the actual demo
18
+ // content. This allows the user to see how the design would actually behave
19
+ // at different viewport widths, and allows for fixed and absolute positioned
20
+ // elements to be displayed in a reasonable way.
21
+ //
22
+ // The JavaScript portion of this component manages the communication of
23
+ // height changes from the `iframe` to make sure that the demo is entirely
24
+ // visible and shows the current width and allows the user to see a small
25
+ // number of preset widths.
26
+ //
27
+ // @since 1.0.0
28
+
29
+
30
+
31
+ $resizable--min-width: 18rem;
32
+ $resizable--border: 1px solid ui-color(gray, darker);
33
+ $resizable--default-transition-timing: 0.3s ease;
34
+
35
+ $resizable__handle--width: 1.25rem;
36
+ $resizable__handle--groove-height: double(default(spacing));
37
+ $resizable__handle--groove-percentage-width: 0.35;
38
+
39
+ $resizable__size-button__icon--size: 1.8rem;
40
+
41
+
42
+
43
+ //*
44
+ // The core component of a `Resizable`. This part of the component contains
45
+ // the handle and `iframe`, and is the part of the component that is actually
46
+ // resized when dragging the handle/ using the size buttons. The `min-width`
47
+ // specified here should account for both the `min-width` of the content *and*
48
+ // the width of the handle (which will be positioned absolutely over the right
49
+ // side).
50
+ //
51
+ // @helper docks_resizable
52
+
53
+ .resizable {
54
+ // position
55
+ position: relative;
56
+
57
+ // box model
58
+ margin: 0 auto;
59
+ width: 100%;
60
+ min-width: ($resizable--min-width + $resizable__handle--width);
61
+
62
+ // backdrop
63
+ @include default(border-radius);
64
+
65
+ // type
66
+ line-height: 0;
67
+
68
+ > .card {
69
+ position: relative;
70
+ padding-right: $resizable__handle--width;
71
+ }
72
+
73
+ .iframe {
74
+ width: 100%;
75
+ min-height: 10rem;
76
+ transition: height $resizable--default-transition-timing;
77
+ overflow: hidden;
78
+ }
79
+ }
80
+
81
+ //*
82
+ // Provides a transition that smoothly moves the resizable container from one
83
+ // width to the next. This is not done by default as dragging the handle would
84
+ // appear broken.
85
+
86
+ .resizable--is-transitioning-width {
87
+ transition: width $resizable--default-transition-timing;
88
+ }
89
+
90
+
91
+
92
+ //*
93
+ // The handle by which to resize the container. Default style gives two small
94
+ // grooves in the middle of the handle that affords its draggability.
95
+
96
+ .resizable__handle {
97
+ // position
98
+ position: absolute;
99
+ top: 0; right: 0;
100
+
101
+ // box model
102
+ width: $resizable__handle--width;
103
+ height: 100%;
104
+
105
+ // backdrop
106
+ cursor: col-resize;
107
+ background: ui-color(gray, dark);
108
+ border-radius: 0 default(border-radius) default(border-radius) 0;
109
+
110
+ &:hover,
111
+ &:focus {
112
+ outline: none;
113
+ }
114
+
115
+ &:after {
116
+ $resizable__handle--groove-width: $resizable__handle--groove-percentage-width * $resizable__handle--width;
117
+
118
+ content: "";
119
+
120
+ // position
121
+ position: absolute;
122
+ top: 50%; left: 50%;
123
+
124
+ // box model
125
+ display: block;
126
+ height: $resizable__handle--groove-height;
127
+ width: $resizable__handle--groove-width;
128
+ margin-top: negative(half($resizable__handle--groove-height));
129
+ margin-left: negative(half($resizable__handle--groove-width));
130
+
131
+ // backdrop
132
+ border-right: $resizable--border;
133
+ border-left: $resizable--border;
134
+ }
135
+ }
136
+
137
+
138
+
139
+ //*
140
+ // A container for all of the information and acions available for the
141
+ // component.
142
+
143
+ .resizable__actions {
144
+ display: flex;
145
+ justify-content: space-between;
146
+ align-items: flex-end;
147
+ margin-bottom: half(default(spacing));
148
+ }
149
+
150
+
151
+
152
+
153
+ //*
154
+ // A small notice that shows the current width of the (content of the) resizable
155
+ // module. This indicator slides in when the size changes (through the use of
156
+ // the `resizable__width-indicator--is-visible` variant).
157
+ //
158
+ // The indicator shows the width in both `px` and `em` values which are
159
+ // contained in the submodules `resizable__width-indicator__px` and
160
+ // `resizable__width-indicator__em`, respectively.
161
+ //
162
+ // @state --is-visible - The indicator is currently being shown.
163
+
164
+ .resizable__width-indicator {
165
+ // type
166
+ color: color(gray-dark);
167
+ font: 300 1rem/1 Consolas, monospace;;
168
+
169
+ // backdrop
170
+ opacity: 0.4;
171
+ transition: opacity $resizable--default-transition-timing;
172
+ }
173
+
174
+ .resizable__width-indicator--is-visible { opacity: 1; }
175
+
176
+
177
+
178
+ //*
179
+ // A vertically-oriented set of buttons that resize the resizable module to
180
+ // predetermined widths. These widths have been set in the Javascript part of
181
+ // this module.
182
+
183
+ .resizable__size-buttons {
184
+ display: flex;
185
+ }
186
+
187
+
188
+
189
+ //*
190
+ // A single button that resizes the module.
191
+ //
192
+ // @state --is-active (select)
193
+ // Indicates that this button has been pressed and that the user has not
194
+ // subsequently resized the module in some other way.
195
+ //
196
+ // @state --is-hidden (none)
197
+ // Indicates that the button should be hidden because not enough screen space
198
+ // exists for its resize.
199
+ //
200
+ // @variant --small (none) - Resizes to a roughly smartphone-sized width.
201
+ // @variant --medium (none) - Resizes to a roughly tablet-sized width.
202
+ // @variant --large (none) - Resizes to a roughly desktop-sized width.
203
+
204
+ .resizable__size-button {
205
+ position: relative;
206
+ margin-left: half(default(spacing));
207
+ cursor: pointer;
208
+
209
+ opacity: 0.5;
210
+ transition: opacity $resizable--default-transition-timing;
211
+
212
+ > .icon {
213
+ height: $resizable__size-button__icon--size;
214
+ width: $resizable__size-button__icon--size;
215
+
216
+ @include icon--recolor(gray);
217
+ transition: fill $resizable--default-transition-timing;
218
+ }
219
+
220
+ &:hover,
221
+ &:focus,
222
+ &:active,
223
+ &.resizable__size-button--is-active {
224
+ outline: none;
225
+ }
226
+
227
+ &:hover,
228
+ &:focus {
229
+ opacity: 0.8;
230
+ }
231
+
232
+ &.resizable__size-button--is-active,
233
+ &:active {
234
+ opacity: 1;
235
+
236
+ > .icon {
237
+ fill: color(blue);
238
+ stroke: color(blue);
239
+ }
240
+ }
241
+ }
242
+
243
+ .resizable__size-button--is-hidden {
244
+ display: none;
245
+ }
@@ -0,0 +1,249 @@
1
+ import Resizable from "./resizable";
2
+ import Builder from "~utilities/builder";
3
+ import Keycodes from "~utilities/keycodes";
4
+
5
+ var SizeButtons,
6
+ SizeRelationships, click_size_button, next_unhidden_size_button,
7
+ previous_unhidden_size_button, key_on_size_button;
8
+
9
+ const classes = {
10
+ root: "resizable__size-button",
11
+ container: "resizable__size-buttons"
12
+ };
13
+
14
+ const states = {
15
+ root: {
16
+ hidden: "resizable__size-button--is-hidden",
17
+ active: "resizable__size-button--is-active"
18
+ }
19
+ };
20
+
21
+ const attrs = {
22
+ button_size: "data-resizable-size-button-size",
23
+ size_to: "data-resizable-size-to"
24
+ };
25
+
26
+ SizeRelationships = {
27
+ SMALL: 320,
28
+ MEDIUM: 768,
29
+ LARGE: 960
30
+ };
31
+
32
+ // Attaches media queries for each of the size buttons to conditionally hide/
33
+ // show them depending on whether or not the size they want to generate is within
34
+ // the available space.
35
+ //
36
+ // @param {HTMLElement} button - The size button. It should have an
37
+ // `attrs.button_size` attribute, which determines
38
+ // what size they should make the component.
39
+ // @param {Number} size_adjustment - The difference in width between the viewport
40
+ // and the space available to the component.
41
+ //
42
+ // @private
43
+
44
+ // attach_media_listener_to_size_button = (button, size_adjustment = 0) => {
45
+ // var size = button.getAttribute(attrs.button_size),
46
+ // respond_width = SizeRelationships[size.toUpperCase()],
47
+ // listener, media_query;
48
+
49
+ // if(!respond_width) { return; }
50
+ // button.setAttribute(attrs.size_to, respond_width);
51
+
52
+ // listener = (mq) => {
53
+ // button.classList[mq.matches ? "remove" : "add"](states.size_button.hidden);
54
+ // };
55
+
56
+ // media_query = window.matchMedia(`(min-width: ${respond_width + size_adjustment}px)`);
57
+ // media_query.addListener(listener);
58
+ // listener(media_query);
59
+ // };
60
+
61
+ //*
62
+ // Captures a click even on a size button and sends the appropriate `set_width`
63
+ // method call to the associated `Resizable` component.
64
+ //
65
+ // @param {Object} event - The click event.
66
+ // @private
67
+
68
+ click_size_button = (event) => {
69
+ var button = $(event.target).closest(`.${classes.root}`);
70
+ SizeButtons.for(button).active_button = button;
71
+ };
72
+
73
+ //*
74
+ // Finds the next visible size button after the passed `button`. This is used
75
+ // for cycling through these buttons with the keyboard. This will cycle through
76
+ // all buttons in the list, wrapping around to the first buttons if no following
77
+ // buttons are visible. As a result, this method might return the same `button`
78
+ // that was passed (if it is the only visible size button).
79
+ //
80
+ // @param {HTMLElement} button - The current button (that the user is moving off
81
+ // of with the keyboard).
82
+ //
83
+ // @private
84
+ // @returns HTMLElement - The next visible size button within the `button`'s set.
85
+
86
+ next_unhidden_size_button = (button) => {
87
+ var sibling = button.nextElementSibling;
88
+
89
+ while(sibling) {
90
+ if(!sibling.classList.contains(states.size_button.hidden)) { return sibling; }
91
+ sibling = sibling.nextElementSibling;
92
+ }
93
+
94
+ for(sibling of Array.from(button.parentNode.children)) {
95
+ if(sibling === button) { break; }
96
+ if(!sibling.classList.contains(states.size_button.hidden)) { return sibling; }
97
+ }
98
+
99
+ return null;
100
+ };
101
+
102
+ //*
103
+ // Finds the previous visible size button after the passed `button`. This is used
104
+ // for cycling through these buttons with the keyboard. This will cycle through
105
+ // all buttons in the list, wrapping around to the last buttons if no previous
106
+ // buttons are visible. As a result, this method might return the same `button`
107
+ // that was passed (if it is the only visible size button).
108
+ //
109
+ // @param {HTMLElement} button - The current button (that the user is moving off
110
+ // of with the keyboard).
111
+ //
112
+ // @private
113
+ // @returns HTMLElement - The previous visible size button within the `button`'s
114
+ // set.
115
+
116
+ previous_unhidden_size_button = (button) => {
117
+ var sibling = button.previousElementSibling;
118
+
119
+ while(sibling) {
120
+ if(!sibling.classList.contains(states.size_button.hidden)) { return sibling; }
121
+ sibling = sibling.previousElementSibling;
122
+ }
123
+
124
+ for(sibling of Array.from(button.parentNode.children).reverse()) {
125
+ if(sibling === button) { break; }
126
+ if(!sibling.classList.contains(states.size_button.hidden)) { return sibling; }
127
+ }
128
+
129
+ return null;
130
+ };
131
+
132
+ //*
133
+ // Handles key presses on a size button. If the key is enter or space, the
134
+ // size button will be activated. If the key is an arrow key, this function will
135
+ // move focus to the correct sibling size button.
136
+ //
137
+ // @param {Object} event - The `keypress` event.
138
+ // @private
139
+
140
+ key_on_size_button = (event) => {
141
+ var button, new_button;
142
+
143
+ if(Keycodes.ACTIVATE.includes(event.which)) {
144
+ event.preventDefault();
145
+ click_size_button(event);
146
+ }
147
+
148
+ if(Keycodes.ARROWS.includes(event.which)) {
149
+ event.preventDefault();
150
+ button = $(event.target).closest(`.${classes.size_button}`)[0];
151
+ new_button = Keycodes.NEXT.includes(event.which) ?
152
+ next_unhidden_size_button(button) :
153
+ previous_unhidden_size_button(button);
154
+
155
+ if(new_button) {
156
+ SizeButtons.for(button).focused_button = new_button;
157
+ }
158
+ }
159
+ };
160
+
161
+ //*
162
+ // @factory
163
+
164
+ SizeButtons = (buttons) => {
165
+ var api,
166
+ associations, active_button, a11y, activate_button, focus_button,
167
+ activate_active_button, deactivate_active_button, size, a_button;
168
+
169
+ buttons = Array.from(buttons.children);
170
+ associations = {};
171
+ for(a_button of buttons) {
172
+ size = SizeRelationships[a_button.getAttribute(attrs.button_size)];
173
+ associations[size] = a_button;
174
+ }
175
+
176
+ a11y = {
177
+ focus(button) {
178
+ button.setAttribute("tabindex", "0");
179
+ button.focus();
180
+ },
181
+
182
+ blur(button) {
183
+ button.setAttribute("tabindex", "-1");
184
+ },
185
+
186
+ select(button) {
187
+ this.focus(button);
188
+ button.setAttribute("aria-selected", "true");
189
+ },
190
+
191
+ deselect(button) {
192
+ this.blur(button);
193
+ button.setAttribute("aria-selected", "false");
194
+ }
195
+ };
196
+
197
+ deactivate_active_button = () => {
198
+ if(!active_button) { return; }
199
+
200
+ a11y.deslect(active_button);
201
+ active_button.classList.remove(states.root.active);
202
+ };
203
+
204
+ activate_button = (button) => {
205
+ if(!buttons.includes(button) || active_button === button) { return active_button; }
206
+
207
+ deactivate_active_button();
208
+ active_button = button;
209
+ Resizable.for(button).set_width(parseInt(button.getAttribute(attrs.size_button), 10), { animated: true });
210
+ activate_active_button();
211
+ return active_button;
212
+ };
213
+
214
+ focus_button = (button) => {
215
+ a11y.focus(button);
216
+ return button;
217
+ };
218
+
219
+ activate_active_button = () => {
220
+ if(!active_button) { return; }
221
+
222
+ a11y.select(active_button);
223
+ active_button.classList.add(states.root.active);
224
+ };
225
+
226
+ api = {
227
+ set active_button(button) { return activate_button(button); },
228
+ get active_button() { return active_button; },
229
+ set focused_button(button) { return focus_button(button); },
230
+
231
+ try_size(new_size) {
232
+ deactivate_active_button();
233
+ active_button = associations[new_size];
234
+ activate_active_button();
235
+ }
236
+ };
237
+
238
+ return api;
239
+ };
240
+
241
+ SizeButtons.init = () => {
242
+ Builder.build_and_cache(SizeButtons, { name: classes.container });
243
+
244
+ $(document)
245
+ .on("click", `.${classes.root}`, click_size_button)
246
+ .on("keydown", `.${classes.root}`, key_on_size_button);
247
+ };
248
+
249
+ export default SizeButtons;
@@ -0,0 +1,3 @@
1
+ {
2
+ "main": "scroll_container.js"
3
+ }
@@ -0,0 +1,4 @@
1
+ .scroll-container {
2
+ // Contain any interior margins
3
+ overflow: hidden;
4
+ }
@@ -0,0 +1,24 @@
1
+ import Builder from "~utilities/builder";
2
+
3
+ const classes = {
4
+ root: "scroll-container"
5
+ };
6
+
7
+ var ScrollContainer;
8
+
9
+ ScrollContainer = (node) => {
10
+ var force_height = (height) => { node.style.minHeight = `${height}px`; };
11
+
12
+ return {
13
+ maintain_current_height() { force_height(node.offsetHeight); },
14
+ restore_height() { node.style.minHeight = null; },
15
+
16
+ scroll_to(contained_node) {
17
+ node.parentNode.scrollTop = contained_node.getBoundingClientRect().top - node.getBoundingClientRect().top;
18
+ }
19
+ };
20
+ };
21
+
22
+ ScrollContainer.init = Builder.initialize_once(ScrollContainer, { name: classes.root, cache: true });
23
+
24
+ export default ScrollContainer;
@@ -0,0 +1,99 @@
1
+ // ___ ___ ___ ___ ___
2
+ // / /\ / /\ / /\ ___ ___ / /\ /__/\
3
+ // / /:/_ / /:/_ / /:/ / /\/ /\ / /::\ \ \:\
4
+ // / /:/ /\ / /:/ /\ / /:/ / /:/ /:/ / /:/\:\ \ \:\
5
+ // / /:/ /::\ / /:/ /:/_ / /:/ ___ / /:/__/::\ / /:/ \:\ _____\__\:\
6
+ // /__/:/ /:/\:\/__/:/ /:/ /\/__/:/ / /\/ /::\__\/\:\__/__/:/ \__\:\/__/::::::::\
7
+ // \ \:\/:/~/:/\ \:\/:/ /:/\ \:\ / /:/__/:/\:\ \ \:\/\ \:\ / /:/\ \:\~~\~~\/
8
+ // \ \::/ /:/ \ \::/ /:/ \ \:\ /:/\__\/ \:\ \__\::/\ \:\ /:/ \ \:\ ~~~
9
+ // \__\/ /:/ \ \:\/:/ \ \:\/:/ \ \:\/__/:/ \ \:\/:/ \ \:\
10
+ // /__/:/ \ \::/ \ \::/ \__\/\__\/ \ \::/ \ \:\
11
+ // \__\/ \__\/ \__\/ \__\/ \__\/
12
+
13
+ //*
14
+ // @pattern Section
15
+ //
16
+ // Sections are simply ways of grouping related content and provising
17
+ // separation between that contained content and "sibling" content.
18
+ //
19
+ // Smaller variations are available for more condensed content, like content
20
+ // inside of a popover.
21
+ //
22
+ // @since 1.0.0
23
+
24
+
25
+
26
+ //*
27
+ // A container around some content that provides the vertical separation from
28
+ // other `section`s. This will also remove any top/ bottom padding from the
29
+ // first/ last child, respectively, to avoid more vertical padding than
30
+ // necessary.
31
+
32
+ .section {
33
+ margin: double(default(spacing)) 0;
34
+ padding: default(spacing) 0;
35
+
36
+ > *:first-child {
37
+ &,
38
+ & > *:first-child {
39
+ margin-top: 0;
40
+ }
41
+ }
42
+
43
+ > *:last-child {
44
+ &,
45
+ & > *:last-child {
46
+ margin-bottom: 0;
47
+ }
48
+ }
49
+ }
50
+
51
+ //*
52
+ // A smaller section with no border separating content. Use this variant for
53
+ // places where the base amount of vertical padding is excessive (for example,
54
+ // in popovers or other limited-width containers).
55
+
56
+ .section--small {
57
+ border: none;
58
+ padding: 0;
59
+ margin: default(spacing) 0;
60
+ }
61
+
62
+ //*
63
+ // A section with a light gray background that separates it visually from the
64
+ // other sections. Use this to differentiate between significantly different
65
+ // groups of content. It is best to only use this with `section--small` —
66
+ // regular `section`s already have sufficient separation in most cases.
67
+
68
+ .section--subdued {
69
+ background: color(gray-light);
70
+ overflow: hidden;
71
+
72
+ &.section--small {
73
+ padding: default(spacing) 0;
74
+ margin: 0;
75
+ }
76
+ }
77
+
78
+
79
+
80
+ //*
81
+ // Use this container for when you want a group of sections to have additional
82
+ // vertical separation from the content around it. The amount of additional
83
+ // space depends on whether the container contains regular or `--small`
84
+ // `section`s.
85
+ //
86
+ // This container is not necessary — for example, sections can sit on their own
87
+ // inside a popover.
88
+
89
+ .section__container {
90
+ > .section {
91
+ &:first-child { margin-top: double(default(spacing)); }
92
+ &:last-child { margin-bottom: double(default(spacing)); }
93
+ }
94
+
95
+ > .section--small {
96
+ &:first-child { margin-top: default(spacing); }
97
+ &:last-child { margin-bottom: default(spacing); }
98
+ }
99
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "main": "select.js"
3
+ }
@@ -0,0 +1,21 @@
1
+ <%
2
+ component.configure do |config|
3
+ config.defaults options: [],
4
+ name: "select",
5
+ id: "select",
6
+ code?: false
7
+
8
+ config.classes base: "select",
9
+ input: "select__input"
10
+
11
+ config.conditional_classes if: :code?, base: "select--code"
12
+ end
13
+ %>
14
+
15
+ <div class="<%= component.classes_for(:base) %>">
16
+ <select class="<%= component.classes_for(:input) %>" id="<%= component.id %>" name="<%= component.name %>">
17
+ <% component.options.each do |option| %>
18
+ <option><%= option %></option>
19
+ <% end %>
20
+ </select>
21
+ </div>
@@ -0,0 +1,35 @@
1
+ const classes = {
2
+ root: "select",
3
+ input: "select__input"
4
+ };
5
+
6
+ const states = {
7
+ root: { focused: `${classes.root}--is-focused` }
8
+ };
9
+
10
+ var Select, focus_or_blur_select;
11
+
12
+ //*
13
+ // Translates the `focus`/ `blur` events on the actual `select` node into the
14
+ // appropriate addition/ removal of the focused state on the base node of the
15
+ // component. This has to be done because most of the visual styling for the
16
+ // component is placed on the container, so any adjustments to those styles on
17
+ // focus require that container to be aware of the state of its contained
18
+ // `select`.
19
+ //
20
+ // @param {Object} event - The `focus`/ `blur` event on the `select`.
21
+ // @private
22
+
23
+ focus_or_blur_select = (event) => {
24
+ var method = event.type === "focusin" ? "add" : "remove";
25
+ $(event.target).closest(".#{CLASSES.BASE}")[0].classList[method](states.root.focused);
26
+ };
27
+
28
+ Select = {
29
+ init() {
30
+ $(document).on("focus blur", `.${classes.input}`, focus_or_blur_select);
31
+ }
32
+ };
33
+
34
+ export { classes };
35
+ export default Select;