refactor(ui): user can edit pill content
This commit is contained in:
parent
f48b7c59d5
commit
e5371cddaf
|
@ -1,11 +1,17 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { type ColorProps, type PastelProps, type VariantProps, type RaisedProps, color } from '~/composables/color'
|
||||
|
||||
|
||||
const input = ref();
|
||||
const emit = defineEmits<{
|
||||
click: [event: MouseEvent]
|
||||
}>()
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
emit('click', event)
|
||||
emit('click', event);
|
||||
if (model.value !== undefined) {
|
||||
(input.value as HTMLInputElement).focus();
|
||||
}
|
||||
}
|
||||
const props = defineProps<{ noUnderline?:true } & (PastelProps | ColorProps) & VariantProps & RaisedProps>()
|
||||
const model = defineModel<string>()
|
||||
|
@ -22,7 +28,16 @@ const model = defineModel<string>()
|
|||
<div v-if="!!$slots.image" class="pill-image">
|
||||
<slot name="image" />
|
||||
</div>
|
||||
<input v-if="model" class="pill-content" v-model="model" style="border-radius:16px; min-width: max-content; width:min-content;" />
|
||||
<!-- TODO: Sanitize text on blur? -->
|
||||
<span contenteditable
|
||||
v-if="model !== undefined"
|
||||
ref="input"
|
||||
class="pill-content"
|
||||
@keydown.enter="(e) => (e.target as HTMLInputElement).blur()"
|
||||
@blur="(e) => model = (e.target as HTMLInputElement).innerText.trim()"
|
||||
>
|
||||
{{ model }}
|
||||
</span>
|
||||
<div class="pill-content" v-if="!!$slots.default">
|
||||
<slot />
|
||||
</div>
|
||||
|
@ -32,10 +47,15 @@ const model = defineModel<string>()
|
|||
<style lang="scss">
|
||||
@import './pill.scss';
|
||||
label.funkwhale.pill.pill {
|
||||
height: 28px;
|
||||
>input {
|
||||
min-width: 40px;
|
||||
min-height: 28px;
|
||||
white-space: pre;
|
||||
cursor: text;
|
||||
> span[contenteditable] {
|
||||
// Note that <Input>s can't be styled with `min-width` or `width` directly.
|
||||
width: 120px;
|
||||
// SOLUTION: Contenteditable. Everything else is a dirty hack.
|
||||
border-radius:16px;
|
||||
outline: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -156,24 +156,32 @@ Image pills contain a small circular image on their left. These can be used for
|
|||
|
||||
## Editable pill
|
||||
|
||||
Add `v-model="..."` to link the pill content to a `ref`. Note that the pill is not rendered if v-model is ''.
|
||||
Add `v-model="..."` to link the pill content to a `ref`.
|
||||
|
||||
```ts
|
||||
import { computed, ref } from "vue";
|
||||
const customTag = ref(" ");
|
||||
const isDeleted = computed(() => customTag.value === "");
|
||||
import { ref } from "vue";
|
||||
const customTag = ref("Custom Tag");
|
||||
```
|
||||
|
||||
```vue-html
|
||||
<Pill v-model="customTag" />
|
||||
|
||||
<Button primary v-if="isDeleted" :onClick="() => customTag=' '">New Pill</Button>
|
||||
<Button primary low-height
|
||||
:disabled="customTag === ''"
|
||||
:onClick="() => customTag = ''"
|
||||
>
|
||||
Reset: {{ customTag }}
|
||||
</Button>
|
||||
|
||||
```
|
||||
|
||||
<Pill v-model="customTag">
|
||||
<template #image>
|
||||
<div style="background-color: #0004" />
|
||||
</template>
|
||||
</Pill>
|
||||
<Pill no-underline v-model="customTag" />
|
||||
|
||||
<Button primary v-if="isDeleted" :onClick="() => customTag=' '">New Pill</Button>
|
||||
Edit the text, then hit Enter or click outside. The button will show the updated text.
|
||||
|
||||
<Button primary low-height
|
||||
:disabled="customTag === ''"
|
||||
:onClick="() => customTag = ''"
|
||||
>
|
||||
Reset: {{ customTag }}
|
||||
</Button>
|
||||
|
|
Loading…
Reference in New Issue