docks_theme_api 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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;