mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-03 04:27:53 +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": {
|
"BREADCRUMB": {
|
||||||
"ARIA_LABEL": "Breadcrumb"
|
"ARIA_LABEL": "Breadcrumb"
|
||||||
|
},
|
||||||
|
"LABEL": {
|
||||||
|
"TAG_BUTTON": "tag"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user