mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 20:18:08 +00:00
feat: Add Label Input components (#10480)
This commit is contained in:
49
app/javascript/dashboard/components-next/Label/AddLabel.vue
Normal file
49
app/javascript/dashboard/components-next/Label/AddLabel.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
|
||||
|
||||
defineProps({
|
||||
labelMenuItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['updateLabel']);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const showDropdown = ref(false);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative">
|
||||
<button
|
||||
class="flex items-center gap-1 px-2 py-1 rounded-md outline-dashed h-[26px] outline-1 outline-n-slate-6 hover:bg-n-alpha-2"
|
||||
:class="{ 'bg-n-alpha-2': showDropdown }"
|
||||
@click="showDropdown = !showDropdown"
|
||||
>
|
||||
<span class="i-lucide-plus" />
|
||||
<span class="text-sm text-n-slate-11">
|
||||
{{ t('LABEL.TAG_BUTTON') }}
|
||||
</span>
|
||||
</button>
|
||||
<DropdownMenu
|
||||
v-if="showDropdown"
|
||||
v-on-clickaway="() => (showDropdown = false)"
|
||||
:menu-items="labelMenuItems"
|
||||
show-search
|
||||
class="z-[100] w-48 mt-2 overflow-y-auto ltr:left-0 rtl:right-0 top-full max-h-52"
|
||||
@action="emit('updateLabel', $event)"
|
||||
>
|
||||
<template #thumbnail="{ item }">
|
||||
<div
|
||||
class="rounded-sm size-2"
|
||||
:style="{ backgroundColor: item.thumbnail.color }"
|
||||
/>
|
||||
</template>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</template>
|
||||
22
app/javascript/dashboard/components-next/Label/LabelItem.vue
Normal file
22
app/javascript/dashboard/components-next/Label/LabelItem.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
label: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="bg-n-alpha-2 rounded-md flex items-center h-7 w-fit py-1 ltr:pl-1 rtl:pr-1 ltr:pr-1.5 rtl:pl-1.5"
|
||||
>
|
||||
<div
|
||||
class="w-2 h-2 m-1 rounded-sm"
|
||||
:style="{ backgroundColor: label.color }"
|
||||
/>
|
||||
<span class="text-sm text-n-slate-12">
|
||||
{{ label.title }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script setup>
|
||||
import AddLabel from '../AddLabel.vue';
|
||||
import { labelMenuItems } from './fixtures';
|
||||
|
||||
function onUpdateLabel(label) {
|
||||
console.log('Label updated:', label);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Story title="Components/Label/Add Label">
|
||||
<Variant title="Default (button with label menu items with active state)">
|
||||
<div class="h-[300px] p-4">
|
||||
<AddLabel
|
||||
:label-menu-items="labelMenuItems"
|
||||
@update-label="onUpdateLabel"
|
||||
/>
|
||||
</div>
|
||||
</Variant>
|
||||
|
||||
<Variant title="Empty List (button with empty label menu)">
|
||||
<div class="h-[300px] p-4">
|
||||
<AddLabel :label-menu-items="[]" @update-label="onUpdateLabel" />
|
||||
</div>
|
||||
</Variant>
|
||||
</Story>
|
||||
</template>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script setup>
|
||||
import Label from '../LabelItem.vue';
|
||||
import { label } from './fixtures';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Story title="Components/Label/Label item">
|
||||
<Variant title="Default">
|
||||
<Label :label="label" />
|
||||
</Variant>
|
||||
|
||||
<Variant title="Custom Label">
|
||||
<Label
|
||||
:label="{
|
||||
title: 'Custom Label',
|
||||
color: '#FF5733',
|
||||
}"
|
||||
/>
|
||||
</Variant>
|
||||
</Story>
|
||||
</template>
|
||||
@@ -0,0 +1,62 @@
|
||||
export const label = {
|
||||
id: 1,
|
||||
title: 'delivery',
|
||||
color: '#A2FDD5',
|
||||
};
|
||||
|
||||
export const labelMenuItems = [
|
||||
{
|
||||
label: 'delivery',
|
||||
value: 3,
|
||||
thumbnail: {
|
||||
color: '#A2FDD5',
|
||||
},
|
||||
isSelected: true,
|
||||
action: 'addLabel',
|
||||
},
|
||||
{
|
||||
label: 'lead',
|
||||
value: 6,
|
||||
thumbnail: {
|
||||
color: '#F161C8',
|
||||
},
|
||||
isSelected: false,
|
||||
action: 'addLabel',
|
||||
},
|
||||
{
|
||||
label: 'ops-handover',
|
||||
value: 4,
|
||||
thumbnail: {
|
||||
color: '#A53326',
|
||||
},
|
||||
isSelected: false,
|
||||
action: 'addLabel',
|
||||
},
|
||||
{
|
||||
label: 'billing',
|
||||
value: 1,
|
||||
thumbnail: {
|
||||
color: '#28AD21',
|
||||
},
|
||||
isSelected: false,
|
||||
action: 'addLabel',
|
||||
},
|
||||
{
|
||||
label: 'premium-customer',
|
||||
value: 5,
|
||||
thumbnail: {
|
||||
color: '#6FD4EF',
|
||||
},
|
||||
isSelected: false,
|
||||
action: 'addLabel',
|
||||
},
|
||||
{
|
||||
label: 'software',
|
||||
value: 2,
|
||||
thumbnail: {
|
||||
color: '#8F6EF2',
|
||||
},
|
||||
isSelected: false,
|
||||
action: 'addLabel',
|
||||
},
|
||||
];
|
||||
@@ -30,5 +30,8 @@
|
||||
},
|
||||
"BREADCRUMB": {
|
||||
"ARIA_LABEL": "Breadcrumb"
|
||||
},
|
||||
"LABEL": {
|
||||
"TAG_BUTTON": "tag"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user