UNPKG

vuetify

Version:

Vue Material Component Framework

251 lines (250 loc) 8.88 kB
import { withDirectives as _withDirectives, resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue"; // Styles import "./VListItem.css"; // Components import { VAvatar } from "../VAvatar/index.mjs"; import { VDefaultsProvider } from "../VDefaultsProvider/index.mjs"; import { VIcon } from "../VIcon/index.mjs"; import { VListItemSubtitle } from "./VListItemSubtitle.mjs"; import { VListItemTitle } from "./VListItemTitle.mjs"; // Directives import { Ripple } from "../../directives/ripple/index.mjs"; // Composables import { genOverlays, makeVariantProps, useVariant } from "../../composables/variant.mjs"; import { IconValue } from "../../composables/icons.mjs"; import { makeBorderProps, useBorder } from "../../composables/border.mjs"; import { makeDensityProps, useDensity } from "../../composables/density.mjs"; import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs"; import { makeElevationProps, useElevation } from "../../composables/elevation.mjs"; import { makeRoundedProps, useRounded } from "../../composables/rounded.mjs"; import { makeRouterProps, useLink } from "../../composables/router.mjs"; import { makeTagProps } from "../../composables/tag.mjs"; import { makeThemeProps, provideTheme } from "../../composables/theme.mjs"; import { useList } from "./list.mjs"; import { useNestedItem } from "../../composables/nested/nested.mjs"; // Utilities import { computed, watch } from 'vue'; import { EventProp, genericComponent, useRender } from "../../util/index.mjs"; // Types export const VListItem = genericComponent()({ name: 'VListItem', directives: { Ripple }, props: { active: { type: Boolean, default: undefined }, activeClass: String, activeColor: String, appendAvatar: String, appendIcon: IconValue, disabled: Boolean, lines: String, link: { type: Boolean, default: undefined }, nav: Boolean, prependAvatar: String, prependIcon: IconValue, ripple: { type: Boolean, default: true }, subtitle: [String, Number, Boolean], title: [String, Number, Boolean], value: null, onClick: EventProp, onClickOnce: EventProp, ...makeBorderProps(), ...makeDensityProps(), ...makeDimensionProps(), ...makeElevationProps(), ...makeRoundedProps(), ...makeRouterProps(), ...makeTagProps(), ...makeThemeProps(), ...makeVariantProps({ variant: 'text' }) }, emits: { click: e => true }, setup(props, _ref) { let { attrs, slots, emit } = _ref; const link = useLink(props, attrs); const id = computed(() => props.value ?? link.href.value); const { select, isSelected, isIndeterminate, isGroupActivator, root, parent, openOnSelect } = useNestedItem(id, false); const list = useList(); const isActive = computed(() => props.active !== false && (props.active || link.isActive?.value || isSelected.value)); const isLink = computed(() => props.link !== false && link.isLink.value); const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || props.value != null && !!list)); const roundedProps = computed(() => props.rounded || props.nav); const variantProps = computed(() => ({ color: isActive.value ? props.activeColor ?? props.color : props.color, variant: props.variant })); watch(() => link.isActive?.value, val => { if (val && parent.value != null) { root.open(parent.value, true); } if (val) { openOnSelect(val); } }, { immediate: true }); const { themeClasses } = provideTheme(props); const { borderClasses } = useBorder(props); const { colorClasses, colorStyles, variantClasses } = useVariant(variantProps); const { densityClasses } = useDensity(props); const { dimensionStyles } = useDimension(props); const { elevationClasses } = useElevation(props); const { roundedClasses } = useRounded(roundedProps); const lineClasses = computed(() => props.lines ? `v-list-item--${props.lines}-line` : undefined); const slotProps = computed(() => ({ isActive: isActive.value, select, isSelected: isSelected.value, isIndeterminate: isIndeterminate.value })); function onClick(e) { emit('click', e); if (isGroupActivator || !isClickable.value) return; link.navigate?.(e); props.value != null && select(!isSelected.value, e); } function onKeyDown(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(e); } } useRender(() => { const Tag = isLink.value ? 'a' : props.tag; const hasColor = !list || isSelected.value || isActive.value; const hasTitle = slots.title || props.title; const hasSubtitle = slots.subtitle || props.subtitle; const hasAppend = !!(slots.append || props.appendAvatar || props.appendIcon); const hasPrepend = !!(slots.prepend || props.prependAvatar || props.prependIcon); list?.updateHasPrepend(hasPrepend); return _withDirectives(_createVNode(Tag, { "class": ['v-list-item', { 'v-list-item--active': isActive.value, 'v-list-item--disabled': props.disabled, 'v-list-item--link': isClickable.value, 'v-list-item--nav': props.nav, 'v-list-item--prepend': !hasPrepend && list?.hasPrepend.value, [`${props.activeClass}`]: props.activeClass && isActive.value }, themeClasses.value, borderClasses.value, hasColor ? colorClasses.value : undefined, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value], "style": [hasColor ? colorStyles.value : undefined, dimensionStyles.value], "href": link.href.value, "tabindex": isClickable.value ? 0 : undefined, "onClick": onClick, "onKeydown": isClickable.value && !isLink.value && onKeyDown }, { default: () => [genOverlays(isClickable.value || isActive.value, 'v-list-item'), hasPrepend && _createVNode("div", { "key": "prepend", "class": "v-list-item__prepend" }, [props.prependAvatar && _createVNode(VAvatar, { "key": "prepend-avatar", "density": props.density, "image": props.prependAvatar }, null), props.prependIcon && _createVNode(VIcon, { "key": "prepend-icon", "density": props.density, "icon": props.prependIcon }, null), slots.prepend && _createVNode(VDefaultsProvider, { "key": "prepend", "defaults": { VAvatar: { density: props.density, image: props.prependAvatar }, VIcon: { density: props.density, icon: props.prependIcon }, VListItemAction: { start: true } } }, { default: () => [slots.prepend(slotProps.value)] })]), _createVNode("div", { "class": "v-list-item__content", "data-no-activator": "" }, [hasTitle && _createVNode(VListItemTitle, { "key": "title" }, { default: () => [slots.title?.({ title: props.title }) ?? props.title] }), hasSubtitle && _createVNode(VListItemSubtitle, { "key": "subtitle" }, { default: () => [slots.subtitle?.({ subtitle: props.subtitle }) ?? props.subtitle] }), slots.default?.(slotProps.value)]), hasAppend && _createVNode("div", { "key": "append", "class": "v-list-item__append" }, [slots.append && _createVNode(VDefaultsProvider, { "key": "append", "defaults": { VAvatar: { density: props.density, image: props.appendAvatar }, VIcon: { density: props.density, icon: props.appendIcon }, VListItemAction: { end: true } } }, { default: () => [slots.append(slotProps.value)] }), props.appendIcon && _createVNode(VIcon, { "key": "append-icon", "density": props.density, "icon": props.appendIcon }, null), props.appendAvatar && _createVNode(VAvatar, { "key": "append-avatar", "density": props.density, "image": props.appendAvatar }, null)])] }), [[_resolveDirective("ripple"), isClickable.value && props.ripple]]); }); return {}; } }); //# sourceMappingURL=VListItem.mjs.map