Skip to content

Commit

Permalink
feat(VBtn): add stacked and prepend/append icon props (#13643)
Browse files Browse the repository at this point in the history
Co-authored-by: John Leider <john.j.leider@gmail.com>
  • Loading branch information
KaelWD and johnleider committed May 12, 2021
1 parent 73f4cb5 commit f4ff228
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 10 deletions.
3 changes: 3 additions & 0 deletions packages/api-generator/src/locale/en/v-btn.json
@@ -1,11 +1,14 @@
{
"props": {
"appendIcon": "Adds an icon after the default slot content.",
"block": "Expands the button to 100% of available space.",
"color": "Applies specified color to the control - it can be the name of material color (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). You can find list of built in classes on the [colors page](/styles/colors#material-colors).",
"disabled": "Removes the ability to click or target the component.",
"flat": "Removes the button box shadow.",
"icon": "Designates the button as icon. Button will become _round_ and applies the **text** prop.",
"plain": "Removes the default background change applied when hovering over the button.",
"prependIcon": "Adds an icon before the default slot content.",
"stacked": "Displays the button as a flex-column.",
"text": "Makes the background transparent. When using the **color** prop, the color will be applied to the button text instead of the background."
}
}
Expand Up @@ -6,7 +6,7 @@ exports[`VAppBarNavIcon should match a snapshot 1`] = `
>
<span class="v-btn__overlay">
</span>
<i class="mdi-menu mdi v-icon notranslate v-icon--size-default"
<i class="mdi-menu mdi v-icon notranslate v-icon--size-default v-btn__icon"
aria-hidden="true"
>
</i>
Expand Down
9 changes: 9 additions & 0 deletions packages/vuetify/src/components/VBtn/VBtn.sass
Expand Up @@ -20,6 +20,7 @@
transition-timing-function: $standard-easing
user-select: none
vertical-align: $button-vertical-align
flex-shrink: 0

@at-root
+button-sizes()
Expand Down Expand Up @@ -80,6 +81,14 @@
// so we need to divide it to get the desired value
opacity: ($button-disabled-overlay / $button-disabled-opacity)

&--stacked
flex-direction: column
line-height: $button-stacked-line-height

@at-root
@include button-sizes($button-stacked-sizes, true)
@include density('v-btn', 'height', $button-stacked-density)

.v-btn__overlay
background-color: currentColor
border-radius: inherit
Expand Down
28 changes: 27 additions & 1 deletion packages/vuetify/src/components/VBtn/VBtn.tsx
Expand Up @@ -32,8 +32,11 @@ export default defineComponent({
flat: Boolean,
plain: Boolean,
icon: [Boolean, String],
prependIcon: String,
appendIcon: String,

block: Boolean,
stacked: Boolean,

color: String,
disabled: Boolean,
Expand Down Expand Up @@ -81,6 +84,7 @@ export default defineComponent({
'v-btn--plain': props.plain,
'v-btn--block': props.block,
'v-btn--disabled': props.disabled,
'v-btn--stacked': props.stacked,
},
themeClasses.value,
borderClasses.value,
Expand All @@ -100,10 +104,32 @@ export default defineComponent({
>
<span class="v-btn__overlay" />

{ !props.icon && props.prependIcon && (
<VIcon
class="v-btn__icon"
icon={ props.prependIcon }
left={ !props.stacked }
/>
)}

{ typeof props.icon === 'boolean'
? slots.default?.()
: <VIcon icon={ props.icon } size={ props.size } />
: (
<VIcon
class="v-btn__icon"
icon={ props.icon }
size={ props.size }
/>
)
}

{ !props.icon && props.appendIcon && (
<VIcon
class="v-btn__icon"
icon={ props.appendIcon }
right={ !props.stacked }
/>
)}
</props.tag>,
[useDirective<RippleDirectiveBinding>(Ripple, {
value: !props.disabled,
Expand Down
16 changes: 10 additions & 6 deletions packages/vuetify/src/components/VBtn/_mixins.scss
@@ -1,14 +1,18 @@
@mixin button-sizes {
@function roundEven ($val) {
@return 2 * round($val / 2)
}

@mixin button-sizes ($map: $button-sizes, $immediate: false) {
@each $sizeName, $multiplier in $size-scales {
$size: map-get($button-sizes, 'font-size') + (2 * $multiplier) / 16;
$height: map-get($button-sizes, 'height') + (8 * $multiplier);
$size: map-get($map, 'font-size') + (2 * $multiplier) / 16;
$height: map-get($map, 'height') + (8 * $multiplier);

.v-btn--size-#{$sizeName} {
#{if($immediate, &, '')}.v-btn--size-#{$sizeName} {
--v-btn-size: #{$size};
--v-btn-height: #{$height};
font-size: $size;
min-width: round($height * $button-width-ratio);
padding: 0 ($height / $button-padding-ratio);
min-width: roundEven($height * map-get($map, 'width-ratio'));
padding: 0 roundEven($height / map-get($map, 'padding-ratio'));
}
}
}
20 changes: 19 additions & 1 deletion packages/vuetify/src/components/VBtn/_variables.scss
Expand Up @@ -10,18 +10,23 @@ $button-elevation: ('default': 2, 'hover': 4, 'active': 8) !default;
$button-font-size: map-deep-get($typography, 'button', 'size') !default;
$button-font-weight: map-deep-get($typography, 'button', 'weight') !default;
$button-height: 36px !default;
$button-stacked-height: 72px !default;
$button-icon-border-radius: map-get($rounded, 'circle') !default;
$button-icon-font-size: 24px !default;
$button-icon-size: 48px !default;
$button-line-height: normal !default;
$button-stacked-line-height: 1.7 !default;
$button-padding-ratio: 2.25 !default;
$button-stacked-padding-ratio: 4.5 !default;
$button-positions: absolute fixed !default;
$button-text-letter-spacing: map-deep-get($typography, 'button', 'letter-spacing') !default;
$button-text-transform: map-deep-get($typography, 'button', 'text-transform') !default;
$button-vertical-align: middle !default;
$button-width-ratio: 16/9 !default;
$button-stacked-width-ratio: 1 !default;

$button-density: ('default': 0, 'comfortable': -2, 'compact': -3) !default;
$button-stacked-density: ('default': 0, 'comfortable': -4, 'compact': -6) !default;
$button-icon-density: ('default': 3, 'comfortable': 0, 'compact': -2) !default;

$button-border: () !default;
Expand All @@ -38,11 +43,24 @@ $button-sizes: () !default;
$button-sizes: map-merge(
(
'height': $button-height,
'font-size': $button-font-size
'font-size': $button-font-size,
'width-ratio': $button-width-ratio,
'padding-ratio': $button-padding-ratio
),
$button-sizes
);

$button-stacked-sizes: () !default;
$button-stacked-sizes: map-merge(
(
'height': $button-stacked-height,
'font-size': $button-font-size,
'width-ratio': $button-stacked-width-ratio,
'padding-ratio': $button-stacked-padding-ratio
),
$button-stacked-sizes
);

$button-icon-sizes: () !default;
$button-icon-sizes: map-merge(
(
Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VIcon/VIcon.sass
Expand Up @@ -38,7 +38,7 @@

.v-icon
&--size-default
.v-btn:not(.v-btn--icon) &
.v-btn:not(.v-btn--icon):not(.v-btn--stacked) &
font-size: $icon-btn-font-size
height: $icon-btn-height
width: $icon-btn-width
Expand Down

0 comments on commit f4ff228

Please sign in to comment.