wave-ui 1.42.2 → 1.44.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-ui",
3
- "version": "1.42.2",
3
+ "version": "1.44.1",
4
4
  "description": "An emerging UI framework for Vue.js & Vue 3 with only the bright side. :sunny:",
5
5
  "author": "Antoni Andre <antoniandre.web@gmail.com>",
6
6
  "main": "./dist/wave-ui.umd.js",
@@ -5,9 +5,10 @@ export { default as WApp } from './w-app.vue'
5
5
  export { default as WBadge } from './w-badge.vue'
6
6
  export { default as WBreadcrumbs } from './w-breadcrumbs.vue'
7
7
  export { default as WButton } from './w-button.vue'
8
+ export { default as WCard } from './w-card.vue'
8
9
  export { default as WCheckbox } from './w-checkbox.vue'
9
10
  export { default as WCheckboxes } from './w-checkboxes.vue'
10
- export { default as WCard } from './w-card.vue'
11
+ export { default as WConfirm } from './w-confirm.vue'
11
12
  export { default as WDatePicker } from './w-date-picker.vue'
12
13
  export { default as WDialog } from './w-dialog.vue'
13
14
  export { default as WDivider } from './w-divider.vue'
@@ -1,5 +1,5 @@
1
1
  <template lang="pug">
2
- .w-app(:class="{ 'theme--dark': dark, 'd-block': block }")
2
+ .w-app(:class="classes")
3
3
  slot
4
4
  notification-manager
5
5
  </template>
@@ -16,7 +16,17 @@ export default {
16
16
  name: 'w-app',
17
17
  props: {
18
18
  dark: { type: Boolean },
19
- block: { type: Boolean }
19
+ block: { type: Boolean },
20
+ row: { type: Boolean },
21
+ alignCenter: { type: Boolean },
22
+ alignEnd: { type: Boolean },
23
+ justifyCenter: { type: Boolean },
24
+ justifyEnd: { type: Boolean },
25
+ justifySpaceBetween: { type: Boolean },
26
+ justifySpaceAround: { type: Boolean },
27
+ justifySpaceEvenly: { type: Boolean },
28
+ textCenter: { type: Boolean },
29
+ textRight: { type: Boolean }
20
30
  },
21
31
 
22
32
  components: { NotificationManager },
@@ -26,6 +36,25 @@ export default {
26
36
  notifManager: null
27
37
  }),
28
38
 
39
+ computed: {
40
+ classes () {
41
+ return {
42
+ 'd-block': this.block,
43
+ 'row': this.row,
44
+ 'align-center': this.alignCenter,
45
+ 'align-end': this.alignEnd,
46
+ 'justify-center': this.justifyCenter,
47
+ 'justify-end': this.justifyEnd,
48
+ 'justify-space-between': this.justifySpaceBetween,
49
+ 'justify-space-around': this.justifySpaceAround,
50
+ 'justify-space-evenly': this.justifySpaceEvenly,
51
+ 'text-center': this.textCenter,
52
+ 'text-right': this.textRight,
53
+ 'theme--dark': this.dark
54
+ }
55
+ }
56
+ },
57
+
29
58
  methods: {
30
59
  getBreakpoint () {
31
60
  const width = window.innerWidth
@@ -85,6 +114,17 @@ export default {
85
114
  flex-direction: column;
86
115
  min-height: 100vh;
87
116
 
117
+ &.row {flex-direction: row;}
88
118
  &.d-block {display: block;}
119
+ &.align-center {align-items: center;}
120
+ &.align-end {align-items: flex-end;}
121
+ &.justify-center {justify-content: center;}
122
+ &.justify-end {justify-content: flex-end;}
123
+ &.justify-space-between {justify-content: space-between;}
124
+ &.justify-space-around {justify-content: space-around;}
125
+ &.justify-space-evenly {justify-content: space-evenly;}
126
+ &.text-center {text-align: center;}
127
+ &.text-right {text-align: right;}
128
+
89
129
  }
90
130
  </style>
@@ -2,12 +2,12 @@
2
2
  .w-card(:class="classes" :style="styles")
3
3
  .w-card__title(
4
4
  v-if="$slots.title"
5
- :class="{ 'w-card__title--has-toolbar': titleHasToolbar, [titleClass]: titleClass || false }")
5
+ :class="{ 'w-card__title--has-toolbar': titleHasToolbar, ...titleClasses }")
6
6
  slot(name="title")
7
- .w-card__title(v-else-if="title" :class="titleClass || false" v-html="title")
7
+ .w-card__title(v-else-if="title" :class="titleClasses" v-html="title")
8
8
  w-image.w-card__image(v-if="image" :src="image" v-bind="imgProps")
9
9
  slot(name="image-content")
10
- .w-card__content(:class="contentClass || false")
10
+ .w-card__content(:class="contentClasses")
11
11
  slot
12
12
  .w-card__actions(
13
13
  v-if="$slots.actions"
@@ -16,6 +16,8 @@
16
16
  </template>
17
17
 
18
18
  <script>
19
+ import { objectifyClasses } from '../utils/index'
20
+
19
21
  export default {
20
22
  name: 'w-card',
21
23
 
@@ -28,21 +30,31 @@ export default {
28
30
  title: { type: String },
29
31
  image: { type: String },
30
32
  imageProps: { type: Object },
31
- titleClass: { type: String },
32
- contentClass: { type: String }
33
+ titleClass: { type: [String, Object, Array] },
34
+ contentClass: { type: [String, Object, Array] }
33
35
  },
34
36
 
35
37
  emits: [],
36
38
 
37
39
  computed: {
40
+ titleClasses () {
41
+ return objectifyClasses(this.titleClass)
42
+ },
43
+
44
+ contentClasses () {
45
+ return objectifyClasses(this.contentClass)
46
+ },
47
+
38
48
  titleHasToolbar () {
39
49
  const { title } = this.$slots
40
50
  return title && title.map(vnode => vnode.tag).join('').includes('w-toolbar')
41
51
  },
52
+
42
53
  actionsHasToolbar () {
43
54
  const { actions } = this.$slots
44
55
  return actions && actions.map(vnode => vnode.tag).join('').includes('w-toolbar')
45
56
  },
57
+
46
58
  imgProps () {
47
59
  return {
48
60
  tag: 'div',
@@ -50,6 +62,7 @@ export default {
50
62
  ...this.imageProps
51
63
  }
52
64
  },
65
+
53
66
  classes () {
54
67
  return {
55
68
  [this.color]: this.color,
@@ -59,6 +72,7 @@ export default {
59
72
  'w-card--shadow': this.shadow
60
73
  }
61
74
  },
75
+
62
76
  styles () {
63
77
  return false
64
78
  }
@@ -0,0 +1,103 @@
1
+ <template lang="pug">
2
+ .w-confirm
3
+ w-menu(v-model="showPopup" v-bind="wMenuProps")
4
+ template(#activator="{ on }")
5
+ w-button.w-confirm__button(v-on="on" v-bind="buttonProps")
6
+ slot
7
+ w-flex(:column="!inline" align-center)
8
+ div
9
+ slot(name="question") Are you sure?
10
+ .w-flex.justify-end(:class="inline ? 'ml2' : 'mt2'")
11
+ w-button.mr2(
12
+ v-if="!noCancel"
13
+ v-bind="cancelButton"
14
+ :bg-color="(cancelButton || {}).bgColor || 'error'"
15
+ @click="onCancel")
16
+ slot(name="cancel") Cancel
17
+ w-button(
18
+ v-bind="confirmButton"
19
+ :bg-color="(confirmButton || {}).bgColor || 'success'"
20
+ @click="onConfirm")
21
+ slot(name="confirm") Confirm
22
+ </template>
23
+
24
+ <script>
25
+ export default {
26
+ name: 'w-confirm',
27
+ props: {
28
+ // Main button props.
29
+ bgColor: { type: String },
30
+ color: { type: String },
31
+ icon: { type: String },
32
+ mainButton: { type: Object }, // Allow passing down an object of props to the w-button component.
33
+
34
+ // Cancel & confirm buttons props.
35
+ noCancel: { type: Boolean }, // Removes the cancel button.
36
+ cancelButton: { type: [Boolean, Object] }, // Allow passing down an object of props to the w-button component.
37
+ confirmButton: { type: Object }, // Allow passing down an object of props to the w-button component.
38
+
39
+ // global menu props.
40
+ inline: { type: Boolean }, // The layout inside the menu.
41
+
42
+ // W-menu props.
43
+ menu: { type: Object }, // Allow passing down an object of props to the w-menu component.
44
+ // All the menu props shorthands, as long as they don't conflict with the button props.
45
+ noArrow: { type: Boolean }, // Adds a directional triangle to the edge of the menu, like a tooltip.
46
+ top: { type: Boolean },
47
+ bottom: { type: Boolean },
48
+ left: { type: Boolean },
49
+ right: { type: Boolean },
50
+ alignTop: { type: Boolean },
51
+ alignBottom: { type: Boolean },
52
+ alignLeft: { type: Boolean },
53
+ alignRight: { type: Boolean },
54
+ persistent: { type: Boolean },
55
+ transition: { type: String }
56
+ },
57
+
58
+ emits: ['cancel', 'confirm'],
59
+
60
+ data: () => ({
61
+ showPopup: false,
62
+ props: []
63
+ }),
64
+
65
+ computed: {
66
+ wMenuProps () {
67
+ return {
68
+ top: this.top,
69
+ bottom: this.bottom,
70
+ left: this.left,
71
+ right: this.right,
72
+ arrow: !this.noArrow,
73
+ alignTop: this.alignTop,
74
+ alignBottom: this.alignBottom,
75
+ alignLeft: this.alignLeft,
76
+ alignRight: this.alignRight,
77
+ persistent: this.persistent,
78
+ transition: this.transition,
79
+ ...this.menu
80
+ }
81
+ },
82
+ buttonProps () {
83
+ return {
84
+ bgColor: this.bgColor,
85
+ color: this.color,
86
+ icon: this.icon,
87
+ ...this.mainButton
88
+ }
89
+ }
90
+ },
91
+
92
+ methods: {
93
+ onCancel () {
94
+ this.$emit('cancel')
95
+ this.showPopup = false
96
+ },
97
+ onConfirm () {
98
+ this.$emit('confirm')
99
+ this.showPopup = false
100
+ }
101
+ }
102
+ }
103
+ </script>
@@ -119,9 +119,7 @@ export default {
119
119
  &.size--lg {font-size: round(1.7 * $base-font-size);}
120
120
  &.size--xl {font-size: 2 * $base-font-size;}
121
121
 
122
- // Icon's vertical alignment in button.
123
- .w-button &, .w-button &:before {line-height: inherit;}
124
- // Always an even number to vertical align well in button.
122
+ // Always an even number to align well vertically in a button.
125
123
  .w-button.size--xs & {font-size: round(0.95 * divide($base-font-size, 2)) * 2;}
126
124
  .w-alert.size--xs & {font-size: $base-font-size;}
127
125
  .w-button.size--sm &, .w-alert.size--sm & {font-size: round(1.15 * $base-font-size);}
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
2
  .w-menu-wrap
3
3
  slot(name="activator" :on="activatorEventHandlers")
4
- transition(:name="transitionName")
4
+ transition(:name="transitionName" appear)
5
5
  .w-menu(
6
6
  v-if="custom && menuVisible"
7
7
  ref="menu"
@@ -18,8 +18,8 @@
18
18
  @mouseenter.native="showOnHover && (hoveringMenu = true)"
19
19
  @mouseleave.native="showOnHover && ((hoveringMenu = false), closeMenu())"
20
20
  :tile="tile"
21
- :title-class="titleClass"
22
- :content-class="contentClass"
21
+ :title-class="titleClasses"
22
+ :content-class="contentClasses"
23
23
  :shadow="shadow"
24
24
  :no-border="noBorder"
25
25
  :class="classes"
@@ -34,7 +34,7 @@
34
34
  ref="overlay"
35
35
  :value="menuVisible"
36
36
  :persistent="persistent"
37
- :class="overlayClass || null"
37
+ :class="overlayClasses"
38
38
  v-bind="overlayProps"
39
39
  :z-index="(zIndex || 200) - 1"
40
40
  @input="menuVisible = false")
@@ -50,6 +50,7 @@
50
50
  * and move the menu elsewhere in the DOM.
51
51
  */
52
52
 
53
+ import { objectifyClasses } from '../utils/index'
53
54
  import { consoleWarn } from '../utils/console'
54
55
 
55
56
  // const marginFromWindowSide = 4 // Amount of px from a window side, instead of overflowing.
@@ -69,10 +70,11 @@ export default {
69
70
  round: { type: Boolean },
70
71
  noBorder: { type: Boolean },
71
72
  transition: { type: String },
72
- menuClass: { type: String },
73
- titleClass: { type: String },
74
- contentClass: { type: String },
73
+ menuClass: { type: [String, Object, Array] },
74
+ titleClass: { type: [String, Object, Array] },
75
+ contentClass: { type: [String, Object, Array] },
75
76
  // Position.
77
+ arrow: { type: Boolean }, // The small triangle pointing toward the activator.
76
78
  detachTo: { type: [String, Boolean, Object] },
77
79
  fixed: { type: Boolean },
78
80
  top: { type: Boolean },
@@ -86,7 +88,7 @@ export default {
86
88
  zIndex: { type: [Number, String, Boolean] },
87
89
  minWidth: { type: [Number, String] }, // can be like: `40`, `5em`, `activator`.
88
90
  overlay: { type: Boolean },
89
- overlayClass: { type: String },
91
+ overlayClass: { type: [String, Object, Array] },
90
92
  overlayProps: { type: Object }, // Allow passing down an object of props to the w-overlay component.
91
93
  persistent: { type: Boolean },
92
94
  noPosition: { type: Boolean }
@@ -163,27 +165,46 @@ export default {
163
165
  )
164
166
  },
165
167
 
168
+ menuClasses () {
169
+ return objectifyClasses(this.menuClass)
170
+ },
171
+
172
+ titleClasses () {
173
+ return objectifyClasses(this.titleClass)
174
+ },
175
+
176
+ contentClasses () {
177
+ return objectifyClasses(this.contentClass)
178
+ },
179
+
180
+ overlayClasses () {
181
+ return objectifyClasses(this.overlayClass)
182
+ },
183
+
166
184
  classes () {
167
185
  return {
168
186
  [this.color]: this.color,
169
187
  [`${this.bgColor}--bg`]: this.bgColor,
170
- [this.menuClass]: this.menuClass,
171
- [`w-menu--${this.position}`]: true,
172
- [`w-menu--align-${this.alignment}`]: this.alignment,
188
+ ...this.menuClasses,
189
+ [`w-menu--${this.position}`]: !this.noPosition,
190
+ [`w-menu--align-${this.alignment}`]: !this.noPosition && this.alignment,
173
191
  'w-menu--tile': this.tile,
174
192
  'w-menu--card': !this.custom,
175
193
  'w-menu--round': this.round,
194
+ 'w-menu--arrow': this.arrow,
176
195
  'w-menu--shadow': this.shadow,
177
196
  'w-menu--fixed': this.fixed
178
197
  }
179
198
  },
180
199
 
200
+ // The floatting menu styles.
181
201
  styles () {
182
202
  return {
183
203
  zIndex: this.zIndex || this.zIndex === 0 || (this.overlay && !this.zIndex && 200) || null,
184
204
  top: (this.menuCoordinates.top && `${~~this.menuCoordinates.top}px`) || null,
185
205
  left: (this.menuCoordinates.left && `${~~this.menuCoordinates.left}px`) || null,
186
- minWidth: (this.minWidth && this.menuMinWidth) || null
206
+ minWidth: (this.minWidth && this.menuMinWidth) || null,
207
+ '--w-menu-bg-color': this.arrow && this.$waveui.colors[this.bgColor || 'white']
187
208
  }
188
209
  },
189
210
 
@@ -484,5 +505,14 @@ export default {
484
505
  &--bottom {margin-top: 3 * $base-increment;}
485
506
  &--left {margin-left: -3 * $base-increment;}
486
507
  &--right {margin-left: 3 * $base-increment;}
508
+
509
+ &--arrow {
510
+ &.w-menu--top {margin-top: -4 * $base-increment;}
511
+ &.w-menu--bottom {margin-top: 4 * $base-increment;}
512
+ &.w-menu--left {margin-left: -4 * $base-increment;}
513
+ &.w-menu--right {margin-left: 4 * $base-increment;}
514
+
515
+ @include triangle(var(--w-menu-bg-color), '.w-menu', 9px);
516
+ }
487
517
  }
488
518
  </style>
@@ -62,7 +62,7 @@ export default {
62
62
  z-index: 1000;
63
63
  pointer-events: none;
64
64
  width: 280px;
65
- overflow: auto;
65
+ overflow-x: hidden;
66
66
 
67
67
  &--left {right: auto;left: 0;}
68
68
 
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
2
  .w-tooltip-wrap(ref="wrapper" :class="{ 'w-tooltip-wrap--attached': !detachTo }")
3
3
  slot(name="activator" :on="eventHandlers")
4
- transition(:name="transitionName")
4
+ transition(:name="transitionName" appear)
5
5
  .w-tooltip(ref="tooltip" v-show="showTooltip" :class="classes" :style="styles")
6
6
  //- When there is a bg color, another div wrapper is needed for the triangle
7
7
  //- to inherit the current color.
@@ -20,6 +20,7 @@
20
20
  * and move the tooltip elsewhere in the DOM.
21
21
  */
22
22
 
23
+ import { objectifyClasses } from '../utils/index'
23
24
  import { consoleWarn } from '../utils/console'
24
25
 
25
26
  const marginFromWindowSide = 4 // Amount of px from a window side, instead of overflowing.
@@ -36,8 +37,8 @@ export default {
36
37
  shadow: { type: Boolean },
37
38
  tile: { type: Boolean },
38
39
  round: { type: Boolean },
39
- transition: { type: String, default: '' },
40
- tooltipClass: { type: String },
40
+ transition: { type: String },
41
+ tooltipClass: { type: [String, Object, Array] },
41
42
  // Position.
42
43
  detachTo: {},
43
44
  fixed: { type: Boolean },
@@ -65,6 +66,10 @@ export default {
65
66
  }),
66
67
 
67
68
  computed: {
69
+ tooltipClasses () {
70
+ return objectifyClasses(this.tooltipClass)
71
+ },
72
+
68
73
  transitionName () {
69
74
  const direction = this.position.replace(/top|bottom/, m => ({ top: 'up', bottom: 'down' }[m]))
70
75
  return this.transition || `w-tooltip-slide-fade-${direction}`
@@ -137,7 +142,7 @@ export default {
137
142
  return {
138
143
  [this.color]: !this.bgColor,
139
144
  [`${this.bgColor} ${this.bgColor}--bg`]: this.bgColor,
140
- [this.tooltipClass]: this.tooltipClass,
145
+ ...this.tooltipClasses,
141
146
  [`w-tooltip--${this.position}`]: true,
142
147
  'w-tooltip--tile': this.tile,
143
148
  'w-tooltip--round': this.round,
@@ -274,8 +279,7 @@ export default {
274
279
  },
275
280
 
276
281
  removeTooltip () {
277
- // el.remove() doesn't work on IE11.
278
- if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.parentNode.removeChild(this.tooltipEl)
282
+ if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.remove()
279
283
  }
280
284
 
281
285
  },
@@ -290,8 +294,7 @@ export default {
290
294
  beforeDestroy () {
291
295
  this.removeTooltip()
292
296
 
293
- // el.remove() doesn't work on IE11.
294
- if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.parentNode.removeChild(this.activatorEl)
297
+ if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.remove()
295
298
  },
296
299
 
297
300
  watch: {
@@ -0,0 +1,100 @@
1
+ @mixin default-transition($duration: $transition-duration, $delay: 0s) {
2
+ transition: $duration $delay ease-in-out;
3
+ }
4
+
5
+ @mixin out-back-transition($duration: $transition-duration, $delay: 0s) {
6
+ transition: $duration $delay cubic-bezier(0.18, 0.89, 0.32, 1.28);
7
+ }
8
+
9
+ /**
10
+ * Generates a triangle arrow on the edge of an element.
11
+ *
12
+ * @param $color: the color to apply to the triangle.
13
+ * @param $selector: the element selector that receives the modifiers (--top, --left, etc.).
14
+ * @param $size: the triangle size at the base.
15
+ * @param $thickness: the border thickness, 0 to remove the border.
16
+ */
17
+ @mixin triangle($color: white, $selector: '', $size: 7px, $thickness: 1px) {
18
+ @if ($thickness > 0) {
19
+ // The underneath border triangle.
20
+ &:before {
21
+ content: '';
22
+ position: absolute;
23
+ width: 0;
24
+ height: 0;
25
+ border: $size solid transparent;
26
+ }
27
+
28
+ &#{$selector}--top:before {
29
+ top: 100%;
30
+ left: 50%;
31
+ border-top-color: inherit;
32
+ transform: translateX(-50%);
33
+ margin-top: 0;
34
+ }
35
+ &#{$selector}--bottom:before {
36
+ bottom: 100%;
37
+ left: 50%;
38
+ border-bottom-color: inherit;
39
+ transform: translateX(-50%);
40
+ margin-bottom: 0;
41
+ }
42
+ &#{$selector}--left:before {
43
+ left: 100%;
44
+ top: 50%;
45
+ border-left-color: inherit;
46
+ transform: translateY(-50%);
47
+ margin-left: 0;
48
+ }
49
+ &#{$selector}--right:before {
50
+ right: 100%;
51
+ top: 50%;
52
+ border-right-color: inherit;
53
+ transform: translateY(-50%);
54
+ margin-right: 0;
55
+ }
56
+
57
+ &#{$selector}--align-top:before {transform: none;top: (2 * $base-increment) - 1px;}
58
+ &#{$selector}--align-bottom:before {transform: none;top: auto;bottom: (2 * $base-increment) - 1px;}
59
+ &#{$selector}--align-left:before {transform: none;left: (2 * $base-increment) - 1px;}
60
+ &#{$selector}--align-right:before {transform: none;left: auto;right: (2 * $base-increment) - 1px;}
61
+ }
62
+
63
+ // The colored triangle on top of `:before`.
64
+ &:after {
65
+ content: '';
66
+ position: absolute;
67
+ width: 0;
68
+ height: 0;
69
+ border: ($size - $thickness) solid transparent;
70
+ }
71
+ &#{$selector}--top:after {
72
+ top: 100%;
73
+ left: 50%;
74
+ border-top-color: $color;
75
+ transform: translateX(-50%);
76
+ }
77
+ &#{$selector}--bottom:after {
78
+ bottom: 100%;
79
+ left: 50%;
80
+ border-bottom-color: $color;
81
+ transform: translateX(-50%);
82
+ }
83
+ &#{$selector}--left:after {
84
+ left: 100%;
85
+ top: 50%;
86
+ border-left-color: $color;
87
+ transform: translateY(-50%);
88
+ }
89
+ &#{$selector}--right:after {
90
+ right: 100%;
91
+ top: 50%;
92
+ border-right-color: $color;
93
+ transform: translateY(-50%);
94
+ }
95
+
96
+ &#{$selector}--align-top:after {transform: none;top: 2 * $base-increment;}
97
+ &#{$selector}--align-bottom:after {transform: none;top: auto;bottom: 2 * $base-increment;}
98
+ &#{$selector}--align-left:after {transform: none;left: 2 * $base-increment;}
99
+ &#{$selector}--align-right:after {transform: none;left: auto;right: 2 * $base-increment;}
100
+ }
@@ -28,15 +28,6 @@ $form-field-height: round(2 * $base-font-size) !default;
28
28
  // Always an even number for better vertical alignment. (Used in checkbox, radio, switch)
29
29
  $small-form-el-size: round(divide(1.3 * $base-font-size, 2)) * 2 !default;
30
30
 
31
- // Mixins.
32
- @mixin default-transition($duration: $transition-duration, $delay: 0s) {
33
- transition: $duration $delay ease-in-out;
34
- }
35
-
36
- @mixin out-back-transition($duration: $transition-duration, $delay: 0s) {
37
- transition: $duration $delay cubic-bezier(0.18, 0.89, 0.32, 1.28);
38
- }
39
-
40
31
  // COMPONENTS DEFAULTS.
41
32
  // ========================================================
42
33
  // w-drawer.
@@ -1,4 +1,5 @@
1
1
  @import './variables';
2
+ @import './mixins';
2
3
  @import './base';
3
4
  @import './typography';
4
5
  @import './layout';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Takes CSS classes as a string array or object and turn them into an object.
3
+ *
4
+ * @param {String|Array|Object} classes the CSS classes to merge into an object
5
+ * @return {Object}
6
+ */
7
+ export const objectifyClasses = (classes = {}) => {
8
+ if (typeof classes === 'string') classes = { [classes]: true }
9
+ else if (typeof classes === 'array') classes = { [classes.join(' ')]: true }
10
+ return classes
11
+ }