| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <template>
- <div class="add-item" :class="{ active }">
- <div class="add-item__prefix">
- <slot name="prefix"></slot>
- </div>
- <img :src="icon || PlaeceHolderAddIcon" alt="" />
- <div v-if="isEditing">
- <input
- ref="inputRef"
- v-model="editingContent"
- @blur="saveEdit"
- @keyup.enter="saveEdit"
- @keyup.esc="cancelEdit"
- class="add-item__input"
- />
- </div>
- <span v-else @dblclick="icon ? startEdit() : null" class="add-item__content">
- {{ content }}
- </span>
- <div class="add-item__suffix">
- <slot name="suffix"></slot>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref } from 'vue';
- import PlaeceHolderAddIcon from 'assets/svg/placeholder-add-item.svg';
- const props = defineProps<{
- icon?: string;
- active?: boolean;
- content: string;
- }>();
- const emit = defineEmits<{
- (e: 'update:content', value: string): void;
- }>();
- const isEditing = ref(false);
- const editingContent = ref(props.content);
- const inputRef = ref<HTMLInputElement | null>(null);
- function startEdit() {
- if (!props.icon) return;
- isEditing.value = true;
- editingContent.value = props.content;
- setTimeout(() => {
- inputRef.value?.focus();
- });
- }
- function saveEdit() {
- if (editingContent.value.trim() !== '') {
- emit('update:content', editingContent.value);
- } else {
- editingContent.value = props.content;
- }
- isEditing.value = false;
- }
- function cancelEdit() {
- editingContent.value = props.content;
- isEditing.value = false;
- }
- </script>
- <style lang="scss" scoped>
- .add-item {
- display: flex;
- align-items: center;
- gap: 12px;
- width: 100%;
- height: 24px;
- font-size: 14px;
- color: $text-color;
-
- img {
- height: 100%;
- }
-
- &.active {
- color: $white-color;
- }
-
- &__content {
- flex-grow: 1;
- }
-
- &__prefix,
- &__suffix {
- display: flex;
- align-items: center;
- cursor: pointer;
- }
-
- &__suffix {
- margin-left: auto;
- }
-
- &__input {
- width: 100%;
- height: 100%;
- font-size: 14px;
- border: 1px solid $text-color;
- border-radius: 4px;
- color: $text-color;
- padding: 2px 10px;
- outline: none;
- border: none;
- }
- }
- </style>
|