wave-ui 2.44.0 → 2.45.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": "2.44.0",
3
+ "version": "2.45.1",
4
4
  "description": "An emerging UI framework for Vue.js (2 & 3) with only the bright side. :sunny:",
5
5
  "author": "Antoni Andre <antoniandre.web@gmail.com>",
6
6
  "homepage": "https://antoniandre.github.io/wave-ui",
@@ -48,29 +48,29 @@
48
48
  "lint": "vite lint"
49
49
  },
50
50
  "devDependencies": {
51
- "@babel/core": "^7.19.6",
51
+ "@babel/core": "^7.20.2",
52
52
  "@babel/eslint-parser": "^7.19.1",
53
53
  "@babel/plugin-proposal-class-properties": "^7.18.6",
54
54
  "@mdi/font": "^5.9.55",
55
55
  "@vitejs/plugin-vue": "^3.2.0",
56
- "@vue/compiler-sfc": "3.2.41",
56
+ "@vue/compiler-sfc": "3.2.45",
57
57
  "autoprefixer": "^10.4.13",
58
58
  "axios": "^0.25.0",
59
59
  "eslint": "^7.32.0",
60
- "eslint-plugin-vue": "^9.6.0",
60
+ "eslint-plugin-vue": "^9.7.0",
61
61
  "font-awesome": "^4.7.0",
62
62
  "gsap": "^3.11.3",
63
63
  "ionicons": "^4.6.3",
64
64
  "material-design-icons": "^3.0.1",
65
- "postcss": "^8.4.18",
65
+ "postcss": "^8.4.19",
66
66
  "pug": "^3.0.2",
67
67
  "rollup-plugin-delete": "^2.0.0",
68
- "sass": "^1.55.0",
68
+ "sass": "^1.56.1",
69
69
  "simple-syntax-highlighter": "^2.2.5",
70
70
  "splitpanes": "^3.1.5",
71
71
  "standard": "^17.0.0",
72
- "vite": "^3.2.1",
73
- "vue": "^3.2.41",
72
+ "vite": "^3.2.3",
73
+ "vue": "^3.2.45",
74
74
  "vue-router": "^4.1.6",
75
75
  "vueperslides": "^3.5.1",
76
76
  "vuex": "^4.1.0"
@@ -4,7 +4,7 @@ export { default as WAlert } from './w-alert.vue'
4
4
  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
- export { default as WButton } from './w-button.vue'
7
+ export { default as WButton } from './w-button/index.vue'
8
8
  export { default as WCard } from './w-card.vue'
9
9
  export { default as WCheckbox } from './w-checkbox.vue'
10
10
  export { default as WCheckboxes } from './w-checkboxes.vue'
@@ -15,12 +15,13 @@
15
15
  w-button.w-accordion__expand-icon(
16
16
  v-if="expandIcon && !expandIconRight"
17
17
  :icon="(item._expanded && collapseIcon) || expandIcon"
18
+ :icon-props="expandIconProps"
18
19
  :disabled="item._disabled || null"
19
20
  :tabindex="-1"
20
21
  text
21
22
  @keypress.stop
22
23
  @click.stop="!item._disabled && toggleItem(item, $event)"
23
- :class="{ 'w-accordion__expand-icon--expanded': item._expanded }")
24
+ :class="{ 'w-accordion__expand-icon--expanded': item._expanded, 'w-accordion__expand-icon--rotate90': expandIconRotate90 }")
24
25
  //- Title.
25
26
  slot(
26
27
  v-if="$slots[`item-title.${item.id || i + 1}`]"
@@ -36,7 +37,7 @@
36
37
  text
37
38
  @keypress.stop
38
39
  @click.stop="!item._disabled && toggleItem(item, $event)"
39
- :class="{ 'w-accordion__expand-icon--expanded': item._expanded }")
40
+ :class="{ 'w-accordion__expand-icon--expanded': item._expanded, 'w-accordion__expand-icon--rotate90': expandIconRotate90 }")
40
41
  //- Content.
41
42
  w-transition-expand(
42
43
  y
@@ -77,6 +78,8 @@ export default {
77
78
  contentClass: { type: String },
78
79
  expandIcon: { type: [String, Boolean], default: 'wi-triangle-down' },
79
80
  expandIconRight: { type: Boolean },
81
+ expandIconRotate90: { type: Boolean },
82
+ expandIconProps: { type: Object, default: () => ({}) },
80
83
  expandSingle: { type: Boolean },
81
84
  collapseIcon: { type: String },
82
85
  shadow: { type: Boolean },
@@ -174,8 +177,9 @@ export default {
174
177
  margin-right: $base-increment;
175
178
 
176
179
  .w-accordion--rotate-icon & {@include default-transition;}
180
+ &--rotate90 {transform: rotate(-90deg);}
177
181
  &--expanded {transform: rotate(-180deg);}
178
- .w-accordion--icon-right &--expanded {transform: rotate(180deg);}
182
+ &--expanded.w-accordion__expand-icon--rotate90 {transform: rotate(0deg);}
179
183
 
180
184
  .w-icon:before {font-size: 1.1em;}
181
185
  }
@@ -112,8 +112,8 @@ export default {
112
112
  &--inline {position: static;}
113
113
 
114
114
  &--round {
115
- width: round(1.1 * divide($base-font-size, 2)) * 2;
116
- padding: 0 (round(1.1 * divide($base-font-size, 4)) * 2);
115
+ aspect-ratio: 1;
116
+ padding: 0;
117
117
  }
118
118
 
119
119
  // Sizes.
@@ -184,11 +184,11 @@ export default {
184
184
  }
185
185
  &--shadow {box-shadow: $box-shadow;}
186
186
 
187
- &--dot.w-badge {min-width: 0;padding: 0;}
188
- &--dot.size--xs {width: round(1.35 * $base-increment);height: round(1.35 * $base-increment);}
189
- &--dot.size--sm {width: round(1.7 * $base-increment);height: round(1.7 * $base-increment);}
190
- &--dot.size--md {width: round(2.2 * $base-increment);height: round(2.2 * $base-increment);}
191
- &--dot.size--lg {width: round(2.75 * $base-increment);height: round(2.75 * $base-increment);}
192
- &--dot.size--xl {width: 3 * $base-increment;height: 3 * $base-increment;}
187
+ &--dot.w-badge {min-width: 0;padding: 0;aspect-ratio: 1;}
188
+ &--dot.size--xs {height: round(1.35 * $base-increment);}
189
+ &--dot.size--sm {height: round(1.7 * $base-increment);}
190
+ &--dot.size--md {height: round(2.2 * $base-increment);}
191
+ &--dot.size--lg {height: round(2.75 * $base-increment);}
192
+ &--dot.size--xl {height: 3 * $base-increment;}
193
193
  }
194
194
  </style>
@@ -6,7 +6,6 @@ component.w-button(
6
6
  :class="classes"
7
7
  :disabled="!!disabled || null"
8
8
  v-on="listeners"
9
- v-bind="$attrs"
10
9
  :style="styles")
11
10
  w-icon(v-if="icon" v-bind="iconProps || {}") {{ icon }}
12
11
  slot(v-else)
@@ -24,8 +23,6 @@ component.w-button(
24
23
 
25
24
  <script>
26
25
  export default {
27
- name: 'w-button',
28
-
29
26
  props: {
30
27
  color: { type: String },
31
28
  bgColor: { type: String },
@@ -199,6 +196,7 @@ $spinner-size: 40;
199
196
  padding-right: 3 * $base-increment;
200
197
  }
201
198
  &--icon {
199
+ aspect-ratio: 1;
202
200
  border-radius: 99em;
203
201
  padding: 0;
204
202
  }
@@ -227,11 +225,8 @@ $spinner-size: 40;
227
225
  &.size--xl {padding-left: 3 * $base-increment;padding-right: 3 * $base-increment;}
228
226
  &--round.size--xs {padding-left: round(1.5 * $base-increment);padding-right: round(1.5 * $base-increment);}
229
227
  &--round.size--xl {padding-left: round(4.5 * $base-increment);padding-right: round(4.5 * $base-increment);}
230
- &--icon.size--xs {width: round(1.25 * divide($base-font-size, 2)) * 2;padding-left: 0;padding-right: 0;}
231
- &--icon.size--sm {width: round(1.55 * divide($base-font-size, 2)) * 2;}
232
- &--icon.size--md {width: round(1.85 * divide($base-font-size, 2)) * 2;}
233
- &--icon.size--lg {width: round(2.2 * divide($base-font-size, 2)) * 2;}
234
- &--icon.size--xl {width: round(2.5 * divide($base-font-size, 2)) * 2;padding-left: 0;padding-right: 0;}
228
+ &--icon.size--xs {padding-left: 0;padding-right: 0;}
229
+ &--icon.size--xl {padding-left: 0;padding-right: 0;}
235
230
 
236
231
  // Overlay to mark the focus, hover and active state.
237
232
  &:before {
@@ -0,0 +1,68 @@
1
+ <template lang="pug">
2
+ component(v-if="tooltip" is="w-tooltip" v-bind="tooltipProps || {}")
3
+ template(#activator="{ on }")
4
+ button-partial(v-bind="buttonProps" v-on="on")
5
+ slot
6
+ div(v-html="tooltip")
7
+ button-partial(v-else v-bind="buttonProps")
8
+ slot
9
+ </template>
10
+
11
+ <script>
12
+ import ButtonPartial from './button.vue'
13
+
14
+ export default {
15
+ name: 'w-button',
16
+ inheritAttrs: false, // The attrs are only bound to the button-partial, not the root.
17
+
18
+ props: {
19
+ color: { type: String },
20
+ bgColor: { type: String },
21
+ dark: { type: Boolean },
22
+ outline: { type: Boolean },
23
+ text: { type: Boolean },
24
+ round: { type: Boolean },
25
+ shadow: { type: Boolean },
26
+ tile: { type: Boolean },
27
+ tooltip: { type: String },
28
+ tooltipProps: { type: Object, default: () => ({}) },
29
+ route: { type: [String, Object] }, // Creates a link.
30
+ // Force use of `a` instead of router-link.
31
+ // Router link does not go to a url starting with `#` with history mode.
32
+ forceLink: { type: Boolean },
33
+ type: { type: String, default: 'button' },
34
+ disabled: { type: Boolean },
35
+ loading: { type: Boolean },
36
+ // If an icon is passed, no text will display.
37
+ icon: { type: String, default: null },
38
+ iconProps: { type: Object, default: () => ({}) },
39
+ // Positions.
40
+ absolute: { type: Boolean },
41
+ fixed: { type: Boolean },
42
+ top: { type: Boolean },
43
+ bottom: { type: Boolean },
44
+ left: { type: Boolean },
45
+ right: { type: Boolean },
46
+ zIndex: { type: [Number, String] },
47
+ // Sizes.
48
+ width: { type: [Number, String] },
49
+ height: { type: [Number, String] },
50
+ xs: { type: Boolean },
51
+ sm: { type: Boolean },
52
+ md: { type: Boolean },
53
+ lg: { type: Boolean },
54
+ xl: { type: Boolean }
55
+ },
56
+
57
+ components: { ButtonPartial },
58
+
59
+ emits: [],
60
+
61
+ computed: {
62
+ buttonProps () {
63
+ const { tooltip, tooltipProps, ...props } = this.$props
64
+ return { ...props, ...this.$attrs }
65
+ }
66
+ }
67
+ }
68
+ </script>
@@ -23,19 +23,29 @@ component(
23
23
  role="checkbox")
24
24
  template(v-if="hasLabel && labelOnLeft")
25
25
  label.w-checkbox__label.w-form-el-shakable.pr2(
26
- v-if="$slots.default || label"
26
+ v-if="$slots.default"
27
27
  :for="`w-checkbox--${_.uid}`"
28
28
  :class="labelClasses")
29
29
  slot {{ label }}
30
+ label.w-checkbox__label.w-form-el-shakable.pr2(
31
+ v-else-if="label"
32
+ :for="`w-checkbox--${_.uid}`"
33
+ :class="labelClasses"
34
+ v-html="label")
30
35
  .w-checkbox__input(@click="$refs.input.focus();$refs.input.click()" :class="this.color")
31
- svg(width="11px" height="9px" viewbox="0 0 12 9")
36
+ svg(viewBox="-0.5 0 12 10")
32
37
  polyline(points="1 5 4 8 10 2")
33
38
  template(v-if="hasLabel && !labelOnLeft")
34
39
  label.w-checkbox__label.w-form-el-shakable.pl2(
35
- v-if="$slots.default || label"
40
+ v-if="$slots.default"
36
41
  :for="`w-checkbox--${_.uid}`"
37
42
  :class="labelClasses")
38
43
  slot {{ label }}
44
+ label.w-checkbox__label.w-form-el-shakable.pl2(
45
+ v-else-if="label"
46
+ :for="`w-checkbox--${_.uid}`"
47
+ :class="labelClasses"
48
+ v-html="label")
39
49
  </template>
40
50
 
41
51
  <script>
@@ -152,7 +162,7 @@ $inactive-color: #666;
152
162
  &__input {
153
163
  position: relative;
154
164
  width: $small-form-el-size;
155
- height: $small-form-el-size;
165
+ aspect-ratio: 1;
156
166
  display: flex;
157
167
  flex: 0 0 auto; // Prevent stretching width or height.
158
168
  align-items: center;
@@ -163,8 +173,8 @@ $inactive-color: #666;
163
173
 
164
174
  // The checkmark - visible when checked.
165
175
  &__input svg {
166
- width: auto;
167
- height: auto;
176
+ width: 70%;
177
+ aspect-ratio: 1;
168
178
  fill: none;
169
179
  stroke-width: 2;
170
180
  stroke: white;
@@ -175,7 +185,6 @@ $inactive-color: #666;
175
185
  transition: $transition-duration ease-out;
176
186
  opacity: 0;
177
187
  position: relative;
178
- top: -0.5px; // For browser zoom levels.
179
188
  z-index: 1;
180
189
 
181
190
  :checked ~ & {
@@ -190,7 +199,7 @@ $inactive-color: #666;
190
199
  content: '';
191
200
  position: absolute;
192
201
  width: 100%;
193
- height: 100%;
202
+ aspect-ratio: 1;
194
203
  border: $outline-width solid $inactive-color;
195
204
  border-radius: $border-radius;
196
205
  transition: $transition-duration ease-in-out;
@@ -221,7 +230,7 @@ $inactive-color: #666;
221
230
  content: "";
222
231
  position: absolute;
223
232
  width: inherit;
224
- height: inherit;
233
+ aspect-ratio: 1;
225
234
  background-color: currentColor;
226
235
  border-radius: 100%;
227
236
  transform: scale(0);
@@ -12,11 +12,14 @@
12
12
  v-if="cancel !== false"
13
13
  v-bind="cancelButtonProps"
14
14
  :bg-color="(cancelButton || {}).bgColor || 'error'"
15
+ @keyup.escape="!persistent && onCancel()"
15
16
  @click="onCancel")
16
17
  slot(name="cancel") {{ cancelButton.label }}
17
18
  w-button(
18
19
  v-bind="confirmButtonProps"
19
20
  :bg-color="(confirmButton || {}).bgColor || 'success'"
21
+ v-focus
22
+ @keyup.escape="!persistent && onCancel()"
20
23
  @click="onConfirm")
21
24
  slot(name="confirm") {{ confirmButton.label }}
22
25
  </template>
@@ -45,7 +48,11 @@ export default {
45
48
  inline: { type: Boolean }, // The layout inside the menu.
46
49
 
47
50
  // W-menu props.
48
- menu: { type: Object }, // Allow passing down an object of props to the w-menu component.
51
+ // Allow passing down an object of props to the w-menu component.
52
+ menu: { type: Object, default: () => ({}) },
53
+ // Allow passing down an object of props to the w-tooltip component.
54
+ // If a string is given, that will be the label of the tooltip.
55
+ tooltip: { type: [Boolean, Object, String] },
49
56
  // All the menu props shorthands, as long as they don't conflict with the button props.
50
57
  noArrow: { type: Boolean }, // Adds a directional triangle to the edge of the menu, like a tooltip.
51
58
  top: { type: Boolean },
@@ -104,11 +111,20 @@ export default {
104
111
  ...this.menu
105
112
  }
106
113
  },
114
+ tooltipObject () {
115
+ let tooltip = { label: typeof this.tooltip === 'string' ? this.tooltip : '' }
116
+ if (typeof this.tooltip === 'object') tooltip = Object.assign({}, tooltip, this.tooltip)
117
+ return tooltip
118
+ },
107
119
  buttonProps () {
120
+ const { label, ...tooltipProps } = this.tooltipObject
121
+
108
122
  return {
109
123
  bgColor: this.bgColor,
110
124
  color: this.color,
111
125
  icon: this.icon,
126
+ tooltip: label,
127
+ tooltipProps,
112
128
  ...this.mainButton
113
129
  }
114
130
  }
@@ -88,7 +88,7 @@ export default {
88
88
  methods: {
89
89
  readIcon () {
90
90
  const { default: slot } = this.$slots
91
- const [fontName = '', icon = ''] = typeof slot === 'function' && slot()[0].children.trim().split(' ') || []
91
+ const [fontName = '', icon = ''] = (typeof slot === 'function' && slot()[0].children.trim().split(' ')) || []
92
92
  this.fontName = fontName
93
93
  this.icon = icon
94
94
 
@@ -111,6 +111,7 @@ export default {
111
111
  line-height: 1;
112
112
  font-size: 1.2em;
113
113
  width: 1em;
114
+ // The aspect ratio will not work if the content is the content overflows.
114
115
  height: 1em;
115
116
 
116
117
  &.size--xs {font-size: round(0.85 * $base-font-size);}
@@ -182,8 +182,8 @@ export default {
182
182
  attrs () {
183
183
  // Keep the `class` attribute bound to the wrapper and not the input.
184
184
  // eslint-disable-next-line no-unused-vars
185
- const { class: classes, ...attrs } = this.$attrs
186
- return attrs
185
+ const { class: classes, ...htmlAttrs } = this.$attrs
186
+ return htmlAttrs
187
187
  },
188
188
 
189
189
  listeners () {
@@ -193,12 +193,6 @@ export default {
193
193
  return listeners
194
194
  },
195
195
 
196
- attrs () {
197
- // eslint-disable-next-line no-unused-vars
198
- const { class: Class, ...htmlAttrs } = this.$attrs
199
- return htmlAttrs
200
- },
201
-
202
196
  hasValue () {
203
197
  switch (this.type) {
204
198
  case 'file': return !!this.inputFiles.length
@@ -387,6 +381,8 @@ $inactive-color: #777;
387
381
  span.fade-leave-to {position: absolute;}
388
382
  }
389
383
 
384
+ &--loading {cursor: wait;}
385
+
390
386
  // Input field wrapper.
391
387
  // ------------------------------------------------------
392
388
  &__input-wrap {
@@ -50,6 +50,7 @@ import DetachableMixin from '../mixins/detachable'
50
50
  export default {
51
51
  name: 'w-menu',
52
52
  mixins: [DetachableMixin],
53
+ inheritAttrs: false, // The attrs are only bound to the button-partial, not the root.
53
54
 
54
55
  props: {
55
56
  modelValue: {}, // Show or hide.
@@ -21,6 +21,7 @@ export default {
21
21
  modelValue: {},
22
22
  opacity: { type: [Number, String, Boolean] },
23
23
  bgColor: { type: String },
24
+ absolute: { type: Boolean },
24
25
  zIndex: { type: [Number, String, Boolean] },
25
26
  persistent: { type: Boolean },
26
27
  persistentNoAnimation: { type: Boolean }
@@ -47,7 +48,8 @@ export default {
47
48
  },
48
49
  classes () {
49
50
  return {
50
- 'w-overlay--persistent-animate': this.persistentAnimate
51
+ 'w-overlay--persistent-animate': this.persistentAnimate,
52
+ 'w-overlay--absolute': this.absolute
51
53
  }
52
54
  },
53
55
  styles () {
@@ -112,6 +114,7 @@ export default {
112
114
  justify-content: center;
113
115
  background-color: rgba(0, 0, 0, 0.3);
114
116
 
117
+ &--absolute {position: absolute;}
115
118
  &--persistent-animate {animation: 0.15s w-overlay-pop cubic-bezier(0.6, -0.28, 0.74, 0.05);}
116
119
  &--no-pointer-event {pointer-events: none;}
117
120
  }
@@ -7,8 +7,8 @@
7
7
  :style="`width: ${progressValue}%`")
8
8
 
9
9
  //- Circular progress.
10
- template(v-else)
11
- svg(:viewBox="`${circleCenter / 2} ${circleCenter / 2} ${circleCenter} ${circleCenter}`")
10
+ svg(v-else :viewBox="`${circleCenter / 2} ${circleCenter / 2} ${circleCenter} ${circleCenter}`")
11
+ //- Background first, in SVG there is no z-index.
12
12
  circle.bg(
13
13
  v-if="bgColor || this.progressValue > -1"
14
14
  :class="bgColor"
@@ -18,30 +18,21 @@
18
18
  fill="transparent"
19
19
  :stroke-dasharray="circleCircumference"
20
20
  :stroke-width="stroke")
21
- svg.w-progress__progress(
22
- :viewBox="`${circleCenter / 2} ${circleCenter / 2} ${circleCenter} ${circleCenter}`"
23
- :style="`stroke-dashoffset: ${(1 - (progressValue / 100)) * circleCircumference}`")
24
- circle(
21
+ circle.w-progress__progress(
25
22
  :cx="circleCenter"
26
23
  :cy="circleCenter"
27
24
  :r="circleRadius"
28
25
  fill="transparent"
29
26
  :stroke-width="stroke"
30
27
  :stroke-linecap="roundCap && 'round'"
31
- :stroke-dasharray="circleCircumference")
28
+ :stroke-dasharray="circleCircumference"
29
+ :style="`stroke-dashoffset: ${(1 - (progressValue / 100)) * circleCircumference}`")
32
30
 
33
31
  .w-progress__label(v-if="label || $slots.default" :class="labelColor || false")
34
32
  slot {{ Math.round(progressValue) }}{{ circle ? '' : '%' }}
35
33
  </template>
36
34
 
37
35
  <script>
38
- /**
39
- * This component (circular) is hacked to work on Edge as it does not support transform on svg elements.
40
- * https://caniuse.com/#feat=mdn-css_properties_transform-origin_support_in_svg
41
- * It is meant to be 2 circles in 1 svg, with animation on the circle, now instead, there are 2 svgs,
42
- * and the animation is on the second svg itself.
43
- */
44
-
45
36
  // For circular progress.
46
37
  const circleSize = 40
47
38
  const circleRadius = circleSize / 2
@@ -256,7 +247,7 @@ $circle-size: 40;
256
247
  &--circular {
257
248
  display: inline-flex;
258
249
  width: 3em;
259
- height: auto;
250
+ aspect-ratio: 1;
260
251
  font-size: $base-font-size;
261
252
 
262
253
  svg {display: block;width: 100%;}
@@ -264,19 +255,10 @@ $circle-size: 40;
264
255
  &.w-progress--default-bg circle.bg {stroke: rgba(0, 0, 0, 0.1);}
265
256
 
266
257
  .w-progress__progress {
267
- position: absolute;
268
- top: 0;
269
- left: 0;
270
- right: 0;
271
- bottom: 0;
272
-
273
- circle {
274
- stroke: currentColor;
275
- stroke-dashoffset: inherit;
276
- will-change: stroke-dashoffset;
277
- }
258
+ transform-origin: 100% 100%;
278
259
  transform: rotate(-90deg);
279
- will-change: transform;
260
+ stroke: currentColor;
261
+ will-change: stroke-dashoffset;
280
262
  @include default-transition;
281
263
  }
282
264
  &.w-progress--round-cap .w-progress__progress {stroke-linecap: round;}
@@ -21,19 +21,29 @@ component(
21
21
  role="radio")
22
22
  template(v-if="hasLabel && labelOnLeft")
23
23
  label.w-radio__label.w-form-el-shakable.pr2(
24
- v-if="$slots.default || label"
24
+ v-if="$slots.default"
25
25
  :for="`w-radio--${_.uid}`"
26
26
  :class="labelClasses")
27
27
  slot {{ label }}
28
+ label.w-radio__label.w-form-el-shakable.pr2(
29
+ v-else-if="label"
30
+ :for="`w-radio--${_.uid}`"
31
+ :class="labelClasses"
32
+ v-html="label")
28
33
  .w-radio__input(
29
34
  @click="$refs.input.focus();$refs.input.click()"
30
35
  :class="this.color")
31
36
  template(v-if="hasLabel && !labelOnLeft")
32
37
  label.w-radio__label.w-form-el-shakable.pl2(
33
- v-if="$slots.default || label"
38
+ v-if="$slots.default"
34
39
  :for="`w-radio--${_.uid}`"
35
40
  :class="labelClasses")
36
41
  slot {{ label }}
42
+ label.w-radio__label.w-form-el-shakable.pl2(
43
+ v-else-if="label"
44
+ :for="`w-radio--${_.uid}`"
45
+ :class="labelClasses"
46
+ v-html="label")
37
47
  </template>
38
48
 
39
49
  <script>
@@ -154,7 +164,7 @@ $inactive-color: #666;
154
164
  position: relative;
155
165
  border-radius: 100%;
156
166
  width: $small-form-el-size;
157
- height: $small-form-el-size;
167
+ aspect-ratio: 1;
158
168
  display: flex;
159
169
  flex: 0 0 auto; // Prevent stretching width or height.
160
170
  align-items: center;
@@ -198,7 +208,7 @@ $inactive-color: #666;
198
208
  content: "";
199
209
  position: absolute;
200
210
  width: inherit;
201
- height: inherit;
211
+ aspect-ratio: 1;
202
212
  background-color: currentColor;
203
213
  border-radius: 100%;
204
214
  transform: scale(0);
@@ -165,7 +165,7 @@ export default {
165
165
  &__button {
166
166
  position: relative;
167
167
  width: 1.1em;
168
- height: 1.1em;
168
+ aspect-ratio: 1;
169
169
  display: inline-flex;
170
170
  align-items: center;
171
171
  justify-content: center;
@@ -215,6 +215,7 @@ export default {
215
215
  position: absolute;
216
216
  left: 0;
217
217
  width: 100%;
218
+ height: 100%;
218
219
  font-size: 1em;
219
220
  justify-content: flex-start;
220
221
  overflow: hidden;
@@ -295,7 +295,7 @@ export default {
295
295
  transform: translateX(-50%);
296
296
  top: 0;
297
297
  width: $base-increment;
298
- height: $base-increment;
298
+ aspect-ratio: 1;
299
299
  background-color: rgba(0, 0, 0, 0.2);
300
300
  border-radius: 99em;
301
301
  // box-shadow: 0 0 0 1px #fff;
@@ -358,7 +358,7 @@ export default {
358
358
  &__thumb {
359
359
  position: absolute;
360
360
  width: 3 * $base-increment;
361
- height: 3 * $base-increment;
361
+ aspect-ratio: 1;
362
362
  left: 100%;
363
363
  top: 50%;
364
364
  transform: translate(-50%, -50%);
@@ -373,7 +373,7 @@ export default {
373
373
  left: 0;
374
374
  top: 0;
375
375
  width: 100%;
376
- height: 100%;
376
+ aspect-ratio: 1;
377
377
  border: none;
378
378
  border-radius: 99em;
379
379
  cursor: pointer;
@@ -452,7 +452,7 @@ export default {
452
452
  transform: translateX(-50%) rotate(-45deg);
453
453
  border-radius: 99em 99em 99em 0;
454
454
  width: 2.8em;
455
- height: 2.8em;
455
+ aspect-ratio: 1;
456
456
 
457
457
  & > div {
458
458
  position: absolute;
@@ -61,7 +61,7 @@ export default {
61
61
  align-self: center;
62
62
  font-size: 2rem;
63
63
  width: 1em;
64
- height: 1em;
64
+ aspect-ratio: 1;
65
65
 
66
66
  &.size--xs {font-size: round(0.9 * divide($base-font-size, 2)) * 2;}
67
67
  &.size--sm {font-size: round(1.5 * $base-font-size);}
@@ -73,7 +73,7 @@ export default {
73
73
  content: '';
74
74
  position: absolute;
75
75
  width: 100%;
76
- height: 100%;
76
+ aspect-ratio: 1;
77
77
  top: 0;
78
78
  left: 0;
79
79
  background-color: currentColor;