mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
Co-authored-by: Benjamin Scharf <bs@zammad.com> Co-authored-by: Dusan Vuckovic <dv@zammad.com> Co-authored-by: Joe Schröcker <js@zammad.com>
77 lines
2.2 KiB
Vue
77 lines
2.2 KiB
Vue
<!-- Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/ -->
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
|
|
import type { TableItem } from './types'
|
|
|
|
export interface Props {
|
|
item: TableItem
|
|
onClickRow?: (tableItem: TableItem) => void
|
|
isRowSelected?: boolean
|
|
hasCheckbox?: boolean
|
|
noAutoStriping?: boolean
|
|
isStriped?: boolean
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
const emit = defineEmits<{
|
|
'click-row': [TableItem]
|
|
}>()
|
|
|
|
const rowId = 'selectable-table-row'
|
|
|
|
const isClickable = computed(() => (props.onClickRow || props.hasCheckbox) && !props.item.disabled)
|
|
|
|
const rowEventHandler = computed(() =>
|
|
isClickable.value
|
|
? {
|
|
attrs: {
|
|
'aria-describedby': rowId,
|
|
tabindex: props.hasCheckbox ? -1 : 0,
|
|
class:
|
|
'group focus-visible:outline-transparent active:bg-blue-800 active:dark:bg-blue-800 focus-visible:bg-blue-800 focus-visible:dark:bg-blue-900 focus-within:text-white hover:bg-blue-600 dark:hover:bg-blue-900',
|
|
},
|
|
events: {
|
|
click: () => {
|
|
;(document.activeElement as HTMLElement)?.blur()
|
|
emit('click-row', props.item)
|
|
},
|
|
keydown: (event: KeyboardEvent) => {
|
|
if (event.key !== 'Enter') return
|
|
emit('click-row', props.item)
|
|
},
|
|
},
|
|
}
|
|
: { attrs: {}, events: {} },
|
|
)
|
|
|
|
const hasScreenReaderHelpText = computed(() => !!document?.getElementById(rowId))
|
|
</script>
|
|
|
|
<template>
|
|
<tr
|
|
:class="{
|
|
'odd:bg-blue-200 odd:dark:bg-gray-700': !noAutoStriping,
|
|
'bg-blue-200 dark:bg-gray-700': isStriped === true,
|
|
'bg-blue-800!': !hasCheckbox && isRowSelected,
|
|
'cursor-pointer': isClickable,
|
|
}"
|
|
style="clip-path: xywh(0 0 100% 100% round 0.375rem)"
|
|
:data-item-id="item.id"
|
|
data-test-id="table-row"
|
|
v-bind="rowEventHandler.attrs"
|
|
v-on="rowEventHandler.events"
|
|
>
|
|
<slot :is-row-selected="isRowSelected" />
|
|
|
|
<template v-if="!hasScreenReaderHelpText">
|
|
<Teleport to="body">
|
|
<p v-if="rowEventHandler.attrs['aria-describedby']" :id="rowId" class="sr-only absolute">
|
|
{{ __('Select table row') }}
|
|
</p>
|
|
</Teleport>
|
|
</template>
|
|
</tr>
|
|
</template>
|