feat: make QuoteCard editable
This commit is contained in:
parent
39dff4a928
commit
3c1ed677d8
@ -15,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pinia/nuxt": "^0.3.1",
|
"@pinia/nuxt": "^0.3.1",
|
||||||
"build-url": "^6.0.1"
|
"build-url": "^6.0.1",
|
||||||
|
"vue-contenteditable": "^4.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ $alert-border: 2px solid #F0A0A0;
|
|||||||
$quote-background-color: #ffff88;
|
$quote-background-color: #ffff88;
|
||||||
$quote-border: none;
|
$quote-border: none;
|
||||||
$quote-text-color: #384048;
|
$quote-text-color: #384048;
|
||||||
|
$quote-editmode-background-color: #ffcc88;
|
||||||
$quote-new-background-color: none;
|
$quote-new-background-color: none;
|
||||||
$quote-new-border: 5px dashed #ffffff;
|
$quote-new-border: 5px dashed #ffffff;
|
||||||
$quote-new-text-color: #ffffff;
|
$quote-new-text-color: #ffffff;
|
||||||
|
@ -1,19 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['quote-card__container', { 'quote-card__container__editable': editable }]">
|
<div class="quote-card__container"
|
||||||
|
:class="{ 'quote-card__container__editable': editable, 'quote-card__container__editable__edit-mode': isEditMode }">
|
||||||
|
|
||||||
<div v-if="editable" class="quote-card__action-buttons">
|
<div v-if="editable" class="quote-card__action-buttons">
|
||||||
<QuoteCardActionButton @click="editQuote" icon="edit" />
|
<QuoteCardActionButton @click="editQuote" icon="edit" />
|
||||||
<QuoteCardActionButton @click="deleteQuote" icon="trash" />
|
<QuoteCardActionButton @click="deleteQuote" icon="trash" />
|
||||||
</div>
|
</div>
|
||||||
<div class="quote-card__text-container">
|
<div class="quote-card__text-container">
|
||||||
<div :id="quoteElId" class="quote-card__quote" :contenteditable="isEditMode">
|
<contenteditable
|
||||||
{{ quote.quote }}
|
:id="quoteElId"
|
||||||
</div>
|
class="quote-card__quote"
|
||||||
|
tag="div"
|
||||||
|
:contenteditable="isEditMode"
|
||||||
|
v-model="quote.quote"
|
||||||
|
:no-nl="true"
|
||||||
|
:no-html="true"
|
||||||
|
@returned="saveQuote"
|
||||||
|
@blur="saveQuote"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import contenteditable from 'vue-contenteditable'
|
||||||
import useEngine from '@/composables/useEngine'
|
import useEngine from '@/composables/useEngine'
|
||||||
import type { Quote } from '@/composables/engine.d'
|
import type { Quote } from '@/composables/engine.d'
|
||||||
|
|
||||||
@ -39,6 +50,19 @@ const editQuote = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deleteQuote = () => useEngine().deleteQuote(props.quote.id)
|
const deleteQuote = () => useEngine().deleteQuote(props.quote.id)
|
||||||
|
|
||||||
|
const saveQuote = () => {
|
||||||
|
isEditMode.value = false
|
||||||
|
useEngine().saveQuote(props.quote.id, props.quote.quote)
|
||||||
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
const $el = document.getElementById(quoteElId)
|
||||||
|
$el.blur()
|
||||||
|
const sel = window.getSelection()
|
||||||
|
sel.removeAllRanges()
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -55,15 +79,19 @@ const deleteQuote = () => useEngine().deleteQuote(props.quote.id)
|
|||||||
border: $quote-border;
|
border: $quote-border;
|
||||||
border-radius: 0 16px 0 0;
|
border-radius: 0 16px 0 0;
|
||||||
color: $quote-text-color;
|
color: $quote-text-color;
|
||||||
}
|
|
||||||
|
|
||||||
&__editable {
|
&__editable {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
|
|
||||||
|
&__edit-mode {
|
||||||
|
background-color: $quote-editmode-background-color;
|
||||||
|
}
|
||||||
|
|
||||||
& .quote-card__quote {
|
& .quote-card__quote {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__text-container {
|
&__text-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -74,12 +102,12 @@ const deleteQuote = () => useEngine().deleteQuote(props.quote.id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__quote {
|
&__quote {
|
||||||
|
margin: 2px;
|
||||||
font-family: $font-secondary;
|
font-family: $font-secondary;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__container__editable:hover &__action-buttons {
|
&__container__editable:hover &__action-buttons {
|
||||||
|
@ -4212,6 +4212,11 @@ vue-bundle-renderer@^0.3.9:
|
|||||||
dependencies:
|
dependencies:
|
||||||
bundle-runner "^0.0.1"
|
bundle-runner "^0.0.1"
|
||||||
|
|
||||||
|
vue-contenteditable@^4.0.4:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-contenteditable/-/vue-contenteditable-4.0.4.tgz#914b184bc8d8985b07a1b5ddd9290328a778561d"
|
||||||
|
integrity sha512-v29iTxGyhReWsnSyi5geFf/S1vuI+HxOt90vtAn3BlhIuIsAqsjMqsjA1LHNpYhxBTpvoLXdDCye4Gzu26uGGQ==
|
||||||
|
|
||||||
vue-demi@*:
|
vue-demi@*:
|
||||||
version "0.13.6"
|
version "0.13.6"
|
||||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.6.tgz#f9433cbd75e68a970dec066647f4ba6c08ced48f"
|
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.6.tgz#f9433cbd75e68a970dec066647f4ba6c08ced48f"
|
||||||
|
Loading…
Reference in New Issue
Block a user