UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

168 lines (137 loc) 4.19 kB
import { h, ref, computed, getCurrentInstance } from 'vue' import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js' import useRouterLink, { useRouterLinkProps } from '../../composables/private.use-router-link/use-router-link.js' import { createComponent } from '../../utils/private.create/create.js' import { hUniqueSlot } from '../../utils/private.render/render.js' import { stopAndPrevent } from '../../utils/event/event.js' import { isKeyCode } from '../../utils/private.keyboard/key-composition.js' export default createComponent({ name: 'QItem', props: { ...useDarkProps, ...useRouterLinkProps, tag: { type: String, default: 'div' }, active: { type: Boolean, default: null }, clickable: Boolean, dense: Boolean, insetLevel: Number, tabindex: [String, Number], focused: Boolean, manualFocus: Boolean }, emits: ['click', 'keyup'], setup(props, { slots, emit }) { const { proxy: { $q } } = getCurrentInstance() const isDark = useDark(props, $q) const { hasLink, linkAttrs, linkClass, linkTag, navigateOnClick } = useRouterLink() const rootRef = ref(null) const blurTargetRef = ref(null) const isActionable = computed( () => props.clickable === true || hasLink.value === true || props.tag === 'label' ) const isClickable = computed( () => props.disable !== true && isActionable.value === true ) const classes = computed( () => 'q-item q-item-type row no-wrap' + (props.dense === true ? ' q-item--dense' : '') + (isDark.value === true ? ' q-item--dark' : '') + (hasLink.value === true && props.active === null ? linkClass.value : props.active === true ? ` q-item--active${props.activeClass !== void 0 ? ` ${props.activeClass}` : ''}` : '') + (props.disable === true ? ' disabled' : '') + (isClickable.value === true ? ' q-item--clickable q-link cursor-pointer ' + (props.manualFocus === true ? 'q-manual-focusable' : 'q-focusable q-hoverable') + (props.focused === true ? ' q-manual-focusable--focused' : '') : '') ) const style = computed(() => { if (props.insetLevel === void 0) { return null } const dir = $q.lang.rtl === true ? 'Right' : 'Left' return { ['padding' + dir]: 16 + props.insetLevel * 56 + 'px' } }) function onClick(e) { if (isClickable.value === true) { if (blurTargetRef.value !== null && e.qAvoidFocus !== true) { if ( e.qKeyEvent !== true && document.activeElement === rootRef.value ) { blurTargetRef.value.focus() } else if (document.activeElement === blurTargetRef.value) { rootRef.value.focus() } } navigateOnClick(e) } } function onKeyup(e) { if (isClickable.value === true && isKeyCode(e, [13, 32]) === true) { stopAndPrevent(e) // for ripple e.qKeyEvent = true // for click trigger const evt = new MouseEvent('click', e) evt.qKeyEvent = true rootRef.value.dispatchEvent(evt) } emit('keyup', e) } function getContent() { const child = hUniqueSlot(slots.default, []) if (isClickable.value === true) { child.unshift( h('div', { class: 'q-focus-helper', tabindex: -1, ref: blurTargetRef }) ) } return child } return () => { const data = { ref: rootRef, class: classes.value, style: style.value, role: 'listitem', onClick, onKeyup } if (isClickable.value === true) { data.tabindex = props.tabindex || '0' Object.assign(data, linkAttrs.value) } else if (isActionable.value === true) { data['aria-disabled'] = 'true' } return h(linkTag.value, data, getContent()) } } })