vuetify
Version:
Vue Material Component Framework
238 lines (237 loc) • 7.26 kB
JavaScript
import { createVNode as _createVNode } from "vue";
// Styles
import "./VList.css";
// Components
import { VListChildren } from "./VListChildren.js"; // Composables
import { createList } from "./list.js";
import { makeBorderProps, useBorder } from "../../composables/border.js";
import { useBackgroundColor } from "../../composables/color.js";
import { makeComponentProps } from "../../composables/component.js";
import { provideDefaults } from "../../composables/defaults.js";
import { makeDensityProps, useDensity } from "../../composables/density.js";
import { makeDimensionProps, useDimension } from "../../composables/dimensions.js";
import { makeElevationProps, useElevation } from "../../composables/elevation.js";
import { IconValue } from "../../composables/icons.js";
import { makeItemsProps } from "../../composables/list-items.js";
import { makeNestedProps, useNested } from "../../composables/nested/nested.js";
import { makeRoundedProps, useRounded } from "../../composables/rounded.js";
import { makeTagProps } from "../../composables/tag.js";
import { makeThemeProps, provideTheme } from "../../composables/theme.js";
import { makeVariantProps } from "../../composables/variant.js"; // Utilities
import { computed, ref, shallowRef, toRef } from 'vue';
import { EventProp, focusChild, genericComponent, getPropertyFromItem, isPrimitive, omit, propsFactory, useRender } from "../../util/index.js"; // Types
function transformItem(props, item) {
const type = getPropertyFromItem(item, props.itemType, 'item');
const title = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemTitle);
const value = getPropertyFromItem(item, props.itemValue, undefined);
const children = getPropertyFromItem(item, props.itemChildren);
const itemProps = props.itemProps === true ? omit(item, ['children']) : getPropertyFromItem(item, props.itemProps);
const _props = {
title,
value,
...itemProps
};
return {
type,
title: _props.title,
value: _props.value,
props: _props,
children: type === 'item' && children ? transformItems(props, children) : undefined,
raw: item
};
}
function transformItems(props, items) {
const array = [];
for (const item of items) {
array.push(transformItem(props, item));
}
return array;
}
export function useListItems(props) {
const items = computed(() => transformItems(props, props.items));
return {
items
};
}
export const makeVListProps = propsFactory({
baseColor: String,
/* @deprecated */
activeColor: String,
activeClass: String,
bgColor: String,
disabled: Boolean,
expandIcon: IconValue,
collapseIcon: IconValue,
lines: {
type: [Boolean, String],
default: 'one'
},
slim: Boolean,
nav: Boolean,
'onClick:open': EventProp(),
'onClick:select': EventProp(),
'onUpdate:opened': EventProp(),
...makeNestedProps({
selectStrategy: 'single-leaf',
openStrategy: 'list'
}),
...makeBorderProps(),
...makeComponentProps(),
...makeDensityProps(),
...makeDimensionProps(),
...makeElevationProps(),
itemType: {
type: String,
default: 'type'
},
...makeItemsProps(),
...makeRoundedProps(),
...makeTagProps(),
...makeThemeProps(),
...makeVariantProps({
variant: 'text'
})
}, 'VList');
export const VList = genericComponent()({
name: 'VList',
props: makeVListProps(),
emits: {
'update:selected': value => true,
'update:activated': value => true,
'update:opened': value => true,
'click:open': value => true,
'click:activate': value => true,
'click:select': value => true
},
setup(props, _ref) {
let {
slots
} = _ref;
const {
items
} = useListItems(props);
const {
themeClasses
} = provideTheme(props);
const {
backgroundColorClasses,
backgroundColorStyles
} = useBackgroundColor(() => props.bgColor);
const {
borderClasses
} = useBorder(props);
const {
densityClasses
} = useDensity(props);
const {
dimensionStyles
} = useDimension(props);
const {
elevationClasses
} = useElevation(props);
const {
roundedClasses
} = useRounded(props);
const {
children,
open,
parents,
select,
getPath
} = useNested(props);
const lineClasses = toRef(() => props.lines ? `v-list--${props.lines}-line` : undefined);
const activeColor = toRef(() => props.activeColor);
const baseColor = toRef(() => props.baseColor);
const color = toRef(() => props.color);
createList();
provideDefaults({
VListGroup: {
activeColor,
baseColor,
color,
expandIcon: toRef(() => props.expandIcon),
collapseIcon: toRef(() => props.collapseIcon)
},
VListItem: {
activeClass: toRef(() => props.activeClass),
activeColor,
baseColor,
color,
density: toRef(() => props.density),
disabled: toRef(() => props.disabled),
lines: toRef(() => props.lines),
nav: toRef(() => props.nav),
slim: toRef(() => props.slim),
variant: toRef(() => props.variant)
}
});
const isFocused = shallowRef(false);
const contentRef = ref();
function onFocusin(e) {
isFocused.value = true;
}
function onFocusout(e) {
isFocused.value = false;
}
function onFocus(e) {
if (!isFocused.value && !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget))) focus();
}
function onKeydown(e) {
const target = e.target;
if (!contentRef.value || ['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
if (e.key === 'ArrowDown') {
focus('next');
} else if (e.key === 'ArrowUp') {
focus('prev');
} else if (e.key === 'Home') {
focus('first');
} else if (e.key === 'End') {
focus('last');
} else {
return;
}
e.preventDefault();
}
function onMousedown(e) {
isFocused.value = true;
}
function focus(location) {
if (contentRef.value) {
return focusChild(contentRef.value, location);
}
}
useRender(() => {
return _createVNode(props.tag, {
"ref": contentRef,
"class": ['v-list', {
'v-list--disabled': props.disabled,
'v-list--nav': props.nav,
'v-list--slim': props.slim
}, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class],
"style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
"tabindex": props.disabled ? -1 : 0,
"role": "listbox",
"aria-activedescendant": undefined,
"onFocusin": onFocusin,
"onFocusout": onFocusout,
"onFocus": onFocus,
"onKeydown": onKeydown,
"onMousedown": onMousedown
}, {
default: () => [_createVNode(VListChildren, {
"items": items.value,
"returnObject": props.returnObject
}, slots)]
});
});
return {
open,
select,
focus,
children,
parents,
getPath
};
}
});
//# sourceMappingURL=VList.js.map