Files
n8n-enterprise-unlocked/packages/design-system/src/components/N8nButton/Button.vue
Csaba Tuncsik fc580f7ee8 fix(editor): Fix design system button with icon vertical alignment (#6284)
* fix(editor): Fix design system button with icon vertical alignment

* trigger checks

---------

Co-authored-by: Alex Grozav <alex@grozav.com>
2023-05-24 13:03:46 +02:00

489 lines
11 KiB
Vue

<template>
<button
:class="classes"
:disabled="disabled || loading"
:aria-disabled="ariaDisabled"
:aria-busy="ariaBusy"
aria-live="polite"
v-on="$listeners"
>
<span :class="$style.icon" v-if="loading || icon">
<n8n-spinner v-if="loading" :size="size" />
<n8n-icon v-else-if="icon" :icon="icon" :size="size" />
</span>
<span v-if="label || $slots.default">
<slot>{{ label }}</slot>
</span>
</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import N8nIcon from '../N8nIcon';
import N8nSpinner from '../N8nSpinner';
export default defineComponent({
name: 'n8n-button',
props: {
label: {
type: String,
},
type: {
type: String,
default: 'primary',
validator: (value: string): boolean =>
['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger'].includes(value),
},
size: {
type: String,
default: 'medium',
validator: (value: string): boolean =>
['xmini', 'mini', 'small', 'medium', 'large', 'xlarge'].includes(value),
},
loading: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
outline: {
type: Boolean,
default: false,
},
text: {
type: Boolean,
default: false,
},
icon: {
type: [String, Array],
},
block: {
type: Boolean,
default: false,
},
active: {
type: Boolean,
default: false,
},
float: {
type: String,
validator: (value: string): boolean => ['left', 'right'].includes(value),
},
square: {
type: Boolean,
default: false,
},
},
components: {
N8nSpinner,
N8nIcon,
},
computed: {
ariaBusy(): 'true' | undefined {
return this.loading ? 'true' : undefined;
},
ariaDisabled(): 'true' | undefined {
return this.disabled ? 'true' : undefined;
},
classes(): string {
return (
`button ${this.$style.button} ${this.$style[this.type]}` +
`${this.size ? ` ${this.$style[this.size]}` : ''}` +
`${this.outline ? ` ${this.$style.outline}` : ''}` +
`${this.loading ? ` ${this.$style.loading}` : ''}` +
`${this.float ? ` ${this.$style[`float-${this.float}`]}` : ''}` +
`${this.text ? ` ${this.$style.text}` : ''}` +
`${this.disabled ? ` ${this.$style.disabled}` : ''}` +
`${this.block ? ` ${this.$style.block}` : ''}` +
`${this.active ? ` ${this.$style.active}` : ''}` +
`${this.icon || this.loading ? ` ${this.$style.icon}` : ''}` +
`${this.square ? ` ${this.$style.square}` : ''}`
);
},
},
});
</script>
<style lang="scss" module>
@import '../../css/mixins/utils';
@import '../../css/common/var';
.button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
border: var(--border-width-base) $button-border-color var(--border-style-base);
color: $button-font-color;
background-color: $button-background-color;
font-weight: var(--font-weight-bold);
border-radius: $button-border-radius;
padding: $button-padding-vertical $button-padding-horizontal;
font-size: $button-font-size;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.3s;
@include utils-user-select(none);
&:hover {
color: $button-hover-color;
border-color: $button-hover-border-color;
background-color: $button-hover-background-color;
}
&:focus {
border-color: $button-focus-outline-color;
outline: $focus-outline-width solid $button-focus-outline-color;
}
&:active,
&.active {
color: $button-active-color;
border-color: $button-active-border-color;
background-color: $button-active-background-color;
outline: none;
}
&::-moz-focus-inner {
border: 0;
}
> i {
display: none;
}
> span {
display: flex;
justify-content: center;
align-items: center;
}
span + span {
margin-left: var(--spacing-3xs);
}
}
$loading-overlay-background-color: rgba(255, 255, 255, 0);
/**
* Colors
*/
.secondary {
--button-color: var(--color-primary);
--button-border-color: var(--color-primary);
--button-background-color: var(--color-background-xlight);
--button-active-background-color: var(--color-primary-tint-2);
--button-active-color: var(--color-primary);
--button-active-border-color: var(--color-primary);
--button-hover-background-color: var(--color-primary-tint-3);
--button-hover-color: var(--color-primary);
--button-hover-border-color: var(--color-primary);
--button-focus-outline-color: var(--color-primary-tint-1);
}
.tertiary {
font-weight: var(--font-weight-bold) !important;
--button-background-color: var(--color-background-xlight);
--button-color: var(--color-text-dark);
--button-border-color: var(--color-neutral-850);
--button-active-background-color: var(--color-primary-tint-2);
--button-active-color: var(--color-primary);
--button-active-border-color: var(--color-primary);
--button-hover-background-color: var(--color-neutral-950);
--button-hover-color: var(--color-text-dark);
--button-hover-border-color: var(--color-neutral-800);
--button-focus-outline-color: hsla(
var(--color-neutral-h),
var(--color-neutral-s),
var(--color-neutral-l),
0.2
);
}
.success {
--button-background-color: var(--color-success);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-success);
--button-active-background-color: var(--color-success-350);
--button-active-border-color: var(--color-success-350);
--button-hover-background-color: var(--color-success-450);
--button-hover-border-color: var(--color-success-450);
--button-focus-outline-color: hsla(
var(--color-success-h),
var(--color-success-s),
var(--color-success-l),
0.33
);
}
.warning {
--button-background-color: var(--color-warning);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-warning);
--button-active-background-color: var(--color-warning-500);
--button-active-border-color: var(--color-warning-500);
--button-hover-background-color: var(--color-warning-650);
--button-hover-border-color: var(--color-warning-650);
--button-focus-outline-color: hsla(
var(--color-warning-h),
var(--color-warning-s),
var(--color-warning-l),
0.33
);
}
.danger {
--button-background-color: var(--color-danger);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-danger);
--button-active-color: var(--color-text-xlight);
--button-active-background-color: var(--color-danger-600);
--button-active-border-color: var(--color-danger-600);
--button-hover-background-color: var(--color-danger-700);
--button-hover-border-color: var(--color-danger-700);
--button-focus-outline-color: hsla(
var(--color-danger-h),
var(--color-danger-s),
var(--color-danger-l),
0.33
);
}
/**
* Sizes
*/
.xmini {
--button-padding-vertical: var(--spacing-4xs);
--button-padding-horizontal: var(--spacing-3xs);
--button-font-size: var(--font-size-3xs);
&.square {
height: 22px;
width: 22px;
}
}
.mini {
--button-padding-vertical: var(--spacing-4xs);
--button-padding-horizontal: var(--spacing-2xs);
--button-font-size: var(--font-size-2xs);
&.square {
height: 22px;
width: 22px;
}
}
.small {
--button-padding-vertical: var(--spacing-3xs);
--button-padding-horizontal: var(--spacing-xs);
--button-font-size: var(--font-size-2xs);
&.square {
height: 26px;
width: 26px;
}
}
.medium {
--button-padding-vertical: var(--spacing-2xs);
--button-padding-horizontal: var(--spacing-xs);
--button-font-size: var(--font-size-2xs);
&.square {
height: 30px;
width: 30px;
}
}
.large {
&.square {
height: 42px;
width: 42px;
}
}
.xlarge {
--button-padding-vertical: var(--spacing-xs);
--button-padding-horizontal: var(--spacing-s);
--button-font-size: var(--font-size-m);
&.square {
height: 46px;
width: 46px;
}
}
/**
* Modifiers
*/
.outline {
--button-color: var(--color-primary);
--button-background-color: transparent;
--button-disabled-background-color: transparent;
--button-active-background-color: transparent;
&.primary {
--button-color: var(--color-primary);
--button-border-color: var(--color-primary);
--button-active-background-color: var(--color-primary);
}
&.tertiary {
--button-color: var(--color-text-dark);
}
&.success {
--button-color: var(--color-success);
--button-border-color: var(--color-success);
--button-active-background-color: var(--color-success);
}
&.warning {
--button-color: var(--color-warning);
--button-border-color: var(--color-warning);
--button-active-background-color: var(--color-warning);
}
&.danger {
--button-color: var(--color-danger);
--button-border-color: var(--color-danger);
--button-active-background-color: var(--color-danger);
}
}
.text {
--button-color: var(--color-text-light);
--button-border-color: transparent;
--button-background-color: transparent;
--button-active-color: var(--color-text-light);
--button-active-background-color: transparent;
--button-active-border-color: transparent;
--button-hover-color: var(--color-text-light);
--button-hover-background-color: transparent;
--button-hover-border-color: transparent;
&.primary {
--button-color: var(--color-primary);
--button-active-color: var(--color-primary);
--button-hover-color: var(--color-primary);
}
&.secondary {
--button-color: var(--color-primary-tint-1);
--button-active-color: var(--color-primary-tint-1);
--button-hover-color: var(--color-primary-tint-1);
}
&.success {
--button-color: var(--color-success);
--button-active-color: var(--color-success);
--button-hover-color: var(--color-success);
}
&.tertiary {
--button-hover-color: var(--color-primary);
}
&.warning {
--button-color: var(--color-warning);
--button-active-color: var(--color-warning);
--button-hover-color: var(--color-warning);
}
&.danger {
--button-color: var(--color-danger);
--button-active-color: var(--color-danger);
--button-hover-color: var(--color-danger);
}
&:hover {
text-decoration: underline;
}
}
.loading {
position: relative;
pointer-events: none;
&:before {
pointer-events: none;
content: '';
position: absolute;
left: -1px;
top: -1px;
right: -1px;
bottom: -1px;
border-radius: inherit;
background-color: $loading-overlay-background-color;
}
}
.disabled {
&,
&:hover,
&:active,
&:focus {
cursor: not-allowed;
background-image: none;
color: $button-disabled-font-color;
background-color: $button-disabled-background-color;
border-color: $button-disabled-border-color;
}
}
.transparent {
--button-background-color: transparent;
--button-active-background-color: transparent;
}
.icon {
display: inline-flex;
justify-content: center;
align-items: center;
svg {
display: block;
}
}
.block {
width: 100%;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
</style>