mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
125 lines
3.4 KiB
Vue
125 lines
3.4 KiB
Vue
<template>
|
|
<div class="clickToEdit" :class="{ empty: !value.length }">
|
|
<component :is="tagName" class="m-0" v-if="!editing" @click="toggleEdit(true)">
|
|
<span class="editable"></span>
|
|
<span>{{ displayValue }}</span>
|
|
<slot name="tooltip" :editing="editing" :localValue="localValue"></slot>
|
|
</component>
|
|
|
|
<component :is="tagName" v-if="editing">
|
|
<slot
|
|
:toggleEdit="toggleEdit"
|
|
:editing="editing"
|
|
:placeholder="placeholder"
|
|
:stateValidator="stateValidator">
|
|
<debounced-input v-model="localValue" :delay="debounceDelay">
|
|
<template v-slot="{ value: debouncedValue, input }">
|
|
<b-form-input
|
|
ref="clickToEditInput"
|
|
:value="debouncedValue"
|
|
@input="input"
|
|
@blur="toggleEdit(false)"
|
|
:autofocus="true"
|
|
:placeholder="placeholder"
|
|
:state="stateValidator(debouncedValue, localValue)" />
|
|
</template>
|
|
</debounced-input>
|
|
</slot>
|
|
</component>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import DebouncedInput from "./DebouncedInput";
|
|
|
|
const defaultStateValidator = (val, origVal) => {
|
|
if (val === origVal) {
|
|
return null;
|
|
}
|
|
return val.length > 0;
|
|
};
|
|
|
|
export default {
|
|
components: {
|
|
DebouncedInput,
|
|
},
|
|
props: {
|
|
value: { type: String, required: true },
|
|
tagName: { type: String, required: false, default: "h2" },
|
|
placeholder: { type: String, required: false, default: "" },
|
|
stateValidator: { type: Function, required: false, default: defaultStateValidator },
|
|
debounceDelay: { type: Number, required: false, default: 1000 },
|
|
},
|
|
data() {
|
|
return {
|
|
editing: false,
|
|
};
|
|
},
|
|
computed: {
|
|
displayValue() {
|
|
return this.localValue || this.placeholder;
|
|
},
|
|
localValue: {
|
|
get() {
|
|
return this.value;
|
|
},
|
|
set(newVal, oldVal) {
|
|
if (newVal !== oldVal) {
|
|
this.$emit("input", newVal);
|
|
// closes click to edit if it didn't close on its own
|
|
this.$refs["clickToEditInput"].blur();
|
|
}
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
toggleEdit(forceVal) {
|
|
this.editing = forceVal !== undefined ? forceVal : !this.editing;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "theme/blue.scss";
|
|
@import "~scss/mixins.scss";
|
|
|
|
.clickToEdit {
|
|
position: relative;
|
|
&:hover .editable {
|
|
@include fontawesome($fa-var-edit);
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
color: $brand-info;
|
|
font-size: 0.8rem;
|
|
}
|
|
/* changes placeholder text, it's a brittle and ugly selector
|
|
but bootstrap-vue doesn't give us much to work with */
|
|
&.empty > p > span {
|
|
color: adjust-color($text-color, $alpha: -0.6);
|
|
font-style: italic;
|
|
}
|
|
}
|
|
|
|
h1 input {
|
|
font-size: $h1-font-size;
|
|
font-weight: 500;
|
|
}
|
|
|
|
h2 input {
|
|
font-size: $h2-font-size;
|
|
font-weight: 500;
|
|
}
|
|
|
|
h3 input {
|
|
font-size: $h3-font-size;
|
|
font-weight: 500;
|
|
}
|
|
|
|
h4 input {
|
|
font-size: $h4-font-size;
|
|
font-weight: 500;
|
|
}
|
|
</style>
|