feat: add button component
This commit is contained in:
@@ -40,3 +40,139 @@
|
||||
.hide {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--color-amber-100: 255 243 208;
|
||||
--color-amber-200: 255 236 183;
|
||||
--color-amber-25: 254 253 251;
|
||||
--color-amber-300: 255 224 161;
|
||||
--color-amber-400: 245 208 140;
|
||||
--color-amber-50: 255 249 237;
|
||||
--color-amber-500: 228 187 120;
|
||||
--color-amber-600: 214 163 92;
|
||||
--color-amber-700: 214 163 92;
|
||||
--color-amber-800: 255 186 26;
|
||||
--color-amber-900: 145 89 48;
|
||||
--color-amber-950: 79 52 34;
|
||||
|
||||
--color-ash-100: 235 235 239;
|
||||
--color-ash-200: 228 228 233;
|
||||
--color-ash-25: 252 252 253;
|
||||
--color-ash-300: 221 221 227;
|
||||
--color-ash-400: 211 212 219;
|
||||
--color-ash-50: 249 249 251;
|
||||
--color-ash-500: 185 187 198;
|
||||
--color-ash-600: 139 141 152;
|
||||
--color-ash-700: 126 128 138;
|
||||
--color-ash-75: 242 242 245;
|
||||
--color-ash-800: 96 100 108;
|
||||
--color-ash-900: 28 32 36;
|
||||
|
||||
--color-primary-100: 222 234 255;
|
||||
--color-primary-200: 206 223 255;
|
||||
--color-primary-25: 252 253 254;
|
||||
--color-primary-300: 186 209 255;
|
||||
--color-primary-400: 163 190 255;
|
||||
--color-primary-50: 246 249 255;
|
||||
--color-primary-500: 131 164 250;
|
||||
--color-primary-600: 69 110 255;
|
||||
--color-primary-700: 57 95 241;
|
||||
--color-primary-75: 236 242 255;
|
||||
--color-primary-800: 53 88 217;
|
||||
--color-primary-900: 27 44 99;
|
||||
|
||||
--color-ruby-100: 255 220 225;
|
||||
--color-ruby-200: 255 206 214;
|
||||
--color-ruby-25: 255 252 253;
|
||||
--color-ruby-300: 248 191 200;
|
||||
--color-ruby-400: 239 172 184;
|
||||
--color-ruby-50: 255 247 248;
|
||||
--color-ruby-500: 229 146 163;
|
||||
--color-ruby-600: 229 70 102;
|
||||
--color-ruby-700: 220 59 93;
|
||||
--color-ruby-75: 254 234 237;
|
||||
--color-ruby-800: 202 36 77;
|
||||
--color-ruby-900: 100 23 43;
|
||||
|
||||
--color-teal-100: 224 248 243;
|
||||
--color-teal-200: 204 243 234;
|
||||
--color-teal-25: 250 254 253;
|
||||
--color-teal-300: 184 234 224;
|
||||
--color-teal-400: 161 222 210;
|
||||
--color-teal-50: 243 251 249;
|
||||
--color-teal-500: 83 185 171;
|
||||
--color-teal-600: 18 165 148;
|
||||
--color-teal-700: 13 155 138;
|
||||
--color-teal-75: 236 249 255;
|
||||
--color-teal-800: 0 133 115;
|
||||
--color-teal-900: 13 61 56;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--color-amber-100: 57 39 15;
|
||||
--color-amber-200: 67 46 18;
|
||||
--color-amber-25: 31 19 0;
|
||||
--color-amber-300: 83 57 22;
|
||||
--color-amber-400: 111 77 29;
|
||||
--color-amber-50: 37 24 4;
|
||||
--color-amber-500: 169 118 42;
|
||||
--color-amber-600: 169 118 42;
|
||||
--color-amber-700: 255 203 71;
|
||||
--color-amber-800: 255 204 77;
|
||||
--color-amber-900: 255 231 179;
|
||||
--color-amber-950: 255 231 179;
|
||||
|
||||
--color-ash-100: 46 48 53;
|
||||
--color-ash-200: 53 55 60;
|
||||
--color-ash-25: 24 24 26;
|
||||
--color-ash-300: 60 63 68;
|
||||
--color-ash-400: 70 75 80;
|
||||
--color-ash-50: 27 27 31;
|
||||
--color-ash-500: 90 97 101;
|
||||
--color-ash-600: 105 110 119;
|
||||
--color-ash-700: 120 127 133;
|
||||
--color-ash-75: 39 40 45;
|
||||
--color-ash-800: 173 177 184;
|
||||
--color-ash-900: 237 238 240;
|
||||
|
||||
--color-primary-100: 24 43 109;
|
||||
--color-primary-200: 31 53 129;
|
||||
--color-primary-25: 11 16 31;
|
||||
--color-primary-300: 40 64 146;
|
||||
--color-primary-400: 48 76 168;
|
||||
--color-primary-50: 16 23 41;
|
||||
--color-primary-500: 57 89 196;
|
||||
--color-primary-600: 69 110 255;
|
||||
--color-primary-700: 58 96 240;
|
||||
--color-primary-75: 20 34 81;
|
||||
--color-primary-800: 140 177 255;
|
||||
--color-primary-900: 210 225 255;
|
||||
|
||||
--color-ruby-100: 78 19 37;
|
||||
--color-ruby-200: 94 26 46;
|
||||
--color-ruby-25: 25 17 19;
|
||||
--color-ruby-300: 111 37 57;
|
||||
--color-ruby-400: 136 52 71;
|
||||
--color-ruby-50: 30 21 23;
|
||||
--color-ruby-500: 179 68 90;
|
||||
--color-ruby-600: 229 70 102;
|
||||
--color-ruby-700: 236 90 114;
|
||||
--color-ruby-75: 58 20 30;
|
||||
--color-ruby-800: 255 148 157;
|
||||
--color-ruby-900: 254 210 225;
|
||||
|
||||
--color-teal-100: 2 59 55;
|
||||
--color-teal-200: 8 72 67;
|
||||
--color-teal-25: 13 21 20;
|
||||
--color-teal-300: 28 105 97;
|
||||
--color-teal-400: 28 105 97;
|
||||
--color-teal-50: 17 28 27;
|
||||
--color-teal-500: 32 126 115;
|
||||
--color-teal-600: 41 163 131;
|
||||
--color-teal-700: 14 179 158;
|
||||
--color-teal-75: 13 45 42;
|
||||
--color-teal-800: 11 216 182;
|
||||
--color-teal-900: 173 240 221;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ label {
|
||||
// Focus outline removal
|
||||
.button,
|
||||
textarea,
|
||||
input:focus {
|
||||
input:focus:not(.reset-base) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// scss-lint:disable SpaceAfterPropertyColon
|
||||
// scss-lint:disable MergeableSelector
|
||||
button {
|
||||
button:not(.reset-base) {
|
||||
font-family: inherit;
|
||||
transition:
|
||||
background-color 0.25s ease-out,
|
||||
@@ -96,7 +96,7 @@ button {
|
||||
}
|
||||
|
||||
// @TODDO - Remove after moving all buttons to woot-button
|
||||
.icon+.button__content {
|
||||
.icon + .button__content {
|
||||
@apply w-auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,48 +15,54 @@
|
||||
@update="updateUser"
|
||||
/>
|
||||
|
||||
<form @submit.prevent="updateUser('profile')">
|
||||
<label :class="{ error: $v.name.$error }">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.NAME.LABEL') }}
|
||||
<input
|
||||
v-model="name"
|
||||
type="text"
|
||||
:placeholder="$t('PROFILE_SETTINGS.FORM.NAME.PLACEHOLDER')"
|
||||
@input="$v.name.$touch"
|
||||
/>
|
||||
<span v-if="$v.name.$error" class="message">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.NAME.ERROR') }}
|
||||
</span>
|
||||
</label>
|
||||
<label :class="{ error: $v.displayName.$error }">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.DISPLAY_NAME.LABEL') }}
|
||||
<input
|
||||
v-model="displayName"
|
||||
type="text"
|
||||
:placeholder="
|
||||
$t('PROFILE_SETTINGS.FORM.DISPLAY_NAME.PLACEHOLDER')
|
||||
"
|
||||
@input="$v.displayName.$touch"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
<form
|
||||
class="flex flex-col gap-6"
|
||||
@submit.prevent="updateUser('profile')"
|
||||
>
|
||||
<form-input
|
||||
v-model="name"
|
||||
type="text"
|
||||
name="name"
|
||||
:class="{ error: $v.name.$error }"
|
||||
:label="$t('PROFILE_SETTINGS.FORM.NAME.LABEL')"
|
||||
:placeholder="$t('PROFILE_SETTINGS.FORM.NAME.PLACEHOLDER')"
|
||||
:has-error="$v.name.$error"
|
||||
:error-message="$t('PROFILE_SETTINGS.FORM.NAME.ERROR')"
|
||||
@blur="$v.name.$touch"
|
||||
/>
|
||||
<form-input
|
||||
v-model="displayName"
|
||||
type="text"
|
||||
name="displayName"
|
||||
:class="{ error: $v.displayName.$error }"
|
||||
:label="$t('PROFILE_SETTINGS.FORM.DISPLAY_NAME.LABEL')"
|
||||
:placeholder="$t('PROFILE_SETTINGS.FORM.DISPLAY_NAME.PLACEHOLDER')"
|
||||
:has-error="$v.displayName.$error"
|
||||
:error-message="$t('PROFILE_SETTINGS.FORM.DISPLAY_NAME.ERROR')"
|
||||
@blur="$v.displayName.$touch"
|
||||
/>
|
||||
<form-input
|
||||
v-if="!globalConfig.disableUserProfileUpdate"
|
||||
v-model="email"
|
||||
type="email"
|
||||
name="email"
|
||||
:class="{ error: $v.email.$error }"
|
||||
:label="$t('PROFILE_SETTINGS.FORM.EMAIL.LABEL')"
|
||||
:placeholder="$t('PROFILE_SETTINGS.FORM.EMAIL.PLACEHOLDER')"
|
||||
:has-error="$v.email.$error"
|
||||
:error-message="$t('PROFILE_SETTINGS.FORM.EMAIL.ERROR')"
|
||||
@blur="$v.email.$touch"
|
||||
/>
|
||||
<v3-button
|
||||
type="submit"
|
||||
color-scheme="primary"
|
||||
variant="solid"
|
||||
icon="copy"
|
||||
show-right-icon
|
||||
size="large"
|
||||
>
|
||||
{{ $t('PROFILE_SETTINGS.FORM.EMAIL.LABEL') }}
|
||||
<input
|
||||
v-model.trim="email"
|
||||
type="email"
|
||||
:placeholder="$t('PROFILE_SETTINGS.FORM.EMAIL.PLACEHOLDER')"
|
||||
@input="$v.email.$touch"
|
||||
/>
|
||||
<span v-if="$v.email.$error" class="message">
|
||||
{{ $t('PROFILE_SETTINGS.FORM.EMAIL.ERROR') }}
|
||||
</span>
|
||||
</label>
|
||||
<woot-button type="submit" :is-loading="isProfileUpdating">
|
||||
{{ $t('PROFILE_SETTINGS.BTN_TEXT') }}
|
||||
</woot-button>
|
||||
</v3-button>
|
||||
</form>
|
||||
|
||||
<personal-wrapper
|
||||
@@ -139,6 +145,8 @@ import { mapGetters } from 'vuex';
|
||||
import { clearCookiesOnLogout } from '../../../../store/utils/api';
|
||||
import { hasValidAvatarUrl } from 'dashboard/helper/URLHelper';
|
||||
import NotificationSettings from './NotificationSettings.vue';
|
||||
import FormInput from 'v3/components/Form/Input.vue';
|
||||
import V3Button from 'v3/components/Form/Button.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -149,6 +157,8 @@ export default {
|
||||
ChangePassword,
|
||||
NotificationSettings,
|
||||
AccessToken,
|
||||
FormInput,
|
||||
V3Button,
|
||||
},
|
||||
mixins: [alertMixin, globalConfigMixin, uiSettingsMixin],
|
||||
data() {
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<button
|
||||
class="inline-flex items-center gap-1 text-sm font-medium reset-base rounded-xl w-fit"
|
||||
:type="type"
|
||||
:class="buttonClasses"
|
||||
:disabled="isDisabled || isLoading"
|
||||
@click="handleClick"
|
||||
>
|
||||
<fluent-icon :size="iconSize" :icon="icon" class="flex-shrink-0" />
|
||||
<span
|
||||
v-if="$slots.default"
|
||||
class="text-sm font-medium truncate"
|
||||
:class="{ 'text-left rtl:text-right': size !== 'expanded' }"
|
||||
>
|
||||
<slot />
|
||||
</span>
|
||||
<fluent-icon :size="iconSize" icon="chevron-right" class="flex-shrink-0" />
|
||||
</button>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'submit',
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
emoji: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
colorScheme: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
},
|
||||
classNames: {
|
||||
type: [String, Object],
|
||||
default: '',
|
||||
},
|
||||
isDisabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isExpanded: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
// variantClasses() {
|
||||
// if (this.variant.includes('link')) {
|
||||
// return `clear ${this.variant}`;
|
||||
// }
|
||||
// return this.variant;
|
||||
// },
|
||||
// hasOnlyIcon() {
|
||||
// const hasEmojiOrIcon = this.emoji || this.icon;
|
||||
// return !this.$slots.default && hasEmojiOrIcon;
|
||||
// },
|
||||
// hasOnlyIconClasses() {
|
||||
// return this.hasOnlyIcon ? 'button--only-icon' : '';
|
||||
// },
|
||||
|
||||
buttonClasses() {
|
||||
return [
|
||||
this.colorClass,
|
||||
this.sizeClass,
|
||||
// this.variantClasses,
|
||||
// this.hasOnlyIconClasses,
|
||||
// this.size,
|
||||
// this.colorClass,
|
||||
// this.classNames,
|
||||
// this.isDisabled ? 'disabled' : '',
|
||||
// this.isExpanded ? 'expanded' : '',
|
||||
];
|
||||
},
|
||||
colorClass() {
|
||||
if (this.colorScheme === 'primary') {
|
||||
return 'bg-primary-600 text-white hover:bg-primary-700 active:bg-primary-700 focus:ring focus:ring-offset-1 focus:ring-primary-400';
|
||||
}
|
||||
if (this.colorScheme === 'secondary') {
|
||||
return 'bg-ash-100 text-white hover:bg-ash-200 active:bg-ash-200 focus:ring focus:ring-offset-1 focus:ring-ash-400';
|
||||
}
|
||||
if (this.colorScheme === 'danger') {
|
||||
return 'bg-ruby-600 text-white hover:bg-ruby-700 active:bg-ruby-700 focus:ring focus:ring-offset-1 focus:ring-ruby-400';
|
||||
}
|
||||
return 'bg-primary-500 text-white';
|
||||
},
|
||||
sizeClass() {
|
||||
if (this.size === 'md') {
|
||||
return 'px-3 py-2 text-sm';
|
||||
}
|
||||
return 'px-4 py-2.5 text';
|
||||
},
|
||||
iconSize() {
|
||||
switch (this.size) {
|
||||
case 'tiny':
|
||||
return 12;
|
||||
case 'small':
|
||||
return 14;
|
||||
case 'medium':
|
||||
return 16;
|
||||
case 'large':
|
||||
return 18;
|
||||
|
||||
default:
|
||||
return 16;
|
||||
}
|
||||
},
|
||||
showDarkSpinner() {
|
||||
return (
|
||||
this.colorScheme === 'secondary' ||
|
||||
this.variant === 'clear' ||
|
||||
this.variant === 'link' ||
|
||||
this.variant === 'hollow'
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick(evt) {
|
||||
this.$emit('click', evt);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -20,15 +20,13 @@
|
||||
:data-testid="dataTestid"
|
||||
:value="value"
|
||||
:class="{
|
||||
'focus:outline-red-600 outline-red-600 dark:focus:outline-red-600 dark:outline-red-600':
|
||||
hasError,
|
||||
'outline-slate-200 dark:outline-slate-600 dark:focus:outline-woot-500 focus:outline-woot-500':
|
||||
!hasError,
|
||||
'outline-ruby-600 focus:outline-ruby-600': hasError,
|
||||
'outline-ash-200 focus:outline-primary-500': !hasError,
|
||||
'px-3 py-3': spacing === 'base',
|
||||
'px-3 py-2 mb-0': spacing === 'compact',
|
||||
'pl-9': icon,
|
||||
}"
|
||||
class="block w-full border-none rounded-md shadow-sm appearance-none outline outline-1 focus:outline-2 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 sm:text-sm sm:leading-6 dark:bg-slate-800"
|
||||
class="block w-full h-10 ltr:pl-3 ltr:pr-2 rtl:pl-2 rtl:pr-3 py-2.5 !border-none shadow-sm appearance-none reset-base rounded-xl outline outline-1 focus:outline-1 text-ash-900 placeholder:text-ash-200 sm:text-sm sm:leading-6"
|
||||
@input="onInput"
|
||||
@blur="$emit('blur')"
|
||||
/>
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
<label
|
||||
v-if="label"
|
||||
:for="name"
|
||||
class="flex justify-between text-sm font-medium leading-6 text-slate-900 dark:text-white"
|
||||
:class="{ 'text-red-500': hasError }"
|
||||
class="flex justify-between text-sm font-medium leading-6 text-ash-900"
|
||||
>
|
||||
<slot name="label">
|
||||
{{ label }}
|
||||
@@ -12,18 +11,18 @@
|
||||
<slot name="rightOfLabel" />
|
||||
</label>
|
||||
<div class="w-full">
|
||||
<div class="flex items-center relative w-full">
|
||||
<div class="relative flex items-center w-full">
|
||||
<fluent-icon
|
||||
v-if="icon"
|
||||
size="16"
|
||||
:icon="icon"
|
||||
class="absolute left-2 transform text-slate-400 dark:text-slate-600 w-5 h-5"
|
||||
class="absolute w-5 h-5 transform left-2 text-ash-400"
|
||||
/>
|
||||
<slot />
|
||||
</div>
|
||||
<span
|
||||
v-if="errorMessage && hasError"
|
||||
class="text-xs text-red-400 leading-2"
|
||||
class="text-xs text-ruby-800 leading-2"
|
||||
>
|
||||
{{ errorMessage }}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user