Files
Kotyata/layers/ui/components/accordion/item.vue
2026-03-17 13:24:22 +03:00

80 lines
1.9 KiB
Vue

<template>
<div
:class="[
cn.b(),
cn.is('focused', focused),
cn.is('active', isActive),
cn.is('disabled', disabled),
]"
>
<button
:class="[cn.e('head')]"
type="button"
@focus="focused = true"
@blur="focused = false"
@click="handleClick"
@keydown.space.enter.stop.prevent="handleClick"
>
<slot name="title">
<h3 :class="[cn.e('title')]">
{{ title }}
</h3>
</slot>
<Component
:is="resolveComponent(`ui-icon-${isActive ? activeIcon : inactiveIcon}`)"
v-if="!disabled"
:class="cn.e('icon')"
/>
</button>
<UiAccordionTransition>
<div
v-show="isActive"
:class="[cn.e('wrapper')]"
>
<div :class="[cn.e('content')]">
<slot />
</div>
</div>
</UiAccordionTransition>
</div>
</template>
<script setup lang="ts">
import { uniqueId } from 'lodash-es'
import { computed, inject, ref } from 'vue'
import useClassname from '../../composables/use-classname'
import UiAccordionTransition from './transition.vue'
import { accordionContextKey } from './constants'
import type { UiIcon } from '#build/types/ui/icons'
export interface Props {
id?: string | number
title?: string
}
defineOptions({
name: 'UiAccordionItem',
})
const props = withDefaults(defineProps<Props>(), {
id: () => uniqueId(),
title: '',
})
const accordion = inject(accordionContextKey)
const cn = useClassname('ui-accordion-item')
const focused = ref(false)
const isActive = computed(() => accordion?.isActive(props.id) ?? false)
const activeIcon = computed<UiIcon>(() => accordion?.activeIcon.value ?? 'minus')
const inactiveIcon = computed<UiIcon>(() => accordion?.inactiveIcon.value ?? 'plus')
const disabled = computed<boolean>(() => accordion?.disabled.value ?? false)
function handleClick() {
accordion?.handleItemClick(props.id)
}
</script>