feat(lite/buttons): Add multiple button colors, outlined and transparent (#6393)
This commit is contained in:
parent
6d1086539e
commit
94b2b8ec70
@ -73,7 +73,6 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, watch } from "vue";
|
import { computed, watch } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import type {
|
import type {
|
||||||
Filter,
|
Filter,
|
||||||
FilterComparisonType,
|
FilterComparisonType,
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
:class="[
|
:class="className"
|
||||||
`color-${buttonColor}`,
|
|
||||||
{ busy: isBusy, disabled: isDisabled, active },
|
|
||||||
]"
|
|
||||||
:disabled="isBusy || isDisabled"
|
:disabled="isBusy || isDisabled"
|
||||||
:type="type || 'button'"
|
:type="type || 'button'"
|
||||||
class="ui-button"
|
class="ui-button"
|
||||||
>
|
>
|
||||||
<UiIcon :busy="isBusy" :icon="icon" class="icon" />
|
<span v-if="isBusy" class="loader" />
|
||||||
<slot v-if="!isBusy" />
|
<template v-else>
|
||||||
|
<UiIcon :icon="icon" class="icon" />
|
||||||
|
<slot />
|
||||||
|
</template>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, unref } from "vue";
|
import { computed, inject, unref } from "vue";
|
||||||
|
import type { Color } from "@/types";
|
||||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||||
|
|
||||||
@ -24,10 +25,12 @@ const props = withDefaults(
|
|||||||
busy?: boolean;
|
busy?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
icon?: IconDefinition;
|
icon?: IconDefinition;
|
||||||
color?: "primary" | "secondary";
|
color?: Color;
|
||||||
|
outlined?: boolean;
|
||||||
|
transparent?: boolean;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{ busy: undefined, disabled: undefined }
|
{ busy: undefined, disabled: undefined, outlined: undefined }
|
||||||
);
|
);
|
||||||
|
|
||||||
const isGroupBusy = inject("isButtonGroupBusy", false);
|
const isGroupBusy = inject("isButtonGroupBusy", false);
|
||||||
@ -36,8 +39,24 @@ const isBusy = computed(() => props.busy ?? unref(isGroupBusy));
|
|||||||
const isGroupDisabled = inject("isButtonGroupDisabled", false);
|
const isGroupDisabled = inject("isButtonGroupDisabled", false);
|
||||||
const isDisabled = computed(() => props.disabled ?? unref(isGroupDisabled));
|
const isDisabled = computed(() => props.disabled ?? unref(isGroupDisabled));
|
||||||
|
|
||||||
const buttonGroupColor = inject("buttonGroupColor", "primary");
|
const isGroupOutlined = inject("isButtonGroupOutlined", false);
|
||||||
|
const isGroupTransparent = inject("isButtonGroupTransparent", false);
|
||||||
|
|
||||||
|
const buttonGroupColor = inject("buttonGroupColor", "info");
|
||||||
const buttonColor = computed(() => props.color ?? unref(buttonGroupColor));
|
const buttonColor = computed(() => props.color ?? unref(buttonGroupColor));
|
||||||
|
|
||||||
|
const className = computed(() => {
|
||||||
|
return [
|
||||||
|
`color-${buttonColor.value}`,
|
||||||
|
{
|
||||||
|
busy: isBusy.value,
|
||||||
|
active: props.active,
|
||||||
|
disabled: isDisabled.value,
|
||||||
|
outlined: props.outlined ?? unref(isGroupOutlined),
|
||||||
|
transparent: props.transparent ?? unref(isGroupTransparent),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="postcss" scoped>
|
<style lang="postcss" scoped>
|
||||||
@ -47,57 +66,117 @@ const buttonColor = computed(() => props.color ?? unref(buttonGroupColor));
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 5em;
|
|
||||||
min-height: 2.5em;
|
min-height: 2.5em;
|
||||||
padding: 0 0.75em;
|
padding: 0 0.75em;
|
||||||
|
cursor: pointer;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
border: none;
|
color: var(--button-color);
|
||||||
border-radius: 0.4em;
|
border: 1px solid var(--button-border-color);
|
||||||
box-shadow: var(--shadow-100);
|
border-radius: 0.5em;
|
||||||
|
background-color: var(--button-background-color);
|
||||||
gap: 0.75em;
|
gap: 0.75em;
|
||||||
|
|
||||||
|
&:not(.transparent) {
|
||||||
|
box-shadow: var(--shadow-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-info {
|
||||||
|
--button-accent-color: var(--color-extra-blue-base);
|
||||||
|
--button-accent-color-hover: var(--color-extra-blue-d20);
|
||||||
|
--button-accent-color-active: var(--color-extra-blue-d40);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-success {
|
||||||
|
--button-accent-color: var(--color-green-infra-base);
|
||||||
|
--button-accent-color-hover: var(--color-green-infra-d20);
|
||||||
|
--button-accent-color-active: var(--color-green-infra-d40);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-warning {
|
||||||
|
--button-accent-color: var(--color-orange-world-base);
|
||||||
|
--button-accent-color-hover: var(--color-orange-world-d20);
|
||||||
|
--button-accent-color-active: var(--color-orange-world-d40);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-error {
|
||||||
|
--button-accent-color: var(--color-red-vates-base);
|
||||||
|
--button-accent-color-hover: var(--color-red-vates-d20);
|
||||||
|
--button-accent-color-active: var(--color-red-vates-d40);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
--button-accent-color: var(--button-accent-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active,
|
||||||
|
&.busy {
|
||||||
|
--button-accent-color: var(--button-accent-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
--button-color: var(--color-blue-scale-500);
|
||||||
|
--button-border-color: transparent;
|
||||||
|
--button-background-color: var(--button-accent-color);
|
||||||
|
|
||||||
|
&.outlined {
|
||||||
|
--button-color: var(--button-accent-color);
|
||||||
|
--button-border-color: var(--button-accent-color);
|
||||||
|
--button-background-color: var(--background-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.transparent {
|
||||||
|
--button-color: var(--button-accent-color);
|
||||||
|
--button-border-color: transparent;
|
||||||
|
--button-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.busy {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
color: var(--color-blue-scale-400);
|
cursor: not-allowed;
|
||||||
background-color: var(--background-color-secondary);
|
--button-color: var(--color-blue-scale-400);
|
||||||
}
|
--button-border-color: transparent;
|
||||||
|
--button-background-color: var(--background-color-secondary);
|
||||||
&:not(.disabled) {
|
|
||||||
&.color-primary {
|
|
||||||
color: var(--color-blue-scale-500);
|
|
||||||
background-color: var(--color-extra-blue-base);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--color-extra-blue-d20);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active,
|
|
||||||
&.active,
|
|
||||||
&.busy {
|
|
||||||
background-color: var(--color-extra-blue-d40);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.color-secondary {
|
|
||||||
color: var(--color-extra-blue-base);
|
|
||||||
border: 1px solid var(--color-extra-blue-base);
|
|
||||||
background-color: var(--color-blue-scale-500);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--color-extra-blue-d20);
|
|
||||||
border-color: var(--color-extra-blue-d20);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active,
|
|
||||||
&.active,
|
|
||||||
&.busy {
|
|
||||||
color: var(--color-extra-blue-d40);
|
|
||||||
border-color: var(--color-extra-blue-d40);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
animation: spin 1s infinite linear;
|
||||||
|
border-radius: 0.75em;
|
||||||
|
|
||||||
|
background: conic-gradient(
|
||||||
|
from 90deg at 50% 50%,
|
||||||
|
rgba(255, 255, 255, 0) 0deg,
|
||||||
|
rgba(255, 255, 255, 0) 0.04deg,
|
||||||
|
var(--button-color) 360deg
|
||||||
|
);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
content: "";
|
||||||
|
border-radius: 0.6em;
|
||||||
|
background-color: var(--button-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -6,11 +6,14 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, provide } from "vue";
|
import { computed, provide } from "vue";
|
||||||
|
import type { Color } from "@/types";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
busy?: boolean;
|
busy?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
color?: "primary" | "secondary";
|
color?: Color;
|
||||||
|
outlined?: boolean;
|
||||||
|
transparent?: boolean;
|
||||||
}>();
|
}>();
|
||||||
provide(
|
provide(
|
||||||
"isButtonGroupBusy",
|
"isButtonGroupBusy",
|
||||||
@ -22,7 +25,15 @@ provide(
|
|||||||
);
|
);
|
||||||
provide(
|
provide(
|
||||||
"buttonGroupColor",
|
"buttonGroupColor",
|
||||||
computed(() => props.color ?? "primary")
|
computed(() => props.color ?? "info")
|
||||||
|
);
|
||||||
|
provide(
|
||||||
|
"isButtonGroupOutlined",
|
||||||
|
computed(() => props.outlined ?? false)
|
||||||
|
);
|
||||||
|
provide(
|
||||||
|
"isButtonGroupTransparent",
|
||||||
|
computed(() => props.transparent ?? false)
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
1
@xen-orchestra/lite/src/types/index.ts
Normal file
1
@xen-orchestra/lite/src/types/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export type Color = "info" | "error" | "warning" | "success";
|
Loading…
Reference in New Issue
Block a user