diff options
author | 2023-04-19 21:38:59 +0200 | |
---|---|---|
committer | 2023-04-19 22:33:22 +0200 | |
commit | c45bce36f985a550d7bfad744099b601cb61e449 (patch) | |
tree | 2c5e186db857776a06879dce7529b5396de214b1 /src/ui/c-button | |
parent | df989e24b3937876f094301e33762677d604888a (diff) | |
download | it-tools-c45bce36f985a550d7bfad744099b601cb61e449.tar.gz it-tools-c45bce36f985a550d7bfad744099b601cb61e449.tar.zst it-tools-c45bce36f985a550d7bfad744099b601cb61e449.zip |
refactor(ui): getting ride of naive ui buttons
Diffstat (limited to 'src/ui/c-button')
-rw-r--r-- | src/ui/c-button/c-button.theme.ts | 240 | ||||
-rw-r--r-- | src/ui/c-button/c-button.vue | 113 |
2 files changed, 353 insertions, 0 deletions
diff --git a/src/ui/c-button/c-button.theme.ts b/src/ui/c-button/c-button.theme.ts new file mode 100644 index 0000000..2f25e6f --- /dev/null +++ b/src/ui/c-button/c-button.theme.ts @@ -0,0 +1,240 @@ +import { defineThemes } from '../theme/theme.models'; +import { appThemes } from '../theme/themes'; + +export const { useTheme } = defineThemes({ + dark: { + basic: { + default: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'rgba(255, 255, 255, 0.08)', + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'rgba(255, 255, 255, 0.12)', + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'rgba(255, 255, 255, 0.24)', + }, + + outline: { + color: appThemes.dark.primary.color, + }, + }, + + primary: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.colorPressed, + }, + + outline: { + color: appThemes.dark.primary.color, + }, + }, + + warning: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.colorPressed, + }, + + outline: { + color: appThemes.dark.warning.color, + }, + }, + }, + + text: { + default: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'transparent', + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'rgba(255, 255, 255, 0.12)', + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: 'rgba(255, 255, 255, 0.82)', + }, + + outline: { + color: appThemes.dark.primary.color, + }, + }, + + primary: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.primary.colorPressed, + }, + + outline: { + color: appThemes.dark.primary.color, + }, + }, + + warning: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.dark.warning.colorPressed, + }, + + outline: { + color: appThemes.dark.warning.color, + }, + }, + }, + }, + light: { + basic: { + default: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'rgba(46, 51, 56, 0.05)', + + hover: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'rgba(46, 51, 56, 0.09)', + }, + + pressed: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'rgba(46, 51, 56, 0.22)', + }, + + outline: { + color: appThemes.light.primary.color, + }, + }, + + primary: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.primary.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.primary.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.primary.colorPressed, + }, + + outline: { + color: appThemes.light.primary.color, + }, + }, + + warning: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.warning.color, + + hover: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.warning.colorHover, + }, + + pressed: { + textColor: appThemes.dark.text.baseColor, + backgroundColor: appThemes.light.warning.colorPressed, + }, + + outline: { + color: appThemes.light.warning.color, + }, + }, + }, + text: { + default: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'transparent', + + hover: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'rgba(46, 51, 56, 0.09)', + }, + + pressed: { + textColor: appThemes.light.text.baseColor, + backgroundColor: 'rgba(46, 51, 56, 0.13)', + }, + + outline: { + color: appThemes.light.primary.color, + }, + }, + primary: { + textColor: appThemes.light.primary.color, + backgroundColor: 'transparent', + + hover: { + textColor: appThemes.light.primary.colorHover, + backgroundColor: 'rgba(46, 51, 56, 0.09)', + }, + + pressed: { + textColor: appThemes.light.primary.colorPressed, + backgroundColor: 'rgba(46, 51, 56, 0.13)', + }, + + outline: { + color: appThemes.light.primary.color, + }, + }, + warning: { + textColor: appThemes.light.warning.color, + backgroundColor: 'transparent', + + hover: { + textColor: appThemes.light.warning.colorHover, + backgroundColor: 'rgba(46, 51, 56, 0.09)', + }, + + pressed: { + textColor: appThemes.light.warning.colorPressed, + backgroundColor: 'rgba(46, 51, 56, 0.13)', + }, + + outline: { + color: appThemes.light.warning.color, + }, + }, + }, + }, +}); diff --git a/src/ui/c-button/c-button.vue b/src/ui/c-button/c-button.vue new file mode 100644 index 0000000..a179cc2 --- /dev/null +++ b/src/ui/c-button/c-button.vue @@ -0,0 +1,113 @@ +<template> + <component + :is="tag" + :href="href ?? to" + class="c-button" + :class="{ disabled, round, circle }" + :to="to" + @click="handleClick" + > + <slot /> + </component> +</template> + +<script lang="ts" setup> +import type { RouteLocationRaw } from 'vue-router'; +import { useTheme } from './c-button.theme'; + +const props = withDefaults( + defineProps<{ + type?: 'default' | 'primary'; + variant?: 'basic' | 'text'; + disabled?: boolean; + round?: boolean; + circle?: boolean; + href?: string; + to?: RouteLocationRaw; + }>(), + { + type: 'default', + variant: 'basic', + disabled: false, + round: false, + circle: false, + href: undefined, + to: undefined, + }, +); +const { variant, disabled, round, circle, href, type, to } = toRefs(props); + +const emits = defineEmits(['click']); + +function handleClick(event: MouseEvent) { + if (!disabled.value) { + emits('click', event); + } +} + +const theme = useTheme(); +const variantTheme = computed(() => theme.value[variant.value][type.value]); +const tag = computed(() => { + if (href.value) { + return 'a'; + } + if (to.value) { + return 'router-link'; + } + return 'button'; +}); +</script> + +<style lang="less" scoped> +.c-button { + margin: 0; + line-height: 1; + font-family: inherit; + font-size: inherit; + border: none; + text-align: center; + cursor: pointer; + text-decoration: none; + height: 34px; + font-weight: 400; + color: v-bind('variantTheme.textColor'); + padding: 0 14px; + border-radius: 4px; + transition: background-color cubic-bezier(0.4, 0, 0.2, 1) 0.3s; + + background-color: v-bind('variantTheme.backgroundColor'); + display: inline-flex; + flex-direction: row; + align-items: center; + justify-content: center; + + // outline-offset: 1px; + &.round { + border-radius: 100px; + } + + &.circle { + border-radius: 40px; + width: 34px; + } + + &:not(.disabled) { + &:hover { + background-color: v-bind('variantTheme.hover.backgroundColor'); + } + + &:active { + background-color: v-bind('variantTheme.pressed.backgroundColor'); + } + } + + &:focus { + outline: 2px solid v-bind('variantTheme.outline.color'); + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } +} +</style> |