Files
mixtape/zero.Backoffice.UI/app/components/ui-button.vue
T

162 lines
4.0 KiB
Vue
Raw Normal View History

2020-03-27 01:17:22 +01:00
<template>
2021-12-10 14:23:14 +01:00
<button :type="buttonType" class="ui-button has-state" :class="buttonClass" :disabled="disabled || state == 'loading' || !isDefaultState" @click="tryClick">
2020-06-24 16:01:24 +02:00
<span v-if="label" class="ui-button-text" v-localize:html="label"></span>
2021-01-17 20:04:43 +01:00
<ui-icon v-if="caret" :symbol="caretSymbol" class="ui-button-caret" />
2021-09-11 12:01:13 +02:00
<ui-icon v-if="icon" :symbol="icon" class="ui-button-icon" :stroke="stroke" />
2020-04-09 13:06:15 +02:00
<span v-if="!isDefaultState" class="ui-button-state">
2020-04-10 11:12:11 +02:00
<i v-if="stateDisplay == 'loading'" class="ui-button-progress"></i>
2021-01-17 20:04:43 +01:00
<ui-icon v-if="stateDisplay == 'success'" symbol="fth-check" />
<ui-icon v-if="stateDisplay == 'error'" symbol="fth-x" />
2020-04-09 13:06:15 +02:00
</span>
2020-03-27 01:17:22 +01:00
</button>
</template>
<script>
2020-04-09 15:53:03 +02:00
const STATE_DEFAULT = 'default';
const STATE_LOADING = 'loading';
const STATE_SUCCESS = 'success';
const STATE_ERROR = 'error';
const STATES = [STATE_DEFAULT, STATE_LOADING, STATE_SUCCESS, STATE_ERROR];
2020-03-27 01:17:22 +01:00
export default {
name: 'uiButton',
props: {
label: {
2021-11-11 13:46:03 +01:00
type: [String, Object]
2020-03-27 01:17:22 +01:00
},
state: {
type: String,
2020-04-09 15:53:03 +02:00
default: STATE_DEFAULT
},
submit: {
type: Boolean,
default: false
2020-03-27 01:17:22 +01:00
},
2020-03-30 17:11:56 +02:00
type: {
2020-03-27 01:17:22 +01:00
type: String,
default: 'action'
},
2020-04-07 00:11:35 +02:00
icon: {
type: String
},
2021-09-11 12:01:13 +02:00
stroke: {
type: Number,
default: 2
},
2020-03-30 17:46:29 +02:00
caret: String,
caretPosition: {
type: String,
default: 'right'
},
2020-04-03 14:27:39 +02:00
disabled: Boolean,
2020-04-09 13:06:15 +02:00
stateDuration: {
type: Number,
default: 2000
2020-04-09 15:53:03 +02:00
},
2020-04-10 19:17:37 +02:00
ellipsis: {
2020-04-09 15:53:03 +02:00
type: Boolean,
default: false
2020-10-09 15:26:26 +02:00
},
attach: {
type: Boolean,
default: false
2020-04-03 14:27:39 +02:00
}
2020-03-27 01:17:22 +01:00
},
2020-04-09 13:06:15 +02:00
data: () => ({
2020-04-10 11:12:11 +02:00
stateDisplay: null,
2020-04-10 01:17:16 +02:00
stateTimeout: null
2020-04-09 13:06:15 +02:00
}),
2020-04-10 11:12:11 +02:00
created()
{
this.stateDisplay = this.state;
},
2020-03-27 01:17:22 +01:00
computed: {
2020-04-09 15:53:03 +02:00
buttonType()
{
return this.submit ? 'submit' : 'button';
},
2020-04-09 13:06:15 +02:00
buttonClass()
{
let classes = [];
classes.push('type-' + this.type.split(' ').join(' type-'));
2020-04-10 11:12:11 +02:00
classes.push('state-' + (this.isDefaultState ? STATE_DEFAULT : this.stateDisplay));
2020-04-09 13:06:15 +02:00
2020-04-10 11:12:11 +02:00
if (this.caret)
{
classes.push('caret-' + this.caretPosition);
}
2020-04-09 13:06:15 +02:00
if (this.icon)
{
classes.push('has-icon');
}
2020-04-10 19:17:37 +02:00
if (this.ellipsis)
2020-04-09 15:53:03 +02:00
{
classes.push('has-ellipsis');
}
2020-06-24 16:01:24 +02:00
if (!this.label)
{
classes.push('no-label');
}
2020-10-09 15:26:26 +02:00
if (this.attach)
{
classes.push('is-attached');
}
2020-04-09 13:06:15 +02:00
return classes;
},
2021-01-17 20:04:43 +01:00
caretSymbol()
2020-04-09 13:06:15 +02:00
{
return 'fth-chevron-' + this.caret;
},
isDefaultState()
{
2020-04-10 11:12:11 +02:00
return !this.stateDisplay || this.stateDisplay === STATE_DEFAULT || STATES.indexOf(this.stateDisplay) < 0;
2020-04-09 13:06:15 +02:00
}
},
watch: {
state(value)
{
2020-04-10 11:12:11 +02:00
this.stateDisplay = value;
2020-04-09 13:06:15 +02:00
clearTimeout(this.stateTimeout);
2020-04-09 15:53:03 +02:00
if (value && STATES.indexOf(value) < 0)
{
console.warn(`ui-button: Supported states are "${STATES.join('", "')}"`);
}
if (value === STATE_SUCCESS || value === STATE_ERROR)
2020-04-09 13:06:15 +02:00
{
this.stateTimeout = setTimeout(() =>
{
//const stateUpdate = 'update:state';
//// check if :state property has .sync modifier
//let listeners = this.$options._parentListeners;
//const hasSyncModifier = listeners && listeners[stateUpdate];
//if (!hasSyncModifier)
//{
// console.warn(`ui-button: Add the .sync modifier to the "state" property, as changing the state to "${STATE_SUCCESS}" or "${STATE_ERROR}" will automatically set it back to "${STATE_DEFAULT}" after the state duration timeout`);
//}
2020-04-10 11:12:11 +02:00
this.stateDisplay = STATE_DEFAULT;
2020-04-09 13:06:15 +02:00
}, this.stateDuration);
}
}
2021-12-10 14:23:14 +01:00
},
methods: {
tryClick(ev)
{
this.$emit('click', ev);
}
2020-03-27 01:17:22 +01:00
}
}
2020-03-30 17:46:29 +02:00
</script>