Skip to content
Open

Chip #23

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<template>
<main>
Vue-Tailwind
</main>
<main>Vue-Tailwind</main>
</template>
64 changes: 64 additions & 0 deletions src/components/DxhChips.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div
class="inline-block"
:class="{ 'cursor-grab': draggable }"
:draggable="draggable"
@dragstart="handleDragStart"
@dragover="handleDragOver"
@dragend="handleDragEnd"
>
<div :class="['flex items-center py-2 px-3 border bg-gray-300 rounded-lg', classes]">
<slot :text="text">
<span class="text mr-2">{{ text }}</span>
</slot>
<span v-if="closeable" class="cursor-pointer">
<slot name="close" @click="close">
<svg
xmlns="http://www.w3.org/2000/svg"
height="16"
width="16"
viewBox="0 0 512 512"
@click="close"
>
<path
d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"
/>
</svg>
</slot>
</span>
</div>
</div>
</template>

<script setup lang="ts">
import { defineProps, defineEmits } from 'vue'

const { classes, text, closeable, draggable } = defineProps<{
classes?: string
text: string
closeable?: boolean
draggable?: boolean
}>()

const emit = defineEmits(['close', 'drop'])

const close = () => {
emit('close')
}

const handleDragStart = (event: DragEvent) => {
if (draggable) {
event.dataTransfer?.setData('text/plain', text)
}
}

const handleDragOver = (event: DragEvent) => {
event.preventDefault()
}

const handleDragEnd = () => {
if (draggable) {
emit('drop', text)
}
}
</script>
48 changes: 48 additions & 0 deletions src/components/__tests__/DxhChip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import DxhChips from '../DxhChips.vue'

describe('DxhChips.vue', () => {
it('renders draggable item with close button', () => {
const wrapper = mount(DxhChips, {
props: {
text: 'Sample Text',
closeable: true,
draggable: true
}
})
expect(wrapper.classes()).toContain('inline-block')
expect(wrapper.classes()).toContain('cursor-grab')

expect(
wrapper.find('.flex.items-center.py-2.px-3.border.bg-gray-300.rounded-lg').exists()
).toBe(true)

expect(wrapper.find('.text').text()).toBe('Sample Text')

const closeButton = wrapper.find('span.cursor-pointer')
expect(closeButton.exists()).toBe(true)

expect(wrapper.attributes('draggable')).toBe('true')
expect(wrapper.emitted('close')).toBeFalsy()

wrapper.trigger('dragstart')
expect(wrapper.emitted('drop')).toBeFalsy()

wrapper.trigger('dragend')
expect(wrapper.emitted('drop')).toBeTruthy()
})

it('renders draggable item without close button', () => {
const wrapper = mount(DxhChips, {
props: {
text: 'Sample Text',
closeable: false,
draggable: true
}
})

const closeButton = wrapper.find('span.cursor-pointer')
expect(closeButton.exists()).toBe(false)
})
})
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DButton from "./components/DButton.vue"
import DInput from "./components/DInput.vue"
import DButton from './components/DButton.vue'
import DInput from './components/DInput.vue'
import DxhChips from './components/DxhChips.vue'

export default {DButton, DInput}
export default { DButton, DInput, DxhChips }